Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/Makefile
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/Makefile	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/Makefile	(revision 2309)
@@ -0,0 +1,244 @@
+include ../Mgr/Makefile.h
+ 
+all: $(LIB)libFitsIOServer.a
+clean:
+	rm -f $(OBJ)datacirclefits.o $(OBJ)fabtcolread.o $(OBJ)fabtwriter.o $(OBJ)fboloread.o $(OBJ)fbtntintf.o $(OBJ)fitsautoreader.o $(OBJ)fitsbntbllineRW.o $(OBJ)fitsfile.o $(OBJ)fitslocalmap.o $(OBJ)fitsntuple.o $(OBJ)fitsspherehealpix.o $(OBJ)fitsspherethetaphi.o $(OBJ)fitstarray.o $(OBJ)fitsxntuple.o
+	rm -f $(LIB)libFitsIOServer.a
+$(LIB)libFitsIOServer.a : $(OBJ)datacirclefits.o $(OBJ)fabtcolread.o $(OBJ)fabtwriter.o $(OBJ)fboloread.o $(OBJ)fbtntintf.o $(OBJ)fitsautoreader.o $(OBJ)fitsbntbllineRW.o $(OBJ)fitsfile.o $(OBJ)fitslocalmap.o $(OBJ)fitsntuple.o $(OBJ)fitsspherehealpix.o $(OBJ)fitstarray.o $(OBJ)fitsxntuple.o
+	$(ARCXX) $(ARCXXFLAGS) $@ $($(ARARGS))
+ifeq ($(CXX),cxx)
+	$(CXX) $? $(CPPFLAGS) $(CXXFLAGS) -o $(OBJ)xx.x -Hf
+endif 
+ 
+$(OBJ)datacirclefits.o: datacirclefits.cc datacirclefits.h \
+ $(INC)datacirclebase.h \
+ $(INC)circle.h \
+ $(INC)vector3d.h \
+ $(INC)longlat.h \
+ $(INC)machdefs.h \
+ $(INC)utilgeom.h \
+ $(INC)unitvector.h \
+ $(INC)geometry.h \
+ $(EXTINCPATH)FitsIO/fitsio.h \
+ $(EXTINCPATH)FitsIO/longnam.h
+$(OBJ)fabtcolread.o: fabtcolread.cc \
+ $(INC)machdefs.h \
+ $(INC)pexceptions.h fabtcolread.h \
+ $(INC)anydataobj.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(EXTINCPATH)FitsIO/fitsio.h \
+ $(EXTINCPATH)FitsIO/longnam.h
+$(OBJ)fabtwriter.o: fabtwriter.cc $(INC)machdefs.h \
+ $(INC)pexceptions.h fabtwriter.h \
+ $(INC)anydataobj.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(EXTINCPATH)FitsIO/fitsio.h \
+ $(EXTINCPATH)FitsIO/longnam.h
+$(OBJ)fboloread.o: fboloread.cc $(INC)machdefs.h \
+ $(INC)pexceptions.h fboloread.h \
+ $(INC)anydataobj.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h fabtcolread.h \
+ $(EXTINCPATH)FitsIO/fitsio.h \
+ $(EXTINCPATH)FitsIO/longnam.h
+$(OBJ)fbtntintf.o: fbtntintf.cc $(INC)machdefs.h \
+ $(INC)pexceptions.h fbtntintf.h \
+ $(INC)anydataobj.h \
+ $(INC)ntupintf.h \
+ $(EXTINCPATH)FitsIO/fitsio.h \
+ $(EXTINCPATH)FitsIO/longnam.h
+$(OBJ)fitsautoreader.o: fitsautoreader.cc \
+ $(INC)pexceptions.h \
+ $(INC)machdefs.h fitsautoreader.h \
+ $(INC)anydataobj.h fitsfile.h \
+ $(INC)ndatablock.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)mutyv.h \
+ $(EXTINCPATH)FitsIO/fitsio.h \
+ $(EXTINCPATH)FitsIO/longnam.h fitstarray.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)utilarr.h fitsspherehealpix.h \
+ $(INC)spherehealpix.h \
+ $(INC)sphericalmap.h \
+ $(INC)smathconst.h \
+ $(INC)pixelmap.h \
+ $(INC)spherepos.h \
+ $(INC)unitvector.h \
+ $(INC)vector3d.h \
+ $(INC)longlat.h \
+ $(INC)utilgeom.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)HEALPixUtils.h fitsntuple.h \
+ $(INC)ntuple.h \
+ $(INC)ntupintf.h fitsxntuple.h \
+ $(INC)xntuple.h fitslocalmap.h \
+ $(INC)localmap.h
+$(OBJ)fitsbntbllineRW.o: fitsbntbllineRW.cc \
+ $(INC)pexceptions.h \
+ $(INC)machdefs.h fitsbntbllineRW.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)mutyv.h fitsfile.h \
+ $(INC)ndatablock.h \
+ $(EXTINCPATH)FitsIO/fitsio.h \
+ $(EXTINCPATH)FitsIO/longnam.h \
+ $(INC)utils.h
+$(OBJ)fitsfile.o: fitsfile.cc $(INC)machdefs.h \
+ fitsfile.h $(INC)ndatablock.h \
+ $(INC)anydataobj.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)mutyv.h \
+ $(EXTINCPATH)FitsIO/fitsio.h \
+ $(EXTINCPATH)FitsIO/longnam.h \
+ $(INC)strutil.h fitsspherehealpix.h \
+ $(INC)spherehealpix.h \
+ $(INC)sphericalmap.h \
+ $(INC)smathconst.h \
+ $(INC)pixelmap.h \
+ $(INC)spherepos.h \
+ $(INC)unitvector.h \
+ $(INC)vector3d.h \
+ $(INC)longlat.h \
+ $(INC)utilgeom.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)utilarr.h \
+ $(INC)HEALPixUtils.h
+$(OBJ)fitslocalmap.o: fitslocalmap.cc \
+ $(INC)machdefs.h fitslocalmap.h \
+ $(INC)pexceptions.h \
+ $(INC)localmap.h \
+ $(INC)pixelmap.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)spherepos.h \
+ $(INC)unitvector.h \
+ $(INC)vector3d.h \
+ $(INC)longlat.h \
+ $(INC)utilgeom.h \
+ $(INC)sphericalmap.h \
+ $(INC)smathconst.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h fitsfile.h \
+ $(EXTINCPATH)FitsIO/fitsio.h \
+ $(EXTINCPATH)FitsIO/longnam.h
+$(OBJ)fitsntuple.o: fitsntuple.cc \
+ $(INC)pexceptions.h \
+ $(INC)machdefs.h fitsntuple.h \
+ $(INC)ntuple.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)ntupintf.h \
+ $(INC)dvlist.h \
+ $(INC)mutyv.h fitsfile.h \
+ $(INC)ndatablock.h \
+ $(EXTINCPATH)FitsIO/fitsio.h \
+ $(EXTINCPATH)FitsIO/longnam.h
+$(OBJ)fitsspherehealpix.o: fitsspherehealpix.cc \
+ $(INC)pexceptions.h \
+ $(INC)machdefs.h fitsspherehealpix.h \
+ $(INC)spherehealpix.h \
+ $(INC)sphericalmap.h \
+ $(INC)smathconst.h \
+ $(INC)pixelmap.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)spherepos.h \
+ $(INC)unitvector.h \
+ $(INC)vector3d.h \
+ $(INC)longlat.h \
+ $(INC)utilgeom.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)HEALPixUtils.h fitsfile.h \
+ $(EXTINCPATH)FitsIO/fitsio.h \
+ $(EXTINCPATH)FitsIO/longnam.h fitstarray.h
+$(OBJ)fitstarray.o: fitstarray.cc $(INC)machdefs.h \
+ $(INC)pexceptions.h fitstarray.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h fitsfile.h \
+ $(EXTINCPATH)FitsIO/fitsio.h \
+ $(EXTINCPATH)FitsIO/longnam.h
+$(OBJ)fitsxntuple.o: fitsxntuple.cc \
+ $(INC)pexceptions.h \
+ $(INC)machdefs.h fitsxntuple.h \
+ $(INC)xntuple.h \
+ $(INC)ntupintf.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h fitsfile.h \
+ $(INC)ndatablock.h \
+ $(EXTINCPATH)FitsIO/fitsio.h \
+ $(EXTINCPATH)FitsIO/longnam.h
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/datacirclefits.cc
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/datacirclefits.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/datacirclefits.cc	(revision 2309)
@@ -0,0 +1,142 @@
+#include <iostream.h>
+#include "datacirclefits.h"
+
+/*
+   Class used to recover the circles and measures involved in a mission. The parameters needful to create a circle and the number of samples on this circle are read from a FITS data array. In addition, a function returns the measurement at a given angular position psi on the circle.
+*/
+
+DataCircleFits::DataCircleFits() : 
+  _fptr(NULL)
+, _NMeasurements(0)
+, _ICircle(0)
+, _mesures(NULL)
+, _stored_data(false)
+{;}
+
+DataCircleFits::DataCircleFits(fitsfile *is,int hdunum,bool sdata) :
+  _fptr(NULL)
+, _NMeasurements(0)
+, _ICircle(hdunum)
+, _mesures(NULL)
+, _stored_data(sdata)
+{
+
+  // pointer to the FITS file
+  _fptr= is;
+  int status = 0;
+
+  // move to the HDU containing a circle
+  fits_movabs_hdu(_fptr,hdunum,NULL,&status);
+
+  // angles of the circle
+  double theta;
+  fits_read_key(_fptr,TDOUBLE,"CIRTHETA",&theta,NULL,&status);
+
+  double phi;
+  fits_read_key(_fptr,TDOUBLE,"CIRPHI",&phi,NULL,&status);
+
+  double aperture;
+  fits_read_key(_fptr,TDOUBLE,"CIRAPER",&aperture,NULL,&status);
+
+  UnitVector temp(theta,phi);
+  SetCircle(temp,aperture);
+
+  fits_read_key(_fptr,TINT,"NSAMPLES",&_NMeasurements,NULL,&status);
+
+  if(_stored_data) {
+    // vector repeat value for the column (there is only 1 column)
+    long repeat;
+    fits_get_coltype(_fptr,1,NULL,&repeat,NULL,&status);
+
+    double dnull= 0.;
+    int    anull;
+    _mesures= new double[_NMeasurements];
+   int i;
+   for(i = 0; i < _NMeasurements; i++) {
+     // row index: range 1 to NAXIS2
+     int index= i+1;
+     
+     // starting line index
+     int stline= index/repeat; 
+     int stelem= index-stline*repeat;
+     if(stelem != 0) {
+       stline++;
+     } else {
+       stelem= repeat;
+     }
+     fits_read_col(_fptr,TDOUBLE,1,stline,stelem,1,&dnull,&_mesures[i],&anull,&status);
+   }
+  }
+}
+  
+DataCircleFits::~DataCircleFits() {
+
+  if(_mesures != NULL) delete [] _mesures;
+}
+
+int DataCircleFits::NMeasurements() const {
+
+  return _NMeasurements;
+}
+
+double DataCircleFits::getData(double psi) const {
+
+  double dtab;
+  int ibin= l_ft_nint(psi*_NMeasurements/(2.*M_PI));
+  //cout << " ibin= " << ibin << ", " << psi << endl;
+
+  if(_stored_data) {
+    dtab= _mesures[ibin];
+  } else {
+    int status= 0;
+    fits_movabs_hdu(_fptr,_ICircle,NULL,&status);
+
+    // vector repeat value for the column (there is only 1 column)
+    long repeat;
+    fits_get_coltype(_fptr,1,NULL,&repeat,NULL,&status);
+   
+    double dnull= 0.;
+    int    anull;
+
+    int index= ibin+1;
+    // starting line index
+    int stline= index/repeat; 
+    int stelem= index-stline*repeat;
+    if(stelem != 0) {
+      stline++;
+    } else {
+      stelem= repeat;
+    }
+    fits_read_col(_fptr,TDOUBLE,1,stline,stelem,1,&dnull,&dtab,&anull,&status);
+  }
+  //cout << "DataCircleFits:: bin= " << ibin << ", " << dtab << endl;
+  return dtab;
+}
+
+void DataCircleFits::print(ostream& out) const {
+
+  out << " Circle:: ApertureAngle= " << ApertureAngle() << ", Theta= " 
+      << Theta() << ", Phi= " << Phi() << ", NSamples= " 
+      << NMeasurements() << endl;
+}
+
+double DataCircleFits::getTMeasure(double psi) const {
+
+  if(_mesures == NULL) {
+    cout << "  DataCircleFits::getTMeasure data must be stored"
+	 << " in an array... verify the option" << endl;
+    exit(0);
+  }
+  int ibin= l_ft_nint(psi*_NMeasurements/(2.*M_PI));
+  return _mesures[ibin];
+}
+
+double DataCircleFits::getTOffset() const {
+
+  int status= 0;
+  fits_movabs_hdu(_fptr,_ICircle,NULL,&status);
+
+  double omes= 0.0;
+  fits_read_key_dbl(_fptr,"OFFSET",&omes,NULL,&status);
+  return omes;
+}
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/datacirclefits.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/datacirclefits.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/datacirclefits.h	(revision 2309)
@@ -0,0 +1,30 @@
+#ifndef DATACIRCLEFITS_H_SEEN
+#define DATACIRCLEFITS_H_SEEN
+
+#include "datacirclebase.h"
+#include "FitsIO/fitsio.h" 
+
+class DataCircleFits : public DataCircleBase {
+
+ public:
+
+  DataCircleFits();
+  DataCircleFits(fitsfile*,int,bool);
+  virtual ~DataCircleFits();
+
+  virtual int NMeasurements() const;
+  virtual double getData(double) const;
+  virtual double getTMeasure(double) const;
+  virtual void print(ostream&) const;
+
+  double getTOffset() const;
+
+ private:
+
+  fitsfile* _fptr;
+  int _ICircle;
+  int _NMeasurements;
+  bool _stored_data;
+  double* _mesures;
+};
+#endif
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/exclude
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/exclude	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/exclude	(revision 2309)
@@ -0,0 +1,5 @@
+fitsioserver.cc
+fitsbntbllinereader.cc.encours
+fitsbntbllinereaderXX.cc
+fitsbntbllinereader.travail.cc
+fitsbntbllinereader.sv.cc
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/extlib_list
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/extlib_list	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/extlib_list	(revision 2309)
@@ -0,0 +1,1 @@
+cfitsio
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/extslb_list
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/extslb_list	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/extslb_list	(revision 2309)
@@ -0,0 +1,1 @@
+cfitsio
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/fabtcolread.cc
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/fabtcolread.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/fabtcolread.cc	(revision 2309)
@@ -0,0 +1,600 @@
+/* Lecteur de colonne de table Fits (binaire ou ASCII) avec buffer */
+#include "machdefs.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include "pexceptions.h"
+#include "fabtcolread.h"
+//! Class for reading a column in a FITS ASCII or BINARY table
+
+/*!
+  \class SOPHYA::FitsABTColRead
+  \ingroup FitsIOServer
+  Class for reading a column in a FITS ASCII or BINARY table
+  \verbatim
+  -- Exemple:
+  FitsABTColRead fbt("myfits.fits","BoloMuv_28",0,1000,1,3);
+  fbt.SetDebug(3);
+  fbt.Print(3);
+  // Read element by element
+  for(long i=0;i<fbt.GetNbLine();i++) {
+    double x = fbt.Read(i);
+    if(i%lpmod==0) cout<<i<<": "<<x<<endl;
+  }
+  // Read into a vector
+  TVector<double> data;
+  long n = fbt.Read(32,50,data);
+    cout<<"Number of values read: "<<n<<endl;
+  data.ReSize(100);
+  n = fbt.Read(10,-1,data);
+    cout<<"Number of values read: "<<n<<endl;
+  \endverbatim
+*/
+
+//////////////////////////////////////////////////////////////
+/*!
+  Constructor.
+  \param fname : FITS file name to be read
+  \param collabel : label of the column to be read
+  \param ihdu : number of the HDU where the column is.
+  \param blen : read buffer length
+  \param bsens : buffer reading direction
+  \param lp : debug level
+  \verbatim
+  - if ihdu=0 or ihdu>nhdu first binary or ASCII table is taken
+  - bsens>0    read forward
+    bsens<0    read backward
+    bsens==0   read centered
+  \endverbatim
+  \warning ihdu = [1,nhdu]
+*/
+FitsABTColRead::FitsABTColRead(string fname,string collabel
+                            ,int ihdu,long blen,long bsens,int lp)
+{
+Init(fname.c_str(),collabel.c_str(),-1,ihdu,blen,bsens,lp);
+}
+
+/*!
+  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[
+*/
+FitsABTColRead::FitsABTColRead(string fname,int colnum
+                            ,int ihdu,long blen,long bsens,int lp)
+{
+Init(fname.c_str(),"",colnum,ihdu,blen,bsens,lp);
+}
+
+/*! Constructor. see below */
+FitsABTColRead::FitsABTColRead(const char * cfname,const char* collabel
+                            ,int ihdu,long blen,long bsens,int lp)
+{
+Init(cfname,collabel,-1,ihdu,blen,bsens,lp);
+}
+
+/*! Constructor. see below */
+FitsABTColRead::FitsABTColRead(const char * cfname,int colnum
+                            ,int ihdu,long blen,long bsens,int lp)
+{
+Init(cfname,"",colnum,ihdu,blen,bsens,lp);
+}
+
+/*! Constructor by copy */
+FitsABTColRead::FitsABTColRead(FitsABTColRead& fbt)
+{
+Init(fbt.GetFileName().c_str(),fbt.GetColLabel().c_str()
+    ,fbt.GetColNum(),fbt.GetHDU()
+    ,fbt.GetBLen(),fbt.GetBSens(),fbt.DbgLevel);
+}
+
+/*! Init routine called by the constructor */
+void FitsABTColRead::Init(const char* fname,const char* collabel,int colnum
+                        ,int ihdu,long blen,long bsens,int lp)
+{
+ // Parametres Generaux
+ FitsFN = fname;
+ ColLabel = collabel;
+ ColTUnit = "";
+ ColTForm = "";
+ ColNum = colnum;
+ ColTypeCode = 0;
+ IHdu = ihdu;
+ NHdu = 0;
+ HduType = 0;
+ NBcol = 0;
+ NBline = 0;
+ SetNulVal();
+ SetDebug(lp);
+ NFitsRead = 0;
+ FitsPtr = NULL;
+ LineDeb = LineFin = -1;
+ Buffer = NULL;
+ ChangeBuffer(blen,bsens);
+
+ //////////////////////////
+ // Ouverture du fichier //
+ //////////////////////////
+
+ int sta=0;
+ if(FitsFN.size() <= 0 ) {
+   IHdu = -1; Delete();
+   throw ParmError("FitsABTColRead::Init: Fits file name error\n");
+ }
+ const char * cfitsfn = FitsFN.c_str();
+
+ // Open fits
+ if(fits_open_file(&FitsPtr,cfitsfn,READONLY,&sta)) {
+   printerror(sta); Delete();
+   throw NullPtrError("FitsABTColRead::Init: Error opening Fits file\n");
+ }
+
+ // Get number of hdu
+ if(fits_get_num_hdus(FitsPtr,&NHdu,&sta)) {
+   printerror(sta); Delete();
+   throw NotAvailableOperation("FitsABTColRead::Init: Error getting NHdu\n");
+ }
+ if(DbgLevel>1) cout<<"FitsABTColRead::Init  NHdu="<<NHdu<<endl;
+ if(NHdu<=0) {
+   Delete();
+   throw SzMismatchError("FitsABTColRead::Init: Bad NHdu\n");
+ }
+
+ // 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)) printerror(sta);
+     if(DbgLevel>1) cout<<"...Init ihdu="
+                        <<ihdu<<" HduType="<<HduType<<endl;
+     if(HduType==BINARY_TBL || HduType==ASCII_TBL) {IHdu = ihdu; break;}
+   }
+ if(IHdu<=0 || IHdu>NHdu) {
+   cout<<"NO BINARY or ASCII hdu found"<<endl;
+   IHdu = 0; Delete();
+   throw TypeMismatchExc("FitsABTColRead::Init: NO BINARY or ASCII hdu found\n");
+ }
+ if(fits_movabs_hdu(FitsPtr,IHdu,&HduType,&sta)) {
+   printerror(sta); Delete();
+   throw RangeCheckError("FitsABTColRead::Init: Error moving to requested HDU\n");
+ }
+ if(HduType!=BINARY_TBL && HduType!=ASCII_TBL) {
+   Delete();
+   throw TypeMismatchExc("FitsABTColRead::Init: HDU not ASCII/BINARY table\n");
+ }
+
+ // Get number of columns
+ if(fits_get_num_cols(FitsPtr,&NBcol,&sta)) {
+   printerror(sta); Delete();
+   throw NotAvailableOperation("FitsABTColRead::Init: Error getting number of columns\n");
+ }
+ if(DbgLevel>1) cout<<"...Init  NBcol="<<NBcol<<endl;
+ if(NBcol<1) {
+   Delete();
+   throw RangeCheckError("FitsABTColRead::Init: Bad number of colums\n");
+ }
+
+ // Get number of rows
+ if(fits_get_num_rows(FitsPtr,&NBline,&sta)) {
+   printerror(sta); Delete();
+   throw NotAvailableOperation("FitsABTColRead::Init: Error getting number of rows\n");
+ }
+ if(DbgLevel>1) cout<<"...Init  NBline="<<NBline<<endl;
+ if(NBline<1) {
+   Delete();
+   throw RangeCheckError("FitsABTColRead::Init: Bad number of rows\n");
+ }
+
+ // Get column number
+ char labelcol[128];
+ if(ColLabel.size() > 0) {
+   strcpy(labelcol,ColLabel.c_str());
+   if(fits_get_colnum(FitsPtr,CASESEN,labelcol,&ColNum,&sta)) {
+     printerror(sta); Delete();
+     throw NotAvailableOperation("FitsABTColRead::Init: Error getting column name\n");
+   }
+   ColNum--;  // Convention [0,ncol[
+ }
+ if(DbgLevel>1) cout<<"...Init  ColNum="<<ColNum<<endl;
+ if(ColNum<0 || ColNum>=NBcol) {
+   Delete();
+   throw RangeCheckError("FitsABTColRead::Init: Bad column number\n");
+ }
+
+ // Get column type
+ if(fits_get_coltype(FitsPtr,ColNum+1,&ColTypeCode,NULL,NULL,&sta)) {
+   printerror(sta); Delete();
+   throw ParmError("FitsABTColRead::Init: Error getting column type\n");
+ }
+ if(DbgLevel>1) cout<<"...Init ColTypeCode="<<ColTypeCode<<endl;
+ if(ColTypeCode==TSTRING || ColTypeCode==TCOMPLEX ||  ColTypeCode==TDBLCOMPLEX
+                         || ColTypeCode<0 ) {
+   Delete();
+   throw ParmError("FitsABTColRead::Init: Selected column is not Numerical\n");
+ }
+
+ // Get column name back, tunit, tform
+ char tunit[64], tform[64], tdisp[64];
+ long repeat=0; double tscale=1., tzero=0.;
+ int rc=0;
+ if(HduType==BINARY_TBL) {
+   fits_get_bcolparms(FitsPtr,ColNum+1,labelcol,tunit,tform
+                     ,&repeat,&tscale,&tzero,NULL,tdisp,&sta);
+ } else {
+   fits_get_acolparms(FitsPtr,ColNum+1,labelcol,&repeat,tunit,tform
+                     ,&tscale,&tzero,NULL,tdisp,&sta);
+ }
+ if(rc) {
+   printerror(sta); Delete();
+   throw RangeCheckError("FitsABTColRead::Init: Error getting the column caracteristics\n");
+ }
+ ColLabel = labelcol;
+ ColTUnit = tunit;
+ ColTForm = tform;
+
+ if(DbgLevel)
+   cout<<"FitsABTColRead::Init Num="<<ColNum<<" Label="<<ColLabel
+       <<" TypeCode="<<ColTypeCode<<" TUnit="<<ColTUnit<<" TForm="<<ColTForm<<endl;
+ if(DbgLevel>1)
+   cout<<"      (repeat="<<repeat<<",tscale="<<tscale<<",tzero="<<tzero
+       <<",tdisp="<<tdisp<<")"<<endl;
+
+}
+
+/*! Destructor. */
+FitsABTColRead::~FitsABTColRead()
+{
+ Delete();
+}
+
+//////////////////////////////////////////////////////////////
+double FitsABTColRead::ReadKey(char *keyname)
+{
+ if(keyname==NULL) return 0.;
+ int sta=0; double val=0.;
+ if(fits_read_key(FitsPtr,TDOUBLE,keyname,&val,NULL,&sta))
+   printerror(sta);
+ return val;
+}
+
+//////////////////////////////////////////////////////////////
+/*! Change the buffer caracteristiques (see creator) */
+void FitsABTColRead::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)) )
+     {delete [] Buffer; Buffer=NULL;}
+ }
+
+ // Re-allocate
+ if(Buffer==NULL) Buffer = new double[NBuffer];
+
+ // Tell program that nothing is into buffer
+ LineDeb = LineFin = -1;
+}
+
+/*! Delete called by the destructor */
+void FitsABTColRead::Delete()
+{
+ if(Buffer!=NULL) {delete [] Buffer; Buffer=NULL;}
+ LineDeb = LineFin = -1;
+ int sta = 0;
+ if(fits_close_file(FitsPtr,&sta)) printerror(sta);
+ FitsPtr = NULL;
+}
+
+/////////////////////////////////////////////////
+/*!
+  Read row "n" 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 FitsABTColRead::Read(long n,bool usebuffer)
+// Attention: n=nline [0,NBline[, cfistio veut [1,NBline]
+// Attention: colnum  [0,NBcol[ , cfistio veut [1,NBcol]
+{
+ int sta=0;
+ if(n<0 || n>=NBline)
+   throw RangeCheckError("FitsABTColRead::Read try to read outside line range\n");
+
+ // Pas de bufferisation, on lit betement
+ if(NBuffer==1 || !usebuffer) {
+   NFitsRead++;
+   double val;
+   fits_read_col(FitsPtr,TDOUBLE,ColNum+1,n+1,1,1,NULL,&val,NULL,&sta);
+   if(sta) {
+     printerror(sta);
+     throw NotAvailableOperation("FitsABTColRead::Read: Error Reading Fits file\n");
+   }
+   // On ne remplit Buffer[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[0]=val; LineDeb=LineFin=n;}
+   return val;
+ }
+
+ // Gestion avec bufferisation
+ if(!Buffer)
+   throw RangeCheckError("FitsABTColRead::Read: Buffer not allocated\n");
+ if(n<LineDeb || n>LineFin) {
+   NFitsRead++;
+   long 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 = row1-1; LineFin = row2-1;
+   //cout<<"DBG-FitsRead: row1="<<row1<<" row2="<<row2<<" nrow="<<nrow
+   //    <<" LineDeb,Fin="<<LineDeb<<","<<LineFin<<endl;
+   fits_read_col(FitsPtr,TDOUBLE,ColNum+1,row1,1,nrow,NULL,Buffer,NULL,&sta);
+   if(sta) {
+     printerror(sta);
+     LineDeb = LineFin = -1;
+     throw NotAvailableOperation("FitsABTColRead::Read: Error Reading Fits file\n");
+   }
+ }
+
+ long ibuf = n-LineDeb;
+ return Buffer[ibuf];
+}
+
+/*!
+  Read rows from "n1" to "n2" and return the values into TVector of double
+  \return NREAD the number of values read (n2-n1+1).
+  \warning row = [0,NRows[, the routine read [n1,n2]
+  \verbatim
+  - if n2<0 then read [n1,n2] where "n2=min(n1+vector_size-1,nrows-1)"
+  - Last row read is ALWAYS: "n2 = n1 + NREAD -1"
+  - The TVector is never resized if not necessary
+  -------------------------------------------------------------------------
+  - ex: suppose the column table contains 10 elements: nrows=10, rows=[0,9]
+
+    TVector<double> V(5);
+      bt.Read(3,5,V)  -> read rows=3,4,5     -> V.Size()==5 -> return 3
+      bt.Read(3,-1,V) -> read rows=3,4,5,6,7 -> V.Size()==5 -> return 5
+      bt.Read(7,-1,V) -> read rows=7,8,9     -> V.Size()==5 -> return 3
+      bt.Read(2,-1,V) -> read rows=2,3,4,5,6 -> V.Size()==5 -> return 5
+      bt.Read(-1,5,V) -> throw exception
+
+    TVector<double> V(5);
+      bt.Read(3,99,V) -> read rows=3,4,5,6,7,8,9 -> V.Size()==7 -> return 7
+
+    TVector<double> V(5);
+      bt.Read(2,8,V)  -> read rows=2,3,4,5,6,7,8 -> V.Size()==7 -> return 7
+
+    TVector<double> V;
+      bt.Read(3,5,V)  -> read rows=3,4,5 -> V.Size()==3 -> return 3
+
+    TVector<double> V;
+      bt.Read(3,-1,V) -> throw exception
+  -------------------------------------------------------------------------
+  \endverbatim
+*/
+long FitsABTColRead::Read(long n1,long n2,TVector<double>& data)
+{
+ if(n1<0 || n1>=NBline)
+   throw RangeCheckError("FitsABTColRead::Read TVector bad requested 1srt line \n");
+ if(data.Size()<=0 && n2<n1)
+   throw RangeCheckError("FitsABTColRead::Read TVector bad requested 2sd line \n");
+ if(n2<0) n2 = n1 + data.Size()-1;
+ if(n2>=NBline) n2 = NBline-1;
+
+ sa_size_t nread = n2-n1+1;
+ if(data.Size()<nread) data.SetSize(nread);
+
+ //for(long i=n1;i<=n2;i++) data(i-n1) = Read(i);
+ int sta=0;
+ fits_read_col(FitsPtr,TDOUBLE,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
+ if(sta) {
+   printerror(sta);
+   throw NotAvailableOperation("FitsABTColRead::Read_TVector<double>: Error Reading Fits file\n");
+ }
+
+ return nread;
+}
+
+/*! idem before but for TVector of float */
+long FitsABTColRead::Read(long n1,long n2,TVector<float>& data)
+{
+ if(n1<0 || n1>=NBline)
+   throw RangeCheckError("FitsABTColRead::Read TVector bad requested 1srt line \n");
+ if(data.Size()<=0 && n2<n1)
+   throw RangeCheckError("FitsABTColRead::Read TVector bad requested 2sd line \n");
+ if(n2<0) n2 = n1 + data.Size()-1;
+ if(n2>=NBline) n2 = NBline-1;
+
+ sa_size_t nread = n2-n1+1;
+ if(data.Size()<nread) data.SetSize(nread);
+
+ //for(long i=n1;i<=n2;i++) data(i-n1) = Read(i);
+ int sta=0;
+ fits_read_col(FitsPtr,TFLOAT,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
+ if(sta) {
+   printerror(sta);
+   throw NotAvailableOperation("FitsABTColRead::Read_TVector<float>: Error Reading Fits file\n");
+ }
+
+ return nread;
+}
+
+/*! idem before but for TVector of unsigned short */
+long FitsABTColRead::Read(long n1,long n2,TVector<uint_2>& data)
+{
+ if(n1<0 || n1>=NBline)
+   throw RangeCheckError("FitsABTColRead::Read TVector bad requested 1srt line \n");
+ if(data.Size()<=0 && n2<n1)
+   throw RangeCheckError("FitsABTColRead::Read TVector bad requested 2sd line \n");
+ if(n2<0) n2 = n1 + data.Size()-1;
+ if(n2>=NBline) n2 = NBline-1;
+
+ sa_size_t nread = n2-n1+1;
+ if(data.Size()<nread) data.SetSize(nread);
+
+ int sta=0;
+ fits_read_col(FitsPtr,TUSHORT,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
+ if(sta) {
+   printerror(sta);
+   throw NotAvailableOperation("FitsABTColRead::Read_TVector<uint_2>: Error Reading Fits file\n");
+ }
+
+ return nread;
+}
+
+/*! idem before but for TVector of int_4 */
+long FitsABTColRead::Read(long n1,long n2,TVector<int_4>& data)
+{
+ if(n1<0 || n1>=NBline)
+   throw RangeCheckError("FitsABTColRead::Read TVector bad requested 1srt line \n");
+ if(data.Size()<=0 && n2<n1)
+   throw RangeCheckError("FitsABTColRead::Read TVector bad requested 2sd line \n");
+ if(n2<0) n2 = n1 + data.Size()-1;
+ if(n2>=NBline) n2 = NBline-1;
+
+ sa_size_t nread = n2-n1+1;
+ if(data.Size()<nread) data.SetSize(nread);
+
+ //for(long i=n1;i<=n2;i++) data(i-n1) = Read(i);
+ int sta=0;
+ int T = (sizeof(long)==4) ? TLONG: TINT;
+ fits_read_col(FitsPtr,T,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
+ if(sta) {
+   printerror(sta);
+   throw NotAvailableOperation("FitsABTColRead::Read_TVector<int_4>: Error Reading Fits file\n");
+ }
+
+ return nread;
+}
+
+/*! idem before but for TVector of int_8 */
+long FitsABTColRead::Read(long n1,long n2,TVector<int_8>& data)
+{
+#ifdef TLONGLONG
+ if(n1<0 || n1>=NBline)
+   throw RangeCheckError("FitsABTColRead::Read TVector bad requested 1srt line \n");
+ if(data.Size()<=0 && n2<n1)
+   throw RangeCheckError("FitsABTColRead::Read TVector bad requested 2sd line \n");
+ if(n2<0) n2 = n1 + data.Size()-1;
+ if(n2>=NBline) n2 = NBline-1;
+
+ sa_size_t nread = n2-n1+1;
+ if(data.Size()<nread) data.SetSize(nread);
+
+ int sta=0;
+ fits_read_col(FitsPtr,TLONGLONG,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
+ if(sta) {
+   printerror(sta);
+   throw NotAvailableOperation("FitsABTColRead::Read_TVector<int_8>: Error Reading Fits file\n");
+ }
+
+ return nread;
+#else
+  throw PException("FitsABTColRead::Read(..,TVector<int_8>&) Not in that cfitsio version");
+#endif
+}
+
+/////////////////////////////////////////////////
+/*!
+  Return the number of the first row where "val1"<=val<="val2" starting at row "rowstart"
+  \verbatim
+  - The search is performed from "rowstart" to the end
+      in ascending order (from "rowstart" to nrows).
+  - Warning: "rowstart<0" means "rowstart==0" (search all the table column)
+             That is the default
+  \endverbatim
+  \return <0 means not found
+*/
+long FitsABTColRead::FirstRow(double val1,double val2,long rowstart)
+{
+ long row = -1;
+ if(NBline==0) return row;
+ // Change buffer for efficiency
+ long bsens=BuffSens; bool bchange=false;
+ if(bsens<=0) {ChangeBuffer(BuffLen,1); bchange=true;}
+ if(rowstart<0) rowstart = 0;
+ if(rowstart>=NBline) rowstart = NBline-1;
+ for(long i=rowstart;i<NBline;i++) {
+   double val = Read(i);
+   if(val<val1 || val>val2) continue;
+   row = i;
+   break;
+ }
+ if(bchange) ChangeBuffer(BuffLen,bsens);
+ return row;
+}
+
+/*!
+  Return the number of the first row where val1<=val<=val2 starting at row rowstart
+  \return <0 means not found
+  \verbatim
+  - The search is performed from "rowstart" to the beginning
+      in descending order (from "rowstart" to 0).
+  - Warning: "rowstart<0" means "rowstart==nrows-1" (search all the table column)
+             That is the default
+  \endverbatim
+*/
+long FitsABTColRead::LastRow(double val1,double val2,long rowstart)
+{
+ long row = -1;
+ if(NBline==0) return row;
+ // Change buffer for efficiency
+ long bsens=BuffSens; bool bchange=false;
+ if(bsens>=0) {ChangeBuffer(BuffLen,-1); bchange=true;}
+ if(rowstart<0 || rowstart>=NBline) rowstart = NBline-1;
+ for(long i=rowstart;i>=0;i--) {
+   double val = Read(i);
+   if(val<val1 || val>val2) continue;
+   row = i;
+   break;
+ }
+ if(bchange) ChangeBuffer(BuffLen,bsens);
+ return row;
+}
+
+/////////////////////////////////////////////////
+void FitsABTColRead::printerror(int sta) const
+{
+ int stat = sta;
+ fits_report_error(stdout,stat);
+ fflush(stdout);
+ return;
+}
+
+/*! Print on stream os */
+void FitsABTColRead::Print(ostream& os,int lp) const
+{
+ os<<"FitsABTColRead:Print ("<<BuffLen<<","<<BuffSens<<","<<NulVal<<")"
+   <<" ncols="<<NBcol<<" nrows="<<NBline;
+ if(lp>0) os<<" NRead="<<NFitsRead;
+ os<<"\n... "<<FitsFN<<"["<<IHdu<<"/"<<NHdu<<"]"
+   <<"\n... Label["<<ColNum<<"]="<<ColLabel
+   <<" TypeCode="<<ColTypeCode
+   <<" TUnit="<<ColTUnit<<" TForm="<<ColTForm
+   <<endl;
+}
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/fabtcolread.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/fabtcolread.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/fabtcolread.h	(revision 2309)
@@ -0,0 +1,115 @@
+/* Interface Fits BINARY/ASCII Table Column Reader    cmv 26/09/2001 */
+#ifndef FABTCOLREAD_H_SEEN
+#define FABTCOLREAD_H_SEEN
+
+#include "machdefs.h"
+#include <iostream.h>
+#include <string.h>
+#include <string>
+
+#include "anydataobj.h"
+#include "tvector.h"
+#include "FitsIO/fitsio.h"
+
+namespace SOPHYA {
+
+//! Class for reading a column in a FITS ASCII or BINARY table
+class FitsABTColRead : public AnyDataObj {
+public:
+  FitsABTColRead(string fname,string collabel,int ihdu=0
+                ,long blen=100,long bsens=1,int lp=0);
+  FitsABTColRead(string fname,int colnum,int ihdu=0
+                ,long blen=100,long bsens=1,int lp=0);
+  FitsABTColRead(const char *cfname,const char *collabel,int ihdu=0
+                ,long blen=100,long bsens=1,int lp=0);
+  FitsABTColRead(const char *cfname,int colnum,int ihdu=0
+                ,long blen=100,long bsens=1,int lp=0);
+  FitsABTColRead(FitsABTColRead& fbt);
+  virtual ~FitsABTColRead();
+
+  void ChangeBuffer(long blen=100,long bsens=1);
+
+  double ReadKey(char *keyname);
+
+  double Read(long n,bool usebuffer=true);
+
+  long   Read(long n1,long n2,TVector<uint_2>& data);
+  long   Read(long n1,long n2,TVector<int_4>& data);
+  long   Read(long n1,long n2,TVector<int_8>& data);
+  long   Read(long n1,long n2,TVector<float>& data);
+  long   Read(long n1,long n2,TVector<double>& data);
+
+  //! return the value of the first row
+  double ReadFirstRow(bool usebuffer=false)
+                     {return Read(0,usebuffer);}
+  //! return the value of the last row
+  double ReadLastRow(bool usebuffer=false)
+                    {return Read(NBline-1,usebuffer);}
+
+  long FirstRow(double val1,double val2,long rowstart=-1);
+  long LastRow(double val1,double val2,long rowstart=-1);
+
+  //! Set debug level
+  inline void    SetDebug(int lp=0) {DbgLevel = (unsigned short) lp;}
+  //! Set null value to be return when reading null data (0=return the data)
+  inline void    SetNulVal(double nulval=0.) {NulVal = nulval;}
+  //! Get the FITS file name
+  inline string  GetFileName(void) {return FitsFN;}
+  //! Get the FITS file pointer (cfistio pointer)
+  inline fitsfile* GetFitsPointer(void) {return FitsPtr;}
+  //! Get the number of HDU in the FITS file
+  inline int     GetNHDU(void) {return NHdu;}
+  //! Get the number of the HDU read
+  inline int     GetHDU(void) {return IHdu;}
+  //! Get the HDU type
+  inline int     GetHDUType(void) {return HduType;}
+  //! Get the number of rows in the FITS HDU to be read
+  inline long    GetNbLine(void) {return NBline;}
+  //! Get the number of columns in the FITS HDU to be read
+  inline int     GetNbCol(void) {return NBcol;}
+  //! Get the columns number that is read
+  inline int     GetColNum(void) {return ColNum;}
+  //! Get the columns label that is read
+  inline string  GetColLabel(void) {return ColLabel;}
+  //! Get the columns type code that is read
+  inline int     GetColTypeCode(void) {return ColTypeCode;}
+  //! Get the columns fits tunit that is read
+  inline string  GetColTUnit(void) {return ColTUnit;}
+  //! Get the columns fits tform that is read
+  inline string  GetColTForm(void) {return ColTForm;}
+  //! Get the read requested buffer length
+  inline long    GetBLen(void) {return BuffLen;}
+  //! Get the read buffer direction
+  inline long    GetBSens(void) {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 read effective buffer length
+  inline long    GetNBuffer(void) {return NBuffer;}
+  //! Get the read bufferpointer
+  inline double* GetBuffer(void) {return Buffer;}
+
+protected:
+  void Init(const char *cfname,const char *collabel,int colnum
+           ,int ihdu,long blen,long bsens,int lp);
+  void Delete(void);
+  void printerror(int sta) const;
+
+  string FitsFN,ColLabel,ColTUnit,ColTForm;
+  int ColNum,ColTypeCode,IHdu,NHdu,HduType,NBcol;
+  long NBline;
+
+  double NulVal;
+  unsigned short DbgLevel;
+  long BuffLen, BuffSens;
+
+  unsigned long NFitsRead;
+  fitsfile *FitsPtr;
+  long LineDeb, LineFin;
+  double *Buffer;
+  long NBuffer;
+};
+
+} // namespace SOPHYA
+#endif    /* FABTCOLREAD_H_SEEN */
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/fabtwriter.cc
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/fabtwriter.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/fabtwriter.cc	(revision 2309)
@@ -0,0 +1,507 @@
+/* Writer de table Fits (binaire ou ASCII) */
+#include "machdefs.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include "pexceptions.h"
+#include "fabtwriter.h"
+
+/*!
+  \class SOPHYA::FitsABTWriter
+  \ingroup FitsIOServer
+  Class for writing a FITS ASCII or BINARY table
+  \verbatim
+  //-----------------------------------------------------------
+  -- Exemple 1: Writing element by element
+  FitsABTWriter fbtw(fitswrit,BINARY_TBL);
+  fbtw.SetExtName("MY_OWN_EXTENSION");
+  fbtw.AddCol("vars",NULL,"km",TSHORT);       // col=0
+  fbtw.AddCol("vars2",NULL,"km",TSHORT);      // col=1
+  fbtw.AddCol("varl",NULL,"Degre",TLONG);     // col=2
+  fbtw.AddCol("varf",NULL,"",TFLOAT);         // col=3
+  fbtw.AddCol("vard","","arcmin",TDOUBLE);    // col=4
+  fbtw.SetDebug(3);
+  for(long i=0;i<1000;i++) {
+    double x = i;
+    fbtw.Write(0,i,1000.*x); // if overflow, managed by cfitsio
+                             // Write(int,long,double) is called
+    fbtw.Write(1,i,(short)(1000.*x));
+                             // if overflow, managed by language
+                             // Write(int,long,short) is called
+    fbtw.Write(2,i,x);
+    fbtw.Write(3,i,x);
+    fbtw.Write(4,i,x);
+  }
+  cout<<"Number of Overflows when writing: "
+      <<fbtw.GetNOverFlow()<<endl;
+
+  //-----------------------------------------------------------
+  -- Exemple 2: Writing into TVector
+  ...
+  TVector<double> datad(100);
+  TVector<float>  dataf(100);
+  TVector<int_4>  datal(100);
+  for(long i=0;i<9990;i+=100) {
+    long i2=i+100-1; if(i2>=9990) i2=9990-1;
+    for(long j=0;j<100;j++) datad(i) =  ...;
+    for(long j=0;j<100;j++) dataf(i) =  ...;
+    for(long j=0;j<100;j++) datal(i) =  ...;
+    fbtw.Write(1,i,datal);
+    fbtw.Write(2,i,dataf);
+    fbtw.Write(3,i,datad);
+  }
+  \endverbatim
+*/
+
+//////////////////////////////////////////////////////////////
+/*!
+  Constructor.
+  \param fname : FITS file name to be written
+  \param hdutype : type of extension to be created (BINARY_TBL or ASCII_TBL)
+  \param lp : debug level
+*/
+FitsABTWriter::FitsABTWriter(string fname,int hdutype,int lp)
+{
+  createfits(fname.c_str(),hdutype,lp);
+}
+
+/*! See FitsABTWriter() */
+FitsABTWriter::FitsABTWriter(const char* cfname,int hdutype,int lp)
+{
+  createfits(cfname,hdutype,lp);
+}
+
+/*! See FitsABTWriter() */
+void FitsABTWriter::createfits(const char *cfname,int hdutype,int lp)
+{
+ FirstTime = true;
+ FitsPtr = NULL;
+ HduType = hdutype;
+ SetDebug(lp);
+ FitsFN = cfname;
+ NOverFlow = 0;
+
+ if(DbgLevel)
+   cout<<"FitsABTWriter::createfits FitsFN="<<FitsFN
+       <<" HduType="<<HduType<<endl;
+
+ if(FitsFN.size() <= 0 )
+   throw ParmError("FitsABTWriter::createfits: Fits file name error\n");
+
+ if(HduType!=BINARY_TBL && HduType!=ASCII_TBL)
+   throw TypeMismatchExc("FitsABTWriter::createfits: Only BINARY or ASCII table permitted\n");
+
+ // create new FITS file
+ int sta=0;
+ if(fits_create_file(&FitsPtr,FitsFN.c_str(),&sta)) {
+   printerror(sta);
+   throw NullPtrError("FitsABTWriter::createfits: Error creating Fits file\n");
+ }
+
+ // create d'un Primary HDU
+ //long naxes[1] = {0};
+ //if(fits_create_img(FitsPtr,BYTE_IMG,0,naxes,&sta)) {
+ //  printerror(sta);
+ //  throw NullPtrError("FitsABTWriter::createfits: Error creating Primary extension\n");
+ //}
+
+}
+
+/*! Destructor */
+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);
+}
+
+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);
+   }
+ DoubleKey.resize(0);
+ LongKey.resize(0);
+}
+
+//////////////////////////////////////////////////////////////
+/*!
+  Add a new column to the FITS table
+  \param label : column label
+  \param tform : fits tform definition ("1I","1J","1E","1J",...)
+         (can be automatically set as "datatype"
+          if BINARY_TBL and tform="" or tform=NULL)
+  \param tunit : fits tunit definition (optional)
+  \param datatype : TBYTE TSHORT TLONG (TINT32BIT) TLONGLONG TFLOAT TDOUBLE
+                    TUSHORT TULONG. That parameter is only use in case
+                    of a BINARY_TBL table when tform is not defined).
+  \return The number of the new added column in the table.
+  \warning col = [0,ncol-1]
+*/
+int FitsABTWriter::addcol(const char* label,const char* tform
+                         ,const char* tunit,int datatype)
+{
+  if(!FirstTime)
+    throw AllocationError("FitsABTWriter::addcol: table already created\n");
+ 
+ // Gestion auto du tform pour les tables binaires avec le datatype (si non-definie)
+ bool tformauto = false;
+ if(HduType==BINARY_TBL || HduType==ASCII_TBL) {
+   if(tform==NULL)           tformauto = true;
+   else if(strlen(tform)<=0) tformauto = true;
+ }
+ if(tformauto && HduType==BINARY_TBL) {
+   char str[8];
+   if(datatype==TBYTE)          strcpy(str,"1B");
+   else if(datatype==TSHORT)    strcpy(str,"1I");
+   else if(datatype==TLONG)     strcpy(str,"1J");
+#ifdef TINT32BIT
+   else if(datatype==TINT32BIT) strcpy(str,"1J");
+#endif
+#ifdef TLONGLONG
+   else if(datatype==TLONGLONG) strcpy(str,"1K");
+#endif
+   else if(datatype==TFLOAT)    strcpy(str,"1E");
+   else if(datatype==TDOUBLE)   strcpy(str,"1D");
+   else if(datatype==TUSHORT)   strcpy(str,"1U");
+   else if(datatype==TULONG)    strcpy(str,"1V");
+   else
+     throw ParmError("FitsABTWriter::addcol: datatype not allowed\n");
+   TForm.push_back(str);
+ } else if(tformauto && HduType==ASCII_TBL) {
+   char str[8];
+   if(datatype==TBYTE)          strcpy(str,"I5");
+   else if(datatype==TSHORT)    strcpy(str,"I7");
+   else if(datatype==TLONG)     strcpy(str,"I11");
+#ifdef TINT32BIT
+   else if(datatype==TINT32BIT) strcpy(str,"I11");
+#endif
+#ifdef TLONGLONG
+   else if(datatype==TLONGLONG) strcpy(str,"I21");
+#endif
+   else if(datatype==TFLOAT)    strcpy(str,"E29.20");
+   else if(datatype==TDOUBLE)   strcpy(str,"E29.20");
+   else if(datatype==TUSHORT)   strcpy(str,"I7");
+   else if(datatype==TULONG)    strcpy(str,"I11");
+   else
+     throw ParmError("FitsABTWriter::addcol: datatype not allowed\n");
+   TForm.push_back(str);
+ } else {
+   if(tform) TForm.push_back(tform); else TForm.push_back("");
+   datatype = 0;
+ }
+ Label.push_back(label);
+ if(tunit) TUnit.push_back(tunit); else TUnit.push_back("");
+
+ int n = (int) Label.size() -1;
+
+ if(DbgLevel)
+   cout<<"FitsABTWriter::addcol["<<n<<"] Label="<<Label[n]
+       <<" TForm="<<TForm[n]
+       <<" TUnit="<<TUnit[n]
+       <<" datatype="<<datatype<<endl;
+
+ return n;
+}
+
+/*! Create the table. Done at the first write request. */
+void FitsABTWriter::createtbl(void)
+{
+  if(!FirstTime) return;
+
+ int tfields = Label.size();
+ if(tfields<=0)
+   throw ParmError("FitsABTWriter::createtbl: Zero column asked !\n");
+
+ long nrows = 0;
+ char *extname = NULL;
+ char **ttype   = (char **) malloc(tfields*sizeof(char *));
+ char **tform   = (char **) malloc(tfields*sizeof(char *));
+ char **tunit   = (char **) malloc(tfields*sizeof(char *));
+
+ if(ExtName.size()>0) {
+   extname = (char *) malloc((strlen(ExtName.c_str())+1)*sizeof(char));
+   strcpy(extname,ExtName.c_str());
+ }
+ int i;
+ for(i=0;i<tfields;i++) {
+   ttype[i] = (char *) malloc((strlen(Label[i].c_str())+1)*sizeof(char));
+     strcpy(ttype[i],Label[i].c_str());
+   tform[i] = (char *) malloc((strlen(TForm[i].c_str())+1)*sizeof(char));
+     strcpy(tform[i],TForm[i].c_str());
+   tunit[i] = (char *) malloc((strlen(TUnit[i].c_str())+1)*sizeof(char));
+     strcpy(tunit[i],TUnit[i].c_str());
+ }
+
+ // append a new empty binary/ascii table onto the FITS file
+ int sta=0;
+ if(fits_create_tbl(FitsPtr,HduType,nrows,tfields,ttype,tform,tunit,extname,&sta)) {
+   printerror(sta);
+   throw NullPtrError("FitsABTWriter::createtbl: Error creating Table extension\n");
+ }
+
+ // Append Fits key
+ writekeys();
+
+ // menage
+ if(extname) delete [] extname;
+ for(i=0;i<tfields;i++) {
+   if(ttype[i]) delete [] ttype[i];
+   if(tform[i]) delete [] tform[i];
+   if(tunit[i]) delete [] tunit[i];
+ }
+ if(ttype) delete [] ttype;
+ if(tform) delete [] tform;
+ if(tunit) delete [] tunit;
+
+ FirstTime = false;
+}
+
+//////////////////////////////////////////////////////////////
+/*!
+  Write a data to FITS file.
+  \param col : column number [0,ncol[
+  \param row : row number    [0,nrow[
+  \param val : value to be written
+  \warning that routine write a SHORT value into column "col"
+           which could have been defined with an other type.
+           Cast is performed by the cfitsio package.
+  \verbatim
+  WARNING: suppose that the column has be defined to be TSHORT
+           and suppose that you wanted to write a double value "val"
+   - If you write dummy.Write(col,row,(short)(val))
+       the Write(int,long,short) routine is called and
+       the cast is performed by the C++ language.
+   - If you write dummy.Write(col,row,val) where val is double
+       the Write(int,long,double) routine is called and
+       the cast is performed by the cfistio package.
+  \endverbatim
+*/
+
+/*! Write unsigned char (1 Byte) data to FITS file (see below) */
+void FitsABTWriter::Write(int col,long row,uint_1 val)
+{
+  if(FirstTime) createtbl();
+  int sta=0;
+  if(fits_write_col(FitsPtr,TBYTE,col+1,row+1,1,1,&val,&sta))
+    printerrorwrite("unsigned char",col,row,sta);
+}
+
+/*! Write short (2 Bytes) data to FITS file (see below) */
+void FitsABTWriter::Write(int col,long row,int_2 val)
+{
+  if(FirstTime) createtbl();
+  int sta=0;
+  if(fits_write_col(FitsPtr,TSHORT,col+1,row+1,1,1,&val,&sta))
+    printerrorwrite("short",col,row,sta);
+}
+
+/*! Write unsigned short (2 Bytes) data to FITS file (see below) */
+void FitsABTWriter::Write(int col,long row,uint_2 val)
+{
+  if(FirstTime) createtbl();
+  int sta=0;
+  if(fits_write_col(FitsPtr,TUSHORT,col+1,row+1,1,1,&val,&sta))
+    printerrorwrite("unsigned short",col,row,sta);
+}
+
+/*! Write long (4 Bytes) data to FITS file (see below) */
+void FitsABTWriter::Write(int col,long row,int_4 val)
+{
+  if(FirstTime) createtbl();
+  int sta=0;
+  // Bug ou inconsistence cfitsio sur machine ou long=8Bytes ?
+  int T = (sizeof(long)==4) ? TLONG: TINT;
+  if(fits_write_col(FitsPtr,T,col+1,row+1,1,1,&val,&sta))
+    printerrorwrite("long",col,row,sta);
+}
+
+/*! Write unsigned long (4 Bytes) data to FITS file (see below) */
+void FitsABTWriter::Write(int col,long row,uint_4 val)
+{
+  if(FirstTime) createtbl();
+  int sta=0;
+  // Bug ou inconsistence cfitsio sur machine ou long=8Bytes ?
+  int T = (sizeof(unsigned long)==4) ? TULONG: TUINT;
+  if(fits_write_col(FitsPtr,T,col+1,row+1,1,1,&val,&sta))
+    printerrorwrite("long",col,row,sta);
+}
+
+/*! Write long long (8 Bytes) data to FITS file (see below) */
+void FitsABTWriter::Write(int col,long row,int_8 val)
+{
+#ifdef TLONGLONG
+  if(FirstTime) createtbl();
+  int sta=0;
+  if(fits_write_col(FitsPtr,TLONGLONG,col+1,row+1,1,1,&val,&sta))
+    printerrorwrite("long long",col,row,sta);
+#else
+  throw PException("FitsABTWriter::Write(..,int_8) Not in that cfitsio version");
+#endif
+}
+
+/*! Write float data to FITS file (see below) */
+void FitsABTWriter::Write(int col,long row,float val)
+{
+  if(FirstTime) createtbl();
+  int sta=0;
+  if(fits_write_col(FitsPtr,TFLOAT,col+1,row+1,1,1,&val,&sta))
+    printerrorwrite("float",col,row,sta);
+}
+
+/*! Write double data to FITS file (see below) */
+void FitsABTWriter::Write(int col,long row,double val)
+{
+  if(FirstTime) createtbl();
+  int sta=0;
+  if(fits_write_col(FitsPtr,TDOUBLE,col+1,row+1,1,1,&val,&sta))
+    printerrorwrite("double",col,row,sta);
+}
+
+//////////////////////////////////////////////////////////////
+/*!
+  Write a vector of data to FITS file.
+  \param col : column number [0,ncol[
+  \param row : starting row number    [0,nrow[
+  \param val : vector to be written
+  \return "N" = number of the next row to be written,
+      that is "N-1" is the number of the last row written.
+*/
+
+/*! Write a vector of unsigned short (2 Bytes) data to FITS file (see below) */
+long FitsABTWriter::Write(int col,long row,TVector<uint_2>& val)
+{
+  if(FirstTime) createtbl();
+  long nel = val.Size();
+  int sta=0;
+  if(fits_write_col(FitsPtr,TUSHORT,col+1,row+1,1,nel,val.Data(),&sta))
+    printerrorwrite("long",col,row,sta);
+  return row+nel;
+}
+
+/*! Write a vector of long (4 Bytes) data to FITS file (see below) */
+long FitsABTWriter::Write(int col,long row,TVector<int_4>& val)
+{
+  if(FirstTime) createtbl();
+  long nel = val.Size();
+  int sta=0;
+  // Bug ou inconsistence cfitsio sur machine ou long=8Bytes ?
+  int T = (sizeof(long)==4) ? TLONG: TINT;
+  if(fits_write_col(FitsPtr,T,col+1,row+1,1,nel,val.Data(),&sta))
+    printerrorwrite("long",col,row,sta);
+  return row+nel;
+}
+
+/*! Write a vector of long long (8 Bytes) data to FITS file (see below) */
+long FitsABTWriter::Write(int col,long row,TVector<int_8>& val)
+{
+#ifdef TLONGLONG
+  if(FirstTime) createtbl();
+  long nel = val.Size();
+  int sta=0;
+  if(fits_write_col(FitsPtr,TLONGLONG,col+1,row+1,1,nel,val.Data(),&sta))
+    printerrorwrite("long long",col,row,sta);
+  return row+nel;
+#else
+  throw PException("FitsABTWriter::Write(..,TVector<int_8>&) Not in that cfitsio version");
+#endif
+}
+
+/*! Write a vector of float data to FITS file (see below) */
+long FitsABTWriter::Write(int col,long row,TVector<float>&  val)
+{
+  if(FirstTime) createtbl();
+  long nel = val.Size();
+  int sta=0;
+  if(fits_write_col(FitsPtr,TFLOAT,col+1,row+1,1,nel,val.Data(),&sta))
+    printerrorwrite("float",col,row,sta);
+  return row+nel;
+}
+
+/*! Write a vector of double data to FITS file (see below) */
+long FitsABTWriter::Write(int col,long row,TVector<double>& val)
+{
+  if(FirstTime) createtbl();
+  long nel = val.Size();
+  int sta=0;
+  if(fits_write_col(FitsPtr,TDOUBLE,col+1,row+1,1,nel,val.Data(),&sta))
+    printerrorwrite("double",col,row,sta);
+  return row+nel;
+}
+
+//////////////////////////////////////////////////////////////
+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
+{
+os<<"FitsABTWriter::Print: FitsFN "<<FitsFN<<endl
+  <<"                      HduType "<<HduType<<"  NOverFlow "<<NOverFlow
+  <<"  NCol "<<Label.size()<<endl;
+if(Label.size()>0 && lp>=1)
+  for(int i=0;i<(int)Label.size();i++)
+    os<<i<<"... Label="<<Label[i]<<" TForm="<<TForm[i]<<" TUnit="<<TUnit[i]<<endl;
+}
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/fabtwriter.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/fabtwriter.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/fabtwriter.h	(revision 2309)
@@ -0,0 +1,99 @@
+/* Interface Fits BINARY/ASCII Table Writer    cmv 26/09/2001 */
+#ifndef FABTWRITER_H_SEEN
+#define FABTWRITER_H_SEEN
+
+#include "machdefs.h"
+#include <iostream.h>
+#include <string.h>
+#include <string>
+
+#include "anydataobj.h"
+#include "tvector.h"
+#include "FitsIO/fitsio.h"
+
+#include <vector>
+
+namespace SOPHYA {
+
+//! Class for writing a FITS ASCII or BINARY table
+class FitsABTWriter : public AnyDataObj {
+public:
+  FitsABTWriter(string fname,int hdutype=BINARY_TBL,int lp=0);
+  FitsABTWriter(const char* cfname,int hdutype=BINARY_TBL,int lp=0);
+  virtual ~FitsABTWriter();
+
+  void Flush(void);
+
+  //! Write a double value in Fits header.
+  void WriteKey(const char *keyname,double val,char* comment=NULL);
+  //! Write a long value in Fits header.
+  void WriteKey(const char *keyname,long val,char* comment=NULL);
+
+  //! Add a new column to the FITS table and return its number (see addcol).
+  inline int AddCol(string label,string tform=string("")
+                   ,string tunit=string(""),int datatype=TDOUBLE)
+     {return addcol(label.c_str(),tform.c_str(),tunit.c_str(),datatype);}
+  //! Add a new column to the FITS table and return its number (see addcol).
+  inline int AddCol(const char* label,const char* tform=""
+                   ,const char* tunit="",int datatype=TDOUBLE)
+     {return addcol(label,tform,tunit,datatype);}
+
+  //! Set the FITS table extension name
+  inline void SetExtName(string extname=string("")) {ExtName = extname;}
+  //! Set the FITS table extension name
+  inline void SetExtName(char* extname="") {ExtName = extname;}
+  //! Set debug level
+  inline void SetDebug(int lp=0) {DbgLevel = (unsigned short) lp;}
+
+  void Write(int col,long row,uint_1 val);
+  void Write(int col,long row,int_2 val);
+  void Write(int col,long row,uint_2 val);
+  void Write(int col,long row,int_4 val);
+  void Write(int col,long row,uint_4 val);
+  void Write(int col,long row,int_8 val);
+  void Write(int col,long row,float val);
+  void Write(int col,long row,double val);
+  long Write(int col,long row,TVector<uint_2>& val);
+  long Write(int col,long row,TVector<int_4>& val);
+  long Write(int col,long row,TVector<int_8>& val);
+  long Write(int col,long row,TVector<float>& val);
+  long Write(int col,long row,TVector<double>& val);
+  //! Return the number of overflows managed by cfitsio
+  inline unsigned long GetNOverFlow(void) {return NOverFlow;}
+
+  //! Return the number of created columns
+  inline int GetNbCol(void) {return (int) Label.size();}
+
+  //! 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);}
+
+protected:
+  struct KeyDouble {string keyname; double val; string comment;};
+  struct KeyLong   {string keyname; long   val; string comment;};
+
+  void createfits(const char *cfname,int hdutype,int lp);
+  int addcol(const char* label,const char* tform
+            ,const char* tunit,int datatype);
+  void createtbl(void);
+  void writekeys(void);
+  void printerrorwrite(const char* type,int col,long row,int sta);
+  void printerror(int sta) const;
+
+  string FitsFN,ExtName;
+  int HduType;
+  unsigned short DbgLevel;
+  fitsfile *FitsPtr;
+  bool FirstTime;
+  vector<string> Label;
+  vector<string> TForm;
+  vector<string> TUnit;
+  unsigned long NOverFlow;
+
+  vector<struct KeyDouble> DoubleKey;
+  vector<struct KeyLong>   LongKey;
+};
+
+} // namespace SOPHYA
+#endif    /* FABTWRITER_H_SEEN */
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/fboloread.cc
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/fboloread.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/fboloread.cc	(revision 2309)
@@ -0,0 +1,246 @@
+/* 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]; mFABT[col]=NULL;}
+ } 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();
+   return;
+ }
+
+ // 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: /tags/V_Dec2002/SophyaExt/FitsIOServer/fboloread.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/fboloread.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/fboloread.h	(revision 2309)
@@ -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 */
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/fbtntintf.cc
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/fbtntintf.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/fbtntintf.cc	(revision 2309)
@@ -0,0 +1,298 @@
+/* Interface Fits BINARY/ASCII Table     cmv 21/05/2001 */
+#include "machdefs.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include "pexceptions.h"
+#include "fbtntintf.h"
+
+//////////////////////////////////////////////////////////////
+FitsBTNtuIntf::FitsBTNtuIntf(string fname,int ihdu
+               ,int_4 blen,int_4 bsens,uint_2 lp)
+{
+ DbgLevel = lp;
+ SetNulVal();
+ SetBuffer(blen,bsens);
+ FitsFN = fname;
+ IHdu = ihdu;
+ Init();
+}
+
+FitsBTNtuIntf::FitsBTNtuIntf(char * cfname,int ihdu
+               ,int_4 blen,int_4 bsens,uint_2 lp)
+{
+ DbgLevel = lp;
+ SetNulVal();
+ SetBuffer(blen,bsens);
+ FitsFN = cfname;
+ IHdu = ihdu;
+ Init();
+}
+
+FitsBTNtuIntf::FitsBTNtuIntf(FitsBTNtuIntf& fbtnt)
+{
+ DbgLevel = fbtnt.DbgLevel;
+ SetNulVal(fbtnt.NulVal);
+ SetBuffer(fbtnt.BuffLen,fbtnt.BuffSens);
+ FitsFN = fbtnt.FitsFN;
+ IHdu = fbtnt.IHdu;
+ Init();
+}
+
+FitsBTNtuIntf::FitsBTNtuIntf()
+{
+ DbgLevel = 0;
+ SetNulVal();
+ SetBuffer();
+ FitsFN = "";
+ IHdu = -1;
+ Init();
+}
+
+FitsBTNtuIntf::~FitsBTNtuIntf()
+{
+ Delete();
+}
+
+
+//////////////////////////////////////////////////////////////
+void FitsBTNtuIntf::ChangeBuffer(int_4 blen,int_4 bsens)
+{
+SetBuffer(blen,bsens);
+DeAllocBuff();
+AllocBuff();
+}
+
+void FitsBTNtuIntf::AllocBuff(void)
+{
+if(Buffer==NULL || NBcol<=0) return;
+int_4 n = BuffLen; if(BuffSens==0) n++;
+for(int icol=0;icol<NBcol;icol++)
+  if(ColReadable[icol]) Buffer[icol] = new double[n];
+    else Buffer[icol] = NULL;
+}
+
+void FitsBTNtuIntf::DeAllocBuff(void)
+{
+if(Buffer==NULL || NBcol<=0) return;
+for(int icol=0;icol<NBcol;icol++)
+  if(Buffer[icol]!=NULL) 
+    {delete [] Buffer[icol]; Buffer[icol] = NULL;}
+LineDeb = LineFin = -1;
+}
+
+void FitsBTNtuIntf::Delete()
+{
+ DeAllocBuff();
+ delete [] Buffer; Buffer=NULL;
+ if(mRet!=NULL) delete [] mRet;
+ if(ColReadable!=NULL) delete [] ColReadable;
+
+ int sta = 0;
+ if(fits_close_file(FitsPtr,&sta)) printerror(sta);
+ FitsPtr = NULL;
+}
+
+void FitsBTNtuIntf::Init()
+{
+ NBcol = 0; NBline = 0;
+ LineDeb = LineFin = -1;
+ ColName.resize(0);
+ ColReadable = NULL;
+ Buffer = NULL;
+ mRet = NULL;
+ NFitsRead = 0;
+
+ if(FitsFN.size() <= 0 ) {
+   FitsPtr = NULL;
+   IHdu = -1;
+   return;
+ }
+
+ //////////////////////////
+ // Ouverture du fichier //
+ //////////////////////////
+
+ int sta=0,nhdu,hdutype;
+ const char * cfitsfn = FitsFN.c_str();
+
+ // Open fits
+ if(fits_open_file(&FitsPtr,cfitsfn,READONLY,&sta)) printerror(sta);
+
+ // Get number of hdu
+ if(fits_get_num_hdus(FitsPtr,&nhdu,&sta)) printerror(sta);
+ if(DbgLevel) cout<<"FitsBTNtuIntf::Init  nhdu="<<nhdu<<endl;
+ if(nhdu<=0) {Delete(); return;}
+
+ // Get HDU for bin table
+ // si IHdu <=0 on cherche la 1ere bin 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)) printerror(sta);
+     if(DbgLevel) cout<<"...Init ihdu="
+                      <<ihdu<<" hdutype="<<hdutype<<endl;
+     if(hdutype==BINARY_TBL || hdutype==ASCII_TBL) {IHdu = ihdu; break;}
+   }
+ if(IHdu<=0 || IHdu>nhdu) {
+   cout<<"NO BINARY or ASCII hdu found"<<endl;
+   Delete();
+   return;
+ }
+ if(fits_movabs_hdu(FitsPtr,IHdu,&hdutype,&sta)) printerror(sta);
+ if(hdutype!=BINARY_TBL && hdutype!=ASCII_TBL) {Delete(); return;}
+
+ // Get number of columns
+ if(fits_get_num_cols(FitsPtr,&NBcol,&sta)) printerror(sta);
+ if(DbgLevel) cout<<"...Init  NBcol="<<NBcol<<endl;
+ if(NBcol<1) {Delete(); return;}
+ mRet = new double[NBcol];
+ ColReadable = new bool[NBcol];
+ Buffer = new double*[NBcol];
+ int icol;
+ for(icol=0;icol<NBcol;icol++)
+   {Buffer[icol]=NULL; ColReadable[icol]=false;}
+
+ // Get number of rows
+ if(fits_get_num_rows(FitsPtr,&NBline,&sta)) printerror(sta);
+ if(DbgLevel) cout<<"...Init  NBline="<<NBline<<endl;
+ if(NBline<1) {Delete(); return;}
+
+ // Get column infos
+ for(icol=0;icol<NBcol;icol++) {
+   int colnum,typecode;
+   char templt[16], colname[256];
+   sprintf(templt,"%d",icol+1);
+   if(fits_get_colname(FitsPtr,CASESEN,templt,colname,&colnum,&sta))
+     printerror(sta);
+   ColName.push_back(colname);
+   if(fits_get_coltype(FitsPtr,icol+1,&typecode,NULL,NULL,&sta))
+     printerror(sta);
+   if(typecode!=TSTRING && typecode!=TCOMPLEX &&  typecode!=TDBLCOMPLEX)
+        ColReadable[icol] = true;
+   if(DbgLevel)
+     cout<<"...Init col="<<icol+1
+	 <<" name="<<ColName[icol]
+         <<" typecode="<<typecode<<" (readable="
+         <<ColReadable[icol]<<")"<<endl;
+ }
+ // Prepare buffer
+ AllocBuff();
+
+}
+
+/////////////////////////////////////////////////
+uint_4 FitsBTNtuIntf::NbLines() const
+{
+ return NBline;
+}
+
+uint_4 FitsBTNtuIntf::NbColumns() const
+{
+ return NBcol;
+}
+
+r_8 * FitsBTNtuIntf::GetLineD(int n) const
+// Attention: n [0,NBline[, cfistio veut [1,NBline]
+{
+ int sta=0,anynul;
+ if(n<0 || n>=NBline) return NULL;
+
+ // Pas de bufferisation, on lit betement
+ if(BuffLen==1) {
+   NFitsRead++;
+   for(int icol=0;icol<NBcol;icol++) {
+     mRet[icol] = 0.;
+     if(!ColReadable[icol]) continue;
+     fits_read_col_dbl(FitsPtr,icol+1,n+1,1,1,NulVal,&mRet[icol],&anynul,&sta);
+     if(sta) printerror(sta);
+   }
+   return mRet;
+ }
+
+ // Gestion avec bufferisation
+ if(!Buffer) {
+   cout<<"FitsBTNtuIntf::GetLineD Buffer not allocated"<<endl;
+   return NULL;
+ }
+ if(n<LineDeb || n>LineFin) {
+   NFitsRead++;
+   long row1,row2,nrow;
+   if(BuffSens>0) { // Cas remplissage forward
+     row1 = n+1;
+     row2 = row1+BuffLen-1; if(row2>NBline) row2 = NBline;
+   } else if(BuffSens<0) { // Cas remplissage backward
+     row2 = n+1;
+     row1 = row2-BuffLen+1; if(row1<1) row1 = 1;
+   } else { // Cas remplissage centre
+     row1 = n+1 - BuffLen/2; if(row1<1) row1 = 1;
+     row2 = n+1 + BuffLen/2; if(row2>NBline) row2 = NBline;
+   }
+   nrow = row2 - row1 + 1;
+   LineDeb = row1-1; LineFin = row2-1;
+   //cout<<"DBG-FitsRead: row1="<<row1<<" row2="<<row2<<" nrow="<<nrow
+   //    <<" LineDeb,Fin="<<LineDeb<<","<<LineFin<<endl;
+   for(int icol=0;icol<NBcol;icol++) {
+     if(!ColReadable[icol]) continue;
+     fits_read_col_dbl(FitsPtr,icol+1,row1,1,nrow,NulVal,Buffer[icol],&anynul,&sta);
+     if(sta) printerror(sta);
+   }
+ }
+
+ int_4 ibuf = n-LineDeb;
+ for(int icol=0;icol<NBcol;icol++)
+   if(ColReadable[icol]) mRet[icol] = (Buffer[icol])[ibuf];
+     else mRet[icol] = 0.;
+
+ return mRet;
+}
+
+r_8 FitsBTNtuIntf::GetCell(int n, int k) const
+{
+ if(n<0 || n>=NBline || k<0 || k>=NBcol) return 0.;
+ r_8 * r = GetLineD(n);
+ return r[k];
+}
+
+/*!
+  Retourne une chaine de caracteres avec la declaration des noms de 
+  variables. si "nomx!=NULL" , des instructions d'affectation
+  a partir d'un tableau "nomx[i]" sont ajoutees (pour interface NTuple).
+*/
+string FitsBTNtuIntf::VarList_C(const char* nomx) const
+{
+ string rets;
+ rets = "\ndouble";
+ int icol;
+ for(icol=0;icol<NBcol;icol++) {
+  rets += " " + ColName[icol];
+  if(icol!=NBcol-1) rets += ","; else rets += ";\n";
+ }
+ if(!nomx) return rets;
+ char buff[256];
+ for(icol=0;icol<NBcol;icol++) {
+   sprintf(buff," = %s[%d];\n",nomx,icol);
+   rets += ColName[icol] + buff;
+ }
+ return rets;
+}
+
+/////////////////////////////////////////////////
+void FitsBTNtuIntf::printerror(int sta) const
+{
+ int stat = sta;
+ fits_report_error(stdout,stat);
+ return;
+}
+
+void FitsBTNtuIntf::Print(ostream& os,int lp) const
+{
+ os<<"FitsBTNtuIntf:Print ("<<BuffLen<<","<<NulVal<<")"
+   <<" ncols="<<NBcol<<" nrows="<<NBline;
+ if(lp>0) os<<" fitsrd="<<NFitsRead<<"*ncols";
+ os<<"\n"<<FitsFN<<"["<<IHdu<<"]"<<endl;
+ if(NBcol<=0 || lp<1) return;
+ for(int icol=0;icol<NBcol;icol++) {
+   os<<" "<<ColName[icol]<<"("<<ColReadable[icol]<<")";
+   if(icol%4==3 || icol==NBcol-1) os<<endl;
+ }
+}
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/fbtntintf.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/fbtntintf.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/fbtntintf.h	(revision 2309)
@@ -0,0 +1,63 @@
+/* Interface Fits BINARY/ASCII Table     cmv 21/05/2001 */
+#ifndef FBTNTINTF_H_SEEN
+#define FBTNTINTF_H_SEEN
+
+#include "machdefs.h"
+#include <iostream.h>
+#include <string.h>
+#include <string>
+
+#include "anydataobj.h"
+#include "ntupintf.h"
+#include "FitsIO/fitsio.h"
+
+#include <vector>
+
+namespace SOPHYA {
+
+class FitsBTNtuIntf : public AnyDataObj, public NTupleInterface {
+public:
+  FitsBTNtuIntf(string fname,int ihdu=0,int_4 blen=100,int_4 bsens=1,uint_2 lp=0);
+  FitsBTNtuIntf(char *cfname,int ihdu=0,int_4 blen=100,int_4 bsens=1,uint_2 lp=0);
+  FitsBTNtuIntf(FitsBTNtuIntf& fbtnt);
+  FitsBTNtuIntf();
+  virtual ~FitsBTNtuIntf();
+
+  void SetNulVal(r_8 nulval=0.) {NulVal = nulval;}
+  void ChangeBuffer(int_4 blen,int_4 bsens=1);
+  virtual void Print(ostream& os,int lp=1) const;
+  inline  void Print(int lp=1) const {Print(cout,lp);}
+
+  virtual uint_4 NbLines() const ;
+  virtual uint_4 NbColumns() const ;
+  virtual r_8 * GetLineD(int n) const ;
+  virtual r_8 GetCell(int n, int k) const ;
+  virtual string VarList_C(const char* nomx=NULL) const ;
+
+protected:
+  inline void SetBuffer(int_4 blen=100,int_4 bsens=1)
+       {BuffLen = (blen<=0)?1:blen; BuffSens = bsens;}
+  void DeAllocBuff(void);
+  void AllocBuff(void);
+  void Init(void);
+  void Delete(void);
+  void printerror(int sta) const;
+
+  string FitsFN;
+  int IHdu;
+  uint_2 DbgLevel;
+  fitsfile *FitsPtr;
+  long NBline;
+  int  NBcol;
+  r_8 NulVal;
+  int_4 BuffLen, BuffSens;
+  mutable uint_4 NFitsRead;
+  mutable long LineDeb, LineFin;
+  vector<string> ColName;
+  bool* ColReadable;
+  double **Buffer;
+  mutable r_8 * mRet;
+};
+
+} // namespace SOPHYA
+#endif    /* FBTNTINTF_H_SEEN */
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsautoreader.cc
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsautoreader.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsautoreader.cc	(revision 2309)
@@ -0,0 +1,268 @@
+#include "pexceptions.h"
+#include "fitsautoreader.h"
+#include "dvlist.h"
+
+///////////////////////////////////////////////////////////////////////
+// ---- gestion de persistance I/O format fits--
+// objets
+////////////////////////////////////////////////////////////////////
+
+/*!
+  \class SOPHYA::FITS_AutoReader
+  \ingroup FitsIOServer
+  FITS reader with automatic mapping on SOPHYA objects.
+*/
+
+FITS_AutoReader::FITS_AutoReader() {InitNull();};
+FITS_AutoReader::FITS_AutoReader(const char inputfile[])
+{
+  InitNull();
+  inFits_  = new FitsInFile (inputfile);
+  filename_ = string(inputfile);
+}
+FITS_AutoReader::FITS_AutoReader(string const & inputfile)
+{
+  InitNull();
+  inFits_  = new FitsInFile (inputfile);
+  filename_ = inputfile;
+}
+FITS_AutoReader::~FITS_AutoReader()
+{
+  if (inFits_ != NULL) delete inFits_;
+  if (dobj_ != NULL) delete dobj_;
+}
+
+int FITS_AutoReader::NbBlocks()
+{
+  return inFits_->NbBlocks();
+}
+
+ // parametre toutCharger : uniquement pour les BINTABLE et s'il ne
+ // s'agit pas explicitement d'un objet SOPHYA, on charge toute la 
+ // table en memoire sous forme d'un xntuple si toutCharger= true.
+ // et si le nombre d'entrees est superieur a 1000.
+ // sinon (c-a-d : il ne s'agit pas d'un objet connu de SOPHYA
+ //                c'est une BINTABLE avec plus de 1000 entrees
+ //                totuCharger = false)
+ // on ouvre une FitsBTNtuIntf (lecture ulterieure, bufferisee, des valeurs)
+AnyDataObj* FITS_AutoReader::ReadObject(int hdunum, bool toutCharger) const
+{
+  if (hdunum<=0) 
+    {
+      throw PException(" FITS_AutoReader::ReadObject : hdu number must be positive");
+    }
+  inFits_->ReadHeader(hdunum);
+  if (inFits_->IsFitsEOF()) return NULL;
+  if (inFits_->IsFitsERROR())
+    {
+      throw IOExc("FITS_AutoReader::ReadObject: FITSIO error in reading");
+    }
+  DVList dvl=inFits_->DVListFromFits();
+  string nameObj = dvl.GetS("CONTENT");
+  //    cout << " SOPHYA object identified as: " << dvl.GetS("CONTENT") << endl;
+  if (nameObj == string("TArray") )
+    {
+      return newTArray();
+    }
+  else if  (nameObj == string("SphereHEALPix") )
+    {
+      return newSphereHEALPix();
+    }
+  else if  (nameObj == string("LocalMap") )
+    {
+      return newLocalMap();
+    }
+  else if  (nameObj == string("NTuple") )
+    {
+      return newNTuple();
+    }
+  else if  (nameObj == string("XNTuple") )
+    {
+      return newXNTuple();
+    }
+  // on n'a trouve aucun nom d'objet connu de SOPHYA, on fait une 
+  // recherche qualitative.
+  //
+  // si c'est une image fits, on cree un TArray
+  else if (inFits_->IsFitsImage())
+    {
+      return newTArray();
+    }
+  // si c'est une bintable on cherche le mot cle ORDERING pour identifier 
+  // une spherehealpix
+  else if (inFits_->IsFitsTable())
+    {
+      if (dvl.GetS("ORDERING") != string("")) return newSphereHEALPix();
+      // sinon on cherche ntuple ou xntuple
+      else
+	{
+	  int index=0;
+          int k;
+	  for (k=0; k < inFits_->NbColsFromFits(); k++) 
+	    {
+	      if (inFits_->ColTypeFromFits(k) != FitsFile::FitsDataType_float)
+		{
+		index = 1;
+		break;
+	      }
+	  }
+	if (index == 0)  return newNTuple();
+	else 
+	  {
+	    if (!toutCharger ) 
+	      {
+		int maxEntries=0;
+                int k;
+		for ( k=0; k < inFits_->NbColsFromFits(); k++) 
+		  {
+		    if (inFits_->NentriesFromFits(k) > maxEntries ) maxEntries =  inFits_->NentriesFromFits(k); 
+		  }
+		if ( maxEntries > 1000) return newFitsBTNtuIntf(hdunum);
+		else return newXNTuple();
+	      }
+	    else  return newXNTuple();
+
+	  }
+      }
+    }
+  else
+    {
+      cout << " WARNING ( FITS_AutoReader::ReadObject) : object not recognized as a  SOPHYA object" << endl;
+      return new DVList(dvl);
+    }
+  
+}
+
+AnyDataObj*  FITS_AutoReader::newTArray() const
+{
+      FitsFile::FitsDataType dtype = inFits_->ImageType();
+      switch (dtype)
+	{
+	case FitsFile::FitsDataType_double :
+	  {
+	    TArray<r_8>* matptr = new TArray<r_8>;
+	    FITS_TArray<r_8> fta(matptr);
+	    fta.Read(*inFits_, inFits_->currentHeaderIndex());
+	    return matptr;
+	  }
+	case FitsFile::FitsDataType_float :
+	  {
+	    TArray<r_4>* matptr = new TArray<r_4>;
+	    FITS_TArray<r_4> fta(matptr);
+	    fta.Read(*inFits_,  inFits_->currentHeaderIndex());
+	    return matptr;
+	  }
+	case  FitsFile::FitsDataType_int :
+	  {
+	    TArray<int_4>* matptr = new TArray<int_4>;
+	    FITS_TArray<int_4> fta(matptr);
+	    fta.Read(*inFits_,  inFits_->currentHeaderIndex());
+	    return matptr;
+	  }
+	default :
+	  cout << "type = " << (int) dtype << endl;
+	  throw IOExc("FITS_AutoReader::ReadObject : unsupported data type for TArray");
+	}
+}
+
+AnyDataObj*  FITS_AutoReader::newSphereHEALPix() const
+{
+      FitsFile::FitsDataType dtype;
+      if (inFits_->IsFitsTable()) dtype = inFits_->ColTypeFromFits(0);
+      else
+	{
+	  cout << " WARNING : Sperehealpix not binary table : unusual " << endl;
+	  dtype = inFits_->ImageType();
+	}
+      switch (dtype)
+	{
+	case FitsFile::FitsDataType_double :
+	  {
+	    SphereHEALPix<r_8>* sphptr = new SphereHEALPix<r_8>;
+	    FITS_SphereHEALPix<r_8> fta(sphptr);
+	    fta.Read(*inFits_,  inFits_->currentHeaderIndex());
+	    return sphptr;
+	  }
+	case FitsFile::FitsDataType_float :
+	  {
+	    SphereHEALPix<r_4>* sphptr = new SphereHEALPix<r_4>;
+	    FITS_SphereHEALPix<r_4> fta(sphptr);
+	    fta.Read(*inFits_,  inFits_->currentHeaderIndex());
+	    return sphptr;
+	  }
+        //CMV: Bon c'est quand meme sympa de pouvoir re-lire ce
+	// qu'on a ecrit !! Je fais cette modif mais a priori
+	// ce n'est que du sparadra car ca devrait planter
+	// sur certaines machines (int!=long).
+	case  FitsFile::FitsDataType_int :
+	case  FitsFile::FitsDataType_long :
+	  {
+	    SphereHEALPix<int_4>* sphptr = new SphereHEALPix<int_4>;
+	    FITS_SphereHEALPix<int_4> fta(sphptr);
+	    fta.Read(*inFits_,  inFits_->currentHeaderIndex());
+	    return sphptr;
+	  }
+	default :
+	  cout << "type = " << (int) dtype << endl;
+	  throw IOExc("FITS_AutoReader::ReadObject : unsupported data type for SphereHEALpix");
+	}
+}
+
+AnyDataObj*  FITS_AutoReader::newLocalMap() const
+{
+      FitsFile::FitsDataType dtype;
+      if (inFits_->IsFitsTable()) dtype = inFits_->ColTypeFromFits(0);
+      else
+	{
+	  cout << " WARNING : Localmap not binary table : unusual " << endl;
+	  dtype = inFits_->ImageType();
+	}
+      switch (dtype)
+	{
+	case FitsFile::FitsDataType_double :
+	  {
+	    LocalMap<r_8>* locmptr = new LocalMap<r_8>;
+	    FITS_LocalMap<r_8> fta(locmptr);
+	    fta.Read(*inFits_,  inFits_->currentHeaderIndex());
+	    return locmptr;
+	  }
+	case FitsFile::FitsDataType_float :
+	  {
+	    LocalMap<r_4>* locmptr = new LocalMap<r_4>;
+	    FITS_LocalMap<r_4> fta(locmptr);
+	    fta.Read(*inFits_,  inFits_->currentHeaderIndex());
+	    return locmptr;
+	  }
+	case  FitsFile::FitsDataType_int :
+	  {
+	    LocalMap<int_4>* locmptr = new LocalMap<int_4>;
+	    FITS_LocalMap<int_4> fta(locmptr);
+	    fta.Read(*inFits_,  inFits_->currentHeaderIndex());
+	    return locmptr;
+	  }
+	default :
+	  cout << "type = " << (int) dtype << endl;
+	  throw IOExc("FITS_AutoReader::ReadObject : unsupported data type for LocalMap");
+	}
+}
+NTuple* FITS_AutoReader::newNTuple() const
+{
+      NTuple* ntptr = new NTuple;
+      FITS_NTuple fta(ntptr);
+      fta.Read(*inFits_,  inFits_->currentHeaderIndex());
+      return ntptr;
+}
+XNTuple* FITS_AutoReader::newXNTuple() const
+{
+      XNTuple* xntptr = new XNTuple;
+      FITS_XNTuple fta(xntptr);
+      fta.Read(*inFits_,  inFits_->currentHeaderIndex());
+      return xntptr;
+}
+
+FitsBTNtuIntf* FITS_AutoReader::newFitsBTNtuIntf(int hdunum) const
+{
+      FitsBTNtuIntf* btnptr = new FitsBTNtuIntf(filename_,hdunum);
+      return btnptr;
+}
+
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsautoreader.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsautoreader.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsautoreader.h	(revision 2309)
@@ -0,0 +1,69 @@
+#ifndef FITSAUTOREADER_SEEN
+#define FITSAUTOREADER_SEEN
+
+
+// Guy Le Meur 11/2000
+
+#include "machdefs.h"
+#include "anydataobj.h"
+#include "fitsfile.h"
+#include "fitstarray.h"
+#include "fitsspherehealpix.h"
+#include "fitsntuple.h"
+#include "fitsxntuple.h"
+#include "fitslocalmap.h"
+#include "fbtntintf.h"
+
+namespace SOPHYA {
+///////////////////////////////////////////////////////////////////////
+// ------------- Classe pour la gestion de persistance I/O format fits--
+// des objets
+//////////////////////////////////////////////////////////////////////
+
+
+class FITS_AutoReader 
+{
+public:
+
+FITS_AutoReader();
+FITS_AutoReader(const char inputfile[]);
+FITS_AutoReader(string const & inputfile);
+virtual ~FITS_AutoReader();
+ int NbBlocks();
+
+ // parametre toutCharger : uniquement pour les BINTABLE et s'il ne
+ // s'agit pas explicitement d'un objet SOPHYA, on charge toute la 
+ // table en memoire sous forme d'un xntuple si toutCharger= true.
+ // et si le nombre d'entrees est superieur a 1000.
+ // sinon (c-a-d : il ne s'agit pas d'un objet connu de SOPHYA
+ //                c'est une BINTABLE avec plus de 1000 entrees
+ //                totuCharger = false)
+ // on ouvre une FitsBTNtuIntf (lecture ulterieure, bufferisee, des valeurs)
+AnyDataObj* ReadObject(int hdunum, bool toutCharger = false) const;
+
+
+private :
+
+AnyDataObj* newTArray() const;
+AnyDataObj* newSphereHEALPix() const;
+AnyDataObj* newLocalMap() const;
+NTuple* newNTuple() const;
+XNTuple* newXNTuple() const;
+ FitsBTNtuIntf* newFitsBTNtuIntf(int hdunum) const;
+inline void InitNull()
+   {
+     inFits_ = NULL;
+     dobj_ = NULL;
+     ownobj_ = false;
+   }
+
+
+ string filename_;
+FitsInFile* inFits_;
+AnyDataObj* dobj_;
+bool ownobj_;
+
+};
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsbntbllineRW.cc
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsbntbllineRW.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsbntbllineRW.cc	(revision 2309)
@@ -0,0 +1,172 @@
+#include "pexceptions.h"
+#include "fitsbntbllineRW.h"
+#include "utils.h"
+///////////////////////////////////////////////////////////
+//    
+//    
+///////////////////////////////////////////////////////////
+
+
+#define LONNOM 31 
+
+
+FITS_BntblLineReader::FITS_BntblLineReader()
+{
+  InitNull();
+}
+
+FITS_BntblLineReader::FITS_BntblLineReader(const char inputfile[],int hdunum) 
+                                                                 
+{
+  InitNull();
+  inFits_  = new FitsInFile (inputfile);
+  inFits_->ReadHeader(hdunum);
+
+  //  if (!fn->IsFitsTable())
+  if (!inFits_->IsFitsTable())
+    {
+      throw PException("FITS_BntblLineReader: the fits file seems not to be a bintable nor ASCII table");
+    }
+
+  //
+  int nbcols, nbentries;
+  //  nbcols = fn->NbColsFromFits();
+  nbcols = inFits_->NbColsFromFits();
+  nbentries = 0;
+  int k;
+  //  for (k=0; k<nbcols; k++) nbentries=max( nbentries, fn->NentriesFromFits(k) );
+  for (k=0; k<nbcols; k++) nbentries=max( nbentries, inFits_->NentriesFromFits(k) );
+
+  //
+  // pour mettre les colonnes dans l'ordre double, float, int, char :
+  // tableau de correspondance 
+  // DfitsCol(j)= numero dans le fichier fits de la  jeme variable double du 
+  // xntuple;
+  // FfitsCol(j)= numero dans le fichier fits de la  jeme variable float du 
+  // xntuple;
+  // etc.
+  vector<int> DfitsCol;
+  vector<int> FfitsCol;
+  vector<int> IfitsCol;
+  vector<int> SfitsCol;
+  vector<int> LfitsCol;
+  vector<int> BfitsCol;
+  for (k=0; k<nbcols;k++)
+    {
+       FitsFile::FitsDataType ss= inFits_->ColTypeFromFits(k);
+
+      if (ss == FitsFile::FitsDataType_double) DfitsCol.push_back(k);
+      else if (ss == FitsFile::FitsDataType_float) FfitsCol.push_back(k);
+      else if (ss == FitsFile::FitsDataType_int) IfitsCol.push_back(k);
+      else if (ss == FitsFile::FitsDataType_long) LfitsCol.push_back(k);
+      else if (ss == FitsFile::FitsDataType_byte) BfitsCol.push_back(k);
+      else if (ss == FitsFile::FitsDataType_char) SfitsCol.push_back(k);
+      else {
+	cout << " FITS_XNTuple: colonne fits " << k << " type= " << (int) ss << endl;
+	throw  IOExc("type de champ inconnu");
+      }
+    }
+  vector<string> ColN(nbcols);
+  int compt=0;
+  for (k=0; k<DfitsCol.size(); k++)
+    {
+      ColN[compt++] = inFits_->ColNameFromFits(DfitsCol[k]);
+    }
+  for (k=0; k<FfitsCol.size(); k++)
+    {
+      ColN[compt++] =  inFits_->ColNameFromFits(FfitsCol[k]);
+    }
+  for (k=0; k<IfitsCol.size(); k++)
+    {
+      ColN[compt++] =  inFits_->ColNameFromFits(IfitsCol[k]);
+    }
+  for (k=0; k<LfitsCol.size(); k++)
+    {
+      ColN[compt++] =  inFits_->ColNameFromFits(LfitsCol[k]);
+    }
+  for (k=0; k<BfitsCol.size(); k++)
+    {
+      ColN[compt++] =  inFits_->ColNameFromFits(BfitsCol[k]);
+    }
+  for (k=0; k<SfitsCol.size(); k++)
+    {
+      ColN[compt++] = inFits_->ColNameFromFits(SfitsCol[k]);
+    }
+
+  ligne_.setFormat(DfitsCol.size(), FfitsCol.size(), IfitsCol.size(), LfitsCol.size(), BfitsCol.size(),SfitsCol.size(),  ColN);
+}
+
+
+FITS_BntblLineReader::~FITS_BntblLineReader()
+{
+  if (inFits_ != NULL) delete inFits_;
+}
+
+BnTblLine& FITS_BntblLineReader::ReadNextLine()
+{
+  inFits_->GetBinTabLine(nextLineToBeRead_++, ligne_);
+  return ligne_;
+}
+
+
+
+
+FITS_BntblLineWriter::FITS_BntblLineWriter(char inputfile[],int dc, int fc,int ic, int lc, int bc, int cc,  vector<string> names,DVList* ptr_dvl,  FitsFile::WriteMode wrm)
+{
+  int k;
+  int nbcols = dc+fc+ic+cc+lc+bc;
+  if (nbcols !=  names.size())
+    {
+      cout << " WARNING: BnTblLineWriter:: length of vector of column names not equal to total number of columns" << endl;
+    }
+  InitNull();
+  outFits_  = new FitsOutFile (inputfile, wrm);
+  string types;
+  vector<int> StringSizes(cc);
+  for (k=0; k<dc;k++)
+    {
+      types+='D';
+    }
+  for (k=0; k<fc;k++)
+    {
+      types+='E';
+    }
+  for (k=0; k<ic;k++)
+    {
+      types+='J';
+    }
+  for (k=0; k<lc;k++)
+    {
+      types+='J';
+    }
+  for (k=0; k<bc;k++)
+    {
+      types+='B';
+    }
+  for (k=0; k<cc;k++)
+    {
+      types+='A';
+      StringSizes[k] = names[dc+fc+ic+lc+bc+k].length();
+    }            
+  string extname("Lines_on_Binary_tbl"); 
+
+  outFits_->makeHeaderBntblOnFits(types, names, 1, nbcols, ptr_dvl, extname,StringSizes); 
+    ligne_.setFormat(dc, fc, ic,lc,bc,cc, names);
+    
+}
+
+FITS_BntblLineWriter::~FITS_BntblLineWriter()
+{
+  //  if (dvl_ != NULL) delete dvl_;
+  if (outFits_ != NULL)  delete outFits_;
+}
+
+void FITS_BntblLineWriter::WriteNextLine( BnTblLine& WorkLine)
+{
+  if (! ligne_.sameFormat(WorkLine) )
+    {
+    	      throw PException("  FITS_BntblLineWriter:: line to be written does not match the header");
+    }
+  outFits_->PutBinTabLine(nextLineToBeWritten_++, WorkLine);
+
+}
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsbntbllineRW.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsbntbllineRW.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsbntbllineRW.h	(revision 2309)
@@ -0,0 +1,103 @@
+// Guy Le Meur 06/2000
+
+
+#ifndef FITSBntblLineRW_SEEN
+#define FITSBntblLineRW_SEEN
+#include "dvlist.h"
+#include "fitsfile.h"
+//#include "xntuple.h"
+
+namespace SOPHYA {
+///////////////////////////////////////////////////////////
+//   Lecture ligne par ligne d'une BINTABLE sur fichier FITS 
+//   
+///////////////////////////////////////////////////////////
+
+class  FITS_BntblLineReader : public FitsIOHandler  
+{
+
+public:
+FITS_BntblLineReader();
+FITS_BntblLineReader(const char inputfile[],int hdunum=2);
+~FITS_BntblLineReader();
+
+BnTblLine& ReadNextLine();
+ inline  BnTblLine& GetBnTblLine()  {return ligne_;}
+ inline long GetNextLineIndex() const {return nextLineToBeRead_;}
+ inline  void SetStartingLineIndex(long n)  { nextLineToBeRead_ = n;}
+
+ inline int status() const {return inFits_->statusF();};
+ inline string GetStatus(int status) const {return inFits_->GetErrStatus(status);}; 
+
+// Renvoie une reference sur l''objet DVList Associe
+inline const DVList& DVListFromFits() const
+  {
+    return(inFits_->DVListFromFits());
+  }
+
+
+protected:
+
+  // implementation de  FitsIOHandler
+  virtual void  ReadFromFits(FitsInFile& is) {};
+virtual void    WriteToFits(FitsOutFile& os) {};
+
+ private :
+
+inline void InitNull()
+   {
+     inFits_ = NULL;
+     nextLineToBeRead_= 0;
+   }
+  // attributs de classe
+
+ FitsInFile* inFits_;
+ long nextLineToBeRead_;
+ BnTblLine ligne_;
+};
+
+
+//////////////////////////////////////////////////////////////////
+
+
+class  FITS_BntblLineWriter : public FitsIOHandler  
+{
+
+
+public:
+ FITS_BntblLineWriter(char inputfile[],int dc, int fc, int ic, int lc, int bc,int cc, vector<string> names, DVList* dvl=NULL, FitsFile::WriteMode wrm = FitsFile::clear);
+~FITS_BntblLineWriter();
+ void WriteNextLine( BnTblLine& WorkLine);
+
+// Renvoie une reference sur l''objet DVList Associe 
+ //inline const DVList& DVListFromFits() const
+ //  {
+ //   return(outFits_->DVListFromFits());
+ // }
+
+ private :
+
+inline void InitNull()
+   {
+     outFits_ = NULL;
+     nextLineToBeWritten_= 0;
+   }
+
+protected:
+
+  // implementation de  FitsIOHandler
+  virtual void  ReadFromFits(FitsInFile& is) {};
+virtual void    WriteToFits(FitsOutFile& os) {};
+
+
+  // attributs de classe
+
+ FitsOutFile* outFits_;
+  long nextLineToBeWritten_;
+  BnTblLine ligne_;
+};
+
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsfile.cc
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsfile.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsfile.cc	(revision 2309)
@@ -0,0 +1,2498 @@
+#include "machdefs.h"
+#include <stdlib.h>
+#include "fitsfile.h"
+#include "pexceptions.h"
+#include "strutil.h"
+#include "anydataobj.h" 
+#include "fitsspherehealpix.h"
+
+/*!
+   \defgroup FitsIOServer FitsIOServer  module
+   This module contains classes which handle FITS format I/O for 
+   SOPHYA objects. This module uses cfitsio library.
+*/
+
+void BnTblLine::setFormat(int dc, int fc, int ic,  int lc, int bc,int cc, vector<string> names)
+   {
+    int nbcols = dc + fc + ic + cc + lc + bc;
+    int maxName = names.size();
+    if (nbcols != maxName)
+      {
+	cout << " WARNING: BnTblLine:: length of vector of column names not equal to total number of columns" << endl;
+	maxName = nbcols < maxName ? nbcols : maxName;
+      }
+    ColName_ = vector<string>(nbcols);
+    int k;
+    for (k=0; k < maxName; k++) ColName_[k] = names[k];
+    if (dc >0) ddata_ = vector<double>(dc);
+    if (fc >0) fdata_ = vector<float>(fc);
+    if (ic >0) idata_ = vector<int>(ic);
+    if (lc >0) ldata_ = vector<long>(lc);
+    if (bc >0) bdata_ = vector<unsigned char>(bc);
+    if (cc >0) cdata_ = vector<string>(cc);
+   }
+
+bool BnTblLine::sameFormat(const BnTblLine& btl) const
+   {
+     if (btl.ddata_.size() == ddata_.size() && btl.fdata_.size() == fdata_.size() && btl.idata_.size() == idata_.size() && btl.cdata_.size() == cdata_.size() &&  btl.ldata_.size() == ldata_.size() &&  btl.bdata_.size() == bdata_.size()) return true;
+     else return false;
+   }
+
+void BnTblLine::Print()
+   {
+     int k;
+     cout << " ********* ligne ************* " << endl;
+     cout << " *** noms de variables  " << endl;
+     for (k=0; k < ColName_.size(); k++) cout << ColName_[k] << " ";
+     cout << endl;
+     cout << " *** variables doubles  " << endl;
+     for (k=0; k < ddata_.size(); k++) cout << ddata_[k] << " ";
+     cout << endl;
+     cout << " *** variables float  " << endl;
+     for (k=0; k < fdata_.size(); k++) cout << fdata_[k] << " ";
+     cout << endl;
+     cout << " *** variables int  " << endl;
+     for (k=0; k < idata_.size(); k++) cout << idata_[k] << " ";
+     cout << endl;
+     cout << " *** variables string  " << endl;
+     for (k=0; k < cdata_.size(); k++) cout << cdata_[k] << " ";
+     cout << endl;
+     cout << " *** variables long  " << endl;
+     for (k=0; k < ldata_.size(); k++) cout << ldata_[k] << " ";
+     cout << endl;
+     cout << " *** variables byte  " << endl;
+     for (k=0; k < bdata_.size(); k++) cout << (int)bdata_[k] << " ";
+     cout << endl;
+     cout << " ***************************** " << endl;
+   }
+
+FitsFile::BufferLine::BufferLine(const vector<FitsFile::FitsDataType>& types)
+{
+
+
+  int dc=0;
+  int fc=0;
+  int shc=0;
+  int ic=0;
+  int lc=0;
+  int cc=0;
+  int bc=0;
+  id_  = vector< pair<FitsFile::FitsDataType, int> >(types.size());
+  int k;
+  for (k= 0; k < types.size(); k++)
+    {
+      switch( types[k] )
+	{
+	case FitsFile::FitsDataType_double :
+	  {
+            id_[k] = pair<FitsFile::FitsDataType, int>(FitsFile::FitsDataType_double, dc);
+	    dc++;
+	    break;
+	  }
+	case FitsFile::FitsDataType_float :
+	  {
+            id_[k] = pair<FitsFile::FitsDataType, int>(FitsFile::FitsDataType_float, fc);
+	    fc++;
+	    break;
+	  }
+	case  FitsFile::FitsDataType_short :
+	  {
+            id_[k] = pair<FitsFile::FitsDataType, int>(FitsDataType_short, shc);
+	    shc++;
+	    break;
+	  }
+	case  FitsFile::FitsDataType_int :
+	  {
+            id_[k] = pair<FitsFile::FitsDataType, int>(FitsDataType_int, ic);
+	    ic++;
+	    break;
+	  }
+	case  FitsFile::FitsDataType_long :
+	  {
+            id_[k] = pair<FitsFile::FitsDataType, int>(FitsFile::FitsDataType_long, lc);
+	    lc++;
+	    break;
+	  }
+	case  FitsFile::FitsDataType_byte :
+	  {
+            id_[k] = pair<FitsFile::FitsDataType, int>(FitsFile::FitsDataType_byte, bc);
+	    bc++;
+	    break;
+	  }
+	case FitsDataType_char :
+	  {
+            id_[k] = pair<FitsFile::FitsDataType, int>(FitsFile::FitsDataType_char, cc);
+	    cc++;
+	    break;
+	  }
+	default:
+	  {
+	    throw PException(" FitsFile::getHeaderWithSophyaObject() : unsupported FITS data type");
+	  }
+	}
+    }
+
+  if (dc >0) ddata_ = vector<r_8>(dc);
+  if (fc >0) fdata_ = vector<r_4>(fc);
+  if (shc >0) shdata_ = vector<int_2>(shc);
+  if (ic >0) idata_ = vector<int_4>(ic);
+  if (lc >0) ldata_ = vector<int_8>(lc);
+  if (cc >0) cdata_ = vector<string>(cc);
+  if (bc >0) bdata_ = vector<unsigned char>(bc);
+}
+
+
+void FitsFile::BufferLine::Print() const
+{
+  cout << " impression de la ligne: " << endl;
+
+  cout << " doubles : " << endl;
+  int k;
+  for (k=0; k< ddata_.size(); k++)
+    {
+      cout << ddata_[k] << " " ;
+    } 
+  cout << endl;
+
+  cout << " floats : " << endl;
+  for (k=0; k< fdata_.size(); k++)
+    {
+      cout << fdata_[k] << " " ;
+    } 
+  cout << endl;
+
+  cout << " entiers courts: " << endl;
+  for (k=0; k< shdata_.size(); k++)
+    {
+      cout << shdata_[k] << " " ;
+    } 
+  cout << endl;
+  cout << " entiers : " << endl;
+  for (k=0; k< idata_.size(); k++)
+    {
+      cout << idata_[k] << " " ;
+    } 
+  cout << endl;
+
+  cout << " entiers longs : " << endl;
+  for (k=0; k< ldata_.size(); k++)
+    {
+      cout << ldata_[k] << " " ;
+    } 
+  cout << endl;
+
+  cout << " chaines carac.  : " << endl;
+  for (k=0; k< cdata_.size(); k++)
+    {
+      cout << cdata_[k] << " " ;
+    } 
+  cout << endl;
+
+  cout << " bytes : " << endl;
+  for (k=0; k< bdata_.size(); k++)
+    {
+      cout << (char)bdata_[k] << " " ;
+    } 
+  cout << endl;
+
+
+}
+
+/*!
+  \class SOPHYA::FitsIOHandler
+  \ingroup FitsIOServer
+The class structure is analogous to Sophya-PPersist system :
+Each SOPHYA object XXX is associated with a object of class FITS_XXX 
+ (inheriting from FitsFileHandler), to which input/output operations with FITS 
+ files are delegated (through a class Hierarchy : FitsFile (virtual), 
+ FitsInFile, FitsOutFile) . A typical example of use is the following : 
+
+\verbatim
+  int m=... ;
+  SphereHEALPix<r_8> sphere1(m);           // definition of the SOPHYA object
+  .... fill the sphere ....
+
+  FITS_SphereHEALPix<r_8> fits_sph1(sphere1); 
+                                           // delegated object
+  fits_sph.Write("myfile.fits");           // writing on FITS file
+
+   FITS_SphereHEALPix<r_8> fits_sph2("myfile.fits"); 
+                                           // load a delegated object 
+                                           // from FITS file
+   SphereHEALPix<r_8> sphere2=(SphereHEALPix<r_8>)fits_sph2; 
+                                           // casting the delegated object
+                                           // into a SOPHYA object
+\endverbatim
+  
+
+*/
+
+/*! \fn void  SOPHYA::FitsIOHandler::Read(char flnm[],int hdunum)
+
+this method is called from inherited objects : 
+
+opens a file 'flnm' 
+
+gets parameters in extension-header (hdunum)
+
+calls the method 'ReadFromFits' from the inherited  object
+*/ 
+void   FitsIOHandler::Read(char flnm[],int hdunum)
+{
+  FitsInFile ifts(flnm);
+  Read(ifts, hdunum);
+}
+
+  /*! \fn void SOPHYA::FitsIOHandler::Read(FitsInFile& is, int hdunum)
+Read the data on extension hdunum (or primary header, if hdunum=1) from FitsInFIle. If hdunum is not addressed, , one reads the next extension, with respect to the current position. 
+   */
+void FitsIOHandler::Read(FitsInFile& is, int hdunum) 
+{
+  is.ReadHeader(hdunum);
+  ReadFromFits(is);
+}
+
+
+/*! \fn void SOPHYA::FitsIOHandler::Write(char flnm[])
+this method is called from inherited objects. 
+
+for writing a new object in a new fits-extension :
+
+\warning By convention, primary header may contain fits-image data.
+For switching off this convention (i.e. to make sure that all data will be on fits-extensions) use the method : 
+
+firstImageOnPrimaryHeader() (see below)
+
+calls the method 'WriteToFits' from the inherited  object
+
+*/ 
+void FitsIOHandler::Write(char flnm[]) 
+
+{
+  FitsOutFile of(flnm, FitsFile::unknown);
+  Write(of);
+}
+
+void FitsIOHandler::Write(FitsOutFile& os) 
+{
+  WriteToFits(os);
+}
+
+
+
+ 
+FitsFile::~FitsFile()
+{
+  int status = 0;
+    if( fptr_ != NULL)
+    {
+      fits_close_file(fptr_,&status);
+      // je ne fais pas      delete fptr_, c'est la lib. fitsio qui a fait 
+      // new...
+    }
+   if( status )  printerror( status );
+}
+
+
+void FitsFile::printerror(int &status) 
+  //*****************************************************/
+  //* Print out cfitsio error messages and exit program */
+  //*****************************************************/
+{
+  if( status )
+    {
+      fits_report_error(stderr,status);
+      throw IOExc("FitsFile:: error FITSIO status");
+    }
+  return;
+}
+
+void FitsFile::printerror(int& status, char* texte) 
+  //*****************************************************/
+  //* Print out cfitsio error messages and exit program */
+  //*****************************************************/
+{
+  // print out cfitsio error messages and exit program 
+  // print error report  
+     fits_report_error(stderr, status);
+  cout << " erreur:: " << texte << endl;
+  throw IOExc("FitsFile:: error FITSIO status");
+}
+void FitsFile::printerrorAndContinue(int& status, char* texte) 
+  //*****************************************************/
+  //* Print out cfitsio error messages and exit program */
+  //*****************************************************/
+{
+  // print out cfitsio error messages and exit program 
+  // print error report  
+     fits_report_error(stderr, status);
+  cout << " erreur:: " << texte << endl;
+  //  throw IOExc("FitsFile:: error FITSIO status");
+}
+
+void FitsFile::ResetStatus(int& status) 
+{
+  fits_status_ = status;
+  status = 0;
+  fits_clear_errmsg();
+}
+
+string FitsFile::GetErrStatus(int status) 
+{
+  char text[31];
+  fits_get_errstatus(status, text);
+  return string(text);
+}
+
+/*!
+  \class SOPHYA::FitsInFile
+  \ingroup FitsIOServer
+class for reading  SOPHYA objects from FITS Format Files (uses cfitsio lib)
+*/
+
+FitsInFile::FitsInFile()
+{
+  InitNull();
+}
+
+FitsInFile::FitsInFile(string const & flnm)
+{
+    InitNull();
+   int status = 0;
+   fits_open_file(&fptr_,flnm.c_str(),READONLY,&status);
+   if( status ) printerror( status );
+}
+
+FitsInFile::FitsInFile(const char * flnm)
+{
+    InitNull();
+   int status = 0;
+   fits_open_file(&fptr_,flnm,READONLY,&status);
+   if( status ) printerror( status );
+}
+
+
+void FitsInFile::InitNull()
+{
+  imageDataType_ = FitsDataType_NULL;
+  naxis_ = 0;
+  nbData_ = 0;
+  nrows_ = 0;
+  nbcols_ = 0;
+  naxisn_.clear();
+  repeat_.clear();
+  noms_.clear();
+  taille_des_chaines_.clear();
+  dvl_.Clear();
+
+  dnull_ = 1.e-300;
+  fnull_ = 1.e-33;
+  inull_= 99999;
+  cnull_= string("xxx");
+  
+
+}
+
+//////////////////////////////////////////////////////////
+//     methods with general purpose
+/////////////////////////////////////////////////////////
+
+int FitsInFile::NbBlocks(char flnm[])
+{
+  int status = 0;
+  int nbhdu = 0; 
+  fitsfile* fileptr; 
+  fits_open_file(&fileptr,flnm,READONLY,&status);
+  if( status ) printerror( status, "NbBlocks: erreur ouverture fichier" );
+  fits_get_num_hdus(fileptr, &nbhdu, &status); 
+  fits_close_file(fileptr,&status);
+  return nbhdu;
+}
+int FitsInFile::NbBlocks()
+{
+  int status = 0;
+  int nbhdu = 0; 
+  fits_get_num_hdus(fptr_, &nbhdu, &status); 
+  return nbhdu;
+}
+
+void FitsInFile::GetBlockType(char flnm[], int hdunum, FitsExtensionType& typeOfExtension, int& naxis, vector<int>& naxisn, FitsDataType& dataType, DVList& dvl )
+{
+  int status = 0;
+  fitsfile* fileptr; 
+  fits_open_file(&fileptr,flnm,READONLY,&status);
+  if( status ) printerror( status, "GetBlockType: erreur ouverture fichier" );
+  // move to the specified HDU number
+  int hdutype = 0;
+  fits_movabs_hdu(fileptr,hdunum,&hdutype,&status);
+  if( status ) printerror( status,"GetBlockType: erreur movabs");
+  if(hdutype == IMAGE_HDU) 
+    {
+      typeOfExtension = FitsExtensionType_IMAGE;
+      GetImageParameters (fileptr, dataType, naxis, naxisn);
+    }
+  else
+    if(hdutype == ASCII_TBL  || hdutype == BINARY_TBL) 
+      {
+	int nrows = 0;
+	vector<string> noms; 
+	vector<FitsDataType> types;   
+	vector<int>  taille_des_chaines;
+	GetBinTabParameters(fileptr, naxis, nrows, naxisn, noms, types, taille_des_chaines); 
+	int k;
+	for (k=0; k< naxisn.size(); k++) naxisn[k] *= nrows;
+	if(hdutype == ASCII_TBL)
+	  {
+	    typeOfExtension = FitsExtensionType_ASCII_TBL; 
+	    dataType = FitsDataType_ASCII;
+	  }
+	else
+	  {
+	    typeOfExtension = FitsExtensionType_BINARY_TBL;
+	    dataType = types[0];
+	  }
+      }
+    else
+      {
+	cout << " hdutype= " << hdutype << endl;
+	throw IOExc("FitsFile::GetBlockType: this HDU type is unknown");
+      }
+  
+  KeywordsIntoDVList(fileptr, dvl, hdunum);
+  fits_close_file(fileptr,&status);
+}
+
+
+void FitsInFile::ReadHeader(int hdunum) 
+{
+  //  InitNull();
+  int status = 0;
+  if (hdunum<0) 
+    {
+      throw PException(" FitsInFile::ReadHeader : hdu number must be not negative");
+    }
+  if (hdunum != 0 ) hdunum_ = hdunum;
+
+  // si le numero de header non precise
+  else
+    {
+      // si c'est le premier objet a lire  
+      if (hdunum_ == 0)
+	{
+	  // on calcule le numero de header a lire
+	  if (imageOnPrimary_ == true ) hdunum_ = 1;
+	  else hdunum_ = 2;
+	}
+      // sinon objet suivant  
+      else hdunum_++;
+    }
+  getHeaderWithSophyaObject();
+  if ( hdutype_ == FitsExtensionType_NULL )
+    {
+      if (hdunum == 0 && hdunum_ == 1)
+	{
+	  hdunum_++;
+	  getHeaderWithSophyaObject();
+	}
+      else 
+	{
+	  cout << " WARNING (FitsInFile::ReadHeader) : no SOPHYA object on HDU number : " << hdunum_ << endl;
+	}
+    }
+  if ( hdutype_ == FitsExtensionType_EOF )
+    {
+	throw PException("FitsFile::ReadHeader, attempt to read through EOF");
+    }
+}
+
+string FitsInFile::getStringKeyword(int hdunum, string keyw, int& retStatus)
+{
+  string s;
+  retStatus = 0;
+  int status = 0;
+  if (hdunum != hdunum_ )
+    {
+      int hdutype;
+      fits_movabs_hdu(fptr_,hdunum,&hdutype,&status);
+    }
+  
+  char value[FLEN_VALUE];
+  char* keyname= const_cast<char*>(keyw.c_str());
+  fits_read_key_str(fptr_,keyname,value,NULL,&status);
+  if (status == 0)
+    s = string(value);
+  else retStatus = status;
+  if (hdunum != hdunum_ )
+    {
+      int hdutype;
+      if (hdunum_ != 0)
+	fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
+      else 	     fits_movabs_hdu(fptr_,1,&hdutype,&status);
+      
+    }
+  return s;
+}
+bool FitsInFile::hasKeyword(int hdunum, string keyw)
+     {
+       bool has=false;
+       int status = 0;
+       if (hdunum != hdunum_ )
+	 {
+	   int hdutype;
+	   fits_movabs_hdu(fptr_,hdunum,&hdutype,&status);
+	 }
+
+       char value[FLEN_VALUE];
+       char* keyname= const_cast<char*>(keyw.c_str());
+       fits_read_keyword(fptr_,keyname,value,NULL,&status);
+       if (status == 0)
+	 has = true;
+       else 
+	 if (status == KEY_NO_EXIST ) status =0;
+	 else fits_report_error(stderr,status); 
+       if (hdunum != hdunum_ )
+	 {
+	   int hdutype;
+	   if (hdunum_ != 0)
+	     fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
+	   else 	     fits_movabs_hdu(fptr_,1,&hdutype,&status);
+
+	 }
+       return has;
+     }
+
+void FitsInFile::GetKeywordsFromHeader (int hdunum, list<FitsKeyword>& mots_cles) const
+{
+  int status = 0;
+  int hdutype;
+  fits_movabs_hdu(fptr_,hdunum,&hdutype,&status);
+  if( status ) fits_report_error(stderr,status);
+
+  // get number of keywords
+  int nkeys,keypos;
+  fits_get_hdrpos(fptr_, &nkeys, &keypos,&status);
+  if( status ) fits_report_error(stderr,status);
+  // shift with the number of mandatory keywords
+  int num= 0;
+  // if primary header
+    if (hdunum == 1) 
+      {
+	// read NAXIS
+	int naxis=0;
+	fits_read_key(fptr_,TINT,"NAXIS",&naxis,NULL,&status);
+	// number of mandatory keywords
+	num = naxis+3;
+      }
+    // extensions
+    else
+      {
+	if (hdutype == IMAGE_HDU)
+	  {
+	    // read NAXIS
+	    int naxis=0;
+	    fits_read_key(fptr_,TINT,"NAXIS",&naxis,NULL,&status);
+	    // number of mandatory keywords
+	    num = naxis+5;
+	  }
+	else
+	  if(hdutype == ASCII_TBL || hdutype == BINARY_TBL)
+	    {
+	      // number of mandatory keywords
+	      num = 8;
+	    }
+      }
+  int j;
+  char keyname[LEN_KEYWORD];  
+  char value[FLEN_VALUE];
+  char comment[FLEN_COMMENT];
+  for(j = num+1; j <= nkeys; j++)
+    {
+      char dtype;
+      fits_read_keyn(fptr_,j,keyname,value,comment,&status);
+      if(status) 
+	{
+	  fits_report_error(stderr,status);
+	  status=0;
+	}
+      string  kn(keyname);
+      string  cm(comment);
+      string  val(value);
+      FitsKeyword kw(kn, val, cm);
+      mots_cles.push_back(kw);
+    }
+  if (hdunum_ > 0) fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
+
+}
+void FitsInFile::GetImageParameters (fitsfile* fileptr,FitsDataType& dataType,int& naxis,vector<int>& naxisn)
+{
+  int hdunum=0;
+  //    cout << " Reading a FITS image in HDU : " << fits_get_hdu_num(fileptr,&hdunum)  << endl;
+  int status= 0;
+
+  // bits per pixels
+  int bitpix=0;
+  fits_read_key(fileptr,TINT,"BITPIX",&bitpix,NULL,&status);
+  if( status )  printerror( status );
+  if(bitpix == DOUBLE_IMG) dataType = FitsDataType_double;
+  else if(bitpix == FLOAT_IMG) dataType = FitsDataType_float;
+  else if(bitpix == LONG_IMG || bitpix == SHORT_IMG ) dataType = FitsDataType_int;
+  else if (bitpix == BYTE_IMG) dataType = FitsDataType_char;
+  else 
+    {
+      cout << " bitpix= " << bitpix << endl;
+      throw PException(" FitsFile::GetImageParameters : unsupported FITS data type");
+    }
+
+  // number of dimensions in the FITS array
+  naxis= 0;
+  fits_read_key(fileptr,TINT,"NAXIS",&naxis,NULL,&status);
+  if( status ) printerror( status );
+  // read the NAXISn keywords to get image size
+  long* naxes = new long[naxis] ;
+  int nfound;
+  fits_read_keys_lng(fileptr,"NAXIS",1,naxis,naxes,&nfound,&status);
+  if( status ) printerror( status );
+  if (nfound != naxis ) 
+    cout << " WARNING : " << nfound << " axes found, expected naxis= " << naxis << endl;
+  int k;
+  for (k=0; k<naxis; k++) 
+    {
+      naxisn.push_back( (int)naxes[k] );
+    }
+  delete [] naxes;
+}
+
+
+
+
+  /*! \fn DVList SOPHYA::FitsInFile::DVListFromPrimaryHeader() const
+
+   \return the keywords of primary header in a DVList 
+
+*/
+DVList  FitsInFile::DVListFromPrimaryHeader() const
+   {
+     int status;
+     DVList dvl;
+     KeywordsIntoDVList(fptr_, dvl, 1);
+     int hdutype = 0;
+     if (hdunum_ > 0) fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
+     return dvl;
+   }
+
+void FitsInFile::getHeaderWithSophyaObject()
+{
+  // si hdunum_ > 1 lit le header correspondant
+  // si hdunum_ = 1 se positionne au (et lit le) premier header qui 
+  //                contient reellement un objet 
+  int status=0;
+  if (hdunum_ < 1)  throw PException(" attempt to read hdunum < 1");
+   InitNull();
+  if (hdunum_ == 1)
+    {
+      // presence of image ?
+      int naxis= 0;
+      fits_read_key(fptr_,TINT,"NAXIS",&naxis,NULL,&status);
+      if( status ) printerror( status );
+      if (naxis > 0 )       // there is an image
+	{
+	  hdutype_ = FitsExtensionType_IMAGE;
+	  GetImageParameters (fptr_, imageDataType_, naxis_, naxisn_);
+	  nbData_ =  1;
+	  int k;
+	  for (k=0; k<naxis_; k++) if (naxisn_[k] > 0) nbData_ *= naxisn_[k];
+	  KeywordsIntoDVList(fptr_, dvl_,hdunum_);
+	}
+      else
+	{
+	  hdutype_ = FitsExtensionType_NULL;
+	  KeywordsIntoDVList(fptr_, dvl_,hdunum_);
+	}
+    }
+  else
+    {
+      int hdutype;
+      fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
+
+      if( status )
+	{
+	  if (status == END_OF_FILE)
+	    {
+	      hdutype_= FitsExtensionType_EOF;
+	      status =0;
+	      return;
+	    }
+	  else
+	    {
+	      cout << "WARNING (FitsInFile::getHeaderWithSophyaObject) : error during movabs" << endl;
+	      hdutype_= FitsExtensionType_ERROR;
+	      status =0;
+	      return;
+	    }
+	  // printerror( status,":FitsInFile::getHeader : erreur movabs");
+	}
+	
+
+      if(hdutype == IMAGE_HDU) 
+	{
+	  hdutype_= FitsExtensionType_IMAGE;
+	  GetImageParameters (fptr_, imageDataType_, naxis_, naxisn_);
+	  nbData_ =  1;
+	  int k;
+	  for (k=0; k<naxis_; k++) if (naxisn_[k] > 0) nbData_ *= naxisn_[k];
+	  KeywordsIntoDVList(fptr_, dvl_,hdunum_);
+	}
+      else if(hdutype == ASCII_TBL)
+	{
+	  hdutype_= FitsExtensionType_ASCII_TBL;
+	  GetBinTabParameters(fptr_,nbcols_, nrows_,repeat_, noms_, types_, taille_des_chaines_);
+	  KeywordsIntoDVList(fptr_, dvl_, hdunum_);
+	}
+      else if(hdutype == BINARY_TBL)
+	{
+	  hdutype_= FitsExtensionType_BINARY_TBL;
+	  GetBinTabParameters(fptr_,nbcols_, nrows_,repeat_, noms_, types_, taille_des_chaines_);
+	  KeywordsIntoDVList(fptr_, dvl_, hdunum_);
+	}
+      else 
+	{
+	  hdutype_= FitsExtensionType_NULL;
+	  KeywordsIntoDVList(fptr_, dvl_, hdunum_);
+	}
+
+    }
+  if (hdutype_ == FitsExtensionType_BINARY_TBL || hdutype_ == FitsExtensionType_ASCII_TBL)
+    {
+      bfl_ = BufferLine(types_);
+    }
+}
+
+
+void FitsInFile::moveToFollowingHeader()
+{
+  int status = 0;
+  hdunum_++;
+  getHeaderWithSophyaObject();
+  if ( hdutype_ == FitsExtensionType_NULL )
+    {
+      cout << " WARNING (FitsInFile::ReadHeader) : no SOPHYA object on HDU number : " << hdunum_ << endl;
+	
+    }
+}
+
+
+
+
+
+/*! \fn int  SOPHYA::FitsInFile::NbColsFromFits() const
+\return number of columns (return 1 if IMAGE) 
+*/
+int  FitsInFile::NbColsFromFits() const
+{
+  if(hdutype_ == FitsExtensionType_BINARY_TBL) return nbcols_;
+  else
+    if(hdutype_ == FitsExtensionType_ASCII_TBL ||  hdutype_ == FitsExtensionType_IMAGE) return 1;
+    else
+      {
+	cout << " hdutype= " << (int) hdutype_ << endl;
+	throw PException("FitsFile::NbColsFromFits, HDU  not supported");
+      }
+}
+
+/*! \fn  int SOPHYA::FitsInFile::NentriesFromFits(int nocol) const
+\return number of data in the current IMAGE extension on FITS file, or number
+ of data of column number 'nocol' of the current BINTABLE extension
+*/
+int FitsInFile::NentriesFromFits(int nocol) const
+{
+  if(hdutype_ == FitsExtensionType_BINARY_TBL)   return nrows_*repeat_[nocol];
+  else
+    if(hdutype_ == FitsExtensionType_ASCII_TBL) return nrows_;
+    else
+      if(hdutype_ == FitsExtensionType_IMAGE) return nbData_;
+      else
+	{
+	  cout << "hdutype= " << (int) hdutype_ << endl;
+	  throw PException("FitsFile::NentriesFromFits, this HDU is not supported");
+	}
+}
+
+/*! \fn char SOPHYA::FitsInFile::ColTypeFromFits(int nocol) const
+
+return a character denoting data type of column number 'nocol' in a BINTABLE :
+
+D : double
+
+E : float 
+
+I : integer
+    
+S : character string 
+
+  */
+
+FitsFile::FitsDataType FitsInFile::ColTypeFromFits(int nocol) const
+{
+  if(hdutype_ != FitsExtensionType_ASCII_TBL && hdutype_ != FitsExtensionType_BINARY_TBL)
+    {
+      throw IOExc("FitsFile::TypeFromFits, this HDU is not an ASCII table nor a binary table");
+    }
+  return types_[nocol];
+}
+
+
+/*! \fn string SOPHYA::FitsInFile::ColNameFromFits(int nocol) const
+
+\return name of the column number 'nocol' of the current BINTABLE extension
+   */
+
+string FitsInFile::ColNameFromFits(int nocol) const
+{
+  if(hdutype_ != FitsExtensionType_ASCII_TBL && hdutype_ != FitsExtensionType_BINARY_TBL)
+    {
+      throw IOExc("FitsFile::TypeFromFits, this HDU is not an ASCII table nor a binary table");
+    }
+  return noms_[nocol];
+}
+
+/*! \fn int DSOPHYA::FitsInFile::ColStringLengthFromFits(int nocol) const
+
+ \return number of characters of each data  for the column number 'nocol' (if char* typed) of the current BINTABLE extension
+*/
+
+int FitsInFile::ColStringLengthFromFits(int nocol) const
+{
+  if(hdutype_ != FitsExtensionType_ASCII_TBL && hdutype_ != FitsExtensionType_BINARY_TBL)
+    {
+      throw IOExc("FitsFile::TypeFromFits, this HDU is not an ASCII table nor a binary table");
+    }
+  int index=-1;
+  int k;
+  for (k=0; k<=nocol; k++) 
+    {
+      if (types_[k] == FitsDataType_char) index++;
+    }
+  return  taille_des_chaines_[index];
+}
+
+const FitsFile::BufferLine&   FitsInFile::GetBufferLine(long NoLine) 
+{
+  int status= 0;
+  int    anynul;
+  double dnull= dnull_;
+  float fnull= fnull_;
+  int inull= inull_;
+  char* cnull=  const_cast<char*>(cnull_.c_str());
+  int ncol;
+  long nels=1;
+  double dval;
+  float  fval;
+  int    ival;
+
+  // pas d'entier de longueur superieure a 32 bits, pour cfitsio
+  int    lval;
+
+  unsigned char usval; 
+  int rang = 0;
+  int ccount = 0;
+  for (ncol=0; ncol<nbcols_; ncol++)
+    {
+      rang =  bfl_.identificateur()[ncol].second;
+      //      cout << " fitsfile : relecture col " << ncol << " type " << bfl_.identificateur()[ncol].first << " rang " << rang << endl; 
+      switch (bfl_.identificateur()[ncol].first)
+	{ 
+	case FitsDataType_double :
+	  fits_read_col(fptr_,TDOUBLE,ncol+1,NoLine+1,1,1,&dnull, &dval,&anynul,&status);
+	  bfl_.r_8Array(rang) = (r_8)dval;
+	  break;
+	case FitsDataType_float :
+	  fits_read_col(fptr_,TFLOAT,ncol+1,NoLine+1,1,1,&fnull,&fval,&anynul,&status);
+	  bfl_.r_4Array(rang)  = (r_4)fval;
+	  break;
+	case FitsDataType_short :
+	  fits_read_col(fptr_,TSHORT,ncol+1,NoLine+1,1,1,&inull,&ival, &anynul,&status);
+	  bfl_.int_2Array(rang) = (int_2)ival;
+	  break;
+	case FitsDataType_int :
+	  fits_read_col(fptr_,TINT,ncol+1,NoLine+1,1,1,&inull,&ival, &anynul,&status);
+	  bfl_.int_4Array(rang) = (int_4)ival;
+	  break;
+	case FitsDataType_long :
+	  fits_read_col(fptr_,TLONG,ncol+1,NoLine+1,1,1,&inull,&lval, &anynul,&status);
+	  bfl_.int_8Array(rang) = (int_8)lval;
+	  break;
+	case FitsDataType_byte :
+	  fits_read_col(fptr_,TBYTE,ncol+1,NoLine+1,1,1,&inull, &usval, &anynul,&status);
+	  bfl_.u_charArray(rang) = usval;
+	  break;
+	case FitsDataType_char :
+	  char* chaine = new char[taille_des_chaines_[ccount++]];
+	  fits_read_col(fptr_,TSTRING,ncol+1,NoLine+1,1,1,cnull,&chaine,&anynul,&status);
+	  bfl_.stringArray(rang) = string(chaine);
+	  break;
+	}
+      if (status)
+	{
+	  ResetStatus(status);
+	  break;
+	}
+    }
+  //  cout << " fitsfile : ligne relue " << endl;
+  //  bfl_.Print();
+  return bfl_;
+}
+
+
+
+/*! \fn void  SOPHYA::FitsInFile::GetBinTabLine(int NoLine, double* ddata, float* fdata, int* idata, char ** cdata)
+
+Get the NoLine-th 'line'  from the current BINTABLE extension on FITS file,
+  */
+
+void  FitsInFile::GetBinTabLine(int NoLine, double* ddata, float* fdata, int* idata, char ** cdata) 
+{
+  int status= 0;
+  int    anynul;
+  double dnull= dnull_;
+  float fnull= fnull_;
+  int inull= inull_;
+  char* cnull= const_cast<char*>(cnull_.c_str());
+  int dcount = 0.;
+  int fcount = 0.;
+  int icount = 0;
+  int ccount =0;
+  int ncol;
+  long nels=1;
+  int ligneAsolue = NoLine+1;
+  for (ncol=0; ncol<nbcols_; ncol++)
+    {
+      int repetition =repeat_[ncol]; 
+      int ligneALire = ligneAsolue/repetition;
+      int premierElement  = ligneAsolue-ligneALire*repetition;
+      if (premierElement != 0 )
+	{
+	  ligneALire++;
+	}
+      else premierElement = repetition;
+
+      switch (types_[ncol])
+	{ 
+	case FitsDataType_double :
+	  {
+	  fits_read_col(fptr_,TDOUBLE,ncol+1,ligneALire,premierElement,1,&dnull,&ddata[dcount++],&anynul,&status);
+	    break;
+	  }
+	case FitsDataType_float :
+	  {	  
+	    fits_read_col(fptr_,TFLOAT,ncol+1,ligneALire,premierElement,1,&fnull,&fdata[fcount++],&anynul,&status);
+	    break;
+	  }
+	case  FitsDataType_int :
+	  {
+	    fits_read_col(fptr_,TINT,ncol+1,ligneALire,premierElement,1,&inull,&idata[icount++],
+			&anynul,&status);
+	    break;
+	  }
+	case  FitsDataType_long :
+	  {
+	    fits_read_col(fptr_,TLONG,ncol+1,ligneALire,premierElement,1,&inull,&idata[icount++], &anynul,&status);
+	    break;
+	  }
+	case  FitsDataType_byte :
+	  {
+	    unsigned char uschar = 0;
+	    fits_read_col(fptr_,TBYTE,ncol+1,ligneALire,premierElement,1,&inull,&uschar, &anynul,&status);
+	    idata[icount++] = (int)uschar;
+	    break;
+	  }
+	case FitsDataType_char :
+	  {
+	    fits_read_col(fptr_,TSTRING,ncol+1,ligneALire,premierElement,1,cnull,&cdata[ccount++],&anynul,&status);
+	    break;
+	  }
+	default:
+	  {
+	    throw PException(" FitsInFile::GetBinTabLine : unsupported FITS data type");
+	  }
+	}
+      if (status)
+	{
+	  ResetStatus(status);
+	  break;
+	}
+    }
+}
+
+/*! \fn void   SOPHYA::FitsInFile::GetBinTabLine(long NoLine,  BnTblLine& ligne)
+Get the NoLine-th 'line'  from the current BINTABLE extension on FITS file,
+*/
+void   FitsInFile::GetBinTabLine(long NoLine,  BnTblLine& ligne) 
+{
+  int status= 0;
+  int    anynul;
+  double dnull= dnull_;
+  float fnull= fnull_;
+  int inull= inull_;
+  char* cnull=  const_cast<char*>(cnull_.c_str());
+  int dcount = 0.;
+  int fcount = 0.;
+  int icount = 0;
+  int lcount = 0;
+  int bcount = 0;
+  int ccount =0;
+  int ncol;
+  long nels=1;
+  for (ncol=0; ncol<nbcols_; ncol++)
+    {
+      switch (types_[ncol])
+	{ 
+	case FitsDataType_double :
+	  {
+	    fits_read_col(fptr_,TDOUBLE,ncol+1,NoLine+1,1,1,&dnull,&ligne.ddata_[dcount++],&anynul,&status);
+	    break;
+	  }
+	case FitsDataType_float :
+	  {
+	    fits_read_col(fptr_,TFLOAT,ncol+1,NoLine+1,1,1,&fnull,&ligne.fdata_[fcount++],&anynul,&status);
+	    break;
+	  }
+	case FitsDataType_int :
+	  {
+	    fits_read_col(fptr_,TINT,ncol+1,NoLine+1,1,1,&inull,&ligne.idata_[icount++], &anynul,&status);
+	    break;
+	  }
+	case FitsDataType_long :
+	  {
+	    fits_read_col(fptr_,TLONG,ncol+1,NoLine+1,1,1,&inull,&ligne.ldata_[lcount++], &anynul,&status);
+	    break;
+	  }
+	case FitsDataType_byte :
+	  {
+	    fits_read_col(fptr_,TBYTE,ncol+1,NoLine+1,1,1,&inull,&ligne.bdata_[bcount++], &anynul,&status);
+	    break;
+	  }
+	case FitsDataType_char :
+	  {
+	    char* chaine = new char[taille_des_chaines_[ccount]];
+	    fits_read_col(fptr_,TSTRING,ncol+1,NoLine+1,1,1,cnull,&chaine,&anynul,&status);
+	    ligne.cdata_[ccount++] = string(chaine);
+	    break;
+	  }
+	default:
+	  {
+	    throw PException(" FitsInFile::GetBinTabLine : unsupported FITS data type");
+	  }
+	}
+      if (status)
+	{
+	  ResetStatus(status);
+	  break;
+	}
+    }
+}
+
+
+
+/*! \fn void SOPHYA::FitsInFile::GetBinTabLine(int NoLine, float* fdata)
+
+Get the NoLine-th float 'line'  from the current BINTABLE extension on FITS file,
+*/
+void FitsInFile::GetBinTabLine(int NoLine, float* fdata) 
+{
+  int status= 0;
+  int    anynul;
+  float fnull= fnull_;
+  long nels=1;
+  int ncol;
+  for (ncol=0; ncol<nbcols_; ncol++)
+    {
+      fits_read_col(fptr_,TFLOAT,ncol+1,NoLine+1,1,1,&fnull,&fdata[ncol],&anynul,&status);
+      if (status)
+	{
+	  ResetStatus(status);
+	  break;
+	}
+    }
+}
+
+
+/*! \fn void SPOPHYA::FitsInFile::GetBinTabFCol(double* valeurs,int nentries, int NoCol) const
+
+fill the array 'valeurs' with double data from the current BINTABLE extension on FITS file, from column number 'NoCol'
+
+\param <nentries>  number of data to be read
+*/
+void FitsInFile::GetBinTabFCol(r_8* valeurs,int nentries, int NoCol) const
+    {
+      int status= 0;
+      int DTYPE;
+      long repeat,width;
+            fits_get_coltype(fptr_, NoCol+1,&DTYPE,&repeat,&width,&status);
+      if( DTYPE != TDOUBLE) 
+	{
+	  if (DTYPE == TFLOAT)  cout << " WARNING: reading double from float : conversion will be made by fitsio library" << endl;
+	  else
+	    throw IOExc("FitsFile::GetBinTabFCol, tentative de lecture non double");
+	}
+      long nels=nentries;
+      int    anynul;
+      double dnull= dnull_;
+
+      fits_read_col(fptr_,TDOUBLE,NoCol+1,1,1,nels,&dnull,valeurs,
+			    &anynul,&status);
+      if( status )
+	{
+	  printerrorAndContinue( status,"erreur lecture de colonne" );
+	}
+    }
+
+/*! \fn  void SOPHYA::FitsInFile::GetBinTabFCol(float* valeurs,int nentries, int NoCol) const
+
+ same as previous method with float data 
+*/
+void FitsInFile::GetBinTabFCol(r_4* valeurs,int nentries, int NoCol) const
+    {
+      int status= 0;
+      int DTYPE;
+      long repeat,width;
+      fits_get_coltype(fptr_, NoCol+1,&DTYPE,&repeat,&width,&status);
+      if( DTYPE != TFLOAT) 
+	{
+	  if (DTYPE == TDOUBLE)  cout << " WARNING: reading float from double : conversion will be made by fitsio library" << endl;
+	  else
+	    throw IOExc("FitsFile::GetBinTabFCol, tentative de lecture non float");
+	}
+      long nels=nentries;
+      int    anynul;
+      float fnull= fnull_;
+      fits_read_col(fptr_,TFLOAT,NoCol+1,1,1,nels,&fnull,valeurs,
+			    &anynul,&status);
+      if( status ) printerrorAndContinue( status,"erreur lecture de colonne" );
+    }
+
+/*! \fn void SOPHYA::FitsInFile::GetBinTabFCol(int* valeurs,int nentries, int NoCol) const
+
+ same as previous method with int data 
+*/
+
+void FitsInFile::GetBinTabFCol(int_4* valeurs,int nentries, int NoCol) const
+    {
+      int status= 0;
+      int DTYPE;
+      long repeat,width;
+      fits_get_coltype(fptr_, NoCol+1,&DTYPE,&repeat,&width,&status);
+      if( DTYPE != TLONG &&  DTYPE != TINT) 
+	{
+	  throw IOExc("FitsFile::GetBinTabFCol, probleme de lecture d'entiers");
+	}
+      long nels=nentries;
+      int    anynul;
+      int inull= inull_;
+
+
+
+      // voir commentaire dans putColToFits()
+      fits_read_col(fptr_,TINT,NoCol+1,1,1,nels,&inull,valeurs,
+			    &anynul,&status);
+      if( status ) printerrorAndContinue( status,"erreur lecture de colonne" );
+    }
+
+/*! \fn void SOPHYA::FitsInFile::GetBinTabFCol(char** valeurs, int nentries, int NoCol) const
+
+ same as previous method with char* data 
+*/
+
+void FitsInFile::GetBinTabFCol(char** valeurs, int nentries, int NoCol) const
+    {
+      int status= 0;
+      int DTYPE;
+      long repeat,width;
+      fits_get_coltype(fptr_, NoCol+1,&DTYPE,&repeat,&width,&status);
+      if( DTYPE != TSTRING &&  DTYPE != TBYTE) 
+	{
+	  throw IOExc("FitsFile::GetBinTabFCol, tentative de lecture non string");
+	}
+      long nels=nentries;
+      int    anynul;
+      char* cnull=  const_cast<char*>(cnull_.c_str());
+      long frow=1;
+      long felem=1;
+      fits_read_col(fptr_,TSTRING,NoCol+1,frow,felem,nels,cnull,valeurs,
+		    &anynul,&status);
+      if( status ) printerrorAndContinue( status,"erreur lecture de colonne" );
+    }
+
+/*! \fn void SOPHYA::FitsInFile::GetSingleColumn(double* map, int nentries) const
+fill the array 'map' with double data from the current extension on FITS file.
+If the extension is BINTABLE, the first column is provided. 
+
+\param <nentries>  number of data to be read
+*/
+void FitsInFile::GetSingleColumn(r_8* map, int nentries) const
+{ 
+  int status = 0;
+  if(hdutype_ == FitsExtensionType_IMAGE) 
+    {
+  
+      if(imageDataType_ != FitsDataType_double) 
+	{
+	  cout << " The data type on fits file is not double...";
+	  cout << " Conversion to double achieved by cfitsio lib" << endl;
+	}
+  
+      int    anynul;
+      double dnull= dnull_;
+  
+      long nels= nentries;
+      fits_read_img(fptr_,TDOUBLE,1,nels,&dnull,map,&anynul,&status);
+      if( status ) printerror( status );
+    }
+  else
+    if(hdutype_ == FitsExtensionType_ASCII_TBL || hdutype_ == FitsExtensionType_BINARY_TBL)
+      {
+	GetBinTabFCol(map,nentries, 0);
+      }
+    else
+      {
+      cout << " hdutype= " << (int) hdutype_ << endl;
+      throw IOExc("FitsFile::GetSingleColumn, this HDU is unknown");
+      }
+}
+
+/*! \fn void SOPHYA::FitsInFile::GetSingleColumn(float* map, int nentries) const
+same as above with float data 
+*/
+void FitsInFile::GetSingleColumn(r_4* map, int nentries) const
+{
+  int status = 0;
+  if(hdutype_ == FitsExtensionType_IMAGE) 
+    {
+      if(imageDataType_ != FitsDataType_float) 
+	{
+	  cout << " The data type on fits file is not float ";
+	  cout << " Conversion to float achieved by cfitsio lib" << endl;
+	}
+      int   anynul;
+      float fnull= fnull_;
+      
+      long nels= nentries;
+      fits_read_img(fptr_,TFLOAT,1,nels,&fnull, map,&anynul,&status);
+      if( status ) printerror( status );
+    }
+  else
+    if(hdutype_ == FitsExtensionType_ASCII_TBL || hdutype_ == FitsExtensionType_BINARY_TBL)
+      {
+	GetBinTabFCol(map,nentries, 0);
+      }
+    else
+      {
+      cout << " hdutype= " << (int) hdutype_ << endl;
+      throw IOExc("FitsFile::GetSingleColumn this HDU is unknown");
+      }
+}
+
+/*! \fn void SOPHYA::FitsInFile::GetSingleColumn( int* map, int nentries) const
+ same as above with int data 
+*/
+void FitsInFile::GetSingleColumn( int_4* map, int nentries) const
+{
+  int status = 0;
+  if(hdutype_ == FitsExtensionType_IMAGE) 
+    {
+      if(imageDataType_ != FitsDataType_int) 
+	{
+	  cout << " The data type on fits file is not int ";
+	  cout << " Conversion to float achieved by cfitsio lib" << endl;
+	}
+      int   anynul;
+      float fnull= fnull_;
+      
+      long nels= nentries;
+      fits_read_img(fptr_,TINT,1,nels,&fnull,map,&anynul,&status);
+      if( status ) printerror( status );
+    }
+  else
+    if(hdutype_ == FitsExtensionType_ASCII_TBL || hdutype_ == FitsExtensionType_BINARY_TBL)
+      {
+	GetBinTabFCol(map,nentries, 0);
+      }
+    else
+      {
+      cout << " hdutype= " << (int) hdutype_ << endl;
+      throw IOExc("FitsFile::GetSingleColumn this HDU is unknown");
+      }
+}
+
+void FitsInFile::GetBinTabParameters(fitsfile* fileptr, int& nbcols, int& nrows,
+				  vector<int>& repeat,
+				  vector<string>& noms, 
+				  vector<FitsDataType>& types,   
+				  vector<int>&  taille_des_chaines)
+{
+  int status= 0;
+  int hdunum=0;
+  int hdutype=0;
+  fits_get_hdu_num(fileptr,&hdunum);
+  fits_get_hdu_type(fileptr, &hdutype, &status);
+
+  if(hdutype != ASCII_TBL && hdutype != BINARY_TBL)
+    {
+      throw IOExc("FitsFile::GetBinTabParameters this HDU is not an ASCII table nor a binary table");
+    }
+  //  if(hdutype == ASCII_TBL)
+  //        cout << " Reading a FITS ascii table in HDU : " << hdunum << endl;  
+  //  if(hdutype == BINARY_TBL)
+  //        cout << " Reading a FITS binary table in HDU : " << hdunum << endl;
+
+  // get the number of columns
+  fits_get_num_cols(fileptr, &nbcols,&status);
+  if( status ) printerror( status );
+
+  // get the number of rows
+  long naxis2= 0;
+  fits_get_num_rows(fileptr,&naxis2,&status);
+  if( status ) printerror( status );
+  nrows = (int)naxis2;
+
+  // get the datatype,  names and the repeat count
+  noms.clear();
+  noms.reserve(nbcols);
+  types.clear();
+  types.reserve(nbcols);
+  repeat.clear();
+  repeat.reserve(nbcols);
+  taille_des_chaines.clear();
+  char **ttype = new char*[nbcols];
+  int ii;
+  // 
+  //
+  for (ii=0; ii < nbcols; ii++) ttype[ii]=new char[FLEN_VALUE];
+  int nfound;
+  fits_read_keys_str(fileptr, "TTYPE",1,nbcols,ttype,&nfound, &status);
+  if( status ) printerror( status,"erreur lecture des noms de colonne");
+  int rept=0;
+  if(hdutype == ASCII_TBL)
+    {
+      for(ii = 0; ii <  nbcols; ii++)
+	{
+	  int DTYPE;
+	  long width;
+	  long repete = 0;
+	  fits_get_coltype(fileptr,ii+1,&DTYPE,&repete,&width,&status);
+	  if( status ) printerror( status,"erreur lecture type de colonne");
+	  rept = repete;
+	  noms.push_back(string(ttype[ii]));
+	  switch (DTYPE)
+	    {
+	    case TDOUBLE :
+	      types.push_back(FitsDataType_double);
+	      break;
+	    case TFLOAT :
+	      types.push_back(FitsDataType_float);
+	      break;
+	    case TLONG :
+	      types.push_back(FitsDataType_long);
+	      break;
+	    case TINT :
+	      types.push_back(FitsDataType_int);
+	      break;
+	    case TSHORT :
+	      types.push_back(FitsDataType_short);
+	      break;
+	    case TSTRING :
+	      types.push_back(FitsDataType_char);
+	      taille_des_chaines.push_back(width);
+	      rept/=width;
+	      break;
+	    default :
+	      cout << " field " << ii+1 << " DTYPE= " << DTYPE << endl;
+	      throw IOExc("FitsFile::GetBinTabParameters, unsupported data type of field, for ASCII table");
+	    }
+	  repeat.push_back(rept);
+	}
+    }
+  else 
+    {
+      for(ii = 0; ii <  nbcols; ii++)
+	{
+	  int DTYPE;
+	  long width;
+	  long repete = 0;
+	  fits_get_coltype(fileptr,ii+1,&DTYPE,&repete,&width,&status);
+	  if( status ) printerror( status,"erreur lecture type de colonne");
+	  rept = repete;
+	  noms.push_back(string(ttype[ii]));
+	  switch (DTYPE)
+	    {
+	    case TDOUBLE :
+	      types.push_back(FitsDataType_double);
+	      break;
+	    case TFLOAT :
+	      types.push_back(FitsDataType_float);
+	      break;
+	    case TLONG :
+	      types.push_back(FitsDataType_long);
+	      break;
+	    case TINT :
+	      types.push_back(FitsDataType_int);
+	      break;
+	    case TSHORT :
+	      types.push_back(FitsDataType_short);
+	      break;
+	    case TSTRING :
+	      types.push_back(FitsDataType_char);
+	      taille_des_chaines.push_back(width);
+	      rept/=width;
+	      break;
+	    case TBYTE :
+	      types.push_back(FitsDataType_byte);
+	      break;
+	    default :
+	      cout << " field " << ii+1 << " DTYPE= " << DTYPE << endl;
+	      throw IOExc("FitsFile::GetBinTabParameters, unsupported data type of field, for BINTABLE");
+	    }
+	  repeat.push_back(rept);
+	}
+    }
+  for (ii=0; ii < nbcols; ii++) delete [] ttype[ii];
+  delete [] ttype;
+}
+
+void FitsInFile::KeywordsIntoDVList(fitsfile* fileptr, DVList& dvl, int hdunum)
+{
+  int status = 0;
+  int hdutype;
+  fits_movabs_hdu(fileptr,hdunum,&hdutype,&status);
+  if( status ) printerror( status,":KeywordsIntoDVList : erreur movabs");
+  // get number of keywords
+  int nkeys,keypos;
+  fits_get_hdrpos(fileptr,&nkeys,&keypos,&status);
+  if( status ) printerror( status );
+
+  // put  keywords in a DVList object
+  char keyname[LEN_KEYWORD]= "";
+  char strval[FLEN_VALUE]= "";
+  char dtype;
+  char card[FLEN_CARD];  
+  char *comkey = "COMMENT";
+  char comment[FLEN_COMMENT];
+
+  // shift with the number of mandatory keywords
+  //  int num= 8;
+    int num= 0;
+    // primary header
+    if (hdunum == 1) 
+      {
+	// read NAXIS
+	int naxis=0;
+	fits_read_key(fileptr,TINT,"NAXIS",&naxis,NULL,&status);
+	// number of mandatory keywords
+	num = naxis+3;
+      }
+    // extensions
+    else
+      {
+	if (hdutype == IMAGE_HDU)
+	  {
+	    // read NAXIS
+	    int naxis=0;
+	    fits_read_key(fileptr,TINT,"NAXIS",&naxis,NULL,&status);
+	    // number of mandatory keywords
+	    num = naxis+5;
+	  }
+	else
+	  if(hdutype == ASCII_TBL || hdutype == BINARY_TBL)
+	    {
+	      // number of mandatory keywords
+	      num = 8;
+	    }
+      }
+  int j;
+  for(j = num+1; j <= nkeys; j++)
+    {
+      fits_read_keyn(fileptr,j,card,strval,NULL,&status);
+      if(status) printerror(status);
+
+      strncpy(keyname,card,LEN_KEYWORD-1);
+      if(strncmp(keyname,comkey,LEN_KEYWORD-1) != 0 && strlen(keyname) != 0 
+	 && strlen(strval) != 0)
+	{
+	  fits_get_keytype(strval,&dtype,&status);
+	  if(status)  printerror(status);
+	  
+	  strip(keyname, 'B',' '); 
+	  strip(strval, 'B',' ');
+	  strip(strval, 'B','\'');
+	  
+	  switch( dtype )  
+	    { 
+	    case 'C':
+	      fits_read_key(fileptr,TSTRING,keyname,strval,comment,&status);
+              if ( strncmp(keyname,"TTYPE",5) == 0 || 
+		   strncmp(keyname,"TFORM",5) == 0 ||
+		   strncmp(keyname,"TBCOL",5) == 0 ) break;
+	      dvl[keyname]= strval;
+	      dvl.SetComment(keyname, comment);
+	      break;
+	    case 'I':
+	      int ival;
+	      fits_read_key(fileptr,TINT,keyname,&ival,comment,&status);
+	        dvl[keyname]= (int_4) ival;		// Portage mac DY
+		dvl.SetComment(keyname, comment);
+	      break;
+	    case 'L':
+	      int ilog;
+	      fits_read_key(fileptr,TLOGICAL,keyname,&ilog,comment,&status);
+	      dvl[keyname]= (int_4) ilog;
+	      dvl.SetComment(keyname, comment);
+	      break;
+	    case 'F':
+	      double dval;
+	      fits_read_key(fileptr,TDOUBLE,keyname,&dval,comment,&status);
+	      dvl[keyname]= dval;
+	      dvl.SetComment(keyname, comment);
+	      break;
+	    }
+	  
+	}
+    } 
+  //    dvl.Print();
+} 
+
+
+/*!
+  \class SOPHYA::FitsOutFile
+  \ingroup FitsIOServer
+ Class for loading  SOPHYA objects from FITS Format Files (uses cfitsio lib)
+*/
+
+FitsOutFile::FitsOutFile()
+{
+  InitNull(); 
+}
+
+   /*! \fn SOPHYA::FitsOutFile::FitsOutFile(char flnm[], WriteMode wrm)
+
+\param <WriteMode>  enum , WriteMode = clear -> if alreadyy exists, the file will be overwritten (else created) ; WriteMode = append -> further objects will be appended to the file if it exists (else : file created). WriteMode = unknown -> file created if does not exist, else : exception. (the last situation is the default)
+
+   */
+
+FitsOutFile::FitsOutFile(string const & flnm, WriteMode wrm)
+{
+  InitNull();
+  openoutputfitsfile(flnm.c_str(), wrm);
+}
+
+FitsOutFile::FitsOutFile(const char * flnm, WriteMode wrm)
+{
+  InitNull();
+  openoutputfitsfile(flnm, wrm);
+}
+
+void FitsOutFile::openoutputfitsfile(const char * flnm, WriteMode wrm)
+{
+  int status = 0; 
+
+  // create new FITS file
+  fits_create_file(&fptr_,flnm,&status);
+  if( status )
+    {
+
+      switch (wrm)
+	{
+      // si on veut ecrire a la fin de ce fichier
+	case append :
+	  status = 0;
+	  fits_clear_errmsg();
+	  fits_open_file(&fptr_,flnm,READWRITE,&status);
+	  if( status )
+	    {
+	      cout << " error opening file: " << flnm << endl;
+	      printerror(status, "failure opening a file supposed to exist");
+	    }
+	  else cout << " file " << flnm << " opened, new objects will be appended " << endl;
+	  fits_get_num_hdus(fptr_, &hdunum_, &status);
+	  int hdutype;
+	  fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
+	  if( status ) printerror( status,":FitsFile::WriteF : erreur movabs");
+	  break;
+       
+	case clear :
+	  {
+	    status = 0;
+	    fits_clear_errmsg();
+	    char* newname = new char[strlen(flnm)+2];
+	    //
+	    newname[0] = '!';
+	    newname[1] = '\0';
+	    strcat(newname, flnm);
+	    fits_create_file(&fptr_,newname,&status);
+	    delete [] newname;
+	    if (status)
+	      {
+		cout << " error opening file: " << flnm << endl;
+		printerror(status, "unable to open file, supposed to exist");
+	      }
+	    else  cout << "  WARNING : file " << flnm << " is overwritten " << endl;
+	    break;
+	  }
+	case unknown : 
+	  printerror(status, " file seems already to exist");
+	  break;
+      
+	}
+    }
+}
+
+
+
+/*! \fn void SOPHYA::FitsOutFile::makeHeaderImageOnFits(char type, int nbdim, int* naxisn,  DVList &dvl) 
+
+create an IMAGE header on FITS file.
+\param <type> type of data (see method ColTypeFromFits)
+\param <nbdim>  number of dimensions : 1D, 2D, 3D etc. = NAXIS
+\param <naxisn>  array containind sizes of the different dimensions
+*/
+void FitsOutFile::makeHeaderImageOnFits(char type, int nbdim, int* naxisn,  DVList* ptr_dvl) 
+{
+  int status = 0;
+  long naxis = nbdim;
+  long* naxes = new long[nbdim];
+  bool hdunfirst= (hdunum_ == 0);
+  if (hdunfirst)
+    {
+      if (imageOnPrimary_ == false)
+	{ 
+	  hdunum_ = 1;
+	  fits_create_img(fptr_,FLOAT_IMG,0,naxes,&status);
+	}
+    }
+  int k;
+  for (k=0; k< nbdim; k++) naxes[k] = (long)naxisn[k];
+  if (type == 'D')
+    fits_create_img(fptr_,DOUBLE_IMG,naxis,naxes,&status);
+  else
+    if  (type == 'E')
+      fits_create_img(fptr_,FLOAT_IMG,naxis,naxes,&status);
+    else
+      if  (type == 'I')
+	fits_create_img(fptr_,LONG_IMG,naxis,naxes,&status);
+      else
+	{
+	  cout << " type of data: " << type << endl;
+	  throw PException("FitsFile:::makeHeaderImageOnFits:unprogrammed type of data ");
+	}
+
+  // on ajoute eventuellement un dvlist prepare et la doc SOPHYA
+  hdunum_++;
+  if (hdunfirst) 
+    {
+      addDVListOnPrimary();
+      writeSignatureOnFits(1);
+    }
+
+  // header format FITS
+   
+   writeAppendedHeaderOnFits();
+
+  // write supplementary keywords (from SOPHYA)
+  //  dvl.Print();
+  if (ptr_dvl != NULL) addKeywordsOfDVList(*ptr_dvl);
+
+  delete [] naxes;
+  if( status ) printerror( status, "erreur creation HDU IMAGE"  );
+
+}
+
+
+/*! \fn void SOPHYA::FitsOutFile::PutImageToFits(int nbData, double* map) const
+
+write double data from array 'map'on an IMAGE extension 
+\param <nbData>  number of data to be written
+*/
+void FitsOutFile::PutImageToFits(int nbData, r_8* map) const
+{
+  int status = 0;
+  long npix= nbData;
+  fits_write_img(fptr_,TDOUBLE,1,npix,map,&status); 
+  if( status ) printerror( status, "erreur ecriture PutImageToFits" );
+}
+
+/*! \fn void SOPHYA::FitsOutFile::PutImageToFits(int nbData, float* map) const
+
+same as previous method with float data 
+*/
+void FitsOutFile::PutImageToFits(int nbData, r_4* map) const
+{
+  int status = 0;
+  long npix= nbData;
+  fits_write_img(fptr_,TFLOAT,1,npix, map,&status); 
+  if( status ) printerror( status, "erreur ecriture PutImageToFits" );
+
+}
+
+  /*! \fn void SOPHYA::FitsOutFile::PutImageToFits( int nbData, int* map) const
+
+ same as previous method with int data */
+void FitsOutFile::PutImageToFits( int nbData, int_4* map) const
+{
+  int status = 0;
+
+  long npix= nbData;
+  fits_write_img(fptr_,TINT,1,npix,map,&status); 
+  if( status ) printerror( status, "erreur ecriture PutImageToFits" );
+}
+
+
+
+/*! \fn void SOPHYA::FitsOutFile::makeHeaderBntblOnFits( string fieldType, vector<string> Noms, int nentries, int tfields, DVList &dvl, string extname, vector<int> taille_des_chaines)
+
+create an BINTABLE header on FITS file.
+\param <fieldType> array conta
+ining characters denoting types of the different column (see method ColTypeFromFits)
+\param <Noms>  array of the names of columns
+\param <nentries>  number of data of each column
+\param <tfields> number of columns
+\param <dvl> a SOPHYA DVList containing keywords to be appended
+\param <extname> keyword EXTNAME for FITS file
+\param <taille_des_chaines> vector containing the number of characters of  data  for each char* typed column, with order of appearance in 'fieldType'
+*/
+void FitsOutFile::makeHeaderBntblOnFits(string fieldType, vector<string> Noms, int nentries, int tfields, DVList* ptr_dvl, string extname, vector<int> taille_des_chaines) 
+{ 
+  int k;
+  int status = 0;
+  long nrows;
+  // verifications de coherences
+
+  if (fieldType.length() != tfields)
+    {
+      cout << " nombre de champs :" << tfields << "nombre de types: " << fieldType.length() << endl;
+      throw ParmError("FitsFile:: fields and types don't match");
+
+    }
+  if (tfields >  Noms.size())
+    {
+      cout << " WARNING: FitsOutFile::makeHeaderBntblOnFits, length of vector of column names not equal to total number of columns" << endl;
+      for (k=0; k<(tfields-Noms.size()); k++) Noms.push_back( string(" "));
+    }
+  
+  // nombre de variables "chaines de caracteres"
+  int nbString = 0;
+  for (k=0; k<tfields;k++) if (fieldType[k] == 'A') nbString++;
+  // coherence de la longueur du vecteur des tailles 
+  if (nbString >  taille_des_chaines.size())
+    {
+      cout << " WARNING: FitsOutFile::makeHeaderBntblOnFits, length of vector of string lengths  not equal to total number of columns" << endl;
+      int strSz=0;
+      for (k=0; k<taille_des_chaines.size(); k++) if ( taille_des_chaines[k] > strSz) strSz = taille_des_chaines[k];
+      for (k=0; k<(nbString-taille_des_chaines.size()); k++) taille_des_chaines.push_back(strSz);
+    }
+  char ** ttype= new char*[tfields];
+  char ** tform= new char*[tfields];
+  char largeur[FLEN_VALUE];
+  int noColString=0;
+  for (k=0; k<tfields;k++)
+    {
+      char  format[FLEN_VALUE];
+      
+      if(nentries < 1024) 
+	{
+	  nrows= nentries;
+	  if (fieldType[k] == 'A')
+	    {
+	      sprintf(largeur,"%d",taille_des_chaines[noColString++]);
+	      strcpy(format,largeur);
+	    }
+	  else strcpy(format,"1");
+	}
+      else
+	{
+	  nrows = nentries/1024;
+	  if(nentries%1024 != 0) nrows++;
+	  if (fieldType[k] == 'A') 
+	    {
+	      char largaux[FLEN_VALUE];
+	      sprintf(largeur,"%d",taille_des_chaines[noColString]);
+	      sprintf(largaux,"%d",1024*taille_des_chaines[noColString]);
+	      noColString++;
+	      strcpy(format, largaux);    
+	    }
+	  else strcpy(format,"1024");
+	}
+      strncat(format,&fieldType[k],1);
+      if (fieldType[k] == 'A') 
+	{
+	  strcat(format,largeur);
+	}
+      ttype[k] =  const_cast<char*>(Noms[k].c_str());
+      tform[k]= new char[FLEN_VALUE];
+      strcpy(tform[k],format);
+    }
+  char* extn = const_cast<char*>(extname.c_str());
+
+  // create a new empty binary table onto the FITS file
+  // physical units if they exist, are defined in the DVList object
+  // so the NULL pointer is given for the tunit parameters.
+  nrows=0;
+  fits_create_tbl(fptr_,BINARY_TBL,nrows,tfields,ttype,tform,
+		  NULL,extn,&status);
+  if( status ) printerror( status );
+
+  int ii;
+  for(ii = 0; ii < tfields; ii++)
+    {
+      delete [] tform[ii];
+    }
+  delete [] ttype;
+  delete [] tform;
+
+  // on ajoute eventuellement des mots-cles
+
+  if ( hdunum_ == 0 )
+    {
+      hdunum_ = 2;
+      addDVListOnPrimary();
+      writeSignatureOnFits(1);
+    }
+  else  hdunum_++;
+
+  // header format FITS
+   
+   writeAppendedHeaderOnFits();
+
+  // write SOPHYA keywords
+  if (ptr_dvl != NULL) addKeywordsOfDVList(*ptr_dvl);
+}
+
+ 
+
+/*! \fn void SOPHYA::FitsOutFile::PutColToFits(int nocol, int nentries, double* donnees) const
+
+write double data from array 'donnees ' on column number 'nocol' of a BINTABLE  extension.
+\param <nentries>  number of data to be written
+*/
+
+void FitsOutFile::PutColToFits(int nocol, int nentries, r_8* donnees) const
+{
+  int status = 0;
+  int hdutype;
+  fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
+  if( status ) printerror(status,"PutColToFits: le movabs a foire");
+  fits_get_hdu_type(fptr_, &hdutype, &status);
+    if(hdutype != ASCII_TBL && hdutype != BINARY_TBL)
+        {
+            cout << " hdunum= " << hdunum_ << " hdutype= " << hdutype << endl;
+     throw IOExc("FitsFile::PutColToFits, this HDU is not an ASCII table nor a binary table");
+          }
+  int code; 
+  long repeat, width;
+  fits_get_coltype(fptr_, nocol+1, &code, &repeat,&width, &status);
+  if( code != TDOUBLE)
+    {
+      cout << " WARNING : types don't match (PutColToFits) : on fits file= " << code << " to be written= DOUBLE " << endl;
+    } 
+  //  cout << " 10 elements de colonne " << endl;
+  //  for (int toto=0; toto < 10; toto++) cout << donnees[toto] << endl;
+  fits_write_col(fptr_,TDOUBLE,nocol+1,1,1,nentries, donnees ,&status);
+  if( status )  printerror( status,"erreur ecriture col. double, dans fichier fits" );
+}
+
+
+
+  /*! \fn void SOPHYA::FitsOutFile::PutColToFits(int nocol, int nentries, float* donnees) const
+
+same as previous method with float data 
+*/
+void FitsOutFile::PutColToFits(int nocol, int nentries, r_4* donnees) const
+{
+  int status = 0;
+  int hdutype;
+  fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
+  if( status ) printerror(status,"PutColToFits: le movabs a foire");
+  fits_get_hdu_type(fptr_, &hdutype, &status);
+  if(hdutype != ASCII_TBL && hdutype != BINARY_TBL)
+    {
+      cout << " hdunum= " << hdunum_ << " hdutype= " << hdutype << endl;
+      throw IOExc("FitsFile::PutColToFits, this HDU is not an ASCII table nor a binary table");
+    }
+  if(hdutype == ASCII_TBL && nocol>0)
+    {
+      throw IOExc("FitsFile::PutColToFits, this HDU is an ASCII table, nocol>0  forbidden");
+    }
+  int code; 
+  long repeat, width;
+  fits_get_coltype(fptr_, nocol+1, &code, &repeat,&width, &status);
+  if( code != TFLOAT)
+    {
+      cout << " WARNING : types don't match (PutColToFits) : on fits file= " << code << " (FITS code), to be written= FLOAT " << endl;
+    } 
+  fits_write_col(fptr_,TFLOAT,nocol+1,1,1,nentries, donnees ,&status);
+  if( status )  printerror( status,"erreur ecriture col. floats, dans fichier fits" );
+}
+
+
+/*! \fn void FitsOutFile::PutColToFits(int nocol, int nentries, int* donnees) const
+
+same as previous method with int data 
+*/
+void FitsOutFile::PutColToFits(int nocol, int nentries, int_4* donnees) const
+{
+  int status = 0;
+  int hdutype;
+  fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
+  if( status ) printerror(status,"PutColToFits: le movabs a foire");
+  fits_get_hdu_type(fptr_, &hdutype, &status);
+  if(hdutype != ASCII_TBL && hdutype != BINARY_TBL)
+    {
+      cout << " hdunum= " << hdunum_ << " hdutype= " << hdutype << endl;
+      throw IOExc("FitsFile::PutColToFits, this HDU is not an ASCII table nor a binary table");
+    }
+  if(hdutype == ASCII_TBL && nocol>0)
+    {
+      throw IOExc("FitsFile::PutColToFits, this HDU is an ASCII table, nocol>0  forbidden");
+    }
+  int code; 
+  long repeat, width;
+  fits_get_coltype(fptr_, nocol+1, &code, &repeat,&width, &status);
+    
+
+  
+  if (code == TINT || code == TLONG)
+    {
+      // cfitsio n'a que des entiers de longueur inferieure a 32 bits.
+      // ici, a l'ecriture TLONG impliquerait que le tableau de donnees
+      // soit un tableau int_8. Donc c'est toujours TINT qu;il faut mettre
+      // De plus, j'ai l'impression que TINT va devenir obsolete dans cfitsio
+      // (GLM)
+      fits_write_col(fptr_,TINT,nocol+1,1,1,nentries, donnees ,&status);
+    }
+  else
+    {
+      cout << " WARNING : types don't match (PutColToFits) : on fits file= " << code << " (FITS code), to be written= integers " << endl;
+    } 
+  if( status )  printerror( status,"erreur ecriture col. entiers, dans fichier fits" );
+}
+
+
+/*! \fn void SOPHYA::FitsOutFile::PutColToFits(int nocol, int nentries, char** donnees) const
+same as previous method with char* data 
+*/
+void FitsOutFile::PutColToFits(int nocol, int nentries, char** donnees) const
+{
+  int status = 0;
+  int hdutype;
+  fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
+  if( status ) printerror(status,"PutColToFits: le movabs a foire");
+  fits_get_hdu_type(fptr_, &hdutype, &status);
+  if(hdutype != ASCII_TBL && hdutype != BINARY_TBL)
+    {
+      cout << " hdunum= " << hdunum_ << " hdutype= " << hdutype << endl;
+      throw IOExc("FitsFile::PutColToFits, this HDU is not an ASCII table nor a binary table");
+    }
+  if(hdutype == ASCII_TBL && nocol>0)
+    {
+      throw IOExc("FitsFile::PutColToFits, this HDU is an ASCII table, nocol>0  forbidden");
+    }
+  int code; 
+  long repeat, width;
+  fits_get_coltype(fptr_, nocol+1, &code, &repeat,&width, &status);
+  if( code != TSTRING)
+    {
+      cout << " WARNING : types don't match (PutColToFits) : on fits file= " << code << " (FITS code), to be written= char** " << endl;
+    } 
+  fits_write_col(fptr_,TSTRING,nocol+1,1,1,nentries, donnees ,&status);
+  if( status )  printerror( status,"erreur ecriture col. chars, dans fichier fits" );
+}
+
+void FitsOutFile::PutBinTabLine(long NoLine,  BnTblLine& ligne) const
+{
+  // on ne fait pas de verification de type, ni de dimension ici, pour 
+  // des raisons de performances
+  int k;
+  int status= 0;
+  int    anynul;
+  int ncol=0;
+  long nels=1;
+  //  int nbcols;
+  //  fits_get_num_cols(fptr_, &nbcols,&status);
+  for (k=0; k<ligne.ddata_.size(); k++, ncol++)
+    {
+      fits_write_col(fptr_,TDOUBLE,ncol+1,NoLine+1,1,1, &ligne.ddata_[k] ,&status);
+      if( status ) printerror( status, "PutBinTabLine : erreur ecriture double"  );
+    }
+  for (k=0; k<ligne.fdata_.size(); k++, ncol++)
+    {
+      fits_write_col(fptr_,TFLOAT,ncol+1,NoLine+1,1,1, &ligne.fdata_[k] ,&status);
+      if( status ) printerror( status, "PutBinTabLine : erreur ecriture float"  );
+    }
+  for (k=0; k<ligne.idata_.size(); k++, ncol++)
+    {
+      fits_write_col(fptr_,TINT,ncol+1,NoLine+1,1,1, &ligne.idata_[k] ,&status);
+      if( status ) printerror( status, "PutBinTabLine : erreur ecriture entier"  );
+    }
+  for (k=0; k<ligne.ldata_.size(); k++, ncol++)
+    {
+      fits_write_col(fptr_,TLONG,ncol+1,NoLine+1,1,1, &ligne.ldata_[k] ,&status);
+      if( status ) printerror( status, "PutBinTabLine : erreur ecriture entier long"  );
+    }
+  for (k=0; k<ligne.bdata_.size(); k++, ncol++)
+    {
+      fits_write_col(fptr_,TBYTE,ncol+1,NoLine+1,1,1, &ligne.bdata_[k] ,&status);
+      if( status ) printerror( status, "PutBinTabLine : erreur ecriture byte"  );
+    }
+  
+  for (k=0; k<ligne.cdata_.size(); k++, ncol++)
+    {
+      fits_write_col(fptr_,TSTRING,ncol+1,NoLine+1,1,1, (void*)ligne.cdata_[k].c_str() ,&status);
+      if( status ) printerror( status, "PutBinTabLine : erreur ecriture caracteres"  );
+    }
+}
+
+
+/* \fn void  SOPHYA::FitsOutFile::DVListIntoPrimaryHeader(DVList& dvl) const
+
+Put keywords from a DVList into the primary header of the fits-file 
+*/
+void  FitsOutFile::DVListIntoPrimaryHeader(DVList& dvl) 
+{
+  int status = 0;
+  int hdutype;
+  if (hdunum_ == 0) 
+    {
+      if (dvlToPrimary_ == NULL) dvlToPrimary_ = new DVList(dvl);
+      else dvlToPrimary_->Merge(dvl);
+    }
+  else
+    {
+      fits_movabs_hdu(fptr_,1,&hdutype,&status);
+      addKeywordsOfDVList(dvl);
+      fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
+    }
+}
+
+
+void FitsOutFile::writeSignatureOnFits(int hdunum) const
+{
+  int status = 0;
+  int hdutype;
+  char keyname[LEN_KEYWORD];
+  char strval[FLEN_VALUE];
+  char comment[FLEN_COMMENT];
+  if (hdunum_ == 0) 
+    {
+      cerr << " WARNING : can't write keywords on non existing primary header" << endl;
+      return;
+    }
+  fits_movabs_hdu(fptr_,1,&hdutype,&status);
+  //
+  strncpy(keyname, "CREATOR", LEN_KEYWORD); 
+  keyname[7] = '\0';
+  strcpy(strval, "SOPHYA");
+  strcpy(comment," SOPHYA Package - FITSIOServer ");
+  fits_write_key(fptr_, TSTRING, keyname, &strval, comment, &status);
+  if( status ) printerror( status );
+  fits_write_date(fptr_, &status);
+  fits_write_comment(fptr_,"..............................................", &status);
+  fits_write_comment(fptr_, " SOPHYA package - FITSIOSever ", &status);
+  fits_write_comment(fptr_, " (C) LAL/IN2P3-CNRS Orsay,  FRANCE 2000", &status);
+  fits_write_comment(fptr_, " (C) DAPNIA/CEA     Saclay, FRANCE 2000", &status);
+  fits_write_comment(fptr_,"..............................................", &status);
+  if( status ) printerror( status, "erreur writeSignatureOnFits"  );
+  //
+  fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
+}
+
+
+void FitsOutFile::addKeywordsOfDVList( DVList& dvl) const
+{
+  int status = 0;
+  fits_write_comment(fptr_,"---------- keywords from SOPHYA ---------", &status);
+  DVList::ValList::const_iterator it;
+  for(it = dvl.Begin(); it != dvl.End(); it++)
+    {
+      MuTyV::MTVType keytype= (*it).second.elval.Type();
+      char keyname[LEN_KEYWORD];
+      strncpy(keyname,(*it).first.substr(0,64).c_str(),LEN_KEYWORD);
+      int bout = ((*it).first.substr(0,64).length() < LEN_KEYWORD) ? (*it).first.substr(0,64).length() : LEN_KEYWORD-1;
+      keyname[bout] = '\0';
+      string key((*it).first.substr(0,64));
+	//      string key(keyname);
+      char comment[FLEN_COMMENT];
+      char strval[FLEN_VALUE]= "";
+      char *comkey = "COMMENT";
+      //      fits_read_keyword(fptr_, keyname, strval, NULL, &status);
+      //  if (status != 0 || strncmp(keyname,comkey,LEN_KEYWORD-1) == 0 ) 
+	{
+	  string coco = dvl.GetComment(key);
+	  coco.copy( comment, FLEN_COMMENT-1);
+	  int bout = (coco.length() < FLEN_COMMENT) ? coco.length() : FLEN_COMMENT-1;
+	  comment[bout]= '\0';
+	  status = 0;
+	  switch (keytype)
+	    {
+	    case MuTyV::MTVInteger :
+	      {
+		int ival = (int)dvl.GetI(key);
+		fits_write_key(fptr_,TINT,keyname,&ival, comment,&status);
+		break;
+	      }
+	    case MuTyV::MTVFloat :
+	      {
+		double dval= (double)dvl.GetD(key);
+		fits_write_key(fptr_,TDOUBLE,keyname,&dval,comment,&status);
+		break;
+	      }
+	    case MuTyV::MTVString :
+	      {
+		char strvaleur[FLEN_VALUE]= "";
+		string valChaine = dvl.GetS(key);
+		valChaine.copy(strvaleur, FLEN_VALUE-1);
+		int fin =  (valChaine.length() < FLEN_VALUE) ? valChaine.length() : FLEN_VALUE-1;
+		strvaleur[fin]= '\0';
+
+		fits_write_key(fptr_,TSTRING,keyname,&strvaleur,comment,&status);
+		break;
+	      }
+	    } 
+	}
+  if( status )  printerror( status,"fitsfile: probleme ecriture mot-cle du dvlist" );
+    }
+  fits_write_comment(fptr_,"--------------------------------------", &status);
+}
+
+
+void FitsOutFile::addDVListOnPrimary()
+    {
+      int status = 0;
+      int hdutype;
+      if (hdunum_ == 0) 
+	{
+	  cerr << " WARNING : can't write keywords on non existing primary header" << endl;
+	  return;
+	}
+      if (dvlToPrimary_ != NULL)
+	{
+	  fits_movabs_hdu(fptr_,1,&hdutype,&status);
+	  addKeywordsOfDVList(*dvlToPrimary_);
+	  delete dvlToPrimary_;
+	  dvlToPrimary_ = NULL;
+	  fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
+	}
+    }
+
+
+/*! \fn void  FitsOutFile::appendInHeader(FitsInFile& infits, int hdunum)
+
+get a header from FitsInFile and append to the header beeing built
+(shifting mandatory keywords)
+*/ 
+
+void FitsOutFile::appendInputHeader(FitsInFile& infits, int hdunum)
+{
+
+  infits.GetKeywordsFromHeader(hdunum, mots_cles_);
+  /*
+  int status = 0;
+  int hdutype;
+  fitsfile* fptr=infits.fitsfilePtr();
+  fits_movabs_hdu(fptr,hdunum,&hdutype,&status);
+  if( status ) fits_report_error(stderr,status);
+
+  // get number of keywords
+  int nkeys,keypos;
+  fits_get_hdrpos(fptr,&nkeys,&keypos,&status);
+  if( status ) fits_report_error(stderr,status);
+  // shift with the number of mandatory keywords
+  int num= 0;
+  // if primary header
+    if (hdunum == 1) 
+      {
+	// read NAXIS
+	int naxis=0;
+	fits_read_key(fptr,TINT,"NAXIS",&naxis,NULL,&status);
+	// number of mandatory keywords
+	num = naxis+3;
+      }
+    // extensions
+    else
+      {
+	if (hdutype == IMAGE_HDU)
+	  {
+	    // read NAXIS
+	    int naxis=0;
+	    fits_read_key(fptr,TINT,"NAXIS",&naxis,NULL,&status);
+	    // number of mandatory keywords
+	    num = naxis+5;
+	  }
+	else
+	  if(hdutype == ASCII_TBL || hdutype == BINARY_TBL)
+	    {
+	      // number of mandatory keywords
+	      num = 8;
+	    }
+      }
+  int j;
+  char keyname[LEN_KEYWORD];  
+  char value[FLEN_VALUE];
+  char comment[FLEN_COMMENT];
+  for(j = num+1; j <= nkeys; j++)
+    {
+      char dtype;
+      fits_read_keyn(fptr,j,keyname,value,comment,&status);
+      if(status) 
+	{
+	  fits_report_error(stderr,status);
+	  status=0;
+	}
+      string  kn(keyname);
+      string  cm(comment);
+      string  val(value);
+      FitsKeyword kw(kn, val, cm);
+      mots_cles_.push_back(kw);
+    }
+  */
+}
+void FitsOutFile::writeAppendedHeaderOnFits()
+{
+  for (list<FitsKeyword>::iterator it=mots_cles_.begin(); it !=mots_cles_.end(); it++)
+    {
+      (*it).writeOnFits(fptr_);
+    } 
+  mots_cles_.clear();
+}
+
+void FitsOutFile::insertKeywordOnHeader(string keyname, double value, string comment)
+{
+  char cvalue[16];
+  sprintf(cvalue,"%e",value);
+  FitsKeyword kw(keyname, string(cvalue), comment, 'F');
+  mots_cles_.push_back(kw);
+}
+void FitsOutFile::insertKeywordOnHeader(string keyname, int value, string comment)
+{
+  char cvalue[16];
+  sprintf(cvalue,"%d",value);
+  FitsKeyword kw(keyname, string(cvalue), comment, 'I');
+  mots_cles_.push_back(kw);
+}
+void FitsOutFile::insertKeywordOnHeader(string keyname, string value, string comment)
+{
+  FitsKeyword kw(keyname, value , comment, 'C');
+  mots_cles_.push_back(kw);
+}
+
+void FitsOutFile::insertCommentLineOnHeader(string comment)
+{
+  FitsKeyword kw(comment);
+  mots_cles_.push_back(kw);
+}
+
+void FitsOutFile::PrintHeaderToBeAppended()
+{
+  cout << " contenu du header en cours de fabrication " << endl;
+  for (list<FitsKeyword>::iterator it=mots_cles_.begin(); it !=mots_cles_.end(); it++)
+    {
+      (*it).Print();
+    } 
+}
+
+
+FitsKeyword::FitsKeyword()
+  {
+    datatype_=' ';
+    keyname_ = string("");
+    dvalue_=0.;
+    ivalue_=1;
+    svalue_=string("");
+    comment_=string("");
+  }
+
+FitsKeyword::FitsKeyword(string comment)
+  {
+    datatype_=' ';
+    keyname_=string("COMMENT");
+    comment_=comment;
+  } 
+
+FitsKeyword::FitsKeyword(string keyname, string value, string comment) :  keyname_(keyname), comment_(comment)
+  {
+    int status=0;
+    char dtype;
+    const char* val= value.c_str();
+    char* valk = const_cast<char*>(val);
+    fits_get_keytype(valk,&dtype,&status);
+    if(status) 
+      {
+	status=0;
+	if (status == VALUE_UNDEFINED) cout << "WARNING (FitsKeyword) : undefined keyword value " << endl;
+	datatype_=' ';
+      }
+    else     datatype_=dtype;
+    
+    switch( datatype_ )  
+      { 
+      case 'C':
+	{
+	  strip(valk, 'B','\'');
+	  svalue_ = string(valk);
+	    break;
+	}
+      case 'I':
+	{
+	  ivalue_ = atoi(val);
+	  break;
+	}
+      case 'L':
+	{
+	  bool bb = value.c_str();
+	  ivalue_ = (int)bb;
+	  break;
+	  }
+      case 'F':
+	{
+	  dvalue_ = atof(val);
+	  break;
+	}
+      case 'X':
+	{
+	  throw IOExc("FitsKeyword , complex keyword value not supported");
+	}
+      }
+  }
+
+// constructeur pour les mots-cles maison (ne prvenant pas de la lecture d'un fichier fits)
+FitsKeyword::FitsKeyword(string keyname, string value, string comment, char type) :  keyname_(keyname), comment_(comment), datatype_(type)
+  {
+    char dtype;
+    const char* val= value.c_str();
+    char* valk = const_cast<char*>(val);
+    switch( datatype_ )  
+      { 
+      case 'C':
+	{
+	  strip(valk, 'B','\'');
+	  svalue_ = string(valk);
+	    break;
+	}
+      case 'I':
+	{
+	  ivalue_ = atoi(val);
+	  break;
+	}
+      case 'L':
+	{
+	  bool bb = value.c_str();
+	  ivalue_ = (int)bb;
+	  break;
+	  }
+      case 'F':
+	{
+	  dvalue_ = atof(val);
+	  break;
+	}
+      case 'X':
+	{
+	  throw IOExc("FitsKeyword , complex keyword value not supported");
+	}
+      }
+  }
+
+void FitsKeyword::writeOnFits(fitsfile* ptr) 
+  {
+    int status=0;
+    char keyname[LEN_KEYWORD];
+    char comment[FLEN_COMMENT];
+    keyname_.copy(keyname, LEN_KEYWORD); 
+    int bout = (keyname_.length() < LEN_KEYWORD) ? keyname_.length() : LEN_KEYWORD-1;
+    keyname[bout] = '\0';
+    comment_.copy( comment, FLEN_COMMENT);
+    bout = (comment_.length() < FLEN_COMMENT) ? comment_.length() : FLEN_COMMENT-1;
+    comment[bout]= '\0';
+
+  int nkeys,keypos;
+  fits_get_hdrpos(ptr,&nkeys,&keypos,&status);
+    switch( datatype_ )  
+      { 
+      case 'C':
+	{
+	  char value[FLEN_VALUE]="";
+	  svalue_.copy(value, FLEN_VALUE-1);
+	  int fin =  (svalue_.length() < FLEN_VALUE) ? svalue_.length() : FLEN_VALUE-1;
+	  value[fin]= '\0';
+	  fits_write_key(ptr,TSTRING,keyname,&value, comment,&status);
+	  fits_report_error(stderr,status);
+	  break;
+	}
+      case 'I':
+	{
+	  fits_write_key(ptr,TINT,keyname,&ivalue_, comment,&status);
+	  fits_report_error(stderr,status);
+	  break;
+	}
+      case 'L':
+	{
+	  fits_write_key(ptr,TLOGICAL,keyname,&ivalue_, comment,&status);
+	  fits_report_error(stderr,status);
+	  break;
+	}
+      case 'F':
+	{
+	  fits_write_key(ptr,TDOUBLE,keyname,&dvalue_, comment,&status);
+	  fits_report_error(stderr,status);
+	  break;
+	}
+      case 'X':
+	{
+	  cout << "FitsKeyword : complex keyword value not supported" << endl;;
+	  break;
+	}
+      default :
+	{
+	  char *comkey = "COMMENT";
+	  if(strncmp(keyname,comkey,LEN_KEYWORD-1) == 0)
+	    {
+	      fits_write_comment(ptr,comment,&status);
+	      fits_report_error(stderr,status);
+	    }
+	  else
+	    {
+	      cout << " WARNING  (FitsKeyword::writeOnFits) : unrecognized keyword : " << keyname_ << endl;
+	    }
+	}
+      }
+  }
+
+void FitsKeyword::Print()
+  {
+    switch( datatype_ )  
+      { 
+      case 'C':
+	{
+	  cout << " mot cle : " << keyname_ << " valeur : " << svalue_ << " commentaire : " << comment_ <<endl;
+	  break;
+	}
+      case 'I':
+	{
+	  cout << " mot cle : " << keyname_ << " valeur : " << ivalue_ << " commentaire : " << comment_ <<endl;
+	  break;
+	}
+      case 'L':
+	{
+	  cout << " mot cle : " << keyname_ << " valeur : " << ivalue_ << " commentaire : " << comment_ <<endl;
+	  break;
+	}
+      case 'F':
+	{
+	  cout << " mot cle : " << keyname_ << " valeur : " << dvalue_ << " commentaire : " << comment_ <<endl;
+	  break;
+	}
+      case 'X':
+	{
+	  cout << "FitsKeyword : complex keyword value not supported" << endl;;
+	}
+      default :
+	{
+	  cout << " mot cle : " << keyname_ << " commentaire : "  << comment_ <<endl;
+	}
+      }
+  }
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsfile.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsfile.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsfile.h	(revision 2309)
@@ -0,0 +1,429 @@
+#ifndef FITSFILE_H
+#define FITSFILE_H
+
+#include "ndatablock.h"
+#include "dvlist.h"
+#include "FitsIO/fitsio.h" 
+
+#define OPENFILE    0
+#define CREATEFILE  1
+#define LEN_KEYWORD 9
+
+// classes for saving/loading SOPHYA objects to/from FITS files...
+// Guy le Meur (september 2000)
+
+
+namespace SOPHYA {
+
+  struct BnTblLine;
+  class BufferLine;
+  class FitsFile;
+  class FitsInFile;
+  class FitsOutFile;
+
+
+
+class  FitsKeyword
+{
+
+ public:
+
+FitsKeyword();
+FitsKeyword(string comment);
+FitsKeyword(string keyname, string value, string comment); 
+FitsKeyword(string keyname, string value, string comment, char type); 
+void writeOnFits(fitsfile* ptr);
+
+void Print();
+
+ private:
+
+  char datatype_;
+  string keyname_;
+  double dvalue_;
+  int ivalue_;
+  string svalue_;
+  string comment_;
+};
+
+
+
+//
+//! Class for managing Interface for SOPHYA objects to FITS Format Files (uses cfitsio lib)
+
+class FitsIOHandler {
+
+
+ public:
+
+   virtual ~FitsIOHandler() {}
+   void   Read(char flnm[],int hdunum= 0);
+   void   Write(char flnm[]) ;
+   void   Read(FitsInFile& ifts, int hdunum=0);
+   void   Write(FitsOutFile& ofts) ;
+
+
+ protected:
+  
+   virtual void    ReadFromFits(FitsInFile& is)=0;           
+   virtual void    WriteToFits(FitsOutFile& os) =0;   
+        
+   friend class FitsInFile;
+   friend class FitsOutFile;
+  };
+
+
+//! Class (virtual) for managing FITS format files
+ class FitsFile {
+
+ public:
+
+   enum WriteMode {append, clear, unknown};
+
+   enum FitsExtensionType {
+     FitsExtensionType_NULL,
+     FitsExtensionType_IMAGE,
+     FitsExtensionType_ASCII_TBL,
+     FitsExtensionType_BINARY_TBL,
+     FitsExtensionType_EOF,
+     FitsExtensionType_ERROR
+   };
+   enum FitsDataType {
+     FitsDataType_NULL,
+     FitsDataType_double,
+     FitsDataType_float,
+     FitsDataType_int,
+     FitsDataType_char,
+     FitsDataType_ASCII,
+     FitsDataType_long,
+     FitsDataType_byte,
+     FitsDataType_short
+   };
+
+
+class BufferLine
+
+  {
+    public :
+
+BufferLine() {;}
+BufferLine(const vector<FitsFile::FitsDataType>& types);
+inline const vector< pair<FitsFile::FitsDataType, int> >& identificateur() const {return id_;}
+ inline r_8&    r_8Array(int k) { return ddata_[k];}
+ inline const r_8&    r_8Array(int k) const { return ddata_[k];}
+ inline r_4& r_4Array(int k) { return fdata_[k];}
+ inline const r_4& r_4Array(int k) const { return fdata_[k];}
+
+
+ inline int_2& int_2Array(int k) { return shdata_[k];}
+ inline const int_2& int_2Array(int k) const { return shdata_[k];}
+ inline int_4& int_4Array(int k) { return idata_[k];}
+ inline const int_4& int_4Array(int k) const { return idata_[k];}
+
+
+ inline int_8& int_8Array(int k) { return ldata_[k];}
+ inline const int_8& int_8Array(int k) const { return ldata_[k];}
+ inline string& stringArray(int k) { return cdata_[k];}
+ inline const string& stringArray(int k) const { return cdata_[k];}
+ inline unsigned char& u_charArray(int k) { return bdata_[k];}
+ inline const unsigned char& u_charArray(int k) const { return bdata_[k];}
+
+
+ void Print() const;
+
+
+    private :
+      // la paire contient le type de la variable et le rang dans le tableau
+      // du type
+   vector< pair<FitsFile::FitsDataType, int> > id_;
+   vector<r_8>     ddata_;
+   vector<r_4>     fdata_;
+   vector<int_2>   shdata_; 
+   vector<int_4>   idata_; 
+   vector<int_8>   ldata_;
+   vector<string>  cdata_;
+   vector<unsigned char>   bdata_;
+  };
+
+
+
+   FitsFile() { InitNull(); };
+   virtual ~FitsFile();
+   static string GetErrStatus(int status);
+   inline  int   statusF() const { return fits_status_;}
+   inline void firstImageOnPrimaryHeader(bool choice) {imageOnPrimary_=choice;}
+   inline int currentHeaderIndex() {return hdunum_;}
+ 
+
+ protected:
+
+
+
+
+
+
+void         ResetStatus(int& status) ; 
+static  void printerror(int&) ;
+static  void printerror(int&,char* texte) ;
+static  void printerrorAndContinue(int& status, char* texte);
+inline void  InitNull() 
+  {
+    fptr_ = NULL; 
+    hdutype_= FitsExtensionType_NULL; 
+    hdunum_ = 0; 
+    fits_status_ = 0; imageOnPrimary_ = true;
+  }
+inline fitsfile* fitsfilePtr() const {return fptr_;}
+
+
+
+   fitsfile *fptr_;     /**<  pointer to the FITS file, defined in fitsio.h */
+   FitsExtensionType hdutype_;        /**<  image or bintable ? */
+   int hdunum_;         /**<   index of header to be read/written */
+   int fits_status_;    /**< last status returned by fitsio library. updated only by several methods */
+   bool imageOnPrimary_;
+
+   BufferLine bfl_;
+
+
+ };
+
+//! Class for saving  SOPHYA objects on FITS Format Files (uses cfitsio lib)
+
+ class FitsInFile : public  FitsFile {
+
+ public:
+   FitsInFile();
+   FitsInFile(string const & flnm);
+   FitsInFile(const char * flnm);
+   ~FitsInFile() { ; };
+
+   static int  NbBlocks(char flnm[]);
+   int  NbBlocks();
+   static void GetBlockType(char flnm[], int hdunum, FitsExtensionType& typeOfExtension, int& naxis, vector<int>& naxisn, FitsDataType& dataType, DVList& dvl  );
+
+   void  ReadHeader(int hdunum);
+bool hasKeyword(int hdunum, string keyw);
+string getStringKeyword(int hdunum, string keyname,int& retStatus);
+
+  /*! \return a reference on a DVList containing the keywords from FITS file */
+  inline const DVList& DVListFromFits() const { return dvl_;}
+
+  void GetKeywordsFromHeader (int hdunum, list<FitsKeyword>& mots_cles) const;
+
+
+  DVList  DVListFromPrimaryHeader() const;
+  void    moveToFollowingHeader();
+
+
+
+
+       //////////////////////////////////////////////////////////
+       ///////   methods for managing extensions ////////////////
+       //////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////
+//       methods for managing FITS IMAGE extension
+///////////////////////////////////////////////////
+
+
+
+/*! \return true if the current header  corresponds to a FITS image extension */
+inline bool IsFitsImage() const { return (hdutype_ == FitsExtensionType_IMAGE);}
+
+
+
+  /*! \return number of dimensions of an image extension : NAXIS parameter (in FITS notations)   */
+inline int nbDimOfImage() const {return naxis_;}
+
+/*! \return a reference on a vector containing sizes of the NAXIS dimensions : NAXIS1, NAXIS2, NAXIS3 etc.  */
+ inline const vector<int>& dimOfImageAxes() const { return naxisn_;}
+
+
+/*! \return total number of data in the current IMAGE extension */
+inline int nbOfImageData() const { return nbData_; }
+
+/*! \return data type of the current IMAGE extension */
+inline FitsFile::FitsDataType ImageType() const {return imageDataType_;}
+
+
+
+//////////////////////////////////////////////////////////////////////////
+//       methods for managing FITS BINARY TABLE or ASCII TABLE extension
+////////////////////////////////////////////////////////////////////////
+
+
+
+
+/*! \return true if the current header  corresponds to a FITS ASCII or BINTABLE extension */
+inline bool IsFitsTable() const {return (hdutype_ == FitsExtensionType_ASCII_TBL || hdutype_ == FitsExtensionType_BINARY_TBL);}
+
+
+
+
+ static  void GetBinTabParameters(fitsfile* fileptr, int& nbcols, int& nrows,
+				  vector<int>& repeat,
+				  vector<string>& noms, 
+				  vector<FitsDataType>& types,   
+				  vector<int>&  taille_des_chaines);
+ FitsDataType   ColTypeFromFits(int nocol) const;
+ string ColNameFromFits(int nocol) const;
+ int    ColStringLengthFromFits(int nocol) const;
+ const BufferLine& GetBufferLine(long NoLine); 
+ void   GetBinTabLine(int NoLine, double* ddata, float* fdata, int* idata, char
+** cdata) ;
+ void   GetBinTabLine(long NoLine, BnTblLine& ligne) ;
+ void   GetBinTabLine(int NoLine, float* fdata) ;
+ void   GetBinTabFCol(r_8* valeurs, int nentries, int NoCol) const;
+ void   GetBinTabFCol(r_4* valeurs, int nentries, int NoCol) const;
+ void   GetBinTabFCol(int_4* valeurs, int nentries,  int NoCol) const;
+ void   GetBinTabFCol(char** valeurs,int nentries, int NoCol) const;
+
+/////////////////////////////////////////////////////////////
+//       methods for managing any type of FITS extension
+////////////////////////////////////////////////////////
+
+/*! \return true if the current header  is beyond the maximum */
+inline bool IsFitsEOF() const {return (hdutype_ == FitsExtensionType_EOF);}
+/*! \return true if the current header  is incorrect, following a cfitsio, movavs error */
+inline bool IsFitsERROR() const {return (hdutype_ == FitsExtensionType_ERROR);}
+
+  int     NbColsFromFits() const;
+  int     NentriesFromFits(int nocol) const;
+
+
+  void    GetSingleColumn(r_8* map, int nentries) const;
+
+  void    GetSingleColumn(r_4*  map, int nentries) const;
+
+  void    GetSingleColumn(int_4* map, int nentries) const;
+
+
+
+
+
+  private :
+
+void InitNull();
+
+void getHeaderWithSophyaObject();
+static void KeywordsIntoDVList(fitsfile* fileptr, DVList& dvl, int hdunum); 
+static  void GetImageParameters (fitsfile* fileptr,FitsDataType& dataType,int& naxis,vector<int>& naxisn);
+
+ FitsDataType imageDataType_;          /**< fits-Image parameter (bitpix)*/
+ int naxis_;           /**< fits-Image parameter */
+ vector<int> naxisn_;  /**< fits-Image parameters : sizes of dimensions */
+ int nbData_;          /*< fits-Image parameter: number of data */
+ int nrows_;           /**< Bintable parameter */
+ vector<int> repeat_;  /**< Bintable parameter */
+ int nbcols_;          /**< Bintable parameter */
+ vector<string> noms_; /**< Bintable parameter: column names */
+ vector<FitsDataType> types_;  /**< Bintable parameters: types of columns (D: double, E: float, I: integers,  A: char*) */
+ DVList dvl_;          /**< DVList for transferring keywords */
+ vector<int>  taille_des_chaines_; /**< Bintable parameters:   length of the char* variables */
+
+  double dnull_;
+  float fnull_;
+  int inull_;
+  string cnull_;
+
+ 
+
+ };
+
+//! Class for loading  SOPHYA objects from FITS Format Files (uses cfitsio lib)
+
+ class FitsOutFile : public  FitsFile {
+
+ public:
+
+   FitsOutFile();
+   FitsOutFile(string const & flnm, WriteMode wrm = unknown );
+   FitsOutFile(const char * flnm, WriteMode wrm = unknown );
+   ~FitsOutFile() { if (dvlToPrimary_ != NULL) delete dvlToPrimary_;};
+   inline void InitNull() {dvlToPrimary_ = NULL;}
+
+       //////////////////////////////////////////////////////////
+       ///////   methods for managing extensions ////////////////
+       //////////////////////////////////////////////////////////
+
+
+
+/////////////////////////////////////////////////////////////
+//       methods for managing FITS IMAGE extension
+///////////////////////////////////////////////////
+
+
+   void makeHeaderImageOnFits(char type, int nbdim, int* naxisn, DVList* dvl) ;
+   void PutImageToFits( int nbData, r_8* map) const;
+   void PutImageToFits(int nbData, r_4* map ) const;
+   void PutImageToFits(int nbData, int_4* map) const;
+
+
+
+//////////////////////////////////////////////////////////////////////////
+//       methods for managing FITS BINARY TABLE or ASCII TABLE extension
+////////////////////////////////////////////////////////////////////////
+
+
+
+   void makeHeaderBntblOnFits ( string fieldType, vector<string> Noms, int nentries, int tfields, DVList* dvl, string extname,  vector<int> taille_des_chaines) ;
+   void appendInputHeader(FitsInFile& headerin, int hdunum);
+   void writeAppendedHeaderOnFits();
+   void PrintHeaderToBeAppended();
+   void insertCommentLineOnHeader(string comment);
+   void insertKeywordOnHeader(string keyname, double value, string comment); 
+   void insertKeywordOnHeader(string keyname, int value, string comment); 
+   void insertKeywordOnHeader(string keyname, string value, string comment); 
+   void PutColToFits(int nocol, int nentries, r_8* donnees) const;
+   void PutColToFits(int nocol, int nentries, r_4* donnees) const;
+   void PutColToFits(int nocol, int nentries, int_4* donnees) const;
+   void PutColToFits(int nocol, int nentries, char** donnees) const;
+   void PutBinTabLine(long NoLine,  BnTblLine& ligne) const;
+
+
+/////////////////////////////////////////////////////////////
+//       methods for managing any type of FITS extension
+////////////////////////////////////////////////////////
+
+
+void  DVListIntoPrimaryHeader(DVList& dvl) ;
+
+
+
+  private :
+
+  void openoutputfitsfile(const char * flnm, WriteMode wrm);
+  void writeSignatureOnFits(int hdunum) const; 
+  void addKeywordsOfDVList( DVList& dvl) const;
+  void addDVListOnPrimary();
+
+  DVList* dvlToPrimary_; /**< for transferring keywords when creating primary header */
+  list<FitsKeyword>  mots_cles_;
+
+ };
+
+ struct BnTblLine 
+ {
+   BnTblLine() {}
+   void setFormat(int dc, int fc, int ic, int lc, int bc, int cc, vector<string> names);
+   bool sameFormat(const BnTblLine& btl) const;
+
+   void Print();
+
+   vector<double> ddata_;
+   vector<float>  fdata_;
+   vector<int>    idata_; 
+   vector<string>  cdata_;
+   vector<string> ColName_;
+   vector<long>   ldata_;
+   vector<unsigned char>   bdata_;
+
+ };
+
+
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsioserver.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsioserver.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsioserver.h	(revision 2309)
@@ -0,0 +1,18 @@
+#ifndef FITSIOSERVER_SEEN
+#define FITSIOSERVER_SEEN
+
+#include "fitsfile.h"
+#include "fitstarray.h"
+#include "fitsspherehealpix.h"
+#include "fitsntuple.h"
+#include "fitsxntuple.h"
+#include "fitslocalmap.h"
+#include "fitsautoreader.h"
+#include "fitsbntbllineRW.h"
+#include "fbtntintf.h"
+
+#include "fabtcolread.h"
+#include "fabtwriter.h"
+#include "fboloread.h"
+
+#endif // FITSIOSERVER_SEEN
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/fitslocalmap.cc
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/fitslocalmap.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/fitslocalmap.cc	(revision 2309)
@@ -0,0 +1,251 @@
+#include "machdefs.h"
+#include "fitslocalmap.h" 
+///////////////////////////////////////////////////////////
+//   Les objets delegues pour la gestion de persistance sur fichiers fits 
+//    pout LocalMap
+///////////////////////////////////////////////////////////
+ 
+/*!
+  \class SOPHYA::FITS_LocalMap
+  \ingroup FitsIOServer
+  FITS format I/O handler for SOPHYA::LocalMap objects.
+*/
+
+using namespace SOPHYA;
+
+template <class T>
+FITS_LocalMap<T>::FITS_LocalMap()
+{
+  dobj_= NULL;
+  ownobj_=false;
+}
+
+template <class T>
+FITS_LocalMap<T>::FITS_LocalMap(char inputfile[],int hdunum)
+{
+  dobj_=NULL;
+  ownobj_=false; 
+  Read(inputfile,hdunum);
+}
+
+template <class T>
+FITS_LocalMap<T>::FITS_LocalMap(const LocalMap<T> & obj) 
+{ 
+    dobj_ = new LocalMap<T>(obj);
+  ownobj_=true; 
+}
+
+template <class T>
+FITS_LocalMap<T>::FITS_LocalMap(LocalMap<T> *obj) 
+{ 
+  dobj_ = obj;
+  ownobj_=false; 
+}
+
+
+template <class T>
+FITS_LocalMap<T>::~FITS_LocalMap()
+{
+  if (ownobj_ && dobj_) delete dobj_;
+}
+
+
+template <class T>
+AnyDataObj* FITS_LocalMap<T>::DataObj()
+{
+  return(dobj_);
+}
+
+
+template <class T>
+void   FITS_LocalMap<T>::SetDataObj(AnyDataObj & o) 
+  {   
+    LocalMap<T>* po = dynamic_cast<  LocalMap<T>* >(& o); 
+    if (po == NULL) return;
+    if (ownobj_ && dobj_) delete dobj_;  
+    dobj_ = po; 
+    ownobj_ = false; 
+  }    
+
+template <class T>
+void FITS_LocalMap<T>::ReadFromFits(FitsInFile& is)
+{
+  if(dobj_ == NULL) 
+    {
+      dobj_= new LocalMap<T>;
+      ownobj_= true;      
+    }
+  int nbentries;
+
+  // lecture sur bin-table
+  //
+  //  if (!is.IsFitsTable())
+  // {
+  //     throw PException("ReadFromFits: the fits file seems not to be a bintable");
+  //  }
+  // int nbcols;
+  // nbcols = is.NbColsFromFits();
+  // if (nbcols != 1) 
+  //  {
+  //    throw IOExc("le fichier fits n'est pas une LocalMap");
+  //  }
+  // nbentries = is.NentriesFromFits(0);
+  //
+
+  // lecture sur image fits
+  //
+  if (!is.IsFitsImage())
+    {
+      throw PException("ReadFromFits: the fits file seems not to be an image");
+    }
+  int dimension = is.nbDimOfImage();
+  if (dimension != 2 )
+    {
+      cout << " WARNING::ReadFromFits: the fits image seems not to be a matrix" << endl;
+    }
+  nbentries =  is.nbOfImageData();
+  //
+
+  DVList dvl=is.DVListFromFits();
+  
+  int_4 nSzX = dvl.GetI("NSZX");
+  int_4 nSzY = dvl.GetI("NSZY");
+  int_4 nPix = dvl.GetI("NPIX");
+  if (nPix != nbentries)
+    {
+      throw IOExc("longueur datablock incompatible avec nPix");
+    }
+  dobj_->ReSize(nSzX, nSzY); 
+  int_4 localMappingDone = dvl.GetI("LCMP");
+  if (localMappingDone)
+    {
+      int_4 x0 = dvl.GetI("X0");
+      int_4 y0 = dvl.GetI("Y0");
+      double theta = dvl.GetD("THETA");
+      double phi   = dvl.GetD("PHI");
+      double angle = dvl.GetD("ANGLE");
+      dobj_->SetOrigin(theta, phi, x0, y0, angle);
+      double angleX = dvl.GetD("ANGLEX");
+      double angleY = dvl.GetD("ANGLEY");
+      dobj_->SetSize(angleX, angleY);
+    }
+  // On lit les DataBlocks;
+
+  dobj_->DataBlock().ReSize(nPix);
+  is.GetSingleColumn(dobj_->DataBlock().Data(),nPix);
+
+  // dvlist de LocalMap
+  dobj_->Info()  = is.DVListFromFits();
+}
+
+template <class T>
+void FITS_LocalMap<T>::WriteToFits(FitsOutFile& os) 
+{
+  if(dobj_ == NULL) 
+    { 
+      cout << " WriteToFits:: dobj_= null " << endl;
+      return;
+    }
+  int nx, ny;
+
+  DVList dvl( dobj_->Info() );
+  nx = dobj_->Size_x();  
+  dvl["NSZX"] = nx;
+  dvl.SetComment("NSZX", "number of pixels in x direction");
+  ny = dobj_->Size_y();
+  dvl["NSZY"] = ny;
+  dvl.SetComment("NSZY", "number of pixels in y direction");
+  dvl["NPIX"] = dobj_->NbPixels();
+  dvl.SetComment("NPIX", "number of pixels in local map");
+
+  if(dobj_->LocalMap_isDone())
+    {
+      dvl["LCMP"] = (int_4) 1;
+      dvl.SetComment("LCMP", "local mapping 1= done, 0= not done");
+      int_4 x0 = 0;
+      int_4 y0 = 0;
+      double theta = 0.;
+      double  phi = 0.;
+      double  angle = 0.;
+      dobj_->Origin(theta, phi, x0, y0, angle);
+      dvl["X0"]     = x0;
+      dvl.SetComment("X0", "number of pixel of the origin, x direction");
+      dvl["Y0"]     = y0;
+      dvl.SetComment("Y0", "number of pixel of the origin, y direction");
+      dvl["THETA"]  = theta;
+      dvl.SetComment("THETA", "theta position of the map-origin");
+      dvl["PHI"]    = phi;
+      dvl.SetComment("PHI", "phi position of the map origin");
+      dvl["ANGLE"]  = angle;
+      dvl.SetComment("ANGLE", "angle between max x axis and sphere phi-axis");
+
+      double angleX =0.;
+      double angleY = 0.;
+      dobj_->Aperture(angleX, angleY);
+      dvl["ANGLEX"] = angleX;
+      dvl.SetComment("ANGLEX", "sphere angle covered by map x-extension ");
+      dvl["ANGLEY"] = angleY;
+      dvl.SetComment("ANGLEY", "sphere angle covered by map y-extension ");
+    }
+  else
+    {
+      dvl["LCMP"] = (int_4) 0;
+    }
+  dvl["Content"]= "LocalMap";
+  dvl.SetComment("Content", "name of SOPHYA object");
+  // On ecrit les dataBlocks 
+  vector<string> Noms;   
+  Noms.push_back(dvl.GetS("Content"));
+  string extname("SIMULATION");
+
+  // sortie sur image fits
+  //
+  char type;
+  if ( typeid(T) == typeid(r_8) ) type='D';
+  else 
+    if ( typeid(T) == typeid(r_4) )  type='E';
+    else
+      if ( typeid(T) == typeid(int_4) )  type='J';
+      else
+	{
+	  cout <<  " type du tableau= " <<  typeid(T).name() << endl;
+	  throw IOExc("FITS_LocalMap:: unknown type");
+	}
+  int nbdim = 2;
+  int* naxisn = new int[nbdim];
+  naxisn[0] = dobj_->Matrix().Size(0);
+  naxisn[1] = dobj_->Matrix().Size(1);
+  os.makeHeaderImageOnFits(type, nbdim, naxisn, &dvl);
+  os.PutImageToFits(nx*ny, dobj_->Matrix().Data());
+
+  delete [] naxisn;
+  //
+
+  // sortie sur bin-table fits
+  //
+  //  string Type;
+  //  if (typeid(T) == typeid(r_8) ) Type+='D';
+  //  else 
+  //   if (typeid(T) == typeid(r_4) )  Type+='E';
+  //   else
+  //    {
+  //	cout <<  " type de la LocalMap = " <<  typeid(T).name() << endl;
+  //	throw IOExc("FITS_LocalMap:: unknown type");
+  //    }
+  //  vector<int> dummy;
+  //  os.makeHeaderBntblOnFits(Type, Noms, dobj_->NbPixels(), 1, &dvl, extname, dummy);
+  //  os.PutColToFits(0,  dobj_->NbPixels(), dobj_->DataBlock().Data()); 
+  //
+
+}
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template FITS_LocalMap<r_8>
+#pragma define_template FITS_LocalMap<r_4>
+#pragma define_template FITS_LocalMap<int_4>
+#endif
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class FITS_LocalMap<r_8>;
+template class FITS_LocalMap<r_4>;
+template class FITS_LocalMap<int_4>;
+#endif
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/fitslocalmap.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/fitslocalmap.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/fitslocalmap.h	(revision 2309)
@@ -0,0 +1,54 @@
+// Guy Le Meur 08/2000
+
+
+#ifndef FITSLOCALMAP_SEEN
+#define FITSLOCALMAP_SEEN
+
+
+#include "pexceptions.h" 
+#include "localmap.h"
+#include "fitsfile.h"
+
+namespace SOPHYA {
+
+
+/////////////////////////////////////////////////////////////////////////
+// Classe pour la gestion de persistance sur fichiers fits
+/////////////////////////////////////////////////////////////////////////
+
+
+
+template <class T>
+class FITS_LocalMap : public FitsIOHandler {
+
+  public :
+FITS_LocalMap();
+FITS_LocalMap(char inputfile[],int hdunum=0);
+FITS_LocalMap(const LocalMap<T> & obj);
+FITS_LocalMap(LocalMap<T> *obj);
+virtual ~FITS_LocalMap();
+virtual AnyDataObj* DataObj();
+virtual   void      SetDataObj(AnyDataObj & o); 
+inline operator LocalMap<T>() { return(*dobj_); }
+
+protected :
+
+void ReadFromFits(FitsInFile& is);
+void WriteToFits(FitsOutFile& os) ;
+
+  LocalMap<T> * dobj_;
+  bool ownobj_;
+};
+//////////////////////////////////////////////////////////////////
+
+template <class T>
+inline FitsOutFile& operator << (FitsOutFile& fios, LocalMap<T> & lm)
+  { FITS_LocalMap<T> fih(&lm); fih.Write(fios); return (fios); }
+
+template <class T>
+inline FitsInFile& operator >> (FitsInFile& fiis, LocalMap<T> & lm)
+  { FITS_LocalMap<T> fih(&lm); fih.Read(fiis); return (fiis); }
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsntuple.cc
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsntuple.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsntuple.cc	(revision 2309)
@@ -0,0 +1,192 @@
+#include "pexceptions.h"
+#include "fitsntuple.h"
+///////////////////////////////////////////////////////////
+//   Les objets delegues pour la gestion de persistance sur fichiers fits 
+//    pout NTuple
+///////////////////////////////////////////////////////////
+
+
+#define LONNOM 8
+#define LONNOM1  (LONNOM+1)
+
+
+/*!
+  \class SOPHYA::FITS_NTuple
+  \ingroup FitsIOServer
+  FITS format I/O handler for SOPHYA::NTuple objects.
+*/
+
+FITS_NTuple::FITS_NTuple()
+{
+  dobj_ = new NTuple;
+  InitNull();
+  ownobj_ = true;
+}
+
+FITS_NTuple::FITS_NTuple(char inputfile[],int hdunum)
+{
+  dobj_ = new NTuple;
+  InitNull();
+  ownobj_ = true; 
+
+  Read(inputfile,hdunum);
+}
+
+
+FITS_NTuple::FITS_NTuple(const NTuple & obj) 
+{ 
+  dobj_ = new NTuple(obj);
+  InitNull();
+  ownobj_ = true; 
+}
+FITS_NTuple::FITS_NTuple(NTuple* obj) 
+{ 
+  dobj_ = obj;
+  InitNull();
+  ownobj_ = false; 
+}
+
+
+FITS_NTuple::~FITS_NTuple()
+{
+  if (ownobj_ && dobj_ != NULL) delete dobj_;
+  //  if (column_ != NULL) delete [] column_;
+}
+
+//void FITS_NTuple::Read(char inputfile[],int hdunum)
+//{
+//  ReadF(inputfile,hdunum);
+//}
+void FITS_NTuple::ReadLines(char inputfile[],int firstLine, int numberOfLines,int hdunum)
+{
+  fistLineToBeRead_ = firstLine;
+  numberOfLinesToBeRead_ = numberOfLines;
+  Read(inputfile,hdunum);
+}
+
+
+
+//void FITS_NTuple::Write(char outputfile[], bool OldFile)
+//{
+//  WriteF(outputfile, OldFile);
+//}
+
+void FITS_NTuple::ReadFromFits(FitsInFile& is)
+{
+  if (!is.IsFitsTable())
+    {
+      throw PException("ReadFromFits: the fits file seems not to be a bintable nor ASCII table");
+    }
+  int nbcols, nbentries;
+  nbcols = is.NbColsFromFits();
+  nbentries = 0;
+  int k;
+  for (k=0; k<nbcols; k++) nbentries=max( nbentries, is.NentriesFromFits(k) );
+  
+  char ** ColName = new char*[nbcols];
+  
+  for (k=0; k<nbcols;k++) 
+    {
+      ColName[k] = new char[LONNOM1]; 
+      strncpy(ColName[k], is.ColNameFromFits(k).c_str(),LONNOM);
+      ColName[k][LONNOM] =  '\0';
+    }
+  for (k=0; k<nbcols;k++)
+    {
+      FitsFile::FitsDataType ss= is.ColTypeFromFits(k);
+      string type;
+      if (ss !=  FitsFile::FitsDataType_float) 
+	{
+	  if (ss == FitsFile::FitsDataType_double) type= string("double");
+	  else
+	    if (ss == FitsFile::FitsDataType_int) type= string("integer");
+	    else
+	      if (ss == FitsFile::FitsDataType_char) type = string("char*");
+	      else
+		type = string("unknown");
+	  cout << " WARNING: the column " << k << " on fits file is not float but : " << type << endl;
+	} 
+    }
+  if(dobj_ == NULL) 
+    { 
+      dobj_= new NTuple(nbcols,ColName);
+      ownobj_ = true;      
+    }
+  else 
+    {
+      dobj_->Clean();
+      (*dobj_) = NTuple(nbcols,ColName);
+    }
+  for (k=0; k<nbcols;k++) 
+    {
+      delete [] ColName[k];
+    }
+  delete [] ColName;
+
+  float* ligne = new float[nbcols];
+
+  int firstln, lastln;
+  if (numberOfLinesToBeRead_ > 0) 
+    {
+      firstln = fistLineToBeRead_;
+      lastln = firstln + numberOfLinesToBeRead_;
+    }
+  else
+    {
+      firstln = 0;
+      lastln  = nbentries;
+    }
+  int numLigne;
+  for (numLigne=firstln; numLigne < lastln; numLigne++)
+    {
+      is.GetBinTabLine(numLigne, ligne);
+      dobj_->Fill((r_4*)ligne);
+    }
+  delete [] ligne;
+
+  dobj_->Info()=is.DVListFromFits();
+}
+
+void FITS_NTuple::WriteToFits(FitsOutFile& os) 
+{
+  if(dobj_ == NULL) 
+    {
+      cout << " WriteToFits:: dobj_= null " << endl;
+      return;
+    }
+
+  // table will have 'ncols'  columns
+  int ncols = dobj_->NVar();
+
+  // table will have 'nrows' rows
+  int nentries = dobj_->NEntry();
+
+  // get names and values from the join DVList object
+  DVList dvl= dobj_->Info();
+  dvl["Content"]= "NTuple";
+  dvl.SetComment("Content", "name of SOPHYA object");
+  // extension name
+  string extname("NTuple_Binary_tbl"); 
+
+  vector<string> Noms(ncols);   
+  int k;
+  for (k=0; k< ncols; k++)
+    {
+      Noms[k]= dobj_->NomIndex(k);
+    }
+
+  string type(ncols, 'E');
+  vector<int> dummy;
+
+  os.makeHeaderBntblOnFits(type,Noms, nentries, ncols, &dvl, extname, dummy);
+   float* column =  new float[nentries];
+   for (k=0; k<ncols;k++)
+     {
+       int j;
+       for(j = 0; j < nentries; j++) column[j]= dobj_->GetVal(j,k);
+       os.PutColToFits(k, nentries, column);
+     }
+   delete [] column;
+
+}
+
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsntuple.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsntuple.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsntuple.h	(revision 2309)
@@ -0,0 +1,77 @@
+// Guy Le Meur 03/2000
+
+
+#ifndef FITSNTuple_SEEN
+#define FITSNTuple_SEEN
+#include "machdefs.h"
+#include "ntuple.h"
+#include "anydataobj.h"
+#include "ppersist.h"
+#include "fitsfile.h"
+
+namespace SOPHYA {
+///////////////////////////////////////////////////////////////////
+// Classe pour la gestion de persistance sur fichiers fits
+// pout NTuple 
+////////////////////////////////////////////////////////////////
+class  FITS_NTuple : public FitsIOHandler  
+{
+
+public:
+
+FITS_NTuple();
+FITS_NTuple(char inputfile[],int hdunum=0);
+FITS_NTuple(const NTuple & obj);
+ FITS_NTuple(NTuple* obj); 
+virtual ~FITS_NTuple();
+
+virtual   AnyDataObj* DataObj() { return(dobj_); }
+virtual   void        SetDataObj(AnyDataObj & o) 
+  {   
+    NTuple* po = dynamic_cast<  NTuple* >(& o); 
+    if (po == NULL) return;
+    if (ownobj_ && dobj_) delete dobj_;  
+    dobj_ = po; 
+    ownobj_ = false; 
+  }    
+
+
+/*!
+fill the XNTuple only with lines from firstLine-th to (firstLine+numberOfLines-1)-th of the FITS-file inputfile.
+\param <firstLine>  first line  to be read (the first line of the file is numbered 0)
+\param <numberOfLines>  number of lines to be read
+*/
+ void ReadLines(char inputfile[],int firstLine, int numberOfLines,int hdunum=0);
+
+inline operator NTuple() { return(*dobj_); }
+inline NTuple * getObj() { return(dobj_); }
+
+protected:
+
+  // implementation de FitsFile
+virtual void ReadFromFits(FitsInFile& is);
+virtual void WriteToFits(FitsOutFile& os) ;
+
+ private : 
+
+inline void InitNull() { fistLineToBeRead_= -1; numberOfLinesToBeRead_= -1;}
+
+
+  // attributs de classe
+  NTuple* dobj_;
+  bool ownobj_;
+  int fistLineToBeRead_;
+  int numberOfLinesToBeRead_;
+};
+//////////////////////////////////////////////////////////////////
+
+inline FitsOutFile& operator << (FitsOutFile& fios, NTuple & nt)
+  { FITS_NTuple fih(&nt); fih.Write(fios); return (fios); }
+
+inline FitsInFile& operator >> (FitsInFile& fiis, NTuple & nt)
+  { FITS_NTuple fih(&nt); fih.Read(fiis); return (fiis); }
+
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsspherehealpix.cc
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsspherehealpix.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsspherehealpix.cc	(revision 2309)
@@ -0,0 +1,294 @@
+#include "pexceptions.h"
+#include "fitsspherehealpix.h"
+#include "tarray.h"
+#include "fitstarray.h" 
+
+
+
+///////////////////////////////////////////////////////////////////////
+// ----objets delegues  pour la gestion de persistance I/O format fits--
+// SphereHealpix
+////////////////////////////////////////////////////////////////////
+
+/*!
+  \class SOPHYA::FITS_SphereHEALPix
+  \ingroup FitsIOServer
+  FITS format I/O handler for SOPHYA::SphereHEALPix objects.
+*/
+
+
+template <class T>
+FITS_SphereHEALPix<T>::FITS_SphereHEALPix()
+{
+  dobj_= new SphereHEALPix<T>;
+  ownobj_= true;
+}
+  
+template <class T>
+FITS_SphereHEALPix<T>::FITS_SphereHEALPix(char inputfile[],int hdunum)
+{
+    dobj_= new SphereHEALPix<T>;
+    ownobj_= true;
+  Read(inputfile,hdunum);
+}
+
+
+template <class T>
+FITS_SphereHEALPix<T>::FITS_SphereHEALPix(const SphereHEALPix<T>& obj)
+{
+  dobj_= new SphereHEALPix<T>(obj);
+  ownobj_= true;
+}
+
+template <class T>
+FITS_SphereHEALPix<T>::FITS_SphereHEALPix(SphereHEALPix<T>* obj)
+{
+  dobj_= obj;
+  ownobj_= false;
+}
+
+template <class T>
+FITS_SphereHEALPix<T>::~FITS_SphereHEALPix()
+{
+  if (ownobj_ && dobj_) delete dobj_;
+}
+
+template <class T>
+AnyDataObj* FITS_SphereHEALPix<T>::DataObj()
+{
+  return(dobj_);
+}
+
+template <class T>
+void FITS_SphereHEALPix<T>::SetDataObj(AnyDataObj & o)
+{
+  SphereHEALPix<T> * po = dynamic_cast< SphereHEALPix<T> * >(&o);
+  if (po == NULL) return;
+  if (ownobj_ && dobj_) delete dobj_;
+  dobj_ = po; 
+  ownobj_ = false;
+} 
+
+
+
+template <class T>
+void FITS_SphereHEALPix<T>::WriteToFits(FitsOutFile& os) 
+{
+  if(dobj_ == NULL) 
+    { 
+      cout << " WriteToFits:: dobj_= null " << endl;
+      return;
+    }
+
+  DVList dvl( dobj_->Info() );  
+
+  SphereCoordSys* cs= dobj_->GetCoordSys();
+  string description= cs->description();
+  dvl["COORDSYS"]= description;
+
+  dvl["PIXTYPE"] = "HEALPIX";
+  dvl.SetComment("PIXTYPE", "HEALPIX Pixelization");
+  dvl["ORDERING"]= dobj_->TypeOfMap();
+  dvl.SetComment("ORDERING", "Pixel ordering scheme, either RING or NESTED");
+  
+  int nSide= dobj_->SizeIndex();
+  dvl["NSIDE"]= (int_4) nSide;
+  dvl.SetComment("NSIDE","Resolution parameter for HEALPIX" );
+
+  int nPix= dobj_->NbPixels();
+  dvl["FIRSTPIX"]= (int_4) 0;
+  dvl.SetComment("FIRSTPIX", "First pixel # (0 based)");
+  dvl["LASTPIX"]= (int_4) nPix-1;
+  dvl.SetComment("LASTPIX", "Last pixel # (0 based)");
+  dvl["Content"]= "SphereHEALPix";
+  dvl.SetComment("Content", "name of SOPHYA object");
+  
+  // On ecrit les dataBlocks 
+  vector<string> Noms;   
+  Noms.push_back(dvl.GetS("Content"));
+  string extname("SIMULATION");
+
+  string Type;
+  if (typeid(T) == typeid(r_8) ) Type+='D';
+  else if (typeid(T) == typeid(r_4) )  Type+='E';
+    else if (typeid(T) == typeid(int_4) )  Type+='J';
+    else
+      {
+       	cout <<  "FITS_SphereHEALPix<T>::WriteToFits()- Unsupported data type (" 
+	     <<  typeid(T).name() << ") throwing IOExc " << endl;
+	throw IOExc("FITS_SphereHEALPix<T>::WriteToFits() unsupported data type");
+      }
+  vector<int> dummy;
+  os.makeHeaderBntblOnFits(Type, Noms, nPix, 1, &dvl, extname, dummy);
+  os.PutColToFits(0,  nPix, dobj_->pixels_.Data()); 
+} 
+
+template <class T> 
+void FITS_SphereHEALPix<T>::ReadFromFits(FitsInFile& is)
+{
+  if(dobj_ == NULL) 
+    {
+      dobj_= new SphereHEALPix<T>;
+      ownobj_= true;      
+    }
+  int nbcols, nbentries;
+  //
+
+  nbcols = is.NbColsFromFits();
+  if (nbcols != 1) 
+    {
+      throw IOExc("le fichier fits n'est pas une sphere Healpix");
+    }
+  DVList dvl=is.DVListFromFits();
+   nbentries = is.NentriesFromFits(0);
+  int lastpix=dvl.GetI("LASTPIX");
+  if (lastpix>0)
+    {
+      if (nbentries!=lastpix+1) 
+	{
+	  nbentries=lastpix+1;
+      	}
+    }
+  // Let's Read the SphereCoordSys object
+  int id= SphereCoordSys_NEUTRAL;
+  string description= "NEUTRAL SphereCoordSystem";
+  string coordsys= dvl.GetS("COORDSYS");
+  // $CHECK$ - Reza 2/05/2000 - compare(size_t, size_t,...) passe pas sur g++     
+  //  if(coordsys.compare(0,7,"ROTATION",0,7) == 0)  $CHECK$ 
+  if(coordsys.substr(0,8) == "ROTATION")
+    {
+      id= SphereCoordSys_ROTATION;
+      description= "ROTATION SphereCoordSystem";
+    } 
+  //  else if(coordsys.compare(0,4,"OTHER",0,4) == 0) $CHECK$ Reza 2/05/2000 
+  else if(coordsys.substr(0,5)  == "OTHER" )
+    {
+      id= SphereCoordSys_OTHER;
+      description= "OTHER SphereCoordSystem";
+    }
+  dobj_->SetCoordSys(new SphereCoordSys(id,description));   
+
+  string ordering= dvl.GetS("ORDERING");
+  //  if(ordering.compare(0,3,"RING",0,3) != 0)  $CHECK$ Reza 2/05/2000
+  if(ordering.substr(0,4) != "RING" )
+    { 
+      cerr << "FITS_SphereHEALPix/Error Not supported ORDERING= " 
+	   << ordering << " substr(0,4)=[" << ordering.substr(0,4) << "]" << endl;
+      throw IOExc(" FITS_SphereHEALPix:: numerotation non RING");
+    }
+
+  int nside= dvl.GetI("NSIDE");
+  int nPix = 0;
+  if(nside <= 0)
+    {
+      //      throw IOExc("FITS_SphereHEALPix:: No resol parameter nside");
+      if (lastpix>0)
+	{
+	  nside = sqrt((double)(nbentries/12));
+	}
+      else
+	{
+	  //	  dvl.Print();
+	  // int naxis2 = dvl.GetI("NAXIS2");
+	  // if (naxis2 > 0 ) 
+	  //  {
+	  nside = sqrt((double)(nbentries/12));
+	      // }
+	      // else
+	      //  throw IOExc("FITS_SphereHEALPix:: No NSIDE nor LASTPIX nor NAXIS2 on file");
+	}
+    }
+  nPix = 12*nside*nside;
+  if (nPix != nbentries)
+    {
+      cout << "WARNING: le nombre de pixels relu " << nbentries << " est incoherent avec la pixelisation Healpix qui donne nPix= " << nPix << endl; 
+      }
+  double Omega= 4.0*Pi/nPix;
+  dobj_->setParameters(nside,nPix,Omega);
+  // On lit les DataBlocks;
+  //
+   dobj_->pixels_.ReSize(nPix);
+  is.GetSingleColumn(dobj_->pixels_.Data(),nPix);
+  //
+
+  // on effectue le decoupage en tranches 
+  dobj_->SetThetaSlices();
+  //
+  dobj_->Info()  = is.DVListFromFits();
+}
+
+template <class T>
+void FITS_SphereHEALPix<T>::Mollweide_picture_projection(char filename[])
+{
+  int ni = 300;
+  int nj = 600;
+  TMatrix<float> map(ni, nj);
+
+   int i,j;
+   for(i=0; i < ni; i++) 
+     {
+       double yd = (i+0.5)/ni-0.5;
+       double facteur=2.*Pi/sin(acos(yd*2));
+       double theta = (0.5-yd)*Pi;
+       for(j=0; j < nj; j++)  
+	 {
+	   double xa = (j+0.5)/nj-0.5;
+	   double phi =  xa*facteur+Pi;
+	   float th=float(theta);
+	   float ff=float(phi);
+	   if (phi<2*Pi && phi>= 0) 
+	     {
+	       map(i,j) = (float)dobj_->PixValSph(th, ff);
+	     }
+	 }
+     }
+   FitsOutFile  fout(filename);
+   fout.firstImageOnPrimaryHeader(true);
+   FITS_TArray<r_4> fta(map);
+   fta.Write(fout);
+   
+}
+template <class T>
+void FITS_SphereHEALPix<T>::sinus_picture_projection(char filename[])
+{
+  int ni = 300;
+  int nj = 600;
+  TMatrix<float> map(ni, nj);
+
+  int i,j;
+   for(i=0; i < ni; i++) 
+     {
+       double yd = (i+0.5)/ni-0.5;
+       double theta = (0.5-yd)*Pi;
+	double facteur=1./sin(theta);
+       for(j=0; j < nj; j++)  
+	 {
+	   double xa = (j+0.5)/nj-0.5;
+	   double phi = 2.*Pi*xa*facteur+Pi;
+	   float th=float(theta);
+	   float ff=float(phi);
+	   if (phi<2*Pi && phi>= 0) 
+	     {
+	       map(i,j) = (float)dobj_->PixValSph(th, ff);
+	     }
+	 }
+     }
+   FitsOutFile  fout(filename);
+   fout.firstImageOnPrimaryHeader(true);
+   FITS_TArray<r_4> fta(map);
+   fta.Write(fout);
+
+   
+}
+
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template FITS_SphereHEALPix<r_8>
+#pragma define_template FITS_SphereHEALPix<r_4>
+#pragma define_template FITS_SphereHEALPix<int_4>
+#endif
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class FITS_SphereHEALPix<r_8>;
+template class FITS_SphereHEALPix<r_4>;
+template class FITS_SphereHEALPix<int_4>;
+#endif
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsspherehealpix.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsspherehealpix.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsspherehealpix.h	(revision 2309)
@@ -0,0 +1,59 @@
+#ifndef FITSSPHEREHEALPIX_SEEN
+#define FITSSPHEREHEALPIX_SEEN
+
+
+// Guy Le Meur 03/2000
+
+
+#include "spherehealpix.h"
+#include "anydataobj.h"
+#include "fitsfile.h"
+
+namespace SOPHYA {
+///////////////////////////////////////////////////////////////////////
+// ------------- Classe pour la gestion de persistance I/O format fits--
+// spherehealpix
+//////////////////////////////////////////////////////////////////////
+template <class T>
+class FITS_SphereHEALPix : public FitsIOHandler  
+{
+public:
+
+FITS_SphereHEALPix();
+FITS_SphereHEALPix(char inputfile[],int hdunum=0); 
+FITS_SphereHEALPix(const SphereHEALPix<T>& obj);
+FITS_SphereHEALPix(SphereHEALPix<T>* obj);
+virtual ~FITS_SphereHEALPix();
+virtual AnyDataObj* DataObj();
+virtual void        SetDataObj(AnyDataObj & o);
+
+void Mollweide_picture_projection(char flnm[]);
+void sinus_picture_projection(char flnm[]);
+//void ReWriteFromFitsToFits(FitsInFile& headerin, FitsOutFile& os); 
+
+inline operator SphereHEALPix<T>() { return(*dobj_); }
+
+protected:
+
+//virtual void ReadFromFits(FitsFile& fn);
+virtual void ReadFromFits(FitsInFile& is);
+virtual void WriteToFits(FitsOutFile& os) ;
+SphereHEALPix<T>* dobj_;
+bool ownobj_;
+};
+
+
+//////////////////////////////////////////////////////////////////
+
+template <class T>
+inline FitsOutFile& operator << (FitsOutFile& fios, SphereHEALPix<T> & sph)
+  { FITS_SphereHEALPix<T> fih(&sph); fih.Write(fios); return (fios); }
+
+template <class T>
+inline FitsInFile& operator >> (FitsInFile& fiis, SphereHEALPix<T> & sph)
+  { FITS_SphereHEALPix<T> fih(&sph); fih.Read(fiis); return (fiis); }
+
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsspherethetaphi.cc
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsspherethetaphi.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsspherethetaphi.cc	(revision 2309)
@@ -0,0 +1,291 @@
+#include "pexceptions.h"
+#include "fitsspherethetaphi.h"
+#include "tarray.h"
+#include "fitstarray.h" 
+
+
+
+///////////////////////////////////////////////////////////////////////
+// ----objets delegues  pour la gestion de persistance I/O format fits--
+// SphereThetaPhi
+////////////////////////////////////////////////////////////////////
+
+/*!
+  \class SOPHYA::FITS_SphereThetaPhi
+  \ingroup FitsIOServer
+  FITS format I/O handler for SOPHYA::SphereThetaPhi objects.
+*/
+
+template <class T>
+FITS_SphereThetaPhi<T>::FITS_SphereThetaPhi()
+{
+  dobj_= new SphereThetaPhi<T>;
+  ownobj_= true;
+}
+
+template <class T>
+FITS_SphereThetaPhi<T>::FITS_SphereThetaPhi(char inputfile[],int hdunum)
+{
+    dobj_= new SphereThetaPhi<T>;
+    ownobj_= true;
+  Read(inputfile,hdunum);
+}
+
+template <class T>
+FITS_SphereThetaPhi<T>::FITS_SphereThetaPhi(const SphereThetaPhi<T>& obj)
+{
+   dobj_= new SphereThetaPhi<T>(obj);
+  ownobj_= true;
+}
+
+template <class T>
+FITS_SphereThetaPhi<T>::FITS_SphereThetaPhi(SphereThetaPhi<T>* obj)
+{
+  dobj_= obj;
+  ownobj_= false;
+}
+
+template <class T>
+FITS_SphereThetaPhi<T>::~FITS_SphereThetaPhi()
+{
+  if (ownobj_ && dobj_) delete dobj_;
+}
+
+template <class T>
+AnyDataObj* FITS_SphereThetaPhi<T>::DataObj()
+{
+  return(dobj_);
+}
+
+template <class T>
+void FITS_SphereThetaPhi<T>::SetDataObj(AnyDataObj & o)
+{
+  SphereThetaPhi<T> * po = dynamic_cast< SphereThetaPhi<T> * >(&o);
+  if (po == NULL) return;
+  if (ownobj_ && dobj_) delete dobj_;
+  dobj_ = po; 
+  ownobj_ = false;
+} 
+
+template <class T>
+void FITS_SphereThetaPhi<T>::WriteToFits(FitsOutFile& os) 
+{
+  if(dobj_ == NULL) 
+    { 
+      cout << " WriteToFits:: dobj_= null " << endl;
+      return;
+    }
+
+  DVList dvl( dobj_->Info() );  
+
+  SphereCoordSys* cs= dobj_->GetCoordSys();
+  string description= cs->description();
+  dvl["COORDSYS"]= description;
+
+  dvl["PIXTYPE"] = "TETAFI";
+  dvl.SetComment("PIXTYPE", "Theta-Phi-LAL Pixelization");
+  dvl["ORDERING"]= dobj_->TypeOfMap();
+  dvl.SetComment("ORDERING", " (unrelevant) ");
+
+  int IndTheta= dobj_->SizeIndex();
+  dvl["INDTHMAX"]= (int_4) IndTheta;
+  dvl.SetComment("INDTHMAX","Resolution parameter for Theta-Phi pixelization sch." );
+
+  int nPix= dobj_->NbPixels();
+  dvl["FIRSTPIX"]= (int_4) 0;
+  dvl.SetComment("FIRSTPIX", "First pixel # (0 based)");
+  dvl["LASTPIX"]= (int_4) nPix-1;
+  dvl.SetComment("LASTPIX", "Last pixel # (0 based)");
+  dvl["Content"]= "SphereThetaPhi";
+  dvl.SetComment("Content", "name of SOPHYA object");
+  
+  // On ecrit les dataBlocks 
+
+  // the BINTABLE consits of 4 columns 
+  // first column  : pixels values (type : T ), length : number of pixels
+  // second column : number of pixels of each theta slice (type : integer) , 
+  //       length  : number of theta-slices  (parameter INDTHMAX above +1)
+  // third  column : cumulated number of pixels until the beginning of each 
+  //       theta slice (type : integer) , same length as the previous one
+  // fourth column : theta values of each slice (type : double_) same length
+  //                 as the previous one.
+  vector<string> Noms(4);   
+  Noms[0] = dvl.GetS("Content");
+  Noms[1] = "NphiParBande";
+  Noms[2] = "CumulPixParBande";
+  Noms[3] = "ThetaBande";
+  string extname("SIMULATION");
+
+
+  string Type;
+  if (typeid(T) == typeid(r_8) ) Type+='D';
+  else if (typeid(T) == typeid(r_4) )  Type+='E';
+  else if (typeid(T) == typeid(int_4) )  Type+='J';
+    else
+      {
+	cout <<  "FITS_SphereThetaPhi<T>::WriteToFits - Unsupported data type (" 
+	     <<  typeid(T).name() << ") throwing IOExc " << endl;
+	throw IOExc("FITS_SphereThetaPhi<T>::WriteToFits() unsupported data type");
+      }
+
+  Type += 'J';
+  Type += 'J';
+  Type += 'D';
+
+  vector<int> dummy;
+  os.makeHeaderBntblOnFits(Type, Noms, nPix, 4, &dvl, extname, dummy);
+  os.PutColToFits(0,  nPix, dobj_->pixels_.Data()); 
+  os.PutColToFits(1,  IndTheta+1, dobj_->NPhi_.Data()); 
+  os.PutColToFits(2,  IndTheta+1, dobj_->TNphi_.Data()); 
+  os.PutColToFits(3,  IndTheta+1, dobj_->Theta_.Data()); 
+}
+
+template <class T> 
+void FITS_SphereThetaPhi<T>::ReadFromFits(FitsInFile& is)
+{
+
+  if(dobj_ == NULL) 
+    {
+      dobj_= new SphereThetaPhi<T>;
+      ownobj_= true;      
+    }
+  int nbcols, nbentries;
+
+  nbcols = is.NbColsFromFits();
+  if (nbcols != 4) 
+    {
+      throw IOExc("le fichier fits n'est pas une sphere ThetaPhi");
+    }
+  DVList dvl=is.DVListFromFits();
+  nbentries = is.NentriesFromFits(0);
+  int lastpix=dvl.GetI("LASTPIX");
+  if (lastpix>0)
+    {
+      if (nbentries!=lastpix+1) 
+	{
+	  nbentries=lastpix+1;
+      	}
+    }
+  
+  // Let's Read the SphereCoordSys object
+  int id= SphereCoordSys_NEUTRAL;
+  string description= "NEUTRAL SphereCoordSystem";
+  string coordsys= dvl.GetS("COORDSYS");
+  if(coordsys.substr(0,8) == "ROTATION")
+    {
+      id= SphereCoordSys_ROTATION;
+      description= "ROTATION SphereCoordSystem";
+    } 
+  else if(coordsys.substr(0,5)  == "OTHER" )
+    {
+      id= SphereCoordSys_OTHER;
+      description= "OTHER SphereCoordSystem";
+    }
+  dobj_->SetCoordSys(new SphereCoordSys(id,description));   
+  
+  int IndThetaMax= dvl.GetI("INDTHMAX");
+  int nPix = 0;
+  if(IndThetaMax <= 0)
+    {
+      throw IOExc("FITS_SphereTheta:: No resol parameter INDTHMAX");
+    }
+  nPix = nbentries;
+  double Omega= 4.0*Pi/nPix;
+  dobj_->setParameters(IndThetaMax,nPix,Omega);
+  
+  // On lit les DataBlocks;
+  //
+  // the BINTABLE consits of 4 columns 
+  // first column  : pixels values (type : T ), length : number of pixels
+  // second column : number of pixels of each theta slice (type : integer) , 
+  //       length  : number of theta-slices  (parameter INDTHMAX above +1)
+  // third  column : cumulated number of pixels until the beginning of each 
+  //       theta slice (type : integer) , same length as the previous one
+  // fourth column : theta values of each slice (type : double_) same length
+  //                 as the previous one.
+
+  dobj_->pixels_.ReSize(nPix);
+  is.GetBinTabFCol(dobj_->pixels_.Data(),nPix,0);
+  dobj_->NPhi_.ReSize(IndThetaMax+1);
+  is.GetBinTabFCol(dobj_->NPhi_.Data(),IndThetaMax+1,1);
+  dobj_->TNphi_.ReSize(IndThetaMax+1);
+  is.GetBinTabFCol(dobj_->TNphi_.Data(),IndThetaMax+1,2);
+  dobj_->Theta_.ReSize(IndThetaMax+1);
+  is.GetBinTabFCol(dobj_->Theta_.Data(),IndThetaMax+1,3);
+}
+
+template <class T>
+void FITS_SphereThetaPhi<T>::Mollweide_picture_projection(char filename[])
+{
+  int ni = 300;
+  int nj = 600;
+  TMatrix<float> map(ni, nj);
+
+   int i,j;
+   for(i=0; i < ni; i++) 
+     {
+       double yd = (i+0.5)/ni-0.5;
+       double facteur=2.*Pi/sin(acos(yd*2));
+       double theta = (0.5-yd)*Pi;
+       for(j=0; j < nj; j++)  
+	 {
+	   double xa = (j+0.5)/nj-0.5;
+	   double phi =  xa*facteur+Pi;
+	   float th=float(theta);
+	   float ff=float(phi);
+	   if (phi<2*Pi && phi>= 0) 
+	     {
+	       map(i,j) = (float)dobj_->PixValSph(th, ff);
+	     }
+	 }
+     }
+   FitsOutFile  fout(filename);
+   fout.firstImageOnPrimaryHeader(true);
+   FITS_TArray<r_4> fta(map);
+   fta.Write(fout);
+   
+}
+template <class T>
+void FITS_SphereThetaPhi<T>::sinus_picture_projection(char filename[])
+{
+  int ni = 300;
+  int nj = 600;
+  TMatrix<float> map(ni, nj);
+
+  int i,j;
+   for(i=0; i < ni; i++) 
+     {
+       double yd = (i+0.5)/ni-0.5;
+       double theta = (0.5-yd)*Pi;
+	double facteur=1./sin(theta);
+       for(j=0; j < nj; j++)  
+	 {
+	   double xa = (j+0.5)/nj-0.5;
+	   double phi = 2.*Pi*xa*facteur+Pi;
+	   float th=float(theta);
+	   float ff=float(phi);
+	   if (phi<2*Pi && phi>= 0) 
+	     {
+	       map(i,j) = (float)dobj_->PixValSph(th, ff);
+	     }
+	 }
+     }
+   FitsOutFile  fout(filename);
+   fout.firstImageOnPrimaryHeader(true);
+   FITS_TArray<r_4> fta(map);
+   fta.Write(fout);
+
+   
+}
+
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template FITS_SphereThetaPhi<r_8>
+#pragma define_template FITS_SphereThetaPhi<r_4>
+#pragma define_template FITS_SphereThetaPhi<int_4>
+#endif
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class FITS_SphereThetaPhi<r_8>;
+template class FITS_SphereThetaPhi<r_4>;
+template class FITS_SphereThetaPhi<int_4>;
+#endif
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsspherethetaphi.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsspherethetaphi.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsspherethetaphi.h	(revision 2309)
@@ -0,0 +1,63 @@
+#ifndef FITSSPHERETHETAPHI_SEEN
+#define FITSSPHERETHETAPHI_SEEN
+
+
+// Guy Le Meur 10/2001
+
+
+#include "spherethetaphi.h"
+#include "anydataobj.h"
+#include "fitsfile.h"
+namespace SOPHYA {
+///////////////////////////////////////////////////////////////////////
+// ------------- Classe pour la gestion de persistance I/O format fits--
+// spherethetaphi
+//////////////////////////////////////////////////////////////////////
+template <class T>
+class FITS_SphereThetaPhi : public FitsIOHandler  
+{
+public:
+
+FITS_SphereThetaPhi();
+FITS_SphereThetaPhi(char inputfile[],int hdunum=0); 
+FITS_SphereThetaPhi(const SphereThetaPhi<T>& obj);
+FITS_SphereThetaPhi(SphereThetaPhi<T>* obj);
+virtual ~FITS_SphereThetaPhi();
+virtual AnyDataObj* DataObj();
+virtual void        SetDataObj(AnyDataObj & o);
+
+void Mollweide_picture_projection(char flnm[]);
+void sinus_picture_projection(char flnm[]);
+
+
+inline operator SphereThetaPhi<T>() { return(*dobj_); }
+
+
+protected:
+
+virtual void ReadFromFits(FitsInFile& is);
+virtual void WriteToFits(FitsOutFile& os) ;
+SphereThetaPhi<T>* dobj_;
+bool ownobj_;
+
+
+
+};
+
+
+//////////////////////////////////////////////////////////////////
+
+template <class T>
+inline FitsOutFile& operator << (FitsOutFile& fios, SphereThetaPhi<T> & sph)
+  { FITS_SphereThetaPhi<T> fih(&sph); fih.Write(fios); return (fios); }
+
+template <class T>
+inline FitsInFile& operator >> (FitsInFile& fiis, SphereThetaPhi<T> & sph)
+  { FITS_SphereThetaPhi<T> fih(&sph); fih.Read(fiis); return (fiis); }
+
+
+
+} // Fin du namespace
+
+
+#endif
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/fitstarray.cc
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/fitstarray.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/fitstarray.cc	(revision 2309)
@@ -0,0 +1,171 @@
+#include "machdefs.h"
+#include "pexceptions.h" 
+#include "fitstarray.h" 
+///////////////////////////////////////////////////////////
+//   Les objets delegues pour la gestion de persistance sur fichiers fits 
+//    pout TArray
+///////////////////////////////////////////////////////////
+
+/*!
+  \class SOPHYA::FITS_TArray
+  \ingroup FitsIOServer
+  FITS format I/O handler for SOPHYA::TArray objects in Sophya.
+*/
+
+using namespace SOPHYA;
+
+template <class T>
+FITS_TArray<T>::FITS_TArray()
+{
+  dobj_= NULL;
+  ownobj_=false;
+}
+
+template <class T>
+FITS_TArray<T>::FITS_TArray(char inputfile[],int hdunum)
+{
+  dobj_=NULL;
+  ownobj_=false; 
+  Read(inputfile,hdunum);
+}
+
+template <class T>
+FITS_TArray<T>::FITS_TArray(const TArray<T> & obj) 
+{ 
+    dobj_ = new TArray<T>(obj);
+  ownobj_=true; 
+}
+
+template <class T>
+FITS_TArray<T>::FITS_TArray(TArray<T> *obj) 
+{ 
+  dobj_ = obj;
+  ownobj_=false; 
+}
+
+
+template <class T>
+FITS_TArray<T>::~FITS_TArray()
+{
+  if (ownobj_ && dobj_) delete dobj_;
+}
+
+
+template <class T>
+AnyDataObj* FITS_TArray<T>::DataObj()
+{
+  return(dobj_);
+}
+
+
+template <class T>
+void   FITS_TArray<T>::SetDataObj(AnyDataObj & o) 
+  {   
+    TArray<T>* po = dynamic_cast<  TArray<T>* >(& o); 
+    if (po == NULL) return;
+    if (ownobj_ && dobj_) delete dobj_;  
+    dobj_ = po; 
+    ownobj_ = false; 
+  }    
+
+
+
+template <class T>
+void FITS_TArray<T>::ReadFromFits(FitsInFile& is)
+{
+  if (!is.IsFitsImage())
+    {
+      throw PException("ReadFromFits: the fits file seems not to be an image");
+    }
+  int dimension = is.nbDimOfImage();
+  sa_size_t * siz = new sa_size_t[dimension];
+  for (int k=0; k< dimension; k++) siz[k] = is.dimOfImageAxes()[k];
+  if(dobj_ == NULL)
+    {
+      dobj_ = new TArray<T>(dimension,siz);
+      ownobj_ = true;
+    }
+  else
+    dobj_->ReSize(dimension,siz);
+  
+  delete [] siz;
+  if (dobj_->Size() != is.nbOfImageData() )
+  {
+    cout << " total size of TArray: " << dobj_->Size() << endl;
+    cout << " total size from fits file: " << is.nbOfImageData() << endl;
+      throw PException("ReadFromFits: size conflict");
+  }
+  // On lit le tableau
+  is.GetSingleColumn( dobj_->Data(),dobj_->Size());
+    dobj_->Info()  = is.DVListFromFits();
+
+}
+
+
+template <class T>
+void FITS_TArray<T>::WriteToFits(FitsOutFile& os)  
+{
+  if(dobj_ == NULL) return;
+  uint_4 nbdim = dobj_->NbDimensions();
+  if ( nbdim == 0) 
+    {
+      throw PException(" FITS_TARRAY: number of dimensions of the array = 0?");
+    }
+  //cout << "FITS_TARRAY: nombre de dimension du tableau a ecrire: " << nbdim << endl;
+  int* naxisn = new int[nbdim];
+  int k;
+  for (k=0; k< nbdim; k++)
+    {
+      naxisn[k] = dobj_->Size(k);
+     // cout << " nombre de donnees dans la la dimension " << k << " : " << naxisn[k] << endl;
+    }
+  char type;
+  if ( typeid(T) == typeid(r_8) ) type='D';
+  else 
+    if ( typeid(T) == typeid(r_4) )  type='E';
+    else
+      if ( typeid(T) == typeid(int_4) )  type='J';
+      else
+	{
+	  cout <<  " type du tableau= " <<  typeid(T).name() << endl;
+	  throw IOExc("FITS_TArray:: unknown type");
+	}
+
+  int nbels = 1;
+  for (k=0; k< nbdim; k++) 
+    {
+      if (naxisn[k] > 0) nbels *= naxisn[k];
+    }
+ // cout << " nombre total d'elements a copier " << nbels << endl;
+  DVList dvl( dobj_->Info() );  
+  dvl["Content"]= "TArray";
+  dvl.SetComment("Content", "name of SOPHYA object");
+  os.makeHeaderImageOnFits(type, nbdim, naxisn, &dvl);
+  if (!dobj_->IsPacked()) 
+    {
+      cout << " IsPacked() = " << dobj_->IsPacked() << endl;
+      throw PException(" FITS_TARRAY: this case is not yet programmed");
+      
+    }
+  if (dobj_->MinStep() != 1) 
+    {
+      cout << " MinStep()) = " << dobj_->MinStep() << endl;
+      throw PException(" FITS_TARRAY: this case is not yet programmed");
+      
+    }
+  os.PutImageToFits(nbels, dobj_->Data());
+  
+  delete [] naxisn;
+}
+
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template FITS_TArray<r_8>
+#pragma define_template FITS_TArray<r_4>
+#pragma define_template FITS_TArray<int_4>
+#endif
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class FITS_TArray<r_8>;
+template class FITS_TArray<r_4>;
+template class FITS_TArray<int_4>;
+#endif
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/fitstarray.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/fitstarray.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/fitstarray.h	(revision 2309)
@@ -0,0 +1,55 @@
+// Guy Le Meur 04/2000
+
+
+#ifndef FITSTARRAY_SEEN
+#define FITSTARRAY_SEEN
+
+
+#include "pexceptions.h" 
+#include "tarray.h"
+#include "fitsfile.h"
+
+namespace SOPHYA {
+
+
+/////////////////////////////////////////////////////////////////////////
+// Classe pour la gestion de persistance sur fichiers fits
+/////////////////////////////////////////////////////////////////////////
+
+
+
+template <class T>
+class FITS_TArray : public FitsIOHandler {
+
+public:
+
+FITS_TArray();
+FITS_TArray(char inputfile[],int hdunum=0);
+FITS_TArray(const TArray<T> & obj);
+FITS_TArray(TArray<T> *obj);
+virtual ~FITS_TArray();
+virtual AnyDataObj* DataObj();
+virtual   void      SetDataObj(AnyDataObj & o); 
+inline operator TArray<T>() { return(*dobj_); }
+
+protected :
+
+void ReadFromFits(FitsInFile& is);
+void WriteToFits(FitsOutFile& os) ;
+
+  TArray<T> * dobj_;
+  bool ownobj_;
+};
+//////////////////////////////////////////////////////////////////
+
+template <class T>
+inline FitsOutFile& operator << (FitsOutFile& fios, TArray<T> & arr)
+  { FITS_TArray<T> fih(&arr); fih.Write(fios); return (fios); }
+
+template <class T>
+inline FitsInFile& operator >> (FitsInFile& fiis, TArray<T> & arr)
+  { FITS_TArray<T> fih(&arr); fih.Read(fiis); return (fiis); }
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsxntuple.cc
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsxntuple.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsxntuple.cc	(revision 2309)
@@ -0,0 +1,398 @@
+#include "pexceptions.h"
+#include "fitsxntuple.h"
+///////////////////////////////////////////////////////////
+//   Les objets delegues pour la gestion de persistance sur fichiers fits 
+//    pout XNTuple
+///////////////////////////////////////////////////////////
+
+/*!
+  \class SOPHYA::FITS_XNTuple
+  \ingroup FitsIOServer
+  FITS format I/O handler for SOPHYA::XNTuple objects.
+*/
+
+
+#define LONNOM 31 
+
+
+FITS_XNTuple::FITS_XNTuple()
+{
+  dobj_ = new XNTuple;
+  InitNull();
+  ownobj_ = true;
+}
+
+FITS_XNTuple::FITS_XNTuple(char inputfile[],int hdunum)
+{
+  dobj_ = new XNTuple;
+  InitNull();
+  ownobj_ = true; 
+
+  Read(inputfile,hdunum);
+}
+
+
+FITS_XNTuple::FITS_XNTuple(const XNTuple & obj) 
+{ 
+  dobj_ = new XNTuple(obj);
+  InitNull();
+  ownobj_ = true; 
+}
+FITS_XNTuple::FITS_XNTuple(XNTuple* obj) 
+{ 
+  dobj_ = obj;
+  InitNull();
+  ownobj_ = false; 
+}
+FITS_XNTuple::~FITS_XNTuple()
+{
+  if (ownobj_ && dobj_ != NULL) delete dobj_;
+}
+
+
+void FITS_XNTuple::ReadLines(char inputfile[],int firstLine, int numberOfLines,int hdunum)
+{
+  fistLineToBeRead_ = firstLine;
+  numberOfLinesToBeRead_ = numberOfLines;
+  Read(inputfile,hdunum);
+}
+
+
+ 
+void FITS_XNTuple::ReadFromFits(FitsInFile& is)
+{   
+  if (!is.IsFitsTable())
+    {
+      throw PException("ReadFromFits: the fits file seems not to be a bintable nor ASCII table");
+    }
+  int nbcols, nbentries;
+  nbcols = is.NbColsFromFits();
+  nbentries = 0;
+  int k;
+  for (k=0; k<nbcols; k++) nbentries=max( nbentries, is.NentriesFromFits(k) );
+
+  //
+  // pour mettre les colonnes dans l'ordre double, float, int, char :
+  // tableau de correspondance 
+  // DfitsCol(j)= numero dans le fichier fits de la  jeme variable double du 
+  // xntuple;
+  // FfitsCol(j)= numero dans le fichier fits de la  jeme variable float du 
+  // xntuple;
+  // etc.
+  vector<int> DfitsCol;
+  vector<int> FfitsCol;
+  vector<int> IfitsCol;
+  vector<int> SfitsCol;
+  for (k=0; k<nbcols;k++)
+    {
+
+      FitsFile::FitsDataType ss= is.ColTypeFromFits(k);
+      switch (ss) 
+	{
+	case  FitsFile::FitsDataType_double :
+	  {
+	    DfitsCol.push_back(k);
+	    break;
+	  }
+	case FitsFile::FitsDataType_float :
+	  {
+	    FfitsCol.push_back(k);
+	    break;
+	  }
+	case FitsFile::FitsDataType_int :
+	  {
+	    IfitsCol.push_back(k);
+	    break;
+	  }
+	case FitsFile::FitsDataType_long :
+	  {
+	    IfitsCol.push_back(k);
+	    break;
+	  }
+	case FitsFile::FitsDataType_byte :
+	  {
+	    IfitsCol.push_back(k);
+	    break;
+	  }
+	case FitsFile::FitsDataType_char :
+	  {
+	    SfitsCol.push_back(k);
+	    break;
+	  }
+	default :
+	  {
+	    cout << " FITS_XNTuple: colonne fits " << k << " type= " << (int) ss << endl;
+	    throw  IOExc("type de champ inconnu");
+	  }
+	}
+    }
+  char ** ColName = new char*[nbcols];
+  int compt=0;
+  for (k=0; k<DfitsCol.size(); k++)
+    {
+      ColName[compt] = new char[LONNOM+1]; 
+      strncpy(ColName[compt], is.ColNameFromFits(DfitsCol[k]).c_str(), LONNOM);
+      ColName[compt++][ LONNOM] =  '\0';
+    }
+  for (k=0; k<FfitsCol.size(); k++)
+    {
+      ColName[compt] = new char[LONNOM+1]; 
+      strncpy(ColName[compt], is.ColNameFromFits(FfitsCol[k]).c_str(), LONNOM);
+      ColName[compt++][ LONNOM] =  '\0';
+    }
+  for (k=0; k<IfitsCol.size(); k++)
+    {
+      ColName[compt] = new char[LONNOM+1]; 
+      strncpy(ColName[compt], is.ColNameFromFits(IfitsCol[k]).c_str(), LONNOM);
+      ColName[compt++][ LONNOM] =  '\0';
+    }
+  for (k=0; k<SfitsCol.size(); k++)
+    {
+      ColName[compt] = new char[LONNOM+1]; 
+      strncpy(ColName[compt], is.ColNameFromFits(SfitsCol[k]).c_str(), LONNOM);
+      ColName[compt++][LONNOM] =  '\0';
+    }
+  int ND = DfitsCol.size();
+  int NF = FfitsCol.size();
+  int NI = IfitsCol.size();
+  int NS = SfitsCol.size();
+  if(dobj_ == NULL) 
+    { 
+      dobj_= new XNTuple(ND, NF, NI, NS,ColName);
+      ownobj_ = true;      
+    }
+  else 
+    {
+      if (ownobj_)
+	{
+	  (*dobj_)= XNTuple(ND, NF, NI, NS,ColName);
+	}
+      else
+	{
+	  if (ND != dobj_->NDVar() || NF != dobj_->NFVar() ||  NI != dobj_->NIVar() || NS != dobj_->NSVar())
+	    {
+	      //	      cout << " WARNING : FITS_XNTuple : XNTuple reconfigured " << endl;
+	      (*dobj_)= XNTuple(ND, NF, NI, NS,ColName);
+	    }
+	}
+    }
+
+  for (k=0; k<nbcols;k++) 
+    {
+      delete [] ColName[k];
+    }
+  delete [] ColName;
+
+    r_8* dligne;
+    r_4* fligne;
+    int_4* iligne;
+    char** cligne;
+
+  if (ND>0) dligne = new double[ND];
+  else dligne=NULL;
+  if (NF>0) fligne = new float[NF];
+  else fligne=NULL;
+  if (NI) iligne = new int[NI];
+  else iligne=NULL;
+  if (NS) 
+    {
+      cligne = new char*[NS];
+      int  taille_des_chaines=0;
+      for (k=0; k< NS; k++)  taille_des_chaines = max( taille_des_chaines, is.ColStringLengthFromFits(SfitsCol[k]) );
+      for (k=0; k<NS; k++) cligne[k]=new char[taille_des_chaines+1];
+    }
+  else cligne=NULL;
+  int firstln, lastln;
+  if (numberOfLinesToBeRead_ > 0) 
+    {
+      firstln = fistLineToBeRead_;
+      lastln = firstln + numberOfLinesToBeRead_;
+    }
+  else
+    {
+      firstln = 0;
+      lastln  = nbentries;
+    }
+  int numLigne;
+  for (numLigne=firstln; numLigne < lastln; numLigne++)
+    {
+      const FitsFile::BufferLine& bfligne = is.GetBufferLine(numLigne);
+      int k;
+      int rang;
+      int dcount =0;
+      int fcount =0;
+      int icount =0;
+      int ccount = 0;
+      for (k=0; k<nbcols;k++)
+	{
+	  rang = bfligne.identificateur()[k].second;
+	  switch (bfligne.identificateur()[k].first)
+	    {
+	    case  FitsFile::FitsDataType_double :
+	      {
+		dligne[dcount++] =  bfligne.r_8Array(rang);
+		break;
+	      }
+	    case  FitsFile::FitsDataType_float :
+	      {
+		fligne[fcount++] =  bfligne.r_4Array(rang);
+		break;
+	      }
+	    case  FitsFile::FitsDataType_short :
+	      {
+		iligne[icount++] =  bfligne.int_2Array(rang);
+		break;
+	      }
+	    case  FitsFile::FitsDataType_int :
+	      {
+		iligne[icount++] =  bfligne.int_4Array(rang);
+		break;
+	      }
+	    case  FitsFile::FitsDataType_long :
+	      {
+		iligne[icount++] =  (int_4)bfligne.int_8Array(rang);
+		break;
+	      }
+	    case  FitsFile::FitsDataType_byte :
+	      {
+		iligne[icount++] =  (int_4)bfligne.u_charArray(rang);
+		break;
+	      }
+	    case FitsFile::FitsDataType_char :
+	      {
+		strncpy( cligne[ccount++], bfligne.stringArray(rang).c_str(),bfligne.stringArray(rang).length());
+		break;
+	      }
+
+	    default:
+	      {  
+		throw PException(" FITS_XNTuple::ReadFromFits : unsupported FITS data type");
+	      }
+	    }
+	
+	}
+      //      is.GetBinTabLine(numLigne, dligne, fligne, iligne, cligne );
+      //      dobj_->Fill((r_8*)dligne, (r_4*)fligne, (int_4*)iligne, cligne);    
+      dobj_->Fill(dligne, fligne, iligne, cligne);    
+    }
+    delete [] dligne;
+    delete [] fligne;
+    delete [] iligne;
+    for (k=0; k< SfitsCol.size(); k++) delete []  cligne[k];
+    delete [] cligne; 
+  dobj_->Info()=is.DVListFromFits();
+
+}
+void FITS_XNTuple::WriteToFits(FitsOutFile& os) 
+{
+
+  if(dobj_ == NULL) 
+    {
+      cout << " WriteToFits:: dobj_= null " << endl;
+      return;
+    }
+
+  // table will have 'ncols'  columns
+  int ncols = dobj_->NVar(); 
+  // table will have 'nrows' rows
+  int nrows = dobj_->NEntry();
+  //  cout << " FITS_XNTuple::WriteToFits : nombre de lignes a ecrire " << nrows << endl;
+  // get names and values from the join DVList object
+  DVList dvl= dobj_->Info();
+  // extension name
+  string extname("XNTuple_Binary_tbl"); 
+  vector<string> Noms(ncols);   
+  int k;
+  for (k=0; k< ncols; k++)
+    {
+      Noms[k] = dobj_->NomIndex(k) ;
+    }
+  string types;
+  for (k=0; k<dobj_->NDVar();k++)
+    {
+      types+='D';
+    }
+  for (k=0; k<dobj_->NFVar();k++)
+    {
+      types+='E';
+    }
+  for (k=0; k<dobj_->NIVar();k++)
+    {
+      types+='J';
+    }
+  for (k=0; k<dobj_->NSVar();k++)
+    {
+      types+='A';
+    }            
+  vector<int> StringSizes(dobj_->NSVar());
+  for (k=0; k< StringSizes.size(); k++) StringSizes[k]=dobj_->mStrSz;
+  dvl["Content"]= "XNTuple";
+  dvl.SetComment("Content", "name of SOPHYA object");
+  os.makeHeaderBntblOnFits(types, Noms, nrows, ncols, &dvl, extname,StringSizes); 
+   
+  int compt=0; 
+   if (dobj_->NDVar() > 0) 
+     {
+       double* dcolumn = new double[nrows];
+       for (k=0; k<dobj_->NDVar();k++)
+	 {
+           int j;
+	   for(j = 0; j < nrows; j++) dcolumn[j]= dobj_->GetDVal(j,compt);
+	   os.PutColToFits(compt, nrows, dcolumn);
+	   compt++;
+	 }
+       delete [] dcolumn;
+     }
+
+   if (dobj_->NFVar() > 0)
+     {
+       float* fcolumn = new float[nrows];
+       for (k=0; k<dobj_->NFVar();k++)
+	 {
+           int j;
+	   for(j = 0; j < nrows; j++) fcolumn[j]= dobj_->GetFVal(j,compt);
+	   os.PutColToFits(compt, nrows, fcolumn);
+	   compt++;
+	 }
+       delete [] fcolumn;
+     }
+
+   if (dobj_->NIVar() > 0)
+     { 
+       int_4* icolumn = new int_4[nrows];
+       for (k=0; k<dobj_->NIVar();k++)
+	 {
+           int j; 
+	   for(j = 0; j < nrows; j++) icolumn[j]= dobj_->GetIVal(j,compt);
+	   //	   for(j = 0; j < nrows; j++) cout << icolumn[j] << endl;;
+
+	   os.PutColToFits(compt, nrows, icolumn);
+	   compt++;
+	 }
+       delete [] icolumn;
+     }
+
+   if (dobj_->NSVar() > 0)
+     {
+      char**  ccolumn = new char*[nrows];
+      for (k=0; k<dobj_->NSVar();k++)
+	{
+	  int j;
+	  for(j = 0; j < nrows; j++)
+	    {
+	      string s= dobj_->GetSVal(j,compt);
+	      ccolumn[j] = new char[dobj_->mStrSz+1];
+	      strcpy(ccolumn[j],s.c_str());
+	    }
+	  os.PutColToFits(compt, nrows, ccolumn);
+	  compt++;
+	  for(j = 0; j < nrows; j++)
+	    {
+	      delete [] ccolumn[j];
+	      ccolumn[j] = NULL;
+	    }
+
+	}
+      delete [] ccolumn;
+     }
+}
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsxntuple.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsxntuple.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/fitsxntuple.h	(revision 2309)
@@ -0,0 +1,79 @@
+// Guy Le Meur 03/2000
+
+
+#ifndef FITSXNTuple_SEEN
+#define FITSXNTuple_SEEN
+#include "machdefs.h"
+#include "xntuple.h"
+#include "anydataobj.h"
+#include "ppersist.h"
+#include "fitsfile.h"
+
+namespace SOPHYA {
+///////////////////////////////////////////////////////////
+//   Les objets delegues pour la gestion de persistance sur fichiers fits 
+//   pour XNTuple
+///////////////////////////////////////////////////////////
+
+class  FITS_XNTuple : public FitsIOHandler  
+{
+
+public:
+FITS_XNTuple();
+FITS_XNTuple(char inputfile[],int hdunum=0);
+FITS_XNTuple(const XNTuple & obj);
+FITS_XNTuple(XNTuple* obj);
+~FITS_XNTuple();
+
+virtual   AnyDataObj* DataObj() { return(dobj_); }
+virtual   void        SetDataObj(AnyDataObj & o) 
+  {   
+    XNTuple* po = dynamic_cast<  XNTuple* >(& o); 
+    if (po == NULL) return;
+    if (ownobj_ && dobj_) delete dobj_;  
+    dobj_ = po; 
+    ownobj_ = false; 
+  }    
+
+
+/*!
+fill the XNTuple only with lines from firstLine-th to (firstLine+numberOfLines-1)-th of the FITS-file inputfile.
+\param <firstLine>  first line  to be read (the first line of the file is numbered 0)
+\param <numberOfLines>  number of lines to be read
+*/
+void ReadLines(char inputfile[],int firstLine, int numberOfLines,int hdunum=0);
+inline operator XNTuple() { return(*dobj_); }
+inline XNTuple * getObj() { return(dobj_); }
+
+protected:
+
+  // implementation de FitsFile
+ virtual void  ReadFromFits(FitsInFile& is);
+virtual void    WriteToFits(FitsOutFile& os) ;
+
+ private :
+
+
+inline void InitNull()
+   {
+     fistLineToBeRead_= -1;
+     numberOfLinesToBeRead_= -1;
+   }
+
+  // attributs de classe
+  XNTuple* dobj_;
+  bool    ownobj_;
+  int fistLineToBeRead_;
+  int numberOfLinesToBeRead_;
+};
+//////////////////////////////////////////////////////////////////
+
+inline FitsOutFile& operator << (FitsOutFile& fios, XNTuple & nt)
+  { FITS_XNTuple fih(&nt); fih.Write(fios); return (fios); }
+
+inline FitsInFile& operator >> (FitsInFile& fiis, XNTuple & nt)
+  { FITS_XNTuple fih(&nt); fih.Read(fiis); return (fiis); }
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaExt/FitsIOServer/objlist.list
===================================================================
--- /tags/V_Dec2002/SophyaExt/FitsIOServer/objlist.list	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/FitsIOServer/objlist.list	(revision 2309)
@@ -0,0 +1,13 @@
+datacirclefits.o
+fabtcolread.o
+fabtwriter.o
+fboloread.o
+fbtntintf.o
+fitsautoreader.o
+fitsbntbllineRW.o
+fitsfile.o
+fitslocalmap.o
+fitsntuple.o
+fitsspherehealpix.o
+fitstarray.o
+fitsxntuple.o
Index: /tags/V_Dec2002/SophyaExt/IFFTW/Makefile
===================================================================
--- /tags/V_Dec2002/SophyaExt/IFFTW/Makefile	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/IFFTW/Makefile	(revision 2309)
@@ -0,0 +1,30 @@
+include ../Mgr/Makefile.h
+ 
+all: $(LIB)libIFFTW.a
+clean:
+	rm -f $(OBJ)fftwserver.o
+	rm -f $(LIB)libIFFTW.a
+$(LIB)libIFFTW.a : $(OBJ)fftwserver.o
+	$(ARCXX) $(ARCXXFLAGS) $@ $($(ARARGS))
+ifeq ($(CXX),cxx)
+	$(CXX) $? $(CPPFLAGS) $(CXXFLAGS) -o $(OBJ)xx.x -Hf
+endif 
+ 
+$(OBJ)fftwserver.o: fftwserver.cc fftwserver.h \
+ $(INC)machdefs.h \
+ $(INC)fftservintf.h \
+ $(INC)pexceptions.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)tvector.h \
+ $(EXTINCPATH)FFTW/fftw.h \
+ $(EXTINCPATH)FFTW/rfftw.h
Index: /tags/V_Dec2002/SophyaExt/IFFTW/extlib_list
===================================================================
--- /tags/V_Dec2002/SophyaExt/IFFTW/extlib_list	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/IFFTW/extlib_list	(revision 2309)
@@ -0,0 +1,2 @@
+fftw
+rfftw
Index: /tags/V_Dec2002/SophyaExt/IFFTW/extslb_list
===================================================================
--- /tags/V_Dec2002/SophyaExt/IFFTW/extslb_list	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/IFFTW/extslb_list	(revision 2309)
@@ -0,0 +1,1 @@
+fftw
Index: /tags/V_Dec2002/SophyaExt/IFFTW/fftwserver.cc
===================================================================
--- /tags/V_Dec2002/SophyaExt/IFFTW/fftwserver.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/IFFTW/fftwserver.cc	(revision 2309)
@@ -0,0 +1,407 @@
+#include "fftwserver.h"
+#include "FFTW/fftw.h"
+#include "FFTW/rfftw.h"
+
+/*!
+   \defgroup IFFTW IFFTW module
+   Module containing interface classes between Sophya objects
+   and FFTW Fourier transform package (see http://www.fftw.org )
+*/
+
+/*! 
+  \class SOPHYA::FFTWServer
+  \ingroup IFFTW
+  An implementation of FFTServerInterface based on FFTW, double
+  precision arrays, using FFTW package, availabale from http://www.fftw.org.
+  Refer to FFTServerInterface for details about FFTServer operations.
+
+  \code
+  #include "fftwserver.h"
+  // ...
+  TMatrix<r_8> in(24,32);
+  TMatrix< complex<r_8> > out;
+  in = RandomSequence();
+  FFTWServer ffts;
+  ffts.setNormalize(true);  // To have normalized transforms
+  cout << " FFTServer info string= " << ffts.getInfo() << endl;
+  cout << "in= " << in << endl;
+  cout << " Calling ffts.FFTForward(in, out) : " << endl;
+  ffts.FFTForward(in, out);
+  cout << "out= " << out << endl;
+  \endcode
+
+*/
+
+#define MAXND_FFTW 5
+
+namespace SOPHYA {
+
+class FFTWServerPlan {
+public:
+  FFTWServerPlan(int n, fftw_direction dir, bool fgreal=false);
+  FFTWServerPlan(int nd, int * nxyz, fftw_direction dir, bool fgreal=false);
+  ~FFTWServerPlan();
+  void Recreate(int n);
+  void Recreate(int nd, int * nxyz);
+
+  static void FillSizes(const BaseArray & in, int * sz);
+
+  int _n;  // Array dimension for 1-d arrays
+  int _nd; // Nb of dimensions for n-d arrays
+  int _nxyz[MAXND_FFTW]; // Array dimensions for n-d arrays
+  fftw_direction _dir;
+
+  fftw_plan p;
+  rfftw_plan rp;
+  fftwnd_plan pnd;
+  rfftwnd_plan rpnd;
+   
+};
+
+} // Fin du namespace
+
+FFTWServerPlan::FFTWServerPlan(int n, fftw_direction dir, bool fgreal)
+{
+  if (n < 1) 
+    throw ParmError("FFTWServerPlan: Array size <= 0 !");
+  p = NULL;
+  rp = NULL;
+  pnd = NULL;
+  rpnd = NULL;
+  _nd = -1;
+  for(int k=0; k<MAXND_FFTW; k++) _nxyz[k] = -10;
+  _n = n;  
+  _dir = dir;
+  if (fgreal) { 
+    rp = rfftw_create_plan(n, dir, FFTW_ESTIMATE);
+    if (rp == NULL) 
+      throw AllocationError("FFTWServerPlan: failed to create plan (rp) !");
+  }
+  else {
+    p = fftw_create_plan(n, dir, FFTW_ESTIMATE);
+    if (p == NULL) 
+      throw AllocationError("FFTWServerPlan: failed to create plan (p) !");
+  }
+    
+}
+
+FFTWServerPlan::FFTWServerPlan(int nd, int * nxyz, fftw_direction dir, bool fgreal)
+{
+  int k;
+  if (nd > MAXND_FFTW)
+    throw ParmError("FFTWServerPlan: Array rank (nd) > MAXND_FFTW !");
+  p = NULL;
+  rp = NULL;
+  pnd = NULL;
+  rpnd = NULL;
+  _n = -10;
+  _nd = nd;
+  for(k=0; k<nd; k++) {
+    if (nxyz[k] < 1) 
+       throw ParmError("FFTWServerPlan: One of the Array size <= 0 !");   
+    _nxyz[k] = nxyz[k];
+  }
+  for(k=nd; k<MAXND_FFTW; k++) _nxyz[k] = -10;
+  _dir = dir;
+  if (fgreal) {
+    rpnd = rfftwnd_create_plan(_nd, _nxyz, dir, FFTW_ESTIMATE);
+    if (rpnd == NULL) 
+      throw AllocationError("FFTWServerPlan: failed to create plan (rpnd) !");
+  }
+  else { 
+    pnd = fftwnd_create_plan(_nd, _nxyz, dir, FFTW_ESTIMATE);
+    if (pnd == NULL) 
+      throw AllocationError("FFTWServerPlan: failed to create plan (pnd) !");
+  }
+
+}
+
+FFTWServerPlan::~FFTWServerPlan()
+{
+  if (p) fftw_destroy_plan(p);
+  if (rp) rfftw_destroy_plan(rp);
+  if (pnd) fftwnd_destroy_plan(pnd);
+  if (rpnd) rfftwnd_destroy_plan(rpnd);
+}
+
+void
+FFTWServerPlan::Recreate(int n)
+{
+  if (n < 1) 
+   throw ParmError("FFTWServerPlan::Recreate(n) n < 0 !");
+  if (_nd > 0)  
+   throw ParmError("FFTWServerPlan::Recreate(n) Multi-dimensional plan ! > 0 !");
+  if (n == _n) return;
+  _n = n;  
+  if (p) {
+    fftw_destroy_plan(p);
+    p = fftw_create_plan(n, _dir, FFTW_ESTIMATE);
+    if (p == NULL) 
+      throw AllocationError("FFTWServerPlan::Recreate failed to create plan (p) !");
+  }
+  else {
+    rfftw_destroy_plan(rp);
+    rp = rfftw_create_plan(n, _dir, FFTW_ESTIMATE);
+    if (rp == NULL) 
+      throw AllocationError("FFTWServerPlan::Recreate failed to create plan (rp) !");
+  }
+
+}
+
+void
+FFTWServerPlan::Recreate(int nd, int * nxyz)
+{
+  if (_n > 0)
+    throw ParmError("FFTWServerPlan::Recreate(nd, nxyz) 1-dimensional plan !");
+  int k;
+  if (nd == _nd) {
+    bool samepl = true;
+    for (int k=0; k<nd; k++) 
+      if (nxyz[k] != _nxyz[k]) samepl = false;
+    if (samepl) return;
+  }
+  if (nd > MAXND_FFTW)
+    throw ParmError("FFTWServerPlan::Recreate(nd, nxyz) Array rank (nd) > MAXND_FFTW !");
+  _nd = nd;
+  for(k=0; k<nd; k++) {
+    if (nxyz[k] < 1) 
+       throw ParmError("FFTWServerPlan::Recreate(nd, nxyz) One of the Array size <= 0 !");   
+    _nxyz[k] = nxyz[k];
+  }
+  for(k=nd; k<MAXND_FFTW; k++) _nxyz[k] = -10;
+  if (pnd) {
+    fftwnd_destroy_plan(pnd);
+    pnd = fftwnd_create_plan(_nd, _nxyz, _dir, FFTW_ESTIMATE);
+    if (pnd == NULL) 
+      throw AllocationError("FFTWServerPlan::Recreate failed to create plan (pnd) !");
+  }
+  else {
+    rfftwnd_destroy_plan(rpnd);
+    rpnd = rfftwnd_create_plan(_nd, _nxyz, _dir, FFTW_ESTIMATE);
+    if (rpnd == NULL) 
+      throw AllocationError("FFTWServerPlan::Recreate failed to create plan (rpnd) !");
+  }
+
+}
+
+void
+FFTWServerPlan::FillSizes(const BaseArray & in, int * sz)
+{
+  int k1 = 0;
+  int k2 = 0;
+  for(k1=in.NbDimensions()-1; k1>=0; k1--) {
+    sz[k2] = in.Size(k1); k2++; 
+  }
+}
+
+/* --Methode-- */
+FFTWServer::FFTWServer()
+  : FFTServerInterface("FFTServer using FFTW package")
+  , ckR8("FFTWServer - ", true, false)
+
+{
+  _p1df = NULL;
+  _p1db = NULL;
+  _pndf = NULL;
+  _pndb = NULL;
+
+  _p1drf = NULL;
+  _p1drb = NULL;
+  _pndrf = NULL;
+  _pndrb = NULL;
+}
+
+
+/* --Methode-- */
+FFTWServer::~FFTWServer()
+{
+  if (_p1df) delete _p1df ;
+  if (_p1db) delete _p1db ;
+  if (_pndf) delete _pndf ;
+  if (_pndb) delete _pndb ;
+
+  if (_p1drf) delete _p1drf ;
+  if (_p1drb) delete _p1drb ;
+  if (_pndrf) delete _pndrf ;
+  if (_pndrb) delete _pndrb ;
+}
+
+/* --Methode-- */
+FFTServerInterface * FFTWServer::Clone()
+{
+  return (new FFTWServer) ;
+}
+
+/* --Methode-- */
+void 
+FFTWServer::FFTForward(TArray< complex<r_8> > const & in, TArray< complex<r_8> > & out)
+{
+  int rank = ckR8.CheckResize(in, out);
+  if (rank == 1) { // One dimensional transform 
+    if (_p1df) _p1df->Recreate(in.Size());
+    else _p1df = new FFTWServerPlan(in.Size(), FFTW_FORWARD, false);
+    fftw_one(_p1df->p, (fftw_complex *)(in.Data()) , (fftw_complex *)(out.Data()) );
+  }
+  else {   // Multi dimensional 
+    if (in.NbDimensions() > MAXND_FFTW) 
+      throw ParmError("FFTWServer::FFTForward( complex<r_8>, complex<r_8> ) rank > MAXND_FFTW !"); 
+    int sz[MAXND_FFTW];
+    FFTWServerPlan::FillSizes(in, sz);
+    //    int k1 = 0;
+    //    int k2 = 0;
+    //    for(k1=in.NbDimensions()-1; k1>=0; k1--) {
+    //      sz[k2] = in.Size(k1); k2++; 
+    //    }
+    if (_pndf) _pndf->Recreate(in.NbDimensions(), sz);
+    else _pndf = new FFTWServerPlan(in.NbDimensions(), sz, FFTW_FORWARD, false);
+    fftwnd_one(_pndf->pnd, (fftw_complex *)(in.Data()) , (fftw_complex *)(out.Data()) );
+  }  
+  if(this->getNormalize()) out=out/complex<r_8>((double)in.Size(),0.);
+  return;
+}
+
+/* --Methode-- */
+void FFTWServer::FFTBackward(TArray< complex<r_8> > const & in, TArray< complex<r_8> > & out)
+{
+  int rank = ckR8.CheckResize(in, out);
+  if (rank == 1) { // One dimensional transform 
+    if (_p1db) _p1db->Recreate(in.Size());
+    else _p1db = new FFTWServerPlan(in.Size(), FFTW_BACKWARD, false);
+    fftw_one(_p1db->p, (fftw_complex *)(in.Data()) , (fftw_complex *)(out.Data()) );
+  }
+  else {   // Multi dimensional 
+    if (in.NbDimensions() > MAXND_FFTW) 
+      throw ParmError("FFTWServer::FFTForward( complex<r_8>, complex<r_8> ) rank > MAXND_FFTW !"); 
+    int sz[MAXND_FFTW];
+    FFTWServerPlan::FillSizes(in, sz);
+    //    int k1 = 0;
+    //    int k2 = 0;
+    //    for(k1=in.NbDimensions()-1; k1>=0; k1--) {
+    //      sz[k2] = in.Size(k1); k2++; 
+    //    }
+    if (_pndb) _pndb->Recreate(in.NbDimensions(), sz);
+    else _pndb = new FFTWServerPlan(in.NbDimensions(), sz, FFTW_BACKWARD, false);
+    fftwnd_one(_pndb->pnd, (fftw_complex *)(in.Data()) , (fftw_complex *)(out.Data()) );
+  }
+
+  return;
+}
+
+
+void FFTWServer::FFTForward(TArray< r_8 > const & in, TArray< complex<r_8> > & out)
+{  
+  int rank = ckR8.CheckResize(in, out);
+  if (rank == 1) { // One dimensional transform 
+    if (_p1drf) _p1drf->Recreate(in.Size());
+    else _p1drf = new FFTWServerPlan(in.Size(), FFTW_REAL_TO_COMPLEX, true);
+    TArray<r_8> outtemp; 
+    outtemp.ReSize(in);
+    rfftw_one(_p1drf->rp, (fftw_real *)(in.Data()) , (fftw_real *)(outtemp.Data()));
+    ReShapetoCompl(outtemp, out);
+  }
+  else {   // Multi dimensional 
+    if (in.NbDimensions() > MAXND_FFTW) 
+      throw ParmError("FFTWServer::FFTForward( complex<r_8>, complex<r_8> ) rank > MAXND_FFTW !"); 
+    int sz[MAXND_FFTW];
+    FFTWServerPlan::FillSizes(in, sz);
+    //    int k1 = 0;
+    //    int k2 = 0;
+    //   for(k1=in.NbDimensions()-1; k1>=0; k1--) {
+    //      sz[k2] = in.Size(k1); k2++; 
+    //    }
+    if (_pndrf) _pndrf->Recreate(in.NbDimensions(), sz);
+    else _pndrf = new FFTWServerPlan(in.NbDimensions(), sz, FFTW_REAL_TO_COMPLEX, true);
+    rfftwnd_one_real_to_complex(_pndrf->rpnd, (fftw_real *)(in.Data()) , 
+				(fftw_complex *)(out.Data()) );
+  }
+  if(this->getNormalize()) out=out/complex<r_8>((double)in.Size(),0.);
+  return;
+
+}
+
+
+
+void FFTWServer::FFTBackward(TArray< complex<r_8> > const & in, TArray< r_8 > & out,
+			     bool usoutsz)
+{
+  
+  int rank = ckR8.CheckResize(in, out, usoutsz);
+  if (rank == 1) { // One dimensional transform 
+    TArray<r_8> intemp;
+    intemp.ReSize(out);
+    if (_p1drb) _p1drb->Recreate(out.Size());
+    else _p1drb = new FFTWServerPlan(out.Size(), FFTW_COMPLEX_TO_REAL, true);
+
+    ReShapetoReal(in, intemp);
+    //    cerr << " DEBUG-FFTWServer::FFTBackward() in = \n" << in << endl;
+    //    cerr << " DEBUG-FFTWServer::FFTBackward() intemp = \n" << intemp << endl;
+    rfftw_one(_p1drb->rp, (fftw_real *)(intemp.Data()) , (fftw_real *)(out.Data()));
+
+  }
+  else {   // Multi dimensional 
+    if (in.NbDimensions() > MAXND_FFTW) 
+      throw ParmError("FFTWServer::FFTForward( complex<r_8>, r_8 ) rank > MAXND_FFTW !"); 
+    int sz[MAXND_FFTW];
+    FFTWServerPlan::FillSizes(out, sz);
+    //    int k1 = 0;
+    //    int k2 = 0;
+    //    for(k1=out.NbDimensions()-1; k1>=0; k1--) {
+    //      sz[k2] = out.Size(k1); k2++; 
+    //    }
+    if (_pndrb) _pndrb->Recreate(in.NbDimensions(), sz);
+    else _pndrb = new FFTWServerPlan(in.NbDimensions(), sz, FFTW_COMPLEX_TO_REAL, true);
+
+    rfftwnd_one_complex_to_real(_pndrb->rpnd, (fftw_complex *)(in.Data()) , (fftw_real *)(out.Data()) );
+  }
+  return;
+}
+
+
+
+/* --Methode-- */
+void FFTWServer::ReShapetoReal(TArray< complex<r_8> > const & ina, TArray< r_8 > & outa)
+{
+  TVector< complex<r_8> > in(ina);
+  TVector< r_8> out(outa);
+  int n = in.NElts();
+  r_8 thr = FFTArrayChecker<r_8>::ZeroThreshold();
+  sa_size_t ncs = ( (in(n-1).imag() < -thr) || (in(n-1).imag() > thr) ) ?
+                    ncs = 2*n-1 : ncs = 2*n-2;
+
+  if (out.NElts() != ncs) {
+    cerr << " DEBUG-FFTWServer::ReShapetoReal() ncs= " << ncs 
+	 << " out.NElts()= " << out.NElts() << endl;
+    throw SzMismatchError("FFTWServer::ReShapetoReal() - Wrong output array size !");
+  }
+  //  if (ncs == 2*n-2)  {
+  out(0) = in(0).real();
+  for(int k=1; k<n; k++) {
+      out(k) = in(k).real();
+      out(ncs-k) = in(k).imag();
+  }
+  if (ncs == 2*n-2)
+    out(ncs-1) = in(n-1).real();
+  
+  //  for(int k=0; k<out.NElts(); k++) cout << "ReShapetoReal out " << k << " " << out(k) << endl;
+}
+
+
+/* --Methode-- */
+void FFTWServer::ReShapetoCompl(TArray< r_8 > const & ina, TArray< complex<r_8> > & outa)
+{
+  TVector< r_8> in(ina);
+  TVector< complex<r_8> > out(outa);
+
+  sa_size_t n = in.NElts();
+  sa_size_t ncs = n/2+1;
+  sa_size_t nc = (n%2 != 0) ? n/2+1 : n/2;
+  if (out.NElts() != ncs)
+    throw SzMismatchError("FFTWServer::ReShapetoCompl() - Wrong output array size !");
+
+  out(0) = complex<r_8> (in(0),0.);
+  for(int k=1; k<ncs; k++) 
+    out(k) = complex<r_8>(in(k), in(n-k));
+  if (n%2 == 0) out(ncs-1) = complex<r_8>(in(n/2), 0.);
+
+}
+
Index: /tags/V_Dec2002/SophyaExt/IFFTW/fftwserver.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/IFFTW/fftwserver.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/IFFTW/fftwserver.h	(revision 2309)
@@ -0,0 +1,50 @@
+#ifndef  FFTWServer_H_SEEN
+#define  FFTWServer_H_SEEN
+
+#include "machdefs.h"
+#include "fftservintf.h"
+
+
+// Classe implementant l'interface FFTServerInterface en 
+// utilisant FFTW 
+
+namespace SOPHYA {
+
+class FFTWServerPlan;
+
+class FFTWServer : public FFTServerInterface {
+ public:
+  FFTWServer();
+  virtual ~FFTWServer();
+
+  
+  virtual FFTServerInterface * Clone();
+
+  // Transforme unidimensionnelle , N-dimensionnel
+  virtual void FFTForward(TArray< complex<r_8> > const & in, TArray< complex<r_8> > & out);
+  virtual void FFTBackward(TArray< complex<r_8> > const & in, TArray< complex<r_8> > & out);
+  virtual void FFTForward(TArray< r_8 > const & in, TArray< complex<r_8> > & out);
+  virtual void FFTBackward(TArray< complex<r_8> > const & in, TArray< r_8 > & out,
+			   bool usoutsz=false);
+
+// Methodes statiques pour reordonner les donnees en 1-D
+  static void ReShapetoReal(TArray< complex<r_8> > const & in, TArray< r_8 > & out);
+  static void ReShapetoCompl(TArray< r_8 > const & in, TArray< complex<r_8> > & out);
+
+ protected:
+ FFTWServerPlan * _p1df;
+ FFTWServerPlan * _p1db;
+ FFTWServerPlan * _pndf;
+ FFTWServerPlan * _pndb;
+
+ FFTWServerPlan * _p1drf;
+ FFTWServerPlan * _p1drb;
+ FFTWServerPlan * _pndrf;
+ FFTWServerPlan * _pndrb;
+
+ FFTArrayChecker<r_8> ckR8;
+};
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaExt/IFFTW/objlist.list
===================================================================
--- /tags/V_Dec2002/SophyaExt/IFFTW/objlist.list	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/IFFTW/objlist.list	(revision 2309)
@@ -0,0 +1,1 @@
+fftwserver.o
Index: /tags/V_Dec2002/SophyaExt/LinAlg/Makefile
===================================================================
--- /tags/V_Dec2002/SophyaExt/LinAlg/Makefile	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/LinAlg/Makefile	(revision 2309)
@@ -0,0 +1,27 @@
+include ../Mgr/Makefile.h
+ 
+all: $(LIB)libLinAlg.a
+clean:
+	rm -f $(OBJ)intflapack.o
+	rm -f $(LIB)libLinAlg.a
+$(LIB)libLinAlg.a : $(OBJ)intflapack.o
+	$(ARCXX) $(ARCXXFLAGS) $@ $($(ARARGS))
+ifeq ($(CXX),cxx)
+	$(CXX) $? $(CPPFLAGS) $(CXXFLAGS) -o $(OBJ)xx.x -Hf
+endif 
+ 
+$(OBJ)intflapack.o: intflapack.cc intflapack.h \
+ $(INC)machdefs.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h
Index: /tags/V_Dec2002/SophyaExt/LinAlg/extlib_list
===================================================================
--- /tags/V_Dec2002/SophyaExt/LinAlg/extlib_list	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/LinAlg/extlib_list	(revision 2309)
@@ -0,0 +1,3 @@
+lapack
+dxml
+for
Index: /tags/V_Dec2002/SophyaExt/LinAlg/extslb_list
===================================================================
--- /tags/V_Dec2002/SophyaExt/LinAlg/extslb_list	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/LinAlg/extslb_list	(revision 2309)
@@ -0,0 +1,3 @@
+lapack
+dxml
+for
Index: /tags/V_Dec2002/SophyaExt/LinAlg/intflapack.cc
===================================================================
--- /tags/V_Dec2002/SophyaExt/LinAlg/intflapack.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/LinAlg/intflapack.cc	(revision 2309)
@@ -0,0 +1,422 @@
+#include <iostream.h>
+#include "intflapack.h"
+#include "tvector.h"
+#include "tmatrix.h"
+#include <typeinfo>
+
+/*!
+   \defgroup LinAlg LinAlg module
+   This module contains classes and functions for complex linear
+   algebra on arrays. This module is intended mainly to have 
+   classes implementing C++ interfaces between Sophya objects
+   and external linear algebra libraries, such as LAPACK.  
+*/
+
+/*! 
+  \class SOPHYA::LapackServer
+  \ingroup LinAlg
+  This class implements an interface to LAPACK library driver routines.
+  The LAPACK (Linear Algebra PACKage) is a collection high performance 
+  routines to solve common problems in numerical linear algebra. 
+  its is available from http://www.netlib.org.
+  
+  The present version of our LapackServer (Feb 2001) provides only 
+  interfaces for the linear system solver and singular value 
+  decomposition (SVD). Only arrays with BaseArray::FortranMemoryMapping 
+  can be handled by LapackServer. LapackServer can be instanciated 
+  for simple and double precision real or complex array types.
+
+  The example below shows solving a linear system A*X = B
+
+  \code
+  #include "intflapack.h"
+  // ...
+  // Use FortranMemoryMapping as default
+  BaseArray::SetDefaultMemoryMapping(BaseArray::FortranMemoryMapping);
+  // Create an fill the arrays A and B
+  int n = 20;
+  Matrix A(n, n);
+  A = RandomSequence();
+  Vector X(n),B(n);
+  X = RandomSequence();
+  B = A*X;
+  // Solve the linear system A*X = B
+  LapackServer<r_8> lps;
+  lps.LinSolve(A,B);
+  // We get the result in B, which should be equal to X ...
+  // Compute the difference B-X ;
+  Vector diff = B-X;
+  \endcode
+
+*/
+
+extern "C" {
+// Drivers pour resolution de systemes lineaires
+  void sgesv_(int_4* n, int_4* nrhs, r_4* a, int_4* lda, 
+	      int_4* ipiv, r_4* b, int_4* ldb, int_4* info);
+  void dgesv_(int_4* n, int_4* nrhs, r_8* a, int_4* lda, 
+	      int_4* ipiv, r_8* b, int_4* ldb, int_4* info);
+  void cgesv_(int_4* n, int_4* nrhs, complex<r_4>* a, int_4* lda, 
+	      int_4* ipiv, complex<r_4>* b, int_4* ldb, int_4* info);
+  void zgesv_(int_4* n, int_4* nrhs, complex<r_8>* a, int_4* lda, 
+	      int_4* ipiv, complex<r_8>* b, int_4* ldb, int_4* info);
+
+  // Driver pour resolution de systemes au sens de Xi2
+  void sgels_(char * trans, int_4* m, int_4* n, int_4* nrhs, r_4* a, int_4* lda, 
+	      r_4* b, int_4* ldb, r_4* work, int_4* lwork, int_4* info);
+  void dgels_(char * trans, int_4* m, int_4* n, int_4* nrhs, r_8* a, int_4* lda, 
+	      r_8* b, int_4* ldb, r_8* work, int_4* lwork, int_4* info);
+  void cgels_(char * trans, int_4* m, int_4* n, int_4* nrhs, complex<r_4>* a, int_4* lda, 
+	      complex<r_4>* b, int_4* ldb, complex<r_4>* work, int_4* lwork, int_4* info);
+  void zgels_(char * trans, int_4* m, int_4* n, int_4* nrhs, complex<r_8>* a, int_4* lda, 
+	      complex<r_8>* b, int_4* ldb, complex<r_8>* work, int_4* lwork, int_4* info);
+
+// Driver pour decomposition SVD 
+  void sgesvd_(char* jobu, char* jobvt, int_4* m, int_4* n, r_4* a, int_4* lda,
+	       r_4* s, r_4* u, int_4* ldu, r_4* vt, int_4* ldvt, 
+	       r_4* work, int_4* lwork, int_4* info);
+  void dgesvd_(char* jobu, char* jobvt, int_4* m, int_4* n, r_8* a, int_4* lda,
+	       r_8* s, r_8* u, int_4* ldu, r_8* vt, int_4* ldvt, 
+	       r_8* work, int_4* lwork, int_4* info);
+  void cgesvd_(char* jobu, char* jobvt, int_4* m, int_4* n, complex<r_4>* a, int_4* lda,
+	       complex<r_4>* s, complex<r_4>* u, int_4* ldu, complex<r_4>* vt, int_4* ldvt, 
+	       complex<r_4>* work, int_4* lwork, int_4* info);
+  void zgesvd_(char* jobu, char* jobvt, int_4* m, int_4* n, complex<r_8>* a, int_4* lda,
+	       complex<r_8>* s, complex<r_8>* u, int_4* ldu, complex<r_8>* vt, int_4* ldvt, 
+	       complex<r_8>* work, int_4* lwork, int_4* info);
+	       
+}
+
+
+//   -------------- Classe LapackServer<T> --------------
+
+template <class T>
+LapackServer<T>::LapackServer()
+{
+  SetWorkSpaceSizeFactor();
+}
+
+template <class T>
+LapackServer<T>::~LapackServer()
+{
+}
+
+//! Interface to Lapack linear system solver driver s/d/c/zgesvd().
+/*! Solve the linear system a * x = b. Input arrays
+  should have FortranMemory mapping (column packed).
+  \param a : input matrix, overwritten on output
+  \param b : input-output, input vector b, contains x on exit
+  \return : return code from lapack driver _gesv()
+ */
+template <class T>
+int LapackServer<T>::LinSolve(TArray<T>& a, TArray<T> & b)
+{
+  if ( ( a.NbDimensions() != 2 ) || ( b.NbDimensions() != 2 ) )
+    throw(SzMismatchError("LapackServer::LinSolve(a,b) a Or b NbDimensions() != 2"));
+  
+  int_4 rowa = a.RowsKA();
+  int_4 cola = a.ColsKA();
+  int_4 rowb = b.RowsKA();
+  int_4 colb = b.ColsKA();
+  if ( a.Size(rowa) !=  a.Size(cola)) 
+    throw(SzMismatchError("LapackServer::LinSolve(a,b) a Not a square Array"));
+  if ( a.Size(rowa) !=  b.Size(rowb)) 
+    throw(SzMismatchError("LapackServer::LinSolve(a,b) RowSize(a <> b) "));
+
+  if (!a.IsPacked(rowa) || !b.IsPacked(rowb))
+     throw(SzMismatchError("LapackServer::LinSolve(a,b) a Or b Not Column Packed"));
+
+  int_4 n = a.Size(rowa);
+  int_4 nrhs = b.Size(colb);
+  int_4 lda = a.Step(cola);
+  int_4 ldb = b.Step(colb);
+  int_4 info;
+  int_4* ipiv = new int_4[n];
+
+  if (typeid(T) == typeid(r_4) )
+    sgesv_(&n, &nrhs, (r_4 *)a.Data(), &lda, ipiv, (r_4 *)b.Data(), &ldb, &info);
+  else if (typeid(T) == typeid(r_8) ) 
+    dgesv_(&n, &nrhs, (r_8 *)a.Data(), &lda, ipiv, (r_8 *)b.Data(), &ldb, &info);
+  else if (typeid(T) == typeid(complex<r_4>) ) 
+    cgesv_(&n, &nrhs, (complex<r_4> *)a.Data(), &lda, ipiv, 
+	   (complex<r_4> *)b.Data(), &ldb, &info);
+  else if (typeid(T) == typeid(complex<r_8>) ) 
+    zgesv_(&n, &nrhs, (complex<r_8> *)a.Data(), &lda, ipiv, 
+	   (complex<r_8> *)b.Data(), &ldb, &info);
+  else {
+    delete[] ipiv;
+    string tn = typeid(T).name();
+    cerr << " LapackServer::LinSolve(a,b) - Unsupported DataType T = " << tn << endl;
+    throw TypeMismatchExc("LapackServer::LinSolve(a,b) - Unsupported DataType (T)");
+  }
+  delete[] ipiv;
+  return(info);
+}
+
+//! Interface to Lapack least squares solver driver s/d/c/zgels().
+/*! Solves the linear least squares problem defined by an m-by-n matrix 
+  \b a and an m element vector \b b .
+  A solution \b x to the overdetermined system of linear equations
+  b = a * x is computed, minimizing the norm of b-a*x. 
+  Underdetermined systems (m<n) are not yet handled.
+  Inout arrays should have FortranMemory mapping (column packed).
+  \param a : input matrix, overwritten on output
+  \param b : input-output, input vector b, contains x on exit.
+  \return : return code from lapack driver _gels()
+  \warning : b is not resized.
+ */
+/*
+  $CHECK$ - A faire - cas m<n 
+       If the linear system is underdetermined, the minimum norm 
+       solution is computed. 
+*/
+
+template <class T>
+int LapackServer<T>::LeastSquareSolve(TArray<T>& a, TArray<T> & b)
+{
+  if ( ( a.NbDimensions() != 2 ) || ( b.NbDimensions() != 2 ) )
+    throw(SzMismatchError("LapackServer::LinSolve(a,b) a Or b NbDimensions() != 2"));
+  
+  int_4 rowa = a.RowsKA();
+  int_4 cola = a.ColsKA();
+  int_4 rowb = b.RowsKA();
+  int_4 colb = b.ColsKA();
+
+
+  if ( a.Size(rowa) !=  b.Size(rowb)) 
+    throw(SzMismatchError("LapackServer::LeastSquareSolve(a,b) RowSize(a <> b) "));
+
+  if (!a.IsPacked(rowa) || !b.IsPacked(rowb))
+     throw(SzMismatchError("LapackServer::LeastSquareSolve(a,b) a Or b Not Column Packed"));
+
+  if ( a.Size(rowa) <  a.Size(cola)) {  // $CHECK$ - m<n a changer
+    cout << " LapackServer<T>::LeastSquareSolve() - m<n - Not yet implemented for "
+	 << " underdetermined systems ! " << endl;
+    throw(SzMismatchError("LapackServer::LeastSquareSolve(a,b) NRows<NCols - "));
+  }
+  int_4 m = a.Size(rowa);
+  int_4 n = a.Size(cola);
+  int_4 nrhs = b.Size(colb);
+
+  int_4 lda = a.Step(cola);
+  int_4 ldb = b.Step(colb);
+  int_4 info;
+
+  int_4 minmn = (m < n) ? m : n;
+  int_4 maxmn = (m > n) ? m : n;
+  int_4 maxmnrhs = (nrhs > maxmn) ? nrhs : maxmn;
+  if (maxmnrhs < 1) maxmnrhs = 1;
+  
+  int_4 lwork = minmn+maxmnrhs*5;
+  T * work = new T[lwork];
+
+  char trans = 'N';
+  
+  if (typeid(T) == typeid(r_4) )
+    sgels_(&trans, &m, &n, &nrhs, (r_4 *)a.Data(), &lda, 
+	   (r_4 *)b.Data(), &ldb, (r_4 *)work, &lwork, &info);
+  else if (typeid(T) == typeid(r_8) ) 
+    dgels_(&trans, &m, &n, &nrhs, (r_8 *)a.Data(), &lda, 
+	   (r_8 *)b.Data(), &ldb, (r_8 *)work, &lwork, &info);
+  else if (typeid(T) == typeid(complex<r_4>) ) 
+    cgels_(&trans, &m, &n, &nrhs, (complex<r_4> *)a.Data(), &lda, 
+	   (complex<r_4> *)b.Data(), &ldb, (complex<r_4> *)work, &lwork, &info);
+  else if (typeid(T) == typeid(complex<r_8>) ) 
+    zgels_(&trans, &m, &n, &nrhs, (complex<r_8> *)a.Data(), &lda, 
+	   (complex<r_8> *)b.Data(), &ldb, (complex<r_8> *)work, &lwork, &info);
+  else {
+    delete[] work;
+    string tn = typeid(T).name();
+    cerr << " LapackServer::LeastSquareSolve(a,b) - Unsupported DataType T = " << tn << endl;
+    throw TypeMismatchExc("LapackServer::LeastSquareSolve(a,b) - Unsupported DataType (T)");
+  }
+  delete[] work;
+  return(info);
+}
+
+
+//! Interface to Lapack SVD driver s/d/c/zgesv().
+/*! Computes the vector of singular values of \b a. Input arrays
+  should have FortranMemoryMapping (column packed).
+  \param a : input m-by-n matrix 
+  \param s : Vector of min(m,n) singular values (descending order)
+  \return : return code from lapack driver _gesvd()
+ */
+
+template <class T>
+int LapackServer<T>::SVD(TArray<T>& a, TArray<T> & s)
+{
+  return (SVDDriver(a, s, NULL, NULL) );
+}
+
+//! Interface to Lapack SVD driver s/d/c/zgesv().
+/*! Computes the vector of singular values of \b a, as well as
+  right and left singular vectors of \b a.
+  \f[
+  A = U \Sigma V^T , ( A = U \Sigma V^H \ complex)
+  \f]
+  \f[
+  A v_i = \sigma_i u_i \ and A^T u_i = \sigma_i v_i \ (A^H \ complex)
+  \f]
+  U and V are orthogonal (unitary) matrices.
+  \param a : input m-by-n matrix (in FotranMemoryMapping)
+  \param s : Vector of min(m,n) singular values (descending order)
+  \param u : Matrix of left singular vectors
+  \param vt : Transpose of right singular vectors.
+  \return : return code from lapack driver _gesvd()
+ */
+template <class T>
+int LapackServer<T>::SVD(TArray<T>& a, TArray<T> & s, TArray<T> & u, TArray<T> & vt)
+{
+  return (SVDDriver(a, s, &u, &vt) );
+}
+
+
+//! Interface to Lapack SVD driver s/d/c/zgesv().
+template <class T>
+int LapackServer<T>::SVDDriver(TArray<T>& a, TArray<T> & s, TArray<T>* up, TArray<T>* vtp)
+{
+  if ( ( a.NbDimensions() != 2 )  )
+    throw(SzMismatchError("LapackServer::SVD(a, ...) a.NbDimensions() != 2"));
+
+  int_4 rowa = a.RowsKA();
+  int_4 cola = a.ColsKA();
+
+  if ( !a.IsPacked(rowa) )
+     throw(SzMismatchError("LapackServer::SVD(a, ...) a Not Column Packed "));
+
+  int_4 m = a.Size(rowa);
+  int_4 n = a.Size(cola);
+  int_4 maxmn = (m > n) ? m : n;
+  int_4 minmn = (m < n) ? m : n;
+
+  char jobu, jobvt;
+  jobu = 'N';
+  jobvt = 'N';
+
+  sa_size_t sz[2];
+  if ( up != NULL) {
+    if ( dynamic_cast< TVector<T> * > (vtp) ) 
+      throw( TypeMismatchExc("LapackServer::SVD() Wrong type (=TVector<T>) for u !") );
+    up->SetMemoryMapping(BaseArray::FortranMemoryMapping);
+    sz[0] = sz[1] = m;
+    up->ReSize(2, sz );
+    jobu = 'A';
+  }
+  else { 
+    up = new TMatrix<T>(1,1);
+    jobu = 'N';
+  }
+  if ( vtp != NULL) {
+    if ( dynamic_cast< TVector<T> * > (vtp) ) 
+      throw( TypeMismatchExc("LapackServer::SVD() Wrong type (=TVector<T>) for vt !") );
+    vtp->SetMemoryMapping(BaseArray::FortranMemoryMapping);
+    sz[0] = sz[1] = n;
+    vtp->ReSize(2, sz );
+    jobvt = 'A';
+  }
+  else { 
+    vtp = new TMatrix<T>(1,1);
+    jobvt = 'N';
+  }
+
+  TVector<T> *vs = dynamic_cast< TVector<T> * > (&s);
+  if (vs) vs->ReSize(minmn);
+  else {
+    TMatrix<T> *ms = dynamic_cast< TMatrix<T> * > (&s);
+    if (ms) ms->ReSize(minmn,1);
+    else  { 
+      sz[0] = minmn; sz[1] = 1;
+      s.ReSize(1, sz);
+    }
+  }
+  
+  int_4 lda = a.Step(a.ColsKA());
+  int_4 ldu = up->Step(up->ColsKA());
+  int_4 ldvt = vtp->Step(vtp->ColsKA());
+
+  int_4 lwork = maxmn*5*wspace_size_factor;
+  T * work = new T[lwork];
+  int_4 info;  
+
+  if (typeid(T) == typeid(r_4) )
+    sgesvd_(&jobu, &jobvt, &m, &n, (r_4 *)a.Data(), &lda,
+	    (r_4 *)s.Data(), (r_4 *) up->Data(), &ldu, (r_4 *)vtp->Data(), &ldvt, 
+	    (r_4 *)work, &lwork, &info);
+  else if (typeid(T) == typeid(r_8) ) 
+    dgesvd_(&jobu, &jobvt, &m, &n, (r_8 *)a.Data(), &lda,
+	    (r_8 *)s.Data(), (r_8 *) up->Data(), &ldu, (r_8 *)vtp->Data(), &ldvt, 
+	    (r_8 *)work, &lwork, &info);
+  else if (typeid(T) == typeid(complex<r_4>) ) 
+    cgesvd_(&jobu, &jobvt, &m, &n, (complex<r_4> *)a.Data(), &lda,
+	    (complex<r_4> *)s.Data(), (complex<r_4> *) up->Data(), &ldu, 
+	    (complex<r_4> *)vtp->Data(), &ldvt, 
+	    (complex<r_4> *)work, &lwork, &info);
+  else if (typeid(T) == typeid(complex<r_8>) ) 
+    zgesvd_(&jobu, &jobvt, &m, &n, (complex<r_8> *)a.Data(), &lda,
+	    (complex<r_8> *)s.Data(), (complex<r_8> *) up->Data(), &ldu, 
+	    (complex<r_8> *)vtp->Data(), &ldvt, 
+	    (complex<r_8> *)work, &lwork, &info);
+  else {
+    if (jobu == 'N') delete up;
+    if (jobvt == 'N') delete vtp;
+    string tn = typeid(T).name();
+    cerr << " LapackServer::SVDDriver(...) - Unsupported DataType T = " << tn << endl;
+    throw TypeMismatchExc("LapackServer::LinSolve(a,b) - Unsupported DataType (T)");
+  }
+
+  if (jobu == 'N') delete up;
+  if (jobvt == 'N') delete vtp;
+  return(info);
+}
+
+void rztest_lapack(TArray<r_4>& aa, TArray<r_4>& bb)
+{
+  if ( aa.NbDimensions() != 2 ) throw(SzMismatchError("rztest_lapack(TMatrix<r_4> A Not a Matrix"));
+  if ( aa.SizeX() !=  aa.SizeY()) throw(SzMismatchError("rztest_lapack(TMatrix<r_4> A Not a square Matrix"));
+  if ( bb.NbDimensions() != 2 ) throw(SzMismatchError("rztest_lapack(TMatrix<r_4> A Not a Matrix"));
+  if ( bb.SizeX() !=  aa.SizeX() ) throw(SzMismatchError("rztest_lapack(TMatrix<r_4> A <> B "));
+  if ( !bb.IsPacked() || !bb.IsPacked() ) 
+    throw(SzMismatchError("rztest_lapack(TMatrix<r_4> Not packed A or B "));
+  
+  int_4 n = aa.SizeX();
+  int_4 nrhs = bb.SizeY();
+  int_4 lda = n;
+  int_4 ldb = bb.SizeX();
+  int_4 info;
+  int_4* ipiv = new int_4[n];
+  sgesv_(&n, &nrhs, aa.Data(), &lda, ipiv, bb.Data(), &ldb, &info);
+  delete[] ipiv;
+  cout << "rztest_lapack/Info= " << info << endl;
+  cout << aa << "\n" << bb << endl;
+  return;
+}
+
+///////////////////////////////////////////////////////////////
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template LapackServer<r_4>
+#pragma define_template LapackServer<r_8>
+#pragma define_template LapackServer< complex<r_4> >
+#pragma define_template LapackServer< complex<r_8> >
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class LapackServer<r_4>;
+template class LapackServer<r_8>;
+template class LapackServer< complex<r_4> >;
+template class LapackServer< complex<r_8> >;
+#endif
+
+#if defined(OS_LINUX)
+//  Pour le link avec f2c sous Linux
+extern "C" {
+    void MAIN__();
+}
+
+void MAIN__()
+{
+  cerr << "MAIN__() function for linking with libf2c.a " << endl;
+  cerr << "  This function should never be called !!! " << endl;
+  throw PError("MAIN__() should not be called - see intflapack.cc");
+}
+#endif
Index: /tags/V_Dec2002/SophyaExt/LinAlg/intflapack.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/LinAlg/intflapack.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/LinAlg/intflapack.h	(revision 2309)
@@ -0,0 +1,72 @@
+#ifndef  IntfLapack_H_SEEN
+#define  IntfLapack_H_SEEN
+
+#include "machdefs.h"
+#include "tarray.h"
+
+namespace SOPHYA {
+
+template <class T>
+class LapackServer { 
+public:
+  LapackServer();
+  virtual ~LapackServer();
+
+  virtual int LinSolve(TArray<T>& a, TArray<T> & b); 
+  virtual int LeastSquareSolve(TArray<T>& a, TArray<T> & b); 
+
+  virtual int SVD(TArray<T>& a, TArray<T> & s); 
+  virtual int SVD(TArray<T>& a, TArray<T> & s, TArray<T> & u, TArray<T> & vt); 
+
+  //! Set the workspace size factor for LAPACK routines
+  inline void SetWorkSpaceSizeFactor(int f = 2)
+  { wspace_size_factor = (f > 1) ? f : 1; }
+
+  //! Returns the workspace size factor
+  inline int  GetWorkSpaceSizeFactor() 
+  { return wspace_size_factor; }
+
+private:
+  int SVDDriver(TArray<T>& a, TArray<T> & s, 
+		TArray<T>* up=NULL, TArray<T> * vtp=NULL);
+
+  int wspace_size_factor;
+};
+
+/*! \ingroup LinAlg
+    \fn LapackLinSolve(TArray<T>&, TArray<T> &)
+    \brief Solves the linear system A*X = B using LapackServer. 
+*/
+template <class T>
+inline int LapackLinSolve(TArray<T>& a, TArray<T> & b)
+{ LapackServer<T> lps; return( lps.LinSolve(a, b) );  }
+
+/*! \ingroup LinAlg
+    \fn LapackLeastSquareSolve(TArray<T>&, TArray<T> &)
+    \brief Solves the linear least squares problem A*X - B
+*/
+template <class T>
+inline int LapackLeastSquareSolve(TArray<T>& a, TArray<T> & b)
+{ LapackServer<T> lps; return( lps.LeastSquareSolve(a, b) );  }
+
+/*! \ingroup LinAlg
+    \fn LapackSVD(TArray<T>&, TArray<T> &)
+    \brief SVD decomposition using LapackServer. 
+*/
+template <class T>
+inline int LapackSVD(TArray<T>& a, TArray<T> & s)
+{ LapackServer<T> lps; return( lps.SVD(a, s) ); }
+
+
+/*! \ingroup LinAlg
+    \fn LapackSVD(TArray<T>&, TArray<T> &, TArray<T> &, TArray<T> &)
+    \brief SVD decomposition using LapackServer. 
+*/
+template <class T>
+inline int LapackSVD(TArray<T>& a, TArray<T> & s, TArray<T> & u, TArray<T> & vt)
+{ LapackServer<T> lps; return( lps.SVD(a, s, u, vt) ); }
+
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaExt/LinAlg/objlist.list
===================================================================
--- /tags/V_Dec2002/SophyaExt/LinAlg/objlist.list	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/LinAlg/objlist.list	(revision 2309)
@@ -0,0 +1,1 @@
+intflapack.o
Index: /tags/V_Dec2002/SophyaExt/XAstroPack/Makefile
===================================================================
--- /tags/V_Dec2002/SophyaExt/XAstroPack/Makefile	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XAstroPack/Makefile	(revision 2309)
@@ -0,0 +1,18 @@
+include ../Mgr/Makefile.h
+ 
+all: $(LIB)libXAstroPack.a
+clean:
+	rm -f $(OBJ)mollweide.o $(OBJ)tstxastro.o $(OBJ)xastropack.o $(OBJ)magfield.o
+	rm -f $(LIB)libXAstroPack.a
+$(LIB)libXAstroPack.a : $(OBJ)magfield.o $(OBJ)mollweide.o $(OBJ)xastropack.o
+	$(ARCXX) $(ARCXXFLAGS) $@ $($(ARARGS))
+ifeq ($(CXX),cxx)
+	$(CXX) $? $(CPPFLAGS) $(CXXFLAGS) -o $(OBJ)xx.x -Hf
+endif 
+ 
+$(OBJ)mollweide.o: mollweide.cc mollweide.h
+$(OBJ)xastropack.o: xastropack.cc xastropack.h \
+ $(INC)machdefs.h \
+ $(EXTINCPATH)XAstro/P_.h \
+ $(EXTINCPATH)XAstro/astro.h
+$(OBJ)magfield.o: magfield.c magfield.h
Index: /tags/V_Dec2002/SophyaExt/XAstroPack/Maketest
===================================================================
--- /tags/V_Dec2002/SophyaExt/XAstroPack/Maketest	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XAstroPack/Maketest	(revision 2309)
@@ -0,0 +1,24 @@
+MODULECXXREPNAME :=  CmvTests
+MODULEDECCXXFLAGS := -msg_quiet
+include $(DPCBASEREP)/Include/MakefileUser.h
+
+LIBNEED := -L$(SLB) -lsophya -L$(LIB) -lFitsIOServer -L$(EXTLIBPATH) -lcfitsio
+
+all: tstxastro mollweide
+
+clean:
+	rm -f tstxastro mollweide
+	rm -f core *.o
+	rm -f mollw.data mollw2.data paw.metafile last.kumacold
+
+##############################################################################
+tstxastro: tstxastro.o xastropack.o
+	$(LINK.cc) $^ -o $@ $(LOADLIBES) $(LIBS) $(LDLIBS)
+tstxastro.o: tstxastro.cc
+xastropack.o: xastropack.cc
+##############################################################################
+mollweide: mollweide.o
+	$(LINK.cc) -DTEST_MOLLWEIDE $^ -o $@ $(LOADLIBES) $(LIBS) $(LDLIBS)
+mollweide.o: mollweide.cc mollweide.h
+	$(COMPILE.cc) -DTEST_MOLLWEIDE -o $@ $<
+##############################################################################
Index: /tags/V_Dec2002/SophyaExt/XAstroPack/exclude
===================================================================
--- /tags/V_Dec2002/SophyaExt/XAstroPack/exclude	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XAstroPack/exclude	(revision 2309)
@@ -0,0 +1,1 @@
+tstxastro.cc
Index: /tags/V_Dec2002/SophyaExt/XAstroPack/extlib_list
===================================================================
--- /tags/V_Dec2002/SophyaExt/XAstroPack/extlib_list	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XAstroPack/extlib_list	(revision 2309)
@@ -0,0 +1,1 @@
+xastro
Index: /tags/V_Dec2002/SophyaExt/XAstroPack/extslb_list
===================================================================
--- /tags/V_Dec2002/SophyaExt/XAstroPack/extslb_list	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XAstroPack/extslb_list	(revision 2309)
@@ -0,0 +1,1 @@
+xastro
Index: /tags/V_Dec2002/SophyaExt/XAstroPack/magfield.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XAstroPack/magfield.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XAstroPack/magfield.c	(revision 2309)
@@ -0,0 +1,781 @@
+/*  module magfield.c */
+
+/* Module to calculate magnetic variation and field given position,
+**               altitude, and date
+** Implements the NIMA (formerly DMA) WMM and IGRF models
+**
+**    http://www.nima.mil/GandG/ngdc-wmm2000.html
+**    For WMM2000 coefficients:
+**    ftp://ftp.ngdc.noaa.gov/Solid_Earth/Mainfld_Mag/DoD_Model/wmm.cof
+**    For IGRF/DGRF coefficients:
+**    http://swdcdb.kugi.kyoto-u.ac.jp/igrf/coef/igrfall.d
+**
+** Copyright (C) 2000  Edward A Williams <Ed_Williams@compuserve.com>
+**
+**  The routine uses a spherical harmonic expansion of the magnetic
+** potential up to twelfth order, together with its time variation, as
+** described in Chapter 4 of "Geomagnetism, Vol 1, Ed. J.A.Jacobs,
+** Academic Press (London 1987)". The program first converts geodetic
+** coordinates (lat/long on elliptic earth and altitude) to spherical
+** geocentric (spherical lat/long and radius) coordinates. Using this,
+** the spherical (B_r, B_theta, B_phi) magnetic field components are
+** computed from the model. These are finally referred to surface (X, Y,
+** Z) coordinates.
+**
+**   Fields are accurate to better than 200nT, variation and dip to
+** better than 0.5 degrees, with the exception of the declination near
+** the magnetic poles (where it is ill-defined) where the error may reach
+** 4 degrees or more.
+**
+**   Variation is undefined at both the geographic and  
+** magnetic poles, even though the field itself is well-behaved. To
+** avoid the routine blowing up, latitude entries corresponding to
+** the geographic poles are slightly offset. At the magnetic poles,
+** the routine returns zero variation.
+**
+** HISTORY
+** Adapted from EAW Excel 3.0 version 3/27/94 EAW
+** Recoded in C++ by Starry Chan
+** WMM95 added and rearranged in ANSI-C EAW 7/9/95
+** Put shell around program and made Borland & GCC compatible EAW 11/22/95
+** IGRF95 added 2/96 EAW
+** WMM2000 IGR2000 added 2/00 EAW
+** Released under GPL  3/26/00 EAW
+** Adaptions and modifications for the SimGear project  3/27/2000 CLO
+** Removed all pow() calls and made static roots[][] arrays to
+** save many sqrt() calls on subsequent invocations
+** 3/28/2000  Norman Vine -- nhv@yahoo.com
+** Put in some bullet-proofing to handle magnetic and geographic poles.
+** 3/28/2000 EAW
+** Added missing comment close, the lack of which caused the altitude 
+** correction to be omitted.
+** 01/31/01 Jim Seymour (jseymour@LinxNet.com)
+**
+** This program is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of the
+** License, or (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful, but
+** WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+** General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+**
+*/ 
+
+#include	<stdio.h>
+#include	<stdlib.h>
+#include	<math.h>
+#include        "magfield.h"
+
+#define	max(a,b)	(((a) > (b)) ? (a) : (b))
+
+static const double pi = 3.14159265358979;
+static const double a = 6378.16;	/* major radius (km) IAU66 ellipsoid */
+static const double f = 1.0 / 298.25;	/* inverse flattening IAU66 ellipsoid */
+static const double b = 6378.16 * (1.0 -1.0 / 298.25 );
+	/* minor radius b=a*(1-f) */
+static const double r_0 = 6371.2;	/* "mean radius" for spherical harmonic expansion */
+
+/*IGRF90 constants */
+static const double gnm_igrf90[13][13] = 
+	{
+        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+	{-29775.4, -1851, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{-2135.8, 3058.2, 1693.2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{1314.6, -2240.2, 1245.6, 806.5, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{938.9, 782.3, 323.9, -422.7, 141.7, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{-211, 352.5, 243.8, -110.8, -165.6, -37, 0, 0, 0, 0, 0, 0, 0}, 
+	{60.7, 63.9, 60.4, -177.5, 2, 16.7, -96.3, 0, 0, 0, 0, 0, 0}, 
+	{76.6, -64.2, 3.7, 27.5, 0.9, 5.7, 9.8, -0.5, 0, 0, 0, 0, 0}, 
+	{22.4, 5.1, -0.9, -10.8, -12.4, 3.8, 3.8, 2.6, -6, 0, 0, 0, 0}, 
+	{4.4, 9.9, 0.8, -12, 9.3, -3.9, -1.4, 7.3, 1.5, -5.5, 0, 0, 0}, 
+	{-3.6, -3.9, 2.4, -5.3, -2.4, 4.4, 3, 1.2, 2.2, 2.9, 0, 0, 0},
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+static const double hnm_igrf90[13][13] = 
+	{
+        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+	{0, 5410.9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, -2277.7, -380, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, -286.5, 293.3, -348.5, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 248.1, -239.5, 87, -299.4, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 47.2, 153.5, -154.4, -69.2, 97.7, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, -15.8, 82.7, 68.3, -52.5, 1.8, 26.9, 0, 0, 0, 0, 0, 0},
+	{0, -81.1, -27.3, 0.6, 20.4, 16.4, -22.6, -5, 0, 0, 0, 0, 0}, 
+	{0, 9.7, -19.9, 7.1, -22.1, 11.9, 11, -16, -10.7, 0, 0, 0, 0}, 
+	{0, -20.8, 15.4, 9.5, -5.7, -6.4, 8.6, 9.1, -6.6, 1.9, 0, 0, 0}, 
+	{0, 1.3, 0.4, 3.1, 5.6, -4.2, -0.5, -1.5, 3.8, -0.5, -6.2, 0, 0}, 
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+static const double gtnm_igrf90[13][13] = 
+	{
+        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+	{18, 10.6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{-12.9, 2.4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+	{3.3, -6.7, 0, -5.9, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0.5, 0.6, -7, 0.5, -5.5, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0.6, -0.1, -1.6, -3.1, 0, 2.3, 0, 0, 0, 0, 0, 0, 0}, 
+	{1.3, -0.2, 1.8, 1.3, -0.2, 0.1, 1.2, 0, 0, 0, 0, 0, 0}, 
+	{0.6, -0.5, -0.3, 0.6, 1.6, 0.2, 0.2, 0.3, 0, 0, 0, 0, 0}, 
+	{0.2, -0.7, -0.2, 0.1, -1.1, 0, 0, -0.5, -0.6, 0, 0, 0, 0}, 
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+static const double htnm_igrf90[13][13] =
+	{
+        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+	{0, -16.1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, -15.8, -13.8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 4.4, 1.6, -10.6, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 2.6, 1.8, 3.1, -1.4, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, -0.1, 0.5, 0.4, 1.7, 0.4, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 0.2, -1.3, 0, -0.9, 0.5, 1.2, 0, 0, 0, 0, 0, 0}, 
+	{0, 0.6, 0.2, 0.8, -0.5, -0.2, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 0.5, -0.2, 0.3, 0.3, 0.4, -0.5, -0.3, 0.6, 0, 0, 0, 0}, 
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+/* IGRF95 */
+static const double gnm_igrf95[13][13] =
+{
+  {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+  {-29682.0, -1789.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+  {-2197.0, 3074.0, 1685.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+  {1329.0, -2268.0, 1249.0, 769.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+  {941.0, 782.0, 291.0, -421.0, 116.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+  {-210.0, 352.0, 237.0, -122.0, -167.0, -26.0, 0.0, 0.0, 0.0, 0.0,0.0,0.0,0.0},
+  {66.0, 64.0, 65.0, -172.0, 2.0, 17.0, -94.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {78.0, -67.0, 1.0, 29.0, 4.0, 8.0, 10.0, -2.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {24.0, 4.0, -1.0, -9.0, -14.0, 4.0, 5.0, 0.0, -7.0, 0.0,0.0, 0.0, 0.0},
+  {4.0, 9.0, 1.0, -12.0, 9.0, -4.0, -2.0, 7.0, 0.0, -6.0, 0.0, 0.0, 0.0},
+  {-3.0, -4.0, 2.0, -5.0, -2.0, 4.0, 3.0, 1.0, 3.0, 3.0, 0.0, 0.0, 0.0},
+  {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0}
+ };
+
+static const double hnm_igrf95[13][13]=
+{
+  {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {0.0, 5318.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {0.0, -2356.0, -425.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {0.0, -263.0, 302.0, -406.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {0.0, 262.0, -232.0, 98.0, -301.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {0.0, 44.0, 157.0, -152.0, -64.0, 99.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {0.0, -16.0, 77.0, 67.0, -57.0, 4.0, 28.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {0.0, -77.0, -25.0, 3.0, 22.0, 16.0, -23.0, -3.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {0.0, 12.0, -20.0, 7.0, -21.0, 12.0, 10.0, -17.0, -10.0,0.0, 0.0, 0.0, 0.0},
+  {0.0, -19.0, 15.0, 11.0, -7.0, -7.0, 9.0, 7.0, -8.0, 1.0, 0.0, 0.0, 0.0},
+  {0.0, 2.0, 1.0, 3.0, 6.0, -4.0, 0.0, -2.0, 3.0, -1.0, -6.0, 0.0, 0.0},
+  {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0}
+};
+
+static const double gtnm_igrf95[13][13]=
+{
+  {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {17.6, 13.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {-13.2, 3.7, -0.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {1.5, -6.4, -0.2, -8.1, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {0.8, 0.9, -6.9, 0.5, -4.6, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {0.8, 0.1, -1.5, -2.0, -0.1, 2.3, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {0.5, -0.4, 0.6, 1.9, -0.2, -0.2, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {-0.2, -0.8, -0.6, 0.6, 1.2, 0.1, 0.2, -0.6, 0.0,0.0, 0.0, 0.0, 0.0},
+  {0.3, -0.2, 0.1, 0.4, -1.1, 0.3, 0.2, -0.9, -0.3, 0.0,0.0, 0.0, 0.0},
+  {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0}
+ };
+
+static const double htnm_igrf95[13][13]=
+{
+  {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {0.0, -18.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {0.0, -15.0, -8.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {0.0, 4.1, 2.2, -12.1, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {0.0, 1.8, 1.2, 2.7, -1.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {0.0, 0.2, 1.2, 0.3, 1.8, 0.9, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {0.0, 0.3, -1.6, -0.2, -0.9, 1.0, 2.2, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {0.0, 0.8, 0.2, 0.6, -0.4, 0.0, -0.3, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {0.0, 0.4, -0.2, 0.2, 0.7, 0.0, -1.2, -0.7, -0.6, 0.0,0.0, 0.0, 0.0},
+  {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0},
+  {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0, 0.0, 0.0, 0.0}
+};
+
+/*WMM85 constants */
+static const double gnm_wmm85[13][13] = 
+	{
+        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+	{-29879.8, -1903.3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{-2070.6, 3040.8, 1696.7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{1303.9, -2203, 1241.7, 839.4, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{933.8, 781.8, 359, -424.5, 164.5, 0, 0, 0, 0, 0, 0, 0, 0},
+	{-216.4, 353, 254.3, -93.7, -157.5, -45.2, 0, 0, 0, 0, 0, 0, 0}, 
+	{53.2, 63.8, 51.3, -188.4, 3.3, 20.3, -101.7, 0, 0, 0, 0, 0, 0}, 
+	{76.9, -60.7, 0.7, 25.4, -8.1, 6.9, 7, -4.4, 0, 0, 0, 0, 0}, 
+	{18.4, 5.1, 1.2, -12, -9.1, 0.1, 4.7, 6.5, -9.5, 0, 0, 0, 0}, 
+	{5.7, 10.9, 0.9, -12.2, 9.5, -3.3, -1, 6.5, 1.5, -4.8, 0, 0, 0}, 
+	{-3.4, -4.7, 2.5, -5.5, -2.1, 4.6, 3.2, 0.6, 1.9, 2.8, -0.2, 0, 0}, 
+	{2.3, -0.8, -2, 2.1, 0.2, -0.4, -0.4, 1.6, 1.5, -0.7, 2.3, 3.5, 0}, 
+	{-1.8, 0, 0.1, -0.3, 0.5, 0.5, -0.6, -0.4, 0, -0.5, 0, 0.7, -0.2}};
+static const double hnm_wmm85[13][13] = 
+	{
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+	{0, 5490.5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, -2189.1, -312, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, -310.3, 282.6, -299.2, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 227.2, -246.7, 72.5, -299.1, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 43.4, 148.2, -154.8, -71.8, 91.5, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, -12.3, 87.9, 67.8, -51.1, -4, 20.8, 0, 0, 0, 0, 0, 0}, 
+	{0, -80.1, -25.9, -0.9, 21.6, 18.5, -20, -7.7, 0, 0, 0, 0, 0}, 
+	{0, 3.8, -20.2, 5, -24.2, 12.2, 7.6, -16.3, -10.9, 0, 0, 0, 0}, 
+	{0, -20.8, 15.8, 9, -5, -6.4, 9.1, 9.9, -5.8, 2.3, 0, 0, 0}, 
+	{0, 1.2, 0.4, 2.5, 5.6, -4.4, -0.5, -1.6, 3.7, -0.5, -6.1, 0, 0}, 
+	{0, 1.3, 2, -1.1, -2.8, 0.7, -0.1, -2.4, -0.4, -1.5, -1.5, 0.7, 0},
+	{0, 0.3, 0.6, 2.5, -1.7, 0.3, 0.2, -0.1, 0.1, 0.1, -1.4, 0.4, 0.7}};
+static const double gtnm_wmm85[13][13] = 
+	{
+        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+	{21.9, 10.6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{-11.2, 1.8, 9.3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{8.3, -2, -0.6, 2.4, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{-1.2, 0.1, -9.7, -1.7, -9.3, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{1.4, -0.5, -1.2, -2.2, 0.9, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{3.1, 0, 1.8, -0.2, -0.4, 2.4, 1.8, 0, 0, 0, 0, 0, 0}, 
+	{-0.1, -0.8, -1.2, 1.1, 0, 0.6, -1.8, -1.2, 0, 0, 0, 0, 0},
+	{0.2, 0, 0.7, 0.1, 0.2, -0.3, -0.1, 0.2, -2.2, 0, 0, 0, 0}, 
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+static const double htnm_wmm85[13][13] = 
+	{
+        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+	{0, -31.5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, -9.7, -19.9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 6.1, 1.3, -13, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+	{0, 1.3, 3.6, 2.5, 0.6, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, -0.9, 0.6, 0.3, 2.4, -1.4, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 0.7, -2.1, -1.4, -4.3, -0.7, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 0, 1.2, 2, 2.6, 0.9, 0.8, 0.4, 0, 0, 0, 0, 0}, 
+	{0, -0.6, -1.5, 0.1, -1.1, 0.4, -2, 0.9, 1.5, 0, 0, 0, 0}, 
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+
+/* wmm90 constants */
+static const double gnm_wmm90[13][13] =
+	{
+        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+	{-29780.5, -1851.7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{-2134.3, 3062.2, 1691.9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{1312.9, -2244.7, 1246.8, 808.6, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{933.5, 784.9, 323.5, -421.7, 139.2, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{-208.3, 352.2, 246.5, -110.8, -162.3, -37.2, 0, 0, 0, 0, 0, 0, 0}, 
+	{59, 63.7, 60, -181.3, 0.4, 15.4, -96, 0, 0, 0, 0, 0, 0}, 
+	{76.1, -62.1, 1.3, 30.2, 4.7, 7.9, 10.1, 1.9, 0, 0, 0, 0, 0}, 
+	{22.9, 2.3, -1.2, -11.7, -17.5, 2.2, 5.7, 3, -7, 0, 0, 0, 0}, 
+	{3.6, 9.5, -0.9, -10.7, 10.7, -3.2, -1.4, 6.3, 0.8, -5.5, 0, 0, 0},
+	{-3.3, -2.6, 4.5, -5.6, -3.6, 3.9, 3.2, 1.7, 3, 3.7, 0.7, 0, 0}, 
+	{1.3, -1.4, -2.5, 3.2, 0.2, -1.1, 0.3, -0.3, 0.9, -1.1, 2.4, 3, 0}, 
+	{-1.3, 0.1, 0.5, 0.7, 0.4, -0.2, -1.1, 0.9, -0.6, 0.8, 0.2, 0.4, 0.2}};
+static const double hnm_wmm90[13][13] = 
+	{
+        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+	{0, 5407.2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, -2278.3, -384.3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, -284.9, 291.7, -352.4, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 249.4, -232.7, 91.3, -296.5, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 40.8, 148.7, -154.6, -67.6, 97.4, 0, 0, 0, 0, 0, 0, 0},
+	{0, -14.7, 82.2, 70, -56.2, -1.4, 24.6, 0, 0, 0, 0, 0, 0}, 
+	{0, -78.6, -26.7, 0.1, 19.9, 17.9, -21.5, -6.8, 0, 0, 0, 0, 0}, 
+	{0, 9.7, -19.3, 6.6, -20.1, 13.4, 9.8, -19, -9.1, 0, 0, 0, 0}, 
+	{0, -21.9, 14.3, 9.5, -6.7, -6.4, 9.1, 8.9, -8, 2.1, 0, 0, 0}, 
+	{0, 2.6, 1.2, 2.6, 5.7, -4, -0.4, -1.7, 3.8, -0.8, -6.5, 0, 0}, 
+	{0, 0, 1, -1.6, -2.2, 1.1, -0.7, -1.7, -1.5, -1.3, -1.1, 0.6, 0}, 
+	{0, 0.7, 0.7, 1.3, -1.5, 0.3, 0.2, -1.1, 1.2, -0.2, -1.3, 0.6, 0.6}};
+static const double gtnm_wmm90[13][13] = 
+	{
+        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+	{16, 9.3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+	{-11.7, 3.7, 1.8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{2.1, -7.6, 0, -5.8, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{-0.8, 1, -7.4, 0.8, -6.4, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{1.7, 0, 0, -2.7, 0, 3, 0, 0, 0, 0, 0, 0, 0}, 
+	{0.8, 0, 1.5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0.5, 0, -0.9, 1.5, 2.7, -1, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, -1.1, 0, 0, -2.1, 0, 1, 0, 0, 0, 0, 0, 0}, 
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+static const double htnm_wmm90[13][13] = 
+	{
+        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+	{0, -13.8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, -12.8, -14.9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 3.1, 0.8, -11.3, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 3.3, 3.7, 2.8, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 0, -2.1, 1.2, 1.2, 0.6, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, -0.6, -0.6, 0, -2.3, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 0.6, 0.8, 0, 0, 0, 0.4, 0, 0, 0, 0, 0, 0}, 
+	{0, 0.4, -0.8, 0.5, 0.3, 0.5, 0, -0.7, 0, 0, 0, 0, 0},
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
+	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+/* wmm95 constants */
+static const double gnm_wmm95[13][13] =
+        {
+        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+	{-29682.1,-1782.2,0,0,0,0,0,0,0,0,0,0,0},
+        {-2194.7,3078.6,1685.7,0,0,0,0,0,0,0,0,0,0},
+	{1318.8,-2273.6,1246.9,766.3,0,0,0,0,0,0,0,0,0},
+        {940,782.9,290.9,-418.9,113.8,0,0,0,0,0,0,0,0},
+        {-209.5,354,238.2,-122.1,-162.8,-23.3,0,0,0,0,0,0,0},
+        {68.5,65.6,64.1,-169.1,-0.5,16.5,-91,0,0,0,0,0,0},
+        {78,-68.1,0.1,29.6,6,8.7,9.2,-2.4,0,0,0,0,0},
+        {24.7,3.4,-1.5,-9.6,-16.5,2.6,3.6,-4.9,-8.5,0,0,0,0},
+        {2.9,7.5,0.4,-10.3,9.7,-2.3,-2.4,6.8,-0.5,-6.5,0,0,0},
+        {-2.9,-3.3,2.8,-4.3,-3.1,2.4,2.8,0.7,4.1,3.6,0.6,0,0},
+        {1.7,-1.6,-3.6,1.2,-0.6,0.1,-0.7,-0.8,1.3,-0.3,2.2,4.2,0},
+        {-1.8,0.9,-0.1,-0.5,0.8,0.2,0.5,0.4,-0.4,0.3,0.2,0.4,0.6}};
+static const double hnm_wmm95[13][13] =
+	{
+        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+        {0,5315.6,0,0,0,0,0,0,0,0,0,0,0},
+        {0,-2359.1,-418.6,0,0,0,0,0,0,0,0,0,0},
+        {0,-261.1,301,-416.5,0,0,0,0,0,0,0,0,0},
+        {0,259.4,-230.9,99.8,-306.1,0,0,0,0,0,0,0,0},
+        {0,43.7,157.6,-150.1,-59.2,104.4,0,0,0,0,0,0,0},
+        {0,-15.2,74.3,69.4,-55.3,3,33.3,0,0,0,0,0,0},
+        {0,-76.1,-24.5,1.6,20,16.5,-23.6,-6.8,0,0,0,0,0},
+        {0,14.9,-19.5,6.3,-20.4,12.2,7,-19,-8.8,0,0,0,0},
+        {0,-19.8,14.6,10.9,-7.5,-6.8,9.3,7.7,-8.1,2.6,0,0,0},
+	{0,3.2,1.7,2.9,5.6,-3.4,-0.7,-2.9,2.3,-1.6,-6.6,0,0},
+        {0,0.3,1,-3.6,-1.4,1.9,0.2,-1.3,-2.4,-0.6,-2.2,1.3,0},
+        {0,0.3,1.4,0.8,-3,0.7,0.5,-0.8,0.6,0.1,-1.3,-0.4,0.9}};
+static const double gtnm_wmm95[13][13] =
+        {
+        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+        {17.6,13.2,0,0,0,0,0,0,0,0,0,0,0},
+        {-13.7,4,-0.3,0,0,0,0,0,0,0,0,0,0},
+        {0.8,-6.6,-0.5,-8.5,0,0,0,0,0,0,0,0,0},
+        {1.2,1.1,-6.8,0.3,-4.5,0,0,0,0,0,0,0,0},
+        {0.9,0.5,-1.4,-1.7,0,2.1,0,0,0,0,0,0,0},
+	{0.4,-0.3,0.3,2.1,0,-0.4,-0.4,0,0,0,0,0,0},
+        {-0.3,-1.1,-0.5,0.5,1.3,0.1,0,-0.9,0,0,0,0,0},
+        {0.1,0,0.4,0.3,-1.3,0.5,0.4,-0.9,0.1,0,0,0,0},
+        {0,0,0,0,0,0,0,0,0,0,0,0,0},
+        {0,0,0,0,0,0,0,0,0,0,0,0,0},
+        {0,0,0,0,0,0,0,0,0,0,0,0,0},
+        {0,0,0,0,0,0,0,0,0,0,0,0,0}};
+static const double htnm_wmm95[13][13] =
+        {
+        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+	{0,-18,0,0,0,0,0,0,0,0,0,0,0},
+	{0,-14.6,-7.2,0,0,0,0,0,0,0,0,0,0},
+        {0,4,2.2,-12.6,0,0,0,0,0,0,0,0,0},
+        {0,1.3,1,2.5,-1.2,0,0,0,0,0,0,0,0},
+        {0,0.5,1.5,0.6,1.7,0.6,0,0,0,0,0,0,0},
+        {0,0.7,-1.5,-0.5,-0.7,1.1,2.6,0,0,0,0,0,0},
+        {0,0.3,0,0.7,-0.6,0.1,-0.6,-0.4,0,0,0,0,0},
+        {0,0.4,-0.3,0.1,0.8,-0.1,-1.3,-0.9,-1.1,0,0,0,0},
+        {0,0,0,0,0,0,0,0,0,0,0,0,0},
+        {0,0,0,0,0,0,0,0,0,0,0,0,0},
+        {0,0,0,0,0,0,0,0,0,0,0,0,0},
+        {0,0,0,0,0,0,0,0,0,0,0,0,0}};
+
+static const double gnm_wmm2000[13][13] =
+        {
+	{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{-29616.0, -1722.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{-2266.7, 3070.2, 1677.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{1322.4, -2291.5, 1255.9, 724.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{932.1, 786.3, 250.6, -401.5, 106.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{-211.9, 351.6, 220.8, -134.5, -168.8, -13.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{73.8, 68.2, 74.1, -163.5, -3.8, 17.1, -85.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{77.4, -73.9, 2.2, 35.7, 7.3, 5.2, 8.4, -1.5, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{23.3, 7.3, -8.5, -6.6, -16.9, 8.6, 4.9, -7.8, -7.6, 0.0, 0.0, 0.0, 0.0},
+	{5.7, 8.5, 2.0, -9.8, 7.6, -7.0, -2.0, 9.2, -2.2, -6.6, 0.0, 0.0, 0.0},
+	{-2.2, -5.7, 1.6, -3.7, -0.6, 4.1, 2.2, 2.2, 4.6, 2.3, 0.1, 0.0, 0.0},
+	{3.3, -1.1, -2.4, 2.6, -1.3, -1.7, -0.6, 0.4, 0.7, -0.3, 2.3, 4.2, 0.0},
+	{-1.5, -0.2, -0.3, 0.5, 0.2, 0.9, -1.4, 0.6, -0.6, -1.0, -0.3, 0.3, 0.4},
+	};
+
+static const double hnm_wmm2000[13][13]=
+        {
+	{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 5194.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, -2484.8, -467.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, -224.7, 293.0, -486.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 273.3, -227.9, 120.9, -302.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 42.0, 173.8, -135.0, -38.6, 105.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, -17.4, 61.2, 63.2, -62.9, 0.2, 43.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, -62.3, -24.5, 8.9, 23.4, 15.0, -27.6, -7.8, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 12.4, -20.8, 8.4, -21.2, 15.5, 9.1, -15.5, -5.4, 0.0, 0.0, 0.0, 0.0},
+	{0.0, -20.4, 13.9, 12.0, -6.2, -8.6, 9.4, 5.0, -8.4, 3.2, 0.0, 0.0, 0.0},
+	{0.0, 0.9, -0.7, 3.9, 4.8, -5.3, -1.0, -2.4, 1.3, -2.3, -6.4, 0.0, 0.0},
+	{0.0, -1.5, 0.7, -1.1, -2.3, 1.3, -0.6, -2.8, -1.6, -0.1, -1.9, 1.4, 0.0},
+	{0.0, -1.0, 0.7, 2.2, -2.5, -0.2, 0.0, -0.2, 0.0, 0.2, -0.9, -0.2, 1.0},
+	};
+
+static const double gtnm_wmm2000[13][13]=
+        {
+	{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{14.7, 11.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{-13.6, -0.7, -1.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.3, -4.3, 0.9, -8.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{-1.6, 0.9, -7.6, 2.2, -3.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{-0.9, -0.2, -2.5, -2.7, -0.9, 1.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{1.2, 0.2, 1.7, 1.6, -0.1, -0.3, 0.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{-0.4, -0.8, -0.2, 1.1, 0.4, 0.0, -0.2, -0.2, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{-0.3, 0.6, -0.8, 0.3, -0.2, 0.5, 0.0, -0.6, 0.1, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	};
+
+static const double htnm_wmm2000[13][13]=
+        {
+        {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, -20.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, -21.5, -9.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 6.4, -1.3, -13.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 2.3, 0.7, 3.7, -0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 0.0, 2.1, 2.3, 3.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, -0.3, -1.7, -0.9, -1.0, -0.1, 1.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 1.4, 0.2, 0.7, 0.4, -0.3, -0.8, -0.1, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, -0.5, 0.1, -0.2, 0.0, 0.1, -0.1, 0.3, 0.2, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+        };
+
+static const double gnm_igrf2000[13][13] =
+        {
+	{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{-29615.0, -1728.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{-2267.0, 3072.0, 1672.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{1341.0, -2290.0, 1253.0, 715.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{935.0, 787.0, 251.0, -405.0, 110.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{-217.0, 351.0, 222.0, -131.0, -169.0, -12.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{72.0, 68.0, 74.0, -161.0, -5.0, 17.0, -91.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{79.0, -74.0, 0.0, 33.0, 9.0, 7.0, 8.0, -2.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{25.0, 6.0, -9.0, -8.0, -17.0, 9.0, 7.0, -8.0, -7.0, 0.0, 0.0, 0.0, 0.0},
+	{5.0, 9.0, 3.0, -8.0, 6.0, -9.0, -2.0, 9.0, -4.0, -8.0, 0.0, 0.0, 0.0},
+	{-2.0, -6.0, 2.0, -3.0, 0.0, 4.0, 1.0, 2.0, 4.0, 0.0, -1.0, 0.0, 0.0},
+	{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	};
+
+static const double hnm_igrf2000[13][13]=
+        {
+	{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 5186.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, -2478.0, -458.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, -227.0, 296.0, -492.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 272.0, -232.0, 119.0, -304.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 44.0, 172.0, -134.0, -40.0, 107.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, -17.0, 64.0, 65.0, -61.0, 1.0, 44.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, -65.0, -24.0, 6.0, 24.0, 15.0, -25.0, -6.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 12.0, -22.0, 8.0, -21.0, 15.0, 9.0, -16.0, -3.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, -20.0, 13.0, 12.0, -6.0, -8.0, 9.0, 4.0, -8.0, 5.0, 0.0, 0.0, 0.0},
+	{0.0, 1.0, 0.0, 4.0, 5.0, -6.0, -1.0, -3.0, 0.0, -2.0, -8.0, 0.0, 0.0},
+	{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	};
+
+static const double gtnm_igrf2000[13][13]=
+        {
+	{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{14.6, 10.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{-12.4, 1.1, -1.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.7, -5.4, 0.9, -7.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{-1.3, 1.6, -7.3, 2.9, -3.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, -0.7, -2.1, -2.8, -0.8, 2.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{1.0, -0.4, 0.9, 2.0, -0.6, -0.3, 1.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{-0.4, -0.4, -0.3, 1.1, 1.1, -0.2, 0.6, -0.9, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{-0.3, 0.2, -0.3, 0.4, -1.0, 0.3, -0.5, -0.7, -0.4, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	};
+
+static const double htnm_igrf2000[13][13]=
+        {
+	{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, -22.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, -20.6, -9.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 6.0, -0.1, -14.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 2.1, 1.3, 5.0, 0.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, -0.1, 0.6, 1.7, 1.9, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, -0.2, -1.4, 0.0, -0.8, 0.0, 0.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 1.1, 0.0, 0.3, -0.1, -0.6, -0.7, 0.2, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 0.1, 0.0, 0.0, 0.3, 0.6, -0.4, 0.3, 0.7, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+	};
+
+
+
+static const int nmax = 12;
+
+double P[13][13];
+double DP[13][13];
+double gnm[13][13];
+double hnm[13][13];
+double sm[13];
+double cm[13];
+
+static double root[13];
+static double roots[13][13][2];
+
+/* Convert date to Julian day    1950-2049 */
+unsigned long int yymmdd_to_julian_days(int yy,int mm,int dd)
+{
+  unsigned long jd;
+ 
+  yy = (yy < 50) ? (2000 + yy) : (1900 + yy);
+  jd = dd - 32075L + 1461L * (yy + 4800L + (mm - 14) / 12 ) / 4;
+  jd = jd + 367L * (mm - 2 - (mm - 14) / 12*12) / 12;
+  jd = jd - 3 * ((yy + 4900L + (mm - 14) / 12) / 100) / 4;
+
+  return(jd);
+} 
+
+/* Convert degrees to radians */
+double deg_to_rad(double deg)
+{
+return deg*pi/180.;
+}
+
+/* Convert radians to degrees */
+double rad_to_deg(double rad)
+{
+return rad*180./pi;
+}
+	     
+
+
+
+/* 
+ * return variation (in radians) given geodetic latitude (radians), longitude
+ * (radians) ,height (km) and (Julian) date
+ * model=1 is IGRF90, 2 is WMM85, 3 is WMM90, 4 is WMM95, 
+ * 5 is IGRF95, 6 is WMM2000, 7 is IGRF2000
+ * N and E lat and long are positive, S and W negative
+*/
+
+double SGMagVar( double lat, double lon, double h, long dat, int model, double* field )
+{
+    /* output field B_r,B_th,B_phi,B_x,B_y,B_z */
+    int n,m;
+    double yearfrac,sr,r,theta,c,s,psi,fn,fn_0,B_r,B_theta,B_phi,X,Y,Z;
+    double sinpsi, cospsi, inv_s;
+
+    static int been_here = 0;
+	
+    double sinlat = sin(lat);
+    double coslat = cos(lat);
+
+    /* convert to geocentric */ 
+    sr = sqrt(a*a*coslat*coslat + b*b*sinlat*sinlat);
+    /* sr is effective radius */
+    theta = atan2(coslat * (h*sr + a*a), sinlat * (h*sr + b*b));
+		  
+    /* theta is geocentric co-latitude */
+
+    r = h*h + 2.0*h * sr +
+	(a*a*a*a - ( a*a*a*a - b*b*b*b ) * sinlat*sinlat ) / 
+	(a*a - (a*a - b*b) * sinlat*sinlat );
+
+    r = sqrt(r);
+
+    /* r is geocentric radial distance */
+    c = cos(theta);
+    s = sin(theta);
+      /* protect against zero divide at geographic poles */
+    inv_s =  1.0 / (s + (s == 0.)*1.0e-8); 
+
+    /*zero out arrays */
+    for ( n = 0; n <= nmax; n++ ) {
+      for ( m = 0; m <= n; m++ ) {
+	P[n][m] = 0;
+	DP[n][m] = 0;
+      }
+    }
+
+    /* diagonal elements */
+    P[0][0] = 1;
+    P[1][1] = s;
+    DP[0][0] = 0;
+    DP[1][1] = c;
+    P[1][0] = c ;
+    DP[1][0] = -s;
+
+    /* these values will not change for subsequent function calls */
+    if( !been_here ) {
+      for ( n = 2; n <= nmax; n++ ) {
+	root[n] = sqrt((2.0*n-1) / (2.0*n));
+      }
+	
+      for ( m = 0; m <= nmax; m++ ) {
+	double mm = m*m;
+	for ( n = max(m + 1, 2); n <= nmax; n++ ) {
+	  roots[m][n][0] = sqrt((n-1)*(n-1) - mm);
+	  roots[m][n][1] = 1.0 / sqrt( n*n - mm);
+	}
+      }
+      been_here = 1;
+    }
+	
+    for ( n=2; n <= nmax; n++ ) {
+      /*  double root = sqrt((2.0*n-1) / (2.0*n)); */
+      P[n][n] = P[n-1][n-1] * s * root[n];
+      DP[n][n] = (DP[n-1][n-1] * s + P[n-1][n-1] * c) * root[n];
+    }
+
+    /* lower triangle */
+    for ( m = 0; m <= nmax; m++ ) {
+      /*  double mm = m*m;  */
+      for ( n = max(m + 1, 2); n <= nmax; n++ ) {
+	/* double root1 = sqrt((n-1)*(n-1) - mm); */
+	/* double root2 = 1.0 / sqrt( n*n - mm);  */
+	P[n][m] = (P[n-1][m] * c * (2.0*n-1) -
+		   P[n-2][m] * roots[m][n][0]) * roots[m][n][1];
+	DP[n][m] = ((DP[n-1][m] * c - P[n-1][m] * s) *
+		    (2.0*n-1) - DP[n-2][m] * roots[m][n][0]) * roots[m][n][1];
+      }
+    }
+
+    /* compute gnm, hnm at dat */
+    switch(model) {
+    case 1:	/* IGRF90 */
+      yearfrac = (dat - yymmdd_to_julian_days(90,1,1)) / 365.25;
+      for (n=1;n<=nmax;n++)
+        for (m = 0;m<=nmax;m++) {
+	  gnm[n][m] = gnm_igrf90[n][m] + yearfrac * gtnm_igrf90[n][m];
+	  hnm[n][m] = hnm_igrf90[n][m] + yearfrac * htnm_igrf90[n][m];
+	}
+      break;
+
+    case 2:	/* WMM85 */
+      yearfrac = (dat - yymmdd_to_julian_days(85,1,1)) / 365.25;
+      for (n=1;n<=nmax;n++)
+        for (m = 0;m<=nmax;m++) {
+	  gnm[n][m] = gnm_wmm85[n][m] + yearfrac * gtnm_wmm85[n][m];
+	  hnm[n][m] = hnm_wmm85[n][m] + yearfrac * htnm_wmm85[n][m];
+	}
+      break;
+
+    case 3:	/* WMM90 */
+      yearfrac = (dat - yymmdd_to_julian_days(90,1,1)) / 365.25;
+      for (n=1;n<=nmax;n++)
+	for (m = 0;m<=nmax;m++) {
+	  gnm[n][m] = gnm_wmm90[n][m] + yearfrac * gtnm_wmm90[n][m];
+	  hnm[n][m] = hnm_wmm90[n][m] + yearfrac * htnm_wmm90[n][m];
+	}
+      break;
+
+    case 4:	/* WMM95 */
+      yearfrac = (dat - yymmdd_to_julian_days(95,1,1)) / 365.25;
+      for (n=1;n<=nmax;n++)
+        for (m = 0;m<=nmax;m++) {
+           gnm[n][m] = gnm_wmm95[n][m] + yearfrac * gtnm_wmm95[n][m];
+	   hnm[n][m] = hnm_wmm95[n][m] + yearfrac * htnm_wmm95[n][m];
+	}
+      break;
+    case 5:	/* IGRF95 */
+      yearfrac = (dat - yymmdd_to_julian_days(95,1,1)) / 365.25;
+      for (n=1;n<=nmax;n++)
+        for (m = 0;m<=nmax;m++) {
+           gnm[n][m] = gnm_igrf95[n][m] + yearfrac * gtnm_igrf95[n][m];
+	   hnm[n][m] = hnm_igrf95[n][m] + yearfrac * htnm_igrf95[n][m];
+	}
+      break;
+    case 6:      /* WMM2000 */
+      yearfrac = (dat - yymmdd_to_julian_days(0,1,1)) / 365.25;
+       for (n=1;n<=nmax;n++)
+         for (m = 0;m<=nmax;m++) {
+           gnm[n][m] = gnm_wmm2000[n][m] + yearfrac * gtnm_wmm2000[n][m];
+	   hnm[n][m] = hnm_wmm2000[n][m] + yearfrac * htnm_wmm2000[n][m];
+	 }
+       break;
+    case 7:      /* IGRF2000 */
+      yearfrac = (dat - yymmdd_to_julian_days(0,1,1)) / 365.25;
+      for (n=1;n<=nmax;n++)
+	for (m = 0;m<=nmax;m++) {
+	  gnm[n][m] = gnm_igrf2000[n][m] + yearfrac * gtnm_igrf2000[n][m];
+	  hnm[n][m] = hnm_igrf2000[n][m] + yearfrac * htnm_igrf2000[n][m];
+	}
+      break;  
+    }
+
+    /* compute sm (sin(m lon) and cm (cos(m lon)) */
+    for (m = 0;m<=nmax;m++) {
+      sm[m] = sin(m * lon);
+      cm[m] = cos(m * lon);
+    }
+
+    /* compute B fields */
+    B_r = 0.0;
+    B_theta = 0.0;
+    B_phi = 0.0;
+    fn_0 = r_0/r;
+    fn = fn_0 * fn_0;
+	
+    for ( n = 1; n <= nmax; n++ ) {
+      double c1_n=0;
+      double c2_n=0;
+      double c3_n=0;
+      for ( m = 0; m <= n; m++ ) {
+	double tmp = (gnm[n][m] * cm[m] + hnm[n][m] * sm[m]); 
+	c1_n += tmp * P[n][m];
+	c2_n += tmp * DP[n][m];
+	c3_n +=  m * (gnm[n][m] * sm[m] - hnm[n][m] * cm[m]) * P[n][m];
+      }
+      /* fn=pow(r_0/r,n+2.0);   */
+      fn *= fn_0;
+      B_r += (n + 1) * c1_n * fn;
+      B_theta -= c2_n * fn;
+      B_phi += c3_n * fn * inv_s;
+    }
+
+
+
+    /* Find geodetic field components: */
+    psi = theta - (pi / 2.0 - lat);
+    sinpsi = sin(psi);
+    cospsi = cos(psi);
+    X = -B_theta * cospsi - B_r * sinpsi;
+    Y = B_phi;
+    Z = B_theta * sinpsi - B_r * cospsi;
+
+    field[0]=B_r;
+    field[1]=B_theta;
+    field[2]=B_phi;
+    field[3]=X;
+    field[4]=Y;
+    field[5]=Z;   /* output fields */
+    /* find variation in radians */
+    /* return zero variation at magnetic pole X=Y=0. */
+    /* E is positive */
+    return (X != 0. || Y != 0.) ? atan2(Y, X) : (double) 0.; 
+}
+
Index: /tags/V_Dec2002/SophyaExt/XAstroPack/magfield.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/XAstroPack/magfield.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XAstroPack/magfield.h	(revision 2309)
@@ -0,0 +1,66 @@
+/* magfield.h -- compute local magnetic variation given position,
+**               altitude, and date
+**
+** This is an implementation of the NIMA WMM 2000
+**
+**    http://www.nima.mil/GandG/ngdc-wmm2000.html
+**    For WMM2000 coefficients:
+**    ftp://ftp.ngdc.noaa.gov/Solid_Earth/Mainfld_Mag/DoD_Model/wmm.cof
+**    For IGRF/DGRF coefficients:
+**    http://swdcdb.kugi.kyoto-u.ac.jp/igrf/coef/igrfall.d
+**
+** Copyright (C) 2000  Edward A Williams <Ed_Williams@compuserve.com>
+**
+** Adapted from Excel 3.0 version 3/27/94 EAW
+** Recoded in C++ by Starry Chan
+** WMM95 added and rearranged in ANSI-C EAW 7/9/95
+** Put shell around program and made Borland & GCC compatible EAW 11/22/95
+** IGRF95 added 2/96 EAW
+** WMM2000 IGR2000 added 2/00 EAW
+** Released under GPL 3/26/00 EAW
+** Adaptions and modifications for the SimGear project  3/27/2000 CLO
+**
+** This program is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License as
+** published by the Free Software Foundation; either version 2 of the
+** License, or (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful, but
+** WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+** General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+**
+*/
+#ifndef MAGFIELD_H
+#define MAGFIELD_H
+
+#ifdef __cplusplus
+extern "C" {  /* extern "C" */
+#endif
+
+/* Convert date to Julian day    1950-2049 */
+unsigned long int yymmdd_to_julian_days( int yy, int mm, int dd );
+
+/* Convert degrees to radians */
+double deg_to_rad( double deg );
+
+/* Convert radians to degrees */
+double rad_to_deg( double rad );
+
+/* return variation (in radians) given geodetic latitude (radians), longitude
+(radians) ,height (km), (Julian) date and field model
+model=1 is IGRF90, 2 is WMM85, 3 is WMM90, 4 is WMM95, 5 is IGRF95, 
+6 is WMM2000, 7 is IGRF2000
+N and E lat and long are positive, S and W negative
+*/
+double SGMagVar( double lat, double lon, double h, long dat, int model, double* field );
+
+#ifdef __cplusplus
+}             /* extern "C" */
+#endif
+
+#endif
Index: /tags/V_Dec2002/SophyaExt/XAstroPack/mollweide.cc
===================================================================
--- /tags/V_Dec2002/SophyaExt/XAstroPack/mollweide.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XAstroPack/mollweide.cc	(revision 2309)
@@ -0,0 +1,189 @@
+//#define TEST_MOLLWEIDE
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include "mollweide.h"
+
+#if defined(TEST_MOLLWEIDE)
+#include "timing.h"
+double _t;
+#endif
+
+/*! \ingroup XAstroPack
+ \brief La vraie projection Mollweide (longitude,latitude) -> (xmoll,ymoll)
+ \param input: longitude [0,2PI[ en radians
+ \param input: latitude  [-Pi/2,Pi/2] en radians
+ \param output: xmoll dans [-2*sqrt(2),2*sqrt(2)]
+ \param output: ymoll dans [-sqrt(2),sqrt(2)]
+ \warning Probleme de precision pour t pres de Pi/2 (latitude pres de -Pi/2 ou Pi/2)
+ \warning Longitude=Pi=180 au milieu en xmoll=0
+ \return t
+ \verbatim
+ - La vraie MollWeide:
+ Equation implicite en t: 2*t+sin(2*t) = Pi*sin(lat) = a
+     | xmoll = 2*sqrt(2)*(lon-Pi)/Pi*cos(t)
+     | ymoll = sqrt(2)*sin(t)
+ --------------------------------------------------------
+ INPUT: longitude [0,2PI[      en radians
+        latitude  [-Pi/2,Pi/2] en radians
+ OUTPUT: xmoll dans [-2*sqrt(2),2*sqrt(2)]
+         ymoll dans [-sqrt(2),sqrt(2)]
+ RETURN: t
+ --------------------------------------------------------
+ REMARQUES:
+ - xmoll varie [-2*sqrt(2),2*sqrt(2)]
+        centre galactique (longitude=0) au bord,
+        anti-centre (longitude=180) au milieu.
+   pour centre galactique (longitude=0) au milieu,
+        anti-centre (longitude=180) au bord:
+        xmoll' = 2*sqrt(2)*longitude/Pi*cos(t) = xmoll+2*sqrt(2)
+        xmoll' varie [0,4*sqrt(2)]
+ - ymoll varie [-sqrt(2),sqrt(2)] plan gal en 0
+ - t varie [-Pi/2,Pi/2]
+ - a varie [-Pi,Pi]  (a <-> -a  <==> t <-> -t)
+ - Pour latitude --> -latitude alors t --> -t
+        latitude=90   --> t=Pi/2
+        latitude=-90  --> t=-Pi/2
+ RAPIDITE: 10^6 appels a MollWeide_XY en 5.2 seconde (PC Linux 500Mhz)
+ PRECISION: eps=1e-16  -> |t-tvrai|<1e-6 toujours
+                          |t-tvrai|<1e-10 pour t<1.57
+                          |t-tvrai|<1e-10 pour t<1.57
+                          |t-tvrai|<3e-14 pour t<1.50
+                          |t-tvrai|<5e-15 pour t<1.40
+ \endverbatim
+*/
+double MollWeide_XY(double longitude,double latitude,double* xmoll,double*ymoll)
+{
+ int i,niter=2;
+ double tini,t0,f0,f1,f2,e1,e2,dt,a,asgn,eps=1.e-16;
+ 
+ a = M_PI*sin(latitude);
+ if(a<0.) {a*=-1.; asgn=-1.;} else asgn=1.;
+ // premier guess t1 ok pour t->0 (droite)
+ f1 = a/4.;
+ // second guess t2 ok pour t->Pi/2 (DL en Pi/2, type a+b*x^3)
+ f2 = 0.75*(M_PI-a);
+ if(f2>0.) f2=M_PI_2-pow(f2,0.33333333333333333); else f2=M_PI_2;
+ e1 = 2.*f1+sin(2.*f1)-a; if(e1<0.) e1 *= -1.;
+ e2 = 2.*f2+sin(2.*f2)-a; if(e2<0.) e2 *= -1.;
+ tini = (f1*e2+f2*e1)/(e1+e2);
+ //printf("---> a=%e tini=%e f1=%e f2=%e\n",a,tini,f1,f2);
+ if(tini<0) tini=0.; else if(tini>M_PI_2) tini=M_PI_2;
+ // L'approximation par le DL au 2sd ordre, on resoud:
+ // a = f(x0) + f'(x0)*(x-x0) + f''(x0)*(x-x0)^2/2
+ t0 = tini;
+ for(i=0;i<niter;i++) {
+   e1 = sin(2.*t0);
+   f0 = 2.*t0+e1;           // (f(x0))     >=0 sur 0<t<Pi/2
+   //printf(".%d    a-f0=%e\n",i,a-f0);
+   if(a-f0<eps && a-f0>-eps) break;
+   f1 = 2.*(1.+cos(2.*t0)); // (f'(x0))    >=0 sur 0<t<Pi/2
+   f2 = -2.*e1;             // (f''(x0)/2) <=0 sur 0<t<Pi/2
+   dt = f1*f1 - 4.*(f0-a)*f2;
+   //printf(".%d    f0=%e f1=%e f2=%e disc=%e\n",i,f0,f1,f2,dt);
+   if(dt>=0.) dt=-f1+sqrt(dt); else dt=0.;
+   ////printf(".%d    -b+sqrt(disc)=%e\n",i,dt);
+   if(f2<-eps && (dt>eps || dt<-eps)) { // approx parabolique
+     t0 += dt/(2.*f2);
+     //printf(".%d  parab  t0=%e\n",i,t0);
+   } else if(f1>eps) {
+     t0 += (a-f0)/f1; // approx lineaire
+     //printf(".%d  lin  t0=%e\n",i,t0);
+   }
+   if(t0<0) t0=0.; else if(t0>M_PI_2) t0=M_PI_2;
+ }
+
+ t0 *= asgn;
+ *xmoll = 2.*M_SQRT2*(longitude-M_PI)/M_PI*cos(t0);
+ *ymoll = M_SQRT2*sin(t0);
+
+ #if defined(TEST_MOLLWEIDE)
+ _t = tini;
+ #endif
+
+ return t0;
+}
+
+/*! \ingroup XAstroPack
+ \brief La vraie projection Mollweide (xmoll,ymoll) -> (longitude,latitude)
+ \param input: xmoll dans [-2*sqrt(2),2*sqrt(2)]
+ \param input: ymoll dans [-sqrt(2),sqrt(2)]
+ \param output: longitude [0,2PI[ en radians
+ \param output: latitude  [-Pi/2,Pi/2] en radians
+ \return t
+ \warning Probleme de precision pour t pres de Pi/2 (latitude pres de -Pi/2 ou Pi/2)
+ \warning Longitude=Pi=180 au milieu en xmoll=0
+ \verbatim
+ --------------------------------------------------------
+ INPUT: xmoll dans [-2*sqrt(2),2*sqrt(2)]
+        ymoll dans [-sqrt(2),sqrt(2)]
+ OUTPUT: longitude [0,2PI[      en radians
+         latitude  [-Pi/2,Pi/2] en radians
+ RETURN: t if OK
+         -991 : xmoll hors limites
+         -992 : ymoll hors limites
+         -993 : non inversible (poles de la sphere)
+ --------------------------------------------------------
+ \endverbatim
+*/
+double MollWeide_LL(double xmoll,double ymoll,double* longitude,double* latitude)
+{
+ double t,a,eps=1.e-20;
+
+ *longitude = *latitude = -999.;
+ if(xmoll<-2*M_SQRT2 || xmoll>2*M_SQRT2) return(-901.);
+ if(ymoll<-M_SQRT2 || ymoll>M_SQRT2) return(-902.);
+
+ t = ymoll/M_SQRT2; if(t<-1.) t=-1.; else if(t>1.) t=1.;
+ t = asin(t);
+
+ a = (2.*t+sin(2.*t))/M_PI; if(a<-1.) a=-1.; else if(a>1.) a=1.;
+ *latitude = asin(a);
+
+ a= cos(t);
+ if(fabs(a)<eps) return(-903.);
+ *longitude = M_PI*(xmoll/(2.*M_SQRT2*a)+1.);
+
+ return(t);
+}
+
+///////////////////////////////////////
+////////// Programme de test //////////
+///////////////////////////////////////
+#if defined(TEST_MOLLWEIDE)
+int main()
+{
+ FILE *file  = fopen("mollw.data","w");
+ FILE *file2 = fopen("mollw2.data","w");
+ int i,npoints=250000;
+ double tvrai,lon,lat,x,y,tcalc,a;
+ double longitude,latitude,tll,txy;
+ InitTim();
+
+ tll=txy=0.;
+ for(i=0;i<=npoints;i++) {
+   //tvrai = 1.57078;
+   tvrai = (double)i*(M_PI_2) /(double)npoints;
+   a = 2.*tvrai+sin(2.*tvrai);
+   lat = asin(a/M_PI);
+   tcalc = MollWeide_XY(0.,lat,&x,&y);
+   if(fabs(tcalc-tvrai)>tll) {tll = fabs(tcalc-tvrai); txy=tvrai;}
+   if(file) fprintf(file,"%e %e %e %e %e\n",tvrai,tcalc,_t,a,tcalc-tvrai);
+ }
+ printf("Maximum difference: %e for t=%.10e=Pi/2-%.10e\n",tll,txy,M_PI_2-txy);
+ if(file) fclose(file);
+ PrtTim("--- End of first testing ---");
+
+ for(lon=0.;lon<360.;lon+=2.5) for(lat=-90.;lat<=90.1;lat+=2.5) {
+   txy = MollWeide_XY(lon*M_PI/180.,lat*M_PI/180.,&x,&y);
+   tll = MollWeide_LL(x,y,&longitude,&latitude);
+   longitude *= 180./M_PI;
+   latitude  *= 180./M_PI;
+   if(file2) fprintf(file2,"%e %e %e %e %e %e %e %e %e %e\n"
+     ,lon,lat,x,y,longitude,latitude,txy,tll,longitude-lon,latitude-lat);
+ }
+ if(file2) fclose(file2);
+ PrtTim("--- End of second testing ---");
+ return 0;
+}
+#endif
Index: /tags/V_Dec2002/SophyaExt/XAstroPack/mollweide.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/XAstroPack/mollweide.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XAstroPack/mollweide.h	(revision 2309)
@@ -0,0 +1,5 @@
+#ifndef MOLLWEIDE_H_SEEN
+#define MOLLWEIDE_H_SEEN
+double MollWeide_XY(double longitude,double latitude,double* xmoll,double* ymoll);
+double MollWeide_LL(double xmoll,double ymoll,double* longitude,double* latitude);
+#endif
Index: /tags/V_Dec2002/SophyaExt/XAstroPack/objlist.list
===================================================================
--- /tags/V_Dec2002/SophyaExt/XAstroPack/objlist.list	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XAstroPack/objlist.list	(revision 2309)
@@ -0,0 +1,3 @@
+magfield.o
+mollweide.o
+xastropack.o
Index: /tags/V_Dec2002/SophyaExt/XAstroPack/tstxastro.cc
===================================================================
--- /tags/V_Dec2002/SophyaExt/XAstroPack/tstxastro.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XAstroPack/tstxastro.cc	(revision 2309)
@@ -0,0 +1,117 @@
+// Test des possibilites de xastropack
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream.h>
+#include <string.h>
+#include <math.h>
+#include "xastropack.h"
+
+/*==========================================================================*/
+#if 1
+// Test de InRange InRangeCoLat InRangeLat
+int main(int narg, char *arg[])
+{
+  if(narg<3) {
+    cout<<"usage: tstxastro range,vmax val,u"<<endl
+        <<"          u = unite de val (h,d,r def=r)"<<endl;
+    return -1;
+  }
+
+  double range,vmax=-12345.6789;
+  sscanf(arg[1],"%lf,%lf",&range,&vmax);
+  if(vmax==-12345.6789) vmax = range/2.;
+  double val0,val; char unite='r';
+  sscanf(arg[2],"%lf,%c",&val0,&unite);
+
+  val = val0; InRange(&val,range);
+  printf("InRange(%.9f, %.2f) = %.9f\n",val0,range,val);
+  val = val0; InRange(&val,range,vmax);
+  printf("InRange(%.9f, %.2f, %.2f) = %.9f\n",val0,range,vmax,val);
+
+  unsigned long un;
+  if(unite=='h') un = TypUniteH;
+    else if(unite=='d') un = TypUniteD;
+      else un = TypUniteR;
+  val = val0; InRangeCoLat(&val,un);
+  printf("InRangeCoLat(%.9f %c) = %.9f\n",val0,unite,val);
+  val = val0; InRangeLat(&val,un);
+  printf("InRangeLat(%.9f %c) = %.9f\n",val0,unite,val);
+  
+  return 0;
+}
+#endif
+
+/*==========================================================================*/
+#if 0
+// Test de DecodeTypAstro
+int main(int narg, char *arg[])
+{
+  if(narg<2) {
+    cout<<"usage: tstxastro ctype"<<endl;
+    return -1;
+  }
+
+  cout<<"ctype = "<<arg[1]<<endl;
+  unsigned long typ = DecodeTypAstro(arg[1]);
+  string s = DecodeTypAstro(typ);
+  cout<<"typ = "<<typ<<" from "<<s<<endl;
+
+  cout<<"...TypCoordEq  "<<(typ&TypCoordEq)<<endl;
+  cout<<"...TypCoordGal "<<(typ&TypCoordGal)<<endl;
+  cout<<"...TypCoordHor "<<(typ&TypCoordHor)<<endl;
+  cout<<"...TypCoordEcl "<<(typ&TypCoordEcl)<<endl;
+
+  cout<<"...TypCoord1H "<<(typ&TypCoord1H)<<endl;
+  cout<<"...TypCoord1D "<<(typ&TypCoord1D)<<endl;
+  cout<<"...TypCoord1R "<<(typ&TypCoord1R)<<endl;
+
+  cout<<"...TypCoord1C "<<(typ&TypCoord1C)<<endl;
+  cout<<"...TypCoord1L "<<(typ&TypCoord1L)<<endl;
+
+  cout<<"...TypCoord2H "<<(typ&TypCoord2H)<<endl;
+  cout<<"...TypCoord2D "<<(typ&TypCoord2D)<<endl;
+  cout<<"...TypCoord2R "<<(typ&TypCoord2R)<<endl;
+
+  cout<<"...TypCoord2C "<<(typ&TypCoord2C)<<endl;
+  cout<<"...TypCoord2L "<<(typ&TypCoord2L)<<endl;
+
+  unsigned long typu1 = GetCoordUnit(1,typ);
+  cout<<"\ntypu1 = "<<typu1<<endl;
+  cout<<"...TypCoordH "<<(typu1&TypUniteH)<<endl;
+  cout<<"...TypCoordD "<<(typu1&TypUniteD)<<endl;
+  cout<<"...TypCoordR "<<(typu1&TypUniteR)<<endl;
+
+  unsigned long typu2 = GetCoordUnit(2,typ);
+  cout<<"\ntypu2 = "<<typu2<<endl;
+  cout<<"...TypCoordH "<<(typu2&TypUniteH)<<endl;
+  cout<<"...TypCoordD "<<(typu2&TypUniteD)<<endl;
+  cout<<"...TypCoordR "<<(typu2&TypUniteR)<<endl;
+  
+  return 0;
+}
+#endif
+
+/*==========================================================================*/
+#if 0
+// Test de CoordConvertToStd
+int main(int narg, char *arg[])
+{
+  if(narg<2) {cout<<"usage: tstxastro ctype A,B"<<endl;return -1;}
+  double coord1_ini=0., coord2_ini=0.;
+  if(narg>2) sscanf(arg[2],"%lf,%lf",&coord1_ini,&coord2_ini);
+
+  printf("ctype = %s\n",arg[1]);
+  unsigned long typ = DecodeTypAstro(arg[1]);
+  string str = DecodeTypAstro(typ);
+
+  double coord1 = coord1_ini, coord2 = coord2_ini;
+  unsigned long newtyp = CoordConvertToStd(typ,&coord1,&coord2);
+  string newstr = DecodeTypAstro(newtyp);
+
+  printf("typ = %lo %s ==> newtyp = %lo %s\n"
+        ,typ,str.c_str(),newtyp,newstr.c_str());
+  printf("coord1 %.6f  ==>  %.6f\n",coord1_ini,coord1);
+  printf("coord2 %.6f  ==>  %.6f\n",coord2_ini,coord2);
+  return 0;
+}
+#endif
Index: /tags/V_Dec2002/SophyaExt/XAstroPack/xastropack.cc
===================================================================
--- /tags/V_Dec2002/SophyaExt/XAstroPack/xastropack.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XAstroPack/xastropack.cc	(revision 2309)
@@ -0,0 +1,830 @@
+#include <math.h>
+#include <stdio.h>
+#include "xastropack.h"
+
+// BUGS BUGS BUGS BUGS BUGS BUGS BUGS BUGS BUGS BUGS
+// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+// >>>> Corrections de divers bugs trouve dans libastro (CMV)
+// 1******* In the file vsop87.c line 154:
+// p = q/(t_abs[alpha] + alpha * t_abs[alpha-1] * 1e-4 + 1e-35);
+// - to avoid t_abs[-1] when alpha=0, replaced by :  
+// if(alpha>0) p = t_abs[alpha-1]; else p=0;
+// p = q/(t_abs[alpha] + alpha * p * 1e-4 + 1e-35);
+// Mail envoye a ecdowney@ClearSkyInstitute.com
+// 2******* In the file eq_ecl.c line 69:
+// *q = asin((sy*ceps)-(cy*seps*sx*sw));
+// eq_ecl.c Protection NaN dans ecleq_aux, replaced by : 
+// *q = (sy*ceps)-(cy*seps*sx*sw);
+// if(*q<-1.) *q = -PI/2.; else if(*q>1.) *q = PI/2.; else *q = asin(*q);
+// Mail envoye a ecdowney@ClearSkyInstitute.com
+// >>>> Corrections effectuees dans la version Xephem 3.5
+// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+
+/*!
+  \defgroup XAstroPack XAstroPack module
+  This module contains simple programs to perform various
+  astronomical computation (based on the libastro of Xephem).
+
+  \verbatim
+// TEMPS: modified Julian date (mjd) (number of days elapsed since 1900 jan 0.5)
+//        jour [1,31] (dy)
+//        mois [1,12] (mn)
+//        annee       (yr)
+//        universal time [0,24[ (utc)
+//        Greenwich mean siderial [0,24[ (gst)
+//        Greenwich mean siderial at 0h UT [0,24[ (gst0)
+// EQUATORIALE: ascension droite en heures [0,24[ (ra)
+//              declinaison en degres [-90,90]    (dec)
+//              angle horaire en heures ]-12,12] (-12=12) (ha) 
+//              temps sideral du lieu: tsid=ha+ra (ou lst)
+// GALACTIQUE: longitude en degres [0,360[  (glng)
+//             latitude en degres [-90,90]  (glat)
+//             (colatitude en degres [0,180]  (gcolat))
+// HORIZONTAL: azimuth en degres [0,360[   (az)
+//                 (angle round to the east from north+)
+//             altitude ou elevation en degres [-90,90] (alt)
+//             (distance zenitale en degres [0,180] (zendist))
+// ECLIPTIQUE: lontitude ecliptique en degres [0,360[ (eclng)
+//                 (angle round counter clockwise from the vernal equinoxe)
+//             latitude ecliptique en degres [-90,90] (eclat)
+//             (colatitude ecliptique en degres [0,180] (eccolat))
+// GEOGRAPHIE: longitude en degres ]-180,180]        (geolng)
+//                 (angle <0 vers l'ouest, >0 vers l'est)
+//             latitude en degres [-90,90] (north>0 sud<0) (geolat)
+//             (colatitude en degres [0,180] (north=0, sud=180) (geocolat))
+//
+// --- Remarque sur la colatitude:
+//   La latitude peut etre remplacee par la colatitude
+//      (ou altitude/elevation par la distance zenitale):
+//      latitude   : [-90,90] avec 0=equateur,  90=pole nord, -90=pole sud
+//      colatitude : [0,180]  avec 0=pole nord, 90=equateur,  180=pole sud
+//      colatitude = 90.-latitude , latitude = 90.-colatitude
+  \endverbatim
+*/
+
+/*! \ingroup XAstroPack
+\brief Given a coordinate type "typ", convert to standard for astropack.
+\verbatim
+ La routine convertit (in place) les coordonnees "coord1","coord2"
+ definies par le type "typ" dans les unites standard de ce systeme
+ de coordonnees.
+ "typ" code le systeme de coordonnees astronomiques et les unites utilisees
+
+ - Return : 0 = Problem
+            TypAstroCoord du systeme de coordonnees retourne
+
+ - Les types de coordonnees (A,B) sont definies
+           dans le enum TypAstroCoord (unsigned long):
+   La premiere coordonnee "A" est de type "longitude"
+                          (alpha,longitude,azimuth)
+   La deuxieme coordonnee "B" est de type "latidude"
+                          (delta,latitude,altitude ou elevation)
+
+ *** Definitions des unites des coordonnees
+ - Coordonnee: 
+      TypCoordH en heure
+      TypCoordD en degre
+      TypCoordR en radian
+ - Coordonnee "A": 
+      TypCoord1H en heure
+      TypCoord1D en degre
+      TypCoord1R en radian
+      - Defaut (pas de bit leve): radians
+ - Coordonnee "B": 
+      TypCoord2H en heure
+      TypCoord2D en degre
+      TypCoord2R en radian
+      - Defaut (pas de bit leve): radians
+ *** Definitions des types d'intervalle utilises
+ - Coordonnee "A":
+      TypCoord1C type intervalle
+                 [0,24[ ou [0,360[ ou [0,2Pi[
+      TypCoord1L type intervalle centre
+                 ]-12,12] ou ]-180,180] ou ]-Pi,Pi]
+      - Defaut (pas de bit leve): TypCoord1C
+ - Coordonnee "B": 
+      TypCoord2C type intervalle (colatitude)
+                 [0,12] ou [0,180] ou [0,Pi]
+      TypCoord2L type intervalle centre (latitude)
+                 [-6,6] ou [-90,90] ou [-Pi/2,Pi/2]
+      - Defaut (pas de bit leve): TypCoord2L (latitude)
+ *** Les systemes de coordonnes astronomiques
+ TypCoordEq  coordonnees Equatoriales alpha,delta
+ TypCoordGal coordonnees Galactiques gLong, gLat
+ TypCoordHor coordonnees Horizontales azimuth,altitude
+ TypCoordEcl coordonnees Ecliptiques EclLong,EclLat
+      (Pas de defaut)
+ *** Les systemes de coordonnes astronomiques "standard"
+ TypCoordEqStd   alpha en heure=[0,24[ delta en degre=[-90,90]
+ TypCoordGalStd  long en degre=[0,360[ lat en degre=[-90,90] (latitude)
+ TypCoordHorStd  long en degre=[0,360[ lat en degre=[-90,90] (latitude)
+ TypCoordEclStd  long en degre=[0,360[ lat en degre=[-90,90] (latitude)
+\endverbatim
+*/
+unsigned long CoordConvertToStd(unsigned long typ,double* coord1,double* coord2)
+{
+  unsigned long rc = TypCoordUndef;
+
+  if(typ&TypCoordEq) {
+    // ---- Equatoriales alpha,delta
+    if     (typ&TypCoord1D)    *coord1 = deghr(*coord1);
+    else if(typ&TypCoord1R)    *coord1 = radhr(*coord1);
+    else if(!(typ&TypCoord1H)) *coord1 = radhr(*coord1);
+
+    InRange(coord1,24.);
+
+    if     (typ&TypCoord2H)    *coord2 = hrdeg(*coord2);
+    else if(typ&TypCoord2R)    *coord2 = raddeg(*coord2);
+    else if(!(typ&TypCoord2D)) *coord2 = raddeg(*coord2);
+
+    if(typ&TypCoord2C) {
+      InRangeCoLat(coord2,TypUniteD);
+      ToCoLat(coord2,TypUniteD);
+    } else InRangeLat(coord2,TypUniteD);
+
+    rc=TypCoordEqStd;
+
+  } else if(typ&TypCoordGal || typ&TypCoordHor || typ&TypCoordEcl) {
+    // ---- Galactiques gLong, gLat
+    // ---- Horizontales azimuth,altitude ou elevation
+    // ---- Ecliptiques EclLong,EclLat
+    if     (typ&TypCoord1H)    *coord1 = hrdeg(*coord1);
+    else if(typ&TypCoord1R)    *coord1 = raddeg(*coord1);
+    else if(!(typ&TypCoord1D)) *coord1 = raddeg(*coord1);
+
+    InRange(coord1,360.);
+
+    if     (typ&TypCoord2H)    *coord2 = hrdeg(*coord2);
+    else if(typ&TypCoord2R)    *coord2 = raddeg(*coord2);
+    else if(!(typ&TypCoord2D)) *coord2 = raddeg(*coord2);
+
+    if(typ&TypCoord2C) {
+      InRangeCoLat(coord2,TypUniteD);
+      ToCoLat(coord2,TypUniteD);
+    } else InRangeLat(coord2,TypUniteD);
+
+    if     (typ&TypCoordGal) rc=TypCoordGalStd;
+    else if(typ&TypCoordHor) rc=TypCoordHorStd;
+    else if(typ&TypCoordEcl) rc=TypCoordEclStd;
+
+  } else {          // Systeme de coordonnees non-connu
+    rc=TypCoordUndef;
+  }
+
+  return rc;
+}
+
+/*! \ingroup XAstroPack
+\brief Retourne te type d'unite pour la coordonnee "coordnum"
+       pour un TypAstroCoord valant "typ"
+\verbatim
+   coordnum : numero de coordonnee: 1 ou 2
+   retourne: TypUniteH si la coordonnee est en heure
+             TypUniteD si la coordonnee est en degre
+             TypUniteR si la coordonnee est en radian
+             TypUniteR par defaut
+             TypCoordUndef si le numero de coordonnee est errone.
+\endverbatim
+*/
+unsigned long GetCoordUnit(int coordnum,unsigned long typ)
+{
+ if(coordnum==1) {
+   if     (typ&TypCoord1H) return TypUniteH;
+   else if(typ&TypCoord1D) return TypUniteD;
+   else if(typ&TypCoord1R) return TypUniteR;
+   else                    return TypUniteR;
+ }
+ if(coordnum==2) {
+   if     (typ&TypCoord2H) return TypUniteH;
+   else if(typ&TypCoord2D) return TypUniteD;
+   else if(typ&TypCoord2R) return TypUniteR;
+   else                    return TypUniteR;
+ }
+ return TypCoordUndef;
+}
+
+/*! \ingroup XAstroPack
+\brief Pour decoder et transcrire en TypAstroCoord une chaine
+       donnant la structure du systeme de coordonnees.
+\verbatim
+  ctype = "CAaBb"
+    C: type de coordonnees: E Equatoriales
+                            G Galactiques
+                            H Horizontales
+                            S Ecliptiques
+                            pas de defaut
+    A: unite de la coordonnee 1 (alpha,longitude etc...)
+                            H heure
+                            D degre
+                            R radian
+                            defaut radian
+    a: type d'intervalle pour la coordonnee 1
+                            C intervalle [0,24[ [0,360[ [0,2*Pi[
+                            L intervalle [-12,12[ [-180,180[ [-Pi,Pi[
+                            (defaut: C)
+    A: unite de la coordonnee 2 (delta,latitude etc...)
+                            H heure
+                            D degre
+                            R radian
+                            defaut radian
+    a: type d'intervalle pour la coordonnee 2
+                            C intervalle [0,12] [0,180] [0,Pi]
+                              (type colatitude)
+                            L intervalle [-6,6] [-90,90][ [-Pi/2,Pi/2]
+                            (defaut: L)
+
+    Exemple: GDCDL : galactiques long=[0,360[ lat=[-90,90]
+             GDxDx ou GDxD: idem
+             Gxxxx ou G : galactiques long=[0,2*Pi[ lat=[-Pi/2,Pi/2]
+    Exemple: EHCDL : equatoriales alpha=[0,24[ delta=[-90,90]
+             EHxDx ou EHxD : idem
+             Exxxx ou E : equatoriales alpha=[0,2*Pi[ delta=[-Pi/2,Pi/2]
+                            
+  - Retourne 0 si probleme dans la chaine
+\endverbatim
+*/
+unsigned long DecodeTypAstro(const char *ctype)
+{
+  if(ctype==NULL) return TypCoordUndef;
+  int len = strlen(ctype);
+  if(len<1) return TypCoordUndef;
+
+  unsigned long typ=0;
+  // Le type de systeme de coordonnees
+  int i = 0;
+  if     (ctype[i]=='e' || ctype[i]=='E') typ=TypCoordEq;
+  else if(ctype[i]=='g' || ctype[i]=='G') typ=TypCoordGal;
+  else if(ctype[i]=='h' || ctype[i]=='H') typ=TypCoordHor;
+  else if(ctype[i]=='s' || ctype[i]=='S') typ=TypCoordEcl;
+  else return TypCoordUndef;
+  // La coordonnee 1
+  i = 1;
+  if(i>=len)
+    {typ |= TypCoord1R|TypCoord1C|TypCoord2R|TypCoord2L; return typ;}
+  if     (ctype[i]=='h' || ctype[i]=='H') typ |= TypCoord1H;
+  else if(ctype[i]=='d' || ctype[i]=='D') typ |= TypCoord1D;
+  else if(ctype[i]=='r' || ctype[i]=='R') typ |= TypCoord1R;
+  else                                    typ |= TypCoord1R;
+  i = 2;
+  if(i>=len) {typ |= TypCoord1C|TypCoord2R|TypCoord2L; return typ;}
+  if     (ctype[i]=='c' || ctype[i]=='C') typ |= TypCoord1C;
+  else if(ctype[i]=='l' || ctype[i]=='L') typ |= TypCoord1L;
+  else                                    typ |= TypCoord1C;
+  // La coordonnee 2
+  i = 3;
+  if(i>=len) {typ |= TypCoord2R|TypCoord2L; return typ;}
+  if     (ctype[i]=='h' || ctype[i]=='H') typ |= TypCoord2H;
+  else if(ctype[i]=='d' || ctype[i]=='D') typ |= TypCoord2D;
+  else if(ctype[i]=='r' || ctype[i]=='R') typ |= TypCoord2R;
+  else                                    typ |= TypCoord2R;
+  i = 4;
+  if(i>=len) {typ |= TypCoord2L; return typ;}
+  if     (ctype[i]=='c' || ctype[i]=='C') typ |= TypCoord2C;
+  else if(ctype[i]=='l' || ctype[i]=='L') typ |= TypCoord2L;
+  else                                    typ |= TypCoord2L;
+  // Return
+  return typ;
+}
+
+/*! \ingroup XAstroPack
+\brief Idem DecodeTypAstro(char *) mais a l'envers
+*/
+string DecodeTypAstro(unsigned long typ)
+{
+ string s = "";
+
+ if     (typ&TypCoordEq)  s += "E";
+ else if(typ&TypCoordGal) s += "G";
+ else if(typ&TypCoordHor) s += "H";
+ else if(typ&TypCoordEcl) s += "S";
+ else                     s += "x";
+
+ if     (typ&TypCoord1H) s += "H";
+ else if(typ&TypCoord1D) s += "D";
+ else if(typ&TypCoord1R) s += "R";
+ else                    s += "x";
+
+ if     (typ&TypCoord1C) s += "C";
+ else if(typ&TypCoord1L) s += "L";
+ else                    s += "x";
+
+ if     (typ&TypCoord2H) s += "H";
+ else if(typ&TypCoord2D) s += "D";
+ else if(typ&TypCoord2R) s += "R";
+ else                    s += "x";
+
+ if     (typ&TypCoord2C) s += "C";
+ else if(typ&TypCoord2L) s += "L";
+ else                    s += "x";
+
+ return s;
+}
+
+/*! \ingroup XAstroPack
+\brief Pour convertir la latitude en colatitude et vice-versa (in place)
+\verbatim
+  val = valeur a convertir qui doit etre:
+      si type "latitude"   dans [-6,6] [-90,90] [-Pi/2,Pi/2]
+      si type "colatitude" dans [0,12] [0,180] [0,Pi]
+  typ = type d'unite: heure  TypUniteH
+                      degre  TypUniteD
+                      radian TypUniteR
+        (Defaut: radian TypUniteR)
+\endverbatim
+*/
+void ToCoLat(double *val,unsigned long typ)
+{
+ if     (typ&TypUniteH) *val = 6.    - *val;
+ else if(typ&TypUniteD) *val = 90.   - *val;
+ else if(typ&TypUniteR) *val = PI/2. - *val;
+ else *val = PI/2. - *val;
+}
+
+/*! \ingroup XAstroPack
+\brief Pour remettre la valeur de la COLATITUDE "val" dans la dynamique [0.,range]
+\verbatim
+  val = valeur a convertir qui doit etre mise dans [0,12] [0,180] [0,Pi]
+  typ = type d'unite: heure  TypUniteH
+                      degre  TypUniteD
+                      radian TypUniteR
+  ex en degre: 0 -> 0 ,  90 ->  90 ,  180 -> 180 ,  270 -> 90 ,  360 -> 0
+                        -90 ->  90 , -180 -> 180 , -270 -> 90 , -360 -> 0
+\endverbatim
+*/
+void InRangeCoLat(double *val,unsigned long typ)
+{
+ double range=PI;
+ if(typ==TypUniteH) range=12.; else if(typ==TypUniteD) range=180.;
+ InRange(val,2.*range,range);
+ if(*val<0.) *val*=-1.;
+}
+
+/*! \ingroup XAstroPack
+\brief Pour remettre la valeur de la LATITUDE "val" dans la dynamique [-range/2,range/2]
+\verbatim
+  val = valeur a convertir qui doit etre mise dans [-6,6] [-90,90] [-Pi/2,Pi/2]
+  typ = type d'unite: heure  TypUniteH
+                      degre  TypUniteD
+                      radian TypUniteR
+  ex en degre: 0 -> 0 ,  90 ->  90 ,  180 -> 0 ,  270 -> -90 ,  360 -> 0
+                        -90 -> -90 , -180 -> 0 , -270 ->  90 , -360 -> 0
+\endverbatim
+*/
+void InRangeLat(double *val,unsigned long typ)
+{
+ double range = PI;
+ if(typ==TypUniteH) range = 12.; else if(typ==TypUniteD) range = 180.;
+ InRange(val,2.*range,range);
+ if(*val>range/2.) *val = range - *val;
+   else if(*val<-range/2.) *val = -(range + *val);
+}
+
+/*! \ingroup XAstroPack
+\brief Compute MJD from date
+\verbatim
+ MJD =  modified Julian date (number of days elapsed since 1900 jan 0.5),
+ dy is the decimale value of the day: dy = int(dy) + utc/24.
+\endverbatim
+*/
+double MJDfrDate(double dy,int mn,int yr)
+{
+double mjd;
+cal_mjd(mn,dy,yr,&mjd);
+return mjd;
+}
+
+/*! \ingroup XAstroPack
+\brief Compute date from MJD
+*/
+void DatefrMJD(double mjd,double *dy,int *mn,int *yr)
+{
+mjd_cal(mjd,mn,dy,yr);
+}
+
+/*! \ingroup XAstroPack
+\brief  Given a mjd, return the year as a double.
+*/
+double YearfrMJD(double mjd)
+{
+double yr;
+mjd_year(mjd,&yr);
+return yr;
+}
+
+/*! \ingroup XAstroPack
+\brief Given a decimal year, return mjd
+*/
+double MJDfrYear(double yr)
+{
+double mjd;
+year_mjd(yr,&mjd);
+return mjd;
+}
+
+/*! \ingroup XAstroPack
+\brief Given a mjd, return the year and number of days since 00:00 Jan 1
+\warning: if mjd = 2 January -> number of days = 1
+*/
+void YDfrMJD(double mjd,double *dy,int *yr)
+{
+mjd_dayno(mjd,yr,dy);
+}
+
+/*! \ingroup XAstroPack
+\brief Given a year, 
+*/
+int IsLeapYear(int y)
+{
+return isleapyear(y);
+}
+
+/*! \ingroup XAstroPack
+\brief given an mjd, set *dow to 0..6 according to which day of the week it falls on (0=sunday).
+\return return 0 if ok else -1 if can't figure it out.
+*/
+int DayOrder(double mjd,int *dow)
+{
+return mjd_dow(mjd,dow);
+}
+
+/*! \ingroup XAstroPack
+\brief given a mjd, return the the number of days in the month.
+*/
+int DaysInMonth(double mjd)
+{
+int ndays;
+mjd_dpm(mjd,&ndays);
+return ndays;
+}
+
+/*! \ingroup XAstroPack
+\brief Given a mjd, truncate it to the beginning of the whole day
+*/
+double MJDat0hFrMJD(double mjd)
+{
+return mjd_day(mjd);
+}
+
+/*! \ingroup XAstroPack
+\brief Given a mjd, return the number of hours past midnight of the whole day
+*/
+double HfrMJD(double mjd)
+{
+return mjd_hr(mjd);
+}
+
+/*! \ingroup XAstroPack
+\brief Give GST from UTC
+\verbatim
+ Given a modified julian date, mjd, and a universally coordinated time, utc,
+ return greenwich mean siderial time, *gst.
+ N.B. mjd must be at the beginning of the day.
+\endverbatim
+*/
+double GSTfrUTC(double mjd0,double utc)
+{
+double gst;
+utc_gst(mjd0,utc,&gst);
+return gst;
+}
+
+/*! \ingroup XAstroPack
+\brief Give UTC from GST
+\verbatim
+ Given a modified julian date, mjd, and a greenwich mean siderial time, gst,
+ return universally coordinated time, *utc.
+ N.B. mjd must be at the beginning of the day.
+\endverbatim
+*/                                                                             
+double UTCfrGST(double mjd0,double gst)
+{
+double utc;
+gst_utc(mjd0,gst,&utc);
+return utc;
+}
+
+/*! \ingroup XAstroPack
+\brief Given apparent altitude find airmass.
+*/                                                                             
+double AirmassfrAlt(double alt)
+{
+double x;
+alt = degrad(alt);
+airmass(alt,&x);
+return x;
+}
+
+/*! \ingroup XAstroPack
+\brief given geocentric time "jd" and coords of a distant object at "ra/dec" (J2000),
+find the difference "hcp" in time between light arriving at earth vs the sun.
+\return "hcp" must be subtracted from "geocentric jd" to get "heliocentric jd".
+\warning "jd" is the TRUE Julian day (jd = mjd+MJD0).
+*/
+double HelioCorr(double jd,double ra,double dec)
+{
+double hcp;
+ra=hrrad(ra);
+dec=degrad(dec);
+heliocorr(jd,ra,dec,&hcp);
+return hcp;
+}
+
+/*! \ingroup XAstroPack
+\brief gmst0() - return Greenwich Mean Sidereal Time at 0h UT
+\param mjd0 = date at 0h UT in julian days since MJD0
+*/                                                                             
+double GST0(double mjd0)
+/* Copie depuis le code de Xephem (utc_gst.c) car pas prototype*/
+{
+ double T, x;
+ T = ((int)(mjd0 - 0.5) + 0.5 - J2000)/36525.0;
+ x = 24110.54841 +
+     (8640184.812866 + (0.093104 - 6.2e-6 * T) * T) * T;
+ x /= 3600.0;
+ range(&x, 24.0);
+ return (x);
+}
+
+/*! \ingroup XAstroPack
+\brief return local sidereal time from modified julian day and longitude
+\warning nutation or obliquity correction are taken into account.
+*/                                                                             
+double LSTfrMJD(double mjd,double geolng)
+{
+  double eps,lst,deps,dpsi;
+  utc_gst(mjd_day(mjd),mjd_hr(mjd),&lst);
+  lst += deghr(geolng);
+  obliquity(mjd,&eps);
+  nutation(mjd,&deps,&dpsi);
+  lst += radhr(dpsi*cos(eps+deps));
+  InRange(&lst,24.);
+  return lst;
+}
+
+/*! \ingroup XAstroPack
+\brief Give a time in h:mn:s from a decimal hour
+\verbatim
+// INPUT: hd
+// OUTPUT: h mn s   (h,mn,s >=< 0)
+// REMARQUE: si hd<0 alors h<0 ET mn<0 ET s<0
+// EX: 12.51 -> h=12  mn=30  s=10 ; 
+//    -12.51 -> h=-12 mn=-30 s=-10 ; 
+\endverbatim
+*/                                                                             
+void HMSfrHdec(double hd,int *h,int *mn,double *s)
+{
+ int sgn=1;
+ if(hd<0.) {sgn=-1; hd*=-1.;}
+ *h  = int(hd);
+ *mn = int((hd-(double)(*h))*60.);
+ *s  = (hd - (double)(*h) - (double)(*mn)/60.)*3600.;
+ // pb precision
+ if(*s<0.) *s = 0.;
+ if(*s>60. || *s==60.) {*s-=60.; *mn+=1;} // s=double attention comparaison
+ if(*mn<0) *mn = 0;
+ if(*mn>=60) {*mn-=60; *h+=1;}
+ *h *= sgn; *mn *= sgn; *s *= (double)sgn;
+}
+
+/*! \ingroup XAstroPack
+\brief Give a decimal hour from a time in h:mn:s
+\verbatim
+// INPUT: h , mn , s  (h,mn,s >=< 0)
+// RETURN:  en heures decimales
+// REMARQUE: pour avoir hd=-12.51 <- h=-12 mn=-30 s=-10
+\endverbatim
+*/                                                                             
+double HdecfrHMS(int h,int mn,double s)
+{
+ return ((double)h + (double)mn/60. + s/3600.);
+}
+
+/*! \ingroup XAstroPack
+\brief Give a time string from a time in h:mn:s
+\verbatim
+// INPUT: h , mn , s   (h,mn,s >=< 0)
+// RETURN: string h:mn:s
+\endverbatim
+*/                                                                             
+string ToStringHMS(int h,int mn,double s)
+{
+ double hd = HdecfrHMS(h,mn,s); // put in range
+ HMSfrHdec(hd,&h,&mn,&s);
+ char str[128];
+ if(hd<0.)
+   sprintf(str,"-%d:%d:%.3f",-h,-mn,-s);
+ else
+   sprintf(str,"%d:%d:%.3f",h,mn,s);
+ string dum = str;
+ return dum;
+}
+
+/*! \ingroup XAstroPack
+\brief Give a time string from a decimal hour
+*/                                                                             
+string ToStringHdec(double hd)
+{
+ int h,mn; double s;
+ HMSfrHdec(hd,&h,&mn,&s);
+ return ToStringHMS(h,mn,s);
+}
+
+/*! \ingroup XAstroPack
+\brief Compute precession between 2 dates.
+*/                                                                             
+void Precess(double mjd1,double mjd2,double ra1,double dec1,double *ra2,double *dec2)
+{
+ ra1  = hrrad(ra1);   // radians
+ dec1 = degrad(dec1);  // radians
+ precess(mjd1,mjd2,&ra1,&dec1);
+ *ra2 = radhr(ra1); InRange(ra2,24.);
+ *dec2 = raddeg(dec1);
+}
+
+/*! \ingroup XAstroPack
+\brief Convert equatorial coordinates for the given epoch into galactic coordinates
+*/                                                                             
+void EqtoGal(double mjd,double ra,double dec, double *glng,double *glat)
+// Coordonnees equatoriales -> Coordonnees galactiques
+{
+ ra  = hrrad(ra);   // radians
+ dec = degrad(dec);  // radians
+ eq_gal(mjd,ra,dec,glat,glng);
+ // Vraiment bizarre, sur Linux-g++ glng>=360 ne comprend pas glng==360 ! (CMV)
+ *glng = raddeg(*glng); InRange(glng,360.);
+ *glat = raddeg(*glat);
+}
+
+/*! \ingroup XAstroPack
+\brief Convert galactic coordinates into equatorial coordinates at the given epoch
+*/                                                                             
+void GaltoEq(double mjd,double glng,double glat,double *ra,double *dec)
+// Coordonnees galactiques -> Coordonnees equatoriales
+{
+ glng = degrad(glng);  // radians
+ glat = degrad(glat);  // radians
+ gal_eq (mjd,glat,glng,ra,dec);
+ *ra = radhr(*ra); InRange(ra,24.);
+ *dec = raddeg(*dec);
+}
+
+/*! \ingroup XAstroPack
+\brief Convert equatorial coordinates (with hour angle instead of right ascension) into horizontal coordinates.
+*/                                                                             
+void EqHtoHor(double geolat,double ha,double dec,double *az,double *alt)
+// Coordonnees equatoriales -> Coordonnees horizontales
+{
+ geolat = degrad(geolat);  // radians
+ ha  = hrrad(ha);   // radians
+ dec = degrad(dec);  // radians
+ hadec_aa (geolat,ha,dec,alt,az);
+ *alt = raddeg(*alt);
+ *az  = raddeg(*az); InRange(az,360.);
+}
+
+/*! \ingroup XAstroPack
+ Convert horizontal coordinates into equatorial coordinates (with hour angle instead of right ascension).
+*/                                                                             
+void HortoEqH(double geolat,double az,double alt,double *ha,double *dec)
+// Coordonnees horizontales -> Coordonnees equatoriales
+{
+ geolat = degrad(geolat);  // radians
+ alt = degrad(alt);  // radians
+ az  = degrad(az);  // radians
+ aa_hadec (geolat,alt,az,ha,dec);
+ *ha = radhr(*ha); InRange(ha,24.,12.);
+ *dec = raddeg(*dec);
+}
+
+/*! \ingroup XAstroPack
+\brief Convert equatorial coordinates into horizontal coordinates.
+*/                                                                             
+void EqtoHor(double geolat,double lst,double ra,double dec,double *az,double *alt)
+// Coordonnees equatoriales -> Coordonnees horizontales
+{
+ double ha = lst - ra; InRange(&ha,24.,12.);
+ geolat = degrad(geolat);  // radians
+ ha = hrrad(ha);   // radians
+ dec = degrad(dec);  // radians
+ hadec_aa (geolat,ha,dec,alt,az);
+ *alt = raddeg(*alt);
+ *az  = raddeg(*az); InRange(az,360.);
+}
+
+/*! \ingroup XAstroPack
+ Convert horizontal coordinates into equatorial coordinates.
+*/                                                                             
+void HortoEq(double geolat,double lst,double az,double alt,double *ra,double *dec)
+// Coordonnees horizontales -> Coordonnees equatoriales
+{
+ double ha;
+ geolat = degrad(geolat);  // radians
+ alt = degrad(alt);  // radians
+ az  = degrad(az);  // radians
+ aa_hadec (geolat,alt,az,&ha,dec);
+ *ra = lst - radhr(ha); InRange(ra,24.);
+ *dec = raddeg(*dec);
+}
+
+/*! \ingroup XAstroPack
+\brief Convert equatorial coordinates into geocentric ecliptic coordinates given the modified Julian date.
+\warning Correction for the effect on the angle of the obliquity due to nutation is not included.
+*/                                                                             
+void EqtoEcl(double mjd,double ra,double dec,double *eclng,double *eclat)
+// Coordonnees equatoriales -> Coordonnees ecliptiques
+{
+ ra = hrrad(ra);   // radians
+ dec = degrad(dec);  // radians
+ eq_ecl(mjd,ra,dec,eclat,eclng);
+ *eclng = raddeg(*eclng); InRange(eclng,360.);
+ *eclat = raddeg(*eclat);
+}
+
+/*! \ingroup XAstroPack
+\brief Convert geocentric ecliptic coordinates into equatorial coordinates given the modified Julian date.
+\warning Correction for the effect on the angle of the obliquity due to nutation is not included.
+*/                                                                             
+void EcltoEq(double mjd,double eclng,double eclat,double *ra,double *dec)
+// Coordonnees ecliptiques -> Coordonnees equatoriales
+{
+ eclat = degrad(eclat);  // radians
+ eclng = degrad(eclng);  // radians
+ ecl_eq(mjd,eclat,eclng,ra,dec); 
+ *ra = radhr(*ra); InRange(ra,24.);
+ *dec = raddeg(*dec);
+}
+
+/*! \ingroup XAstroPack
+\brief Give Sun position
+\verbatim
+ given the modified JD, mjd, return the true geocentric ecliptic longitude
+ of the sun for the mean equinox of the date, *eclsn, in degres, the
+ sun-earth distance, *rsn, in AU, and the latitude *ecbsn, in degres
+ (since this is always <= 1.2 arcseconds, in can be neglected by
+ calling with ecbsn = NULL).
+ - REMARQUE:
+ * if the APPARENT ecliptic longitude is required, correct the longitude for
+ *   nutation to the true equinox of date and for aberration (light travel time,
+ *   approximately  -9.27e7/186000/(3600*24*365)*2*pi = -9.93e-5 radians).
+\endverbatim
+*/
+void SunPos(double mjd,double *eclsn,double *ecbsn,double *rsn)
+{
+ sunpos(mjd,eclsn,rsn,ecbsn);
+ *eclsn = raddeg(*eclsn); InRange(eclsn,360.);
+ if(ecbsn!=NULL) *ecbsn = raddeg(*ecbsn);
+}
+
+/*! \ingroup XAstroPack
+\brief Give Moon position
+\verbatim
+ given the mjd, find the geocentric ecliptic longitude, lam, and latitude,
+ bet, and geocentric distance, rho in a.u. for the moon.  also return
+ the sun's mean anomaly, *msp, and the moon's mean anomaly, *mdp. 
+ (for the mean equinox)
+\endverbatim
+*/
+void MoonPos(double mjd,double *eclmn,double *ecbmn,double *rho)
+{
+  double msp,mdp;
+  moon(mjd,eclmn,ecbmn,rho,&msp,&mdp);
+ *eclmn = raddeg(*eclmn); InRange(eclmn,360.);
+ *ecbmn = raddeg(*ecbmn);
+}
+
+/*! \ingroup XAstroPack
+\brief Give planet position
+\verbatim
+ * given a modified Julian date, mjd, and a planet, p, find:
+ *   sunecl: heliocentric longitude, 
+ *   sunecb: heliocentric latitude,
+ *   sundist:  distance from the sun to the planet, 
+ *   geodist: distance from the Earth to the planet,
+ *         none corrected for light time, ie, they are the true values for the
+ *         given instant.
+ *   geoecl:  geocentric ecliptic longitude, 
+ *   geoecb:  geocentric ecliptic latitude,
+ *         each corrected for light time, ie, they are the apparent values as
+ *	   seen from the center of the Earth for the given instant.
+ *   diamang:  angular diameter in arcsec at 1 AU, 
+ *   mag:  visual magnitude when 1 AU from sun and earth at 0 phase angle.
+ *   (for the mean equinox)
+ * all angles are in degres, all distances in AU.
+ *
+ * corrections for nutation and abberation must be made by the caller. The RA 
+ *   and DEC calculated from the fully-corrected ecliptic coordinates are then
+ *   the apparent geocentric coordinates. Further corrections can be made, if
+ *   required, for atmospheric refraction and geocentric parallax.
+ \endverbatim
+*/
+void PlanetPos(double mjd,int numplan,double *sunecl,double *sunecb,double *sundist
+              ,double *geodist,double *geoecl,double *geoecb
+              ,double *diamang,double *mag)
+{
+ plans(mjd,numplan,sunecl,sunecb,sundist,geodist,geoecl,geoecb,diamang,mag);
+ *geoecl = raddeg(*geoecl); InRange(geoecl,360.);
+ *geoecb = raddeg(*geoecb);
+ *sunecl = raddeg(*sunecl); InRange(sunecl,360.);
+ *sunecb = raddeg(*sunecb);
+}
Index: /tags/V_Dec2002/SophyaExt/XAstroPack/xastropack.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/XAstroPack/xastropack.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XAstroPack/xastropack.h	(revision 2309)
@@ -0,0 +1,208 @@
+#ifndef XASTROPACK_H
+#define XASTROPACK_H
+
+#include "machdefs.h"
+#include <string.h>
+#include <string>
+
+#ifdef __cplusplus
+extern "C" {  /* extern "C" */
+#endif
+#include "XAstro/P_.h"
+#include "XAstro/astro.h"
+#ifdef __cplusplus
+}             /* extern "C" */
+#endif
+
+enum TypAstroCoord {
+  //------ Coordonnees de type (A,B) avec:
+  //      A,B <==> alpha,delta
+  //      A,B <==> longitude,latitude
+  //      A,B <==> azimuth,altitude ou elevation
+
+  //------ Les unites des coordonnees
+  TypUniteH       =  (unsigned long)  (1 << 0), // coord en heure
+  TypUniteD       =  (unsigned long)  (1 << 1), // coord en degre
+  TypUniteR       =  (unsigned long)  (1 << 2), // coord en radian
+
+  //------ Les unites des coordonnees A et B
+  TypCoord1H      =  (unsigned long)  (1 << 3), // coord A en heure
+  TypCoord1D      =  (unsigned long)  (1 << 4), // coord A en degre
+  TypCoord1R      =  (unsigned long)  (1 << 5), // coord A en radian
+  TypCoord2H      =  (unsigned long)  (1 << 6), // coord B en heure
+  TypCoord2D      =  (unsigned long)  (1 << 7), // coord B en degre
+  TypCoord2R      =  (unsigned long)  (1 << 8), // coord B en radian
+
+  //------ Le type d'intervalle des coordonnees A et B
+  // Coord A intervalle... ex: [0,24[ ou [0,360[ ou [0,2Pi[
+  TypCoord1C      =  (unsigned long)  (1 << 10),
+  // Coord A intervalle centre... ex: ]-12,12] ou ]-180,180] ou ]-Pi,Pi]
+  TypCoord1L      =  (unsigned long)  (1 << 11),
+  // Coord B intervalle... ex:  [0,12] ou [0,180] ou [0,Pi] (colatitude)
+  TypCoord2C      =  (unsigned long)  (1 << 12),
+  // Coord B intervalle centre... ex: [-6,6] ou [-90,90] ou [-Pi/2,Pi/2] (latitude)
+  TypCoord2L      =  (unsigned long)  (1 << 13),
+
+  //------ Les systemes de coordonnees astronomiques
+  // Coordonnees Equatoriales alpha,delta
+  TypCoordEq     =  (unsigned long)  (1 << 15),
+  // Coordonnees Galactiques gLong, gLat
+  TypCoordGal    =  (unsigned long)  (1 << 16),
+  // Coordonnees Horizontales azimuth,altitude
+  TypCoordHor    =  (unsigned long)  (1 << 17),
+  // Coordonnees Ecliptiques EclLong,EclLat
+  TypCoordEcl    =  (unsigned long)  (1 << 18),
+
+  //------ Les systemes de coordonnees astronomiques "standard"
+  // Coordonnees Equatoriales alpha,delta
+  TypCoordEqStd     =  (unsigned long)  (TypCoordEq |TypCoord1C|TypCoord1H|TypCoord2L|TypCoord2D),
+  // Coordonnees Galactiques gLong, gLat
+  TypCoordGalStd    =  (unsigned long)  (TypCoordGal|TypCoord1C|TypCoord1D|TypCoord2L|TypCoord2D),
+  // Coordonnees Horizontales azimuth,altitude
+  TypCoordHorStd    =  (unsigned long)  (TypCoordHor|TypCoord1C|TypCoord1D|TypCoord2L|TypCoord2D),
+  // Coordonnees Ecliptiques EclLong,EclLat
+  TypCoordEclStd    =  (unsigned long)  (TypCoordEcl|TypCoord1C|TypCoord1D|TypCoord2L|TypCoord2D),
+
+  //------ undef pour la forme
+  TypCoordUndef  =  (unsigned long)  (0)
+};
+
+// ------------------- Utilitaires -------------------
+unsigned long CoordConvertToStd(unsigned long typ,double* coord1,double* coord2);
+unsigned long GetCoordUnit(int coordnum,unsigned long typ);
+unsigned long DecodeTypAstro(const char *ctype);
+inline unsigned long DecodeTypAstro(const string stype)
+                {return DecodeTypAstro(stype.c_str());}
+string        DecodeTypAstro(unsigned long typ);
+void ToCoLat(double* val,unsigned long typ);
+void InRangeLat(double* val,unsigned long typ);
+void InRangeCoLat(double* val,unsigned long typ);
+
+/*!
+\brief Pour remettre la valeur "val" dans la dynamique [0.,range[.
+       Si "vmax" different de "range", c'est la borne superieure
+       qui peut etre atteinte
+       (si elle est depassee, on soustrait "range").
+\verbatim
+  r>0 vmax>0
+  r=24. vmax=24.   -> mets "val" dans [  0,+24[ borne sup exclue
+  r=24. vmax=12.   -> mets "val" dans ]-12,+12] borne inf exclue
+  (ATTENTION: ca ne marche pas pour la latitude [-90,90]
+              car -90 ne peut etre inclus dans l'intervalle)
+\endverbatim
+*/
+inline void InRange(double *val,double range)
+             {*val-=range*floor(*val/range);}
+inline void InRange(double *val,double range,double vmax)
+         {InRange(val,range); if(*val>vmax) *val-=range;}
+
+// ------------------- Gestions des temps -------------------
+/*! \ingroup XAstroPack
+\brief Compute true Julian day from MJD
+*/
+inline double TrueJDfrMJD(double mjd) {return mjd + MJD0;}
+
+/*! \ingroup XAstroPack
+\brief Compute MJD from true Julian day
+*/
+inline double MJDfrTrueJD(double jd) {return jd - MJD0;}
+
+double MJDfrDate(double dy,int mn,int yr);
+void DatefrMJD(double mjd,double *dy,int *mn,int *yr);
+double YearfrMJD(double mjd);
+double MJDfrYear(double yr);
+void YDfrMJD(double mjd,double *dy,int *yr);
+int IsLeapYear(int y);
+int DayOrder(double mjd,int *dow);
+int DaysInMonth(double mjd);
+double MJDat0hFrMJD(double mjd);
+double HfrMJD(double mjd);
+double GSTfrUTC(double mjd0,double utc);
+double UTCfrGST(double mjd0,double gst);
+
+/*! \ingroup XAstroPack
+\brief return local sidereal time from greenwich mean siderial time and longitude
+\param precis : if not zero, then correct for obliquity and nutation
+\warning no nutation or obliquity correction are done.
+*/                                                                             
+inline double LSTfrGST(double gst,double geolng)
+       {double lst = gst + deghr(geolng); InRange(&lst,24.); return lst;}
+
+double GST0(double mjd0);
+double LSTfrMJD(double mjd,double geolng);
+void HMSfrHdec(double hd,int *h,int *mn,double *s);
+double HdecfrHMS(int h,int mn,double s);
+string ToStringHMS(int h,int mn,double s);
+string ToStringHdec(double hd);
+
+// ------------------- Calculs Divers -------------------
+void Precess(double mjd1,double mjd2,double ra1,double dec1,double *ra2,double *dec2);
+inline void PrecessInPlace(double mjd1,double mjd2,double* ra,double* dec) {
+  double ra1=*ra, dec1=*dec;
+  Precess(mjd1,mjd2,ra1,dec1,ra,dec);
+}
+double AirmassfrAlt(double alt);
+double HelioCorr(double jd,double ra,double dec);
+
+// ------------------- Transformation de coordonnees -------------------
+/*! \ingroup XAstroPack
+\brief Give the hour angle from local sideral time and right ascension
+\warning right ascencion should be first precessed to date of interest
+\warning no nutation or obliquity correction are done.
+*/                                                                             
+// Attention au probleme de la discontinuite 0h <==> 24h
+// ts=1  ra=23 ; (ts-ra)=-22 <-12 --> ha = +2 = +24 + (ts-ra)
+// ts=23 ra=1  ; (ts-ra)=+22 >+12 --> ha = -2 = -24 + (ts-ra)
+inline double HafrRaTS(double lst,double ra)
+       {double ha = lst - ra; InRange(&ha,24.,12.); return ha;}
+
+/*! \ingroup XAstroPack
+\brief Give the local sideral time and the hour angle return the right ascencion
+\warning right ascencion is the value precessed to date of interest
+\warning no nutation or obliquity correction are done.
+*/                                                                             
+inline double RafrHaTS(double lst,double ha)
+       {double ra = lst - ha; InRange(&ra,24.); return ra;}
+
+void EqtoGal(double mjd,double ra,double dec,double *glng,double *glat);
+void GaltoEq(double mjd,double glng,double glat,double *ra,double *dec);
+void EqHtoHor(double geolat,double ha,double dec,double *az,double *alt);
+void HortoEqH(double geolat,double az,double alt,double *ha,double *dec);
+void EqtoHor(double geolat,double lst,double ra,double dec,double *az,double *alt);
+void HortoEq(double geolat,double lst,double az,double alt,double *ra,double *dec);
+void EqtoEcl(double mjd,double ra,double dec,double *eclng,double *eclat);
+void EcltoEq(double mjd,double eclng,double eclat,double *ra,double *dec);
+
+// ------------------- Positions des astres -------------------
+void SunPos(double mjd,double *eclsn,double *ecbsn,double *rsn);
+void MoonPos(double mjd,double *lmn,double *bmn,double *rho);
+void PlanetPos(double mjd,int numplan,double *sunecl,double *sunecb,double *sundist
+               ,double *geodist,double *geoecl,double *geoecb
+	       ,double *diamang,double *mag);
+/*! \ingroup XAstroPack
+\brief Same as PlanetPos above with less arguments
+*/
+inline void PlanetPos(double mjd,int numplan,double *geoecl,double *geoecb
+                      ,double *geodist,double *diamang)
+{
+ double sunecl,sunecb,sundist,mag;
+ PlanetPos(mjd,numplan,&sunecl,&sunecb,&sundist,geodist,geoecl,geoecb,diamang,&mag);
+}
+
+/*! \ingroup XAstroPack
+\brief Give Jupiter position
+*/
+inline void JupiterPos(double mjd,double *ecl,double *ecb,double *geodist,double *diamang)
+{
+  PlanetPos(mjd,JUPITER,ecl,ecb,geodist,diamang);
+}
+
+/*! \ingroup XAstroPack
+\brief Give Saturn position
+*/
+inline void SaturnPos(double mjd,double *ecl,double *ecb,double *geodist,double *diamang)
+{
+  PlanetPos(mjd,SATURN,ecl,ecb,geodist,diamang);
+}
+
+#endif
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/Makefile
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/Makefile	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/Makefile	(revision 2309)
@@ -0,0 +1,23 @@
+include $(DPCBASEREP)/Include/MakefileUser.h
+
+all: libxastro.a
+
+clean:
+	rm -f libxastro.a
+	rm -f *.o
+
+install:
+	if [ ! -d $(EXTINCPATH)/XAstro ] ; then mkdir $(EXTINCPATH)/XAstro ; fi
+	rm -f $(EXTINCPATH)/XAstro/astro.h
+	rm -f $(EXTINCPATH)/XAstro/P_.h
+	rm -f $(EXTLIBPATH)/libxastro.a
+	cp *.h $(EXTINCPATH)/XAstro/.
+	cp libxastro.a $(EXTLIBPATH)/.
+
+OBJASTRO := $(addsuffix .o,$(basename $(wildcard *.c)))
+
+libxastro.a : $(OBJASTRO)
+	$(AR) $(ARFLAGS) $@ $(OBJASTRO)
+
+%.o: %.c
+	$(COMPILE.c) -o $@ $<
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/Makefile.bak
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/Makefile.bak	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/Makefile.bak	(revision 2309)
@@ -0,0 +1,64 @@
+# Makefile for the basic astronomy routines.
+# The idea is to compile and archive them into libastro.a
+
+# flags assume gcc
+CFLAGS= -O2 -ffast-math -Wall
+CC = cc
+
+OBJS =	\
+	aa_hadec.o \
+	aberration.o \
+	actan.o \
+	airmass.o \
+	anomaly.o \
+	ap_as.o \
+	auxil.o \
+	chap95.o \
+	chap95_data.o \
+	circum.o \
+	comet.o \
+	dbfmt.o \
+	deep.o \
+	deltat.o \
+	earthsat.o \
+	eq_ecl.o \
+	eq_gal.o \
+	formats.o \
+	helio.o \
+	libration.o \
+	misc.o \
+	mjd.o \
+	moon.o \
+	mooncolong.o \
+	nutation.o \
+	obliq.o \
+	parallax.o \
+	plans.o \
+	precess.o \
+	reduce.o \
+	refract.o \
+	rings.o \
+	riset.o \
+	riset_cir.o \
+	sdp4.o \
+	sgp4.o \
+	sphcart.o \
+	sun.o \
+	thetag.o \
+	utc_gst.o \
+	twobody.o \
+	vsop87.o \
+	vsop87_data.o
+
+libastro.a:	$(OBJS)
+	ar rv $@ $?
+	ranlib $@
+
+libastro.so:    $(OBJS)
+	$(CC) -shared -o $@ $(OBJS)
+
+clobber:
+	rm -f *.o libastro.a
+
+# For RCS Only -- Do Not Edit
+# @(#) $RCSfile: Makefile.bak,v $ $Date: 2001-10-22 12:08:25 $ $Revision: 1.1 $ $Name: not supported by cvs2svn $
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/P_.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/P_.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/P_.h	(revision 2309)
@@ -0,0 +1,14 @@
+/* surround declarations with P_() to include prototypes if it looks likes
+ * compiler should handle them.
+ */
+#ifndef P_
+#if defined(__STDC__) || defined(__cplusplus) || NeedFunctionPrototypes
+#define P_(s) s
+#else
+#define P_(s) ()
+#endif
+#endif /* P_ */
+
+/* For RCS Only -- Do Not Edit
+ * @(#) $RCSfile: P_.h,v $ $Date: 2001-10-22 12:08:25 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $
+ */
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/README
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/README	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/README	(revision 2309)
@@ -0,0 +1,21 @@
+This library contains the basic ephemeris code.
+
+Earth satellite orbit propagation is based on the NORAD SGP4/SDP4 code, as
+converted from the orginal FORTRAN to C by Magnus Backstrom. The paper
+"Spacetrack Report Number 3: Models for Propagation of NORAD Element Sets"
+describes the calculations.
+See http://www.celestrak.com/NORAD/documentation/spacetrk.pdf.
+He following files implement this package:
+    actan.c
+    deep.c
+    deepconst.h
+    satlib.h
+    satspec.h
+    sattypes.h
+    sdp4.c
+    sgp4.c
+    thetag.c
+    vector.h
+
+! For RCS Only -- Do Not Edit
+! @(#) $RCSfile: README,v $ $Date: 2001-10-22 12:08:25 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/VERSION
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/VERSION	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/VERSION	(revision 2309)
@@ -0,0 +1,5 @@
+--------------------------------------------------------
+     "libastro" Xephem library version 3.4
+--------------------------------------------------------
+That code comes out of the Xephem software "libastro" part.
+http://www.clearskyinstitute.com/xephem/xephem.html
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/aa_hadec.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/aa_hadec.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/aa_hadec.c	(revision 2309)
@@ -0,0 +1,78 @@
+/* function to convert between alt/az and ha/dec.
+ */
+
+#include <stdio.h>
+#include <math.h>
+
+#include "P_.h"
+#include "astro.h"
+
+static void aaha_aux P_((double lat, double x, double y, double *p, double *q));
+
+/* given geographical latitude (n+, radians), lat, altitude (up+, radians),
+ * alt, and azimuth (angle round to the east from north+, radians),
+ * return hour angle (radians), ha, and declination (radians), dec.
+ */
+void
+aa_hadec (lat, alt, az, ha, dec)
+double lat;
+double alt, az;
+double *ha, *dec;
+{
+	aaha_aux (lat, az, alt, ha, dec);
+	if (*ha > PI)
+	    *ha -= 2*PI;
+}
+
+/* given geographical (n+, radians), lat, hour angle (radians), ha, and
+ * declination (radians), dec, return altitude (up+, radians), alt, and
+ * azimuth (angle round to the east from north+, radians),
+ */
+void
+hadec_aa (lat, ha, dec, alt, az)
+double lat;
+double ha, dec;
+double *alt, *az;
+{
+	aaha_aux (lat, ha, dec, az, alt);
+}
+
+#ifdef NEED_GEOC
+/* given a geographic (surface-normal) latitude, phi, return the geocentric
+ * latitude, psi.
+ */
+double
+geoc_lat (phi)
+double phi;
+{
+#define	MAXLAT	degrad(89.9999)	/* avoid tan() greater than this */
+	return (fabs(phi)>MAXLAT ? phi : atan(tan(phi)/1.00674));
+}
+#endif
+
+/* the actual formula is the same for both transformation directions so
+ * do it here once for each way.
+ * N.B. all arguments are in radians.
+ */
+static void
+aaha_aux (lat, x, y, p, q)
+double lat;
+double x, y;
+double *p, *q;
+{
+	static double last_lat = -3434, slat, clat;
+	double cap, B;
+
+	if (lat != last_lat) {
+	    slat = sin(lat);
+	    clat = cos(lat);
+	    last_lat = lat;
+	}
+
+	solve_sphere (-x, PI/2-y, slat, clat, &cap, &B);
+	*p = B;
+	*q = PI/2 - acos(cap);
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: aa_hadec.c,v $ $Date: 2001-10-22 12:08:26 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/aberration.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/aberration.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/aberration.c	(revision 2309)
@@ -0,0 +1,136 @@
+/* aberration, Jean Meeus, "Astronomical Algorithms", Willman-Bell, 1995;
+ * based on secular unperturbed Kepler orbit
+ *
+ * the corrections should be applied to ra/dec and lam/beta of the 
+ * epoch of date.
+ */
+
+#include <stdio.h>
+#include <math.h>
+
+#if defined(__STDC__)
+#include <stdlib.h>
+#endif
+
+#include "P_.h"
+#include "astro.h"
+
+#define ABERR_CONST	(20.49552/3600./180.*PI)  /* aberr const in rad */
+#define AB_ECL_EOD	0
+#define AB_EQ_EOD	1
+
+static void ab_aux P_((double mjd, double *x, double *y, double lsn,
+	int mode));
+
+/* apply aberration correction to ecliptical coordinates *lam and *bet
+ * (in radians) for a given time mjd and handily supplied longitude of sun,
+ * lsn (in radians)
+ */
+void
+ab_ecl (mjd, lsn, lam, bet)
+double mjd, lsn, *lam, *bet;
+{
+	ab_aux(mjd, lam, bet, lsn, AB_ECL_EOD);
+}
+
+/* apply aberration correction to equatoreal coordinates *ra and *dec
+ * (in radians) for a given time mjd and handily supplied longitude of sun,
+ * lsn (in radians)
+ */
+void
+ab_eq (mjd, lsn, ra, dec)
+double mjd, lsn, *ra, *dec;
+{
+	ab_aux(mjd, ra, dec, lsn, AB_EQ_EOD);
+}
+
+/* because the e-terms are secular, keep the real transformation for both
+ * coordinate systems in here with the secular variables cached.
+ * mode == AB_ECL_EOD:	x = lam, y = bet	(ecliptical)
+ * mode == AB_EQ_EOD:	x = ra,  y = dec	(equatoreal)
+ */
+static void
+ab_aux (mjd, x, y, lsn, mode)
+double mjd, *x, *y, lsn;
+int mode;
+{
+	static double lastmjd = -10000;
+	static double eexc;	/* earth orbit excentricity */
+	static double leperi;	/* ... and longitude of perihelion */
+	static char dirty = 1;	/* flag for cached trig terms */
+
+	if (mjd != lastmjd) {
+	    double T;		/* centuries since J2000 */
+
+	    T = (mjd - J2000)/36525.;
+	    eexc = 0.016708617 - (42.037e-6 + 0.1236e-6 * T) * T;
+	    leperi = degrad(102.93735 + (0.71953 + 0.00046 * T) * T);
+	    lastmjd = mjd;
+	    dirty = 1;
+	}
+
+	switch (mode) {
+	case AB_ECL_EOD:		/* ecliptical coords */
+	    {
+		double *lam = x, *bet = y;
+		double dlsun, dlperi;
+
+		dlsun = lsn - *lam;
+		dlperi = leperi - *lam;
+
+		/* valid only for *bet != +-PI/2 */
+		*lam -= ABERR_CONST/cos(*bet) * (cos(dlsun) -
+				eexc*cos(dlperi));
+		*bet -= ABERR_CONST*sin(*bet) * (sin(dlsun) -
+				eexc*sin(dlperi));
+	    }
+	    break;
+
+	case AB_EQ_EOD:			/* equatoreal coords */
+	    {
+		double *ra = x, *dec = y;
+		double sr, cr, sd, cd, sls, cls;/* trig values coords */
+		static double cp, sp, ce, se;	/* .. and perihel/eclipic */
+		double dra, ddec;		/* changes in ra and dec */
+
+		if (dirty) {
+		    double eps;
+
+		    cp = cos(leperi);
+		    sp = sin(leperi);
+		    obliquity(mjd, &eps);
+		    se = sin(eps);
+		    ce = cos(eps);
+		    dirty = 0;
+		}
+
+		sr = sin(*ra);
+		cr = cos(*ra);
+		sd = sin(*dec);
+		cd = cos(*dec);
+		sls = sin(lsn);
+		cls = cos(lsn);
+
+		dra = ABERR_CONST/cd * ( -(cr * cls * ce + sr * sls) +
+			    eexc * (cr * cp * ce + sr * sp));
+
+		ddec = se/ce * cd - sr * sd;	/* tmp use */
+		ddec = ABERR_CONST * ( -(cls * ce * ddec + cr * sd * sls) +
+			    eexc * (cp * ce * ddec + cr * sd * sp) );
+		
+		*ra += dra;
+		range (ra, 2*PI);
+		*dec += ddec;
+	    }
+	    break;
+
+	default:
+	    printf ("ab_aux: bad mode: %d\n", mode);
+	    exit (1);
+	    break;
+
+	} /* switch (mode) */
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: aberration.c,v $ $Date: 2001-10-22 12:08:26 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/actan.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/actan.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/actan.c	(revision 2309)
@@ -0,0 +1,67 @@
+#include <math.h>
+
+/* @(#) $Id: actan.c,v 1.2 2001-10-22 12:08:26 cmv Exp $ */
+
+/* commonly in math.h, but not in strict ANSI C */
+#ifndef M_PI
+#define M_PI            3.14159265358979323846
+#define M_PI_2          1.57079632679489661923
+#endif
+
+double
+actan(double sinx, double cosx)
+{
+    double ret;
+
+    ret = 0.0;
+    if(cosx < 0.0) {
+	ret = M_PI;
+    } else if(cosx == 0.0) {
+	if(sinx < 0.0) {
+	    return 3.0 * M_PI_2;
+	} else if(sinx == 0.0) {
+	    return ret;
+	} else /* sinx > 0.0 */ {
+	    return M_PI_2;
+	}
+    } else /* cosx > 0.0 */ {
+	if(sinx < 0.0) {
+	    ret = 2.0 * M_PI;
+	} else if(sinx == 0.0) {
+	    return ret;
+	}
+    }
+
+    return ret + atan(sinx / cosx);
+}
+
+
+#if 0
+
+#define D(X) (180.0 * (X) / M_PI)
+
+void main() {
+    double a, b;
+
+    a =  0.0; b =  2.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b)));
+    a =  1.0; b =  2.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b)));
+    a =  2.0; b =  2.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b)));
+    a =  2.0; b =  1.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b)));
+    a =  2.0; b =  0.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b)));
+    a =  2.0; b = -1.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b)));
+    a =  2.0; b = -2.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b)));
+    a =  1.0; b = -2.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b)));
+    a =  0.0; b = -2.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b)));
+    a = -1.0; b = -2.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b)));
+    a = -2.0; b = -2.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b)));
+    a = -2.0; b = -1.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b)));
+    a = -2.0; b =  0.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b)));
+    a = -2.0; b =  1.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b)));
+    a = -2.0; b =  2.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b)));
+    a = -1.0; b =  2.0; printf("actan(%f, %f) = %f\n", a, b, D(actan(a, b)));
+}
+
+#endif /* 0 */
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: actan.c,v $ $Date: 2001-10-22 12:08:26 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/airmass.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/airmass.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/airmass.c	(revision 2309)
@@ -0,0 +1,27 @@
+#include <math.h>
+
+#include "P_.h"
+#include "astro.h"
+
+/* given apparent altitude find airmass.
+ * R.H. Hardie, 1962, `Photoelectric Reductions', Chapter 8 of Astronomical
+ * Techniques, W.A. Hiltner (Ed), Stars and Stellar Systems, II (University
+ * of Chicago Press: Chicago), pp178-208. 
+ */
+void
+airmass (aa, Xp)
+double aa;		/* apparent altitude, rads */
+double *Xp;		/* airmasses */
+{
+	double sm1;	/* secant zenith angle, minus 1 */
+
+	/* degenerate near or below horizon */
+	if (aa < degrad(3.0))
+	    aa = degrad(3.0);
+
+	sm1 = 1.0/sin(aa) - 1.0;
+	*Xp = 1.0 + sm1*(0.9981833 - sm1*(0.002875 + 0.0008083*sm1));
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: airmass.c,v $ $Date: 2001-10-22 12:08:26 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/anomaly.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/anomaly.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/anomaly.c	(revision 2309)
@@ -0,0 +1,66 @@
+/* improved by rclark@lpl.arizona.edu (Richard Clark) */
+
+#include <stdio.h>
+#include <math.h>
+
+#include "P_.h"
+#include "astro.h"
+
+
+#define TWOPI   	(2*PI)
+#define	STOPERR		(1e-8)
+
+/* given the mean anomaly, ma, and the eccentricity, s, of elliptical motion,
+ * find the true anomaly, *nu, and the eccentric anomaly, *ea.
+ * all angles in radians.
+ */
+void
+anomaly (ma, s, nu, ea)
+double ma, s;
+double *nu, *ea;
+{
+        double m, fea, corr;
+
+        if (s < 1.0) {
+            /* elliptical */
+            double dla;
+
+            m = ma-TWOPI*(long)(ma/TWOPI);
+            if (m > PI) m -= TWOPI;
+            if (m < -PI) m += TWOPI;
+            fea = m;
+
+            for (;;) {
+                dla = fea-(s*sin(fea))-m;
+                if (fabs(dla)<STOPERR)
+                    break;
+                /* avoid runnaway corrections for e>.97 and M near 0*/
+                corr = 1-(s*cos(fea));
+                if (corr < .1) corr = .1;
+                dla /= corr;
+                fea -= dla;
+            }
+            *nu = 2*atan(sqrt((1+s)/(1-s))*tan(fea/2));
+        } else {
+            /* hyperbolic */
+	    double fea1;
+
+            m = fabs(ma);
+            fea = m / (s-1.);
+	    fea1 = pow(6*m/(s*s),1./3.);
+            /* whichever is smaller is the better initial guess */
+            if (fea1 < fea) fea = fea1;
+
+	    corr = 1;
+            while (fabs(corr) > STOPERR) {
+		corr = (m - s * sinh(fea) + fea) / (s*cosh(fea) - 1);
+		fea += corr;
+            }
+            if (ma < 0.) fea = -fea;
+            *nu = 2*atan(sqrt((s+1)/(s-1))*tanh(fea/2));
+        }
+        *ea = fea;
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: anomaly.c,v $ $Date: 2001-10-22 12:08:26 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/ap_as.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/ap_as.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/ap_as.c	(revision 2309)
@@ -0,0 +1,62 @@
+#include <string.h>
+
+#include "P_.h"
+#include "astro.h"
+#include "circum.h"
+
+/* convert the given apparent RA/Dec to astrometric precessed to Mjd IN PLACE.
+ * we have no un-abberation etc so to find the correction: assume
+ * *rap and *decp are astrometric@EOD, convert to apparent and back out
+ * the difference; then precess to Mjd.
+ */
+void
+ap_as (np, Mjd, rap, decp)
+Now *np;
+double Mjd;
+double *rap, *decp;
+{
+	Obj o;
+	Now n;
+
+	zero_mem ((void *)&o, sizeof(o));
+	o.o_type = FIXED;
+	o.f_RA = (float)*rap;
+	o.f_dec = (float)*decp;
+	o.f_epoch = (float)mjd;
+	memcpy ((void *)&n, (void *)np, sizeof(Now));
+	n.n_epoch = EOD;
+	obj_cir (&n, &o);
+	*rap -= o.s_ra - *rap;
+	*decp -= o.s_dec - *decp;
+	if (*decp >  PI/2) {*decp =  PI - *decp; *rap += PI; }
+	if (*decp < -PI/2) {*decp = -PI - *decp; *rap += PI; }
+	range (rap, 2*PI);
+	precess (mjd, Mjd, rap, decp);
+}
+
+/* convert the given astrometric RA/Dec which are precessed to Mjd into
+ * apparent @ EOD IN PLACE.
+ */
+void
+as_ap (np, Mjd, rap, decp)
+Now *np;
+double Mjd;
+double *rap, *decp;
+{
+	Obj o;
+	Now n;
+
+	zero_mem ((void *)&o, sizeof(o));
+	o.o_type = FIXED;
+	o.f_RA = (float)*rap;
+	o.f_dec = (float)*decp;
+	o.f_epoch = (float)Mjd;
+	memcpy ((void *)&n, (void *)np, sizeof(Now));
+	n.n_epoch = EOD;
+	obj_cir (&n, &o);
+	*rap = o.s_ra;
+	*decp = o.s_dec;
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: ap_as.c,v $ $Date: 2001-10-22 12:08:26 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/astro.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/astro.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/astro.h	(revision 2309)
@@ -0,0 +1,194 @@
+#ifndef PI
+#define	PI		3.141592653589793
+#endif
+
+/* conversions among hours (of ra), degrees and radians. */
+#define	degrad(x)	((x)*PI/180.)
+#define	raddeg(x)	((x)*180./PI)
+#define	hrdeg(x)	((x)*15.)
+#define	deghr(x)	((x)/15.)
+#define	hrrad(x)	degrad(hrdeg(x))
+#define	radhr(x)	deghr(raddeg(x))
+
+/* ratio of from synodic (solar) to sidereal (stellar) rate */
+#define	SIDRATE		.9972695677
+
+#define	SPD	(24.0*3600.0)	/* seconds per day */
+
+/* manifest names for planets.
+ * N.B. must coincide with usage in pelement.c and plans.c.
+ * N.B. only the first 8 are valid for use with plans().
+ */
+#define	MERCURY	0
+#define	VENUS	1
+#define	MARS	2
+#define	JUPITER	3
+#define	SATURN	4
+#define	URANUS	5
+#define	NEPTUNE	6
+#define	PLUTO	7
+
+/* a few more handy ones */
+#define	SUN	8
+#define	MOON	9
+#define	OBJX	10
+#define	OBJY	11
+#define	OBJZ	12
+#define	NOBJ	13	/* total number of basic objects */
+
+/* starting point for MJD calculations
+ */
+#define MJD0  2415020.0
+#define J2000 (2451545.0 - MJD0)      /* let compiler optimise */
+
+
+
+/* global function declarations */
+
+/* aa_hadec.c */
+extern void aa_hadec P_((double lat, double alt, double az, double *ha,
+    double *dec));
+extern void hadec_aa P_((double lat, double ha, double dec, double *alt,
+    double *az)); 
+
+/* aberration.c */
+extern void ab_ecl P_((double mjd, double lsn, double *lam, double *bet));
+extern void ab_eq P_((double mjd, double lsn, double *ra, double *dec));
+
+/* airmass.c */
+extern void airmass P_((double aa, double *Xp));
+
+/* anomaly.c */
+extern void anomaly P_((double ma, double s, double *nu, double *ea));
+
+/* chap95.c */
+extern int chap95 P_((double mjd, int obj, double prec, double *ret));
+
+/* chap95_data.c */
+
+/* comet.c */
+extern void comet P_((double mjd, double ep, double inc, double ap, double qp,
+    double om, double *lpd, double *psi, double *rp, double *rho, double *lam,
+    double *bet));
+
+/* deltat.c */
+extern double deltat P_((double mjd));
+
+/* eq_ecl.c */
+extern void eq_ecl P_((double mjd, double ra, double dec, double *lat,
+    double *lng));
+extern void ecl_eq P_((double mjd, double lat, double lng, double *ra,
+    double *dec));
+
+/* eq_gal.c */
+extern void eq_gal P_((double mjd, double ra, double dec, double *lat,
+    double *lng));
+extern void gal_eq P_((double mjd, double lat, double lng, double *ra,
+    double *dec));
+
+/* formats.c */
+extern void fs_sexa P_((char *out, double a, int w, int fracbase));
+extern void fs_date P_((char out[], double jd));
+extern void f_scansex P_((double o, char *str, double *dp));
+extern void f_sscandate P_((char *bp, int pref, int *m, double *d, int *y));
+extern int scansex P_((char *str, double *dp));
+
+/* helio.c */
+extern void heliocorr P_((double jd, double ra, double dec, double *hcp));
+
+/* libration.c */
+extern void llibration P_((double JD, double *llatp, double *llonp));
+
+/* misc.c */
+extern void zero_mem P_((void *loc, unsigned len));
+extern int tickmarks P_((double min, double max, int numdiv, double ticks[]));
+extern int lc P_((int cx, int cy, int cw, int x1, int y1, int x2, int y2,
+    int *sx1, int *sy1, int *sx2, int *sy2));
+extern void hg_mag P_((double h, double g, double rp, double rho, double rsn,
+    double *mp));
+extern int magdiam P_((int fmag, int magstp, double scale, double mag,
+    double size));
+extern void gk_mag P_((double g, double k, double rp, double rho, double *mp));
+extern double atod P_((char *buf));
+extern void solve_sphere P_((double A, double b, double cc, double sc,
+    double *cap, double *Bp));
+extern double delra P_((double dra));
+
+/* mjd.c */
+extern void cal_mjd P_((int mn, double dy, int yr, double *mjd));
+extern void mjd_cal P_((double mjd, int *mn, double *dy, int *yr));
+extern int mjd_dow P_((double mjd, int *dow));
+extern int isleapyear P_((int year));
+extern void mjd_dpm P_((double mjd, int *ndays));
+extern void mjd_year P_((double mjd, double *yr));
+extern void year_mjd P_((double y, double *mjd));
+extern void rnd_second P_((double *t));
+extern void mjd_dayno P_((double jd, int *yr, double *dy));
+extern double mjd_day P_((double jd));
+extern double mjd_hr P_((double jd));
+extern void range P_((double *v, double r));
+
+/* moon.c */
+extern void moon P_((double mjd, double *lam, double *bet, double *rho,
+    double *msp, double *mdp));
+
+/* mooncolong.c */
+extern void moon_colong P_((double jd, double lt, double lg, double *cp, double *kp, double *ap, double *sp));
+
+/* nutation.c */
+extern void nutation P_((double mjd, double *deps, double *dpsi));
+extern void nut_eq P_((double mjd, double *ra, double *dec));
+
+/* obliq.c */
+extern void obliquity P_((double mjd, double *eps));
+
+/* parallax.c */
+extern void ta_par P_((double tha, double tdec, double phi, double ht,
+    double *rho, double *aha, double *adec));
+
+/* plans.c */
+extern void plans P_((double mjd, int p, double *lpd0, double *psi0,
+    double *rp0, double *rho0, double *lam, double *bet, double *dia,
+    double *mag));
+
+/* precess.c */
+extern void precess P_((double mjd1, double mjd2, double *ra, double *dec));
+
+/* reduce.c */
+extern void reduce_elements P_((double mjd0, double mjd, double inc0,
+    double ap0, double om0, double *inc, double *ap, double *om));
+
+/* refract.c */
+extern void unrefract P_((double pr, double tr, double aa, double *ta));
+extern void refract P_((double pr, double tr, double ta, double *aa));
+
+/* rings.c */
+extern void satrings P_((double sb, double sl, double sr, double el, double er,
+    double JD, double *etiltp, double *stiltp));
+
+/* riset.c */
+extern void riset P_((double ra, double dec, double lat, double dis,
+    double *lstr, double *lsts, double *azr, double *azs, int *status));
+
+/* sphcart.c */
+extern void sphcart P_((double l, double b, double r, double *x, double *y,
+    double *z));
+extern void cartsph P_((double x, double y, double z, double *l, double *b,
+    double *r));
+
+/* sun.c */
+extern void sunpos P_((double mjd, double *lsn, double *rsn, double *bsn));
+
+/* twobody.c */
+extern void vrc P_((double *v, double *r, double tp, double e, double q));
+
+/* utc_gst.c */
+extern void utc_gst P_((double mjd, double utc, double *gst));
+extern void gst_utc P_((double mjd, double gst, double *utc));
+
+/* vsop87.c */
+extern int vsop87 P_((double mjd, int obj, double prec, double *ret));
+
+/* For RCS Only -- Do Not Edit
+ * @(#) $RCSfile: astro.h,v $ $Date: 2001-10-22 12:08:26 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $
+ */
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/auxil.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/auxil.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/auxil.c	(revision 2309)
@@ -0,0 +1,50 @@
+/* aux functions so programs besides XEphem can use this library.
+ */
+
+#include <stdio.h>
+
+#if defined (__STDC__)
+#include <stdlib.h>
+#endif
+
+#include "P_.h"
+#include "astro.h"
+#include "circum.h"
+#include "preferences.h"
+
+static int prefs[NPREFS] = {
+    PREF_TOPO, PREF_METRIC, PREF_MDY, PREF_UTCTZ, PREF_HIPREC, PREF_NOMSGBELL,
+    PREF_PREFILL, PREF_TIPSON, PREF_CONFIRMON, PREF_WEEKSTART
+};
+
+/* called anytime we want to know a preference.
+ */
+int
+pref_get(pref)
+Preferences pref;
+{
+	return (prefs[pref]);
+}
+
+/* call to force a certain preference, return the old setting.
+ */
+int
+pref_set (pref, new)
+Preferences pref;
+int new;
+{
+	int prior = pref_get(pref);
+	prefs[pref] = new;
+	return (prior);
+}
+
+/* given an mjd, return it modified for terrestial dynamical time */
+double
+mm_mjed (np)
+Now *np;
+{
+	return (mjd + deltat(mjd)/86400.0);
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: auxil.c,v $ $Date: 2001-10-22 12:08:26 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/chap95.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/chap95.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/chap95.c	(revision 2309)
@@ -0,0 +1,180 @@
+/* heliocentric rectangular equatorial coordinates of Jupiter to Pluto;
+ * from Chapront's expansion of DE200/extension of DE200;  mean equator J2000.0
+ *
+ * calculation time (milliseconds) on an HP 715/75, Jupiter to Pluto:
+ * (each coordinate component counted as 1 term,
+ * secular terms included for JD 2448908.5 = 1992 Oct 13.0)
+ *
+ *      prec	terms	rates	no rates
+ *	0.0	2256	5.1	4.6
+ *
+ *	1e-7	792	2.6	2.4	--> nominal precision rel. to DE200
+ *	1e-6	535	2.1	2.0
+ *	1e-5	350	1.8	1.6
+ *	1e-4	199	1.5	1.4
+ *	1e-3	96	1.2	1.1
+ *
+ *	no drop	2256	4.5	3.9	(code without test criterion)
+ */
+
+#include <math.h>
+#include "P_.h"
+#include "astro.h"
+#include "chap95.h"
+
+extern void zero_mem P_((void *loc, unsigned len));
+
+#define CHAP_MAXTPOW	2	/* NB: valid for all 5 outer planets */
+
+/* chap95()
+ *
+ * input:
+ *	mjd	modified JD; days from J1900.0 = 2415020.0
+ *
+ *	prec	precision level, in radians.
+ *		if (prec = 0.0), you get the full precision, namely
+ *		a deviation of not more than 0.02 arc seconds (1e-7 rad)
+ *		from the JPL DE200 integration, on which this expansion
+ *		is based.
+ *
+ *	obj	object number as in astro.h (jupiter=3, saturn=4, ...)
+ *
+ * output:
+ *	ret[6]	cartesian components of position and velocity
+ *
+ * return:
+ *	0	Ok
+ *	1	time out of range [CHAP_BEGIN .. CHAP_END]
+ *	2	object out of range [JUPITER .. PLUTO]
+ *	3	precision out of range [0.0 .. 1e-3]
+ */
+int
+chap95 (mjd, obj, prec, ret)
+double mjd;
+int obj;
+double prec;
+double *ret;
+{
+	static double a0[] = {		/* semimajor axes for precision ctrl */
+	    0.39, 0.72, 1.5, 5.2, 9.6, 19.2, 30.1, 39.5, 1.0
+	};
+	double sum[CHAP_MAXTPOW+1][6];	/* [T^0, ..][X,Y,Z,X',Y',Z'] */
+	double T, t;			/* time in centuries and years */
+	double ca, sa, Nu;		/* aux vars for terms */
+	double precT[CHAP_MAXTPOW+1];	/* T-augmented precision threshold */
+	chap95_rec *rec;		/* term coeffs */
+	int cooidx;
+
+	/* check parameters */
+	if (mjd < CHAP_BEGIN || mjd > CHAP_END)
+		return (1);
+
+	if (obj < JUPITER || obj > PLUTO)
+		return (2);
+
+	if (prec < 0.0 || prec > 1e-3)
+		return (3);
+
+	/* init the sums */
+	zero_mem ((void *)sum, sizeof(sum));
+
+	T = (mjd - J2000)/36525.0;	/* centuries since J2000.0 */
+
+	/* modify precision treshold for
+	 * a) term storing scale
+	 * b) convert radians to au
+	 * c) account for skipped terms (more terms needed for better prec)
+	 *    threshold empirically established similar to VSOP; stern
+	 * d) augment for secular terms
+	 */
+	precT[0] = prec * CHAP_SCALE				/* a) */
+			* a0[obj]				/* b) */
+			/ (10. * (-log10(prec + 1e-35) - 2));	/* c) */
+	t = 1./(fabs(T) + 1e-35);				/* d) */
+	precT[1] = precT[0]*t;
+	precT[2] = precT[1]*t;
+
+	t = T * 100.0;		/* YEARS since J2000.0 */
+
+	ca = sa = Nu = 0.;	/* shut up compiler warning 'uninitialised' */
+
+	switch (obj) {		/* set initial term record pointer */
+	    case JUPITER:	rec = chap95_jupiter;	break;
+	    case SATURN:	rec = chap95_saturn;	break;
+	    case URANUS:	rec = chap95_uranus;	break;
+	    case NEPTUNE:	rec = chap95_neptune;	break;
+	    case PLUTO:		rec = chap95_pluto;	break;
+	    default:
+		return (2);	/* wrong object: severe internal trouble */
+	}
+
+	/* do the term summation into sum[T^n] slots */
+	for (; rec->n >= 0; ++rec) {
+	    double *amp;
+
+	    /* NOTE:  The formula
+	     * X = SUM[i=1,Records] T**n_i*(CX_i*cos(Nu_k*t)+SX_i*sin(Nu_k*t))
+	     * could be rewritten as  SUM( ... A sin (B + C*t) )
+	     * "saving" trigonometric calls.  However, e.g. for Pluto,
+	     * there are only 65 distinct angles NU_k (130 trig calls).
+	     * With that manipulation, EVERY arg_i would be different for X,
+	     * Y and Z, which is 3*96 terms.  Hence, the formulation as
+	     * given is good (optimal?).
+	     */
+
+	    for (cooidx = 0, amp = rec->amp; cooidx < 3; ++cooidx) {
+		double C, S, term, termdot;
+		short n;		/* fast access */
+
+		C = *amp++;
+		S = *amp++;
+		n = rec->n;
+
+		/* drop term if too small
+		 * this is quite expensive:  17% of loop time
+		 */
+		if (fabs(C) + fabs(S) < precT[n])
+			continue;
+
+		if (n == 0 && cooidx == 0) {	/* new Nu only here */
+		    double arg;
+
+		    Nu = rec->Nu;
+		    arg = Nu * t;
+		    arg -= floor(arg/(2.*PI))*(2.*PI);
+		    ca = cos(arg);	/* blast it - even for Nu = 0.0 */
+		    sa = sin(arg);
+		}
+
+		term = C * ca + S * sa;
+		sum[n][cooidx] += term;
+#if CHAP_GETRATE
+		termdot = (-C * sa + S * ca) * Nu;
+		sum[n][cooidx+3] += termdot;
+		if (n > 0) sum[n - 1][cooidx+3] += n/100.0 * term;
+#endif
+	    } /* cooidx */
+	} /* records */
+
+	/* apply powers of time and sum up */
+	for (cooidx = 0; cooidx < 6; ++cooidx) {
+	    ret[cooidx] = (sum[0][cooidx] +
+			T * (sum[1][cooidx] +
+			T * (sum[2][cooidx] )) )/CHAP_SCALE;
+	}
+
+	/* TEST: if the MAIN terms are dropped, get angular residue
+	ret[0] = sqrt(ret[0]*ret[0] + ret[1]*ret[1] + ret[2]*ret[2])/a0[obj];
+	*/
+
+#if CHAP_GETRATE
+	for (cooidx = 3; cooidx < 6; ++cooidx) {
+	    ret[cooidx] /= 365.25;	/* yearly to daily rate */
+	}
+#endif
+
+    return (0);
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: chap95.c,v $ $Date: 2001-10-22 12:08:26 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/chap95.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/chap95.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/chap95.h	(revision 2309)
@@ -0,0 +1,69 @@
+/* Position of outer planets; straightforward from:
+ftp://adc.gsfc.nasa.gov/pub/adc/archives/journal_tables/A+AS/109/181:
+
+J/A+AS/109/181                            Planetary ephemerides (Chapront, 1995)
+===============================================================================
+Representation of planetary ephemerides by frequency analysis. Application to
+the five outer planets.
+       CHAPRONT J.
+      <Astron. Astrophys. Suppl. Ser. 109, 181 (1995)>
+      =1995A&AS..109..181C      (SIMBAD/NED Reference)
+===============================================================================
+
+Keywords: ephemerides - planets and satellites: general - methods: numerical
+
+Contents:
+  Heliocentric equatorial rectangular coordinates of the five outer planets
+  (X, Y and Z). The source is based on DE200 (tables 4 to 7) or a reconstruction
+  of DE200 by numerical integration (tables 9 to 13). The reference frame is
+  the mean equator and equinox J2000 of DE200.
+
+  The general formulation of the series X is:
+  X = SUM[i=1,Records] T**n_i*(CX_i*cos(Nu_k*t)+SX_i*sin(Nu_k*t))
+  The formulation is identical for Y and Z.
+  T is the time (TDB) in Julian centuries from J2000:
+        T = (JulianDate - 2451545.0)/36525
+  t is the time (TDB) in Julian years from J2000:
+        t = (JulianDate - 2451545.0)/365.25
+  Nu is the frequency. Frequencies are identical for all terms of rank k:
+                Nu_k = Nu_i when n_i = 0
+                For purely secular terms k = 0 and Nu_0 = 0
+
+===============================================================================
+(End)                                          Patricia Bauer [CDS] 03-Oct-1994
+*/
+
+#define CHAP_SCALE	1e10
+
+/* JDs of validity period */
+#define CHAP_BEGIN	(2338032.5 - MJD0)	/* 1689/3/19 */
+#define CHAP_END	(2542032.5 - MJD0)	/* 2247/10/1 */
+
+/* coding flags */
+/* calculating rates increases time by about 10%
+ *
+ * On an HP715/75, for pluto the times per step are 0.00049 s and 0.00057 s
+ * This method is quite fast.
+ */
+#define CHAP_GETRATE    1
+
+typedef struct {
+	short n;	/* order of time; "-1" marks end of list */
+	double amp[6];	/* amplitudes of cosine and sine terms for x,y,z */
+			/* in original order [CX,SX,CY,SY,CZ,SZ] */
+	double Nu;	/* Frequency Nu_k; given only at n=0 */
+} chap95_rec;
+
+extern chap95_rec chap95_jupiter[];
+extern chap95_rec chap95_saturn[];
+extern chap95_rec chap95_uranus[];
+extern chap95_rec chap95_neptune[];
+extern chap95_rec chap95_pluto[];
+
+#include "P_.h"
+extern int chap95 P_((double mjd, int obj, double prec, double *ret));
+
+
+/* For RCS Only -- Do Not Edit
+ * @(#) $RCSfile: chap95.h,v $ $Date: 2001-10-22 12:08:26 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $
+ */
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/chap95_data.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/chap95_data.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/chap95_data.c	(revision 2309)
@@ -0,0 +1,783 @@
+/* data tables for Chapront95 expansion of DE200 for outer planets
+ *
+ * created by automatic conversion from original distribution files at
+ * ftp://adc.gsfc.nasa.gov/pub/adc/archives/journal_tables/A+AS/109/181
+ */
+
+#include "chap95.h"
+
+chap95_rec chap95_jupiter[] = {
+	{ 0, { -3658015942., 0., -908357166., 0., -300271978., 0. }, 0. },
+	{ 1, { 3211736., 0., -12066362., 0., -5380492., 0. },  },
+	{ 0, { 4891337., 5430776., -9059458., 4045908., -3979137., 1598300. }, 0.0168745727060282 },
+	{ 1, { -1952368., 3224556., -3665363., -6161184., -1519962., -2703058. },  },
+	{ 0, { 589280., -62004., -1226982., 1326111., -536148., 568311. }, 0.0319163179770344 },
+	{ 0, { -132797., 113059., 332715., -538044., 144358., -232591. }, 0.0404897860926306 },
+	{ 0, { 19390., -8208., -31003., 153367., -13456., 65630. }, 0.0595473299932462 },
+	{ 0, { -2479., -51303., 154576., 368773., 65961., 157222. }, 0.0831987723231718 },
+	{ 1, { -170149., 190549., 249291., -236183., 108588., -106146. },  },
+	{ 0, { -14177274., -32784827., -28623327., 13932421., -12074567., 6670491. }, 0.1015656301267251 },
+	{ 1, { -3789129., 1413684., 2551178., 1957155., 1164465., 819456. },  },
+	{ 0, { 12762505., 226609., -4837955., 12330917., -2405339., 5249055. }, 0.1121334694975955 },
+	{ 1, { 547155., 1481967., -2013999., -2660987., -879208., -1179904. },  },
+	{ 0, { -62226., -41759., -601831., 240767., -255949., 106231. }, 0.1235484250413803 },
+	{ 0, { 38451., -38927., 103878., -40998., 43472., -16957. }, 0.1380033981088614 },
+	{ 0, { 6892., -67712., 62422., 39405., 26942., 18451. }, 0.1534434914458037 },
+	{ 0, { -75., 8062., -21151., -17198., -9222., -7580. }, 0.1694333239035300 },
+	{ 0, { 35355., 38181., 70566., -4376., 30386., -2939. }, 0.1895181584594278 },
+	{ 0, { -743715., -251198., -403257., 598432., -166123., 265466. }, 0.2002642151969322 },
+	{ 0, { 5834437., -10339387., 9606367., 9534188., 3806370., 4385708. }, 0.2140513638608579 },
+	{ 1, { 1033031., -590411., -1874404., 575478., -835406., 235620. },  },
+	{ 2, { 514744., -29792., -180518., -472533., -83894., -204253. },  },
+	{ 0, { 160903., -61277., -282564., -163689., -122933., -69902. }, 0.2282692683160305 },
+	{ 0, { -27903., 23114., 66255., 2167., 28792., 688. }, 0.2391180221674930 },
+	{ 0, { 4501., -5373., -15639., 12832., -6785., 5553. }, 0.2594200270243392 },
+	{ 0, { -7016., 15969., 7639., -40047., 3504., -17544. }, 0.2773387700991547 },
+	{ 0, { 12123., -71452., 49781., 137809., 20807., 61532. }, 0.2898870950096423 },
+	{ 0, { 9304., 220632., -262203., -258243., -112815., -119757. }, 0.2988785450891279 },
+	{ 0, { -326815., -368979., 836570., 374605., 369053., 187133. }, 0.3074463122377075 },
+	{ 0, { -285560., 1568528., -1374181., -462165., -548097., -222596. }, 0.3260929459480317 },
+	{ 1, { 61071., -241375., 291550., 243626., 110389., 123427. },  },
+	{ 2, { 227305., 162244., -116416., 352218., -65158., 140646. },  },
+	{ 0, { 132035., 23450., 116510., 219543., 39775., 92330. }, 0.3428930094327709 },
+	{ 0, { -45107., 4887., -87029., -68971., -33182., -29857. }, 0.3524288275557115 },
+	{ 0, { 11180., 1421., 46242., 3234., 18448., 1726. }, 0.3676619945918164 },
+	{ 0, { 55636., 74415., 46443., -53844., 16908., -25824. }, 0.3817149836030239 },
+	{ 0, { -38712., -7953., 29506., -14698., 13883., -4384. }, 0.4024967272931009 },
+	{ 0, { 737722., -3325874., -1725701., 1468892., -912453., 541637. }, 0.4182255664674069 },
+	{ 0, { 5843515., 17000877., -16425950., 5641739., -7208900., 1880856. }, 0.4281067291965077 },
+	{ 1, { -2114864., 879909., -1266263., -2982111., -450528., -1332322. },  },
+	{ 0, { -110808., 282843., -713054., 221824., -319044., 77631. }, 0.4373541005020147 },
+	{ 0, { 27829., -71864., 150036., -117804., 67370., -49093. }, 0.4560888031675395 },
+	{ 0, { 539822., 432225., -319385., 741980., -155058., 309230. }, 0.4797023746036813 },
+	{ 1, { 353284., -620503., 706907., 178082., 295983., 93413. },  },
+	{ 2, { -261070., -393195., 329623., -469610., 151911., -193312. },  },
+	{ 0, { -2161367., -547925., 176106., -2360409., 138737., -1001848. }, 0.5007107300722267 },
+	{ 0, { 27247697., -10878578., 11956310., 25892704., 4272604., 11389311. }, 0.5164419295757459 },
+	{ 0, { 42877248480., -29362030594., 27366424342., 39132999157., 10686125728., 17489248357. }, 0.5296606590588865 },
+	{ 1, { -15857296., -20344255., 19186229., -13052624., 8755482., -9908361. },  },
+	{ 2, { 6609281., 13149967., -10297853., 6131752., -4439009., 2280289. },  },
+	{ 0, { -18516226., 26000654., -21956172., -17721375., -8891106., -8274169. }, 0.5451799187785868 },
+	{ 0, { 924882., -10894893., 8857638., 2001907., 3741179., 1161552. }, 0.5595376466726170 },
+	{ 0, { 27311120., 29858821., -26928769., 14296744., -12217212., 5123580. }, 0.5795066100144535 },
+	{ 1, { 13030129., -18873913., 10742323., 12477743., 4123021., 5837654. },  },
+	{ 2, { -7424534., -11497916., 9860547., -3566473., 4394376., -1162013. },  },
+	{ 0, { -26277687., -24566747., 22551607., -14225886., 10328130., -5247184. }, 0.5911608643334181 },
+	{ 1, { 8339866., -11546546., 6481932., 8138775., 2473924., 3793057. },  },
+	{ 0, { -712821., 106326., 116149., -425425., 75173., -183273. }, 0.6154942605989902 },
+	{ 0, { 10367622., 10279698., -8594103., 9404066., -3937577., 3712537. }, 0.6326027345940838 },
+	{ 1, { 897045., 857895., -751707., 469816., -332572., 171768. },  },
+	{ 0, { 189069., -432469., 40216., 165708., -8464., 80857. }, 0.6444812066531010 },
+	{ 1, { 358961., 188063., -197366., 119155., -93776., 37030. },  },
+	{ 0, { 2801., -42321., 23044., 13212., 9231., 7153. }, 0.6631203366491857 },
+	{ 0, { 4336., 3618., -871., -1752., -434., -1180. }, 0.6824152589010221 },
+	{ 0, { -14481., -6624., 4573., -1496., 2554., -8. }, 0.7002707215510490 },
+	{ 0, { -223890., 106356., -2013., -41001., 13805., -21357. }, 0.7195602591163895 },
+	{ 1, { 28954., 129738., -23285., -9336., -9672., -11954. },  },
+	{ 0, { 500290., -303873., -27592., 125875., -40399., 71687. }, 0.7280600120460897 },
+	{ 0, { 729018., -876869., -461257., 537352., -184892., 325523. }, 0.7385877731868745 },
+	{ 1, { -549774., 403499., -445388., -787700., -178960., -329235. },  },
+	{ 0, { -154224., -136331., 129548., -90101., 64599., -32148. }, 0.7506622252123309 },
+	{ 0, { 36827., 21410., -22046., 16972., -12019., 7006. }, 0.7602186192346818 },
+	{ 0, { -9432., -929., 4761., -3712., 2630., -1835. }, 0.7714697369886172 },
+	{ 0, { 2272., -244., -1058., 1139., -553., 579. }, 0.7851226034217180 },
+	{ 0, { 236., 2440., 694., 90., 191., -135. }, 0.8150362349770407 },
+	{ 0, { 2171., -25731., -8199., 18101., -2071., 8952. }, 0.8291920856012017 },
+	{ 0, { -6488604., 1912961., -2051708., -5704251., -640826., -2468602. }, 0.8459901559232306 },
+	{ 1, { 133871., -10089., -90464., 3174., -43566., 7399. },  },
+	{ 2, { 3748., 19859., 25943., -57668., 8170., -24731. },  },
+	{ 0, { 41412., 22074., -6939., -4045., -5698., -1697. }, 0.8578592213260567 },
+	{ 0, { 574., 1501., -732., 4283., -255., 1685. }, 0.8738246080594192 },
+	{ 0, { 2322., -1798., 335., 937., 88., 501. }, 0.8963147077496537 },
+	{ 0, { -43604., -1899., 4040., -39896., 2661., -17151. }, 0.9105458422489332 },
+	{ 0, { 3596., -6271., 379., 5996., 286., 2760. }, 0.9259391061890530 },
+	{ 0, { -999582., 6287537., -5679601., -791405., -2413314., -507432. }, 0.9494173054851961 },
+	{ 1, { 111599., -339713., 235481., 52027., 98992., 33925. },  },
+	{ 2, { -33602., -140395., 93339., -35641., 41369., -10865. },  },
+	{ 0, { 149940., -187453., 95997., 203410., 38908., 91533. }, 0.9614421422806174 },
+	{ 0, { 46262., 123227., -97700., -14018., -43879., -8187. }, 0.9766842863215204 },
+	{ 0, { -150852., -63931., 82864., -16270., 39997., -7673. }, 0.9902969827486889 },
+	{ 0, { 580431., 130968., -306415., 215177., -145258., 96440. }, 1.0007147457558208 },
+	{ 0, { -315446., -113604., 191678., -91901., 90254., -41025. }, 1.0094608196461621 },
+	{ 1, { -3456., -446353., 229052., 185524., 103258., 88674. },  },
+	{ 0, { -189618., 113597., 8806., -140678., 6615., -64661. }, 1.0246980386783211 },
+	{ 0, { 4202483., 3000173., -2459447., 3363962., -1179328., 1385544. }, 1.0482030530764612 },
+	{ 1, { 1203874., -292900., 70065., 779465., 3811., 351179. },  },
+	{ 0, { 735702407., -1021641460., 944902088., 667150510., 387126729., 310854521. }, 1.0592824949737543 },
+	{ 1, { -225227., -2656169., 2070353., -678917., 860531., -321583. },  },
+	{ 0, { -906103., 1248865., -1249024., -614151., -510434., -296157. }, 1.0735437556293621 },
+	{ 0, { 133104., -244102., 224418., -12870., 91960., 2555. }, 1.0875704154537504 },
+	{ 0, { -98191., 334119., -93120., 114027., -39453., 36051. }, 1.1091289342301658 },
+	{ 1, { 131527., 1551., 58039., -54878., 19569., -21191. },  },
+	{ 2, { 65753., -188377., 68757., -76650., 28565., -25385. },  },
+	{ 0, { 61867., -343846., 16261., -113012., 8972., -35330. }, 1.1225031990563263 },
+	{ 0, { -7347., 137455., 17960., 22121., 5845., 4618. }, 1.1328877109810458 },
+	{ 0, { 11044., -88733., -25019., 37631., -8977., 18971. }, 1.1464066922869334 },
+	{ 0, { 11350781., -248125., 270190., 10489566., -145232., 4511204. }, 1.1622993228682923 },
+	{ 0, { -52127., 35850., -14691., -77957., -5084., -33671. }, 1.1728440239417584 },
+	{ 1, { -12008., 23292., -2942., -7282., -1291., -3563. },  },
+	{ 0, { 4294., 460., -3058., 3439., -1373., 1474. }, 1.1878668274609869 },
+	{ 0, { -1289., -734., 1786., -2248., 786., -941. }, 1.1998692758026896 },
+	{ 0, { 361., -793., 308., -1262., 122., -515. }, 1.2317935880659059 },
+	{ 0, { -195., 2534., -191., 3923., -67., 1609. }, 1.2448441509199817 },
+	{ 0, { -5385., -19904., 6349., -3489., 3158., -1221. }, 1.2560282933480911 },
+	{ 0, { 413790., -613072., 546872., 412919., 228594., 191066. }, 1.2653944427657104 },
+	{ 1, { -20115., 4841., -30066., -2156., -12194., -733. },  },
+	{ 0, { -56810., -2443., 14410., -37878., 7539., -15830. }, 1.2776927606634534 },
+	{ 1, { -883., -20034., 8211., 10587., 3489., 5153. },  },
+	{ 0, { -2444., 1465., 414., 793., 279., 259. }, 1.2924980461987274 },
+	{ 0, { 864., -632., -623., -218., -312., -55. }, 1.3014788911147197 },
+	{ 0, { 26233., -115536., 1588., -54448., 260., -17749. }, 1.3673745438817879 },
+	{ 0, { -366768., 241272., -241508., -348534., -93295., -154126. }, 1.3764442873088090 },
+	{ 1, { -4898., -22923., 39935., -25211., 16711., -10168. },  },
+	{ 0, { 7481., -4670., -7877., -4002., -3598., -1348. }, 1.3867469996002664 },
+	{ 0, { -2408., 1756., 2965., 1290., 1336., 416. }, 1.3958662188525488 },
+	{ 0, { 972., -751., -912., -28., -417., 39. }, 1.4068178503492994 },
+	{ 0, { -20343., 4804., -6579., -18594., -2298., -8037. }, 1.4396065958679622 },
+	{ 0, { 894., 1313., 1992., 632., 793., 162. }, 1.4496940872610145 },
+	{ 0, { -1983., -4631., -7582., 723., -2974., 660. }, 1.4625845924962999 },
+	{ 0, { 648492., 510288., -503142., 612739., -227097., 254982. }, 1.4790870471301645 },
+	{ 1, { -7847., 5399., -12816., -32834., -5768., -13533. },  },
+	{ 2, { -5935., 4107., 3696., -8454., 1585., -3763. },  },
+	{ 0, { 471., -326., 1178., -492., 455., -210. }, 1.5004111597792062 },
+	{ 0, { -1102., 5980., -5712., -389., -2409., -319. }, 1.5140608680143952 },
+	{ 0, { 235., -531., 427., -154., 168., -42. }, 1.5277453924778683 },
+	{ 0, { 1530., 1846., -2090., 2162., -918., 867. }, 1.5510420454912401 },
+	{ 0, { -8695., -5270., 3702., -11973., 1786., -4877. }, 1.5653775377343770 },
+	{ 0, { 108442., 13977., -7635., 130460., -5580., 54970. }, 1.5750243622459430 },
+	{ 0, { 12988439., -44123991., 40567288., 11522384., 17076170., 6015693. }, 1.5888946239094504 },
+	{ 1, { -297436., -96470., 75756., -224551., 37973., -97866. },  },
+	{ 2, { -140095., 49206., -15492., -114871., -4072., -51280. },  },
+	{ 0, { -213784., 360331., -204961., -174648., -85958., -85816. }, 1.5999174688094493 },
+	{ 0, { 34848., -82622., 33382., 30061., 14595., 15488. }, 1.6100691344943834 },
+	{ 1, { 43010., 10308., -12996., 14235., -6844., 6576. },  },
+	{ 0, { -1221., -3776., 845., 910., 489., 461. }, 1.6263710325060152 },
+	{ 0, { 554., 745., -310., -340., -171., -141. }, 1.6392210890659527 },
+	{ 0, { 20026., -16502., -3852., -9369., -2306., -3026. }, 1.6820002884969334 },
+	{ 0, { 813659., -336143., 300160., 724773., 109085., 319540. }, 1.6916922798012188 },
+	{ 1, { 1602., -17457., 27667., -10914., 11558., -4357. },  },
+	{ 0, { -5880., 742., -5245., -7508., -2092., -3141. }, 1.7051957386154943 },
+	{ 0, { 1260., 203., 1855., 1795., 753., 722. }, 1.7137017697983383 },
+	{ 0, { -181., 118., 893., -230., 356., -133. }, 1.7715707154892435 },
+	{ 0, { 715., -2305., -3568., 635., -1416., 471. }, 1.7804397794409668 },
+	{ 0, { 100206., -23631., 4854., 93727., 818., 43069. }, 1.7946296659726320 },
+	{ 1, { 4224., -2685., 2729., -6839., 1031., -2737. },  },
+	{ 2, { 84., 2460., 356., -441., 163., -287. },  },
+	{ 0, { -3928., 2396., -1944., -4367., -655., -1968. }, 1.8082885005321963 },
+	{ 1, { -1281., -1070., 1425., -1360., 663., -508. },  },
+	{ 0, { -434., -572., -639., 581., -222., 273. }, 1.8824124715680111 },
+	{ 0, { 5875., -12921., -96., 9965., 681., 4780. }, 1.8981641851181350 },
+	{ 1, { 3309., -927., -4565., 1029., -1995., 584. },  },
+	{ 0, { -14234., 16692., -15551., -9091., -6255., -4365. }, 1.9094415371356366 },
+	{ 1, { -5299., -4657., 1995., -4393., 1032., -1732. },  },
+	{ 0, { -215., 526., -123., -7., -42., -32. }, 1.9243893317056575 },
+	{ 0, { -1607., 1027., -1015., -1384., -397., -623. }, 1.9690057130935361 },
+	{ 0, { 907., -182., 55., -552., -12., -217. }, 1.9888685259410335 },
+	{ 0, { 80093., 1775., -15336., 49616., -8505., 21779. }, 2.0075896690458515 },
+	{ 1, { 3675., 886., 9437., 1003., 3841., 302. },  },
+	{ 2, { -2718., 2441., 1312., 2111., 647., 750. },  },
+	{ 0, { -749., 2213., 3067., 2387., 1321., 864. }, 2.0177406604319246 },
+	{ 0, { 82., 445., -97., 12., -47., -15. }, 2.0452450030168667 },
+	{ 0, { 939., 145., -364., 1452., -175., 622. }, 2.0918668035808388 },
+	{ 0, { 29763., -11270., 1340., 26747., 35., 12241. }, 2.1052596067061962 },
+	{ 1, { -752., -10176., 11464., -2886., 4981., -1015. },  },
+	{ 0, { -122433., -1948247., 1789021., -131787., 769924., -8458. }, 2.1185267640432053 },
+	{ 1, { -14746., -2745., 3642., -14273., 1472., -6101. },  },
+	{ 2, { -1381., -4337., 4157., -766., 1816., -296. },  },
+	{ 0, { 207., 2382., -2373., 455., -1016., 119. }, 2.1318821280894955 },
+	{ 0, { 317., -2045., -1566., 2287., -544., 1086. }, 2.2071860619320218 },
+	{ 0, { 45591., -42445., 35109., 42326., 14234., 19311. }, 2.2209783021218397 },
+	{ 1, { 100., -868., 334., -2387., 63., -853. },  },
+	{ 2, { -274., 556., 48., -449., -11., -223. },  },
+	{ 0, { 347., -11., -113., -232., -65., -97. }, 2.3082627901909945 },
+	{ 0, { 16054., -5418., 3307., 5345., 1043., 2606. }, 2.3219886353180517 },
+	{ 1, { -19., -205., 4127., -783., 1741., -387. },  },
+	{ 2, { -647., 309., -95., 84., -24., 13. },  },
+	{ 0, { 2409., -2117., -2607., -228., -1170., 136. }, 2.4200734218253461 },
+	{ 1, { 19., -536., 414., 216., 214., 119. },  },
+	{ 0, { 2201., 3681., -3051., 2808., -1347., 1419. }, 2.4294275957278497 },
+	{ 0, { -423., 745., -737., -631., -315., -318. }, 2.4385609820738123 },
+	{ 0, { 300., -1484., -1399., 755., -530., 425. }, 2.5260130486716892 },
+	{ 0, { 5490., -1919., 480., 4689., 156., 2132. }, 2.5361042359568997 },
+	{ 1, { 215., -174., 275., -263., 81., -64. },  },
+	{ 0, { 308., -156., 185., 292., 82., 121. }, 2.5459330159552604 },
+	{ 0, { 5463., 46., 202., 1602., -48., 766. }, 2.6374295145352566 },
+	{ 1, { 581., 381., 1106., 451., 460., 165. },  },
+	{ 0, { -36662., -85712., 78236., -34663., 34443., -12759. }, 2.6481663000165407 },
+	{ 0, { 1477., -1072., -1320., -336., -622., -3. }, 2.7397040327703399 },
+	{ 0, { 1659., -2071., 2391., 2294., 963., 1120. }, 2.7490048220101793 },
+	{ 1, { -1336., -455., -28., -609., -7., -260. },  },
+	{ 0, { 1366., -1582., -496., 1101., -173., 602. }, 2.8494750099923127 },
+	{ 1, { 141., -92., 188., -517., 50., -205. },  },
+	{ 2, { -23., 180., 65., -168., 19., -81. },  },
+	{ 0, { 1495., 362., 78., -117., -5., -23. }, 2.9530548702113095 },
+	{ 1, { 107., 70., 510., 245., 223., 92. },  },
+	{ 0, { 497., -250., -298., -554., -148., -215. }, 3.0510128159210788 },
+	{ 0, { 602., -271., -371., 232., -153., 154. }, 3.1654820818460752 },
+	{ 0, { -3037., -3424., 3284., -2814., 1483., -1134. }, 3.1775127563235914 },
+	{ 0, { 483., 216., 36., -224., 1., -77. }, 3.2694305438716178 },
+	{ 0, { 4935., 381., -381., 4408., -298., 2013. }, 3.3406022698986924 },
+	{ 0, { 235., -159., -104., -386., -58., -142. }, 3.3695779911862527 },
+	{ 0, { 339., -47., -126., -82., -67., -13. }, 3.4790904552288531 },
+	{ 0, { -5663., -29987., 27509., -5003., 11933., -2162. }, 6.2830762443769794 },
+	{ 0, { -59., -82., -23., 24., -12., 18. }, 8.4686530580615642 },
+	{ 0, { -17635., 511., -921., -16011., 697., -7231. }, 10.2131290491330340 },
+	{ 0, { -227., 115., -23., -264., 11., -116. }, 10.2220725794374050 },
+	{ /* end jupiter */ -1,  },
+};
+
+chap95_rec chap95_saturn[] = {
+	{ 0, { 359537177., 0., -7206382337., 0., -2991243838., 0. }, 0. },
+	{ 1, { -20377631., 0., 15883341., 0., 8071624., 0. },  },
+	{ 0, { -64236683., -52860196., 142442224., -49744952., 58042432., -24365782. }, 0.0168745727060282 },
+	{ 0, { 30177751., 18129933., -67656128., 22849231., -27163043., 12315751. }, 0.0265670063186787 },
+	{ 1, { -8215259., 21212644., -23554648., -50768821., -12209063., -18901172. },  },
+	{ 0, { 1964057., 724735., -4686899., 1417179., -1646759., 941321. }, 0.0493811968866401 },
+	{ 1, { -134000., 3348965., -10011640., -8728398., -4234207., -2535628. },  },
+	{ 0, { 5686743., 3475773., -334368., 3091703., 72747., 926256. }, 0.0662237107929899 },
+	{ 0, { 554020., 1079938., -2966895., -1601162., -1509110., -278930. }, 0.0843726142307477 },
+	{ 0, { 4610964., 21987586., 31945199., -5263812., 13882828., -4598499. }, 0.1010129457774524 },
+	{ 0, { -66034588., -94070401., 111667599., -68387008., 47456033., -25071683. }, 0.1128014605528121 },
+	{ 1, { -4294328., -12886739., 37728596., -1754644., 11349347., 1748900. },  },
+	{ 0, { 6081642., 23561987., -38577166., -9734586., -12217167., -502775. }, 0.1245386660916166 },
+	{ 0, { -11635904., -19574871., 36907731., -11918213., 11119486., -6364841. }, 0.1376921108585382 },
+	{ 0, { 104499813., 75674727., -132241710., 152846005., -35848667., 59734045. }, 0.1532223867622918 },
+	{ 0, { -119336309., -65929841., 110429555., -174948245., 28176754., -66225503. }, 0.1635156403544941 },
+	{ 1, { 52564319., -48818442., 77555859., 94135021., 31177405., 26437148. },  },
+	{ 2, { 56660530., 23619473., -35687037., 84928050., -8020678., 31023884. },  },
+	{ 0, { 59047999., -9112158., 18208825., 74844916., 8173908., 26476289. }, 0.1849404508049137 },
+	{ 0, { -195085048., 130948239., -157301623., -207103141., -57416134., -80784650. }, 0.1994326216901347 },
+	{ 0, { 61319082350., -72972816459., 68513342186., 55646924765., 25657191842., 26113032275. }, 0.2133734516582497 },
+	{ 1, { 58897194., 107088220., -104901917., 68459614., -34345682., 47420026. },  },
+	{ 2, { -100212137., 21822222., -43604349., -89401596., -12674282., -32150723. },  },
+	{ 0, { 18845535., -49223999., 35615797., 26623302., 16402647., 15391365. }, 0.2335002178020494 },
+	{ 0, { -4180907., 4465884., 38621., -479609., 814285., -1219056. }, 0.2510310507212479 },
+	{ 1, { -18966213., 1413107., 11641634., -15116208., 6182492., -9256829. },  },
+	{ 0, { 3257184., 9509868., -11066286., -7321147., -6968557., -3079573. }, 0.2622227446243415 },
+	{ 0, { -1404116., -417364., 2858988., 1478988., 1856930., 162727. }, 0.2775489797512927 },
+	{ 0, { 1467706., 1107543., -4409004., 226468., -2199319., 678454. }, 0.2926511843672006 },
+	{ 0, { -63623237., -37507272., 39122548., -67696931., 18154709., -27796755. }, 0.3162439145857524 },
+	{ 1, { -3829645., 1269380., -9251051., -8961610., -4871745., -2487901. },  },
+	{ 2, { 1909651., 1468024., -7914338., 6203925., -2960534., 3971621. },  },
+	{ 0, { 6281876., -3642612., -4761114., 23447042., 286480., 12241212. }, 0.3340526064764550 },
+	{ 0, { -5802348., 5752123., -4991225., -30347977., -5911367., -14358380. }, 0.3467225133858732 },
+	{ 0, { 7539581., -27234846., 89254406., 72087653., 50683522., 25464083. }, 0.3654342931118227 },
+	{ 1, { -16970597., 906805., 25342361., -65544284., 5459306., -34110644. },  },
+	{ 2, { -5198192., 11224087., -33200716., -38195205., -20121188., -14873633. },  },
+	{ 0, { -2145161., 31156404., -111624554., -59422928., -60033284., -17237400. }, 0.3766625707476834 },
+	{ 0, { -2433702., -8759560., 35127703., 5461246., 17518688., -795950. }, 0.3868793178145906 },
+	{ 0, { 3948221., 3250926., -14710717., 6016597., -6668684., 4126312. }, 0.4021189702952532 },
+	{ 0, { -64852219., -1152783., 37078116., -78426047., 17075754., -36402504. }, 0.4173317886569649 },
+	{ 0, { 2598837096., -322512661., 333925850., 2403155625., 25718615., 1008149551. }, 0.4268085445169599 },
+	{ 1, { -8046615., 50513333., -65775281., -14855286., -30373245., -5862741. },  },
+	{ 0, { 14632122., -1627420., 391595., 27967394., 1503248., 13109492. }, 0.4393540871607130 },
+	{ 0, { -3977607., 2348335., -4492336., -11638695., -3044963., -5280793. }, 0.4516261147924168 },
+	{ 0, { 3891847., -6235742., 13257786., 12849113., 7381680., 5287411. }, 0.4647357720725654 },
+	{ 0, { -2681944., 5714068., -11275550., -8345687., -6000449., -3297402. }, 0.4765294470438712 },
+	{ 1, { -3310032., -1656488., 6283436., -7934719., 2454880., -4374462. },  },
+	{ 2, { 581001., -2310426., 4449727., 1912796., 2258154., 644572. },  },
+	{ 0, { -543181., 190668., 100357., -477814., 102237., -296580. }, 0.4992649823773071 },
+	{ 0, { 734019., 40318., 205332., 241668., 50065., 172083. }, 0.5130863461740709 },
+	{ 0, { 34991657., -27811324., 27384011., 28671165., 10659597., 13066000. }, 0.5295353231453532 },
+	{ 1, { -995667., 165111., 1788489., 16637., 818086., -43110. },  },
+	{ 2, { -317358., -198759., -6708., 263693., 27631., 133736. },  },
+	{ 0, { -31862., -65198., 73955., 29129., 36339., 15797. }, 0.5497097571860546 },
+	{ 0, { -4929., 225052., -215444., -8168., -89868., -12808. }, 0.5633695884286543 },
+	{ 0, { 24691., 22218., -9270., 18179., -4474., 5589. }, 0.5991350601911121 },
+	{ 0, { 289471., 202198., -100019., 60710., -58404., 1113. }, 0.6158926177569189 },
+	{ 1, { 99636., -158087., 49023., 12201., 5200., 13036. },  },
+	{ 0, { -1368816., -1646305., 699872., -1449808., 365729., -462486. }, 0.6277831102482128 },
+	{ 0, { 86066856., 61934875., -56200895., 80007767., -26961118., 30372088. }, 0.6401904307430363 },
+	{ 1, { -1903624., 1069032., -956603., -1766047., -334714., -771306. },  },
+	{ 2, { 388212., 231504., -217129., 594559., -86428., 243060. },  },
+	{ 0, { 806222., 541401., -454902., 1046875., -196326., 413041. }, 0.6510631728715514 },
+	{ 0, { -45865., -22253., 10036., -80738., 2915., -31853. }, 0.6610474418282967 },
+	{ 0, { 7873., 2358., 3189., 5877., 1281., 2008. }, 0.6837277548947647 },
+	{ 0, { -98664., 39992., -40413., -90837., -12525., -38879. }, 0.7043645359718698 },
+	{ 0, { -1946., 3664., 10236., -357., 4293., -1167. }, 0.7177278015736290 },
+	{ 0, { -284513., 3015890., 2554237., 521699., 1046024., 49179. }, 0.7348232721925007 },
+	{ 1, { 192624., 52403., 33461., -150025., -105., -61152. },  },
+	{ 0, { -574265., -320413., 457058., -572461., 214214., -240685. }, 0.7435248864377025 },
+	{ 1, { 1145., -36334., 41717., 108651., 15647., 49114. },  },
+	{ 0, { 4558., -12170., 12006., 2809., 4790., 1802. }, 0.7636282240814432 },
+	{ 0, { -13700., 9256., -10447., -12051., -3998., -5133. }, 0.7781708314331308 },
+	{ 0, { 2247., -693., 1592., 1083., 680., 202. }, 0.7950594399751412 },
+	{ 0, { -1275., 5493., -6655., 924., -2492., 1116. }, 0.8129117802019118 },
+	{ 0, { -1223., -19571., 23014., -16306., 6735., -10155. }, 0.8251778324059539 },
+	{ 0, { 303076., 327040., 524629., -601728., 145475., -284414. }, 0.8382097667143232 },
+	{ 1, { -68015., 68576., -104282., -95123., -56039., -18028. },  },
+	{ 0, { 804121., 5204866., -4807644., 856208., -2083791., 112505. }, 0.8530682323228537 },
+	{ 1, { 29622., -215766., 182882., 33800., 76379., -13007. },  },
+	{ 0, { -13943., 51584., -40954., -8800., -23024., -3606. }, 0.8654403493251860 },
+	{ 0, { 3328., -7556., 4381., 1661., 2910., -36. }, 0.8766682028622256 },
+	{ 0, { -1505., 1631., -856., 784., -507., 674. }, 0.8895787094971168 },
+	{ 0, { -7919., -1616., 1989., -5290., 1264., -2147. }, 0.9133756947048002 },
+	{ 0, { -719., -2923., 1034., -5631., 504., -2040. }, 0.9236279354499169 },
+	{ 0, { 235224., 39046., -67004., -248093., -51203., -88317. }, 0.9453092341234691 },
+	{ 1, { 23462., -3456., -13540., 1977., -2121., 4776. },  },
+	{ 2, { -14574., -833., 1399., 12342., 2166., 4371. },  },
+	{ 0, { -26186., -43172., 35585., -24094., 17801., -8640. }, 0.9587102428763801 },
+	{ 0, { 5306., 3426., -2598., 4654., -1521., 1836. }, 0.9687040706037242 },
+	{ 0, { -1404., -1568., 973., -1250., 478., -476. }, 0.9844044794489883 },
+	{ 0, { 710., 549., -640., -936., -297., -397. }, 1.0125530865194814 },
+	{ 0, { -4798., 528., 2241., 2772., 1073., 1027. }, 1.0243303434648821 },
+	{ 0, { 19204., -11735., -10052., -9127., -4600., -2887. }, 1.0350677988213037 },
+	{ 0, { -70967., 104737., 71732., 36807., 31189., 9485. }, 1.0444890430562743 },
+	{ 0, { -225798., 798684., 944928., 428637., 404105., 131989. }, 1.0535670598935039 },
+	{ 0, { 421437., -821624., 460671., 296203., 193979., 145015. }, 1.0624723083698995 },
+	{ 1, { 404141., 190563., -153412., 239290., -77801., 95534. },  },
+	{ 0, { -6822., -2424., -12141., -503., -4568., -254. }, 1.0799687683920178 },
+	{ 0, { 5231., 2124., 4765., -2411., 1681., -1002. }, 1.0944898935961935 },
+	{ 0, { -4360., -571., -2843., 2544., -920., 1015. }, 1.1034700208578079 },
+	{ 0, { 2352., -783., 1220., -2044., 355., -732. }, 1.1190075299813413 },
+	{ 0, { -5735., 3169., 186., 5121., 420., 1436. }, 1.1356439922218147 },
+	{ 0, { 26551., -30281., 5089., -56530., 4098., -12591. }, 1.1476494842799982 },
+	{ 0, { 182096., 230606., 190305., 20362., 32484., -34547. }, 1.1561539197957733 },
+	{ 1, { -46354., -35766., 25278., 21603., 6113., 24924. },  },
+	{ 2, { -6693., -10691., -762., -24972., 5267., -3607. },  },
+	{ 0, { 7509., -14080., 2266., 4828., -2812., 2396. }, 1.1724975800169239 },
+	{ 0, { -1097., 4594., -221., -711., 861., -846. }, 1.1827508062529084 },
+	{ 0, { 268., -1663., 197., 151., -139., 350. }, 1.1922546935063294 },
+	{ 0, { 3821., -6929., -9691., -9738., -1997., -3976. }, 1.2526642649376578 },
+	{ 1, { -3679., 2852., -872., 4458., -151., 647. },  },
+	{ 0, { 103288., 30887., 44394., -80994., 5313., -31354. }, 1.2615381418438327 },
+	{ 0, { 11722., -929., 20555., -32545., 6476., -10964. }, 1.2737411543354145 },
+	{ 0, { -17778., 2234., -8752., -2076., -2194., -1934. }, 1.2848042137871682 },
+	{ 1, { -807., -10464., -4345., -4583., -776., -1210. },  },
+	{ 0, { -2021., 243., -476., 1775., -175., 485. }, 1.2966706439177036 },
+	{ 0, { -414., 1251., 1334., 193., 402., 122. }, 1.3428511130177547 },
+	{ 0, { -6545., 29273., 20095., -2836., 7521., 1278. }, 1.3563973340863262 },
+	{ 1, { 13556., 3272., -1197., -10568., 545., -3663. },  },
+	{ 0, { -180708., 208447., 210704., 176234., 95276., 55650. }, 1.3681253803708262 },
+	{ 1, { 18503., 8458., -1041., -19835., 212., -7272. },  },
+	{ 2, { -2022., 9714., 3806., 25., 1699., 1106. },  },
+	{ 0, { 967., -692., -12., -1766., -76., -677. }, 1.3856345885533017 },
+	{ 0, { 704., -587., -2388., 1139., -927., 144. }, 1.4516885121122214 },
+	{ 0, { -2400., 3304., 8864., -6463., 3877., -1185. }, 1.4602508651959594 },
+	{ 0, { 69982., 97834., 73391., 17685., 16742., -10304. }, 1.4727239692395073 },
+	{ 1, { -11044., -13056., 19308., 14020., 3724., 10827. },  },
+	{ 2, { -6082., -426., 3637., -7457., 3010., -854. },  },
+	{ 0, { 2590., -1868., 1096., 1043., -731., -69. }, 1.4872423683478513 },
+	{ 0, { -938., 62., 121., -521., 280., -164. }, 1.4985129994148070 },
+	{ 0, { 1803., 2377., 1110., -3335., 260., -1477. }, 1.5652937634682971 },
+	{ 0, { 64498., -5114., 68142., -30202., 22032., -11748. }, 1.5815555196973523 },
+	{ 1, { -22825., 4620., 14325., -12393., 6615., -5873. },  },
+	{ 2, { -7166., 4559., -5012., 2048., -1874., 652. },  },
+	{ 0, { -2200., -10219., 11039., 3346., 4934., 1509. }, 1.5955514308541998 },
+	{ 0, { 1099., 1374., -2363., -260., -1043., -86. }, 1.6049203503395801 },
+	{ 0, { -1208., -104., 561., 969., 230., 560. }, 1.6737223157218182 },
+	{ 0, { -86480., 70728., 67924., 86008., 31534., 31153. }, 1.6843589552967209 },
+	{ 1, { 933., 1492., 4350., -2566., 1516., -847. },  },
+	{ 2, { -1244., -445., -70., 369., 72., 345. },  },
+	{ 0, { 1465., -2624., 397., -65., -76., -7. }, 1.6977622139834585 },
+	{ 0, { 14992., 53026., 36206., 5674., 12375., -4229. }, 1.7889276713056903 },
+	{ 1, { -1089., -6208., 2064., 7721., -744., 4049. },  },
+	{ 2, { -1281., -2343., -210., 276., 49., 532. },  },
+	{ 0, { 3295., -4264., -3112., 6622., -2534., 1159. }, 1.8013654629975304 },
+	{ 1, { 1876., 442., -2702., -870., -615., -793. },  },
+	{ 0, { 21586., 22255., 25169., -13704., 7397., -6814. }, 1.8952695349759525 },
+	{ 1, { 1293., 636., 1855., -2161., 651., -493. },  },
+	{ 2, { -1508., -959., -1185., 1162., -341., 540. },  },
+	{ 0, { -837., -468., -77., 639., 49., 332. }, 1.9082748451618770 },
+	{ 0, { -39181., 17943., 18554., 39996., 9033., 15315. }, 2.0006786235742782 },
+	{ 1, { 70., 479., 1963., -746., 664., -147. },  },
+	{ 2, { -729., 4., -323., -76., -29., 30. },  },
+	{ 0, { -726., 389., 1661., 467., 647., 367. }, 2.0949703642270960 },
+	{ 0, { -2813., 21512., 16741., 5023., 6930., 302. }, 2.1045989992211052 },
+	{ 0, { 6314., -196., -4305., 3407., -2614., -923. }, 2.1133294411524268 },
+	{ 0, { -1183., -1102., 1934., -946., 1020., -24. }, 2.1218152921149840 },
+	{ 0, { 7013., 13819., 14243., -3085., 4615., -2198. }, 2.2116085451863530 },
+	{ 1, { 548., 591., 1334., -724., 439., -127. },  },
+	{ 2, { -499., -647., -721., 383., -233., 184. },  },
+	{ 0, { -96., -348., -69., 163., -3., 83. }, 2.2246966026380783 },
+	{ 0, { -16878., 3417., 3609., 17709., 2011., 6948. }, 2.3169860146393306 },
+	{ 1, { -184., 273., 1066., -86., 376., 65. },  },
+	{ 2, { -421., -143., -106., -9., 9., 50. },  },
+	{ 0, { -1773., 10467., 5877., 4502., 2612., 236. }, 2.4212184393363345 },
+	{ 1, { 100., -1698., -212., 1585., -581., 698. },  },
+	{ 2, { -416., -532., 192., 38., 49., 218. },  },
+	{ 0, { 922., 6585., 6161., 638., 2178., -274. }, 2.5279051498015881 },
+	{ 1, { 305., 668., 969., -324., 338., -92. },  },
+	{ 0, { -7788., -691., -557., 7570., 62., 3142. }, 2.6333307376329276 },
+	{ 1, { -16., 174., 511., 158., 148., 85. },  },
+	{ 0, { -2797., 3622., 2705., 2693., 1341., 812. }, 2.7374368855151237 },
+	{ 0, { 1332., 523., -1008., -331., -394., -592. }, 2.7462646949156313 },
+	{ 0, { -528., 3192., 2851., 1151., 1069., 178. }, 2.8441606111313287 },
+	{ 1, { 54., 266., 527., 58., 138., 54. },  },
+	{ 0, { -3128., -1136., -1090., 3069., -358., 1285. }, 2.9496547906250985 },
+	{ 0, { -1332., 1366., 789., 1313., 449., 356. }, 3.0553439327040071 },
+	{ 1, { 46., -504., -405., 221., -232., 58. },  },
+	{ 0, { -722., 1469., 1417., 916., 574., 235. }, 3.1603882818225530 },
+	{ 1, { -8., 210., 314., 24., 105., 6. },  },
+	{ 0, { -1228., -704., -610., 1193., -210., 520. }, 3.2660150757959667 },
+	{ 0, { 4966., 349., -230., 4527., -271., 2058. }, 3.3406700896158381 },
+	{ 0, { -1003., 494., 345., 782., 229., 294. }, 3.3700954272546491 },
+	{ 0, { -642., 504., 417., 592., 188., 175. }, 3.4766263286125869 },
+	{ 0, { -5495., -30050., 27370., -5109., 11883., -2182. }, 6.2830758491321381 },
+	{ 1, { 12., 3., -21., -32., -16., -11. },  },
+	{ 0, { -127., 83., -47., -145., -13., -74. }, 8.4563910900857575 },
+	{ 0, { -17655., 888., -832., -16055., 726., -7281. }, 10.2133651230379790 },
+	{ 1, { -15., -178., 73., 27., 40., 18. },  },
+	{ 0, { 10., 56., 204., -33., 91., -14. }, 10.2233419556680150 },
+	{ /* end saturn */ -1,  },
+};
+
+chap95_rec chap95_uranus[] = {
+	{ 0, { 13442911073., 0., -1930919457., 0., -1035250405., 0. }, 0. },
+	{ 1, { 54660667., 0., 47196247., 0., 21339801., 0. },  },
+	{ 0, { -6259970., -59715827., 56026092., -14879299., 23598892., -7731463. }, 0.0168745727060282 },
+	{ 0, { 5314993., 24095734., -17644181., 11961180., -6018215., 6587969. }, 0.0271621114651946 },
+	{ 0, { 816977., 27548111., -6448076., -468658., -4057252., -1448251. }, 0.0379771556339559 },
+	{ 0, { -1624242., 11338144., -20621799., 1496992., -5688694., 248222. }, 0.0558181533535525 },
+	{ 0, { 131350139561., 139711771423., -127221614269., 120945393838., -57589414088., 51010747052. }, 0.0747869939016385 },
+	{ 1, { 83579181., -50475439., 18032923., 50477352., 27217847., 30911037. },  },
+	{ 2, { 56177356., -62348507., 45006161., 56816875., 23394627., 20236290. },  },
+	{ 0, { -3192217., -67613872., 26532975., 31518890., 20804461., -5888651. }, 0.0851607526391989 },
+	{ 0, { 41246376., 168261887., -122401100., -97532527., -40313762., 5947933. }, 0.1076082382556661 },
+	{ 0, { -36235133., -140754409., 98201785., 64357246., 36255198., -9379330. }, 0.1131136321134916 },
+	{ 1, { 90255544., -46394994., -47508423., 75649120., 8064423., 19668708. },  },
+	{ 0, { -32042356., -21687295., 28029568., 15213468., 1662570., -3156568. }, 0.1256919464048962 },
+	{ 0, { 44969984., -2310664., -13084603., 20841905., 1428192., 12115421. }, 0.1384460864609660 },
+	{ 0, { -524718966., -4511367463., 4156633821., -484927968., 1817662129., -148236372. }, 0.1495664992280332 },
+	{ 0, { 61267776., 1565740., -24266489., 45519765., -3901964., 18298390. }, 0.1552897599647365 },
+	{ 0, { -7222268., 4911333., 3283374., -6377102., -254066., -1537379. }, 0.1694039594031046 },
+	{ 0, { 5873930., -4900474., -1827803., 7852582., -31798., 1819946. }, 0.1845250832150644 },
+	{ 0, { 1077339., 18380396., -901066., -10767827., -265560., 162663. }, 0.2002468734837309 },
+	{ 0, { -154311950., -219502970., 131091842., 178959446., 20655458., 5719299. }, 0.2141097583453364 },
+	{ 0, { -5528333., 212500368., -111109179., -139612191., -43337512., -21342579. }, 0.2193685795401007 },
+	{ 1, { -104517351., 177302072., 101064024., -75975513., -8816707., 3791842. },  },
+	{ 0, { 173653756., 151082404., -200861767., -135511564., -29950212., -17024507. }, 0.2293024101260499 },
+	{ 0, { -125918181., -44661266., 113832135., 56003631., 10092584., 6332126. }, 0.2359817391381943 },
+	{ 0, { 47624832., 2554277., -41914694., -13040594., -2759654., -2423818. }, 0.2431604796510437 },
+	{ 0, { -8805576., 2810717., 8600588., 666061., 636138., 663527. }, 0.2535948403663328 },
+	{ 0, { 1249271., -2422256., -2280787., 1243851., -81187., -241977. }, 0.2733943804314553 },
+	{ 0, { 90677., 14160054., 8529623., -8138579., 1686982., 1494393. }, 0.2885148535115661 },
+	{ 0, { 1004449., -20392040., -8104371., 18545176., -2778508., 705194. }, 0.2992461358046305 },
+	{ 1, { 5543727., 3362260., -1567031., -3163455., 585366., 471498. },  },
+	{ 2, { 2655788., 6883407., 3736665., -5070470., 1464904., 724248. },  },
+	{ 0, { 6192631., 6484479., 3731891., -6957619., 2642135., 445342. }, 0.3105692746147310 },
+	{ 0, { -1442546., -845134., -640944., 1375084., -614517., 35173. }, 0.3190867931520337 },
+	{ 0, { 683659., 282897., 363207., -694577., 243073., -261582. }, 0.3384589317094125 },
+	{ 0, { 210243., 95767., -88268., -40253., -126237., -71385. }, 0.3483018025771290 },
+	{ 0, { -122260., -61161., 139582., -75155., 89557., -59104. }, 0.3543646679104152 },
+	{ 0, { -341621., -166635., -6649., -236115., -4011., -98828. }, 0.3749354720310226 },
+	{ 0, { -34509., -47428., -33958., 69865., -15389., 28074. }, 0.3881544744399507 },
+	{ 0, { 127606., 82441., 63875., -131276., 30216., -55026. }, 0.4044642096018178 },
+	{ 0, { -55719., 35282., 53204., 42166., 20409., 8040. }, 0.4146735688956036 },
+	{ 0, { 745574., -86708., 85642., 660718., 2349., 278769. }, 0.4267276978319757 },
+	{ 0, { 46965., -63806., -140582., -2689., -51451., -6263. }, 0.4523712047583937 },
+	{ 1, { -44676., -29125., -21496., 62165., -11514., 20667. },  },
+	{ 0, { -47313., 131228., 153909., 13721., 54937., 13501. }, 0.4584750578982092 },
+	{ 0, { 64299., -217224., -204896., -47815., -89991., -26071. }, 0.4786471499447322 },
+	{ 0, { -216., 53443., -19130., -71538., -27839., -11228. }, 0.4920510287505367 },
+	{ 0, { -151224., -75735., -3305., 268854., -6542., 67361. }, 0.5051499531573665 },
+	{ 0, { 928196., 102377., -314167., -1414544., -33869., -402228. }, 0.5147029966036326 },
+	{ 0, { -1724399., 110969., 999802., 2605327., 184425., 789530. }, 0.5199630930448305 },
+	{ 0, { 40911206., -27399316., 26874089., 37399873., 10439229., 16767175. }, 0.5296669053399393 },
+	{ 1, { 583136., 1214598., 1755827., -1272416., 584159., -311166. },  },
+	{ 0, { 1173041., -1074191., -1886355., -1719260., -508991., -616258. }, 0.5369668320738028 },
+	{ 0, { -202800., 314145., 489969., 260218., 136957., 100165. }, 0.5445620632918582 },
+	{ 0, { 30834., -64556., -105954., -37083., -35677., -17746. }, 0.5559973222735549 },
+	{ 0, { 388., 18963., 34845., -2990., 13141., -175. }, 0.5645354635177183 },
+	{ 0, { -3029., -2222., -3901., 4299., -1477., 1512. }, 0.5864917785646289 },
+	{ 0, { 364., -3970., 4198., -17799., 1736., -7653. }, 0.6024030347783642 },
+	{ 0, { -64408., -16238., -14709., 52293., -7099., 22267. }, 0.6155618610057497 },
+	{ 0, { -8702., 7365., -847., 28860., 2496., 17960. }, 0.6266278765065182 },
+	{ 0, { 37681., 20807., -24633., 19631., -10642., 8265. }, 0.6366292306281224 },
+	{ 0, { 3191., 5638., -2365., 9854., -1386., 3658. }, 0.6449290790303238 },
+	{ 0, { -5177., -823., -2003., 5908., -949., 2341. }, 0.6763170666119763 },
+	{ 0, { -3638., 10059., 7207., 4377., 3151., 2651. }, 0.6862778987939261 },
+	{ 0, { 11748., -14352., -13920., -7897., -5625., -2944. }, 0.6979445752019332 },
+	{ 0, { -8438., 12018., 9236., 3586., 3477., 1505. }, 0.7048114577856822 },
+	{ 0, { 1834., -5463., -4042., -1281., -1755., -771. }, 0.7111948880743650 },
+	{ 0, { -4692., -8326., -4750., 8084., -2967., 3594. }, 0.7473196860221153 },
+	{ 0, { 4040., 13701., 10942., -11503., 6915., -5226. }, 0.7526899558709467 },
+	{ 0, { 22865., -59285., -48182., -15767., -20987., -6907. }, 0.7617757396112786 },
+	{ 1, { 3873., 1796., -260., -5778., -1031., -4126. },  },
+	{ 0, { 272., -668., 1897., 1033., 987., 184. }, 0.7769058037180200 },
+	{ 0, { -2176., 7071., 5492., 2930., 2571., 1313. }, 0.8199388514022748 },
+	{ 0, { -184998., 97937., 88915., 171155., 41794., 73600. }, 0.8350541004724259 },
+	{ 1, { -197., -3126., -715., 1748., -208., 825. },  },
+	{ 0, { -5824., 1942., -2170., -8871., -927., -3596. }, 0.8453935583217296 },
+	{ 0, { 252., 2148., -787., 1499., -241., 459. }, 0.8551127263577434 },
+	{ 0, { 3107., 6817., 10906., 19., 4504., -914. }, 0.8879713761393457 },
+	{ 0, { 6532., -6647., -8432., -9470., -3566., -3649. }, 0.8938517525956896 },
+	{ 1, { 2415., -4253., -3554., -6203., -2191., -2419. },  },
+	{ 0, { -3926., 523., -5326., 11396., -2537., 5007. }, 0.9076103122110721 },
+	{ 0, { 1486., 6143., -4417., -1583., -1883., -794. }, 0.9528977392964432 },
+	{ 0, { 1226., -908., 2507., -1706., 1029., -874. }, 0.9646777216958613 },
+	{ 0, { -11300., -22605., 26258., -9349., 12130., -5605. }, 0.9849512095278805 },
+	{ 1, { 1457., -2630., 860., 1293., 487., 641. },  },
+	{ 2, { -685., -2643., -646., -848., -225., -318. },  },
+	{ 0, { -2190., -3253., -891., -1611., -317., -665. }, 0.9964090016851210 },
+	{ 0, { -1179., -3116., -2763., 1595., -1346., 737. }, 1.0352639155374268 },
+	{ 0, { 7916., 3274., -3481., 4472., -1826., 2498. }, 1.0515675436820877 },
+	{ 0, { 697761., -973027., 901279., 634785., 369311., 295489. }, 1.0592810372818169 },
+	{ 1, { -1426., -5270., 2981., -566., 1562., -288. },  },
+	{ 0, { -1789., 2512., -1045., -777., -493., -461. }, 1.0720350844573199 },
+	{ 0, { 3343., -1231., -1017., -2862., -464., -1223. }, 1.1429483332496098 },
+	{ 0, { 11373., -2498., -1580., 8748., -883., 3741. }, 1.1609636069979286 },
+	{ 1, { -1522., -2635., 28., 1104., -15., 464. },  },
+	{ 0, { -1975., 3205., 2553., 2452., 995., 1112. }, 1.1691873087779718 },
+	{ 0, { -9107., -5910., -5019., 8600., -1999., 3899. }, 1.2152142837985198 },
+	{ 1, { -4., -1508., -1102., -242., -397., -127. },  },
+	{ 0, { -1971., 699., -3., 1482., -78., 551. }, 1.2226982614159414 },
+	{ 0, { -31., -206., 25., 63., 54., 23. }, 1.2355263592688024 },
+	{ 0, { 2581., 7563., 7150., -2433., 3120., -1128. }, 1.2857063346850945 },
+	{ 1, { 1638., -740., -410., -2267., -163., -1002. },  },
+	{ 0, { 6494., 16800., 14424., -5912., 6217., -2861. }, 1.2908372220692612 },
+	{ 0, { -2870., 4014., 4972., 2882., 2300., 1194. }, 1.3652019003010083 },
+	{ 1, { 121., -268., -412., 87., -162., 47. },  },
+	{ 2, { 204., -295., -187., 24., -76., 9. },  },
+	{ 0, { -3114., 953., -618., -2692., -475., -1304. }, 1.4390426416344881 },
+	{ 0, { 643., 554., -351., 588., -171., 247. }, 1.4790740463977397 },
+	{ 0, { 470., -497., -239., -9., -101., -35. }, 1.5778081754901920 },
+	{ 0, { 12015., -42122., 38323., 10981., 16121., 5766. }, 1.5889777636732787 },
+	{ 1, { -377., -28., -105., 615., -60., 248. },  },
+	{ 2, { -102., -86., -77., -32., -33., -28. },  },
+	{ 0, { -1329., 1696., 1422., 1073., 644., 441. }, 1.6698689170399983 },
+	{ 0, { 653., -443., 76., 737., 22., 321. }, 1.6917823552881666 },
+	{ 0, { 4010., -973., -776., -3727., -389., -1621. }, 1.7447101363840591 },
+	{ 0, { 796., 753., 911., -908., 375., -434. }, 1.8195524075201825 },
+	{ 0, { -67., 529., -320., 151., -164., 92. }, 1.8944084825549634 },
+	{ 0, { 10., -1636., 1676., -13., 718., 43. }, 2.1173586606692205 },
+	{ 0, { -176., -699., -800., 57., -346., 33. }, 2.1995558975407743 },
+	{ 0, { 4804., 493., -302., 4547., -271., 2069. }, 3.3406137564373255 },
+	{ 1, { -37., 63., -60., 6., -25., 5. },  },
+	{ 0, { -6127., -30327., 27236., -5550., 11893., -2472. }, 6.2830758108542479 },
+	{ 1, { 13., 96., 24., 144., -4., 74. },  },
+	{ 2, { 94., 86., 39., 73., 3., 45. },  },
+	{ 0, { -103., 11., 317., -154., 157., -57. }, 8.4710588767699999 },
+	{ 0, { -1072., -875., 799., -1217., 416., -503. }, 10.1988027176192690 },
+	{ 0, { -7126., 105., -353., -6736., 285., -3012. }, 10.2074359814049150 },
+	{ 1, { -735., 3920., -3778., -636., -1657., -531. },  },
+	{ 0, { -9779., 1441., -1464., -8409., -23., -3858. }, 10.2156685960931930 },
+	{ /* end uranus */ -1,  },
+};
+
+chap95_rec chap95_neptune[] = {
+	{ 0, { -2753381808., 0., -2555187184., 0., -977694282., 0. }, 0. },
+	{ 1, { -53706852., 0., 9024894., 0., 5113590., 0. },  },
+	{ 0, { 5353414., 16329756., -10315608., -18211298., -4313685., -7909387. }, 0.0179617912970447 },
+	{ 0, { -19054385., -287482557., 282900211., 40600685., 114409567., 24195009. }, 0.0323644369574163 },
+	{ 0, { 171759338654., 246707191188., -226959547603., 161070501549., -97171931583., 59786666580. }, 0.0381185507042915 },
+	{ 0, { 269128284., 157897034., -86709918., 293605458., -39838078., 115245563. }, 0.0449423189622218 },
+	{ 0, { -93736103., -37825790., -26561507., -91732038., -9592733., -35920288. }, 0.0600427026897851 },
+	{ 0, { 178516553., 51475281., 124180124., 108331691., 49005129., 40587728. }, 0.0705779080356058 },
+	{ 0, { -1684231243., 681665499., -958998993., -1353650791., -355010040., -565296249. }, 0.0772675784146183 },
+	{ 0, { 1122264068., -578428299., 1063564939., 463713621., 414676760., 190864744. }, 0.0843726142307477 },
+	{ 0, { -781685034., 475952164., -808860716., -228929931., -316705638., -94548544. }, 0.0871507153151969 },
+	{ 0, { 56385979., -39979207., 64276567., 7694958., 25352958., 3214483. }, 0.1012471242645664 },
+	{ 1, { 63310243., 43285497., 22448880., 66731902., 8926250., 26309541. },  },
+	{ 0, { 2712359., -37080616., 26122509., -21572378., 10482381., -8529034. }, 0.1128959119291703 },
+	{ 0, { 1376659., 7176921., -1442553., 7206580., -479409., 2921144. }, 0.1246811309098641 },
+	{ 0, { -2552808., -3146754., -931704., -4559708., -491329., -1812338. }, 0.1349961443322037 },
+	{ 0, { 1162812., 462968., 719939., 2310847., 376498., 885784. }, 0.1402125408882514 },
+	{ 0, { -252283., -142326., -110247., -49287., -46731., -28945. }, 0.1616161402063230 },
+	{ 0, { 243162., -91598., 106479., 16854., 55597., 8501. }, 0.1776262925892778 },
+	{ 0, { -672251., 231673., -319786., 386301., -155882., 135214. }, 0.1904084544956719 },
+	{ 0, { 1867133., -1866896., 239943., -1803069., 228227., -732880. }, 0.2026926199831023 },
+	{ 0, { 32066276., -61274160., 6958960., -9094869., 4399306., -3854675. }, 0.2132050927412489 },
+	{ 1, { -11587231., -5526999., -7458452., 2330330., -3274130., 322813. },  },
+	{ 0, { -16700375., 45567407., 14051147., 28126677., 3238872., 12733553. }, 0.2160078733553654 },
+	{ 0, { 601249., -3740179., -1686685., -1590049., -510731., -804485. }, 0.2225065497464809 },
+	{ 0, { 71272., 256103., 179344., -10427., 65192., 15214. }, 0.2362432045351159 },
+	{ 0, { -58547., -82547., -51318., 58153., -20501., 15047. }, 0.2470536247773912 },
+	{ 0, { -6723., 19924., 26278., 12439., 9453., 3700. }, 0.2721326326759872 },
+	{ 0, { -3710., 4976., -7051., 254., -1464., 195. }, 0.2834391769690069 },
+	{ 0, { -12572., -6375., 5687., 15436., 615., 5233. }, 0.2938091870567225 },
+	{ 0, { -14716., 204103., 159833., 45074., 65416., 11053. }, 0.3117802888037338 },
+	{ 0, { -17577., 42568., 85327., -50768., 36610., -17999. }, 0.3148973170728874 },
+	{ 0, { -12308., -4224., -5418., 20456., -3011., 7048. }, 0.3237199721077774 },
+	{ 0, { -453., 863., 3006., -1602., 798., -820. }, 0.3434014414974197 },
+	{ 0, { -4296., 775., 4295., 2013., 1131., 245. }, 0.3679427772208049 },
+	{ 0, { 2844., 8238., -10394., 16799., -2798., 8324. }, 0.3785701069003719 },
+	{ 0, { -12477., -18952., 16324., -32949., 3954., -15266. }, 0.3833769854125967 },
+	{ 0, { -22365., 128., 5047., -4988., 1724., -1653. }, 0.3921552738853996 },
+	{ 0, { 4383., -6090., 178., -7672., -722., -3343. }, 0.4052046013289639 },
+	{ 0, { 714788., -68799., 122150., 736324., 10410., 310430. }, 0.4266933782608374 },
+	{ 1, { 12121., 14734., 49080., -28648., 20910., -8012. },  },
+	{ 0, { 46510., -21693., -58299., -84149., -12783., -39407. }, 0.4328778616668182 },
+	{ 0, { -18771., 8624., 16635., 18600., 2724., 10462. }, 0.4397536016965201 },
+	{ 0, { 3796., -9377., -6884., 415., -1798., -1014. }, 0.4503999814583104 },
+	{ 0, { -7089., 1370., -2220., 4940., -839., 2525. }, 0.4636405151525668 },
+	{ 0, { 5125., -1762., 2170., -4527., 631., -2166. }, 0.4745702135817129 },
+	{ 0, { 36688., -1584., -8174., -32426., -3946., -13037. }, 0.4886034832877044 },
+	{ 0, { -5607., 1955., 1641., 547., 484., -201. }, 0.5046352473687760 },
+	{ 0, { 45109., -21568., 12616., 26255., 6182., 12720. }, 0.5178003462986053 },
+	{ 0, { 40893658., -28000813., 26124943., 37354584., 10197353., 16693506. }, 0.5296623039564303 },
+	{ 1, { -21062., -35782., 31769., -20330., 15353., -11834. },  },
+	{ 2, { 10720., 5927., -12424., -538., -3613., -359. },  },
+	{ 0, { -28607., 23386., -38172., -43627., -12236., -20256. }, 0.5403804874893231 },
+	{ 0, { 66., 635., 4597., 3533., 1279., 1843. }, 0.5486365851140401 },
+	{ 0, { -1646., 2776., -3727., -1793., -1436., -354. }, 0.5631942288095021 },
+	{ 0, { -353., 460., 306., -526., 107., -133. }, 0.5739537566607668 },
+	{ 0, { -48., -518., 599., -406., 229., -183. }, 0.6031743297859348 },
+	{ 0, { -230., -43., -65., 493., -36., 204. }, 0.6175060453479511 },
+	{ 0, { 19445., 2550., -25130., 13108., -10967., 5418. }, 0.6333639350967218 },
+	{ 0, { 13473., 21421., -1023., 17345., -1204., 6355. }, 0.6373233385189475 },
+	{ 1, { 864., -8826., 6444., 11189., 2532., 4949. },  },
+	{ 0, { 1578., 3023., 2194., 1035., 836., 338. }, 0.6488504417528818 },
+	{ 0, { -3340., -7100., -6757., 2738., -2684., 1301. }, 0.6617542675140329 },
+	{ 0, { 1017., 744., 847., -982., 332., -425. }, 0.6999703675245400 },
+	{ 1, { 42., 10., 19., -41., 10., -16. },  },
+	{ 0, { 1891., 647., -479., 1705., -149., 715. }, 0.7361514522905745 },
+	{ 0, { -747., -1284., 1091., -507., 523., -190. }, 0.7442630004913908 },
+	{ 0, { -25., 104., -104., -129., -52., -37. }, 0.7785774183375729 },
+	{ 0, { -512., 349., 592., 506., 250., 205. }, 0.8337771392669406 },
+	{ 0, { -6683., 244., -856., -5864., -184., -2467. }, 0.8456021851592702 },
+	{ 1, { -1203., -318., -1016., 257., -373., 120. },  },
+	{ 0, { -24., 3933., -1820., 1132., -757., 301. }, 0.8511022350336571 },
+	{ 0, { 201., -293., -309., -190., -131., -68. }, 0.8740442975723336 },
+	{ 0, { 308., -601., -394., -483., -169., -197. }, 0.9077766553319553 },
+	{ 0, { -16598., 27372., 14431., 13730., 6210., 4914. }, 0.9458755575816939 },
+	{ 1, { -126., -1380., -1472., 3523., -609., 1504. },  },
+	{ 2, { 143., -540., 222., -105., 87., -32. },  },
+	{ 0, { 329., 51., -160., 190., -86., 81. }, 0.9622835434242619 },
+	{ 0, { 128., 272., 129., -159., 60., -76. }, 0.9782201450147658 },
+	{ 0, { 420., 770., -363., -155., -115., -92. }, 1.0124707282567436 },
+	{ 0, { -2248., -3936., 3766., -2218., 1312., -630. }, 1.0195444397190756 },
+	{ 0, { -857., -445., 435., -868., 168., -286. }, 1.0327159571739788 },
+	{ 0, { 3376., 287., -315., 3751., -219., 1451. }, 1.0465646752474935 },
+	{ 0, { 703800., -971644., 898780., 636713., 368186., 296800. }, 1.0592831516596322 },
+	{ 1, { -2151., -2956., 2235., -1431., 946., -697. },  },
+	{ 2, { -483., -834., 925., 208., 376., 16. },  },
+	{ 0, { -2186., 1237., -468., -857., -221., -500. }, 1.0699466056843263 },
+	{ 0, { 186., -107., -155., -33., -60., 1. }, 1.0856512764294945 },
+	{ 0, { -29., 176., 74., -52., 22., -24. }, 1.1079517768853906 },
+	{ 1, { 68., -82., -7., 40., -2., 17. },  },
+	{ 2, { 47., -125., -59., 70., -19., 30. },  },
+	{ 0, { -79., -181., -17., 75., 0., 31. }, 1.1242912886086618 },
+	{ 0, { 11970., 27., -219., 9608., -385., 4137. }, 1.1622448658047415 },
+	{ 1, { 148., -416., -127., 187., -55., 93. },  },
+	{ 0, { -1209., -240., 543., 444., 267., 180. }, 1.1657893477276102 },
+	{ 0, { 469., -600., 571., 404., 237., 192. }, 1.2652830224888050 },
+	{ 0, { -354., 198., -247., -335., -95., -149. }, 1.3749277491569207 },
+	{ 0, { 1875., 1364., 1214., -1793., 447., -768. }, 1.4364654070205274 },
+	{ 1, { 8., 17., -6., -31., -6., -14. },  },
+	{ 0, { -139., 116., 212., 18., 88., 1. }, 1.4674691182537039 },
+	{ 0, { 498., 950., -86., 629., -57., 244. }, 1.4773951127670801 },
+	{ 0, { -211., 132., -176., -151., -46., -37. }, 1.5126367782986652 },
+	{ 0, { 388., -45., -90., 143., -56., 57. }, 1.5755868837627032 },
+	{ 0, { -262., 394., 82., 179., 60., 76. }, 1.5824073222387700 },
+	{ 0, { 12274., -42141., 38563., 10654., 16215., 5586. }, 1.5888971797699629 },
+	{ 1, { 79., 26., 108., -116., 43., -61. },  },
+	{ 0, { 785., -282., 272., 723., 98., 317. }, 1.6918870360592064 },
+	{ 0, { 107., -210., -181., -174., -73., -72. }, 1.9281473841900221 },
+	{ 0, { -121., -1883., 1696., -129., 731., -7. }, 2.1185461864868773 },
+	{ 0, { 4845., 396., -313., 4430., -275., 2018. }, 3.3406127811310191 },
+	{ 1, { 1., 25., -4., 6., -1., 2. },  },
+	{ 0, { -5503., -29918., 27443., -5129., 11901., -2218. }, 6.2830758192539502 },
+	{ 0, { 149., -16., 70., 137., 24., 69. }, 6.6811483956904603 },
+	{ 0, { 14., 35., -47., -48., -19., -18. }, 8.4710967963441863 },
+	{ 1, { 1., -1., -17., -7., -7., -4. },  },
+	{ 0, { -17638., 555., -991., -16049., 673., -7250. }, 10.2132840866995910 },
+	{ 0, { -44., -259., 211., -59., 89., -24. }, 12.5662764645159580 },
+	{ /* end neptune */ -1,  },
+};
+
+chap95_rec chap95_pluto[] = {
+	{ 0, { 101045891905., 0., 110312086224., 0., 6172492792., 0. }, 0. },
+	{ 1, { 2736962357., 0., 7289921703., 0., 8356828229., 0. },  },
+	{ 0, { -197631754827., 306850452168., -363706825084., -174047739469., -83742488844., -166197114948. }, 0.0255535185296511 },
+	{ 1, { -10339882709., 3627560682., -1704596538., 16082008148., -2615797675., 26582875457. },  },
+	{ 2, { 4555881844., 5354987944., 14163087849., 13295578846., 16544976961., 15318697408. },  },
+	{ 0, { 12877551757., 9141005248., 38823958976., 14074786713., 47081142550., 15934841957. }, 0.0383093966256461 },
+	{ 0, { -20363081906., 43534352230., -68888048997., -6054817551., -37922256273., -13665923314. }, 0.0512632279013590 },
+	{ 0, { 11372859069., -7331041505., 34135169446., -14164330338., 35562426110., -15256543947. }, 0.0629625800045217 },
+	{ 0, { -25223811753., 30334977886., -76993608077., 67207355885., -78022096909., 72709750549. }, 0.0739104871604531 },
+	{ 0, { 19031032676., -21606847641., 49490563510., -67837042251., 54793488046., -76660221358. }, 0.0843726142307477 },
+	{ 1, { 9888109415., 13390931761., 31569755508., 36949340015., 35801709881., 41063108577. },  },
+	{ 2, { -5391246864., 9125341237., -13760381761., 26757260022., -14709006932., 29981422406. },  },
+	{ 0, { 77016900., 8576436595., -758303524., 19868503441., 945693837., 21114141886. }, 0.1009656667626818 },
+	{ 0, { -425710709., -2201772586., -2981443460., -6781825029., -3324565933., -7783206250. }, 0.1181216342983851 },
+	{ 1, { 2255988361., -245384099., 5983679140., -939391729., 6514267045., -1323842110. },  },
+	{ 2, { 531179571., 1086625691., 2182247914., 3044397909., 2484824490., 3408389022. },  },
+	{ 0, { 670122662., 438458646., 1753307958., 718209879., 2047795531., 636335929. }, 0.1384952768343311 },
+	{ 0, { -179746215., -90394676., -766063009., -205567765., -854408253., -261725146. }, 0.1499201895782055 },
+	{ 1, { 110140865., -359336510., 28912500., -843378659., -67920831., -973289319. },  },
+	{ 0, { -118071179., 1819649., -265130729., 91955370., -298913452., 133716152. }, 0.1607487697162686 },
+	{ 0, { 38739517., 9002149., 12071193., -2098061., 15714901., -32081340. }, 0.1760768320056049 },
+	{ 0, { -2332129., 6073325., -5475022., 19141973., -5216109., 20872520. }, 0.1900452184842649 },
+	{ 0, { 8137788., -2826068., -3014741., -6719062., -5256740., -14189611. }, 0.2024941844674784 },
+	{ 0, { 18559203., -16541614., 25112499., 27558953., 14213163., 19938478. }, 0.2134752084935937 },
+	{ 0, { 1940133., -1267576., -1439934., -1986889., -2525015., -3851133. }, 0.2269557049635166 },
+	{ 1, { 1917476., -1704590., 4921317., -5434051., 4782139., -6305807. },  },
+	{ 0, { -822410., -563503., -2747944., -903463., -3210523., -702889. }, 0.2402479397150676 },
+	{ 0, { 962595., -74013., 1141117., 518365., 966375., 17190. }, 0.2531177145689346 },
+	{ 0, { -135658., -8463., -393590., 160618., -448155., 267162. }, 0.2643717493874742 },
+	{ 0, { 231442., -143885., 176186., -1443., 93050., -109960. }, 0.2777029906063622 },
+	{ 0, { -3000., -245., -27453., 92186., -35712., 133397. }, 0.2900297658482435 },
+	{ 0, { 55997., -115242., -44421., -45883., -43549., -47825. }, 0.3037412654012783 },
+	{ 0, { -14892., 15253., 52487., 23252., 43486., 48497. }, 0.3142803959054077 },
+	{ 0, { -2949., -95938., -94512., -17869., -51976., 3765. }, 0.3264027536592037 },
+	{ 0, { 8894., 9213., 33696., 2580., 28347., 6790. }, 0.3373713684595000 },
+	{ 0, { -16468., -43883., -57588., 8839., -17108., 18484. }, 0.3506196546089751 },
+	{ 0, { -4324., 14942., 537., 2320., 8817., -1258. }, 0.3768935755307548 },
+	{ 0, { -2257., -145., -272., -4909., 4559., -6184. }, 0.3901294315026133 },
+	{ 0, { -10889., 10437., -5474., 6213., 16279., -4595. }, 0.4045287784128869 },
+	{ 0, { 719443., -70760., 86542., 684112., 3209., 279550. }, 0.4267968486470127 },
+	{ 1, { 3728., 5875., 3969., 4141., 3826., 956. },  },
+	{ 2, { 9968., 1181., 2923., 6780., 6338., 2119. },  },
+	{ 0, { 6842., 1584., 10374., 4788., 8573., -4658. }, 0.4456721426794963 },
+	{ 0, { -10089., 9939., 3641., 7449., 544., 598. }, 0.4579662921251779 },
+	{ 0, { 1823., 688., 6471., -612., 1565., -5241. }, 0.4724826607880908 },
+	{ 0, { -3424., 9654., 4992., 7807., 583., 1356. }, 0.4869141744280314 },
+	{ 0, { -449., -1794., 3826., -7250., -2319., -7298. }, 0.5001714317315645 },
+	{ 0, { 15872., 9071., 15995., 31749., 10331., 14516. }, 0.5137491938947873 },
+	{ 0, { 40907450., -28046763., 26106307., 37325417., 10171143., 16690754. }, 0.5296557456960209 },
+	{ 1, { -42177., -28947., 38775., -19498., 29548., -4665. },  },
+	{ 2, { 3107., 30472., -6348., 11400., 8980., 1831. },  },
+	{ 0, { -7558., 61741., -13579., -15470., 9629., -26943. }, 0.5428748902518665 },
+	{ 0, { -5153., -16254., 1129., 1453., -5621., 9705. }, 0.5545763246422408 },
+	{ 1, { 4786., -5955., 927., 2343., -4914., 1978. },  },
+	{ 0, { -472., -1295., 65., -1013., 81., 865. }, 0.5737334589484931 },
+	{ 0, { 1071., -818., -1860., -1756., -2076., -217. }, 0.6240874769868805 },
+	{ 0, { 35210., 26306., -24283., 31193., -11240., 11870. }, 0.6381677442023816 },
+	{ 1, { -1433., -467., -610., 819., -193., 1466. },  },
+	{ 2, { -2302., -1111., 916., -1272., 326., -143. },  },
+	{ 0, { 713., -751., -578., -1512., 156., -696. }, 0.6775366989691358 },
+	{ 1, { 60., 611., -229., 120., -170., -479. },  },
+	{ 0, { 566., 1322., -824., 882., 271., -163. }, 0.7307010456855323 },
+	{ 1, { 315., -273., 931., -867., 656., -752. },  },
+	{ 0, { 2637., -5581., -3871., -2275., -3921., 187. }, 0.8349274544218315 },
+	{ 0, { -6012., 8879., 923., -5393., 1314., -3852. }, 0.8466308769723183 },
+	{ 1, { -2430., -2929., -1564., 2843., 65., 3053. },  },
+	{ 2, { -373., -2949., -1724., 190., -949., 999. },  },
+	{ 0, { 3787., 756., 723., -3294., -966., -1395. }, 0.8803279870880313 },
+	{ 0, { 5446., -1146., -595., -4608., -1861., -1044. }, 0.9048452745134871 },
+	{ 0, { 5058., -2711., -831., -3667., -1554., -139. }, 0.9284980837327494 },
+	{ 0, { 1760., -6922., -4114., -3639., -1717., 694. }, 0.9630502889662660 },
+	{ 1, { 963., 1525., 703., -3798., -966., -2055. },  },
+	{ 0, { -854., -5315., -3964., -3549., -797., 142. }, 0.9850575449612223 },
+	{ 1, { 453., 513., -533., -1316., -1407., -442. },  },
+	{ 0, { -1452., 2161., -2167., -2392., 843., -1017. }, 1.0358203937225836 },
+	{ 0, { 717822., -1016247., 926007., 647088., 383619., 291083. }, 1.0592833248900753 },
+	{ 1, { -29524., -7934., 4354., -18649., -4618., -10392. },  },
+	{ 2, { -5165., 7903., -5462., -3951., -3606., -275. },  },
+	{ 0, { -13391., 43036., -26981., -8012., -15174., 6191. }, 1.0698620958167548 },
+	{ 1, { -19633., -2810., 1597., -10192., -4219., -4352. },  },
+	{ 0, { 273., 2230., -349., -375., 851., 287. }, 1.0830212781676249 },
+	{ 0, { 10855., -624., 671., 9748., 207., 3846. }, 1.1622398168028405 },
+	{ 1, { -33., 92., -124., -554., -92., -612. },  },
+	{ 0, { 448., -1008., 1081., 183., 623., -187. }, 1.2654499680761597 },
+	{ 0, { -207., 526., 176., -733., 246., -400. }, 1.3757220045803040 },
+	{ 0, { 638., 340., -422., 36., 44., 18. }, 1.4777197679290477 },
+	{ 0, { 12128., -41950., 38517., 10211., 16357., 5050. }, 1.5888963534561586 },
+	{ 1, { -267., 195., -296., 12., -482., 121. },  },
+	{ 2, { -41., 86., -13., 298., -132., 311. },  },
+	{ 0, { 667., -280., 347., 903., -21., 475. }, 1.6918774676128379 },
+	{ 0, { 30., -1843., 2162., 314., 1153., 512. }, 2.1185453910327063 },
+	{ 0, { 4845., 477., -393., 4358., -362., 2072. }, 3.3406128168607023 },
+	{ 0, { -5939., -29727., 27855., -4133., 12163., -1725. }, 6.2830758108873654 },
+	{ 1, { 5., -58., 6., 45., 39., 54. },  },
+	{ 0, { -223., 149., 91., 102., 231., 420. }, 8.4710959288534031 },
+	{ 0, { -17640., -47., -831., -15721., 782., -7065. }, 10.2132856585962150 },
+	{ 1, { 165., 60., -38., 154., 112., 136. },  },
+	{ 2, { 20., 46., 112., -30., 119., 10. },  },
+	{ /* end pluto */ -1,  },
+};
+
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: chap95_data.c,v $ $Date: 2001-10-22 12:08:26 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/circum.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/circum.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/circum.c	(revision 2309)
@@ -0,0 +1,751 @@
+/* given a Now and an Obj with the object definition portion filled in,
+ * fill in the sky position (s_*) portions.
+ * calculation of positional coordinates reworked by
+ * Michael Sternberg <sternberg@physik.tu-chemnitz.de>
+ *  3/11/98: deflect was using op->s_hlong before being set in cir_pos().
+ *  4/19/98: just edit a comment
+ */
+
+#include <stdio.h>
+#include <math.h>
+#if defined(__STDC__)
+#include <stdlib.h>
+#endif
+
+#include "P_.h"
+#include "astro.h"
+#include "circum.h"
+#include "preferences.h"
+
+
+static int obj_planet P_((Now *np, Obj *op));
+static int obj_fixed P_((Now *np, Obj *op));
+static int obj_elliptical P_((Now *np, Obj *op));
+static int obj_hyperbolic P_((Now *np, Obj *op));
+static int obj_parabolic P_((Now *np, Obj *op));
+static int sun_cir P_((Now *np, Obj *op));
+static int moon_cir P_((Now *np, Obj *op));
+static void cir_sky P_((Now *np, double lpd, double psi, double rp, double *rho,
+    double lam, double bet, double lsn, double rsn, Obj *op));
+static void cir_pos P_((Now *np, double bet, double lam, double *rho, Obj *op));
+static void elongation P_((double lam, double bet, double lsn, double *el));
+static void deflect P_((double mjd1, double lpd, double psi, double rsn,
+    double lsn, double rho, double *ra, double *dec));
+static double h_albsize P_((double H));
+
+/* given a Now and an Obj, fill in the approprirate s_* fields within Obj.
+ * return 0 if all ok, else -1.
+ */
+int
+obj_cir (np, op)
+Now *np;
+Obj *op;
+{
+	switch (op->o_type) {
+	case FIXED:	 return (obj_fixed (np, op));
+	case ELLIPTICAL: return (obj_elliptical (np, op));
+	case HYPERBOLIC: return (obj_hyperbolic (np, op));
+	case PARABOLIC:  return (obj_parabolic (np, op));
+	case EARTHSAT:   return (obj_earthsat (np, op));
+	case PLANET:     return (obj_planet (np, op));
+	default:
+	    printf ("obj_cir() called with type %d\n", op->o_type);
+	    exit(1);
+	    return (-1);	/* just for lint */
+	}
+}
+
+static int
+obj_planet (np, op)
+Now *np;
+Obj *op;
+{
+	double lsn, rsn;	/* true geoc lng of sun; dist from sn to earth*/
+	double lpd, psi;	/* heliocentric ecliptic long and lat */
+	double rp;		/* dist from sun */
+	double rho;		/* dist from earth */
+	double lam, bet;	/* geocentric ecliptic long and lat */
+	double dia, mag;	/* angular diameter at 1 AU and magnitude */
+	int p;
+
+	/* validate code and check for a few special cases */
+	p = op->pl.pl_code;
+	if (p < 0 || p > MOON) {
+	    printf ("unknown planet code: %d\n", p);
+	    exit(1);
+	}
+	else if (p == SUN)
+	    return (sun_cir (np, op));
+	else if (p == MOON)
+	    return (moon_cir (np, op));
+
+	/* find solar ecliptical longitude and distance to sun from earth */
+	sunpos (mjed, &lsn, &rsn, 0);
+
+	/* find helio long/lat; sun/planet and earth/planet dist; ecliptic
+	 * long/lat; diameter and mag.
+	 */
+	plans(mjed, p, &lpd, &psi, &rp, &rho, &lam, &bet, &dia, &mag);
+
+	/* fill in all of op->s_* stuff except s_size and s_mag */
+	cir_sky (np, lpd, psi, rp, &rho, lam, bet, lsn, rsn, op);
+
+	/* set magnitude and angular size */
+	set_smag (op, mag);
+	op->s_size = (float)(dia/rho);
+
+	return (0);
+}
+
+static int
+obj_fixed (np, op)
+Now *np;
+Obj *op;
+{
+	double lsn, rsn;	/* true geoc lng of sun, dist from sn to earth*/
+	double lam, bet;	/* geocentric ecliptic long and lat */
+	double ha;		/* local hour angle */
+	double el;		/* elongation */
+	double alt, az;		/* current alt, az */
+	double ra, dec;		/* ra and dec at epoch of date */
+	double lst;
+
+	if (epoch != EOD && (float)epoch != op->f_epoch) {
+	    /* want a certain epoch -- if it's not what the database is at
+	     * we change the original to save time next time assuming the
+	     * user is likely to stick with this for a while.
+	     */
+	    double tra = op->f_RA, tdec = op->f_dec;
+	    float tepoch = (float)epoch;	/* compare w/float precision */
+	    precess (op->f_epoch, tepoch, &tra, &tdec);
+	    op->f_epoch = tepoch;
+	    op->f_RA = (float)tra;
+	    op->f_dec = (float)tdec;
+	}
+
+	/* set ra/dec to astrometric @ epoch of date */
+	ra = op->f_RA;
+	dec = op->f_dec;
+	precess (op->f_epoch, mjed, &ra, &dec);
+
+	/* convert equatoreal ra/dec to mean geocentric ecliptic lat/long */
+	eq_ecl (mjed, ra, dec, &bet, &lam);
+
+	/* find solar ecliptical long.(mean equinox) and distance from earth */
+	sunpos (mjed, &lsn, &rsn, NULL);
+
+	/* allow for relativistic light bending near the sun */
+	deflect (mjed, lam, bet, lsn, rsn, 1e10, &ra, &dec);
+
+	/* TODO: correction for annual parallax would go here */
+
+	/* correct EOD equatoreal for nutation/aberation to form apparent 
+	 * geocentric
+	 */
+	nut_eq(mjed, &ra, &dec);
+	ab_eq(mjed, lsn, &ra, &dec);
+	op->s_gaera = (float)ra;
+	op->s_gaedec = (float)dec;
+
+	/* set s_ra/dec -- apparent if EOD else astrometric */
+	if (epoch == EOD) {
+	    op->s_ra = (float)ra;
+	    op->s_dec = (float)dec;
+	} else {
+	    /* annual parallax at time mjd is to be added here, too, but
+	     * technically in the frame of epoch (usually different from mjd)
+	     */
+	    op->s_ra = op->f_RA;	/* already precessed */
+	    op->s_dec = op->f_dec;
+	}
+
+	/* compute elongation from ecliptic long/lat and sun geocentric long */
+	elongation (lam, bet, lsn, &el);
+	el = raddeg(el);
+	op->s_elong = (float)el;
+
+	/* these are really the same fields ...
+	op->s_mag = op->f_mag;
+	op->s_size = op->f_size;
+	*/
+
+	/* alt, az: correct for refraction; use eod ra/dec. */
+	now_lst (np, &lst);
+	ha = hrrad(lst) - ra;
+	hadec_aa (lat, ha, dec, &alt, &az);
+	refract (pressure, temp, alt, &alt);
+	op->s_alt = alt;
+	op->s_az = az;
+
+	return (0);
+}
+
+/* compute sky circumstances of an object in heliocentric elliptic orbit at *np.
+ */
+static int
+obj_elliptical (np, op)
+Now *np;
+Obj *op;
+{
+	double lsn, rsn;	/* true geoc lng of sun; dist from sn to earth*/
+	double dt;		/* light travel time to object */
+	double lg;		/* helio long of earth */
+	double nu;		/* true anomaly */
+	double rp=0;		/* distance from the sun */
+	double lo, slo, clo;	/* angle from ascending node */
+	double inc;		/* inclination */
+	double psi=0;		/* heliocentric latitude */
+	double spsi=0, cpsi=0;	/* trig of heliocentric latitude */
+	double lpd; 		/* heliocentric longitude */
+	double rho=0;		/* distance from the Earth */
+	double om;		/* arg of perihelion */
+	double Om;		/* long of ascending node. */
+	double lam;    		/* geocentric ecliptic longitude */
+	double bet;    		/* geocentric ecliptic latitude */
+	double ll=0, sll, cll;	/* helio angle between object and earth */
+	double mag;		/* magnitude */
+	double e_n;		/* mean daily motion */
+	double tp;		/* time from perihelion (days) */
+	double rpd=0;
+	double y;
+	int pass;
+
+	/* find location of earth from sun now */
+	sunpos (mjed, &lsn, &rsn, 0);
+	lg = lsn + PI;
+
+	/* mean daily motion is derived fro mean distance */
+	e_n = 0.9856076686/pow((double)op->e_a, 1.5);
+
+	/* correct for light time by computing position at time mjd, then
+	 *   again at mjd-dt, where
+	 *   dt = time it takes light to travel earth-object distance.
+	 */
+	dt = 0;
+	for (pass = 0; pass < 2; pass++) {
+
+	    reduce_elements (op->e_epoch, mjd-dt, degrad(op->e_inc),
+					degrad (op->e_om), degrad (op->e_Om),
+					&inc, &om, &Om);
+
+	    tp = mjed - dt - (op->e_cepoch - op->e_M/e_n);
+	    vrc (&nu, &rp, tp, op->e_e, op->e_a*(1-op->e_e));
+	    nu = degrad(nu);
+	    lo = nu + om;
+	    slo = sin(lo);
+	    clo = cos(lo);
+	    spsi = slo*sin(inc);
+	    y = slo*cos(inc);
+	    psi = asin(spsi);
+	    lpd = atan(y/clo)+Om;
+	    if (clo<0) lpd += PI;
+	    range (&lpd, 2*PI);
+	    cpsi = cos(psi);
+	    rpd = rp*cpsi;
+	    ll = lpd-lg;
+	    rho = sqrt(rsn*rsn+rp*rp-2*rsn*rp*cpsi*cos(ll));
+
+	    dt = rho*LTAU/3600.0/24.0;	/* light travel time, in days / AU */
+	}
+
+	/* compute sin and cos of ll */
+	sll = sin(ll);
+	cll = cos(ll);
+
+	/* find geocentric ecliptic longitude and latitude */
+	if (rpd < rsn)
+	    lam = atan(-1*rpd*sll/(rsn-rpd*cll))+lg+PI;
+	else
+	    lam = atan(rsn*sll/(rpd-rsn*cll))+lpd;
+	range (&lam, 2*PI);
+	bet = atan(rpd*spsi*sin(lam-lpd)/(cpsi*rsn*sll));
+
+	/* fill in all of op->s_* stuff except s_size and s_mag */
+	cir_sky (np, lpd, psi, rp, &rho, lam, bet, lsn, rsn, op);
+
+	/* compute magnitude and size */
+	if (op->e_mag.whichm == MAG_HG) {
+	    /* the H and G parameters from the Astro. Almanac.
+	     */
+	    if (op->e_size)
+		op->s_size = (float)(op->e_size / rho);
+	    else {
+		hg_mag (op->e_mag.m1, op->e_mag.m2, rp, rho, rsn, &mag);
+		op->s_size = (float)(h_albsize (op->e_mag.m1)/rho);
+
+	    }
+	} else {
+	    /* the g/k model of comets */
+	    gk_mag (op->e_mag.m1, op->e_mag.m2, rp, rho, &mag);
+	    op->s_size = (float)(op->e_size / rho);
+	}
+	set_smag (op, mag);
+
+	return (0);
+}
+
+/* compute sky circumstances of an object in heliocentric hyperbolic orbit.
+ */
+static int
+obj_hyperbolic (np, op)
+Now *np;
+Obj *op;
+{
+	double lsn, rsn;	/* true geoc lng of sun; dist from sn to earth*/
+	double dt;		/* light travel time to object */
+	double lg;		/* helio long of earth */
+	double nu;		/* true anomaly and eccentric anomaly */
+	double rp=0;		/* distance from the sun */
+	double lo, slo, clo;	/* angle from ascending node */
+	double inc;		/* inclination */
+	double psi=0;		/* heliocentric latitude */
+	double spsi=0, cpsi=0;	/* trig of heliocentric latitude */
+	double lpd; 		/* heliocentric longitude */
+	double rho=0;		/* distance from the Earth */
+	double om;		/* arg of perihelion */
+	double Om;		/* long of ascending node. */
+	double lam;    		/* geocentric ecliptic longitude */
+	double bet;    		/* geocentric ecliptic latitude */
+	double e;		/* fast eccentricity */
+	double ll=0, sll, cll;	/* helio angle between object and earth */
+	double n;		/* mean daily motion */
+	double mag;		/* magnitude */
+	double a;		/* mean distance */
+	double tp;		/* time from perihelion (days) */
+	double rpd=0;
+	double y;
+	int pass;
+
+	/* find solar ecliptical longitude and distance to sun from earth */
+	sunpos (mjed, &lsn, &rsn, 0);
+
+	lg = lsn + PI;
+	e = op->h_e;
+	a = op->h_qp/(e - 1.0);
+	n = .98563/sqrt(a*a*a);
+
+	/* correct for light time by computing position at time mjd, then
+	 *   again at mjd-dt, where
+	 *   dt = time it takes light to travel earth-object distance.
+	 */
+	dt = 0;
+	for (pass = 0; pass < 2; pass++) {
+
+	    reduce_elements (op->h_epoch, mjd-dt, degrad(op->h_inc),
+			    degrad (op->h_om), degrad (op->h_Om),
+			    &inc, &om, &Om);
+
+	    tp = mjed - dt - op->h_ep;
+	    vrc (&nu, &rp, tp, op->h_e, op->h_qp);
+	    nu = degrad(nu);
+	    lo = nu + om;
+	    slo = sin(lo);
+	    clo = cos(lo);
+	    spsi = slo*sin(inc);
+	    y = slo*cos(inc);
+	    psi = asin(spsi);
+	    lpd = atan(y/clo)+Om;
+	    if (clo<0) lpd += PI;
+	    range (&lpd, 2*PI);
+	    cpsi = cos(psi);
+	    rpd = rp*cpsi;
+	    ll = lpd-lg;
+	    rho = sqrt(rsn*rsn+rp*rp-2*rsn*rp*cpsi*cos(ll));
+
+	    dt = rho*5.775518e-3;	/* light travel time, in days */
+	}
+
+	/* compute sin and cos of ll */
+	sll = sin(ll);
+	cll = cos(ll);
+
+	/* find geocentric ecliptic longitude and latitude */
+	if (rpd < rsn)
+	    lam = atan(-1*rpd*sll/(rsn-rpd*cll))+lg+PI;
+	else
+	    lam = atan(rsn*sll/(rpd-rsn*cll))+lpd;
+	range (&lam, 2*PI);
+	bet = atan(rpd*spsi*sin(lam-lpd)/(cpsi*rsn*sll));
+
+	/* fill in all of op->s_* stuff except s_size and s_mag */
+	cir_sky (np, lpd, psi, rp, &rho, lam, bet, lsn, rsn, op);
+
+	/* compute magnitude and size */
+	gk_mag (op->h_g, op->h_k, rp, rho, &mag);
+	set_smag (op, mag);
+	op->s_size = (float)(op->h_size / rho);
+
+	return (0);
+}
+
+/* compute sky circumstances of an object in heliocentric hyperbolic orbit.
+ */
+static int
+obj_parabolic (np, op)
+Now *np;
+Obj *op;
+{
+	double lsn, rsn;	/* true geoc lng of sun; dist from sn to earth*/
+	double lam;    		/* geocentric ecliptic longitude */
+	double bet;    		/* geocentric ecliptic latitude */
+	double mag;		/* magnitude */
+	double inc, om, Om;
+	double lpd, psi, rp, rho;
+	double dt;
+	int pass;
+
+	/* find solar ecliptical longitude and distance to sun from earth */
+	sunpos (mjed, &lsn, &rsn, 0);
+
+	/* two passes to correct lam and bet for light travel time. */
+	dt = 0.0;
+	for (pass = 0; pass < 2; pass++) {
+	    reduce_elements (op->p_epoch, mjd-dt, degrad(op->p_inc),
+		degrad(op->p_om), degrad(op->p_Om), &inc, &om, &Om);
+	    comet (mjed-dt, op->p_ep, inc, om, op->p_qp, Om,
+				    &lpd, &psi, &rp, &rho, &lam, &bet);
+	    dt = rho*LTAU/3600.0/24.0;	/* light travel time, in days / AU */
+	}
+
+	/* fill in all of op->s_* stuff except s_size and s_mag */
+	cir_sky (np, lpd, psi, rp, &rho, lam, bet, lsn, rsn, op);
+
+	/* compute magnitude and size */
+	gk_mag (op->p_g, op->p_k, rp, rho, &mag);
+	set_smag (op, mag);
+	op->s_size = (float)(op->p_size / rho);
+
+	return (0);
+}
+
+/* find sun's circumstances now.
+ */
+static int
+sun_cir (np, op)
+Now *np;
+Obj *op;
+{
+	double lsn, rsn;	/* true geoc lng of sun; dist from sn to earth*/
+	double bsn;		/* true latitude beta of sun */
+	double dhlong;
+
+	sunpos (mjed, &lsn, &rsn, &bsn);/* sun's true coordinates; mean ecl. */
+
+	op->s_sdist = 0.0;
+	op->s_elong = 0.0;
+	op->s_phase = 100.0;
+	set_smag (op, -26.8);	/* TODO */
+	dhlong = lsn-PI;	/* geo- to helio- centric */
+	range (&dhlong, 2*PI);
+	op->s_hlong = (float)dhlong;
+	op->s_hlat = (float)(-bsn);
+
+	/* fill sun's ra/dec, alt/az in op */
+	cir_pos (np, bsn, lsn, &rsn, op);
+	op->s_edist = (float)rsn;
+	op->s_size = (float)(raddeg(4.65242e-3/rsn)*3600*2);
+
+	return (0);
+}
+
+/* find moon's circumstances now.
+ */
+static int
+moon_cir (np, op)
+Now *np;
+Obj *op;
+{
+	double lsn, rsn;	/* true geoc lng of sun; dist from sn to earth*/
+	double lam;    		/* geocentric ecliptic longitude */
+	double bet;    		/* geocentric ecliptic latitude */
+	double edistau;		/* earth-moon dist, in au */
+	double el;		/* elongation, rads east */
+	double ms;		/* sun's mean anomaly */
+	double md;		/* moon's mean anomaly */
+	double i;
+
+	moon (mjed, &lam, &bet, &edistau, &ms, &md);	/* mean ecliptic & EOD*/
+	sunpos (mjed, &lsn, &rsn, NULL);		/* mean ecliptic & EOD*/
+
+	op->s_hlong = (float)lam;		/* save geo in helio fields */
+	op->s_hlat = (float)bet;
+
+	/* find angular separation from sun */
+	elongation (lam, bet, lsn, &el);
+	op->s_elong = (float)raddeg(el);		/* want degrees */
+
+	/* solve triangle of earth, sun, and elongation for moon-sun dist */
+	op->s_sdist = (float) sqrt (edistau*edistau + rsn*rsn
+						    - 2.0*edistau*rsn*cos(el));
+
+	/* TODO: improve mag; this is based on a flat moon model. */
+	set_smag (op, -12.7 + 2.5*(log10(PI) - log10(PI/2*(1+1.e-6-cos(el)))));
+
+	/* find phase -- allow for projection effects */
+	i = 0.1468*sin(el)*(1 - 0.0549*sin(md))/(1 - 0.0167*sin(ms));
+	op->s_phase = (float)((1+cos(PI-el-degrad(i)))/2*100);
+
+	/* fill moon's ra/dec, alt/az in op and update for topo dist */
+	cir_pos (np, bet, lam, &edistau, op);
+
+	op->s_edist = (float)edistau;
+	op->s_size = (float)(3600*2.0*raddeg(asin(MRAD/MAU/edistau)));
+						/* moon angular dia, seconds */
+
+	return (0);
+}
+
+/* fill in all of op->s_* stuff except s_size and s_mag.
+ * this is used for sol system objects (except sun and moon); never FIXED.
+ */
+static void
+cir_sky (np, lpd, psi, rp, rho, lam, bet, lsn, rsn, op)
+Now *np;
+double lpd, psi;	/* heliocentric ecliptic long and lat */
+double rp;		/* dist from sun */
+double *rho;		/* dist from earth: in as geo, back as geo or topo */
+double lam, bet;	/* true geocentric ecliptic long and lat */
+double lsn, rsn;	/* true geoc lng of sun; dist from sn to earth*/
+Obj *op;
+{
+	double el;		/* elongation */
+	double f;		/* fractional phase from earth */
+
+	/* compute elongation and phase */
+	elongation (lam, bet, lsn, &el);
+	el = raddeg(el);
+	op->s_elong = (float)el;
+	f = 0.25 * ((rp+ *rho)*(rp+ *rho) - rsn*rsn)/(rp* *rho);
+	op->s_phase = (float)(f*100.0); /* percent */
+
+	/* set heliocentric long/lat; mean ecliptic and EOD */
+	op->s_hlong = (float)lpd;
+	op->s_hlat = (float)psi;
+
+	/* fill solar sys body's ra/dec, alt/az in op */
+	cir_pos (np, bet, lam, rho, op);        /* updates rho */
+
+	/* set earth/planet and sun/planet distance */
+	op->s_edist = (float)(*rho);
+	op->s_sdist = (float)rp;
+}
+
+/* fill equatoreal and horizontal op-> fields; stern
+ *
+ *    input:          lam/bet/rho geocentric mean ecliptic and equinox of day
+ * 
+ * algorithm at EOD:
+ *   ecl_eq	--> ra/dec	geocentric mean equatoreal EOD (via mean obliq)
+ *   deflect	--> ra/dec	  relativistic deflection
+ *   nut_eq	--> ra/dec	geocentric true equatoreal EOD
+ *   ab_eq	--> ra/dec	geocentric apparent equatoreal EOD
+ *					if (PREF_GEO)  --> output
+ *   ta_par	--> ra/dec	topocentric apparent equatoreal EOD
+ *					if (!PREF_GEO)  --> output
+ *   hadec_aa	--> alt/az	topocentric horizontal
+ *   refract	--> alt/az	observed --> output
+ *
+ * algorithm at fixed epoch:
+ *   ecl_eq	--> ra/dec	geocentric mean equatoreal EOD (via mean obliq)
+ *   deflect	--> ra/dec	  relativistic deflection [for alt/az only]
+ *   nut_eq	--> ra/dec	geocentric true equatoreal EOD [for aa only]
+ *   ab_eq	--> ra/dec	geocentric apparent equatoreal EOD [for aa only]
+ *   ta_par	--> ra/dec	topocentric apparent equatoreal EOD
+ *     precess	--> ra/dec	topocentric equatoreal fixed equinox [eq only]
+ *					--> output
+ *   hadec_aa	--> alt/az	topocentric horizontal
+ *   refract	--> alt/az	observed --> output
+ */
+static void
+cir_pos (np, bet, lam, rho, op)
+Now *np;
+double bet, lam;/* geo lat/long (mean ecliptic of date) */
+double *rho;	/* in: geocentric dist in AU; out: geo- or topocentic dist */
+Obj *op;	/* object to set s_ra/dec as per epoch */
+{
+	double ra, dec;		/* apparent ra/dec, corrected for nut/ab */
+	double tra, tdec;	/* astrometric ra/dec, no nut/ab */
+	double lsn, rsn;	/* solar geocentric (mean ecliptic of date) */
+	double ha_in, ha_out;	/* local hour angle before/after parallax */
+	double dec_out;		/* declination after parallax */
+	double dra, ddec;	/* parallax correction */
+	double alt, az;		/* current alt, az */
+	double lst;             /* local sidereal time */
+	double rho_topo;        /* topocentric distance in earth radii */
+
+	/* convert to equatoreal [mean equator, with mean obliquity] */
+	ecl_eq (mjed, bet, lam, &ra, &dec);
+	tra = ra;	/* keep mean coordinates */
+	tdec = dec;
+
+	/* get sun position */
+	sunpos(mjed, &lsn, &rsn, NULL);
+
+	/* allow for relativistic light bending near the sun.
+	 * (avoid calling deflect() for the sun itself).
+	 */
+	if (!is_planet(op,SUN) && !is_planet(op,MOON))
+	    deflect (mjed, op->s_hlong, op->s_hlat, lsn, rsn, *rho, &ra, &dec);
+
+	/* correct ra/dec to form geocentric apparent */
+	nut_eq (mjed, &ra, &dec);
+	if (!is_planet(op,MOON))
+	    ab_eq (mjed, lsn, &ra, &dec);
+	op->s_gaera = (float)ra;
+	op->s_gaedec = (float)dec;
+
+	/* find parallax correction for equatoreal coords */
+	now_lst (np, &lst);
+	ha_in = hrrad(lst) - ra;
+	rho_topo = *rho * MAU/ERAD;             /* convert to earth radii */
+	ta_par (ha_in, dec, lat, elev, &rho_topo, &ha_out, &dec_out);
+
+	/* transform into alt/az and apply refraction */
+	hadec_aa (lat, ha_out, dec_out, &alt, &az);
+	refract (pressure, temp, alt, &alt);
+	op->s_alt = alt;
+	op->s_az = az;
+
+	/* Get parallax differences and apply to apparent or astrometric place
+	 * as needed.  For the astrometric place, rotating the CORRECTIONS
+	 * back from the nutated equator to the mean equator will be
+	 * neglected.  This is an effect of about 0.1" at moon distance.
+	 * We currently don't have an inverse nutation rotation.
+	 */
+	if (pref_get(PREF_EQUATORIAL) == PREF_GEO) {
+	    /* no topo corrections to eq. coords */
+	    dra = ddec = 0.0;
+	} else {
+	    dra = ha_in - ha_out;	/* ra sign is opposite of ha */
+	    ddec = dec_out - dec;
+	    *rho = rho_topo * ERAD/MAU; /* return topocentric distance in AU */
+	}
+
+	/* fill in ra/dec fields */
+	if (epoch == EOD) {		/* apparent geo/topocentric */
+	    ra = ra + dra;
+	    dec = dec + ddec;
+	} else {			/* astrometric geo/topocent */
+	    ra = tra + dra;
+	    dec = tdec + ddec;
+	    precess (mjed, epoch, &ra, &dec);
+	}
+	range(&ra, 2*PI);
+	op->s_ra = (float)ra;
+	op->s_dec = (float)dec;
+}
+
+/* given geocentric ecliptic longitude and latitude, lam and bet, of some object
+ * and the longitude of the sun, lsn, find the elongation, el. this is the
+ * actual angular separation of the object from the sun, not just the difference
+ * in the longitude. the sign, however, IS set simply as a test on longitude
+ * such that el will be >0 for an evening object <0 for a morning object.
+ * to understand the test for el sign, draw a graph with lam going from 0-2*PI
+ *   down the vertical axis, lsn going from 0-2*PI across the hor axis. then
+ *   define the diagonal regions bounded by the lines lam=lsn+PI, lam=lsn and
+ *   lam=lsn-PI. the "morning" regions are any values to the lower left of the
+ *   first line and bounded within the second pair of lines.
+ * all angles in radians.
+ */
+static void
+elongation (lam, bet, lsn, el)
+double lam, bet, lsn;
+double *el;
+{
+	*el = acos(cos(bet)*cos(lam-lsn));
+	if (lam>lsn+PI || (lam>lsn-PI && lam<lsn)) *el = - *el;
+}
+
+/* apply relativistic light bending correction to ra/dec; stern
+ *
+ * The algorithm is from:
+ * Mean and apparent place computations in the new IAU 
+ * system. III - Apparent, topocentric, and astrometric 
+ * places of planets and stars
+ * KAPLAN, G. H.;  HUGHES, J. A.;  SEIDELMANN, P. K.;
+ * SMITH, C. A.;  YALLOP, B. D.
+ * Astronomical Journal (ISSN 0004-6256), vol. 97, April 1989, p. 1197-1210.
+ *
+ * This article is a very good collection of formulea for geocentric and
+ * topocentric place calculation in general.  The apparent and
+ * astrometric place calculation in this file currently does not follow
+ * the strict algorithm from this paper and hence is not fully correct.
+ * The entire calculation is currently based on the rotating EOD frame and
+ * not the "inertial" J2000 frame.
+ */
+static void
+deflect (mjd1, lpd, psi, lsn, rsn, rho, ra, dec)
+double mjd1;		/* epoch */
+double lpd, psi;	/* heliocentric ecliptical long / lat */
+double rsn, lsn;	/* distance and longitude of sun */
+double rho;		/* geocentric distance */
+double *ra, *dec;	/* geocentric equatoreal */
+{
+	double hra, hdec;	/* object heliocentric equatoreal */
+	double el;		/* HELIOCENTRIC elongation object--earth */
+	double g1, g2;		/* relativistic weights */
+	double u[3];		/* object geocentric cartesian */
+	double q[3];		/* object heliocentric cartesian unit vect */
+	double e[3];		/* earth heliocentric cartesian unit vect */
+	double qe, uq, eu;	/* scalar products */
+	int i;			/* counter */
+
+#define G	1.32712438e20	/* heliocentric grav const; in m^3*s^-2 */
+#define c	299792458.0	/* speed of light in m/s */
+
+	elongation(lpd, psi, lsn-PI, &el);
+	el = fabs(el);
+	/* only continue if object is within about 10 deg around the sun
+	 * and not obscured by the sun's disc (radius 0.25 deg)
+	 *
+	 * precise geocentric deflection is:  g1 * tan(el/2)
+	 *	radially outwards from sun;  the vector munching below
+	 *	just applys this component-wise
+	 *	Note:	el = HELIOCENTRIC elongation.
+	 *		g1 is always about 0.004 arc seconds
+	 *		g2 varies from 0 (highest contribution) to 2
+	 */
+	if (el<degrad(170) || el>degrad(179.75)) return;
+
+	/* get cartesian vectors */
+	sphcart(*ra, *dec, rho, u, u+1, u+2);
+
+	ecl_eq(mjd1, psi, lpd, &hra, &hdec);
+	sphcart(hra, hdec, 1.0, q, q+1, q+2);
+
+	ecl_eq(mjd1, 0.0, lsn-PI, &hra, &hdec);
+	sphcart(hra, hdec, 1.0, e, e+1, e+2);
+
+	/* evaluate scalar products */
+	qe = uq = eu = 0.0;
+	for(i=0; i<=2; ++i) {
+	    qe += q[i]*e[i];
+	    uq += u[i]*q[i];
+	    eu += e[i]*u[i];
+	}
+
+	g1 = 2*G/(c*c*MAU)/rsn;
+	g2 = 1 + qe;
+
+	/* now deflect geocentric vector */
+	g1 /= g2;
+	for(i=0; i<=2; ++i)
+	    u[i] += g1*(uq*e[i] - eu*q[i]);
+	
+	/* back to spherical */
+	cartsph(u[0], u[1], u[2], ra, dec, &rho);	/* rho thrown away */
+}
+
+/* estimate size in arc seconds @ 1AU from absolute magnitude, H, and assuming
+ * an albedo of 0.1. With this assumption an object with diameter of 1500m
+ * has an absolute mag of 18.
+ */
+static double
+h_albsize (H)
+double H;
+{
+	return (3600*raddeg(.707*1500*pow(2.51,(18-H)/2)/MAU));
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: circum.c,v $ $Date: 2001-10-22 12:08:26 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/circum.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/circum.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/circum.h	(revision 2309)
@@ -0,0 +1,443 @@
+/* the Now and Obj typedefs.
+ * also, a few miscellaneous constants and declarations.
+ */
+#ifndef _CIRCUM_H
+#define _CIRCUM_H
+
+#define	SPD	(24.0*3600.0)	/* seconds per day */
+#define	MAU	(1.4959787e11)	/* m / au */
+#define	LTAU	499.005		/* seconds light takes to travel 1 AU */
+#define	ERAD	(6.37816e6)	/* earth equitorial radius, m */
+#define	MRAD	(1.740e6)	/* moon equitorial radius, m */
+#define	SRAD	(6.95e8)	/* sun equitorial radius, m */
+#define	FTPM	3.28084		/* ft per m */
+#define	ESAT_MAG	2	/* default satellite magnitude */
+#define	FAST_SAT_RPD	0.25	/* max earth sat rev/day considered "fast" */
+
+#define	EOD	(-9786)		/* special epoch flag: use epoch of date */
+
+/* info about the local observing circumstances and misc preferences */
+typedef struct {
+	double n_mjd;	/* modified Julian date, ie, days since
+			 * Jan 0.5 1900 (== 12 noon, Dec 30, 1899), utc.
+			 * enough precision to get well better than 1 second.
+			 * N.B. if not first member, must move NOMJD inits.
+			 */
+	double n_lat;	/* geographic (surface-normal) lat, >0 north, rads */
+	double n_lng;	/* longitude, >0 east, rads */
+	double n_tz;	/* time zone, hrs behind UTC */
+	double n_temp;	/* atmospheric temp, degrees C */
+	double n_pressure; /* atmospheric pressure, mBar */
+	double n_elev;	/* elevation above sea level, earth radii */
+	double n_dip;	/* dip of sun below hzn at twilight, >0 below, rads */
+	double n_epoch;	/* desired precession display epoch as an mjd, or EOD */
+	char n_tznm[8];	/* time zone name; 7 chars or less, always 0 at end */
+} Now;
+
+/* handy shorthands for fields in a Now pointer, np */
+#define mjd	np->n_mjd
+#define lat	np->n_lat
+#define lng	np->n_lng
+#define tz	np->n_tz
+#define temp	np->n_temp
+#define pressure np->n_pressure
+#define elev	np->n_elev
+#define	dip	np->n_dip
+#define epoch	np->n_epoch
+#define tznm	np->n_tznm
+#define mjed	mm_mjed(np)
+
+/* structures to describe objects of various types.
+ */
+
+/* magnitude values in two different systems */
+typedef struct {
+    float m1, m2;	/* either g/k or H/G, depending on... */
+    int whichm;		/* one of MAG_gk or MAG_HG */
+} Mag;
+
+/* whichm */
+#define MAG_HG          0       /* using 0 makes HG the initial default */
+#define MAG_gk          1
+
+/* we actually store magnitudes times this scale factor in a short int */
+#define	MAGSCALE	100.0
+#define	set_smag(op,m)	((op)->s_mag = (short)floor((m)*MAGSCALE + 0.5))
+#define	set_fmag(op,m)	((op)->f_mag = (short)floor((m)*MAGSCALE + 0.5))
+#define	get_mag(op)	((op)->s_mag / MAGSCALE)
+
+/* longest object name, including trailing '\0' */
+#define	MAXNM	22
+
+/* Obj is a massive union.
+ * many fields are in common so we use macros to make things a little easier.
+ */
+
+typedef unsigned char ObjType_t;
+typedef unsigned char ObjAge_t;
+
+/* fields common to *all* structs in the Obj union.
+ */
+#define	OBJ_COMMON_FLDS							\
+    ObjType_t co_type;	/* current object type; see flags, below */	\
+    unsigned char co_flags;/* FUSER*... used by others */		\
+    char co_name[MAXNM];/* name, including \0 */			\
+    float co_ra;	/* geo/topo app/mean ra, rads */		\
+    float co_dec;	/* geo/topo app/mean dec, rads */		\
+    float co_gaera;	/* geo apparent ra, rads */			\
+    float co_gaedec;	/* geo apparent dec, rads */			\
+    double co_az;	/* azimuth, >0 e of n, rads */			\
+    double co_alt;	/* altitude above topocentric horizon, rads */	\
+    float co_elong;	/* angular sep btwen obj and sun, >0 E, degs */	\
+    float co_size;	/* angular size, arc secs */			\
+    short co_mag;	/* visual magnitude * MAGSCALE */		\
+    ObjAge_t co_age	/* update aging code; see db.c */
+
+/* fields common to all solar system objects in the Obj union */
+#define	OBJ_SOLSYS_FLDS							\
+    OBJ_COMMON_FLDS;	/* all the fixed ones plus ... */		\
+    float so_sdist;	/* dist from object to sun, au */		\
+    float so_edist;	/* dist from object to earth, au */		\
+    float so_hlong;	/* heliocentric longitude, rads */		\
+    float so_hlat;	/* heliocentric latitude, rads */		\
+    float so_phase	/* phase, % */
+
+
+/* a generic object */
+typedef struct {
+    OBJ_COMMON_FLDS;
+} ObjAny;
+
+/* a generic sol system object */
+typedef struct {
+    OBJ_SOLSYS_FLDS;
+} ObjSS;
+
+/* basic Fixed object info.
+ */
+typedef unsigned char byte;
+typedef struct {
+    OBJ_COMMON_FLDS;
+    char  fo_class;	/* object class --  see db.c:db_set_field() et al */
+    char  fo_spect[2];	/* spectral codes, if appropriate */
+    byte  fo_ratio;	/* minor/major diameter ratio. use s/get_ratio() */
+    byte  fo_pa;	/* position angle, E of N, rads. use s/get_pa() */
+    float fo_epoch;	/* epoch of f_RA/dec */
+    float fo_ra;	/* ra, rads, at given epoch */
+    float fo_dec;	/* dec, rads, at given epoch */
+} ObjF;
+
+#define	fo_mag	co_mag	/* pseudonym for so_mag since it is not computed */
+#define	fo_size	co_size	/* pseudonym for so_size since it is not computed */
+
+/* macros to pack/unpack some fields */
+#define	SRSCALE		255.0		/* galaxy size ratio scale */
+#define	PASCALE		(255.0/(2*PI))	/* pos angle scale factor */
+#define	get_ratio(op)	((int)(op)->f_ratio/SRSCALE)
+#define	set_ratio(op,maj,min) ((op)->f_ratio = (byte)(((maj) > 0)	    \
+					? ((min)*SRSCALE/(double)(maj)+0.5) \
+					: 0))
+#define	get_pa(op)	((double)(op)->f_pa/PASCALE)
+#define	set_pa(op,s)	((op)->f_pa = (byte)((s)*PASCALE + 0.5))
+
+#define	NCLASSES	128 /* n potential fo_classes -- allow for all ASCII */
+
+/* basic planet object info */
+typedef struct {
+    OBJ_SOLSYS_FLDS;
+    int pl_code;	/* one of the codes in astro.h */
+} ObjPl;
+
+/* basic info about an object in elliptical heliocentric orbit */
+typedef struct {
+    OBJ_SOLSYS_FLDS;
+    float  eo_inc;	/* inclination, degrees */
+    float  eo_Om;	/* longitude of ascending node, degrees */
+    float  eo_om;	/* argument of perihelion, degress */
+    float  eo_a;	/* mean distance, aka,semi-maj axis,AU */
+    float  eo_M;	/* mean anomaly, ie, degrees from perihelion at cepoch*/
+    float  eo_size;	/* angular size, in arc seconds at 1 AU */
+    double eo_e;	/* eccentricity (double for when near 1 computing q) */
+    double eo_cepoch;	/* epoch date (M reference), as an mjd */
+    double eo_epoch;	/* equinox year (inc/Om/om reference), as an mjd. */
+    Mag    eo_mag;	/* magnitude */
+} ObjE;
+
+/* basic info about an object in hyperbolic heliocentric orbit */
+typedef struct {
+    OBJ_SOLSYS_FLDS;
+    double ho_epoch;	/* equinox year (inc/Om/om reference), as an mjd */
+    double ho_ep;	/* epoch of perihelion, as an mjd */
+    float  ho_inc;	/* inclination, degs */
+    float  ho_Om;	/* longitude of ascending node, degs */
+    float  ho_om;	/* argument of perihelion, degs. */
+    float  ho_e;	/* eccentricity */
+    float  ho_qp;	/* perihelion distance, AU */
+    float  ho_g, ho_k;	/* magnitude model coefficients */
+    float  ho_size;	/* angular size, in arc seconds at 1 AU */
+} ObjH;
+
+/* basic info about an object in parabolic heliocentric orbit */
+typedef struct {
+    OBJ_SOLSYS_FLDS;
+    double po_epoch;	/* reference epoch, as an mjd */
+    double po_ep;	/* epoch of perihelion, as an mjd */
+    float  po_inc;	/* inclination, degs */
+    float  po_qp;	/* perihelion distance, AU */
+    float  po_om;	/* argument of perihelion, degs. */
+    float  po_Om;	/* longitude of ascending node, degs */
+    float  po_g, po_k;	/* magnitude model coefficients */
+    float  po_size;	/* angular size, in arc seconds at 1 AU */
+} ObjP;
+
+/* basic earth satellite object info */
+typedef struct {
+    OBJ_COMMON_FLDS;
+    double eso_epoch;	/* reference epoch, as an mjd */
+    double eso_n;	/* mean motion, rev/day
+			 * N.B. we need double due to a sensitive differencing
+			 * operation used to compute MeanAnomaly in
+			 * esat_main()/satellite.c.
+			 */
+    float  eso_inc;	/* inclination, degs */
+    float  eso_raan;	/* RA of ascending node, degs */
+    float  eso_e;	/* eccentricity */
+    float  eso_ap;	/* argument of perigee at epoch, degs */
+    float  eso_M;	/* mean anomaly, ie, degrees from perigee at epoch */
+    float  eso_decay;	/* orbit decay rate, rev/day^2 */
+    float  eso_drag;	/* object drag coefficient, (earth radii)^-1 */
+    int    eso_orbit;	/* integer orbit number of epoch */
+
+    /* computed "sky" results unique to earth satellites */
+    float  ess_elev;	/* height of satellite above sea level, m */
+    float  ess_range;	/* line-of-site distance from observer to satellite, m*/
+    float  ess_rangev;	/* rate-of-change of range, m/s */
+    float  ess_sublat;	/* latitude below satellite, >0 north, rads */
+    float  ess_sublng;	/* longitude below satellite, >0 east, rads */
+    int    ess_eclipsed;/* 1 if satellite is in earth's shadow, else 0 */
+} ObjES;
+
+typedef union {
+    ObjAny  any;	/* these fields valid for all types */
+    ObjSS   anyss;	/* these fields valid for all solar system types */
+    ObjPl   pl;		/* planet */
+    ObjF    f;		/* fixed object */
+    ObjE    e;		/* object in heliocentric elliptical orbit */
+    ObjH    h;		/* object in heliocentric hyperbolic trajectory */
+    ObjP    p;		/* object in heliocentric parabolic trajectory */
+    ObjES   es;		/* earth satellite */
+} Obj;
+
+
+/* for o_flags -- everybody must agree */
+#define	FUSER0		0x01
+#define	FUSER1		0x02
+#define	FUSER2		0x04
+#define	FUSER3		0x08
+#define	FUSER4		0x10
+#define	FUSER5		0x20
+#define	FUSER6		0x40
+#define	FUSER7		0x80
+
+/* mark an object as being a "field star" */
+#define	FLDSTAR		FUSER3
+
+/* Obj shorthands: */
+#define	o_type	any.co_type
+#define	o_name	any.co_name
+#define	o_flags	any.co_flags
+#define	o_age	any.co_age
+#define	s_ra	any.co_ra
+#define	s_dec	any.co_dec
+#define	s_gaera	any.co_gaera
+#define	s_gaedec any.co_gaedec
+#define	s_az	any.co_az
+#define	s_alt	any.co_alt
+#define	s_elong	any.co_elong
+#define	s_size	any.co_size
+#define	s_mag	any.co_mag
+
+#define	s_sdist	anyss.so_sdist
+#define	s_edist	anyss.so_edist
+#define	s_hlong	anyss.so_hlong
+#define	s_hlat	anyss.so_hlat
+#define	s_phase anyss.so_phase
+
+#define	s_elev		es.ess_elev
+#define	s_range		es.ess_range
+#define	s_rangev	es.ess_rangev
+#define	s_sublat	es.ess_sublat
+#define	s_sublng	es.ess_sublng
+#define	s_eclipsed	es.ess_eclipsed
+
+#define	f_class	f.fo_class
+#define	f_spect	f.fo_spect
+#define	f_ratio	f.fo_ratio
+#define	f_pa	f.fo_pa
+#define	f_epoch	f.fo_epoch
+#define	f_RA	f.fo_ra
+#define	f_dec	f.fo_dec
+#define	f_mag	f.fo_mag
+#define	f_size	f.fo_size
+
+#define	e_cepoch e.eo_cepoch
+#define	e_epoch	e.eo_epoch
+#define	e_inc	e.eo_inc
+#define	e_Om	e.eo_Om
+#define	e_om	e.eo_om
+#define	e_a	e.eo_a
+#define	e_e	e.eo_e
+#define	e_M	e.eo_M
+#define	e_size	e.eo_size
+#define	e_mag	e.eo_mag
+
+#define	h_epoch	h.ho_epoch
+#define	h_ep	h.ho_ep
+#define	h_inc	h.ho_inc
+#define	h_Om	h.ho_Om
+#define	h_om	h.ho_om
+#define	h_e	h.ho_e
+#define	h_qp	h.ho_qp
+#define	h_g	h.ho_g
+#define	h_k	h.ho_k
+#define	h_size	h.ho_size
+
+#define	p_epoch	p.po_epoch
+#define	p_ep	p.po_ep
+#define	p_inc	p.po_inc
+#define	p_qp	p.po_qp
+#define	p_om	p.po_om
+#define	p_Om	p.po_Om
+#define	p_g	p.po_g
+#define	p_k	p.po_k
+#define	p_size	p.po_size
+
+#define	es_epoch	es.eso_epoch
+#define	es_inc		es.eso_inc
+#define	es_raan		es.eso_raan
+#define	es_e		es.eso_e
+#define	es_ap		es.eso_ap
+#define	es_M		es.eso_M
+#define	es_n		es.eso_n
+#define	es_decay	es.eso_decay
+#define	es_drag		es.eso_drag
+#define	es_orbit	es.eso_orbit
+
+/* insure we always refer to the fields and no monkey business */
+#undef OBJ_COMMON_FLDS
+#undef OBJ_SOLSYS_FLDS
+
+/* o_type code.
+ * N.B. names are assigned in order in objmenu.c
+ * N.B. if add one: update the size init in db_init(); switch in obj_cir().
+ * N.B. UNDEFOBJ must be zero so new objects are undefinied by being zeroed.
+ * N.B. maintain the bitmasks too.
+ * N.B. PLANET must be last -- see objmenu.c
+ */
+enum ObjType {
+    UNDEFOBJ=0,
+    FIXED, ELLIPTICAL, HYPERBOLIC, PARABOLIC, EARTHSAT, PLANET,
+    NOBJTYPES
+};
+
+/* types as handy bitmasks too */
+#define	FIXEDM		(1<<FIXED)
+#define	ELLIPTICALM	(1<<ELLIPTICAL)
+#define	HYPERBOLICM	(1<<HYPERBOLIC)
+#define	PARABOLICM	(1<<PARABOLIC)
+#define	EARTHSATM	(1<<EARTHSAT)
+#define	PLANETM		(1<<PLANET)
+#define	ALLM		(FIXEDM | HYPERBOLICM | PARABOLICM | EARTHSATM \
+						      | ELLIPTICALM | PLANETM)
+
+/* define a code for each member in each object type struct.
+ * making them globally unique avoids a nested switch in db_set_field() and
+ * helps with dynamic prompting based on preferences.
+ */
+enum {
+    O_TYPE, O_NAME,
+    F_RA, F_DEC, F_EPOCH, F_MAG, F_SIZE, F_CLASS, F_SPECT,
+    E_INC, E_LAN, E_AOP, E_A, E_N, E_E, E_M, E_CEPOCH, E_EPOCH,E_M1,E_M2,E_SIZE,
+    H_EP, H_INC, H_LAN, H_AOP, H_E, H_QP, H_EPOCH, H_G, H_K, H_SIZE,
+    P_EP, P_INC, P_AOP, P_QP, P_LAN, P_EPOCH, P_G, P_K, P_SIZE,
+    ES_EPOCH,ES_INC,ES_RAAN,ES_E,ES_AP,ES_M,ES_N,ES_DECAY,ES_ORBIT,ES_DRAG
+};
+
+/* rise, set and transit information.
+ */
+typedef struct {
+    int rs_flags;	/* info about what has been computed and any
+			 * special conditions; see flags, below.
+			 */
+    double rs_risetm;	/* mjd time of rise today */
+    double rs_riseaz;	/* azimuth of rise, rads E of N */
+    double rs_trantm;	/* mjd time of transit today */
+    double rs_tranalt;	/* altitude of transit, rads up from horizon */
+    double rs_settm;	/* mjd time of set today */
+    double rs_setaz;	/* azimuth of set, rads E of N */
+} RiseSet;
+
+/* RiseSet flags */
+#define	RS_NORISE	0x0001	/* object does not rise as such today */
+#define	RS_NOSET	0x0002	/* object does not set as such today */
+#define	RS_NOTRANS	0x0004	/* object does not transit as such today */
+#define	RS_CIRCUMPOLAR	0x0010	/* object stays up all day today */
+#define	RS_NEVERUP	0x0020	/* object never up at all today */
+#define	RS_ERROR	0x1000	/* can't figure out anything! */
+#define	RS_RISERR	(0x0100|RS_ERROR) /* error computing rise */
+#define	RS_SETERR	(0x0200|RS_ERROR) /* error computing set */
+#define	RS_TRANSERR	(0x0400|RS_ERROR) /* error computing transit */
+
+#define	is_type(op,m)	((1<<(op)->o_type) & (m))
+#define	is_planet(op,p)	(is_type(op,PLANETM) && ((ObjPl *)op)->pl_code==(p))
+#define	is_ssobj(op)	is_type(op,PLANETM|HYPERBOLICM|PARABOLICM|ELLIPTICALM)
+
+/* used to maintain progress state with db_scanint() and db_scan */
+typedef struct {
+    int m;	/* mask of *N types desired */
+    int t;	/* current Object type, as per ObjType */
+    int n;	/* number of objects "scanned" so far */
+    ObjF *op;	/* local list to also scan */
+    int nop;	/* number in op[] */
+} DBScan;
+
+#endif /* _CIRCUM_H */
+
+
+
+/* Some handy declarations */
+
+/* ap_as.c */
+extern void ap_as P_(( Now *np, double Mjd, double *rap, double *decp));
+extern void as_ap P_(( Now *np, double Mjd, double *rap, double *decp));
+
+/* aux.c */
+extern double mm_mjed P_((Now *np));
+
+/* circum.c */
+extern int obj_cir P_((Now *np, Obj *op));
+
+/* earthsat.c */
+extern int obj_earthsat P_((Now *np, Obj *op));
+
+/* dbfmt.c */
+extern int db_crack_line P_((char s[], Obj *op, char whynot[]));
+extern void db_write_line P_((Obj *op, char *lp));
+extern int get_fields P_((char *s, int delim, char *fields[]));
+extern int db_chk_planet P_((char name[], Obj *op));
+extern int db_tle P_((char *name, char *l1, char *l2, Obj *op));
+
+/* misc.c */
+extern void now_lst P_((Now *np, double *lstp));
+extern void radec2ha P_((Now *np, double ra, double dec, double *hap));
+extern char *obj_description P_((Obj *op));
+extern int is_deepsky P_((Obj *op));
+
+/* riset_cir.c */
+extern void riset_cir P_((Now *np, Obj *op, double dis, RiseSet *rp));
+extern void twilight_cir P_((Now *np, double dis, double *dawn, double *dusk,
+    int *status));
+
+/* For RCS Only -- Do Not Edit
+ * @(#) $RCSfile: circum.h,v $ $Date: 2001-10-22 12:08:26 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $
+ */
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/comet.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/comet.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/comet.c	(revision 2309)
@@ -0,0 +1,86 @@
+#include <math.h>
+
+#include "P_.h"
+#include "astro.h"
+
+/* given a modified Julian date, mjd, and a set of heliocentric parabolic
+ * orbital elements referred to the epoch of date (mjd):
+ *   ep:   epoch of perihelion,
+ *   inc:  inclination,
+ *   ap:   argument of perihelion (equals the longitude of perihelion minus the
+ *	   longitude of ascending node)
+ *   qp:   perihelion distance,
+ *   om:   longitude of ascending node;
+ * find:
+ *   lpd:  heliocentric longitude, 
+ *   psi:  heliocentric latitude,
+ *   rp:   distance from the sun to the planet, 
+ *   rho:  distance from the Earth to the planet,
+ *   lam:  geocentric ecliptic longitude, 
+ *   bet:  geocentric ecliptic latitude,
+ *         none are corrected for light time, ie, they are the true values for
+ *	   the given instant.
+ *
+ * all angles are in radians, all distances in AU.
+ * mutual perturbation corrections with other solar system objects are not
+ * applied. corrections for nutation and abberation must be made by the caller.
+ * The RA and DEC calculated from the fully-corrected ecliptic coordinates are
+ * then the apparent geocentric coordinates. Further corrections can be made,
+ * if required, for atmospheric refraction and geocentric parallax.
+ */
+void
+comet (mjd, ep, inc, ap, qp, om, lpd, psi, rp, rho, lam, bet)
+double mjd;
+double ep, inc, ap, qp, om;
+double *lpd, *psi, *rp, *rho, *lam, *bet;
+{
+	double w, s, s2;
+	double l, sl, cl, y;
+	double spsi, cpsi;
+	double rd, lsn, rsn;
+	double lg, re, ll;
+	double cll, sll;
+	double nu;
+
+#define	ERRLMT	0.0001
+        w = ((mjd-ep)*3.649116e-02)/(qp*sqrt(qp));
+        s = w/3;
+	for (;;) {
+	    double d;
+	    s2 = s*s;
+	    d = (s2+3)*s-w;
+	    if (fabs(d) <= ERRLMT)
+		break;
+	    s = ((2*s*s2)+w)/(3*(s2+1));
+	}
+
+        nu = 2*atan(s);
+	*rp = qp*(1+s2);
+	l = nu+ap;
+        sl = sin(l);
+	cl = cos(l);
+	spsi = sl*sin(inc);
+        *psi = asin(spsi);
+	y = sl*cos(inc);
+        *lpd = atan(y/cl)+om;
+	cpsi = cos(*psi);
+        if (cl<0) *lpd += PI;
+	range (lpd, 2*PI);
+        rd = *rp * cpsi;
+	sunpos (mjd, &lsn, &rsn, 0);
+	lg = lsn+PI;
+        re = rsn;
+	ll = *lpd - lg;
+        cll = cos(ll);
+	sll = sin(ll);
+        *rho = sqrt((re * re)+(*rp * *rp)-(2*re*rd*cll));
+        if (rd<re) 
+            *lam = atan((-1*rd*sll)/(re-(rd*cll)))+lg+PI;
+	else
+	    *lam = atan((re*sll)/(rd-(re*cll)))+*lpd;
+	range (lam, 2*PI);
+        *bet = atan((rd*spsi*sin(*lam-*lpd))/(cpsi*re*sll));
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: comet.c,v $ $Date: 2001-10-22 12:08:26 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/compare_with_xephem.csh
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/compare_with_xephem.csh	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/compare_with_xephem.csh	(revision 2309)
@@ -0,0 +1,39 @@
+#!/bin/csh
+
+if( "$1" == "-h" ) then
+  echo 'Placez vous dans le repertoire ou vous avez'
+  echo 'mis le NOUVEAU code du libastro de Xephem.'
+  echo '> $DPCSOURCE/XephemAstroLib/compare_with_xephem.csh'
+  exit -1
+endif
+
+set dir = $DPCSOURCE/XephemAstroLib/
+set log = `pwd`/compare.log
+
+rm -f $log; touch $log
+
+echo ======================= NOUVEAU REPERTOIRE >>& $log
+ls *.h >>& $log
+ls *.c >>& $log
+
+echo ======================= REPERTOIRE $dir >>& $log
+pushd $dir
+ls *.h  >>& $log
+ls *.c >>& $log
+popd
+
+echo ======================= INCLUDE >>& $log
+foreach f ( *.h )
+  echo ======================= $f >>& $log
+  diff $f $dir/$f >>& $log
+end
+
+echo ======================= FICHIERS >>& $log
+foreach f ( *.c )
+  echo ======================= $f >>& $log
+  diff $f $dir/$f >>& $log
+end
+
+echo "Resultat dans le fichier $log"
+
+exit 0
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/dbfmt.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/dbfmt.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/dbfmt.c	(revision 2309)
@@ -0,0 +1,1016 @@
+/* code to convert between .edb format and an Obj */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <math.h>
+
+#if defined(__STDC__)
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+#include "P_.h"
+#include "astro.h"
+#include "circum.h"
+#include "preferences.h"
+
+extern void zero_mem P_((void *loc, unsigned len));
+extern double atod P_((char *buf));
+
+int get_fields P_((char *s, int delim, char *fields[]));
+int db_set_field P_((char bp[], int id, PrefDateFormat pref, Obj *op));
+int db_chk_planet P_((char name[], Obj *op));
+
+#define MAXDBLINE       256     /* longest allowed db line */
+
+#define FLDSEP          ','     /* major field separator */
+#define SUBFLD          '|'     /* subfield separator */
+#define MAXFLDS 20              /* must be more than on any expected line */
+
+#define ASIZ(a) (sizeof(a)/sizeof(a[0]))
+
+static int line_candidate P_((char *buf));
+static void crack_year P_((char *bp, PrefDateFormat pref, double *p));
+static int db_get_field P_((Obj *op, int id, char *bp));
+static int tle_sum P_((char *l));
+static double tle_fld P_((char *l, int from, int thru));
+static double tle_expfld P_((char *l, int start));
+
+/* crack the given .edb database line into op.
+ * if ok
+ *   return 0
+ * else
+ *   if whynot
+ *     if not even a candidate
+ *       set whynot[0] = '\0'
+ *     else
+ *       fill whynot with reason message.
+ *   return -1
+ */
+int
+db_crack_line (s, op, whynot)
+char s[];
+Obj *op;
+char whynot[];
+{
+	char *flds[MAXFLDS];	/* point to each field for easy reference */
+	char *sflds[MAXFLDS];	/* point to each sub field for easy reference */
+	char copy[MAXDBLINE];	/* work copy; leave s untouched */
+	int nf, nsf;		/* number of fields and subfields */
+	int i;
+
+	/* basic initial check */
+	if (line_candidate (s) < 0) {
+	    if (whynot)
+		whynot[0] = '\0';
+	    return (-1);
+	}
+
+	/* do all the parsing on a copy */
+	(void) strcpy (copy, s);
+	i = strlen(copy);
+	if (copy[i-1] == '\n')
+	    copy[i-1] = '\0';
+
+	/* parse into main fields */
+	nf = get_fields (copy, FLDSEP, flds);
+
+	/* need at least 2: name and type */
+	if (nf < 2) {
+	    if (whynot)
+		sprintf (whynot, "Found only %d fields", nf);
+	    return (-1);
+	}
+
+	/* switch out on type of object - the second field */
+	switch (flds[1][0]) {
+	case 'f': {
+	    static int ids[] = {F_RA, F_DEC, F_MAG};
+	    if (nf < 5 || nf > 7) {
+		if (whynot)
+		    sprintf (whynot, "f needs 5-7 fields: %d", nf);
+		return (-1);
+	    }
+	    zero_mem ((void *)op, sizeof(ObjF));
+	    op->o_type = FIXED;
+	    nsf = get_fields(flds[1], SUBFLD, sflds);
+	    if (nsf > 1 && db_set_field (sflds[1], F_CLASS, PREF_MDY, op) < 0) {
+		if (whynot)
+		    sprintf (whynot, "Bad f class: %c", sflds[1][0]);
+		return (-1);
+	    }
+	    if (nsf > 2)
+		(void) db_set_field (sflds[2], F_SPECT, PREF_MDY, op);
+	    for (i = 2; i < ASIZ(ids)+2; i++)
+		(void) db_set_field (flds[i], ids[i-2], PREF_MDY, op);
+	    (void) db_set_field (nf>5 && flds[5][0] ? flds[5] : "2000",
+							F_EPOCH, PREF_MDY, op);
+	    if (nf == 7)
+		(void) db_set_field (flds[6], F_SIZE, PREF_MDY, op);
+	    break;
+	}
+
+	case 'e': {
+	    static int ids[] = {E_INC, E_LAN, E_AOP, E_A, E_N, E_E, E_M,
+						E_CEPOCH, E_EPOCH, E_M1, E_M2
+	    };
+	    if (nf != 13 && nf != 14) {
+		if (whynot)
+		    sprintf (whynot, "e needs 13 or 14 fields: %d", nf);
+		return (-1);
+	    }
+	    zero_mem ((void *)op, sizeof(ObjE));
+	    op->o_type = ELLIPTICAL;
+	    for (i = 2; i < ASIZ(ids)+2; i++)
+		(void) db_set_field (flds[i], ids[i-2], PREF_MDY, op);
+	    if (nf == 14)
+		(void) db_set_field (flds[13], E_SIZE, PREF_MDY, op);
+	    break;
+	}
+
+	case 'h': {
+	    static int ids[]= {H_EP,H_INC,H_LAN,H_AOP,H_E,H_QP,H_EPOCH,H_G,H_K};
+	    if (nf != 11 && nf != 12) {
+		if (whynot)
+		    sprintf (whynot, "h needs 11 or 12 fields: %d", nf);
+		return (-1);
+	    }
+	    zero_mem ((void *)op, sizeof(ObjH));
+	    op->o_type = HYPERBOLIC;
+	    for (i = 2; i < ASIZ(ids)+2; i++)
+		(void) db_set_field (flds[i], ids[i-2], PREF_MDY, op);
+	    if (nf == 12)
+		(void) db_set_field (flds[11], H_SIZE, PREF_MDY, op);
+	    break;
+	}
+
+	case 'p': {
+	    static int ids[] = {P_EP,P_INC,P_AOP,P_QP,P_LAN,P_EPOCH,P_G,P_K};
+	    if (nf != 10 && nf != 11) {
+		if (whynot)
+		    sprintf (whynot, "p needs 10 or 11 fields: %d", nf);
+		return (-1);
+	    }
+	    zero_mem ((void *)op, sizeof(ObjP));
+	    op->o_type = PARABOLIC;
+	    for (i = 2; i < ASIZ(ids)+2; i++)
+		(void) db_set_field (flds[i], ids[i-2], PREF_MDY, op);
+	    if (nf == 11)
+		(void) db_set_field (flds[10], P_SIZE, PREF_MDY, op);
+	    break;
+	}
+
+	case 'E': {
+	    static int ids[] = {ES_EPOCH,ES_INC,ES_RAAN,ES_E,ES_AP,ES_M,ES_N,
+							    ES_DECAY,ES_ORBIT};
+	    if (nf != 11 && nf != 12) {
+		if (whynot)
+		    sprintf (whynot, "E needs 11 or 12 fields: %d", nf);
+		return (-1);
+	    }
+	    zero_mem ((void *)op, sizeof(ObjES));
+	    op->o_type = EARTHSAT;
+	    for (i = 2; i < ASIZ(ids)+2; i++)
+		(void) db_set_field (flds[i], ids[i-2], PREF_MDY, op);
+	    if (nf == 12)
+		(void) db_set_field (flds[11], ES_DRAG, PREF_MDY, op);
+	    break;
+	}
+
+	case 'P':
+	    /* allow, though ignore, anything after the P */
+	    i = db_chk_planet (flds[0], op);	/* does o_name too */
+	    if (i < 0) {
+		if (whynot)
+		    sprintf (whynot, "Bad planet: %s", flds[0]);
+	    }
+	    return (i);
+
+	default:
+	    if (whynot)
+		sprintf (whynot, "Unknown type: %c", flds[1][0]);
+	    return (-1);
+	}
+
+	/* load up o_name */
+	(void) db_set_field (flds[0], O_NAME, PREF_MDY, op);
+
+	return (0);
+}
+
+/* return 0 if TLE checksum is ok, else -1 */
+static int
+tle_sum (l)
+char *l;
+{
+	char *lastl = l + 68;
+	int sum;
+
+	for (sum = 0; l < lastl; ) {
+	    char c = *l++;
+	    if (c == '\0')
+		return (-1);
+	    if (isdigit(c))
+		sum += c - '0';
+	    else if (c == '-')
+		sum++;
+	}
+
+	return (*l - '0' == (sum%10) ? 0 : -1);
+}
+
+/* extract the given columns and return value.
+ * N.B. from and to are 1-based within l
+ */
+static double
+tle_fld (l, from, thru)
+char *l;
+int from, thru;
+{
+	char buf[32];
+
+	sprintf (buf, "%.*s", thru-from+1, l+from-1);
+	return (atod (buf));
+}
+
+/* extract the exponential value starting at the given column.
+ * N.B. start is 1-based within l
+ */
+static double
+tle_expfld (l, start)
+char *l;
+int start;
+{
+	char buf[32];
+	double v;
+
+	sprintf (buf, ".%.*s", 5, l+start);
+	v = atod (buf) * pow (10.0, tle_fld(l, start+6, start+7));
+	if (l[start-1] == '-')
+	    v = -v;
+	return (v);
+}
+
+/* given 3 lines, first of which is name and next 2 are TLE, fill op.
+ * we skip leading whitespace on all lines.
+ * we do /not/ assume the 2 TLE lines are 0 terminated, but we do reach out into
+ *   each as far as 69 chars.
+ * we detect nonconformance as efficiently as possible.
+ * name ends at first '\0', '\r' or '\n'.
+ * if ok return 0 else return -1
+ */
+int
+db_tle (name, l1, l2, op)
+char *name, *l1, *l2;
+Obj *op;
+{
+	double ep;
+	int i;
+
+	/* check for correct line numbers, macthing satellite numbers and
+	 * correct checksums.
+	 */
+	while (isspace(*l1))
+	    l1++;
+	if (*l1 != '1')
+	    return (-1);
+	while (isspace(*l2))
+	    l2++;
+	if (*l2 != '2')
+	    return (-1);
+	if (strncmp (l1+2, l2+2, 5))
+	    return (-1);
+	if (tle_sum (l1) < 0)
+	    return (-1);
+	if (tle_sum (l2) < 0)
+	    return (-1);
+
+	/* assume it's ok from here out */
+
+	/* fresh */
+	zero_mem ((void *)op, sizeof(ObjES));
+	op->o_type = EARTHSAT;
+
+	/* name, sans leading and trailing whitespace */
+	while (isspace(*name))
+	    name++;
+	i = strcspn (name, "\r\n");
+	while (i > 0 && name[i-1] == ' ')
+	    --i;
+	if (i == 0)
+	    return (-1);
+	if (i > MAXNM-1)
+	    i = MAXNM-1;
+	sprintf (op->o_name, "%.*s", i, name);
+
+	/* goodies from "line 1" */
+	op->es_drag = (float) tle_expfld (l1, 54);
+	i = (int) tle_fld (l1, 19, 20);
+	if (i < 57)
+	    i += 100;
+	cal_mjd (1, tle_fld(l1, 21, 32), i+1900, &ep);
+	op->es_epoch = ep;
+
+	/* goodies from "line 2" */
+	op->es_n = tle_fld (l2, 53, 63);
+	op->es_inc = (float)tle_fld (l2, 9, 16);
+	op->es_raan = (float)tle_fld (l2, 18, 25);
+	op->es_e = (float)(tle_fld (l2, 27, 33) * 1e-7);
+	op->es_ap = (float)tle_fld (l2, 35, 42);
+	op->es_M = (float)tle_fld (l2, 44, 51);
+	op->es_orbit = (int)tle_fld (l2, 64, 68);
+
+	/* yes! */
+	return (0);
+}
+
+/* write the given Obj in .edb format to lp[].
+ * we do _not_ include a trailing '\n'.
+ */
+void
+db_write_line (op, lp)
+Obj *op;
+char *lp;
+{
+	int priorpref;
+	int i;
+
+	/* .edb format always uses MDY.
+	 * N.B. must restore old value before returning from here!
+	 */
+	priorpref = pref_set (PREF_DATE_FORMAT, PREF_MDY);
+
+	switch (op->o_type) {
+	case FIXED: {
+	    static int ids[] = {F_CLASS, F_SPECT, F_RA, F_DEC, F_MAG, F_EPOCH,
+		F_SIZE
+	    };
+
+	    sprintf (lp, "%s,f", op->o_name);
+	    lp += strlen(lp);
+	    for (i = 0; i < ASIZ(ids); i++)
+		lp += db_get_field (op, ids[i], lp);
+	    break;
+	    }
+
+	case ELLIPTICAL: {
+	    static int ids[] = {E_INC, E_LAN, E_AOP, E_A, E_N, E_E, E_M,
+					E_CEPOCH, E_EPOCH, E_M1, E_M2, E_SIZE
+	    };
+
+	    sprintf (lp, "%s,e", op->o_name);
+	    lp += strlen(lp);
+	    for (i = 0; i < ASIZ(ids); i++)
+		lp += db_get_field (op, ids[i], lp);
+	    break;
+	    }
+
+	case HYPERBOLIC: {
+	    static int ids[]= {H_EP, H_INC, H_LAN, H_AOP, H_E, H_QP, H_EPOCH,
+		H_G, H_K, H_SIZE
+	    };
+
+	    sprintf (lp, "%s,h", op->o_name);
+	    lp += strlen(lp);
+	    for (i = 0; i < ASIZ(ids); i++)
+		lp += db_get_field (op, ids[i], lp);
+	    break;
+	    }
+
+	case PARABOLIC: {
+	    static int ids[] = {P_EP, P_INC, P_AOP, P_QP, P_LAN, P_EPOCH, P_G,
+		P_K, P_SIZE
+	    };
+
+	    sprintf (lp, "%s,p", op->o_name);
+	    lp += strlen(lp);
+	    for (i = 0; i < ASIZ(ids); i++)
+		lp += db_get_field (op, ids[i], lp);
+	    break;
+	    }
+
+	case EARTHSAT: {
+	    static int ids[] = {ES_EPOCH, ES_INC, ES_RAAN, ES_E, ES_AP, ES_M,
+		ES_N, ES_DECAY,ES_ORBIT,ES_DRAG
+	    };
+
+	    sprintf (lp, "%s,E", op->o_name);
+	    lp += strlen(lp);
+	    for (i = 0; i < ASIZ(ids); i++)
+		lp += db_get_field (op, ids[i], lp);
+	    break;
+	    }
+
+	case PLANET:
+	    sprintf (lp, "%s,P", op->o_name);
+	    lp += strlen(lp);
+	    break;
+
+	default:
+	    printf ("Unknown type for %s: %d\n", op->o_name, op->o_type);
+	    exit(1);
+	}
+
+	/* restore date format preference */
+	(void) pref_set (PREF_DATE_FORMAT, priorpref);
+}
+
+/* given a text buffer and a field id, and a PREF_DATE_FORMAT,
+ *   set the corresponding member in *op.
+ * return 0 if ok, else -1.
+ */
+int
+db_set_field (bp, id, pref, op)
+char bp[];
+int id;
+PrefDateFormat pref;
+Obj *op;
+{
+	double tmp;
+
+	/* include all the enums and in numeric order to give us the best
+	 * possible chance the compiler will implement this as a jump table.
+	 */
+	switch (id) {
+	case O_TYPE:
+	    printf ("db_set_field: called with id==O_TYPE\n");
+	    exit(1);
+	    break;
+	case O_NAME:
+	    (void) strncpy (op->o_name, bp, sizeof(op->o_name)-1);
+	    op->o_name[sizeof(op->o_name)-1] = '\0';
+	    break;
+	case F_RA:
+	    f_scansex (radhr(op->f_RA), bp, &tmp);
+	    op->f_RA = (float) hrrad(tmp);
+	    break;
+	case F_DEC:
+	    f_scansex (raddeg(op->f_dec), bp, &tmp);
+	    op->f_dec = (float) degrad(tmp);
+	    break;
+	case F_EPOCH:
+	    tmp = op->f_epoch;
+	    crack_year (bp, pref, &tmp);
+	    op->f_epoch = (float) tmp;
+	    break;
+	case F_MAG:
+	    set_fmag (op, atod(bp));
+	    break;
+	case F_SIZE:
+	    op->f_size = (float) atod(bp);
+	    {
+		/* optional minor axis and position angle subfields */
+		char *sflds[MAXFLDS];
+		int nsf = get_fields(bp, SUBFLD, sflds);
+
+		if (nsf == 3) {
+		    set_ratio(op, op->s_size, atod(sflds[1]));
+		    set_pa(op,degrad(atod(sflds[2])));
+		} else {
+		    set_ratio(op,1,1);	/* round */
+		    set_pa(op,0.0);
+		}
+	    }
+	    break;
+	case F_CLASS:
+	    switch (bp[0]) {
+	    case 'A': case 'B': case 'C': case 'D': case 'F': case 'G':
+	    case 'H': case 'K': case 'J': case 'L': case 'M': case 'N':
+	    case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T':
+	    case 'U': case 'V':
+		op->f_class = bp[0];
+		break;
+	    default:
+		return (-1);
+	    }
+	    break;
+	case F_SPECT: {
+	    int i, j;
+	    /* fill f_spect all the way */
+	    for (i = j = 0; i < sizeof(op->f_spect); i++)
+		if ((op->f_spect[i] = bp[j]) != 0)
+		    j++;
+	    break;
+	}
+
+	case E_INC:
+	    op->e_inc = (float) atod (bp);
+	    break;
+	case E_LAN:
+	    op->e_Om = (float) atod (bp);
+	    break;
+	case E_AOP:
+	    op->e_om = (float) atod (bp);
+	    break;
+	case E_A:
+	    op->e_a = (float) atod (bp);
+	    break;
+	case E_N:
+	    /* retired */
+	    break;
+	case E_E:
+	    op->e_e = atod (bp);
+	    break;
+	case E_M:
+	    op->e_M = (float) atod (bp);
+	    break;
+	case E_CEPOCH:
+	    crack_year (bp, pref, &op->e_cepoch);
+	    break;
+	case E_EPOCH:
+	    crack_year (bp, pref, &op->e_epoch);
+	    break;
+	case E_M1:
+	    switch (bp[0]) {
+	    case 'g':
+		op->e_mag.whichm = MAG_gk;
+		bp++;
+		break;
+	    case 'H':
+		op->e_mag.whichm = MAG_HG;
+		bp++;
+		break;
+	    default:
+		/* leave type unchanged if no or unrecognized prefix */
+		break;
+	    }
+	    op->e_mag.m1 = (float) atod(bp);
+	    break;
+	case E_M2:
+	    switch (bp[0]) {
+	    case 'k':
+		op->e_mag.whichm = MAG_gk;
+		bp++;
+		break;
+	    case 'G':
+		op->e_mag.whichm = MAG_HG;
+		bp++;
+		break;
+	    default:
+		/* leave type unchanged if no or unrecognized prefix */
+		break;
+	    }
+	    op->e_mag.m2 = (float) atod(bp);
+	    break;
+	case E_SIZE:
+	    op->e_size = (float) atod (bp);
+	    break;
+
+	case H_EP:
+	    crack_year (bp, pref, &op->h_ep);
+	    break;
+	case H_INC:
+	    op->h_inc = (float) atod (bp);
+	    break;
+	case H_LAN:
+	    op->h_Om = (float) atod (bp);
+	    break;
+	case H_AOP:
+	    op->h_om = (float) atod (bp);
+	    break;
+	case H_E:
+	    op->h_e = (float) atod (bp);
+	    break;
+	case H_QP:
+	    op->h_qp = (float) atod (bp);
+	    break;
+	case H_EPOCH:
+	    crack_year (bp, pref, &op->h_epoch);
+	    break;
+	case H_G:
+	    op->h_g = (float) atod (bp);
+	    break;
+	case H_K:
+	    op->h_k = (float) atod (bp);
+	    break;
+	case H_SIZE:
+	    op->h_size = (float) atod (bp);
+	    break;
+
+	case P_EP:
+	    crack_year (bp, pref, &op->p_ep);
+	    break;
+	case P_INC:
+	    op->p_inc = (float) atod (bp);
+	    break;
+	case P_AOP:
+	    op->p_om = (float) atod (bp);
+	    break;
+	case P_QP:
+	    op->p_qp = (float) atod (bp);
+	    break;
+	case P_LAN:
+	    op->p_Om = (float) atod (bp);
+	    break;
+	case P_EPOCH:
+	    crack_year (bp, pref, &op->p_epoch);
+	    break;
+	case P_G:
+	    op->p_g = (float) atod (bp);
+	    break;
+	case P_K:
+	    op->p_k = (float) atod (bp);
+	    break;
+	case P_SIZE:
+	    op->p_size = (float) atod (bp);
+	    break;
+
+	case ES_EPOCH:
+	    crack_year (bp, pref, &op->es_epoch);
+	    break;
+	case ES_INC:
+	    op->es_inc = (float) atod (bp);
+	    break;
+	case ES_RAAN:
+	    op->es_raan = (float) atod (bp);
+	    break;
+	case ES_E:
+	    op->es_e = (float) atod (bp);
+	    break;
+	case ES_AP:
+	    op->es_ap = (float) atod (bp);
+	    break;
+	case ES_M:
+	    op->es_M = (float) atod (bp);
+	    break;
+	case ES_N:
+	    op->es_n = atod (bp);
+	    break;
+	case ES_DECAY:
+	    op->es_decay = (float) atod (bp);
+	    break;
+	case ES_ORBIT:
+	    op->es_orbit = atoi (bp);
+	    break;
+	case ES_DRAG:
+	    op->es_drag = (float) atod (bp);
+	    break;
+
+	default:
+	    printf ("BUG! db_set_field: bad id: %d\n", id);
+	    exit (1);
+	}
+
+	return (0);
+}
+
+/* given a null-terminated string, fill in fields[] with the starting addresses
+ * of each field delimited by delim or '\0'.
+ * N.B. each character matching delim is REPLACED BY '\0' IN PLACE.
+ * N.B. 0-length fields count, so even if *s=='\0' we return 1.
+ * return the number of fields.
+ */
+int
+get_fields (s, delim, fields)
+char *s;
+int delim;
+char *fields[];
+{
+	int n;
+	char c;
+
+	*fields = s;
+	n = 0;
+	do {
+	    c = *s++;
+	    if (c == delim || c == '\0') {
+		s[-1] = '\0';
+		*++fields = s;
+		n++;
+	    }
+	} while (c);
+
+	return (n);
+}
+
+/* check name for being a planet.
+ * if so, fill in *op and return 0, else return -1.
+ */
+int
+db_chk_planet (name, op)
+char name[];
+Obj *op;
+{
+	char namecpy[256];
+	int i;
+
+	/* these must match the order in astro.h */
+	static char *planet_names[] = {
+	    "Mercury", "Venus", "Mars", "Jupiter", "Saturn",
+	    "Uranus", "Neptune", "Pluto", "Sun", "Moon",
+	};
+
+	/* make a copy to match our case -- strcasecmp() not entirely portable*/
+	strcpy (namecpy, name);
+	if (islower(namecpy[0]))
+	    namecpy[0] = toupper(namecpy[0]);
+	for (i = 1; namecpy[i]; i++)
+	    if (isupper(namecpy[i]))
+		namecpy[i] = tolower(namecpy[i]);
+
+	for (i = MERCURY; i <= MOON; i++) {
+	    if (strcmp (namecpy, planet_names[i]) == 0) {
+		zero_mem ((void *)op, sizeof(ObjPl));
+		op->o_type = PLANET;
+		(void) strcpy (op->o_name, planet_names[i]);
+		op->pl.pl_code = i;
+		return (0);
+	    }
+	}
+
+	return (-1);
+}
+
+/* return 0 if buf qualifies as a database line worthy of a cracking
+ * attempt, else -1.
+ */
+static int
+line_candidate (buf)
+char *buf;
+{
+	char c = buf[0];
+
+	return (c == '#' || c == '!' || isspace(c) ? -1 : 0);
+}
+
+/* given either a decimal year (xxxx[.xxx]) or a calendar (x/x/x)
+ * and a DateFormat preference convert it to an mjd and store it at *p.
+ */
+static void
+crack_year (bp, pref, p)
+char *bp;
+PrefDateFormat pref;
+double *p;
+{
+	int m, y;
+	double d;
+
+	mjd_cal (*p, &m, &d, &y);	/* init with current */
+	f_sscandate (bp, pref, &m, &d, &y);
+	cal_mjd (m, d, y, p);
+}
+
+/* given an *op and a field id, add it to the given text buffer bp.
+ * return the number of characters added to bp.
+ */
+static int
+db_get_field (op, id, bp)
+Obj *op;
+int id;
+char *bp;
+{
+	char *bpsave = bp;
+	double tmp;
+
+	/* include all the enums and in numeric order to give us the best
+	 * possible chance the compiler will implement this as a jump table.
+	 */
+	switch (id) {
+	case F_RA:
+	    sprintf (bp, ",");
+	    bp += strlen(bp);
+	    fs_sexa (bp, radhr(op->f_RA), 2, 36000);
+	    bp += strlen(bp);
+	    break;
+	case F_DEC:
+	    sprintf (bp, ",");
+	    bp += strlen(bp);
+	    fs_sexa (bp, raddeg(op->f_dec), 3, 3600);
+	    bp += strlen(bp);
+	    break;
+	case F_EPOCH:
+	    mjd_year (op->f_epoch, &tmp);
+	    sprintf (bp, ",%.6g", tmp); /* %.7g gives 2000.001 */
+	    bp += strlen(bp);
+	    break;
+	case F_MAG:
+	    sprintf (bp, ",%6.2f", get_mag(op));
+	    bp += strlen(bp);
+	    break;
+	case F_SIZE:
+	    sprintf (bp, ",%.7g", op->f_size);
+	    bp += strlen(bp);
+	    if (op->f_ratio || op->f_pa) {
+		sprintf (bp,"|%g|%g", op->f_size*get_ratio(op),
+							    raddeg(get_pa(op)));
+		bp += strlen(bp);
+	    }
+	    break;
+	case F_CLASS:
+	    if (op->f_class) {
+		sprintf (bp, "|%c", op->f_class);
+		bp += strlen(bp);
+	    }
+	    break;
+	case F_SPECT:
+	    if (op->f_spect[0] != '\0') {
+		sprintf (bp, "|%c", op->f_spect[0]);
+		bp += strlen(bp);
+		if (op->f_spect[1] != '\0') {
+		    sprintf (bp, "%c", op->f_spect[1]);
+		    bp += strlen(bp);
+		}
+	    }
+	    break;
+
+	case E_INC:
+	    sprintf (bp, ",%.7g", op->e_inc);
+	    bp += strlen(bp);
+	    break;
+	case E_LAN:
+	    sprintf (bp, ",%.7g", op->e_Om);
+	    bp += strlen(bp);
+	    break;
+	case E_AOP:
+	    sprintf (bp, ",%.7g", op->e_om);
+	    bp += strlen(bp);
+	    break;
+	case E_A:
+	    sprintf (bp, ",%.7g", op->e_a);
+	    bp += strlen(bp);
+	    break;
+	case E_N:
+	    /* retired */
+	    sprintf (bp, ",");
+	    bp += strlen(bp);
+	    break;
+	case E_E:
+	    sprintf (bp, ",%.7g", op->e_e);
+	    bp += strlen(bp);
+	    break;
+	case E_M:
+	    sprintf (bp, ",%.7g", op->e_M);
+	    bp += strlen(bp);
+	    break;
+	case E_CEPOCH:
+	    sprintf (bp, ",");
+	    bp += strlen(bp);
+	    fs_date (bp, op->e_cepoch);
+	    bp += strlen(bp);
+	    break;
+	case E_EPOCH:
+	    sprintf (bp, ",");
+	    bp += strlen(bp);
+	    fs_date (bp, op->e_epoch);
+	    bp += strlen(bp);
+	    break;
+	case E_M1:
+	    if (op->e_mag.whichm == MAG_gk) {
+		sprintf (bp, ",g%.7g", op->e_mag.m1);
+		bp += strlen(bp);
+	    } else if (op->e_mag.whichm == MAG_HG) {
+		sprintf (bp, ",H%.7g", op->e_mag.m1);
+		bp += strlen(bp);
+	    } else {
+		sprintf (bp, ",%.7g", op->e_mag.m1);
+		bp += strlen(bp);
+	    }
+	    break;
+	case E_M2:
+	    sprintf (bp, ",%.7g", op->e_mag.m2);
+	    bp += strlen(bp);
+	    break;
+	case E_SIZE:
+	    sprintf (bp, ",%.7g", op->e_size);
+	    bp += strlen(bp);
+	    break;
+
+	case H_EP:
+	    sprintf (bp, ",");
+	    bp += strlen(bp);
+	    fs_date (bp, op->h_ep);
+	    bp += strlen(bp);
+	    break;
+	case H_INC:
+	    sprintf (bp, ",%.7g", op->h_inc);
+	    bp += strlen(bp);
+	    break;
+	case H_LAN:
+	    sprintf (bp, ",%.7g", op->h_Om);
+	    bp += strlen(bp);
+	    break;
+	case H_AOP:
+	    sprintf (bp, ",%.7g", op->h_om);
+	    bp += strlen(bp);
+	    break;
+	case H_E:
+	    sprintf (bp, ",%.7g", op->h_e);
+	    bp += strlen(bp);
+	    break;
+	case H_QP:
+	    sprintf (bp, ",%.7g", op->h_qp);
+	    bp += strlen(bp);
+	    break;
+	case H_EPOCH:
+	    sprintf (bp, ",");
+	    bp += strlen(bp);
+	    fs_date (bp, op->h_epoch);
+	    bp += strlen(bp);
+	    break;
+	case H_G:
+	    sprintf (bp, ",%.7g", op->h_g);
+	    bp += strlen(bp);
+	    break;
+	case H_K:
+	    sprintf (bp, ",%.7g", op->h_k);
+	    bp += strlen(bp);
+	    break;
+	case H_SIZE:
+	    sprintf (bp, ",%.7g", op->h_size);
+	    bp += strlen(bp);
+	    break;
+
+	case P_EP:
+	    sprintf (bp, ",");
+	    bp += strlen(bp);
+	    fs_date (bp, op->p_ep);
+	    bp += strlen(bp);
+	    break;
+	case P_INC:
+	    sprintf (bp, ",%.7g", op->p_inc);
+	    bp += strlen(bp);
+	    break;
+	case P_AOP:
+	    sprintf (bp, ",%.7g", op->p_om);
+	    bp += strlen(bp);
+	    break;
+	case P_QP:
+	    sprintf (bp, ",%.7g", op->p_qp);
+	    bp += strlen(bp);
+	    break;
+	case P_LAN:
+	    sprintf (bp, ",%.7g", op->p_Om);
+	    bp += strlen(bp);
+	    break;
+	case P_EPOCH:
+	    sprintf (bp, ",");
+	    bp += strlen(bp);
+	    fs_date (bp, op->p_epoch);
+	    bp += strlen(bp);
+	    break;
+	case P_G:
+	    sprintf (bp, ",%.7g", op->p_g);
+	    bp += strlen(bp);
+	    break;
+	case P_K:
+	    sprintf (bp, ",%.7g", op->p_k);
+	    bp += strlen(bp);
+	    break;
+	case P_SIZE:
+	    sprintf (bp, ",%.7g", op->p_size);
+	    bp += strlen(bp);
+	    break;
+
+	case ES_EPOCH:
+	    sprintf (bp, ",");
+	    bp += strlen(bp);
+	    fs_date (bp, op->es_epoch);
+	    bp += strlen(bp);
+	    break;
+	case ES_INC:
+	    sprintf (bp, ",%.7g", op->es_inc);
+	    bp += strlen(bp);
+	    break;
+	case ES_RAAN:
+	    sprintf (bp, ",%.7g", op->es_raan);
+	    bp += strlen(bp);
+	    break;
+	case ES_E:
+	    sprintf (bp, ",%.7g", op->es_e);
+	    bp += strlen(bp);
+	    break;
+	case ES_AP:
+	    sprintf (bp, ",%.7g", op->es_ap);
+	    bp += strlen(bp);
+	    break;
+	case ES_M:
+	    sprintf (bp, ",%.7g", op->es_M);
+	    bp += strlen(bp);
+	    break;
+	case ES_N:
+	    sprintf (bp, ",%.7g", op->es_n);
+	    bp += strlen(bp);
+	    break;
+	case ES_DECAY:
+	    sprintf (bp, ",%.7g", op->es_decay);
+	    bp += strlen(bp);
+	    break;
+	case ES_ORBIT:
+	    sprintf (bp, ",%d", op->es_orbit);
+	    bp += strlen(bp);
+	    break;
+	case ES_DRAG:
+	    sprintf (bp, ",%.7g", op->es_drag);
+	    bp += strlen(bp);
+	    break;
+
+	default:
+	    printf ("BUG! db_set_field: bad id: %d\n", id);
+	    exit (1);
+	}
+
+	return (bp - bpsave);
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: dbfmt.c,v $ $Date: 2001-10-22 12:08:26 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/deep.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/deep.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/deep.c	(revision 2309)
@@ -0,0 +1,790 @@
+#include <stdlib.h>
+#include <math.h>
+
+#include "deepconst.h"
+#include "satspec.h"
+
+/* *      DEEP SPACE                                         31 OCT 80 */
+/*       SUBROUTINE DEEP */
+/*       COMMON/E1/XMO,XNODEO,OMEGAO,EO,XINCL,XNO,XNDT2O, */
+/*      1           XNDD6O,BSTAR,X,Y,Z,XDOT,YDOT,ZDOT,EPOCH,DS50 */
+/*       COMMON/C1/CK2,CK4,E6A,QOMS2T,S,TOTHRD, */
+/*      1           XJ3,XKE,XKMPER,XMNPDA,AE */
+/*       COMMON/C2/DE2RA,PI,PIO2,TWOPI,X3PIO2 */
+/*       DOUBLE PRECISION EPOCH, DS50 */
+/*       DOUBLE PRECISION */
+/*      *     DAY,PREEP,XNODCE,ATIME,DELT,SAVTSN,STEP2,STEPN,STEPP */
+/*       DATA              ZNS,           C1SS,          ZES/ */
+/*      A                  1.19459E-5,    2.9864797E-6, .01675/ */
+/*       DATA              ZNL,           C1L,           ZEL/ */
+/*      A                  1.5835218E-4,  4.7968065E-7,  .05490/ */
+/*       DATA              ZCOSIS,        ZSINIS,        ZSINGS/ */
+/*      A                  .91744867,     .39785416,     -.98088458/ */
+/*       DATA              ZCOSGS,        ZCOSHS,        ZSINHS/ */
+/*      A                  .1945905,      1.0,           0.0/ */
+/*       DATA Q22,Q31,Q33/1.7891679E-6,2.1460748E-6,2.2123015E-7/ */
+/*       DATA G22,G32/5.7686396,0.95240898/ */
+/*       DATA G44,G52/1.8014998,1.0508330/ */
+/*       DATA G54/4.4108898/ */
+/*       DATA ROOT22,ROOT32/1.7891679E-6,3.7393792E-7/ */
+/*       DATA ROOT44,ROOT52/7.3636953E-9,1.1428639E-7/ */
+/*       DATA ROOT54/2.1765803E-9/ */
+/*       DATA THDT/4.3752691E-3/ */
+
+#define XMO	(sat->elem->se_XMO)
+#define XNODEO	(sat->elem->se_XNODEO)
+#define OMEGAO	(sat->elem->se_OMEGAO)
+#define EO	(sat->elem->se_EO)
+#define XINCL	(sat->elem->se_XINCL)
+#define XNO	(sat->elem->se_XNO)
+#define XNDT20	(sat->elem->se_XNDT20)
+#define XNDD60	(sat->elem->se_XNDD60)
+#define BSTAR	(sat->elem->se_BSTAR)
+#define EPOCH	(sat->elem->se_EPOCH)
+
+#define ZNS	(1.19459E-5)
+#define C1SS	(2.9864797E-6)
+#define ZES	(.01675)
+#define ZNL	(1.5835218E-4)
+#define C1L	(4.7968065E-7)
+#define ZEL	(.05490)
+#define ZCOSIS	(.91744867)
+#define ZSINIS	(.39785416)
+#define ZSINGS	(-.98088458)
+#define ZCOSGS	(.1945905)
+#define ZCOSHS	(1.0)
+#define ZSINHS	(0.0)
+
+#define Q22	(1.7891679E-6)
+#define Q31	(2.1460748E-6)
+#define Q33	(2.2123015E-7)
+#define G22	(5.7686396)
+#define G32	(0.95240898)
+#define G44	(1.8014998)
+#define G52	(1.0508330)
+#define G54	(4.4108898)
+#define ROOT22	(1.7891679E-6)
+#define ROOT32	(3.7393792E-7)
+#define ROOT44	(7.3636953E-9)
+#define ROOT52	(1.1428639E-7)
+#define ROOT54	(2.1765803E-9)
+#define THDT	(4.3752691E-3)
+
+#define IRESFL	(sat->deep->deep_flags.IRESFL)
+#define ISYNFL	(sat->deep->deep_flags.ISYNFL)
+
+#define s_SINIQ	(sat->deep->deep_s_SINIQ)
+#define s_COSIQ	(sat->deep->deep_s_COSIQ)
+#define s_OMGDT	(sat->deep->deep_s_OMGDT)
+#define ATIME	(sat->deep->deep_ATIME)
+#define D2201	(sat->deep->deep_D2201)
+#define D2211	(sat->deep->deep_D2211)
+#define D3210	(sat->deep->deep_D3210)
+#define D3222	(sat->deep->deep_D3222)
+#define D4410	(sat->deep->deep_D4410)
+#define D4422	(sat->deep->deep_D4422)
+#define D5220	(sat->deep->deep_D5220)
+#define D5232	(sat->deep->deep_D5232)
+#define D5421	(sat->deep->deep_D5421)
+#define D5433	(sat->deep->deep_D5433)
+#define DEL1	(sat->deep->deep_DEL1)
+#define DEL2	(sat->deep->deep_DEL2)
+#define DEL3	(sat->deep->deep_DEL3)
+#define E3	(sat->deep->deep_E3)
+#define EE2	(sat->deep->deep_EE2)
+#define FASX2	(sat->deep->deep_FASX2)
+#define FASX4	(sat->deep->deep_FASX4)
+#define FASX6	(sat->deep->deep_FASX6)
+#define OMEGAQ	(sat->deep->deep_OMEGAQ)
+#define PE	(sat->deep->deep_PE)
+#define PINC	(sat->deep->deep_PINC)
+#define PL	(sat->deep->deep_PL)
+#define SAVTSN	(sat->deep->deep_SAVTSN)
+#define SE2	(sat->deep->deep_SE2)
+#define SE3	(sat->deep->deep_SE3)
+#define SGH2	(sat->deep->deep_SGH2)
+#define SGH3	(sat->deep->deep_SGH3)
+#define SGH4	(sat->deep->deep_SGH4)
+#define SGHL	(sat->deep->deep_SGHL)
+#define SGHS	(sat->deep->deep_SGHS)
+#define SH2	(sat->deep->deep_SH2)
+#define SH3	(sat->deep->deep_SH3)
+#define SHS	(sat->deep->deep_SHS)
+#define SHL	(sat->deep->deep_SHL)
+#define SI2	(sat->deep->deep_SI2)
+#define SI3	(sat->deep->deep_SI3)
+#define SL2	(sat->deep->deep_SL2)
+#define SL3	(sat->deep->deep_SL3)
+#define SL4	(sat->deep->deep_SL4)
+#define SSE	(sat->deep->deep_SSE)
+#define SSG	(sat->deep->deep_SSG)
+#define SSH	(sat->deep->deep_SSH)
+#define SSI	(sat->deep->deep_SSI)
+#define SSL	(sat->deep->deep_SSL)
+#define STEP2	(sat->deep->deep_STEP2)
+#define STEPN	(sat->deep->deep_STEPN)
+#define STEPP	(sat->deep->deep_STEPP)
+#define THGR	(sat->deep->deep_THGR)
+#define XFACT	(sat->deep->deep_XFACT)
+#define XGH2	(sat->deep->deep_XGH2)
+#define XGH3	(sat->deep->deep_XGH3)
+#define XGH4	(sat->deep->deep_XGH4)
+#define XH2	(sat->deep->deep_XH2)
+#define XH3	(sat->deep->deep_XH3)
+#define XI2	(sat->deep->deep_XI2)
+#define XI3	(sat->deep->deep_XI3)
+#define XL2	(sat->deep->deep_XL2)
+#define XL3	(sat->deep->deep_XL3)
+#define XL4	(sat->deep->deep_XL4)
+#define XLAMO	(sat->deep->deep_XLAMO)
+#define XLI	(sat->deep->deep_XLI)
+#define XNI	(sat->deep->deep_XNI)
+#define XNQ	(sat->deep->deep_XNQ)
+#define XQNCL	(sat->deep->deep_XQNCL)
+#define ZMOL	(sat->deep->deep_ZMOL)
+#define ZMOS	(sat->deep->deep_ZMOS)
+
+/* *     ENTRANCE FOR DEEP SPACE INITIALIZATION */
+
+/*       ENTRY DPINIT(EQSQ,SINIQ,COSIQ,RTEQSQ,AO,COSQ2,SINOMO,COSOMO, */
+/*      1         BSQ,XLLDOT,OMGDT,XNODOT,XNODP) */
+
+void
+dpinit(SatData *sat, double EQSQ, double SINIQ, double COSIQ,
+	    double RTEQSQ, double AO, double COSQ2, double SINOMO,
+	    double COSOMO, double BSQ, double XLLDOT, double OMGDT,
+	    double XNODOT, double XNODP)
+{
+    double A1, A10, A2, A3, A4, A5, A6, A7, A8, A9, AINV2, AQNV, BFACT,
+	C, CC, COSQ, CTEM, DAY, DS50, EOC, EQ, F220, F221, F311, F321, F322,
+	F330, F441, F442, F522, F523, F542, F543, G200, G201, G211, G300,
+	G310, G322, G410, G422, G520, G521, G532, G533, GAM, PREEP, S1, S2,
+	S3, S4, S5, S6, S7, SE, SGH, SH, SI, SINI2, SINQ, SL, STEM, TEMP,
+	TEMP1, X1, X2, X3, X4, X5, X6, X7, X8, XMAO, XNO2, XNODCE, XNOI,
+	XPIDOT, Z1, Z11, Z12, Z13, Z2, Z21, Z22, Z23, Z3, Z31, Z32, Z33,
+	ZCOSG, ZCOSGL, ZCOSH, ZCOSHL, ZCOSI, ZCOSIL, ZE, ZMO, ZN, ZSING,
+	ZSINGL, ZSINH, ZSINHL, ZSINI, ZSINIL, ZX, ZY;
+
+    int c;
+#if 0
+    A1=A10=A2=A3=A4=A5=A6=A7=A8=A9=AINV2=AQNV=BFACT = signaling_nan();
+    C=CC=COSQ=CTEM=DAY=DS50=EOC=EQ=F220=F221=F311=F321=F322 = signaling_nan();
+    F330=F441=F442=F522=F523=F542=F543=G200=G201=G211=G300 = signaling_nan();
+    G310=G322=G410=G422=G520=G521=G532=G533=GAM=PREEP=S1=S2 = signaling_nan();
+    S3=S4=S5=S6=S7=SE=SGH=SH=SI=SINI2=SINQ=SL=STEM=TEMP = signaling_nan();
+    TEMP1=X1=X2=X3=X4=X5=X6=X7=X8=XMAO=XNO2=XNODCE=XNOI = signaling_nan();
+    XPIDOT=Z1=Z11=Z12=Z13=Z2=Z21=Z22=Z23=Z3=Z31=Z32=Z33 = signaling_nan();
+    ZCOSG=ZCOSGL=ZCOSH=ZCOSHL=ZCOSI=ZCOSIL=ZE=ZMO=ZN=ZSING = signaling_nan();
+    ZSINGL=ZSINH=ZSINHL=ZSINI=ZSINIL=ZX=ZY = signaling_nan();
+#endif
+    if(!sat->deep)
+	sat->deep = (struct deep_data *) malloc(sizeof(struct deep_data));
+    else
+	return;
+
+    /* init_deep(sat->deep); */
+    PREEP = 0.0;
+
+    ZCOSGL = ZCOSHL = ZCOSIL = ZSINGL = ZSINHL = ZSINIL = 0.0;
+
+    /* Save some of the arguments, for use by dpsec() and dpper() */
+    s_SINIQ = SINIQ;
+    s_COSIQ = COSIQ;
+    s_OMGDT = OMGDT;
+
+    THGR = thetag(EPOCH, &DS50);
+
+    EQ = EO;
+    XNQ = XNODP;
+    AQNV = 1.0/AO;
+    XQNCL = XINCL;
+    XMAO = XMO;
+    XPIDOT = OMGDT + XNODOT;
+    SINQ = sin(XNODEO);
+    COSQ = cos(XNODEO);
+    OMEGAQ = OMEGAO;
+
+    /* INITIALIZE LUNAR SOLAR TERMS */
+
+    DAY = DS50 + 18261.5;
+
+    if(DAY != PREEP) {
+	PREEP = DAY;
+	XNODCE = 4.5236020 - 9.2422029E-4 * DAY;
+	STEM = sin(XNODCE);
+	CTEM = cos(XNODCE);
+	ZCOSIL = .91375164 - .03568096 * CTEM;
+	ZSINIL = sqrt(1.0 - ZCOSIL * ZCOSIL);
+	ZSINHL = .089683511 * STEM / ZSINIL;
+	ZCOSHL = sqrt(1.0 - ZSINHL * ZSINHL);
+	C = 4.7199672 + .22997150 * DAY;
+	GAM = 5.8351514 + .0019443680 * DAY;
+	ZMOL = fmod(C-GAM, TWOPI);
+	ZX = .39785416 * STEM / ZSINIL;
+	ZY = ZCOSHL * CTEM + 0.91744867 * ZSINHL * STEM;
+	ZX = actan(ZX, ZY);
+	ZX = GAM + ZX - XNODCE;
+	ZCOSGL = cos(ZX);
+	ZSINGL = sin(ZX);
+	ZMOS = 6.2565837 + .017201977 * DAY;
+	ZMOS = fmod(ZMOS, TWOPI);
+    }
+
+    /* DO SOLAR TERMS */
+
+    SAVTSN = 1.0E20;
+    ZCOSG = ZCOSGS;
+    ZSING = ZSINGS;
+    ZCOSI = ZCOSIS;
+    ZSINI = ZSINIS;
+    ZCOSH = COSQ;
+    ZSINH = SINQ;
+    CC = C1SS;
+    ZN = ZNS;
+    ZE = ZES;
+    ZMO = ZMOS;
+    XNOI = 1.0 / XNQ;
+
+    for(c = 0; c < 2; c++) {
+	A1 = ZCOSG * ZCOSH + ZSING * ZCOSI * ZSINH;
+	A3 = -ZSING * ZCOSH + ZCOSG * ZCOSI * ZSINH;
+	A7 = -ZCOSG * ZSINH + ZSING * ZCOSI * ZCOSH;
+	A8 = ZSING * ZSINI;
+	A9 = ZSING * ZSINH + ZCOSG * ZCOSI * ZCOSH;
+	A10 = ZCOSG * ZSINI;
+	A2 = COSIQ * A7 + SINIQ * A8;
+	A4 = COSIQ * A9 + SINIQ * A10;
+	A5 = - SINIQ * A7 + COSIQ * A8;
+	A6 = - SINIQ * A9 + COSIQ * A10;
+
+	X1 = A1 * COSOMO + A2 * SINOMO;
+	X2 = A3 * COSOMO + A4 * SINOMO;
+	X3 = - A1 * SINOMO + A2 * COSOMO;
+	X4 = - A3 * SINOMO + A4 * COSOMO;
+	X5 = A5 * SINOMO;
+	X6 = A6 * SINOMO;
+	X7 = A5 * COSOMO;
+	X8 = A6 * COSOMO;
+
+	Z31 = 12.0 * X1 * X1 -3.0 * X3 * X3;
+	Z32 = 24.0 * X1 * X2 -6.0 * X3 * X4;
+	Z33 = 12.0 * X2 * X2 -3.0 * X4 * X4;
+	Z1 = 3.0 * (A1 * A1 + A2 * A2) + Z31 * EQSQ;
+	Z2 = 6.0 * (A1 * A3 + A2 * A4) + Z32 * EQSQ;
+	Z3 = 3.0 * (A3 * A3 + A4 * A4) + Z33 * EQSQ;
+	Z11 = -6.0 * A1 * A5 + EQSQ * (-24.0 * X1 * X7 - 6.0 * X3 * X5);
+
+	Z12 = -6.0 * (A1 * A6 + A3 * A5) +
+	    EQSQ * (-24.0 * (X2 * X7 + X1 * X8) - 6.0 * (X3 * X6 + X4 * X5));
+
+	Z13 = -6.0 * A3 * A6 + EQSQ * (-24.0 * X2 * X8 - 6.0 * X4 * X6);
+	Z21 = 6.0 * A2 * A5 + EQSQ * (24.0 * X1 * X5 - 6.0 * X3 * X7);
+
+	Z22 = 6.0 * (A4 * A5 + A2 * A6) +
+	    EQSQ * (24.0 * (X2 * X5 + X1 * X6) - 6.0 * (X4 * X7 + X3 * X8));
+
+	Z23 = 6.0 * A4 * A6 + EQSQ * (24.0 * X2 * X6 - 6.0 * X4 * X8);
+	Z1 = Z1 + Z1 + BSQ * Z31;
+	Z2 = Z2 + Z2 + BSQ * Z32;
+	Z3 = Z3 + Z3 + BSQ * Z33;
+	S3 = CC * XNOI;
+	S2 = -.5 * S3 / RTEQSQ;
+	S4 = S3 * RTEQSQ;
+	S1 = -15.0 * EQ * S4;
+	S5 = X1 * X3 + X2 * X4;
+	S6 = X2 * X3 + X1 * X4;
+	S7 = X2 * X4 - X1 * X3;
+	SE = S1 * ZN * S5;
+	SI = S2 * ZN * (Z11 + Z13);
+	SL = -ZN * S3 * (Z1 + Z3 - 14.0 - 6.0 * EQSQ);
+	SGH = S4 * ZN * (Z31 + Z33 - 6.0);
+	SH = -ZN * S2 * (Z21 + Z23);
+
+	if(XQNCL < 5.2359877E-2)
+	    SH = 0.0;
+
+	EE2 = 2.0 * S1 * S6;
+	E3 = 2.0 * S1 * S7;
+	XI2 = 2.0 * S2 * Z12;
+	XI3 = 2.0 * S2 * (Z13 - Z11);
+	XL2 = -2.0 * S3 * Z2;
+	XL3 = -2.0 * S3 * (Z3 - Z1);
+	XL4 = -2.0 * S3 * (-21.0 - 9.0 * EQSQ) * ZE;
+	XGH2 = 2.0 * S4 * Z32;
+	XGH3 = 2.0 * S4 * (Z33 - Z31);
+	XGH4 = -18.0 * S4 * ZE;
+	XH2 = -2.0 * S2 * Z22;
+	XH3 = -2.0 * S2 * (Z23 - Z21);
+
+	if(c == 0) {
+	    /* DO LUNAR TERMS */
+	    SSE = SE;
+	    SSI = SI;
+	    SSL = SL;
+	    SSH = SH / SINIQ;
+	    SSG = SGH - COSIQ * SSH;
+	    SE2 = EE2;
+	    SI2 = XI2;
+	    SL2 = XL2;
+	    SGH2 = XGH2;
+	    SH2 = XH2;
+	    SE3 = E3;
+	    SI3 = XI3;
+	    SL3 = XL3;
+	    SGH3 = XGH3;
+	    SH3 = XH3;
+	    SL4 = XL4;
+	    SGH4 = XGH4;
+
+	    ZCOSG = ZCOSGL;
+	    ZSING = ZSINGL;
+	    ZCOSI = ZCOSIL;
+	    ZSINI = ZSINIL;
+	    ZCOSH = ZCOSHL * COSQ + ZSINHL * SINQ;
+	    ZSINH = SINQ * ZCOSHL - COSQ * ZSINHL;
+	    ZN = ZNL;
+	    CC = C1L;
+	    ZE = ZEL;
+	    ZMO = ZMOL;
+	}
+    }
+
+    SSE = SSE + SE;
+    SSI = SSI + SI;
+    SSL = SSL + SL;
+    SSG = SSG + SGH - COSIQ / SINIQ * SH;
+    SSH = SSH + SH / SINIQ;
+
+    /* GEOPOTENTIAL RESONANCE INITIALIZATION FOR 12 HOUR ORBITS */
+
+    IRESFL = 0;
+    ISYNFL = 0;
+
+    if(XNQ <= .0034906585 || XNQ >= .0052359877) {
+
+	if(XNQ < (8.26E-3) || XNQ > (9.24E-3))
+	    return;
+
+	if(EQ < 0.5)
+	    return;
+
+	IRESFL = 1;
+	EOC = EQ * EQSQ;
+	G201 = -.306 - (EQ - .64) * .440;
+
+	if(EQ <= (.65)) {
+	    G211 = 3.616 - 13.247 * EQ + 16.290 * EQSQ;
+	    G310 = -19.302 + 117.390 * EQ - 228.419 * EQSQ + 156.591 * EOC;
+	    G322 = -18.9068 + 109.7927 * EQ - 214.6334 * EQSQ + 146.5816 * EOC;
+	    G410 = -41.122 + 242.694 * EQ - 471.094 * EQSQ + 313.953 * EOC;
+	    G422 = -146.407 + 841.880 * EQ - 1629.014 * EQSQ + 1083.435 * EOC;
+	    G520 = -532.114 + 3017.977 * EQ - 5740 * EQSQ + 3708.276 * EOC;
+	} else {
+	    G211 = -72.099 + 331.819 * EQ - 508.738 * EQSQ + 266.724 * EOC;
+	    G310 = -346.844 + 1582.851 * EQ - 2415.925 * EQSQ + 1246.113 * EOC;
+	    G322 = -342.585 + 1554.908 * EQ - 2366.899 * EQSQ + 1215.972 * EOC;
+	    G410 = -1052.797 + 4758.686 * EQ - 7193.992 * EQSQ +
+		3651.957 * EOC;
+	    G422 = -3581.69 + 16178.11 * EQ - 24462.77 * EQSQ + 12422.52 * EOC;
+
+	    if(EQ > (.715))
+		G520 = -5149.66 + 29936.92 * EQ - 54087.36 * EQSQ +
+		    31324.56 * EOC;
+
+	    G520 = 1464.74 - 4664.75 * EQ + 3763.64 * EQSQ;
+	}
+
+	if(EQ < (.7)) {
+	    G533 = -919.2277 + 4988.61 * EQ - 9064.77 * EQSQ + 5542.21 * EOC;
+
+	    G521 = -822.71072 + 4568.6173 * EQ - 8491.4146 * EQSQ +
+		5337.524 * EOC;
+
+	    G532 = -853.666 + 4690.25 * EQ - 8624.77 * EQSQ + 5341.4 * EOC;
+	} else {
+	    G533 = -37995.78 + 161616.52 * EQ - 229838.2 * EQSQ +
+		109377.94 * EOC;
+
+	    G521 = -51752.104 + 218913.95 * EQ - 309468.16 * EQSQ +
+		146349.42 * EOC;
+
+	    G532 = -40023.88 + 170470.89 * EQ - 242699.48 * EQSQ +
+		115605.82 * EOC;
+	}
+
+	SINI2 = SINIQ * SINIQ;
+	F220 = .75 * (1.0 + 2.0 * COSIQ + COSQ2);
+	F221 = 1.5 * SINI2;
+	F321 = 1.875 * SINIQ * (1.0 - 2.0 * COSIQ - 3.0 * COSQ2);
+	F322 = -1.875 * SINIQ * (1.0 + 2.0 * COSIQ - 3.0 * COSQ2);
+	F441 = 35.0 * SINI2 * F220;
+	F442 = 39.3750 * SINI2 * SINI2;
+
+	F522 = 9.84375 * SINIQ * (SINI2 * (1.0 - 2.0 * COSIQ - 5.0 * COSQ2) +
+				  .33333333 * (-2.0 + 4.0 * COSIQ +
+					       6.0 * COSQ2));
+
+	F523 = SINIQ * (4.92187512 * SINI2 * (-2.0 - 4.0 * COSIQ +
+					      10.0 * COSQ2) +
+					      6.56250012 * (1.0 +
+							    2.0 * COSIQ -
+							    3.0 * COSQ2));
+
+	F542 = 29.53125 * SINIQ * (2.0 - 8.0 * COSIQ +
+				   COSQ2 * (-12.0 + 8.0 * COSIQ +
+					    10.0 * COSQ2));
+
+	F543 = 29.53125 * SINIQ * (-2.0 - 8.0 * COSIQ +
+				   COSQ2 * (12.0 + 8.0 * COSIQ -
+					    10.0 * COSQ2));
+
+	XNO2 = XNQ * XNQ;
+	AINV2 = AQNV * AQNV;
+	TEMP1 = 3.0 * XNO2 * AINV2;
+	TEMP = TEMP1 * ROOT22;
+	D2201 = TEMP * F220 * G201;
+	D2211 = TEMP * F221 * G211;
+	TEMP1 = TEMP1 * AQNV;
+	TEMP = TEMP1 * ROOT32;
+	D3210 = TEMP * F321 * G310;
+	D3222 = TEMP * F322 * G322;
+	TEMP1 = TEMP1 * AQNV;
+	TEMP = 2.0 * TEMP1 * ROOT44;
+	D4410 = TEMP * F441 * G410;
+	D4422 = TEMP * F442 * G422;
+	TEMP1 = TEMP1 * AQNV;
+	TEMP = TEMP1 * ROOT52;
+	D5220 = TEMP * F522 * G520;
+	D5232 = TEMP * F523 * G532;
+	TEMP = 2.0 * TEMP1 * ROOT54;
+	D5421 = TEMP * F542* G521;
+	D5433 = TEMP * F543* G533;
+	XLAMO = XMAO + XNODEO + XNODEO - THGR - THGR;
+	BFACT = XLLDOT + XNODOT + XNODOT - THDT - THDT;
+	BFACT = BFACT + SSL + SSH + SSH;
+    } else {
+	/* SYNCHRONOUS RESONANCE TERMS INITIALIZATION */
+
+	IRESFL = 1;
+	ISYNFL = 1;
+	G200 = 1.0 + EQSQ * (-2.5 + .8125 * EQSQ);
+	G310 = 1.0 + 2.0 * EQSQ;
+	G300 = 1.0 + EQSQ * (-6.0 + 6.60937 * EQSQ);
+	F220 = .75 * (1.0 + COSIQ) * (1.0 + COSIQ);
+	F311 = .9375 * SINIQ * SINIQ * (1.0 + 3.0 * COSIQ) -
+	    .75 * (1.0 + COSIQ);
+	F330 = 1.0 + COSIQ;
+	F330 = 1.875 * F330 * F330 * F330;
+	DEL1 = 3.0 * XNQ * XNQ * AQNV * AQNV;
+	DEL2 = 2.0 * DEL1 * F220 * G200 * Q22;
+	DEL3 = 3.0 * DEL1 * F330 * G300 * Q33 * AQNV;
+	DEL1 = DEL1 * F311 * G310 * Q31 * AQNV;
+	FASX2 = .13130908;
+	FASX4 = 2.8843198;
+	FASX6 = .37448087;
+	XLAMO = XMAO + XNODEO + OMEGAO - THGR;
+	BFACT = XLLDOT + XPIDOT - THDT;
+	BFACT = BFACT + SSL + SSG + SSH;
+
+    }
+
+    XFACT = BFACT - XNQ;
+
+    XLI = XLAMO;
+    XNI = XNQ;
+    ATIME = 0.0;
+    STEPP = 720.0;
+    STEPN = -720.0;
+    STEP2 = 259200.0;
+}
+
+/* ENTRANCE FOR DEEP SPACE SECULAR EFFECTS */
+
+void
+dpsec(SatData *sat, double *XLL, double *OMGASM, double *XNODES,
+	   double *EM, double *XINC, double *XN, double T)
+{
+    double DELT, XL, TEMP, XOMI, X2OMI, X2LI, XLDOT;
+    double XNDOT, XNDDT, FT;
+    int state, iret, iretn, done;
+
+    DELT = XLDOT = XNDOT = XNDDT = FT = 0.0;
+    iret = iretn = 0;
+
+#if 0
+    DELT = XL = TEMP = XOMI = X2OMI = X2LI = XLDOT = signaling_nan();
+    XNDOT = XNDDT = FT = signaling_nan();
+#endif
+
+    *XLL = *XLL + SSL * T;
+    *OMGASM = *OMGASM + SSG * T;
+    *XNODES = *XNODES + SSH * T;
+    *EM = EO + SSE * T;
+    *XINC = XINCL + SSI * T;
+
+    if(*XINC < 0.0) {
+	*XINC = -*XINC;
+	*XNODES = *XNODES + PI;
+	*OMGASM = *OMGASM - PI;
+    }
+
+    if(IRESFL == 0)
+	return;
+
+    state = 1;
+    done = 0;
+    while(!done) {
+	/* printf("state = %d\n", state); */
+	switch(state) {
+	case 1:
+	    /*
+	     * Chunk #1
+	     */
+	    if(ATIME == 0.0 || (T >= 0.0 && ATIME < 0.0) ||
+	       (T < 0.0 && ATIME >= 0.0)) {
+		/*
+		 * Chunk #10
+		 */
+		if(T >= 0.0)
+		    DELT = STEPP;
+		else
+		    DELT = STEPN;
+
+		ATIME = 0.0;
+		XNI = XNQ;
+		XLI = XLAMO;
+		state = 4;
+		break;
+	    }
+
+	    /* Fall through */
+	case 2:
+	    /*
+	     * Chunk #2
+	     */
+	    if(fabs(T) < fabs(ATIME)) {
+		/*
+		 * Chunk #2
+		 */
+		if(T >= 0.0)
+		    DELT = STEPN;
+		else
+		    DELT = STEPP;
+
+		iret = 1;
+		state = 8;
+		break;
+	    }
+
+	    /*
+	     * Chunk #3
+	     */
+	    if(T > 0.0)
+		DELT = STEPP;
+	    else
+		DELT = STEPN;
+
+	    /* fall through */
+	case 4:
+	    /*
+	     * Chunk #4
+	     */
+	    if(fabs(T - ATIME) >= STEPP) {
+		iret = 4;
+		state = 8;
+	    } else {
+		/*
+		 * Chunk #5
+		 */
+		FT = T - ATIME;
+		iretn = 6;
+		state = 7;
+	    }
+
+	    break;
+
+	case 6:
+	    /*
+	     * Chunk #6
+	     */
+	    *XN = XNI + XNDOT * FT + XNDDT * FT * FT * 0.5;
+	    XL = XLI + XLDOT * FT + XNDOT * FT * FT * 0.5;
+	    TEMP = -*XNODES + THGR + T * THDT;
+
+	    if(ISYNFL == 0)
+		*XLL = XL + 2.0 * TEMP;
+	    else
+		*XLL = XL - *OMGASM + TEMP;
+
+	    done = 1;
+	    break;
+
+	case 7:
+	    /* DOT TERMS CALCULATED */
+
+	    /*
+	     * Chunk #7
+	     */
+	    if(ISYNFL != 0) {
+		XNDOT =
+		    DEL1 * sin(XLI - FASX2) +
+		    DEL2 * sin(2.0 * (XLI - FASX4)) +
+		    DEL3 * sin(3.0 * (XLI - FASX6));
+
+		XNDDT =
+		    DEL1 * cos(XLI - FASX2) +
+		    2.0 * DEL2 * cos(2.0 * (XLI - FASX4)) +
+		    3.0 * DEL3 * cos(3.0 * (XLI - FASX6));
+	    } else {
+		XOMI = OMEGAQ + s_OMGDT * ATIME;
+		X2OMI = XOMI + XOMI;
+		X2LI = XLI + XLI;
+		XNDOT = D2201 * sin(X2OMI + XLI - G22) +
+		    D2211 * sin(XLI - G22) +
+		    D3210 * sin(XOMI + XLI - G32) +
+		    D3222 * sin(- XOMI + XLI - G32) +
+		    D4410 * sin(X2OMI + X2LI - G44) +
+		    D4422 * sin(X2LI - G44) +
+		    D5220 * sin(XOMI + XLI - G52) +
+		    D5232 * sin(- XOMI + XLI - G52) +
+		    D5421 * sin(XOMI + X2LI - G54) +
+		    D5433 * sin(- XOMI + X2LI - G54);
+
+		XNDDT = D2201 * cos(X2OMI + XLI - G22) +
+		    D2211 * cos(XLI - G22) +
+		    D3210 * cos(XOMI + XLI - G32) +
+		    D3222 * cos(- XOMI + XLI - G32) +
+		    D5220 * cos(XOMI + XLI - G52) +
+		    D5232 * cos(- XOMI + XLI - G52) +
+		    2.*(D4410 * cos(X2OMI + X2LI - G44) +
+			D4422 * cos(X2LI - G44) +
+			D5421 * cos(XOMI + X2LI - G54) +
+			D5433 * cos(- XOMI + X2LI - G54));
+	    }
+
+	    XLDOT = XNI + XFACT;
+	    XNDDT = XNDDT * XLDOT;
+
+	    state = iretn;
+	    break;
+
+	case 8:
+	    /*
+	     * Chunk #8
+	     */
+
+	    /* INTEGRATOR */
+	    iretn = 9;
+	    state = 7;
+	    break;
+
+	case 9:
+	    XLI = XLI + XLDOT * DELT + XNDOT * STEP2;
+	    XNI = XNI + XNDOT * DELT + XNDDT * STEP2;
+	    ATIME = ATIME + DELT;
+
+	    state = iret;
+	    break;
+	}
+    }
+}
+
+/* local */
+
+/* C */
+/* C     ENTRANCES FOR LUNAR-SOLAR PERIODICS */
+/* C */
+/* C */
+/*       ENTRY DPPER(EM,XINC,OMGASM,XNODES,XLL) */
+void
+dpper(SatData *sat, double *EM, double *XINC, double *OMGASM,
+	   double *XNODES, double *XLL, double T)
+{
+    double SINIS, COSIS, ZM, ZF, SINZF, F2, F3, SES, SIS, SLS, SEL, SIL, SLL, PGH, PH, SINOK, COSOK, ALFDP, BETDP, DALF, DBET, XLS, DLS;
+
+#if 0
+    SINIS = COSIS = ZM = ZF = SINZF = F2 = F3 = SES = SIS = signaling_nan();
+    SLS = SEL = SIL = SLL = PGH = signaling_nan();
+    PH = SINOK = COSOK = ALFDP = BETDP = DALF = DBET = XLS = signaling_nan();
+    DLS = signaling_nan();;
+#endif
+    SINIS = sin(*XINC);
+    COSIS = cos(*XINC);
+
+
+/*       IF (DABS(SAVTSN-T).LT.(30.D0))    GO TO 210 */
+    if(fabs(SAVTSN - T) >= (30.0)) {
+	SAVTSN = T;
+	ZM = ZMOS + ZNS * T;
+/*   205 ZF = ZM + 2.0 * ZES * sin(ZM) */
+	ZF = ZM + 2.0 * ZES * sin(ZM);
+	SINZF = sin(ZF);
+	F2 = .5 * SINZF * SINZF - .25;
+	F3 = -.5 * SINZF * cos(ZF);
+	SES = SE2 * F2 + SE3 * F3;
+	SIS = SI2 * F2 + SI3 * F3;
+	SLS = SL2 * F2 + SL3 * F3 + SL4 * SINZF;
+	SGHS = SGH2 * F2 + SGH3 * F3 + SGH4 * SINZF;
+	SHS = SH2 * F2 + SH3 * F3;
+	ZM = ZMOL + ZNL * T;
+	ZF = ZM + 2.0 * ZEL * sin(ZM);
+	SINZF = sin(ZF);
+	F2 = .5 * SINZF * SINZF -.25;
+	F3 = -.5 * SINZF * cos(ZF);
+	SEL = EE2 * F2 + E3 * F3;
+	SIL = XI2 * F2 + XI3 * F3;
+	SLL = XL2 * F2 + XL3 * F3 + XL4 * SINZF;
+	SGHL = XGH2 * F2 + XGH3 * F3 + XGH4 * SINZF;
+	SHL = XH2 * F2 + XH3 * F3;
+	PE = SES + SEL;
+	PINC = SIS + SIL;
+	PL = SLS + SLL;
+    }
+
+/*   210 PGH=SGHS+SGHL */
+    PGH = SGHS + SGHL;
+    PH = SHS + SHL;
+    *XINC = *XINC + PINC;
+    *EM = *EM + PE;
+
+/*       IF(XQNCL.LT.(.2)) GO TO 220 */
+    if(XQNCL >= (.2)) {
+/*       GO TO 218 */
+/* C */
+/* C     APPLY PERIODICS DIRECTLY */
+/* C */
+/*   218 PH=PH/SINIQ */
+	PH = PH / s_SINIQ;
+	PGH = PGH - s_COSIQ * PH;
+	*OMGASM = *OMGASM + PGH;
+	*XNODES = *XNODES + PH;
+	*XLL = *XLL + PL;
+/*       GO TO 230 */
+    } else {
+/* C */
+/* C     APPLY PERIODICS WITH LYDDANE MODIFICATION */
+/* C */
+/*   220 SINOK=sin(XNODES) */
+	SINOK = sin(*XNODES);
+	COSOK = cos(*XNODES);
+	ALFDP = SINIS * SINOK;
+	BETDP = SINIS * COSOK;
+	DALF = PH * COSOK + PINC * COSIS * SINOK;
+	DBET = -PH * SINOK + PINC * COSIS * COSOK;
+	ALFDP = ALFDP + DALF;
+	BETDP = BETDP + DBET;
+	XLS = *XLL + *OMGASM + COSIS * *XNODES;
+	DLS = PL + PGH - PINC * *XNODES * SINIS;
+	XLS = XLS + DLS;
+	*XNODES = actan(ALFDP, BETDP);
+	*XLL = *XLL + PL;
+	*OMGASM = XLS - *XLL - cos(*XINC) * *XNODES;
+    }
+/*   230 CONTINUE */
+/*       RETURN */
+
+}
+/*       END */
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: deep.c,v $ $Date: 2001-10-22 12:08:26 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/deepconst.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/deepconst.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/deepconst.h	(revision 2309)
@@ -0,0 +1,34 @@
+#ifndef _CONST_H
+#define _CONST_H
+
+/* $Id: deepconst.h,v 1.2 2001-10-22 12:08:26 cmv Exp $ */
+
+
+#define GE (3.986005E14)
+
+#define PI (3.1415926535897932385)
+
+#define XKE	(7.43669161E-2)
+#define CK2	(5.413080E-4)
+#define CK4	(6.2098875E-7)
+#define E6A	(10E6)
+#define QOMS2T	(1.88027916E-9)
+#define S	(1.01222928)
+#define TOTHRD	(2.0/3.0) /* 6.6666666666666666667E-1 */
+#define XJ3	(-2.53881E-6)
+/* #define XKE	KE */
+#define XKMPER	(6378.135)
+#define XMNPDA	(1440.0)
+#define AE	(1.0)
+#define DE2RA	(1.7453292519943295769E-2)
+#define PIO2	(1.57079632679489661925)	/* PI/2 */
+#define TWOPI	(6.2831853071795864770)
+#define X3PIO2	(4.7123889803846898578)	/* 3*PI/2 */
+
+#define RHO	(0.15696590235)
+
+#endif /* _CONST_H */
+
+/* For RCS Only -- Do Not Edit
+ * @(#) $RCSfile: deepconst.h,v $ $Date: 2001-10-22 12:08:26 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $
+ */
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/deltat.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/deltat.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/deltat.c	(revision 2309)
@@ -0,0 +1,307 @@
+/* DeltaT = Ephemeris Time - Universal Time
+ *
+ * original code by Stephen Moshier <moshier@world.std.com>,
+ * adapted to xephem by Michael Sternberg <sternberg@physik.tu-chemnitz.de>
+ * smoothed transitions and updated by Neal McBurnett <nealmcb@bell-labs.com>
+ *
+ **********************************************************************
+ *
+ * The tabulated values of deltaT, in hundredths of a second,
+ * were taken from The Astronomical Almanac, page K8.  The program
+ * adjusts for a value of secular tidal acceleration ndot = -25.8
+ * arcsec per century squared, the value used in JPL's DE403 ephemeris.
+ * ELP2000 (and DE200) used the value -23.8946.
+ *
+ * The tabulated range is 1620.0 through 1998.0.  Bessel's interpolation
+ * formula is implemented to obtain fourth order interpolated values at
+ * intermediate times.
+ *
+ * For dates earlier than the tabulated range, the program
+ * calculates approximate formulae of Stephenson and Morrison
+ * or K. M. Borkowski.  These approximations have an estimated
+ * error of 15 minutes at 1500 B.C.  They are not adjusted for small
+ * improvements in the current estimate of ndot because the formulas
+ * were derived from studies of ancient eclipses and other historical
+ * information, whose interpretation depends only partly on ndot.
+ *
+ * For future vaues of deltaT, the function smoothly transitions with
+ * a linear segment back to Stephenson & Morrison's quadratic formula
+ * in 2130.
+ *
+ * Input is mjd (modified julian date from MJD0 on). [stern]
+ *  Note that xephem uses a different epoch for this "mjd" than the
+ *  normal value of JD=240000.5.
+ * See AA page B4.
+ *
+ * Output double deltat(mjd) is ET-UT1 in seconds.
+ *
+ *
+ * References:
+ *
+ * Stephenson, F. R., and L. V. Morrison, "Long-term changes
+ * in the rotation of the Earth: 700 B.C. to A.D. 1980,"
+ * Philosophical Transactions of the Royal Society of London
+ * Series A 313, 47-70 (1984)
+ *
+ * Borkowski, K. M., "ELP2000-85 and the Dynamical Time
+ * - Universal Time relation," Astronomy and Astrophysics
+ * 205, L8-L10 (1988)
+ * Borkowski's formula is derived from eclipses going back to 2137 BC
+ * and uses lunar position based on tidal coefficient of -23.9 arcsec/cy^2.
+ *
+ * Chapront-Touze, Michelle, and Jean Chapront, _Lunar Tables
+ * and Programs from 4000 B.C. to A.D. 8000_, Willmann-Bell 1991
+ * Their table agrees with the one here, but the entries are
+ * rounded to the nearest whole second.
+ *
+ * Stephenson, F. R., and M. A. Houlden, _Atlas of Historical
+ * Eclipse Maps_, Cambridge U. Press (1986)
+ *
+ * from obsolete extrapolation code [stern]:
+ * Morrison, L. V. and F. R. Stephenson, "Sun and Planetary System"
+ * vol 96,73 eds. W. Fricke, G. Teleki, Reidel, Dordrecht (1982)
+ *
+ **********************************************************************
+ *
+ * changes by stern:
+ *   - adopted #include's for xephem
+ *   - made dt[] static
+ *   - made mjd the time argument [was: year Y].
+ *   - updated observed and extrapolated data from tables at
+ *	ftp://maia.usno.navy.mil/ser7/ -- data deviated by up to 0.8 s
+ *   - removed references to "extern double dtgiven"
+ *   - removed DEMO #define and its references
+ *   - replaced treatment after TABEND by linear extrapolation instead
+ *	of second order version
+ *   - installed lastmjd cache (made ans static)
+ *
+ *   - no changes to table interpolation scheme and past extrapolations */
+
+#include "P_.h"
+#include "astro.h"
+
+#define TABSTART 1620.0
+#define TABEND 2006.0
+#define TABSIZ 387
+
+/* Note, Stephenson and Morrison's table starts at the year 1630.
+ * The Chapronts' table does not agree with the Almanac prior to 1630.
+ * The actual accuracy decreases rapidly prior to 1780.
+ */
+static short dt[TABSIZ] = {
+    /* 1620.0 thru 1659.0 */
+    12400, 11900, 11500, 11000, 10600, 10200, 9800, 9500, 9100, 8800,
+    8500, 8200, 7900, 7700, 7400, 7200, 7000, 6700, 6500, 6300,
+    6200, 6000, 5800, 5700, 5500, 5400, 5300, 5100, 5000, 4900,
+    4800, 4700, 4600, 4500, 4400, 4300, 4200, 4100, 4000, 3800,
+    /* 1660.0 thru 1699.0 */
+    3700, 3600, 3500, 3400, 3300, 3200, 3100, 3000, 2800, 2700,
+    2600, 2500, 2400, 2300, 2200, 2100, 2000, 1900, 1800, 1700,
+    1600, 1500, 1400, 1400, 1300, 1200, 1200, 1100, 1100, 1000,
+    1000, 1000, 900, 900, 900, 900, 900, 900, 900, 900,
+    /* 1700.0 thru 1739.0 */
+    900, 900, 900, 900, 900, 900, 900, 900, 1000, 1000,
+    1000, 1000, 1000, 1000, 1000, 1000, 1000, 1100, 1100, 1100,
+    1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100,
+    1100, 1100, 1100, 1100, 1200, 1200, 1200, 1200, 1200, 1200,
+    /* 1740.0 thru 1779.0 */
+    1200, 1200, 1200, 1200, 1300, 1300, 1300, 1300, 1300, 1300,
+    1300, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1500, 1500,
+    1500, 1500, 1500, 1500, 1500, 1600, 1600, 1600, 1600, 1600,
+    1600, 1600, 1600, 1600, 1600, 1700, 1700, 1700, 1700, 1700,
+    /* 1780.0 thru 1799.0 */
+    1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700,
+    1700, 1700, 1600, 1600, 1600, 1600, 1500, 1500, 1400, 1400,
+    /* 1800.0 thru 1819.0 */
+    1370, 1340, 1310, 1290, 1270, 1260, 1250, 1250, 1250, 1250,
+    1250, 1250, 1250, 1250, 1250, 1250, 1250, 1240, 1230, 1220,
+    /* 1820.0 thru 1859.0 */
+    1200, 1170, 1140, 1110, 1060, 1020, 960, 910, 860, 800,
+    750, 700, 660, 630, 600, 580, 570, 560, 560, 560,
+    570, 580, 590, 610, 620, 630, 650, 660, 680, 690,
+    710, 720, 730, 740, 750, 760, 770, 770, 780, 780,
+    /* 1860.0 thru 1899.0 */
+    788, 782, 754, 697, 640, 602, 541, 410, 292, 182,
+    161, 10, -102, -128, -269, -324, -364, -454, -471, -511,
+    -540, -542, -520, -546, -546, -579, -563, -564, -580, -566,
+    -587, -601, -619, -664, -644, -647, -609, -576, -466, -374,
+    /* 1900.0 thru 1939.0 */
+    -272, -154, -2, 124, 264, 386, 537, 614, 775, 913,
+    1046, 1153, 1336, 1465, 1601, 1720, 1824, 1906, 2025, 2095,
+    2116, 2225, 2241, 2303, 2349, 2362, 2386, 2449, 2434, 2408,
+    2402, 2400, 2387, 2395, 2386, 2393, 2373, 2392, 2396, 2402,
+    /* 1940.0 thru 1979.0 */
+     2433, 2483, 2530, 2570, 2624, 2677, 2728, 2778, 2825, 2871,
+     2915, 2957, 2997, 3036, 3072, 3107, 3135, 3168, 3218, 3268,
+     3315, 3359, 3400, 3447, 3503, 3573, 3654, 3743, 3829, 3920,
+     4018, 4117, 4223, 4337, 4449, 4548, 4646, 4752, 4853, 4959,
+    /* 1980.0 thru 1995.0 */
+     5054, 5138, 5217, 5296, 5379, 5434, 5487, 5532, 5582, 5630,
+     5686, 5757, 5831, 5912, 5998, 6078,
+    /* new USNO data (stern) */
+     6163, 6230,
+    /* 1999 USNO data 1998.0 thru 2000.0 (McBurnett) */
+     6297, 6347, 6383, 
+    /* 1999 extrapolation (McBurnett), 2001.0 thru 2006.0
+       Ramp up to 1.6 s/yr to transition smoothly to Stevenson formula
+       in 2130.0 */
+     6440, 6510, 6600, 6750, 6900, 7060
+
+    /* original 1997 USNO extrapolation (stern), 1998.0 thru 2004.0
+     6296, 6420,
+     6510, 6600, 6700, 6800, 6900   */ /* 7000, 7100, 7200, 7300, 7400, */
+
+    /* Extrapolated values (USNO) (original Moshier) [1996.0 thru 2005.0]
+     6183, 6280, 6377, 6475,
+     6572, 6667, 6765, 6861, 6957
+     */
+};
+
+/* calculate  DeltaT = ET - UT1 in seconds.  Describes the irregularities
+ * of the Earth rotation rate in the ET time scale.
+ */
+double deltat(mjd)
+double mjd;
+{
+	double Y;
+	double p, B;
+	int d[6];
+	int i, iy, k;
+	double floor();
+	static double ans;
+	static double lastmjd = -10000;
+
+	if (mjd == lastmjd) {
+	    return(ans);
+	}
+	lastmjd = mjd;
+
+	Y = 2000.0 + (mjd - J2000)/365.25;
+
+	if( Y > TABEND  &&  Y < 2130.0 ) {
+	    /* linear interpolation from table end; stern */
+	    B = Y - TABEND;
+	    ans = dt[TABSIZ-1] + B * (dt[TABSIZ-1]  - dt[TABSIZ-2]);
+	    ans *= 0.01;
+	    return(ans);
+	}
+
+	if( Y < TABSTART  ||  Y >= 2130.0 ) {
+	    if( (Y >= 948.0 - 15.0  &&  Y < TABSTART) ||  Y >= 2130.0 ) {
+		/* Stephenson and Morrison, stated domain is 948 to 1600:
+		 * 25.5(centuries from 1800)^2 - 1.9159(centuries from 1955)^2
+		 * Here we offset by -15 y to minimize the discontinuity,
+		 * thus we use it from 933.0 to 1620.0,
+		 * and from the end of the table to 2130.0.
+		 * f(1620.0) = 60.955200, slope -0.079 s/y
+		 * f(2004.0) = 105.649728, slope 1.02 s/y
+		 * f(2048.0) = 155.176, slope 1.23 s/y
+		 * f(2084.0) = 202.49, slope 1.4 s/y
+		 * f(2130.0) = 272, slope .1616
+	         * f(2150.0) = 305, slope .17
+		 */
+		B = 0.01*(Y - 2000.0);
+		ans = (23.58 * B + 100.3)*B + 101.6;
+	    } else {
+		/* Borkowski */
+	        /* f(2004.0) = 542.7435, slope 2.65 s/y */
+		B = 0.01*(Y - 2000.0)  +  3.75;
+		ans = 35.0 * B * B  +  40.;
+	    }
+	    return(ans);
+	}
+
+	/* Besselian interpolation from tabulated values.
+	 * See AA page K11.
+	 */
+
+	/* value for 1620.1 is 121.96 or so, not 124.0 */
+
+	/* Index into the table.
+	 */
+	p = floor(Y);
+	iy = (int)(p - TABSTART);
+	/* Zeroth order estimate is value at start of year
+	 */
+	ans = dt[iy];
+	k = iy + 1;
+	if( k >= TABSIZ )
+	    goto done; /* No data, can't go on. */
+
+	/* The fraction of tabulation interval
+	 */
+	p = Y - p;
+
+	/* First order interpolated value
+	 */
+	ans += p*(dt[k] - dt[iy]);
+	if( (iy-1 < 0) || (iy+2 >= TABSIZ) )
+	    goto done; /* can't do second differences */
+
+	/* Make table of first differences
+	 */
+	k = iy - 2;
+	for( i=0; i<5; i++ ) {
+	    if( (k < 0) || (k+1 >= TABSIZ) )
+		d[i] = 0;
+	    else d[i] = dt[k+1] - dt[k];
+		k += 1;
+	}
+
+	/* Compute second differences
+	 */
+	for( i=0; i<4; i++ )
+	    d[i] = d[i+1] - d[i];
+	B = 0.25*p*(p-1.0);
+	ans += B*(d[1] + d[2]);
+	if( iy+2 >= TABSIZ )
+	    goto done;
+
+	/* Compute third differences
+	 */
+	for( i=0; i<3; i++ )
+	    d[i] = d[i+1] - d[i];
+	B = 2.0*B/3.0;
+	ans += (p-0.5)*B*d[1];
+	if( (iy-2 < 0) || (iy+3 > TABSIZ) )
+	    goto done;
+
+	/* Compute fourth differences
+	 */
+	for( i=0; i<2; i++ )
+	    d[i] = d[i+1] - d[i];
+	B = 0.125*B*(p+1.0)*(p-2.0);
+	ans += B*(d[0] + d[1]);
+
+	done:
+	/* Astronomical Almanac table is corrected by adding the expression
+	 *     -0.000091 (ndot + 26)(year-1955)^2  seconds
+	 * to entries prior to 1955 (AA page K8), where ndot is the secular
+	 * tidal term in the mean motion of the Moon.
+	 *
+	 * Entries after 1955 are referred to atomic time standards and
+	 * are not affected by errors in Lunar or planetary theory.
+	 */
+	ans *= 0.01;
+	if( Y < 1955.0 ) {
+	    B = (Y - 1955.0);
+	    ans += -0.000091 * (-25.8 + 26.0) * B * B;
+	}
+	return( ans );
+}
+
+
+#ifdef TEST_DT
+main()
+{
+	double ans, y;
+
+	while (scanf("%lf", &y) == 1) {
+		ans = deltat((y - 2000.0)*365.25 + J2000);
+		printf("%.4lf %.4lf\n", y, ans);
+	}
+}
+#endif
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: deltat.c,v $ $Date: 2001-10-22 12:08:26 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/earthsat.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/earthsat.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/earthsat.c	(revision 2309)
@@ -0,0 +1,799 @@
+/* this file contains routines to support Earth satellites.
+ *
+ * Orbit propagation is based on the NORAD SGP4/SDP4 code, as converted from
+ *   the original FORTRAN to C by Magnus Backstrom. The paper "Spacetrack
+ *   Report Number 3: Models for Propagation of NORAD Element Sets" describes
+ *   the calculations.
+ *   See http://www.celestrak.com/NORAD/documentation/spacetrk.pdf.
+ *
+ * A few topocentric routines are also used from the 'orbit' program which is
+ *   Copyright (c) 1986,1987,1988,1989,1990 Robert W. Berger N3EMO
+ *
+ */
+
+/* define this to use orbit's propagator
+#define USE_ORBIT_PROPAGATOR
+ */
+
+/* define this to print some stuff
+#define ESAT_TRACE
+ */
+
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+
+#if defined(__STDC__)
+#include <stdlib.h>
+#endif
+
+#include "P_.h"
+#include "astro.h"
+#include "circum.h"
+#include "preferences.h"
+
+#include "vector.h"
+#include "sattypes.h"
+#include "satlib.h"
+
+
+#define ESAT_MAG        2       /* fake satellite magnitude */
+
+typedef double MAT3x3[3][3];
+
+static void esat_prop P_((Now *np, Obj *op, double *SatX, double *SatY, double
+    *SatZ, double *SatVX, double *SatVY, double *SatVZ));
+static void GetSatelliteParams P_((Obj *op));
+static void GetSiteParams P_((Now *np));
+static double Kepler P_((double MeanAnomaly, double Eccentricity));
+static void GetSubSatPoint P_((double SatX, double SatY, double SatZ,
+    double T, double *Latitude, double *Longitude, double *Height));
+static void GetSatPosition P_((double EpochTime, double EpochRAAN,
+    double EpochArgPerigee, double SemiMajorAxis, double Inclination,
+    double Eccentricity, double RAANPrecession, double PerigeePrecession,
+    double T, double TrueAnomaly, double *X, double *Y, double *Z,
+    double *Radius, double *VX, double *VY, double *VZ));
+static void GetSitPosition P_((double SiteLat, double SiteLong,
+    double SiteElevation, double CrntTime, double *SiteX, double *SiteY,
+    double *SiteZ, double *SiteVX, double *SiteVY, MAT3x3 SiteMatrix));
+static void GetRange P_((double SiteX, double SiteY, double SiteZ,
+    double SiteVX, double SiteVY, double SatX, double SatY, double SatZ,
+    double SatVX, double SatVY, double SatVZ, double *Range,
+    double *RangeRate));
+static void GetTopocentric P_((double SatX, double SatY, double SatZ,
+    double SiteX, double SiteY, double SiteZ, MAT3x3 SiteMatrix, double *X,
+    double *Y, double *Z));
+static void GetBearings P_((double SatX, double SatY, double SatZ,
+    double SiteX, double SiteY, double SiteZ, MAT3x3 SiteMatrix,
+    double *Azimuth, double *Elevation));
+static int Eclipsed P_((double SatX, double SatY, double SatZ,
+    double SatRadius, double CrntTime));
+static void InitOrbitRoutines P_((double EpochDay, int AtEod));
+
+#ifdef USE_ORBIT_PROPAGATOR 
+static void GetPrecession P_((double SemiMajorAxis, double Eccentricity,
+    double Inclination, double *RAANPrecession, double *PerigeePrecession));
+#endif /* USE_ORBIT_PROPAGATOR */
+
+/* stuff from orbit */
+/* char VersionStr[] = "N3EMO Orbit Simulator  v3.9"; */
+
+#ifdef PI2
+#undef PI2
+#endif
+
+#define PI2 (PI*2)
+
+#define MinutesPerDay (24*60.0)
+#define SecondsPerDay (60*MinutesPerDay)
+#define HalfSecond (0.5/SecondsPerDay)
+#define EarthRadius 6378.16             /* Kilometers           */
+#define C 2.997925e5                    /* Kilometers/Second    */
+#define RadiansPerDegree (PI/180)
+#define ABS(x) ((x) < 0 ? (-(x)) : (x))
+#define SQR(x) ((x)*(x))
+ 
+#define EarthFlat (1/298.25)            /* Earth Flattening Coeff. */
+#define SiderealSolar 1.0027379093
+#define SidRate (PI2*SiderealSolar/SecondsPerDay)	/* radians/second */
+#define GM 398600			/* Kilometers^3/seconds^2 */
+ 
+#define Epsilon (RadiansPerDegree/3600)     /* 1 arc second */
+#define SunRadius 695000		
+#define SunSemiMajorAxis  149598845.0  	    /* Kilometers 		   */
+ 
+/*  Keplerian Elements and misc. data for the satellite              */
+static double  EpochDay;                   /* time of epoch                 */
+static double EpochMeanAnomaly;            /* Mean Anomaly at epoch         */
+static long EpochOrbitNum;                 /* Integer orbit # of epoch      */
+static double EpochRAAN;                   /* RAAN at epoch                 */
+static double epochMeanMotion;             /* Revolutions/day               */
+static double OrbitalDecay;                /* Revolutions/day^2             */
+static double EpochArgPerigee;             /* argument of perigee at epoch  */
+static double Eccentricity;
+static double Inclination;
+ 
+/* Site Parameters */
+static double SiteLat,SiteLong,SiteAltitude;
+
+
+static double SidDay,SidReference;	/* Date and sidereal time	*/
+
+/* Keplerian elements for the sun */
+static double SunEpochTime,SunInclination,SunRAAN,SunEccentricity,
+       SunArgPerigee,SunMeanAnomaly,SunMeanMotion;
+
+/* values for shadow geometry */
+static double SinPenumbra,CosPenumbra;
+
+
+/* given a Now and an Obj with info about an earth satellite in the es_* fields
+ * fill in the s_* sky fields describing the satellite.
+ * as usual, we compute the geocentric ra/dec precessed to np->n_epoch and
+ * compute topocentric altitude accounting for refraction.
+ * return 0 if all ok, else -1.
+ */
+int
+obj_earthsat (np, op)
+Now *np;
+Obj *op;
+{
+	double Radius;              /* From geocenter                  */
+	double SatX,SatY,SatZ;	    /* In Right Ascension based system */
+	double SatVX,SatVY,SatVZ;   /* Kilometers/second	       */
+	double SiteX,SiteY,SiteZ;
+	double SiteVX,SiteVY;
+	double SiteMatrix[3][3];
+	double Height;
+	double SSPLat,SSPLong;
+	double Azimuth,Elevation,Range;
+	double RangeRate;
+	double dtmp;
+	double CrntTime;
+	double ra, dec;
+
+#ifdef ESAT_TRACE
+	printf ("\n");
+	printf ("Name = %s\n", op->o_name);
+	printf ("current jd = %13.5f\n", mjd+MJD0);
+	printf ("current mjd = %g\n", mjd);
+	printf ("satellite jd = %13.5f\n", op->es_epoch+MJD0);
+	printf ("satellite mjd = %g\n", op->es_epoch);
+#endif /* ESAT_TRACE */
+
+	/* xephem uses noon 12/31/1899 as 0; orbit uses midnight 1/1/1900.
+	 * thus, xephem runs 12 hours, or 1/2 day, behind of what orbit wants.
+	 */
+	CrntTime = mjd + 0.5;
+
+	/* extract the XEphem data forms into those used by orbit.
+	 * (we still use some functions and names from orbit, thank you).
+	 */
+	InitOrbitRoutines(CrntTime, 1);
+	GetSatelliteParams(op);
+	GetSiteParams(np);
+
+	/* propagate to np->n_mjd */
+	esat_prop (np, op, &SatX, &SatY, &SatZ, &SatVX, &SatVY, &SatVZ);
+	Radius = sqrt (SatX*SatX + SatY*SatY + SatZ*SatZ);
+
+	/* find geocentric EOD equatorial directly from xyz vector */
+	dtmp = atan2 (SatY, SatX);
+	range (&dtmp, 2*PI);
+	op->s_gaera = (float) dtmp;
+	op->s_gaedec = (float) atan2 (SatZ, sqrt(SatX*SatX + SatY*SatY));
+
+	/* find topocentric from site location */
+	GetSitPosition(SiteLat,SiteLong,SiteAltitude,CrntTime,
+		    &SiteX,&SiteY,&SiteZ,&SiteVX,&SiteVY,SiteMatrix);
+	GetBearings(SatX,SatY,SatZ,SiteX,SiteY,SiteZ,SiteMatrix,
+		    &Azimuth,&Elevation);
+
+	op->s_az = Azimuth;
+	refract (pressure, temp, Elevation, &dtmp);
+	op->s_alt = dtmp;
+
+	/* Range: line-of-site distance to satellite, m
+	 * RangeRate: m/s
+	 */
+	GetRange(SiteX,SiteY,SiteZ,SiteVX,SiteVY,
+	    SatX,SatY,SatZ,SatVX,SatVY,SatVZ,&Range,&RangeRate);
+
+	op->s_range = (float)(Range*1000);	/* we want m */
+	op->s_rangev = (float)(RangeRate*1000);	/* we want m/s */
+ 
+	/* SSPLat: sub-satellite latitude, rads 
+	 * SSPLong: sub-satellite longitude, >0 west, rads 
+	 * Height: height of satellite above ground, m
+	 */
+	GetSubSatPoint(SatX,SatY,SatZ,CrntTime,
+	    &SSPLat,&SSPLong,&Height);
+
+	op->s_elev = (float)(Height*1000);	/* we want m */
+	op->s_sublat = (float)SSPLat;
+	op->s_sublng = (float)(-SSPLong);	/* we want +E */
+
+	op->s_eclipsed = Eclipsed(SatX,SatY,SatZ,Radius,CrntTime);
+
+#ifdef ESAT_TRACE
+	printf ("CrntTime = %g\n", CrntTime);
+	printf ("SatX = %g\n", SatX);
+	printf ("SatY = %g\n", SatY);
+	printf ("SatZ = %g\n", SatZ);
+	printf ("Radius = %g\n", Radius);
+	printf ("SatVX = %g\n", SatVX);
+	printf ("SatVY = %g\n", SatVY);
+	printf ("SatVZ = %g\n", SatVZ);
+	printf ("SiteX = %g\n", SiteX);
+	printf ("SiteY = %g\n", SiteY);
+	printf ("SiteZ = %g\n", SiteZ);
+	printf ("SiteVX = %g\n", SiteVX);
+	printf ("SiteVY = %g\n", SiteVY);
+	printf ("Height = %g\n", Height);
+	printf ("SSPLat = %g\n", SSPLat);
+	printf ("SSPLong = %g\n", SSPLong);
+	printf ("Azimuth = %g\n", Azimuth);
+	printf ("Elevation = %g\n", Elevation);
+	printf ("Range = %g\n", Range);
+	printf ("RangeRate = %g\n", RangeRate);
+	fflush (stdout);
+#endif	/* ESAT_TRACE */
+
+	/* find s_ra/dec, depending on current options. */
+	if (pref_get(PREF_EQUATORIAL) == PREF_TOPO) {
+	    double ha, lst;
+	    aa_hadec (lat, (double)op->s_alt, (double)op->s_az, &ha, &dec);
+	    now_lst (np, &lst);
+	    ra = hrrad(lst) - ha;
+	    range (&ra, 2*PI);
+	} else {
+	    ra = op->s_gaera;
+	    dec = op->s_gaedec;
+	}
+	if (epoch != EOD)
+	    precess (mjd, epoch, &ra, &dec);
+	op->s_ra = (float)ra;
+	op->s_dec = (float)dec;
+
+	/* just make up a size and brightness */
+	set_smag (op, ESAT_MAG);
+	op->s_size = (float)0;
+
+	return (0);
+}
+
+/* find position and velocity vector for given Obj at the given time.
+ * set USE_ORBIT_PROPAGATOR depending on desired propagator to use.
+ */
+static void
+esat_prop (np, op, SatX, SatY, SatZ, SatVX, SatVY, SatVZ)
+Now *np;
+Obj *op;
+double *SatX,*SatY,*SatZ;
+double *SatVX,*SatVY,*SatVZ;
+{
+#ifdef USE_ORBIT_PROPAGATOR
+	double ReferenceOrbit;      /* Floating point orbit # at epoch */
+	double CurrentOrbit;
+	long OrbitNum;
+	double RAANPrecession,PerigeePrecession;
+	double MeanAnomaly,TrueAnomaly;
+	double SemiMajorAxis;
+	double AverageMotion,       /* Corrected for drag              */
+	    CurrentMotion;
+	double Radius;
+	double CrntTime;
+
+	SemiMajorAxis = 331.25 * exp(2*log(MinutesPerDay/epochMeanMotion)/3);
+	GetPrecession(SemiMajorAxis,Eccentricity,Inclination,&RAANPrecession,
+			    &PerigeePrecession);
+
+	ReferenceOrbit = EpochMeanAnomaly/PI2 + EpochOrbitNum;
+     
+	CrntTime = mjd + 0.5;
+	AverageMotion = epochMeanMotion + (CrntTime-EpochDay)*OrbitalDecay/2;
+	CurrentMotion = epochMeanMotion + (CrntTime-EpochDay)*OrbitalDecay;
+
+	SemiMajorAxis = 331.25 * exp(2*log(MinutesPerDay/CurrentMotion)/3);
+     
+	CurrentOrbit = ReferenceOrbit + (CrntTime-EpochDay)*AverageMotion;
+
+	OrbitNum = CurrentOrbit;
+     
+	MeanAnomaly = (CurrentOrbit-OrbitNum)*PI2;
+     
+	TrueAnomaly = Kepler(MeanAnomaly,Eccentricity);
+
+	GetSatPosition(EpochDay,EpochRAAN,EpochArgPerigee,SemiMajorAxis,
+		Inclination,Eccentricity,RAANPrecession,PerigeePrecession,
+		CrntTime,TrueAnomaly,SatX,SatY,SatZ,&Radius,SatVX,SatVY,SatVZ);
+
+#ifdef ESAT_TRACE
+	printf ("O Radius = %g\n", Radius);
+	printf ("ReferenceOrbit = %g\n", ReferenceOrbit);
+	printf ("CurrentOrbit = %g\n", CurrentOrbit);
+	printf ("RAANPrecession = %g\n", RAANPrecession);
+	printf ("PerigeePrecession = %g\n", PerigeePrecession);
+	printf ("MeanAnomaly = %g\n", MeanAnomaly);
+	printf ("TrueAnomaly = %g\n", TrueAnomaly);
+	printf ("SemiMajorAxis = %g\n", SemiMajorAxis);
+	printf ("AverageMotion = %g\n", AverageMotion);
+	printf ("CurrentMotion = %g\n", CurrentMotion);
+#endif	/* ESAT_TRACE */
+
+#else	/* ! USE_ORBIT_PROPAGATOR */
+#define	MPD		1440.0		/* minutes per day */
+
+	SatElem se;
+	SatData sd;
+	Vec3 posvec, velvec;
+	double dy;
+	double dt;
+	int yr;
+
+	/* init */
+	memset ((void *)&se, 0, sizeof(se));
+	memset ((void *)&sd, 0, sizeof(sd));
+	sd.elem = &se;
+
+	/* se_EPOCH is packed as yr*1000 + dy, where yr is years since 1900
+	 * and dy is day of year, Jan 1 being 1
+	 */
+	mjd_dayno (op->es_epoch, &yr, &dy);
+	yr -= 1900;
+	dy += 1;
+	se.se_EPOCH = yr*1000 + dy;
+
+	/* others carry over with some change in units */
+	se.se_XNO = op->es_n * (2*PI/MPD);	/* revs/day to rads/min */
+	se.se_XINCL = (float)degrad(op->es_inc);
+	se.se_XNODEO = (float)degrad(op->es_raan);
+	se.se_EO = op->es_e;
+	se.se_OMEGAO = (float)degrad(op->es_ap);
+	se.se_XMO = (float)degrad(op->es_M);
+	se.se_BSTAR = op->es_drag;
+	se.se_XNDT20 = op->es_decay*(2*PI/MPD/MPD); /*rv/dy^^2 to rad/min^^2*/
+
+	se.se_id.orbit = op->es_orbit;
+
+	dt = (mjd-op->es_epoch)*MPD;
+
+#ifdef ESAT_TRACE
+	printf ("se_EPOCH  : %30.20f\n", se.se_EPOCH);
+	printf ("se_XNO    : %30.20f\n", se.se_XNO);
+	printf ("se_XINCL  : %30.20f\n", se.se_XINCL);
+	printf ("se_XNODEO : %30.20f\n", se.se_XNODEO);
+	printf ("se_EO     : %30.20f\n", se.se_EO);
+	printf ("se_OMEGAO : %30.20f\n", se.se_OMEGAO);
+	printf ("se_XMO    : %30.20f\n", se.se_XMO);
+	printf ("se_BSTAR  : %30.20f\n", se.se_BSTAR);
+	printf ("se_XNDT20 : %30.20f\n", se.se_XNDT20);
+	printf ("se_orbit  : %30d\n",    se.se_id.orbit);
+	printf ("dt        : %30.20f\n", dt);
+#endif /* ESAT_TRACE */
+
+	/* compute the state vectors */
+	if (se.se_XNO >= (1.0/225.0))
+	    sgp4(&sd, &posvec, &velvec, dt); /* NEO */
+	else
+	    sdp4(&sd, &posvec, &velvec, dt); /* GEO */
+	if (sd.prop.sgp4)
+	    free (sd.prop.sgp4);	/* sd.prop.sdp4 is in same union */
+	if (sd.deep)
+	    free (sd.deep);
+
+	*SatX = ERAD*posvec.x/1000;	/* earth radii to km */
+	*SatY = ERAD*posvec.y/1000;
+	*SatZ = ERAD*posvec.z/1000;
+	*SatVX = 100*velvec.x;		/* ?? */
+	*SatVY = 100*velvec.y;
+	*SatVZ = 100*velvec.z;
+#endif
+}
+
+
+/* grab the xephem stuff from op and copy into orbit's globals.
+ */
+static void
+GetSatelliteParams(op)
+Obj *op;
+{
+	/* the following are for the orbit functions */
+	/* xephem uses noon 12/31/1899 as 0; orbit uses midnight 1/1/1900 as 1.
+	 * thus, xephem runs 12 hours, or 1/2 day, behind of what orbit wants.
+	 */
+	EpochDay = op->es_epoch + 0.5;
+
+	/* xephem stores inc in degrees; orbit wants rads */
+	Inclination = degrad(op->es_inc);
+
+	/* xephem stores RAAN in degrees; orbit wants rads */
+	EpochRAAN = degrad(op->es_raan);
+
+	Eccentricity = op->es_e;
+
+	/* xephem stores arg of perigee in degrees; orbit wants rads */
+	EpochArgPerigee = degrad(op->es_ap);
+
+	/* xephem stores mean anomaly in degrees; orbit wants rads */
+	EpochMeanAnomaly = degrad (op->es_M);
+
+	epochMeanMotion = op->es_n;
+
+	OrbitalDecay = op->es_decay;
+
+	EpochOrbitNum = op->es_orbit;
+}
+
+
+ 
+static void
+GetSiteParams(np)
+Now *np;
+{
+	SiteLat = lat;
+     
+	/* xephem stores longitude as >0 east; orbit wants >0 west */
+	SiteLong = 2.0*PI - lng;
+     
+	/* what orbit calls altitude xephem calls elevation and stores it from
+	 * sea level in earth radii; orbit wants km
+	 */
+	SiteAltitude = elev*ERAD/1000.0;
+     
+	/* we don't implement a minimum horizon altitude cutoff
+	SiteMinElev = 0;
+	 */
+
+#ifdef ESAT_TRACE
+	printf ("SiteLat = %g\n", SiteLat);
+	printf ("SiteLong = %g\n", SiteLong);
+	printf ("SiteAltitude = %g\n", SiteAltitude);
+	fflush (stdout);
+#endif
+}
+
+ 
+/* Solve Kepler's equation                                      */
+/* Inputs:                                                      */
+/*      MeanAnomaly     Time Since last perigee, in radians.    */
+/*                      PI2 = one complete orbit.               */
+/*      Eccentricity    Eccentricity of orbit's ellipse.        */
+/* Output:                                                      */
+/*      TrueAnomaly     Angle between perigee, geocenter, and   */
+/*                      current position.                       */
+ 
+static
+double Kepler(MeanAnomaly,Eccentricity)
+register double MeanAnomaly,Eccentricity;
+ 
+{
+register double E;              /* Eccentric Anomaly                    */
+register double Error;
+register double TrueAnomaly;
+ 
+    E = MeanAnomaly ;/*+ Eccentricity*sin(MeanAnomaly);  -- Initial guess */
+    do
+        {
+        Error = (E - Eccentricity*sin(E) - MeanAnomaly)
+                / (1 - Eccentricity*cos(E));
+        E -= Error;
+        }
+   while (ABS(Error) >= Epsilon);
+
+    if (ABS(E-PI) < Epsilon)
+        TrueAnomaly = PI;
+      else
+        TrueAnomaly = 2*atan(sqrt((1+Eccentricity)/(1-Eccentricity))
+                                *tan(E/2));
+    if (TrueAnomaly < 0)
+        TrueAnomaly += PI2;
+ 
+    return TrueAnomaly;
+}
+ 
+static void
+GetSubSatPoint(SatX,SatY,SatZ,T,Latitude,Longitude,Height)
+double SatX,SatY,SatZ,T;
+double *Latitude,*Longitude,*Height;
+{
+    double r;
+    /* ECD: long i; */
+
+    r = sqrt(SQR(SatX) + SQR(SatY) + SQR(SatZ));
+
+    *Longitude = PI2*((T-SidDay)*SiderealSolar + SidReference)
+		    - atan2(SatY,SatX);
+
+    /* ECD:
+     * want Longitude in range -PI to PI , +W
+     */
+    range (Longitude, 2*PI);
+    if (*Longitude > PI)
+	*Longitude -= 2*PI;
+
+    *Latitude = atan(SatZ/sqrt(SQR(SatX) + SQR(SatY)));
+
+#if SSPELLIPSE
+#else
+    *Height = r - EarthRadius;
+#endif
+}
+ 
+ 
+#ifdef USE_ORBIT_PROPAGATOR
+static void
+GetPrecession(SemiMajorAxis,Eccentricity,Inclination,
+        RAANPrecession,PerigeePrecession)
+double SemiMajorAxis,Eccentricity,Inclination;
+double *RAANPrecession,*PerigeePrecession;
+{
+  *RAANPrecession = 9.95*pow(EarthRadius/SemiMajorAxis,3.5) * cos(Inclination)
+                 / SQR(1-SQR(Eccentricity)) * RadiansPerDegree;
+ 
+  *PerigeePrecession = 4.97*pow(EarthRadius/SemiMajorAxis,3.5)
+         * (5*SQR(cos(Inclination))-1)
+                 / SQR(1-SQR(Eccentricity)) * RadiansPerDegree;
+}
+#endif /* USE_ORBIT_PROPAGATOR */
+ 
+/* Compute the satellite postion and velocity in the RA based coordinate
+ * system.
+ * ECD: take care not to let Radius get below EarthRadius.
+ */
+
+static void
+GetSatPosition(EpochTime,EpochRAAN,EpochArgPerigee,SemiMajorAxis,
+	Inclination,Eccentricity,RAANPrecession,PerigeePrecession,
+	T,TrueAnomaly,X,Y,Z,Radius,VX,VY,VZ)
+ 
+double EpochTime,EpochRAAN,EpochArgPerigee;
+double SemiMajorAxis,Inclination,Eccentricity;
+double RAANPrecession,PerigeePrecession,T, TrueAnomaly;
+double *X,*Y,*Z,*Radius,*VX,*VY,*VZ;
+
+{
+    double RAAN,ArgPerigee;
+ 
+
+    double Xw,Yw,VXw,VYw;	/* In orbital plane */
+    double Tmp;
+    double Px,Qx,Py,Qy,Pz,Qz;	/* Escobal transformation 31 */
+    double CosArgPerigee,SinArgPerigee;
+    double CosRAAN,SinRAAN,CoSinclination,SinInclination;
+
+    *Radius = SemiMajorAxis*(1-SQR(Eccentricity))
+                        / (1+Eccentricity*cos(TrueAnomaly));
+
+    if (*Radius <= EarthRadius)
+	*Radius = EarthRadius;
+
+
+    Xw = *Radius * cos(TrueAnomaly);
+    Yw = *Radius * sin(TrueAnomaly);
+    
+    Tmp = sqrt(GM/(SemiMajorAxis*(1-SQR(Eccentricity))));
+
+    VXw = -Tmp*sin(TrueAnomaly);
+    VYw = Tmp*(cos(TrueAnomaly) + Eccentricity);
+
+    ArgPerigee = EpochArgPerigee + (T-EpochTime)*PerigeePrecession;
+    RAAN = EpochRAAN - (T-EpochTime)*RAANPrecession;
+
+    CosRAAN = cos(RAAN); SinRAAN = sin(RAAN);
+    CosArgPerigee = cos(ArgPerigee); SinArgPerigee = sin(ArgPerigee);
+    CoSinclination = cos(Inclination); SinInclination = sin(Inclination);
+    
+    Px = CosArgPerigee*CosRAAN - SinArgPerigee*SinRAAN*CoSinclination;
+    Py = CosArgPerigee*SinRAAN + SinArgPerigee*CosRAAN*CoSinclination;
+    Pz = SinArgPerigee*SinInclination;
+    Qx = -SinArgPerigee*CosRAAN - CosArgPerigee*SinRAAN*CoSinclination;
+    Qy = -SinArgPerigee*SinRAAN + CosArgPerigee*CosRAAN*CoSinclination;
+    Qz = CosArgPerigee*SinInclination;
+
+    *X = Px*Xw + Qx*Yw;		/* Escobal, transformation #31 */
+    *Y = Py*Xw + Qy*Yw;
+    *Z = Pz*Xw + Qz*Yw;
+
+    *VX = Px*VXw + Qx*VYw;
+    *VY = Py*VXw + Qy*VYw;
+    *VZ = Pz*VXw + Qz*VYw;
+}
+
+/* Compute the site postion and velocity in the RA based coordinate
+   system. SiteMatrix is set to a matrix which is used by GetTopoCentric
+   to convert geocentric coordinates to topocentric (observer-centered)
+    coordinates. */
+
+static void
+GetSitPosition(SiteLat,SiteLong,SiteElevation,CrntTime,
+             SiteX,SiteY,SiteZ,SiteVX,SiteVY,SiteMatrix)
+
+double SiteLat,SiteLong,SiteElevation,CrntTime;
+double *SiteX,*SiteY,*SiteZ,*SiteVX,*SiteVY;
+MAT3x3 SiteMatrix;
+
+{
+    static double G1,G2; /* Used to correct for flattening of the Earth */
+    static double CosLat,SinLat;
+    static double OldSiteLat = -100000;  /* Used to avoid unneccesary recomputation */
+    static double OldSiteElevation = -100000;
+    double Lat;
+    double SiteRA;	/* Right Ascension of site			*/
+    double CosRA,SinRA;
+
+    if ((SiteLat != OldSiteLat) || (SiteElevation != OldSiteElevation))
+	{
+	OldSiteLat = SiteLat;
+	OldSiteElevation = SiteElevation;
+	Lat = atan(1/(1-SQR(EarthFlat))*tan(SiteLat));
+
+	CosLat = cos(Lat);
+	SinLat = sin(Lat);
+
+	G1 = EarthRadius/(sqrt(1-(2*EarthFlat-SQR(EarthFlat))*SQR(SinLat)));
+	G2 = G1*SQR(1-EarthFlat);
+	G1 += SiteElevation;
+	G2 += SiteElevation;
+	}
+
+
+    SiteRA = PI2*((CrntTime-SidDay)*SiderealSolar + SidReference)
+	         - SiteLong;
+    CosRA = cos(SiteRA);
+    SinRA = sin(SiteRA);
+    
+
+    *SiteX = G1*CosLat*CosRA;
+    *SiteY = G1*CosLat*SinRA;
+    *SiteZ = G2*SinLat;
+    *SiteVX = -SidRate * *SiteY;
+    *SiteVY = SidRate * *SiteX;
+
+    SiteMatrix[0][0] = SinLat*CosRA;
+    SiteMatrix[0][1] = SinLat*SinRA;
+    SiteMatrix[0][2] = -CosLat;
+    SiteMatrix[1][0] = -SinRA;
+    SiteMatrix[1][1] = CosRA;
+    SiteMatrix[1][2] = 0.0;
+    SiteMatrix[2][0] = CosRA*CosLat;
+    SiteMatrix[2][1] = SinRA*CosLat;
+    SiteMatrix[2][2] = SinLat;
+}
+
+static void
+GetRange(SiteX,SiteY,SiteZ,SiteVX,SiteVY,
+	SatX,SatY,SatZ,SatVX,SatVY,SatVZ,Range,RangeRate)
+
+double SiteX,SiteY,SiteZ,SiteVX,SiteVY;
+double SatX,SatY,SatZ,SatVX,SatVY,SatVZ;
+double *Range,*RangeRate;
+{
+    double DX,DY,DZ;
+
+    DX = SatX - SiteX; DY = SatY - SiteY; DZ = SatZ - SiteZ;
+
+    *Range = sqrt(SQR(DX)+SQR(DY)+SQR(DZ));    
+
+    *RangeRate = ((SatVX-SiteVX)*DX + (SatVY-SiteVY)*DY + SatVZ*DZ)
+			/ *Range;
+}
+
+/* Convert from geocentric RA based coordinates to topocentric
+   (observer centered) coordinates */
+
+static void
+GetTopocentric(SatX,SatY,SatZ,SiteX,SiteY,SiteZ,SiteMatrix,X,Y,Z)
+double SatX,SatY,SatZ,SiteX,SiteY,SiteZ;
+double *X,*Y,*Z;
+MAT3x3 SiteMatrix;
+{
+    SatX -= SiteX;
+    SatY -= SiteY;
+    SatZ -= SiteZ;
+
+    *X = SiteMatrix[0][0]*SatX + SiteMatrix[0][1]*SatY
+	+ SiteMatrix[0][2]*SatZ; 
+    *Y = SiteMatrix[1][0]*SatX + SiteMatrix[1][1]*SatY
+	+ SiteMatrix[1][2]*SatZ; 
+    *Z = SiteMatrix[2][0]*SatX + SiteMatrix[2][1]*SatY
+	+ SiteMatrix[2][2]*SatZ; 
+}
+
+static void
+GetBearings(SatX,SatY,SatZ,SiteX,SiteY,SiteZ,SiteMatrix,Azimuth,Elevation)
+double SatX,SatY,SatZ,SiteX,SiteY,SiteZ;
+MAT3x3 SiteMatrix;
+double *Azimuth,*Elevation;
+{
+    double x,y,z;
+
+    GetTopocentric(SatX,SatY,SatZ,SiteX,SiteY,SiteZ,SiteMatrix,&x,&y,&z);
+
+    *Elevation = atan(z/sqrt(SQR(x) + SQR(y)));
+
+    *Azimuth = PI - atan2(y,x);
+
+    if (*Azimuth < 0)
+	*Azimuth += PI;
+}
+
+static int
+Eclipsed(SatX,SatY,SatZ,SatRadius,CrntTime)
+double SatX,SatY,SatZ,SatRadius,CrntTime;
+{
+    double MeanAnomaly,TrueAnomaly;
+    double SunX,SunY,SunZ,SunRad;
+    double vx,vy,vz;
+    double CosTheta;
+
+    MeanAnomaly = SunMeanAnomaly+ (CrntTime-SunEpochTime)*SunMeanMotion*PI2;
+    TrueAnomaly = Kepler(MeanAnomaly,SunEccentricity);
+
+    GetSatPosition(SunEpochTime,SunRAAN,SunArgPerigee,SunSemiMajorAxis,
+		SunInclination,SunEccentricity,0.0,0.0,CrntTime,
+		TrueAnomaly,&SunX,&SunY,&SunZ,&SunRad,&vx,&vy,&vz);
+
+    CosTheta = (SunX*SatX + SunY*SatY + SunZ*SatZ)/(SunRad*SatRadius)
+		 *CosPenumbra + (SatRadius/EarthRadius)*SinPenumbra;
+
+    if (CosTheta < 0)
+        if (CosTheta < -sqrt(SQR(SatRadius)-SQR(EarthRadius))/SatRadius
+	    		*CosPenumbra + (SatRadius/EarthRadius)*SinPenumbra)
+	  
+	    return 1;
+    return 0;
+}
+
+/* Initialize the Sun's keplerian elements for a given epoch.
+   Formulas are from "Explanatory Supplement to the Astronomical Ephemeris".
+   Also init the sidereal reference				*/
+
+static void
+InitOrbitRoutines(EpochDay, AtEod)
+double EpochDay;
+int AtEod;
+{
+    double T,T2,T3,Omega;
+    int n;
+    double SunTrueAnomaly,SunDistance;
+
+    T = (floor(EpochDay)-0.5)/36525;
+    T2 = T*T;
+    T3 = T2*T;
+
+    SidDay = floor(EpochDay);
+
+    SidReference = (6.6460656 + 2400.051262*T + 0.00002581*T2)/24;
+    SidReference -= floor(SidReference);
+
+    /* Omega is used to correct for the nutation and the abberation */
+    Omega = AtEod ? (259.18 - 1934.142*T) * RadiansPerDegree : 0.0;
+    n = (int)(Omega / PI2);
+    Omega -= n*PI2;
+
+    SunEpochTime = EpochDay;
+    SunRAAN = 0;
+
+    SunInclination = (23.452294 - 0.0130125*T - 0.00000164*T2
+		    + 0.000000503*T3 +0.00256*cos(Omega)) * RadiansPerDegree;
+    SunEccentricity = (0.01675104 - 0.00004180*T - 0.000000126*T2);
+    SunArgPerigee = (281.220833 + 1.719175*T + 0.0004527*T2
+			+ 0.0000033*T3) * RadiansPerDegree;
+    SunMeanAnomaly = (358.475845 + 35999.04975*T - 0.00015*T2
+			- 0.00000333333*T3) * RadiansPerDegree;
+    n = (int)(SunMeanAnomaly / PI2);
+    SunMeanAnomaly -= n*PI2;
+
+    SunMeanMotion = 1/(365.24219879 - 0.00000614*T);
+
+    SunTrueAnomaly = Kepler(SunMeanAnomaly,SunEccentricity);
+    SunDistance = SunSemiMajorAxis*(1-SQR(SunEccentricity))
+			/ (1+SunEccentricity*cos(SunTrueAnomaly));
+
+    SinPenumbra = (SunRadius-EarthRadius)/SunDistance;
+    CosPenumbra = sqrt(1-SQR(SinPenumbra));
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: earthsat.c,v $ $Date: 2001-10-22 12:08:27 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/eq_ecl.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/eq_ecl.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/eq_ecl.c	(revision 2309)
@@ -0,0 +1,79 @@
+#include <stdio.h>
+#include <math.h>
+
+#include "P_.h"
+#include "astro.h"
+
+static void ecleq_aux P_((int sw, double mjd, double x, double y,
+    double *p, double *q));
+
+#define	EQtoECL	1
+#define	ECLtoEQ	(-1)
+
+
+/* given the modified Julian date, mjd, and an equitorial ra and dec, each in
+ * radians, find the corresponding geocentric ecliptic latitude, *lat, and
+ * longititude, *lng, also each in radians.
+ * correction for the effect on the angle of the obliquity due to nutation is
+ * not included.
+ */
+void
+eq_ecl (mjd, ra, dec, lat, lng)
+double mjd;
+double ra, dec;
+double *lat, *lng;
+{
+	ecleq_aux (EQtoECL, mjd, ra, dec, lng, lat);
+}
+
+/* given the modified Julian date, mjd, and a geocentric ecliptic latitude,
+ * *lat, and longititude, *lng, each in radians, find the corresponding
+ * equitorial ra and dec, also each in radians.
+ * correction for the effect on the angle of the obliquity due to nutation is
+ * not included.
+ */
+void
+ecl_eq (mjd, lat, lng, ra, dec)
+double mjd;
+double lat, lng;
+double *ra, *dec;
+{
+	ecleq_aux (ECLtoEQ, mjd, lng, lat, ra, dec);
+}
+
+static void
+ecleq_aux (sw, mjd, x, y, p, q)
+int sw;			/* +1 for eq to ecliptic, -1 for vv. */
+double mjd;
+double x, y;		/* sw==1: x==ra, y==dec.  sw==-1: x==lng, y==lat. */
+double *p, *q;		/* sw==1: p==lng, q==lat. sw==-1: p==ra, q==dec. */
+{
+	static double lastmjd = -10000;	/* last mjd calculated */
+	static double seps, ceps;	/* sin and cos of mean obliquity */
+	double sx, cx, sy, cy, ty, sq;
+
+	if (mjd != lastmjd) {
+	    double eps;
+	    obliquity (mjd, &eps);		/* mean obliquity for date */
+    	    seps = sin(eps);
+	    ceps = cos(eps);
+	    lastmjd = mjd;
+	}
+
+	sy = sin(y);
+	cy = cos(y);				/* always non-negative */
+        if (fabs(cy)<1e-20) cy = 1e-20;		/* insure > 0 */
+        ty = sy/cy;
+	cx = cos(x);
+	sx = sin(x);
+        sq = (sy*ceps)-(cy*seps*sx*sw);
+	if (sq < -1) sq = -1;
+	if (sq >  1) sq =  1;
+        *q = asin(sq);
+        *p = atan(((sx*ceps)+(ty*seps*sw))/cx);
+        if (cx<0) *p += PI;		/* account for atan quad ambiguity */
+	range (p, 2*PI);
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: eq_ecl.c,v $ $Date: 2001-10-22 12:08:27 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/eq_gal.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/eq_gal.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/eq_gal.c	(revision 2309)
@@ -0,0 +1,104 @@
+/* code to convert between equitorial and galactic coordinates */
+
+#include <stdio.h>
+#include <math.h>
+
+#include "P_.h"
+#include "astro.h"
+
+static void galeq_aux P_((int sw, double x, double y, double *p, double *q));
+static void galeq_init P_((void));
+
+#define	EQtoGAL	1
+#define	GALtoEQ	(-1)
+#define	SMALL	(1e-20)
+
+static double an = degrad(32.93192);    /* G lng of asc node on equator */
+static double gpr = degrad(192.85948);  /* RA of North Gal Pole, 2000 */
+static double gpd = degrad(27.12825);   /* Dec of  " */
+static double cgpd, sgpd;		/* cos() and sin() of gpd */
+static double mjd2000;			/* mjd of 2000 */
+static int before;			/* whether these have been set yet */
+
+/* given ra and dec, each in radians, for the given epoch, find the
+ * corresponding galactic latitude, *lat, and longititude, *lng, also each in
+ * radians.
+ */
+void
+eq_gal (mjd, ra, dec, lat, lng)
+double mjd, ra, dec;
+double *lat, *lng;
+{
+	galeq_init();
+	precess (mjd, mjd2000, &ra, &dec);
+	galeq_aux (EQtoGAL, ra, dec, lng, lat);
+}
+
+/* given galactic latitude, lat, and longititude, lng, each in radians, find
+ * the corresponding equitorial ra and dec, also each in radians, at the 
+ * given epoch.
+ */
+void
+gal_eq (mjd, lat, lng, ra, dec)
+double mjd, lat, lng;
+double *ra, *dec;
+{
+	galeq_init();
+	galeq_aux (GALtoEQ, lng, lat, ra, dec);
+	precess (mjd2000, mjd, ra, dec);
+}
+
+static void
+galeq_aux (sw, x, y, p, q)
+int sw;			/* +1 for eq to gal, -1 for vv. */
+double x, y;		/* sw==1: x==ra, y==dec.  sw==-1: x==lng, y==lat. */
+double *p, *q;		/* sw==1: p==lng, q==lat. sw==-1: p==ra, q==dec. */
+{
+	double sy, cy, a, ca, sa, b, sq, c, d; 
+
+	cy = cos(y);
+	sy = sin(y);
+	a = x - an;
+	if (sw == EQtoGAL)
+	    a = x - gpr;
+	ca = cos(a);
+	sa = sin(a);
+	b = sa;
+	if (sw == EQtoGAL)
+	    b = ca;
+	sq = (cy*cgpd*b) + (sy*sgpd);
+	*q = asin (sq);
+
+	if (sw == GALtoEQ) {
+	    c = cy*ca;
+	    d = (sy*cgpd) - (cy*sgpd*sa);
+	    if (fabs(d) < SMALL)
+		d = SMALL;
+	    *p = atan (c/d) + gpr;
+	} else {
+	    c = sy - (sq*sgpd);
+	    d = cy*sa*cgpd;
+	    if (fabs(d) < SMALL)
+		d = SMALL;
+	    *p = atan (c/d) + an;
+	}
+
+	if (d < 0) *p += PI;
+	if (*p < 0) *p += 2*PI;
+	if (*p > 2*PI) *p -= 2*PI;
+}
+
+/* set up the definitions */
+static void
+galeq_init()
+{
+	if (!before) {
+	    cgpd = cos (gpd);
+	    sgpd = sin (gpd);
+	    mjd2000 = J2000;
+	    before = 1;
+	}
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: eq_gal.c,v $ $Date: 2001-10-22 12:08:27 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/formats.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/formats.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/formats.c	(revision 2309)
@@ -0,0 +1,307 @@
+#include <stdio.h>
+#include <math.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "P_.h"
+#include "astro.h"
+#include "preferences.h"
+
+/* sprint the variable a in sexagesimal format into out[].
+ * w is the number of spaces for the whole part.
+ * fracbase is the number of pieces a whole is to broken into; valid options:
+ *	360000:	<w>:mm:ss.ss
+ *	36000:	<w>:mm:ss.s
+ *	3600:	<w>:mm:ss
+ *	600:	<w>:mm.m
+ *	60:	<w>:mm
+ */
+void
+fs_sexa (out, a, w, fracbase)
+char *out;
+double a;
+int w;
+int fracbase;
+{
+	unsigned long n;
+	int d;
+	int f;
+	int m;
+	int s;
+	int isneg;
+
+	/* save whether it's negative but do all the rest with a positive */
+	isneg = (a < 0);
+	if (isneg)
+	    a = -a;
+
+	/* convert to an integral number of whole portions */
+	n = (unsigned long)(a * fracbase + 0.5);
+	d = n/fracbase;
+	f = n%fracbase;
+
+	/* form the whole part; "negative 0" is a special case */
+	if (isneg && d == 0)
+	    (void) sprintf (out, "%*s-0", w-2, "");
+	else
+	    (void) sprintf (out, "%*d", w, isneg ? -d : d);
+	out += w;
+
+	/* do the rest */
+	switch (fracbase) {
+	case 60:	/* dd:mm */
+	    m = f/(fracbase/60);
+	    (void) sprintf (out, ":%02d", m);
+	    break;
+	case 600:	/* dd:mm.m */
+	    (void) sprintf (out, ":%02d.%1d", f/10, f%10);
+	    break;
+	case 3600:	/* dd:mm:ss */
+	    m = f/(fracbase/60);
+	    s = f%(fracbase/60);
+	    (void) sprintf (out, ":%02d:%02d", m, s);
+	    break;
+	case 36000:	/* dd:mm:ss.s*/
+	    m = f/(fracbase/60);
+	    s = f%(fracbase/60);
+	    (void) sprintf (out, ":%02d:%02d.%1d", m, s/10, s%10);
+	    break;
+	case 360000:	/* dd:mm:ss.ss */
+	    m = f/(fracbase/60);
+	    s = f%(fracbase/60);
+	    (void) sprintf (out, ":%02d:%02d.%02d", m, s/100, s%100);
+	    break;
+	default:
+	    printf ("fs_sexa: unknown fracbase: %d\n", fracbase);
+	    exit(1);
+	}
+}
+
+/* put the given modified Julian date, jd, in out[] according to preference
+ * format.
+ */
+void
+fs_date (out, jd)
+char out[];
+double jd;
+{
+	int p = pref_get (PREF_DATE_FORMAT);
+	int m, y;
+	double d;
+
+	mjd_cal (jd, &m, &d, &y);
+	/* beware of %g rounding day up */
+	if ((d < 1.0 && d - floor(d) >= .9999995)
+				    || (d < 10.0 && d - floor(d) >= .999995)
+				    || (d >= 10.0 && d - floor(d) >= .99995))
+	    mjd_cal (mjd_day(jd+0.5), &m, &d, &y);
+
+	switch (p) {
+	case PREF_YMD:
+	    (void) sprintf (out, "%4d/%02d/%02.6g", y, m, d);
+	    break;
+	case PREF_DMY:
+	    (void) sprintf (out, "%2.6g/%02d/%-4d", d, m, y);
+	    break;
+	case PREF_MDY:
+	    (void) sprintf (out, "%2d/%02.6g/%-4d", m, d, y);
+	    break;
+	default:
+	    printf ("fs_date: bad date pref: %d\n", p);
+	    exit (1);
+	}
+}
+
+/* scan a sexagesimal string and update a double. the string is of the form
+ *   H:M:S. a negative value may be indicated by a '-' char before any
+ *   component. All components may be integral or real. In addition to ':' the
+ *    separator may also be '/' or ';' or ',' or '-'.
+ * any components not specified in bp[] are copied from old's.
+ *   eg:  ::10	only changes S
+ *        10    only changes H
+ *        10:0  changes H and M
+ */
+void
+f_scansex (o, bp, np)
+double o;	/* old value */
+char bp[];	/* input string */
+double *np;	/* new value */
+{
+	double oh, om, os;
+	double nh, nm, ns;
+	int nneg;
+	double tmp;
+	char c;
+
+	/* fast macro to scan each segment of bp */
+#define	SCANSEX(new,old)						\
+	if (*bp == '-') {nneg = 1; bp++;}				\
+	if (sscanf (bp, "%lf", &new) != 1) new = old;			\
+	while ((c=(*bp)) != '\0') {					\
+	    bp++;							\
+	    if (c==':' || c=='/' || c==';' || c==',' || c=='-')		\
+		break;							\
+	}
+
+	/* get h:m:s components of o in case bp[] defers.
+	 * and constrain to positive for now.
+	 */
+	if (o < 0.0)
+	    o = -o;
+        oh = floor(o);
+	tmp = (o - oh)*60.0;
+	om = floor(tmp);
+	os = (tmp - om)*60.0;
+	
+	/* round to small portion of a second to reduce differencing errors. */
+	if (os > 59.99999) {
+	    os = 0.0;
+	    if ((om += 1.0) >= 60.0) {
+		om = 0.0;
+		oh += 1.0;
+	    }
+	}
+
+	/* scan each component of the buffer */
+	while (*bp == ' ') bp++;
+	nneg = 0;
+	SCANSEX (nh, oh)
+	SCANSEX (nm, om)
+	SCANSEX (ns, os)
+
+	/* back to hours */
+	tmp = ns/3600.0 + nm/60.0 + nh;
+	if (nneg)
+	    tmp = -tmp;
+
+	*np = tmp;
+}
+
+/* crack a floating date string, bp, of the form X/Y/Z determined by the
+ *   PREF_DATE_FORMAT preference into its components. allow the day to be a
+ *   floating point number,
+ * a lone component is always a year if it contains a decimal point or pref
+ *   is MDY or DMY and it is not a reasonable month or day value, respectively.
+ * leave any unspecified component unchanged.
+ * actually, the slashes may be anything but digits or a decimal point.
+ */
+void
+f_sscandate (bp, pref, m, d, y)
+char *bp;
+int pref;       /* one of PREF_X for PREF_DATE_FORMAT */
+int *m, *y;
+double *d;
+{
+        double comp[3]; /* the three components */
+        int set[3];     /* set[i] is 1 if component i is present */
+	int in;		/* scan state: 1 while we are in a component */
+	int ncomp;	/* incremented as each component is discovered */
+	int ndp;	/* number of decimal points in last component */
+        char *bp0 = NULL, c;
+
+	set[0] = set[1] = set[2] = 0;
+	ncomp = 0;
+	in = 0;
+	ndp = 0;
+
+	/* scan the input string.
+	 * '\0' counts as a component terminator too.
+	 */
+	do {
+	    /* here, *bp is the next character to be investigated */
+	    c = *bp;
+	    if (c == '.' || isdigit(c) || (c == '-' && !in)) {
+		/* found what passes for a floating point number */
+		if (in == 0) {
+		    /* save the beginning of it in bp0 and init ndp */
+		    bp0 = bp;
+		    in = 1;
+		    ndp = 0;
+		}
+		if (c == '.')
+		    ndp++;
+	    } else if (c != ' ') {
+		/* not in a number now ... */
+		if (in) {
+		    /* ... but we *were* in a number, so it counts */
+		    if (ncomp >= 3)
+			return;	/* too many components.. just bail */
+		    comp[ncomp] = atod (bp0);
+		    set[ncomp] = 1;
+		    in = 0;
+		}
+
+		/* regardless, a non-blank non-float means another component */
+		ncomp++;
+	    }
+	    bp++;
+	} while (c);
+
+	/* it's a decimal year if there is exactly one component and
+	 *   it contains a decimal point
+	 *   or we are in MDY format and it's not in the range 1..12
+	 *   or we are in DMY format and it's not int the rangle 1..31
+	 */
+	if (ncomp == 1 &&
+		(ndp > 0
+		 || (pref == PREF_MDY && !(comp[0] >= 1 && comp[0] <= 12))
+		 || (pref == PREF_DMY && !(comp[0] >= 1 && comp[0] <= 31)))) {
+	    double Mjd;
+	    year_mjd (comp[0], &Mjd);
+	    mjd_cal (Mjd, m, d, y);
+	    return;
+	}
+
+        switch (pref) {
+        case PREF_MDY:
+            if (set[0]) *m = (int)comp[0];
+            if (set[1]) *d = comp[1];
+            if (set[2]) *y = (int)comp[2];
+            break;
+        case PREF_YMD:
+            if (set[0]) *y = (int)comp[0];
+            if (set[1]) *m = (int)comp[1];
+            if (set[2]) *d = comp[2];
+            break;
+        case PREF_DMY:
+            if (set[0]) *d = comp[0];
+            if (set[1]) *m = (int)comp[1];
+            if (set[2]) *y = (int)comp[2];
+            break;
+	}
+}
+
+/* given a string of the form xx:mm[:ss] or xx:mm.dd, convert it to a double at
+ * *dp. actually, ':' may also be ';', '/' or ',' too. all components may be 
+ * floats.
+ * return -1 if trouble, else 0
+ */
+int
+scansex (str, dp)
+char *str;
+double *dp;
+{
+	double x, m = 0.0, s = 0.0;
+	int isneg;
+	int nf;
+
+	while (isspace(*str))
+	    str++;
+	if (*str == '-') {
+	    isneg = 1;
+	    str++;
+	} else
+	    isneg = 0;
+
+	nf = sscanf (str, "%lf%*[:;/,]%lf%*[:;/,]%lf", &x, &m, &s);
+	if (nf < 1)
+	    return (-1);
+	*dp = x + m/60.0 + s/3600.0;
+	if (isneg)
+	    *dp = - *dp;
+	return (0);
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: formats.c,v $ $Date: 2001-10-22 12:08:27 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/helio.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/helio.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/helio.c	(revision 2309)
@@ -0,0 +1,54 @@
+#include <stdlib.h>
+#include <math.h>
+#include <math.h>
+
+#include "P_.h"
+#include "astro.h"
+
+/* given geocentric time jd and coords of a distant object at ra/dec (J2000),
+ * find the difference in time between light arriving at earth vs the sun.
+ * *hcp must be subtracted from geocentric jd to get heliocentric jd.
+ * From RLM Oct 12, 1995.
+ */
+void
+heliocorr (jd, ra, dec, hcp)
+double jd, ra, dec;
+double *hcp;
+{
+	double e;	/* obliquity of ecliptic */
+	double n;	/* day number */
+	double g;	/* solar mean anomaly */
+	double L;	/* solar ecliptic longitude */
+	double l;	/* mean solar ecliptic longitude */
+	double R;	/* sun distance, AU */
+	double X, Y;	/* equatorial rectangular solar coords */
+	double cdec, sdec;
+	double cra, sra;
+
+	/* following algorithm really wants EOD */
+	precess (J2000, jd - MJD0, &ra, &dec);
+
+	cdec = cos(dec);
+	sdec = sin(dec);
+	cra = cos(ra);
+	sra = sin(ra);
+
+	n = jd - 2451545.0;	/* use epoch 2000 */
+	e = degrad(23.439 - 0.0000004*n);
+	g = degrad(357.528) + degrad(0.9856003)*n;
+	L = degrad(280.461) + degrad(0.9856474)*n;
+	l = L + degrad(1.915)*sin(g) + degrad(0.02)*sin(2.0*g);
+	R = 1.00014 - 0.01671*cos(g) - 0.00014*cos(2.0*g);
+	X = R*cos(l);
+	Y = R*cos(e)*sin(l);
+
+#if 0
+	    printf ("n=%g g=%g L=%g l=%g R=%g X=%g Y=%g\n",
+				n, raddeg(g), raddeg(L), raddeg(l), R, X, Y);
+#endif
+
+	*hcp = 0.0057755 * (cdec*cra*X + (cdec*sra + tan(e)*sdec)*Y);
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: helio.c,v $ $Date: 2001-10-22 12:08:27 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/libration.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/libration.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/libration.c	(revision 2309)
@@ -0,0 +1,2230 @@
+/* This file contains code to calculate the libration in Lunar lat and long.
+ * It is based entirely on code supplied to me 2 Oct 1996 by Stephen L. Moshier,
+ * <moshier@world.std.com>, which implements a trigonometric expansion to
+ * approximate the librations according to JPL DE403. The following doc file
+ * was also supplied therewith:
+
+This program calculates a trigonometric series adjusted for a best fit
+to the lunar librations from the Jet Propulsion Laboratory's DE403
+ephemeris.
+
+lblon403.c and lblat403.c are series for the selenographic longitude
+and latitude of the earth.  The longitude series matches DE403
+with a maximum discrepancy of 2.6" (0.4" rms).  The latitude has a
+maximum discrepancy of 1.9" (0.2" rms).  The two series are valid in
+the Julian year interval 1600 to 2200.
+
+In both Eckhardt and DE403 the moon's principal moment of inertia axes
+form the lunar body coordinate system. The estimated geographic
+locations of these axes vary as measurements and theories gradually
+become more refined.  There is a significant difference between
+Eckhardt and DE403 in the constant term of the longitude.  Almanac and
+cartography coordinates drop the constant term (which is -64" for
+DE403).  That practice gives librations relative to the mean
+selenographic longitude of the earth, for which the discrepancy from
+one theory to the next is small.
+
+Steve Moshier
+October, 1996
+
+ * Any errors in adapting this code to xephem are strictly my own.
+ * Elwood Downey.
+*/
+
+#include <stdio.h>
+#include <math.h>
+
+#include "P_.h"
+#include "astro.h"
+
+#define CHAR short
+
+
+
+/* plantbl.h */
+
+struct plantbl {
+  /*  char max_harmonic[9]; */
+  char max_harmonic[14];
+  char max_power_of_t;
+  CHAR *arg_tbl;
+  int *lon_tbl;
+  int *lat_tbl;
+  int *rad_tbl;
+  double distance;
+  double timescale;
+  double trunclvl;
+};
+
+
+
+/* libra403.c */
+
+static double JD2000 = 2451545.0;
+/* Conversion factors between degrees and radians */
+static double STR = 4.8481368110953599359e-6;	/* radians per arc second */
+
+static double ss[14][24];
+static double cc[14][24];
+
+/* Reduce arc seconds modulo 360 degrees,
+   answer in arc seconds.  */
+static double
+mods3600 (x)
+     double x;
+{
+  double y;
+  y = x - 1.296e6 * floor (x / 1.296e6);
+  return y;
+}
+
+/* Prepare lookup table of sin and cos ( i * L_k )
+   for required multiple angles.
+   K is the array offset corresponding to the planet.
+   ARG is in radians.
+   n is the highest harmonic to compute.  */
+static int
+sscc (k, arg, n)
+     int k;
+     double arg;
+     int n;
+{
+  double cu, su, cv, sv, s;
+  int i;
+
+  if (n <= 0)
+    return 0;
+
+  su = sin (arg);
+  cu = cos (arg);
+  ss[k][0] = su;		/* sin(L) */
+  cc[k][0] = cu;		/* cos(L) */
+  sv = 2.0 * su * cu;
+  cv = cu * cu - su * su;
+  ss[k][1] = sv;		/* sin(2L) */
+  cc[k][1] = cv;
+  for (i = 2; i < n; i++)
+    {
+      s = su * cv + cu * sv;
+      cv = cu * cv - su * sv;
+      sv = s;
+      ss[k][i] = sv;		/* sin( i+1 L ) */
+      cc[k][i] = cv;
+    }
+  return (0);
+}
+
+
+/* Mean elements.
+   Copied from cmoon.c, DE404 version.  */
+
+static double Jlast = -1.0e38;
+static double T;
+
+static int
+dargs (J, plan)
+     double J;
+     struct plantbl *plan;
+{
+  double T2, w;
+
+  if (J == Jlast)
+    return 0;
+
+  T = (J - JD2000) / 36525.0;
+  T2 = T * T;
+
+  /* Mean anomaly of sun = l' (J. Laskar) */
+  w = mods3600 (129596581.038354 * T + 1287104.76154);
+  w += ((((((((
+		1.62e-20 * T
+		- 1.0390e-17) * T
+	      - 3.83508e-15) * T
+	     + 4.237343e-13) * T
+	    + 8.8555011e-11) * T
+	   - 4.77258489e-8) * T
+	  - 1.1297037031e-5) * T
+	 + 1.4732069041e-4) * T
+	- 0.552891801772) * T2;
+  sscc (10, STR * w, plan->max_harmonic[10]);
+
+  /* Mean distance of moon from its ascending node = F */
+  w = mods3600 ((1739527263.0983 - 2.079419901760e-01) * T + 335779.55755);
+  w = w + ((-9.646018347184e-06 * T2	/* F, t^4 */
+	    - 1.138215912580e-03) * T	/* F, t^3 */
+	   - 1.312045233711e+01) * T;	/* F, t^2 */
+  sscc (11, STR * w, plan->max_harmonic[11]);
+
+  /* Mean anomaly of moon = l */
+  w = mods3600 ((1717915923.4728 - 2.035946368532e-01) * T + 485868.28096);
+  w = w + ((-3.421689790404e-04 * T2	/* l, t^4 */
+	    + 4.768357585780e-02) * T	/* l, t^3 */
+	   + 3.146734198839e+01) * T;	/* l, t^2 */
+  sscc (9, STR * w, plan->max_harmonic[9]);
+
+  /* Mean elongation of moon = D */
+  w = mods3600 ((1602961601.4603 + 3.962893294503e-01) * T + 1072260.73512);
+  w = w + ((-2.905334122698e-04 * T2	/* D, t^4 */
+	    - 5.834100476561e-03) * T	/* D, t^3 */
+	   - 6.847070905410e+00) * T;	/* D, t^2 */
+  sscc (12, STR * w, plan->max_harmonic[12]);
+
+  /* Mean longitude of moon, re mean ecliptic and equinox of date */
+  w = mods3600 ((1732564372.83264 - 6.784914260953e-01) * T + 785939.95571);
+  w = w + ((-8.466472828815e-05 * T2	/* L, t^4 */
+	    + 5.722859298199e-03) * T	/* L, t^3 */
+	   - 5.663161722088e+00) * T;	/* L, t^2 */
+  sscc (13, STR * w, plan->max_harmonic[13]);
+
+  /* Mean longitudes of planets (Laskar, Bretagnon) */
+
+  /* Venus.  */
+  w = mods3600 (210664136.4335482 * T + 655127.283046);
+  w += ((((((((
+		-9.36e-023 * T
+		- 1.95e-20) * T
+	      + 6.097e-18) * T
+	     + 4.43201e-15) * T
+	    + 2.509418e-13) * T
+	   - 3.0622898e-10) * T
+	  - 2.26602516e-9) * T
+	 - 1.4244812531e-5) * T
+	+ 0.005871373088) * T2;
+  sscc (1, STR * w, plan->max_harmonic[1]);
+
+  /* Earth.  */
+  w = mods3600 (129597742.26669231 * T + 361679.214649);
+  w += ((((((((-1.16e-22 * T
+	       + 2.976e-19) * T
+	      + 2.8460e-17) * T
+	     - 1.08402e-14) * T
+	    - 1.226182e-12) * T
+	   + 1.7228268e-10) * T
+	  + 1.515912254e-7) * T
+	 + 8.863982531e-6) * T
+	- 2.0199859001e-2) * T2;
+  sscc (2, STR * w, plan->max_harmonic[2]);
+
+  /* Mars.  */
+  w = mods3600 (68905077.59284 * T + 1279559.78866);
+  w += (-1.043e-5 * T + 9.38012e-3) * T2;
+  sscc (3, STR * w, plan->max_harmonic[3]);
+
+  /* Jupiter.  */
+  w = mods3600 (10925660.428608 * T + 123665.342120);
+  w += (1.543273e-5 * T - 3.06037836351e-1) * T2;
+  sscc (4, STR * w, plan->max_harmonic[4]);
+
+  /* Saturn.  */
+  w = mods3600 (4399609.65932 * T + 180278.89694);
+  w += ((4.475946e-8 * T - 6.874806E-5) * T + 7.56161437443E-1) * T2;
+  sscc (5, STR * w, plan->max_harmonic[5]);
+  return 0;
+}
+
+
+
+/* Evaluate series PLAN at Julian date J.
+   Result in arcseconds, usually.  */
+
+static double
+gplan (J, plan)
+     double J;
+     struct plantbl *plan;
+{
+  double su, cu, sv, cv;
+  double t, sl;
+  int j, k, m, k1, ip, np, nt;
+  CHAR *p;
+  int *pl;
+
+  dargs (J, plan);
+  /* Point to start of table of arguments. */
+  p = plan->arg_tbl;
+  /* Point to tabulated cosine and sine amplitudes.  */
+  pl = plan->lon_tbl;
+  sl = 0.0;
+
+  for (;;)
+    {
+      /* Find sine and cosine of argument for this term in the series.
+	 The argument has the form J_1 L_1 + J_2 L_2 + ...
+	 where J_i are integers and L_i are mean elements.  */
+
+      /* Number of periodic arguments. */
+      np = *p++;
+      if (np < 0)
+	break;
+      if (np == 0)
+	{
+	  /* If no periodic arguments, it is a polynomial term.
+	     Evaluate A_n T^n + A_n-1 T^n-1 + ... + A_0.  */
+	  nt = *p++;
+	  cu = *pl++;
+	  for (ip = 0; ip < nt; ip++)
+	    cu = cu * T + *pl++;
+	  sl += cu;
+	  continue;
+	}
+      k1 = 0;
+      cv = 0.0;
+      sv = 0.0;
+      for (ip = 0; ip < np; ip++)
+	{
+	  /* What harmonic.  */
+	  j = *p++;
+	  /* Which planet.  */
+	  m = *p++ - 1;
+	  if (j)
+	    {
+	      k = j;
+	      if (j < 0)
+		k = -k;
+	      k -= 1;
+	      /* sin(k*angle) for planet m.  */
+	      su = ss[m][k];
+	      if (j < 0)
+		su = -su;
+	      /* cos(k*angle) for planet m.  */
+	      cu = cc[m][k];
+	      if (k1 == 0)
+		{
+		  /* Set sine and cosine of first angle. */
+		  sv = su;
+		  cv = cu;
+		  k1 = 1;
+		}
+	      else
+		{
+		  /* Combine angles by trigonometry.  */
+		  t = su * cv + cu * sv;
+		  cv = cu * cv - su * sv;
+		  sv = t;
+		}
+	    }
+	}
+      /* Now cv = cos(arg), sv = sin(arg).
+	 Evaluate
+	 cu = (C_n T^n + C_n-1 T^n-1 + ... + C_0) cos(arg)
+	 su = (S_n T^n + S_n-1 T^n-1 + ... + S_0) sin(arg).  */
+
+      /* Highest power of T.  */
+      nt = *p++;
+      /* Coefficients C_i, S_i.  */
+      cu = *pl++;
+      su = *pl++;
+      for (ip = 0; ip < nt; ip++)
+	{
+	  cu = cu * T + *pl++;
+	  su = su * T + *pl++;
+	}
+      sl += cu * cv + su * sv;
+    }
+  return (plan->trunclvl * sl);
+}
+
+
+
+/* lblat403.c */
+
+static int lattabr[] = {-1};
+static int lattabb[] = {-1};
+static int lattabl[] = {
+    785710,
+
+     -1958,       780,
+
+      -178,      2850,      2243,      5927,      2714,     -2911,
+
+      -174,      5888,    -16705,     10828,    -15113,    -25049,
+
+      -172,      1976,
+
+        37,    -13560,
+
+       -40,      -911,
+
+      -300,       691,
+
+      3779,       722,
+
+        68,     -1048,
+
+     -3092,        -4,      3011,       -31,       250, -14293664,
+
+      -149,      -228,
+
+        -5,      -842,
+
+        62,     57967,
+
+        -7,    -11207,
+
+        15,    -66055,
+
+       -79,    -71560,
+
+         8,      2998,
+
+     -1062,       -46,
+
+        -2,       711,
+
+        -5,        -2,
+
+       367,        -5,      -353,         1,      -117,   2324027,
+
+         0,      -176,
+
+        19,        -4,
+
+        -3,     -1229,
+
+         7,      4327,
+
+        -2,       112,
+
+        -1,      -540,
+
+        73,    102982,
+
+         0,      -137,
+
+         2,       239,
+
+         0,      -216,
+
+         2,      3707,
+
+        -1,      -100,
+
+        -2,       124,
+
+         0,       408,
+
+         1,       561,
+
+         0,       594,
+
+         0,     11866,
+
+        -2,      -229,
+
+        11,      6768,
+
+         2,         1,
+
+        -2,      -788,       -24,    314732,
+
+        -5,     -3238,
+
+        -2,     -1263,
+
+        -1,        94,
+
+        -2,       206,
+
+      -283,   6489836,
+
+        63,      2562,
+
+        -6,      1220,
+
+         0,       135,
+
+       795,      -338,
+
+      -406,      -101,
+
+       757,      -383,
+
+       -73,    -31018,
+
+        -5,     -3010,
+
+         6,      5821,
+
+       167,         7,
+
+         2,    122623,
+
+        41,    138924,
+
+         2,       253,
+
+         0,      -198,
+
+       135,        30,
+
+         2,       934,
+
+        62,       -14,
+
+      -531,   -297537,
+
+        -3,      -205,
+
+         1,      -393,
+
+        -4,      -156,
+
+      -467,        90,
+
+         9,      -346,
+
+       -55,      1368,
+
+      4414,      2094,
+
+       480,       510,
+
+        35,       728,
+
+      6832,      6429,
+
+     -2099,     -3703,
+
+        -9,       579,
+
+       239,      1738,
+
+        22,       968,     60260,     -8929,
+
+        26,       -64,
+
+         0,         0,
+
+       -47,      -351,      2248,     -1175,      3976,      7150,
+
+     15191,         1,    -15535,      -143,     -2308,-239959618,
+
+       -45,       355,      2252,      1189,      4009,     -7131,
+
+      -158,       499,
+
+       776,       -34,
+
+      -389,      4363,
+
+        30,        28,
+
+         0,      -593,
+
+         1,        -1,
+
+        58,       -66,
+
+         4,      1552,
+
+        -1,       244,
+
+       288,        59,
+
+      -276,        62,
+
+         8,      3309,
+
+         2,      1249,
+
+      -156,        -3,
+
+         0,     -7903,
+
+       -47,    154458,
+
+      -710,       160,
+
+         0,       288,
+
+       328,    219514,
+
+        -1,       113,
+
+        -1,      1515,
+
+       -20,     28493,
+
+        13,      9011,
+
+        -1,      1110,
+
+        -1,      -103,
+
+         0,       312,
+
+         1,       360,
+
+         6,      6139,
+
+        -1,       142,
+
+        -1,      -709,
+
+        -1,      -242,
+
+        67,     67200,
+
+         5,      4148,
+
+         1,       137,
+
+       -15,    -17969,
+
+        -2,     -3372,
+
+        -2,     -1739,
+
+       154,    116200,
+
+        -1,      -640,
+
+      -269,   -336274,
+
+         0,     -1557,
+
+        -1,      -353,
+
+       993,        39,
+
+        -1,      -294,
+
+      -646,      -135,
+
+       750,        -3,      -661,         8,      -163,   2591179,
+
+        -1,      -258,
+
+         0,       381,
+
+         6,      8272,
+
+       -44,    -92044,
+
+       -29,     70397,
+
+       -25,    -17892,
+
+         1,        67,
+
+       -44,    -17118,
+
+      2743,       349,
+
+        -4,       231,
+
+      1501,      3099,
+
+       -33,        21,
+
+     -1130,        97,      1263,       164,      -226, -13139965,
+
+       839,      -202,
+
+        -1,       660,
+
+        12,    -10482,
+
+         1,        17,
+
+        -2,     -1480,
+
+       -45,    -26084,
+
+         2,       259,
+
+         0,       258,
+
+        -1,     -1560,
+
+        32,     73046,
+
+        -1,      -370,
+
+        -1,       -77,
+
+        46,     20687,
+
+         1,       742,
+
+         1,      2399,
+
+         2,       741,
+
+         0,        52,
+
+         0,       112,
+
+         0,       297,
+
+         2,       825,
+
+         0,       161,
+
+         1,      4228,
+
+         0,       212,
+
+        -1,      -105,
+
+         6,      2782,
+
+         9,     37199,
+
+         3,      5045,
+
+       105,        -1,
+
+        -1,      -179,
+
+        75,     31274,
+
+        -3,     -1321,
+
+        -1,       363,
+
+         0,      1137,
+
+        58,    104090,
+
+        -2,     -2695,
+
+        -1,      -392,
+
+       -35,    -21763,
+
+        -2,      -205,
+
+       567,        38,
+
+        -7,       117,
+
+      -569,        -9,       321,  -1522061,
+
+        -4,       276,
+
+        -2,      -590,
+
+         2,       632,
+
+       -14,    -10601,
+
+         4,      8703,
+
+       -10,     16870,
+
+        -4,      -995,
+
+       597,        -6,      -386,   -805403,
+
+      1025,      -474,
+
+        -2,       201,
+
+       -95,        16,
+
+      -127,    135570,
+
+         0,      -173,
+
+        10,      8565,
+
+        -3,      1812,
+
+        -1,      -108,
+
+      -107,      -649,
+
+         0,       151,
+
+         1,       950,
+
+         1,       312,
+
+         1,       403,
+
+         0,      -576,
+
+         7,      4418,
+
+        -3,     -4769,
+
+        -1,      -769,
+
+        63,     38890,
+
+         0,      -101,
+
+         0,       169,
+
+        -3,    -14837,
+
+         1,       372,
+
+         0,      -674,
+
+        -3,     -1488,
+
+       -36,   -196300,
+
+         0,      -176,
+
+       -10,     -4811,
+
+        -2,      -991,
+
+         1,       831,
+
+         1,      3138,
+
+      -103,    -51819,
+
+         0,      -133,
+
+        -4,     22171,
+
+         2,       820,
+
+         1,       149,
+
+      2227,      1277,
+
+      -502,     -3049,
+
+         1,       122,
+
+         0,       370,
+
+         0,       166,
+
+         2,       772,
+
+         2,      2057,
+
+        -1,      -486,
+
+        13,    -15447,
+
+        -2,     -1619,
+
+         0,       335,
+
+         0,      -206,
+
+         0,      -104,
+
+       -19,    -19726,
+
+         0,       414,
+
+        -8,     -3425,
+
+       -19,        -1,
+
+         1,       546,
+
+         0,      -392,
+
+         0,     -2754,
+
+         0,      -158,
+
+        -3,     -1790,
+
+        -1,      -230,
+
+         0,      -190,
+
+         0,      -366,
+
+         0,      -154,
+
+};
+
+static CHAR latargs[] = {
+  0,  0,
+  3,  1,  2,  9,  3,-20,  4,  0,
+  4,  1, 13, -1, 10,  3,  2, -4,  3,  2,
+  4,  1, 13, -1, 10, -5,  2,  9,  3,  2,
+  3,  9, 10, -9, 14,  1,  3,  0,
+  3,  1, 11, -1, 12,  1, 13,  0,
+  4,  1, 10, -2, 11,  1, 12, -2, 13,  0,
+  4,  2, 11, -1, 14, 18,  2,-18,  3,  0,
+  3,  1, 13, -1, 10,  1,  3,  0,
+  2,  1, 10, -1, 14,  0,
+  2,  1, 10, -1, 12,  2,
+  4,  1, 14,-18,  2, 16,  3,  1,  5,  0,
+  3,  2, 10, -1, 12, -1, 13,  0,
+  3,  1, 10,  1, 11, -1, 12,  0,
+  4,  1, 10, -1, 11,  1, 12, -2, 13,  0,
+  2,  1, 12, -1, 13,  0,
+  3,  1, 10, -1, 11, -1, 12,  0,
+  3,  3, 10, -1, 12, -2, 13,  0,
+  2,  2, 10, -2, 13,  0,
+  3,  1, 10,  2, 11, -1, 12,  0,
+  3,  1, 10, -2, 13,  1,  3,  0,
+  3,  1, 10,  1, 12, -2, 13,  2,
+  3,  1, 11,  1, 12, -1, 13,  0,
+  2,  2, 12, -2, 13,  0,
+  3,  1, 10, -2, 11, -1, 12,  0,
+  3,  1, 10, -3, 12,  2, 13,  0,
+  4,  3, 10,  1, 11, -1, 12, -2, 13,  0,
+  3,  2, 10,  1, 12, -3, 13,  0,
+  4,  1, 10,  1, 11,  1, 12, -2, 13,  0,
+  2,  3, 12, -3, 13,  0,
+  4,  1, 10, -1, 11, -3, 12,  2, 13,  0,
+  3,  3, 10,  1, 12, -4, 13,  0,
+  4,  1, 10,  2, 11,  1, 12, -2, 13,  0,
+  3,  1, 10,  3, 12, -4, 13,  0,
+  4,  1, 10,  3, 11,  1, 12, -2, 13,  0,
+  3,  3, 11,  1, 12, -2, 13,  0,
+  4,  2, 10,  1, 11,  1, 12, -4, 13,  0,
+  2,  3, 12, -4, 13,  0,
+  3,  2, 11,  1, 12, -2, 13,  0,
+  4,  1, 10,  1, 11,  1, 12, -3, 13,  0,
+  3,  2, 10,  1, 12, -4, 13,  0,
+  4,  1, 14, -3,  2,-16,  3, -4,  4,  0,
+  3,  1, 11,  1, 12, -2, 13,  1,
+  3,  1, 10,  1, 12, -3, 13,  0,
+  4,  2, 10,  1, 11, -1, 12, -2, 13,  0,
+  3,  2, 10, -3, 12,  2, 13,  0,
+  4,  1, 10, -1, 11, -1, 12,  1, 13,  0,
+  2,  1, 12, -2, 13,  0,
+  2,  2, 13, -1, 14,  0,
+  2,  2, 11, -1, 12,  0,
+  4,  1, 10, -1, 11,  1, 12, -3, 13,  0,
+  3,  2, 10, -3, 14,  4,  4,  0,
+  2,  1, 10, -2, 13,  0,
+  3,  1, 13, -3,  3,  4,  4,  0,
+  3,  2, 10, -1, 12, -2, 13,  0,
+  3,  2, 10, -1, 11, -1, 12,  0,
+  3,  1, 10, -1, 12,  1, 13,  0,
+  2,  1, 10, -1, 11,  0,
+  3,  1, 11, -1, 12,  2, 13,  0,
+  2,  1, 11, -1, 12,  0,
+  3,  1, 10, -1, 12, -1, 13,  0,
+  4,  2, 13, -1, 12,  2,  2, -2,  3,  0,
+  3,  1, 13,  2,  2, -3,  3,  0,
+  4,  2, 10, -1, 11, -1, 12, -2, 13,  0,
+  3,  1, 13, -1,  2,  2,  3,  0,
+  2,  2, 10, -1, 12,  0,
+  4,  2, 13, -1, 12,  2,  3, -2,  5,  0,
+  4,  2, 13, -1, 12,  3,  2, -3,  3,  0,
+  4,  2, 10, -2, 11,  1, 12, -2, 13,  0,
+  3,  1, 13,  1,  3, -2,  5,  0,
+  4,  1, 10,  1, 11, -1, 12,  1, 13,  0,
+  3,  1, 13, -5,  2,  9,  3,  0,
+  3,  1, 14,  2,  3, -4,  4,  0,
+  3,  3, 10,  4, 12, -6, 14,  0,
+  3,  1, 13,  3,  2, -4,  3,  0,
+  1,  1, 10,  0,
+  3,  1, 13, -3, 12,  9,  2,  0,
+  4,  1, 10, -1, 11,  1, 12, -1, 13,  0,
+  3,  2, 11, -1, 12,  2, 13,  0,
+  1,  1, 14,  1,
+  4,  1, 12,  1, 10, -1, 14,  1,  5,  0,
+  4,  9, 13, -9, 10,  7,  2, 10,  3,  0,
+  3,  1, 12, -8,  2, 13,  3,  2,
+  1,  1, 12,  2,
+  3,  1, 12,  8,  2,-13,  3,  2,
+  2,  1, 13,  2,  4,  0,
+  4,  2, 13, -1, 12,  5,  2, -6,  3,  0,
+  3,  1, 13, -2, 12,  1,  3,  0,
+  3,  1, 13, -3,  2,  6,  3,  0,
+  4,  1, 10, -1, 11, -1, 12, -1, 13,  0,
+  2,  1, 14,  2,  5,  0,
+  2,  1, 10, -2, 12,  0,
+  2,  2, 10, -3, 12,  0,
+  4,  2, 13, -1, 12,  4,  2, -4,  3,  0,
+  3,  1, 14,  4,  2, -6,  3,  0,
+  2,  1, 13,  1,  2,  0,
+  3,  2, 10,  1, 11, -1, 12,  0,
+  4,  2, 10, -1, 11,  1, 12, -2, 13,  0,
+  2,  1, 10,  1, 11,  0,
+  3,  1, 10,  1, 12, -1, 13,  0,
+  2,  1, 11,  1, 12,  0,
+  3,  3, 12, -2, 13, -1,  3,  0,
+  3,  4, 10, -1, 12, -2, 13,  0,
+  3,  2, 10,  1, 12, -2, 13,  0,
+  4,  1, 10,  1, 11,  1, 12, -1, 13,  0,
+  2,  2, 11,  1, 12,  0,
+  2,  3, 12, -2, 13,  0,
+  4,  2, 10,  1, 11,  1, 12, -2, 13,  0,
+  3,  1, 11,  3, 12, -2, 13,  0,
+  3,  4, 10,  1, 12, -4, 13,  0,
+  4,  2, 10,  2, 11,  1, 12, -2, 13,  0,
+  4,  1, 10,  2, 11,  1, 12, -4, 13,  0,
+  4,  1, 10,  1, 11,  1, 12, -4, 13,  0,
+  4,  1, 10,  3, 11, -1, 12, -2, 13,  0,
+  4,  1, 10, -2, 11, -1, 12,  2, 13,  0,
+  3,  1, 11,  1, 12, -3, 13,  0,
+  3,  1, 10,  1, 12, -4, 13,  0,
+  4,  1, 10,  2, 11, -1, 12, -2, 13,  0,
+  3,  3, 10, -1, 12, -4, 13,  0,
+  4,  1, 10, -1, 11, -1, 12,  2, 13,  0,
+  2,  1, 12, -3, 13,  0,
+  4,  1, 10, -1, 11,  1, 12, -4, 13,  0,
+  4,  1, 10,  1, 11, -1, 12, -2, 13,  0,
+  3,  2, 10, -1, 12, -3, 13,  0,
+  3,  1, 10, -1, 12,  2, 13,  0,
+  3,  1, 10, -2, 11,  1, 12,  0,
+  3,  1, 11, -1, 12,  3, 13,  0,
+  1,  2, 13,  0,
+  3,  1, 11, -1, 12, -1, 13,  0,
+  3,  1, 10, -3, 13, -1,  3,  0,
+  3,  1, 10, -1, 12, -2, 13,  2,
+  3,  3, 10, -1, 11, -1, 12,  0,
+  3,  2, 10, -1, 12,  1, 13,  0,
+  4,  1, 10,  1, 11, -1, 12,  2, 13,  0,
+  3,  1, 10, -1, 11,  1, 12,  0,
+  2,  1, 12,  1, 13,  0,
+  4,  1, 10, -1, 11, -1, 12, -2, 13,  0,
+  3,  1, 10,  1, 11, -3, 12,  0,
+  2,  3, 10, -1, 12,  0,
+  1,  2, 10,  0,
+  4,  2, 10, -1, 11,  1, 12, -1, 13,  0,
+  3,  1, 13,  1, 10,  1, 11,  0,
+  3,  2, 13,  3,  3, -2, 11,  0,
+  2,  1, 10,  1, 12,  2,
+  3,  1, 10, -3, 14,  2,  5,  0,
+  3,  3, 10, -1, 14,  4,  5,  0,
+  3,  1, 11,  1, 12,  1, 13,  0,
+  1,  2, 12,  0,
+  4,  1, 10, -2, 11, -1, 12, -2, 13,  0,
+  2,  1, 10, -3, 12,  0,
+  3,  3, 10,  1, 11, -1, 12,  0,
+  4,  3, 10, -1, 11,  1, 12, -2, 13,  0,
+  3,  2, 10,  1, 12, -1, 13,  0,
+  3,  1, 10,  1, 11,  1, 12,  0,
+  2,  3, 12, -1, 13,  0,
+  3,  1, 10, -1, 11, -3, 12,  0,
+  3,  3, 10,  1, 12, -2, 13,  0,
+  3,  1, 10,  2, 11,  1, 12,  0,
+  3,  1, 10,  3, 12, -2, 13,  0,
+  4,  3, 10,  1, 11,  1, 12, -2, 13,  0,
+  4,  1, 10,  1, 11,  3, 12, -2, 13,  0,
+  4,  2, 10,  1, 11,  1, 12, -6, 13,  0,
+  3,  2, 11,  1, 12, -4, 13,  0,
+  3,  2, 10,  1, 12, -6, 13,  0,
+  4,  2, 10,  2, 11, -1, 12, -4, 13,  0,
+  3,  1, 11,  1, 12, -4, 13,  0,
+  3,  3, 11, -1, 12, -2, 13,  0,
+  3,  1, 10,  1, 12, -5, 13,  0,
+  4,  2, 10,  1, 11, -1, 12, -4, 13,  0,
+  2,  1, 12, -4, 13,  0,
+  3,  2, 11, -1, 12, -2, 13,  0,
+  2,  1, 10, -4, 13,  0,
+  4,  1, 10,  1, 11, -1, 12, -3, 13,  0,
+  3,  2, 10, -1, 12, -4, 13,  0,
+  4,  2, 10, -1, 11, -1, 12,  2, 13,  0,
+  3,  1, 10, -1, 12,  3, 13,  0,
+  3,  1, 11, -1, 12,  4, 13,  0,
+  3,  1, 11, -1, 12, -2, 13,  0,
+  3,  1, 10, -1, 12, -3, 13,  0,
+  4,  2, 10, -1, 11, -1, 12, -4, 13,  0,
+  3,  2, 10, -1, 12,  2, 13,  0,
+  3,  2, 10, -2, 11,  1, 12,  0,
+  2,  1, 10,  2, 13,  0,
+  4,  1, 10, -1, 11,  1, 12,  1, 13,  0,
+  2,  1, 12,  2, 13,  1,
+  4,  1, 10, -1, 11, -1, 12, -3, 13,  0,
+  3,  2, 10, -3, 12, -2, 13,  0,
+  4,  2, 10,  1, 11, -1, 12,  2, 13,  0,
+  3,  2, 10, -1, 11,  1, 12,  0,
+  3,  1, 10,  1, 12,  1, 13,  0,
+  3,  1, 11,  1, 12,  2, 13,  0,
+  2,  4, 10, -1, 12,  0,
+  2,  2, 10,  1, 12,  1,
+  4,  1, 13,  1, 12, 10,  2, -2,  3,  0,
+  3,  2, 11,  1, 12,  2, 13,  0,
+  2,  2, 12,  1, 14,  0,
+  1,  3, 12,  0,
+  3,  3, 10,  1, 12, -1, 13,  0,
+  3,  2, 10,  1, 11,  1, 12,  0,
+  3,  4, 10,  1, 12, -2, 13,  0,
+  3,  2, 10,  3, 12, -2, 13,  0,
+  3,  4, 10, -9,  3, -1,  4,  0,
+  4,  1, 10,  1, 11,  1, 12, -6, 13,  0,
+  3,  1, 10,  1, 12, -6, 13,  0,
+  4,  1, 10,  2, 11, -1, 12, -4, 13,  0,
+  3,  3, 10, -1, 12, -6, 13,  0,
+  4,  1, 10, -1, 11, -1, 12,  4, 13,  0,
+  4,  1, 10,  1, 11, -1, 12, -4, 13,  0,
+  3,  1, 10, -1, 12,  4, 13,  0,
+  4,  1, 10, -2, 11,  1, 12,  2, 13,  0,
+  3,  1, 10, -1, 12, -4, 13,  0,
+  4,  3, 10, -1, 11, -1, 12,  2, 13,  0,
+  4,  1, 10,  1, 11, -1, 12,  4, 13,  0,
+  4,  1, 10, -1, 11,  1, 12,  2, 13,  0,
+  2,  1, 12,  3, 13,  0,
+  4,  1, 10, -1, 11, -1, 12, -4, 13,  0,
+  3,  3, 10, -1, 12,  2, 13,  0,
+  3,  1, 10,  1, 12,  2, 13,  0,
+  3,  1, 11,  1, 12,  3, 13,  0,
+  3,  1, 10, -3, 12, -2, 13,  0,
+  3,  3, 10, -1, 11,  1, 12,  0,
+  3,  2, 10,  1, 12,  1, 13,  0,
+  4,  1, 10,  1, 11,  1, 12,  2, 13,  0,
+  2,  3, 10,  1, 12,  0,
+  4,  2, 10,  1, 11,  1, 12,  1, 13,  0,
+  2,  1, 10,  3, 12,  0,
+  3,  3, 10,  1, 11,  1, 12,  0,
+  3,  5, 10,  1, 12, -2, 13,  0,
+  3,  4, 14, -4,  2,  8,  3,  0,
+  3,  5, 10, -9,  3, -1,  4,  0,
+  4,  2, 10,  1, 11, -1, 12, -6, 13,  0,
+  2,  1, 12, -6, 13,  0,
+  3,  2, 11, -1, 12, -4, 13,  0,
+  3,  2, 10, -1, 12, -6, 13,  0,
+  3,  1, 11, -1, 12, -4, 13,  0,
+  3,  2, 10, -1, 12,  4, 13,  0,
+  2,  1, 12,  4, 13,  0,
+  4,  2, 10, -1, 11,  1, 12,  2, 13,  0,
+  3,  1, 11,  1, 12,  4, 13,  0,
+  3,  1, 11, -3, 12, -2, 13,  0,
+  3,  4, 10, -1, 12,  2, 13,  0,
+  3,  2, 10,  1, 12,  2, 13,  0,
+  4,  2, 10,  1, 11,  1, 12,  2, 13,  0,
+  2,  4, 10,  1, 12,  0,
+  3,  7, 12, -2, 10, -4,  5,  0,
+  3,  1, 10, -1, 12, -6, 13,  0,
+  4,  1, 10, -1, 11,  1, 12,  4, 13,  0,
+  3,  1, 10,  1, 12,  4, 13,  0,
+  4,  3, 10, -1, 11,  1, 12,  2, 13,  0,
+  3,  3, 10,  1, 12,  2, 13,  0,
+  2,  5, 10,  1, 12,  0,
+  2,  1, 12,  6, 13,  0,
+  3,  2, 10,  1, 12,  4, 13,  0,
+  3,  4, 10,  1, 12,  2, 13,  0,
+ -1
+};
+
+/* Total terms = 254, small = 254 */
+static struct plantbl liblat = {
+  /*  {  0, 18, 18, 20,  4,  0,  0,  0,  0,  9,  3,  7,  9,  9,}, */
+  /* Use max of liblon, liblat.  */
+  {  0, 18, 18, 20,  4,  2,  0,  0,  0,  9, 16,  7,  9,  9,},
+ 2,
+ latargs,
+ lattabl,
+ lattabb,
+ lattabr,
+ 3.850000e+05,
+ 36525.0,
+ 1.0e-4,
+};
+
+
+/* lblon403.c */
+static int lontabr[] = {-1};
+static int lontabb[] = {-1};
+static int lontabl[] = {
+   -640001,
+
+       -19,         3,
+
+        -1,         0,
+
+        -3,        17,
+
+         2,        -9,
+
+         2,         3,
+
+       141,      1816,
+
+         2,       -76,
+
+        78,       -81,
+
+         3,         1,
+
+        50,       -13,
+
+       -12,        18,
+
+        -6,        74,
+
+        19,        10,
+
+       -19,       701,
+
+       -26,        37,
+
+        36,      -122,
+
+       131,       -71,
+
+       -40,         1,
+
+     61463,     12853,
+
+         5,       -29,
+
+       354,       201,
+
+        94,        -5,
+
+        31,        25,
+
+       -73,       -22,
+
+       673,      1435,
+
+      3844,        44,
+
+       -44,        -8,
+
+       195,       -16,
+
+      -827,   -171768,
+
+      7051,     -4116,
+
+      1036,       616,     -2034,      6300,    -13786,     -3808,
+
+      -118,      -536,     -1246,       771,      2555,      3214,
+
+       203,        26,
+
+      2975,      -715,
+
+      -743,      1286,
+
+      -232,       -50,
+
+         4,       234,
+
+      -139,       475,
+
+         0,       -98,
+
+        -3,    -11848,
+
+         0,       118,
+
+      -202,       146,
+
+    -33673,      7601,
+
+      -150,        88,
+
+     -1720,      1002,
+
+      -293,       481,
+
+     -2078,         1,
+
+       199,    220655,
+
+       137,      7459,
+
+      -127,        28,
+
+       -10,      2259,
+
+         4,       450,
+
+       -26,        30,       -76,     19043,       215,  -7577830,
+
+       -65,       -45,
+
+        -5,    -14189,
+
+        -6,      -496,
+
+         9,      3265,
+
+         0,      -131,
+
+        48,       -90,
+
+        -9,      -155,
+
+        -2,        21,
+
+       151,        19,
+
+      -101,      -516,
+
+      -827,         3,       796,         2,       134,  -2215850,
+
+       -11,     -1908,
+
+         0,       451,
+
+        -2,      1399,
+
+         3,         7,
+
+      -163,         5,
+
+     -1582,        61,
+
+       -22,    -77215,
+
+       167,   -471084,
+
+       -85,       -28,
+
+         1,      -473,
+
+        -1,       444,
+
+         4,        89,
+
+         6,       -88,
+
+      -157,    -87813,
+
+         3,       274,
+
+        -3,     -1036,
+
+         7,    -17005,
+
+        -1,      -332,
+
+         0,        50,
+
+        -1,      -228,
+
+        -5,     -2986,
+
+        -1,      -334,
+
+         1,      -452,
+
+         0,         4,
+
+         0,      -247,
+
+        -3,     -2493,
+
+        -4,     -1000,
+
+         0,      -160,
+
+         0,     -3163,
+
+       -75,    -74207,
+
+        13,       829,
+
+        32,       481,
+
+       -33,    -11859,
+
+        -2,     -3634,
+
+         7,     -1611,
+
+         3,       520,
+
+        -1,      2534,
+
+         5,      -446,
+
+      -471,         8,       399,      5160,       201,  -2057189,
+
+        83,     -2106,
+
+        11,     12240,
+
+         3,      -270,
+
+       248,      1112,
+
+       -63,    -61809,
+
+      -183,       594,
+
+        27,     25844,
+
+        -3,      5594,
+
+         8,       571,
+
+       -23,     -1855,
+
+       477,      -466,
+
+         0,     -1257,
+
+       247,      1550,
+
+    -10178,      -175,      9570,      -423,      2610, -45917681,
+
+       -51,       937,
+
+     -1001,       168,
+
+      -168,       882,
+
+      1260,     -2894,      4306,     -1515,
+
+         7,       402,
+
+         0,        36,
+
+      -280,      -373,
+
+       -19,       840,
+
+     -1227,      -138,
+
+      3486,   1478247,
+
+      1649,      -644,
+
+       840,       377,
+
+        47,     -1464,
+
+       167,  -1251123,
+
+      -194,      -713,       133,    284429,
+
+         0,      -191,
+
+        -3,      1534,
+
+      -700,       918,
+
+        -7,      -633,
+
+      -221,      -559,
+
+         1,        99,
+
+       -17,     -3513,
+
+       -30,        14,
+
+      -602,     -5006,
+
+       908,      4178,
+
+       542,      -379,
+
+      1568,       782,       528,      2761,
+
+    -38994,    -25804,
+
+   1696398,   -324306,
+
+     47292,     71061,    457883,     52470,    159777, 224906030,
+
+    -13068,    -18508,
+
+      -104,      3754,
+
+       541,       614,      -290,      1412,
+
+       -48,       162,
+
+        42,       -50,
+
+      -609,     -4969,
+
+        44,    -11435,
+
+      -473,      -412,
+
+        22,     -6389,
+
+       -87,        44,
+
+       -39,    180182,
+
+     -4186,     -2227,
+
+      -503,      -208,
+
+       976,      -512,     -1016,     -4403,
+
+        16,     25357,
+
+       565,      -891,
+
+        28,     38836,
+
+      -659,      -855,
+
+      -200,       619,
+
+         1,     -1780,
+
+        24,     17531,
+
+      1053,       335,
+
+       502,      2745,      -309,  -1094576,
+
+        -1,      -263,
+
+         3,      -394,
+
+         0,      4152,
+
+        -1,      -467,
+
+      -339,   -132142,
+
+       -14,    -11676,
+
+        29,     63360,
+
+         0,       129,
+
+       -12,     -4802,
+
+        -1,      -180,
+
+         2,      3424,
+
+         0,        45,
+
+        -1,      -155,
+
+        -1,       -74,
+
+         0,      -134,
+
+        -4,     -1588,
+
+        -1,     -3424,
+
+         2,       119,
+
+       -57,    -27417,
+
+         0,       168,
+
+         0,       206,
+
+       -21,    -80823,
+
+         8,      2324,
+
+        -4,       835,
+
+       396,        -6,      -244,   -308040,
+
+         0,      -294,
+
+       -56,     -1332,
+
+         2,      -110,
+
+       306,      4060,       -58,  -1644587,
+
+      -155,      -210,
+
+        67,     -1642,
+
+        27,     32070,
+
+         9,      3592,
+
+        -8,       -17,
+
+        -1,         2,
+
+        -9,     -4580,
+
+         5,      1940,
+
+         5,     -1217,
+
+        62,      -862,
+
+      -522,     -1163,
+
+         0,         0,
+
+     -1646,         1,      1169,       109,      1395,  23634968,
+
+         2,         0,
+
+      -512,      1148,
+
+        -9,        32,
+
+         0,     -2749,
+
+       969,        -4,
+
+         2,       351,
+
+         1,       105,
+
+       152,     97075,
+
+       -55,    -84524,
+
+       -49,       607,        29,   -242117,
+
+         4,      6518,
+
+         5,       -77,
+
+         1,       -39,
+
+         9,         1,
+
+         5,      -231,
+
+      2296,       -10,     -2453,         3,       138,   7689964,
+
+         0,      -689,
+
+         1,     12635,
+
+      5444,       372,
+
+         9,     -1843,
+
+      3485,      -560,
+
+       909,         3,      -742,        -1,       -66,  -6945414,
+
+         8,        -7,
+
+        -3,      -181,
+
+         1,      1282,
+
+      -115,    -76497,
+
+         3,       -90,
+
+         1,      -142,
+
+        -5,     10263,
+
+       -33,     -9479,
+
+         0,      -657,
+
+        19,     15040,
+
+        -2,      1084,
+
+        -1,      -295,
+
+      -161,       403,
+
+         0,      -175,
+
+        -1,      -392,
+
+        -4,     -3096,
+
+        -9,     -2928,
+
+         1,       332,
+
+       -56,    -43733,
+
+         1,       572,
+
+         2,      -660,
+
+         4,      7540,
+
+         4,      -659,
+
+      -505,   -382941,
+
+        -3,       256,
+
+         2,        30,
+
+        76,    145296,
+
+        -4,      4115,
+
+         9,      6329,
+
+        11,      6962,
+
+         0,      -338,
+
+         1,       153,
+
+         2,      -147,
+
+      -270,       211,
+
+      -519,        97,       385,   1912268,
+
+        -1,      1495,
+
+        -3,       223,
+
+       254,    152832,
+
+        15,      6709,
+
+        -8,     -5835,
+
+       -12,    -29016,
+
+         0,     -5641,
+
+        -2,      4217,
+
+        -2,     -1176,
+
+      -496,         4,       331,    360972,
+
+         1,       918,
+
+        -2,      -136,
+
+      -111,   -762309,
+
+         2,      -610,
+
+         1,        96,
+
+       -11,     -5468,
+
+         0,      4856,
+
+         0,        -2,
+
+       -16,      -668,
+
+        20,      1963,
+
+        -1,       -95,
+
+         0,       -83,
+
+         0,       -96,
+
+        -2,      -902,
+
+         0,     -1523,
+
+       -14,     -5691,
+
+       -10,    -18650,
+
+         0,       131,
+
+         0,       128,
+
+         0,       243,
+
+         1,       644,
+
+       -76,    138046,
+
+        -1,       316,
+
+         8,      2703,
+
+        15,     11758,
+
+        -1,        16,
+
+         2,     -2867,
+
+         5,      6504,
+
+       180,    143085,
+
+        -1,       224,
+
+        86,    -96384,
+
+         1,       471,
+
+         0,      -407,
+
+        -3,     -2886,
+
+        -1,      -919,
+
+         0,       742,
+
+        -2,      1145,
+
+        59,     19306,
+
+         0,        67,
+
+       -61,    -67569,
+
+       -14,     11725,
+
+        -1,      -395,
+
+         1,       772,
+
+        -1,       -49,
+
+       563,       871,      1951,       -22,
+
+        -1,      -711,
+
+         0,       240,
+
+        -6,     -3912,
+
+         1,      2812,
+
+         0,       106,
+
+         0,       378,
+
+         4,     19609,
+
+         6,      3331,
+
+         2,       930,
+
+         0,       -37,
+
+         0,      -502,
+
+         0,     -1257,
+
+        21,     10531,
+
+         2,    -16662,
+
+         0,      -267,
+
+        -1,        22,
+
+         6,      1104,
+
+       -14,     -5544,
+
+         1,      -250,
+
+        -1,      1248,
+
+         0,       325,
+
+         2,      2163,
+
+         2,     -1421,
+
+         0,        73,
+
+        -1,       -67,
+
+         2,       771,
+
+        -1,     -2085,
+
+         0,        67,
+
+         1,       226,
+
+         1,       212,
+
+         0,        56,
+
+};
+
+static CHAR lonargs[] = {
+  0,  0,
+  4,  1, 10,  3, 11,-18,  2, 13,  3,  0,
+  4, -2, 12,  2, 13,  5,  2, -6,  3,  0,
+  4,  2, 10, -2, 13, -2,  3,  3,  5,  0,
+  3,  1, 10, -1, 14,  1,  5,  0,
+  4, -2, 10,  2, 13, -5,  3, -6,  4,  0,
+  2,  1, 12, -1, 14,  0,
+  4, -2, 10,  2, 13,  2,  3, -2,  5,  0,
+  2,  1,  3, -2,  4,  0,
+  4, -1, 12,  1, 13, -3,  2,  6,  3,  0,
+  1,  1,  5,  0,
+  4, -1, 10,  2, 13,-15,  2, 13,  3,  0,
+  4,  2, 10, -2, 13, -3,  2,  3,  3,  0,
+  2,  2, 12, -2, 14,  0,
+  3,  1, 10, -1, 11, -1, 13,  0,
+  2, 11,  2,-18,  3,  0,
+  2,  3,  2, -5,  3,  0,
+  2,  2,  3, -4,  4,  0,
+  2,  5,  2, -8,  3,  0,
+  2,  1, 10, -1, 12,  0,
+  4, -1, 12,  1, 14,  3,  2, -5,  3,  0,
+  3,  6, 12, -6, 13, -4,  2,  0,
+  2,  3,  3, -6,  4,  0,
+  2,  5,  3, -9,  4,  0,
+  4, -1, 10,  2, 13,-18,  2, 18,  3,  0,
+  3,  2, 10, -2,  3, -2, 13,  0,
+  2,  2,  2, -3,  3,  0,
+  4,  2, 10, -2, 13, -4,  2,  5,  3,  0,
+  2,  4,  3, -7,  4,  0,
+  2,  2, 10, -2, 12,  0,
+  2,  3,  3, -5,  4,  0,
+  3,  3,  2, -4,  3, -1,  4,  2,
+  3,  1,  2, -5,  3,  7,  4,  2,
+  4, -2, 10,  2, 13,  5,  2, -6,  3,  0,
+  2,  1,  2, -2,  3,  0,
+  2,  2,  3, -3,  4,  0,
+  4, -1, 12,  1, 14,  4,  2, -6,  3,  0,
+  2,  1,  3, -1,  4,  0,
+  2,  4,  2, -6,  3,  0,
+  4,  2, 10, -2, 13, -2,  2,  2,  3,  0,
+  2,  1,  2, -1,  3,  0,
+  3,  2, 10,  1, 11, -2, 12,  0,
+  2,  1,  3, -3,  5,  0,
+  3,  2, 10, -1,  3, -2, 13,  0,
+  2,  4,  3, -6,  4,  0,
+  2,  1,  3, -2,  5,  0,
+  2,  3,  3, -4,  4,  0,
+  2,  3,  2, -4,  3,  0,
+  2,  1, 10, -1, 13,  0,
+  2,  1,  3, -1,  5,  0,
+  2,  1,  3, -2,  6,  0,
+  2,  2,  3, -2,  4,  0,
+  2,  1,  3, -1,  6,  0,
+  1,  1, 11,  2,
+  2,  1,  3,  1,  5,  0,
+  3,  1, 11, -2, 12,  2, 13,  0,
+  3,  1, 10, -2, 12,  1, 13,  0,
+  2,  2,  2, -2,  3,  0,
+  3,  2, 10, -1, 11, -2, 12,  0,
+  2,  4,  3, -5,  4,  0,
+  2,  3,  3, -3,  4,  0,
+  3,  4, 10, -2, 12, -2, 13,  0,
+  1,  1,  2,  0,
+  2,  2,  3, -3,  5,  0,
+  2,  2, 10, -2, 13,  2,
+  2,  2,  3, -2,  5,  0,
+  2,  3,  3, -3,  2,  0,
+  3,  1, 10,  1, 11, -1, 13,  0,
+  3,  3,  3, -1,  2,  1,  4,  0,
+  2,  2,  3, -1,  5,  0,
+  3,  1, 10,  1, 12, -2, 13,  0,
+  1,  2, 11,  0,
+  2,  2, 12, -2, 13,  0,
+  2,  2,  2, -1,  3,  0,
+  2,  4,  2, -4,  3,  0,
+  2,  3, 10, -3, 13,  0,
+  4,  2, 10, -2, 13,  1,  3, -1,  5,  0,
+  2,  3,  3, -3,  5,  0,
+  3,  2, 10,  1, 11, -2, 13,  0,
+  3,  1, 10,  2, 12, -3, 13,  0,
+  1,  3, 11,  0,
+  3,  1, 11,  2, 12, -2, 13,  0,
+  2,  5,  2, -5,  3,  0,
+  2,  4, 10, -4, 13,  0,
+  2,  6,  2, -6,  3,  0,
+  3,  2, 10,  2, 11, -2, 13,  0,
+  3,  2, 10,  2, 12, -4, 13,  0,
+  3,  2, 11,  2, 12, -2, 13,  0,
+  3,  4, 10,  1, 11, -4, 13,  0,
+  4,  1, 10,  1, 11,  2, 12, -4, 13,  0,
+  3,  1, 10,  3, 11, -2, 13,  0,
+  3,  3, 10,  1, 11, -4, 13,  0,
+  4,  1, 10, -2, 11, -2, 12,  2, 13,  0,
+  3,  1, 10,  2, 12, -4, 13,  0,
+  3,  1, 10,  2, 11, -2, 13,  0,
+  3,  2, 10,  1, 11, -3, 13,  0,
+  3,  1, 13, -2,  2,  1,  4,  0,
+  2,  3, 10, -4, 13,  0,
+  4,  1, 10, -1, 11, -2, 12,  2, 13,  0,
+  4, -1, 10,  2, 13, -2,  2,  2,  3,  0,
+  2,  1, 10, -3, 11,  0,
+  2,  2, 12, -3, 13,  0,
+  2,  2, 11, -1, 13,  0,
+  3,  1, 10,  1, 11, -2, 13,  2,
+  4, -1, 10,  2, 13, -1,  3,  1,  5,  0,
+  2,  2, 10, -3, 13,  0,
+  3,  3, 10, -1, 11, -4, 13,  0,
+  3,  4, 11,  2, 13,-11,  2,  0,
+  3,  1, 10, -2, 12,  2, 13,  0,
+  3,  1, 12, -2, 13,  1,  5,  0,
+  2,  1, 10, -2, 11,  0,
+  2,  1, 11, -1, 13,  0,
+  3,  1, 10, -2, 13,  1,  5,  0,
+  3,  1, 10, -2,  3,  2,  5,  0,
+  3, 18,  2,-18,  3,  2,  5,  0,
+  3,  1, 10, -3,  2,  3,  3,  0,
+  3,  2, 13, 16, 11,-18,  2,  0,
+  2,  1, 10, -2, 13,  2,
+  3,  1, 13, -2, 10,  5,  4,  0,
+  3,  2, 12, -2, 14,  7,  2,  0,
+  3,  1, 10, -2,  3,  3,  5,  0,
+  3,  1, 12, -1,  3, -2,  5,  1,
+  3,  2, 10, -1, 11, -3, 13,  0,
+  3,  3, 10, -2, 12, -2, 13,  0,
+  2,  8,  2, -1,  3,  0,
+  4,  1, 10,  1, 11, -2, 12,  2, 13,  0,
+  3,  1, 12, -2, 14,  2,  4,  0,
+  2,  1, 10, -1, 11,  0,
+  3,  8,  2, -5,  3,  8,  4,  0,
+  2, 18,  2,-17,  3,  0,
+  3,  1, 10, -1,  3,  1,  5,  0,
+  1,  1, 13,  0,
+  3,  1, 10, -1, 11, -2, 13,  1,
+  3,  1, 10,  1, 11, -2, 12,  0,
+  3,  1, 10, -1,  2,  1,  3,  0,
+  3,  2, 13, -8,  2,  1,  3,  0,
+  2,  3, 10, -2, 12,  0,
+  3,  2, 10, -1, 12, -1,  5,  0,
+  3,  3, 10, -2, 11, -2, 13,  0,
+  3,  2, 10, -1, 11, -1, 13,  0,
+  3,  2, 10,  1,  3, -2,  4,  0,
+  3,  1, 12, -1, 10, -1, 14,  0,
+  4, -1, 10,  2, 13,  2,  3, -3,  5,  0,
+  3,  2, 13, -4,  2, -5,  3,  0,
+  3,  2, 12,  2, 10, -3, 14,  1,
+  2,  1, 12, -2,  5,  0,
+  2, 10,  2, -3, 11,  0,
+  1,  1, 10,  2,
+  3,  1, 12, -2, 10, -2,  5,  0,
+  2, 18,  2,-16,  3,  0,
+  2,  2, 12, -3, 14,  1,
+  3,  1, 13,-17,  2,  2, 11,  0,
+  3,  1, 10,  1,  2, -3,  4,  0,
+  3,  1, 12,  1, 10, -1, 14,  0,
+  4, -1, 10,  2, 13,  2,  3, -2,  5,  0,
+  3,  1, 10, -1,  3,  2,  4,  0,
+  4, -1, 10,  2, 13,  3,  2, -3,  3,  0,
+  4,  1, 10, -2, 11,  2, 12, -2, 13,  0,
+  2,  1, 11,  1, 13,  0,
+  3,  8,  2,  2,  3, -3,  4,  0,
+  1,  1, 12,  0,
+  3,  6,  2,  9,  3,-10,  4,  1,
+  3,  1, 10, -2, 11, -2, 13,  0,
+  2,  8,  2,  1,  4,  0,
+  2,  1, 10, -2, 12,  0,
+  2, 11,  2, -4,  3,  0,
+  3,  3, 11, -2, 14,  6,  2,  0,
+  3,  3, 10, -1, 11, -2, 13,  0,
+  2,  2, 10, -1, 13,  0,
+  3,  1, 12, -2,  2,  4,  3,  0,
+  2,  1, 10,  1, 11,  1,
+  4,  1, 10, -1, 11,  2, 12, -2, 13,  0,
+  2,  2, 11,  1, 13,  0,
+  2,  2, 12, -1, 13,  0,
+  3,  1, 10, -1, 11, -2, 12,  0,
+  2,  3, 10, -2, 13,  0,
+  2,  1, 10,  2, 11,  0,
+  3,  1, 10,  2, 12, -2, 13,  0,
+  3,  1, 11,  2, 12, -1, 13,  0,
+  3,  3, 10,  1, 11, -2, 13,  0,
+  2,  1, 10,  3, 11,  0,
+  4,  1, 10,  1, 11,  2, 12, -2, 13,  0,
+  2,  5, 10, -4, 13,  0,
+  3,  3, 10,  2, 11, -2, 13,  0,
+  3,  3, 10,  2, 12, -4, 13,  0,
+  2,  4, 11, -2, 13,  0,
+  3,  2, 10,  2, 11, -4, 13,  0,
+  2,  3, 11, -2, 13,  0,
+  3,  1, 10,  2, 11, -3, 13,  0,
+  3,  2, 10,  1, 11, -4, 13,  0,
+  2,  3, 10, -5, 13,  0,
+  2,  2, 12, -4, 13,  0,
+  2,  2, 11, -2, 13,  0,
+  3,  1, 10,  1, 11, -3, 13,  0,
+  3,  2, 13, -2,  3,  2,  5,  0,
+  2,  2, 10, -4, 13,  1,
+  4,  2, 10, -1, 11, -2, 12,  2, 13,  0,
+  2,  2, 14, -2,  2,  0,
+  3,  1, 10, -2, 12,  3, 13,  0,
+  2,  1, 11, -2, 13,  1,
+  3,  2, 14, -2,  2,  3,  5,  0,
+  3,  2, 13, -1,  3,  1,  5,  0,
+  2,  1, 10, -3, 13,  0,
+  3,  2, 10, -1, 11, -4, 13,  0,
+  4,  2, 10,  1, 11, -2, 12, -2, 13,  0,
+  3,  2, 13,  1, 14, -8,  2,  0,
+  3,  2, 10, -2, 12,  2, 13,  0,
+  2,  2, 10, -2, 11,  0,
+  3,  1, 10, -1, 11,  1, 13,  0,
+  3,  1, 12, -2, 13, -1, 14,  0,
+  3,  2, 13, -8,  2, 13,  3,  0,
+  3,  3, 10, -5, 13,  5,  4,  0,
+  1,  2, 13,  2,
+  3,  3, 10, -1, 13,  5,  4,  0,
+  3,  2, 13,  8,  2,-13,  3,  0,
+  2,  2, 11, -2, 12,  0,
+  3,  1, 10, -1, 11, -3, 13,  0,
+  3,  1, 10, -1, 12, -2, 13,  0,
+  3,  2, 10, -2, 11, -4, 13,  0,
+  3,  2, 10, -2, 12, -2, 13,  0,
+  2,  2, 10, -1, 11,  0,
+  2,  1, 10,  1, 13,  0,
+  2,  1, 11,  2, 13,  1,
+  2,  1, 11, -2, 12,  0,
+  3,  1, 10, -2, 12, -1, 13,  0,
+  2,  4, 10, -2, 12,  0,
+  2,  3, 10, -1, 12,  0,
+  3,  3, 10, -1, 11, -1, 13,  0,
+  1,  2, 10,  2,
+  2,  2, 14, -2,  5,  0,
+  3,  1, 10,  1, 11,  1, 13,  0,
+  2,  1, 10,  1, 12,  0,
+  2,  2, 11,  2, 13,  0,
+  2,  1, 12,  1, 14,  0,
+  1,  2, 12,  2,
+  2,  1, 10, -3, 12,  0,
+  3,  4, 10, -1, 11, -2, 13,  0,
+  2,  3, 10, -1, 13,  0,
+  2,  2, 10,  1, 11,  0,
+  3,  1, 10,  2, 11,  1, 13,  0,
+  3,  1, 10,  2, 12, -1, 13,  0,
+  2,  1, 11,  2, 12,  0,
+  2,  4, 10, -2, 13,  0,
+  2,  2, 10,  2, 11,  0,
+  3,  2, 10,  2, 12, -2, 13,  0,
+  2,  4, 12, -2, 13,  0,
+  3,  4, 10,  1, 11, -2, 13,  0,
+  3,  2, 13, 11,  2,-13,  3,  0,
+  3,  1, 10,  3, 11, -4, 13,  0,
+  3,  3, 10,  1, 11, -6, 13,  0,
+  3,  1, 10,  2, 11, -4, 13,  0,
+  2,  3, 10, -6, 13,  0,
+  3,  1, 10, -3, 11,  2, 13,  0,
+  3,  1, 10,  1, 11, -4, 13,  0,
+  2,  2, 10, -5, 13,  0,
+  3,  1, 10, -2, 12,  4, 13,  0,
+  3,  1, 10, -2, 11,  2, 13,  0,
+  2,  1, 11, -3, 13,  0,
+  2,  1, 10, -4, 13,  0,
+  4,  1, 10,  2, 11, -2, 12, -2, 13,  0,
+  3,  3, 10, -2, 12, -4, 13,  0,
+  3,  1, 10, -1, 11,  2, 13,  0,
+  1,  3, 13,  0,
+  3,  1, 10, -1, 11, -4, 13,  0,
+  4,  1, 10,  1, 11, -2, 12, -2, 13,  0,
+  3,  3, 10, -2, 12,  2, 13,  0,
+  2,  3, 10, -2, 11,  0,
+  3,  2, 10, -1, 11,  1, 13,  0,
+  3,  1, 12,  2, 13, -2,  5,  0,
+  2,  1, 10,  2, 13,  1,
+  2,  1, 11,  3, 13,  0,
+  3,  1, 10, -2, 11, -4, 13,  0,
+  3,  1, 10, -2, 12, -2, 13,  0,
+  2,  3, 10, -1, 11,  0,
+  2,  2, 10,  1, 13,  0,
+  3,  1, 10,  1, 11,  2, 13,  0,
+  3,  1, 10, -1, 11,  2, 12,  0,
+  2,  2, 12,  1, 13,  0,
+  4,  1, 10, -1, 11, -2, 12, -2, 13,  0,
+  1,  3, 10,  1,
+  3,  2, 10,  1, 11,  1, 13,  0,
+  3,  1, 10,  2, 11,  2, 13,  0,
+  2,  1, 10,  2, 12,  0,
+  3,  1, 11,  2, 12,  1, 13,  0,
+  2,  4, 10, -1, 13,  0,
+  2,  3, 10,  1, 11,  0,
+  3,  1, 10,  1, 11,  2, 12,  0,
+  4,  1, 10, -1, 11,  4, 12, -2, 13,  0,
+  2,  5, 10, -2, 13,  0,
+  3,  3, 10,  2, 12, -2, 13,  0,
+  3,  1, 10,  4, 12, -2, 13,  0,
+  3,  2, 10,  2, 11, -6, 13,  0,
+  2,  3, 11, -4, 13,  0,
+  3,  2, 10,  1, 11, -6, 13,  0,
+  2,  2, 11, -4, 13,  0,
+  2,  2, 10, -6, 13,  0,
+  2,  1, 11, -4, 13,  0,
+  2,  1, 10, -5, 13,  0,
+  3,  2, 10, -1, 11, -6, 13,  0,
+  4,  2, 10,  1, 11, -2, 12, -4, 13,  0,
+  3,  2, 10, -2, 11,  2, 13,  0,
+  1,  4, 13,  0,
+  3,  2, 11, -2, 12, -2, 13,  0,
+  3,  2, 10, -2, 12, -4, 13,  0,
+  3,  2, 10, -1, 11,  2, 13,  0,
+  2,  1, 10,  3, 13,  0,
+  2,  1, 11,  4, 13,  0,
+  3,  1, 11, -2, 12, -2, 13,  0,
+  2,  2, 10,  2, 13,  0,
+  3,  1, 10,  1, 11,  3, 13,  0,
+  2,  2, 12,  2, 13,  0,
+  2,  4, 10, -1, 11,  0,
+  2,  3, 10,  1, 13,  0,
+  3,  2, 10,  1, 11,  2, 13,  0,
+  3,  2, 10, -1, 11,  2, 12,  0,
+  3,  1, 10,  2, 12,  1, 13,  0,
+  3,  1, 11,  2, 12,  2, 13,  0,
+  1,  4, 10,  0,
+  3,  3, 10,  1, 11,  1, 13,  0,
+  2,  2, 10,  2, 12,  0,
+  1,  4, 12,  0,
+  2,  4, 10,  1, 11,  0,
+  3,  2, 10,  1, 11,  2, 12,  0,
+  2,  6, 10, -2, 13,  0,
+  3,  5, 12, -1, 14,  2,  4,  1,
+  3,  1, 10,  1, 11, -6, 13,  0,
+  3,  1, 10, -2, 11,  4, 13,  0,
+  2,  1, 10, -6, 13,  0,
+  3,  1, 10, -1, 11,  4, 13,  0,
+  3,  1, 10, -1, 11, -6, 13,  0,
+  4,  1, 10,  1, 11, -2, 12, -4, 13,  0,
+  2,  1, 10,  4, 13,  0,
+  3,  1, 10, -2, 12, -4, 13,  0,
+  3,  3, 10, -1, 11,  2, 13,  0,
+  2,  2, 10,  3, 13,  0,
+  3,  1, 10,  1, 11,  4, 13,  0,
+  4,  1, 10, -1, 11,  2, 12,  2, 13,  0,
+  2,  3, 10,  2, 13,  0,
+  3,  1, 10,  2, 12,  2, 13,  0,
+  3,  3, 10,  1, 11,  2, 13,  0,
+  3,  1, 10, -1, 11,  4, 12,  0,
+  1,  5, 10,  0,
+  2,  3, 10,  2, 12,  0,
+  2,  1, 11, -6, 13,  0,
+  1,  6, 13,  0,
+  3,  2, 10, -1, 11,  4, 13,  0,
+  2,  2, 10,  4, 13,  0,
+  2,  2, 12,  4, 13,  0,
+  3,  4, 10, -1, 11,  2, 13,  0,
+  3,  2, 10,  1, 11,  4, 13,  0,
+  2,  4, 10,  2, 13,  0,
+  3,  2, 10,  2, 12,  2, 13,  0,
+  1,  6, 10,  0,
+  2,  1, 10,  6, 13,  0,
+  2,  3, 10,  4, 13,  0,
+  2,  5, 10,  2, 13,  0,
+ -1
+};
+
+/* Total terms = 356, small = 356 */
+static struct plantbl liblon = {
+  /*  {  0, 18, 18, 10,  3,  2,  0,  0,  0,  6, 16,  6,  6,  3,}, */
+  /* Use max of liblon, liblat.  */
+  {  0, 18, 18, 20,  4,  2,  0,  0,  0,  9, 16,  7,  9,  9,},
+ 2,
+ lonargs,
+ lontabl,
+ lontabb,
+ lontabr,
+ 3.850000e+05,
+ 36525.0,
+ 1.0e-4,
+};
+
+
+
+/* given a Julian date, return the lunar libration in lat and long, in rads.
+ */
+void
+llibration (JD, llatp, llonp)
+double JD;
+double *llatp;
+double *llonp;
+{
+	double lon, lat;	/* arc seconds */
+	
+	lon = gplan (JD, &liblon);
+	lat = gplan (JD, &liblat);
+
+	*llonp = degrad (lon/3600.0);
+	*llatp = degrad (lat/3600.0);
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: libration.c,v $ $Date: 2001-10-22 12:08:27 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/misc.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/misc.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/misc.c	(revision 2309)
@@ -0,0 +1,475 @@
+/* misc handy functions.
+ * every system has such, no?
+ *  4/20/98 now_lst() always just returns apparent time
+ */
+
+#include <stdio.h>
+#include <math.h>
+
+#if defined(__STDC__)
+#include <stdlib.h>
+#include <string.h>
+#else
+extern double atof();
+#endif
+
+#include "P_.h"
+#include "astro.h"
+#include "circum.h"
+
+/* zero from loc for len bytes */
+void
+zero_mem (loc, len)
+void *loc;
+unsigned len;
+{
+	(void) memset (loc, 0, len);
+}
+
+/* given min and max and an approximate number of divisions desired,
+ * fill in ticks[] with nicely spaced values and return how many.
+ * N.B. return value, and hence number of entries to ticks[], might be as
+ *   much as 2 more than numdiv.
+ */
+int
+tickmarks (min, max, numdiv, ticks)
+double min, max;
+int numdiv;
+double ticks[];
+{
+        static int factor[] = { 1, 2, 5 };
+        double minscale;
+        double delta;
+	double lo;
+        double v;
+        int n;
+
+        minscale = fabs(max - min);
+        delta = minscale/numdiv;
+        for (n=0; n < sizeof(factor)/sizeof(factor[0]); n++) {
+	    double scale;
+	    double x = delta/factor[n];
+            if ((scale = (pow(10.0, ceil(log10(x)))*factor[n])) < minscale)
+		minscale = scale;
+	}
+        delta = minscale;
+
+        lo = floor(min/delta);
+        for (n = 0; (v = delta*(lo+n)) < max+delta; )
+	    ticks[n++] = v;
+
+	return (n);
+}
+
+/* given an Obj *, return its type as a descriptive string.
+ * if it's of type fixed then return its class description.
+ * N.B. we return the address of static storage -- do not free or change.
+ */
+char *
+obj_description (op)
+Obj *op;
+{
+	static struct {
+	    char class;
+	    char *desc;
+	} fixed_class_map[] = {
+	    {'A', "Cluster of Galaxies"},
+	    {'B', "Binary Star"},
+	    {'C', "Globular Cluster"},
+	    {'D', "Double Star"},
+	    {'F', "Diffuse Nebula"},
+	    {'G', "Spiral Galaxy"},
+	    {'H', "Spherical Galaxy"},
+	    {'J', "Radio"},
+	    {'K', "Dark Nebula"},
+	    {'L', "Pulsar"},
+	    {'M', "Multiple Star"},
+	    {'N', "Bright Nebula"},
+	    {'O', "Open Cluster"},
+	    {'P', "Planetary Nebula"},
+	    {'Q', "Quasar"},
+	    {'R', "Supernova Remnant"},
+	    {'S', "Star"},
+	    {'T', "Star-like Object"},
+	    {'U', "Cluster, with nebulosity"},
+	    {'V', "Variable Star"},
+	};
+#define	NFCM	(sizeof(fixed_class_map)/sizeof(fixed_class_map[0]))
+
+	switch (op->o_type) {
+	case FIXED:
+	    if (op->f_class) {
+		int i;
+		for (i = 0; i < NFCM; i++)
+		    if (fixed_class_map[i].class == op->f_class)
+			return (fixed_class_map[i].desc);
+	    }
+	    return (op->o_type == FIXED ? "Fixed" : "Field Star");
+	case PARABOLIC:
+	    return ("Solar - Parabolic");
+	case HYPERBOLIC:
+	    return ("Solar - Hyperbolic");
+	case ELLIPTICAL:
+	    return ("Solar - Elliptical");
+	case PLANET:
+	    return ("Planet");
+	case EARTHSAT:
+	    return ("Earth Sat");
+	default:
+	    printf ("obj_description: unknown type: 0x%x\n", op->o_type);
+	    exit (1);
+	    return (NULL);	/* for lint */
+	}
+}
+
+/* given a Now *, find the local apparent sidereal time, in hours.
+ */
+void
+now_lst (np, lstp)
+Now *np;
+double *lstp;
+{
+	static double last_mjd = -23243, last_lng = 121212, last_lst;
+	double eps, lst, deps, dpsi;
+
+	if (last_mjd == mjd && last_lng == lng) {
+	    *lstp = last_lst;
+	    return;
+	}
+
+	utc_gst (mjd_day(mjd), mjd_hr(mjd), &lst);
+	lst += radhr(lng);
+
+	obliquity(mjd, &eps);
+	nutation(mjd, &deps, &dpsi);
+	lst += radhr(dpsi*cos(eps+deps));
+
+	range (&lst, 24.0);
+
+	last_mjd = mjd;
+	last_lng = lng;
+	*lstp = last_lst = lst;
+}
+
+/* convert ra to ha, in range -PI .. PI.
+ * need dec too if not already apparent.
+ */
+void
+radec2ha (np, ra, dec, hap)
+Now *np;
+double ra, dec;
+double *hap;
+{
+	double ha, lst;
+
+	if (epoch != EOD)
+	    as_ap (np, epoch, &ra, &dec);
+	now_lst (np, &lst);
+	ha = hrrad(lst) - ra;
+	if (ha < -PI) ha += 2*PI;
+	if (ha >  PI) ha -= 2*PI;
+	*hap = ha;
+}
+
+/* given a circle and a line segment, find a segment of the line inside the 
+ *   circle.
+ * return 0 and the segment end points if one exists, else -1.
+ * We use a parametric representation of the line:
+ *   x = x1 + (x2-x1)*t and y = y1 + (y2-y1)*t, 0 < t < 1
+ * and a centered representation of the circle:
+ *   (x - xc)**2 + (y - yc)**2 = r**2
+ * and solve for the t's that work, checking for usual conditions.
+ */
+int
+lc (cx, cy, cw, x1, y1, x2, y2, sx1, sy1, sx2, sy2)
+int cx, cy, cw;			/* circle bounding box corner and width */
+int x1, y1, x2, y2;		/* line segment endpoints */
+int *sx1, *sy1, *sx2, *sy2;	/* segment inside the circle */
+{
+	int dx = x2 - x1;
+	int dy = y2 - y1;
+	int r = cw/2;
+	int xc = cx + r;
+	int yc = cy + r;
+	int A = x1 - xc;
+	int B = y1 - yc;
+	double a = dx*dx + dy*dy;	/* O(2 * 2**16 * 2**16) */
+	double b = 2*(dx*A + dy*B);	/* O(4 * 2**16 * 2**16) */
+	double c = A*A + B*B - r*r;	/* O(2 * 2**16 * 2**16) */
+	double d = b*b - 4*a*c;		/* O(2**32 * 2**32) */
+	double sqrtd;
+	double t1, t2;
+
+	if (d <= 0)
+	    return (-1);	/* containing line is purely outside circle */
+
+	sqrtd = sqrt(d);
+	t1 = (-b - sqrtd)/(2.0*a);
+	t2 = (-b + sqrtd)/(2.0*a);
+
+	if (t1 >= 1.0 || t2 <= 0.0)
+	    return (-1);	/* segment is purely outside circle */
+
+	/* we know now that some part of the segment is inside,
+	 * ie, t1 < 1 && t2 > 0
+	 */
+
+	if (t1 <= 0.0) {
+	    /* (x1,y1) is inside circle */
+	    *sx1 = x1;
+	    *sy1 = y1;
+	} else {
+	    *sx1 = (int)(x1 + dx*t1);
+	    *sy1 = (int)(y1 + dy*t1);
+	}
+
+	if (t2 >= 1.0) {
+	    /* (x2,y2) is inside circle */
+	    *sx2 = x2;
+	    *sy2 = y2;
+	} else {
+	    *sx2 = (int)(x1 + dx*t2);
+	    *sy2 = (int)(y1 + dy*t2);
+	}
+
+	return (0);
+}
+
+/* compute visual magnitude using the H/G parameters used in the Astro Almanac.
+ * these are commonly used for asteroids.
+ */
+void
+hg_mag (h, g, rp, rho, rsn, mp)
+double h, g;
+double rp;	/* sun-obj dist, AU */
+double rho;	/* earth-obj dist, AU */
+double rsn;	/* sun-earth dist, AU */
+double *mp;
+{
+	double psi_t, Psi_1, Psi_2, beta;
+	double c;
+	double tb2;
+
+	c = (rp*rp + rho*rho - rsn*rsn)/(2*rp*rho);
+	if (c <= -1)
+	    beta = PI;
+	else if (c >= 1)
+	    beta = 0;
+	else
+	    beta = acos(c);;
+	tb2 = tan(beta/2.0);
+	/* psi_t = exp(log(tan(beta/2.0))*0.63); */
+	psi_t = pow (tb2, 0.63);
+	Psi_1 = exp(-3.33*psi_t);
+	/* psi_t = exp(log(tan(beta/2.0))*1.22); */
+	psi_t = pow (tb2, 1.22);
+	Psi_2 = exp(-1.87*psi_t);
+	*mp = h + 5.0*log10(rp*rho) - 2.5*log10((1-g)*Psi_1 + g*Psi_2);
+}
+
+/* given faintest desired mag, mag step magstp, image scale and object
+ * magnitude and size, return diameter to draw object, in pixels, or 0 if
+ * dimmer than fmag.
+ */
+int
+magdiam (fmag, magstp, scale, mag, size)
+int fmag;	/* faintest mag */
+int magstp;	/* mag range per dot size */
+double scale;	/* rads per pixel */
+double mag;	/* magnitude */
+double size;	/* rads, or 0 */
+{
+	int diam, sized;
+	
+	if (mag > fmag)
+	    return (0);
+	diam = (int)((fmag - mag)/magstp + 1);
+	sized = (int)(size/scale + 0.5);
+	if (sized > diam)
+	    diam = sized;
+
+	return (diam);
+}
+
+/* computer visual magnitude using the g/k parameters commonly used for comets.
+ */
+void
+gk_mag (g, k, rp, rho, mp)
+double g, k;
+double rp;	/* sun-obj dist, AU */
+double rho;	/* earth-obj dist, AU */
+double *mp;
+{
+	*mp = g + 5.0*log10(rho) + 2.5*k*log10(rp);
+}
+
+/* given a string convert to floating point and return it as a double.
+ * this is to isolate possible unportabilities associated with declaring atof().
+ * it's worth it because atof() is often some 50% faster than sscanf ("%lf");
+ */
+double
+atod (buf)
+char *buf;
+{
+	return (atof (buf));
+}
+
+/* solve a spherical triangle:
+ *           A
+ *          /  \
+ *         /    \
+ *      c /      \ b
+ *       /        \
+ *      /          \
+ *    B ____________ C
+ *           a
+ *
+ * given A, b, c find B and a in range 0..B..2PI and 0..a..PI, respectively..
+ * cap and Bp may be NULL if not interested in either one.
+ * N.B. we pass in cos(c) and sin(c) because in many problems one of the sides
+ *   remains constant for many values of A and b.
+ */
+void
+solve_sphere (A, b, cc, sc, cap, Bp)
+double A, b;
+double cc, sc;
+double *cap, *Bp;
+{
+	double cb = cos(b), sb = sin(b);
+	double cA = cos(A);
+	double ca;
+	double B;
+
+	ca = cb*cc + sb*sc*cA;
+	if (ca >  1.0) ca =  1.0;
+	if (ca < -1.0) ca = -1.0;
+	if (cap)
+	    *cap = ca;
+
+	if (!Bp)
+	    return;
+
+	if (cc > .99999) {
+	    /* as c approaches 0, B approaches pi - A */
+	    B = PI - A;
+	} else if (cc < -.99999) {
+	    /* as c approaches PI, B approaches A */
+	    B = A;
+	} else {
+	    /* compute cB and sB and remove common factor of sa from quotient.
+	     * be careful where B causes atan to blow.
+	     */
+	    double sA = sin(A);
+	    double x, y;
+
+	    y = sA*sb*sc;
+	    x = cb - ca*cc;
+	
+	    if (fabs(x) < 1e-5)
+		B = y < 0 ? 3*PI/2 : PI/2;
+	    else
+		B = atan2 (y, x);
+	}
+
+	*Bp = B;
+	range (Bp, 2*PI);
+}
+
+/* #define WANT_MATHERR if your system supports it. it gives SGI fits.
+ */
+#undef WANT_MATHERR
+#if defined(WANT_MATHERR)
+/* attempt to do *something* reasonable when a math function blows.
+ */
+matherr (xp)
+struct exception *xp;
+{
+	static char *names[8] = {
+	    "acos", "asin", "atan2", "pow",
+	    "exp", "log", "log10", "sqrt"
+	};
+	int i;
+
+	/* catch-all */
+	xp->retval = 0.0;
+
+	for (i = 0; i < sizeof(names)/sizeof(names[0]); i++)
+	    if (strcmp (xp->name, names[i]) == 0)
+		switch (i) {
+		case 0:	/* acos */
+		    xp->retval = xp->arg1 >= 1.0 ? 0.0 : -PI;
+		    break;
+		case 1: /* asin */
+		    xp->retval = xp->arg1 >= 1.0 ? PI/2 : -PI/2;
+		    break;
+		case 2: /* atan2 */
+		    if (xp->arg1 == 0.0)
+			xp->retval = xp->arg2 < 0.0 ? PI : 0.0;
+		    else if (xp->arg2 == 0.0)
+			xp->retval = xp->arg1 < 0.0 ? -PI/2 : PI/2;
+		    else
+			xp->retval = 0.0;
+		    break;
+		case 3: /* pow */
+		/* FALLTHRU */
+		case 4: /* exp */
+		    xp->retval = xp->o_type == OVERFLOW ? 1e308 : 0.0;
+		    break;
+		case 5: /* log */
+		/* FALLTHRU */
+		case 6: /* log10 */
+		    xp->retval = xp->arg1 <= 0.0 ? -1e308 : 0;
+		    break;
+		case 7: /* sqrt */
+		    xp->retval = 0.0;
+		    break;
+		}
+
+        return (1);     /* suppress default error handling */
+}
+#endif
+
+/* given the difference in two RA's, in rads, return their difference,
+ *   accounting for wrap at 2*PI. caller need *not* first force it into the
+ *   range 0..2*PI.
+ */
+double
+delra (dra)
+double dra;
+{
+	double fdra = fmod(fabs(dra), 2*PI);
+
+	if (fdra > PI)
+	    fdra = 2*PI - fdra;
+	return (fdra);
+}
+
+/* return 1 if object is considered to be "deep sky", else 0.
+ * The only things deep-sky are fixed objects other than stars.
+ */
+int
+is_deepsky (op)
+Obj *op;
+{
+	int deepsky = 0;
+
+	if (is_type(op, FIXEDM)) {
+	    switch (op->f_class) {
+	    case 'T':
+	    case 'B':
+	    case 'D':
+	    case 'M':
+	    case 'S':
+	    case 'V':
+		break;
+	    default:
+		deepsky = 1;
+		break;
+	    }
+	}
+
+	return (deepsky);
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: misc.c,v $ $Date: 2001-10-22 12:08:27 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/mjd.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/mjd.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/mjd.c	(revision 2309)
@@ -0,0 +1,263 @@
+/* functions to manipulate the modified-julian-date used throughout xephem. */
+
+#include <stdio.h>
+#include <math.h>
+
+#include "P_.h"
+#include "astro.h"
+
+/* given a date in months, mn, days, dy, years, yr,
+ * return the modified Julian date (number of days elapsed since 1900 jan 0.5),
+ * *mjd.
+ */
+void
+cal_mjd (mn, dy, yr, mjd)
+int mn, yr;
+double dy;
+double *mjd;
+{
+	static double last_mjd, last_dy;
+	static int last_mn, last_yr;
+	int b, d, m, y;
+	long c;
+
+	if (mn == last_mn && yr == last_yr && dy == last_dy) {
+	    *mjd = last_mjd;
+	    return;
+	}
+
+	m = mn;
+	y = (yr < 0) ? yr + 1 : yr;
+	if (mn < 3) {
+	    m += 12;
+	    y -= 1;
+	}
+
+	if (yr < 1582 || (yr == 1582 && (mn < 10 || (mn == 10 && dy < 15))))
+	    b = 0;
+	else {
+	    int a;
+	    a = y/100;
+	    b = 2 - a + a/4;
+	}
+
+	if (y < 0)
+	    c = (long)((365.25*y) - 0.75) - 694025L;
+	else
+	    c = (long)(365.25*y) - 694025L;
+
+	d = (int)(30.6001*(m+1));
+
+	*mjd = b + c + d + dy - 0.5;
+
+	last_mn = mn;
+	last_dy = dy;
+	last_yr = yr;
+	last_mjd = *mjd;
+}
+
+/* given the modified Julian date (number of days elapsed since 1900 jan 0.5,),
+ * mjd, return the calendar date in months, *mn, days, *dy, and years, *yr.
+ */
+void
+mjd_cal (mjd, mn, dy, yr)
+double mjd;
+int *mn, *yr;
+double *dy;
+{
+	static double last_mjd, last_dy;
+	static int last_mn, last_yr;
+	double d, f;
+	double i, a, b, ce, g;
+
+	/* we get called with 0 quite a bit from unused epoch fields.
+	 * 0 is noon the last day of 1899.
+	 */
+	if (mjd == 0.0) {
+	    *mn = 12;
+	    *dy = 31.5;
+	    *yr = 1899;
+	    return;
+	}
+
+	if (mjd == last_mjd) {
+	    *mn = last_mn;
+	    *yr = last_yr;
+	    *dy = last_dy;
+	    return;
+	}
+
+	d = mjd + 0.5;
+	i = floor(d);
+	f = d-i;
+	if (f == 1) {
+	    f = 0;
+	    i += 1;
+	}
+
+	if (i > -115860.0) {
+	    a = floor((i/36524.25)+.99835726)+14;
+	    i += 1 + a - floor(a/4.0);
+	}
+
+	b = floor((i/365.25)+.802601);
+	ce = i - floor((365.25*b)+.750001)+416;
+	g = floor(ce/30.6001);
+	*mn = (int)(g - 1);
+	*dy = ce - floor(30.6001*g)+f;
+	*yr = (int)(b + 1899);
+
+	if (g > 13.5)
+	    *mn = (int)(g - 13);
+	if (*mn < 2.5)
+	    *yr = (int)(b + 1900);
+	if (*yr < 1)
+	    *yr -= 1;
+
+	last_mn = *mn;
+	last_dy = *dy;
+	last_yr = *yr;
+	last_mjd = mjd;
+}
+
+/* given an mjd, set *dow to 0..6 according to which day of the week it falls
+ * on (0=sunday).
+ * return 0 if ok else -1 if can't figure it out.
+ */
+int
+mjd_dow (mjd, dow)
+double mjd;
+int *dow;
+{
+	/* cal_mjd() uses Gregorian dates on or after Oct 15, 1582.
+	 * (Pope Gregory XIII dropped 10 days, Oct 5..14, and improved the leap-
+	 * year algorithm). however, Great Britian and the colonies did not
+	 * adopt it until Sept 14, 1752 (they dropped 11 days, Sept 3-13,
+	 * due to additional accumulated error). leap years before 1752 thus
+	 * can not easily be accounted for from the cal_mjd() number...
+	 */
+	if (mjd < -53798.5) {
+	    /* pre sept 14, 1752 too hard to correct |:-S */
+	    return (-1);
+	}
+	*dow = ((long)floor(mjd-.5) + 1) % 7;/* 1/1/1900 (mjd 0.5) is a Monday*/
+	if (*dow < 0)
+	    *dow += 7;
+	return (0);
+}
+
+/* given a year, return whether it is a leap year */
+int
+isleapyear (y)
+int y;
+{
+	return ((y%4==0 && y%100!=0) || y%400==0);
+}
+
+/* given a mjd, return the the number of days in the month.  */
+void
+mjd_dpm (mjd, ndays)
+double mjd;
+int *ndays;
+{
+	static short dpm[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+	int m, y;
+	double d;
+
+	mjd_cal (mjd, &m, &d, &y);
+	*ndays = (m==2 && isleapyear(y)) ? 29 : dpm[m-1];
+}
+
+/* given a mjd, return the year and number of days since 00:00 Jan 1 */
+void
+mjd_dayno (mjd, yr, dy)
+double mjd;
+int *yr;
+double *dy;
+{
+	double yrd;
+	int yri;
+	int dpy;
+
+	mjd_year (mjd, &yrd);
+	*yr = yri = (int)yrd;
+	dpy = isleapyear(yri) ? 366 : 365;
+	*dy = dpy*(yrd-yri);
+}
+
+/* given a mjd, return the year as a double. */
+void
+mjd_year (mjd, yr)
+double mjd;
+double *yr;
+{
+	static double last_mjd, last_yr;
+	int m, y;
+	double d;
+	double e0, e1;	/* mjd of start of this year, start of next year */
+
+	if (mjd == last_mjd) {
+	    *yr = last_yr;
+	    return;
+	}
+
+	mjd_cal (mjd, &m, &d, &y);
+	if (y == -1) y = -2;
+	cal_mjd (1, 1.0, y, &e0);
+	cal_mjd (1, 1.0, y+1, &e1);
+	*yr = y + (mjd - e0)/(e1 - e0);
+
+	last_mjd = mjd;
+	last_yr = *yr;
+}
+
+/* given a decimal year, return mjd */
+void
+year_mjd (y, mjd)
+double y;
+double *mjd;
+{
+	double e0, e1;	/* mjd of start of this year, start of next year */
+	int yf = (int)floor (y);
+	if (yf == -1) yf = -2;
+
+	cal_mjd (1, 1.0, yf, &e0);
+	cal_mjd (1, 1.0, yf+1, &e1);
+	*mjd = e0 + (y - yf)*(e1-e0);
+}
+
+/* round a time in days, *t, to the nearest second, IN PLACE. */
+void
+rnd_second (t)
+double *t;
+{
+	*t = floor(*t*SPD+0.5)/SPD;
+}
+	
+/* given an mjd, truncate it to the beginning of the whole day */
+double
+mjd_day(jd)
+double jd;
+{
+	return (floor(jd-0.5)+0.5);
+}
+
+/* given an mjd, return the number of hours past midnight of the whole day */
+double
+mjd_hr(jd)
+double jd;
+{
+	return ((jd-mjd_day(jd))*24.0);
+}
+
+/* insure 0 <= *v < r.
+ */
+void
+range (v, r)
+double *v, r;
+{
+	*v -= r*floor(*v/r);
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: mjd.c,v $ $Date: 2001-10-22 12:08:27 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/moon.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/moon.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/moon.c	(revision 2309)
@@ -0,0 +1,3487 @@
+/* geocentric moon polar coordinates re mean equinox and ecliptic of date
+
+   S. L. Moshier
+   December, 1996
+
+**********************************************************************
+   Adapted by Michael Sternberg <sternberg@physik.tu-chemnitz.de>
+   for xephem with minor modifications from the originals at:
+   ftp://ftp.std.com/pub/astronomy/selenog.zip
+
+   Precision < 0.05" from -1369 to +2950.
+   Uses table lookup techniques to limit calls to trigonometric functions.
+
+   NB:  Uses International Earth Rotation System (IERS) which is
+	taken as equivalent to FK5 for the purposes of xephem.
+
+   original files used:
+	chewtab.c   mean.c      mlr404.c
+	mlat404.c   selenog.c
+
+   changes:
+	added prototypes, grouped and cleaned up vars and #defines,
+	removed _MSC_VER #ifdefs, uniqed names in moonlr and moonlat,
+	included plantbl.h in .c file, dropped out librations for now.
+
+	in struct plantbl, promoted "char *arg_tbl" to "short *".
+	reason: - more portable (BTW: this is the only place in xephem
+		where "signed char" would have been needed)
+		- using "short" costs a mere 7k memory but avoids core
+		dumps on a machine which we didn't anticipate.
+
+**********************************************************************
+
+
+              Residuals against JPL ephemeris DE404 (arc seconds)
+
+First date in file = 1221000.5
+Number of samples = 1053099
+Sampling interval = 1.515625 days
+
+Peak excursions from these mostly different test points
+were consolidated with the above.  They added .01" to a few
+of the peak readings.
+First date in file = 1221000.50
+Number of samples = 524290.0
+Sampling interval = 3.0 days
+
+
+ Julian Years             Longitude          Latitude           Distance
+                                                               1 = 1.9 km
+                       Peak  RMS   Ave    Peak  RMS   Ave    Peak  RMS   Ave
+ -1369.0 to -1000.0:   0.43  0.07  0.00   0.33  0.05 -0.00   0.18  0.03  0.00 
+ -1000.0 to  -500.0:   0.49  0.06 -0.00   0.33  0.04 -0.00   0.18  0.03  0.00 
+  -500.0 to     0.0:   0.48  0.06  0.00   0.32  0.04  0.00   0.15  0.03  0.00 
+     0.0 to   500.0:   0.45  0.05  0.00   0.30  0.04 -0.00   0.17  0.03 -0.00 
+   500.0 to  1000.0:   0.48  0.05 -0.00   0.29  0.04  0.00   0.17  0.03 -0.00 
+  1000.0 to  1500.0:   0.42  0.05 -0.00   0.28  0.04 -0.00   0.16  0.03  0.00 
+  1500.0 to  2000.0:   0.35  0.05 -0.00   0.26  0.04  0.00   0.15  0.03  0.00 
+  2000.0 to  2500.0:   0.39  0.06  0.00   0.25  0.04 -0.00   0.15  0.03 -0.00 
+  2500.0 to  3000.0:   0.44  0.07 -0.00   0.30  0.05 -0.00   0.19  0.03 -0.00 
+  3000.0 to  3000.8:   0.23  0.08 -0.04   0.11  0.04 -0.00   0.08  0.03 -0.00 
+ */
+
+#include <math.h>
+#if defined(__STDC__)
+#include <stdlib.h>
+#endif
+
+#include "P_.h"
+#include "astro.h"
+
+#define CHAR short
+
+#define NARGS 18
+ 
+struct plantbl {
+  char max_harmonic[NARGS];
+  char max_power_of_t;
+  CHAR *arg_tbl;
+  long *lon_tbl;
+  long *lat_tbl;
+  long *rad_tbl;
+  double distance;
+  double timescale;
+  double trunclvl;
+};
+
+static double mods3600 P_((double x));
+static void mean_elements P_((double JED));
+static int sscc P_((int k, double arg, int n));
+static int g2plan P_((double J, struct plantbl *plan, double *pobj, int flag));
+static double g1plan P_((double J, struct plantbl *plan));
+static int gecmoon P_((double J, struct plantbl *lrtab,
+	struct plantbl *lattab, double *pobj));
+
+/* time points */
+#define MOSHIER_J2000 (2451545.0)
+
+#define MOSHIER_BEGIN (1221000.5 - MJD0) /* directly from above */
+#define MOSHIER_END   (2798525.5 - MJD0) /* 2950.0; from libration table */
+
+
+static double Args[NARGS];
+static double LP_equinox;
+static double NF_arcsec;
+static double Ea_arcsec;
+static double pA_precession;
+
+
+/* This storage ought to be allocated dynamically.  */
+double ss[NARGS][30];
+double cc[NARGS][30];
+
+/* Time, in units of 10,000 Julian years from JED 2451545.0.  */
+static double T;
+
+/* Conversion factors between degrees and radians */
+#define DTR 1.7453292519943295769e-2
+#define RTD 5.7295779513082320877e1
+#define RTS 2.0626480624709635516e5	/* arc seconds per radian */
+#define STR 4.8481368110953599359e-6	/* radians per arc second */
+#define AUKM 1.4959787e8
+
+
+static long lrtabl[] = {
+    175667,     66453,      5249,       -42,
+     20057,       403,     -2360,      6148,
+     -7644,     24646,     -1273,      9127,
+     -1395,      1958,
+       232,      -289,
+       -97,       553,        69,       130,
+       -80,         6,
+       129,      -868,        26,       -89,
+      1042,      1172,       194,      -112,
+    -47433,   -241666,    224626,   -103752,
+     63419,    127606,
+      2294,      -691,     -1827,     -1254,
+        -1,      -119,
+      1057,       324,
+       505,      -195,       254,      -641,
+       -36,      1008,     -1082,        -3,
+       -87,       122,
+       161,        11,
+         2,      -106,
+        29,      -123,
+       -32,        41,
+      -524,       -35,
+       133,      -595,
+       225,       837,      -108,      -191,
+     -2294,       841,      -340,      -394,
+      -351,     -1039,       238,      -108,
+       -66,        21,
+      1405,       869,       520,      2776,
+      -174,        71,
+       425,       652,     -1260,       -80,
+       249,        77,
+      -192,       -17,
+       -97,       134,
+        -7,       -54,
+      -802,     -7436,     -2824,     70869,
+       -35,      2481,
+      1865,      1749,     -2166,      2415,
+        33,      -183,
+      -835,       283,
+        27,       -45,
+        56,       235,
+         2,       718,
+     -1206,       275,       -87,      -158,
+        -7,     -2534,         0,     10774,
+         1,      -324,
+      -208,       821,
+       281,      1340,      -797,       440,
+       224,        72,
+       -65,        -5,
+        -7,       -44,
+       -48,        66,
+      -151,       -40,
+       -41,       -45,
+        76,      -108,
+       -18,      1202,         0,     -2501,
+      1438,      -595,       900,      3040,
+     -3435,        -5,
+      -100,       -26,
+         0,    -13714,
+      -183,        68,
+       453,       -83,
+      -228,       325,
+        97,        13,
+         2,       105,
+       -61,       257,
+         0,        57,
+        88,       -11,
+        -1,     -8220,
+         0,       275,
+       -43,       -10,
+      -199,       105,
+         1,     -5849,         2,     24887,
+      -128,        48,
+       712,       970,     -1407,       845,
+      -266,       378,
+       311,      1526,     -1751,        27,
+         0,   -185858,
+       133,      6383,
+      -108,        25,
+        -7,      1944,
+         5,       390,
+       -11,        31,
+       277,      -384,       158,        72,
+       -81,       -41,       -13,      -111,
+     -2332,    -65804,      -698,    505812,
+        34,   1676716,       -72,  -6664384,
+       154,       -57,        52,        95,
+        -4,        -5,
+        -7,        37,
+       -63,       -32,
+         4,      3349,         1,    -14370,
+        16,       -83,
+         0,      -401,
+        13,      3013,
+        48,       -20,
+         0,       250,
+        51,       -79,
+        -7,      -146,
+       148,         9,
+         0,       -64,
+       -17,       -59,
+       -67,      -492,
+        -2,   2116601,
+       -12,     -1848,
+         8,      -436,
+        -6,       324,         0,     -1363,
+      -163,         9,
+         0,       -74,
+        63,      8167,       -29,     37587,
+       -22,    -74501,
+       -71,       497,
+        -1,    551747,
+       -87,       -22,
+         0,       -51,
+        -1,      -463,
+         0,      -444,
+         3,        89,
+        15,       -84,
+       -36,     -6829,        -5,    -21663,
+         0,     86058,
+         0,      -298,
+        -2,       751,        -2,     -1015,
+         0,        69,
+         1,     -4989,         0,     21458,
+         0,      -330,
+         0,        -7,
+         0,      -226,
+         0,     -1407,         0,      2942,
+         0,        66,
+         0,       667,
+         0,      -155,
+         0,       105,
+         0,      -107,
+         0,       -74,
+         0,       -52,
+         0,        91,
+         0,        59,
+         0,       235,
+        -1,     -1819,         0,      2470,
+        71,        13,
+         0,      1026,
+        14,       -54,
+         0,      -174,
+      -121,       -19,
+         0,      -200,
+         0,      3008,
+       -16,     -8043,       -10,    -37136,
+        -3,     73724,
+      -157,        -5,
+         0,      -854,
+         8,       147,
+       -13,      -893,
+         0,     11869,
+       -23,      -172,
+        89,        14,
+        -1,       872,         0,     -3744,
+        11,      1606,
+         0,      -559,
+        -1,     -2530,
+         0,       454,
+         0,      -193,
+       -60,       -10,
+       -82,       -13,
+       -75,         6,
+        36,        81,
+       354,   -162836,       148,   -516569,
+         4,   2054441,
+         4,       -94,
+        39,        38,
+        61,       -30,
+         2,       121,
+       -11,       590,
+        62,      2108,
+         0,    -12242,
+      -476,       -42,
+       -84,       113,
+      -394,       236,
+         0,       276,
+       -49,        31,
+         0,        86,
+         1,     -1313,
+         1,        69,
+       -60,        88,
+       -46,        18,
+         0,    -63818,
+        14,       -93,
+       113,       547,      -618,        17,
+        -7,     12290,        -1,    -25679,
+         0,        92,
+      -115,        50,
+       -48,       233,
+         4,      1311,         1,     -5567,
+         3,      1251,
+        29,       548,
+      -244,       257,
+        -2,      1825,
+        42,       637,
+       -46,        68,
+       -62,         8,
+         3,       110,
+       445,      -100,      -316,      -202,
+      2925,      -621,       763,      1495,
+      -169,      -184,        20,       -76,
+      -475,      -138,         8,      -141,
+      -197,      1351,     -1284,       422,
+      -129,      1879,      -102,      8382,
+        -9,  45864958,
+      -215,      1350,     -1285,       422,
+      -481,      -136,         8,      -140,
+        40,       -53,
+      2622,      -543,       700,      1406,
+       402,       -95,      -318,      -194,
+       122,        13,
+       -30,       147,
+      -121,      -902,
+        61,       -23,
+       -63,         7,
+        69,       479,
+      -224,       228,
+        -7,       500,
+         0,      -429,
+       -42,       193,
+       -92,        37,
+        67,         5,
+      -350,       -31,
+         0,        67,
+       -55,        -5,
+         0,        47,
+       -36,        53,
+         5,       561,
+         0,      -126,
+         0,       871,
+       -52,         4,
+      -201,    116922,       -22,    371352,
+       -12,  -1473285,
+         0,        87,
+      -164,        84,
+        -3,       422,
+        30,      1434,
+       -26,        38,
+         2,  -1249943,
+      -404,       -34,
+       -57,        79,
+         5,       509,
+         1,       131,
+      -344,       168,
+       112,     22540,        30,     71218,
+        18,   -283983,
+         0,      -851,
+         0,     -1538,
+         0,      1360,
+       -12,        51,
+       -48,        68,
+        88,       -20,
+         1,        63,
+         0,      -568,
+       303,        25,
+         0,      -122,
+        87,       586,      -606,       -14,
+         0,      -100,
+       -85,         8,
+      -165,        54,
+       -45,       140,
+         0,       -54,
+         4,      -831,         1,      3495,
+        31,       116,
+       -46,       -11,
+      -371,       190,
+      -507,       399,
+        -2,        57,
+       -60,        36,
+      -198,     -1174,      -613,      4988,
+       -87,        -4,
+       141,       560,      -276,       187,
+      1876,      1379,       778,      4386,
+        24,       -15,
+       167,      -774,
+       -71,        -9,
+       -62,        90,
+        98,       580,      -663,        -7,
+        34,      -112,
+        57,        15,
+      -355,      -214,
+     -3240,    -13605,     12229,     -5723,
+      3496,      7063,
+        33,       -51,
+      1908,      1160,      -226,       715,
+       964,      1170,     -1264,       623,
+     14071,      5280,      5614,      3026,
+       488,      1576,        -2, 226395859,
+       824,      1106,     -1287,       617,
+      1917,      1156,      -214,       718,
+        90,       -97,
+     12078,     -2366,      3282,      6668,
+      -219,      9179,       593,      2015,
+      -282,      -186,
+        57,        25,
+        31,      -102,
+       -77,        -4,
+      -268,      -341,        -7,       -45,
+        -3,        74,
+        15,      -615,
+       -88,        -7,
+       234,      -353,
+         1,      -119,
+      -163,     -1159,      -601,      4969,
+        22,       -58,
+       -17,    -11434,
+        17,        54,
+       348,       348,      -460,       434,
+      -371,       175,
+       -11,      -204,
+         4,     -6440,
+        -5,       -53,
+        -4,    -14388,       -37,    -45231,
+        -7,    179562,
+       -44,       136,
+      -160,        49,
+      -101,        81,
+        -1,      -188,
+         0,         2,
+        -4,     12124,       -11,    -25217,
+        71,       543,      -557,       -14,
+       -75,       526,
+         0,    395274,
+      -233,       -16,
+        93,       -20,
+       -43,        61,
+         0,     -1275,
+         0,      -824,
+         1,      -415,         0,      1762,
+      -261,       131,
+       -45,        64,
+      -297,       -25,
+         0,    -17533,
+        -6,       -56,
+        21,      1100,
+         1,       327,
+         1,        66,
+        23,      -217,
+       -83,        -7,
+        83,     86847,        49,    275754,
+        -4,  -1093857,
+       -46,         2,
+         0,       -24,
+         0,      -419,
+         0,     -5833,
+         1,       506,
+         0,      -827,
+        -1,      -377,
+       -11,       -78,
+         0,    131945,
+        -2,      -334,
+         1,       -75,
+         0,       -72,
+         0,      -213,
+        -6,      5564,        -2,    -11618,
+         0,      1790,
+         0,      -131,
+         0,         6,
+         0,       -76,
+         0,      -130,
+         0,     -1115,         0,      4783,
+         0,      -195,
+         0,      -627,
+         0,       -55,
+         0,       -83,
+         0,       163,
+         0,       -54,
+         0,        82,
+         0,       149,
+         0,      -754,         0,      1578,
+         0,       138,
+         0,        68,
+         2,     -2506,         0,      3399,
+         0,      -125,
+        86,        16,
+         0,     -6350,         0,     27316,
+        18,       -63,
+         0,      -169,
+        -1,        46,
+      -136,       -21,
+         0,      -239,
+       -30,     -8788,       -15,    -40549,
+        -4,     80514,
+       -46,        -8,
+      -168,        -6,
+        -1,       536,         0,     -2314,
+         9,       148,
+       -13,      -842,
+        -1,    307713,
+       -23,      -175,
+        95,        15,
+         0,      -297,
+        11,      1341,
+         0,      -106,
+         0,         5,
+        -4,        68,
+      -114,        10,
+        32,        75,
+       159,   -130487,        98,   -413967,
+         2,   1647339,
+        -4,       -85,
+       100,       -46,
+         2,        95,
+       -11,       461,
+        51,      1647,
+         0,    -32090,
+      -375,       -33,
+       -65,        86,
+      -300,       180,
+         0,       836,         0,     -3576,
+         0,      -222,
+         0,      -993,
+       -41,        60,
+         0,     -4537,
+      -431,       -34,
+         2,       927,         0,     -1931,
+       -79,        33,
+       -31,       144,
+        -1,       284,         0,     -1207,
+         0,        88,
+       -11,       315,
+      -178,       177,
+        -1,       144,
+       -58,       986,
+        11,        86,
+      -228,      -110,
+      2636,      -494,       718,      1474,
+        28,       -35,
+       -24,       782,      -797,       277,
+      2142,     -1231,       856,      1853,
+        74,     10797,         0,  23699298,
+       -21,       786,      -796,       277,
+        27,       -34,
+      2615,      -494,       712,      1461,
+      -226,      -109,
+       -11,       663,
+         0,      -123,
+      -169,       157,
+       -54,       266,
+         0,       -76,
+         1,      -634,         0,      2738,
+       -25,       106,
+       -63,        24,
+         0,      -372,
+      -221,       -24,
+         0,     -5356,
+         0,      -219,
+         0,        91,
+       -28,      7684,        -6,     24391,
+        -1,    -96795,
+       -77,        43,
+         2,        95,
+       -47,        -3,
+         0,    -84530,
+         2,       310,
+         1,        88,
+       111,     19331,        32,     61306,
+         4,   -243595,
+         0,       770,
+         0,      -103,
+         0,       160,
+         0,       356,
+         0,       236,
+       -41,       354,
+        39,       303,
+        12,       -56,
+       873,      -143,       238,       482,
+       -28,        35,
+       -93,        31,
+        -3,   7690211,
+       -91,        33,
+       -34,        43,
+       824,      -130,       226,       450,
+       -39,       341,
+        -1,      -687,
+         0,      -303,
+        11,     -2935,         1,     12618,
+       121,       924,         9,     -1836,
+      -268,     -1144,      -678,      3685,
+       -69,      -261,
+         0,  -4115951,
+       -69,      -261,
+         5,      -151,
+         0,       -88,
+         0,        91,
+         0,       187,
+         0,     -1281,
+         1,        77,
+         1,      6059,         3,     19238,
+         0,    -76305,
+         0,       -90,
+         0,      -238,
+         0,      -962,         0,      4133,
+         0,        96,
+         0,      9483,
+         0,        85,
+         0,      -688,
+         0,     -5607,
+         0,        55,
+         0,      -752,
+         0,        71,
+         0,       303,
+         0,      -288,
+         0,        57,
+         0,        45,
+         0,       189,
+         0,       401,
+         0,     -1474,         0,      3087,
+         0,       -71,
+         0,      2925,
+         0,       -75,
+         0,       359,
+         0,        55,
+         1,    -10155,         0,     43735,
+         0,      -572,
+         0,       -49,
+         0,      -660,
+         0,     -3591,         0,      7516,
+         0,       668,
+        -1,       -53,
+        -2,    384259,
+         0,      -163,
+         0,       -93,
+         1,       112,
+       -95,    -11528,       -22,    -36505,
+        -1,    145308,
+         5,       145,
+         0,      4047,
+         1,      1483,         0,     -6352,
+         0,       991,         0,     -4262,
+         0,       -93,
+         0,      -334,
+         0,      -160,
+         0,      -153,
+       -10,       127,
+        51,       185,
+       -77,        18,
+        56,      1217,         6,   1919574,
+       -74,        17,
+        50,       180,
+        -5,        93,
+         0,      -104,
+         0,       -58,
+        -3,      -353,        -1,      1499,
+         0,      -229,
+       -15,        86,
+         0,    -93657,
+         0,      1561,         0,     -6693,
+         0,     -5839,
+         1,      6791,         0,    -29143,
+         1,      -701,         0,      3015,
+         0,      2543,
+         0,       693,
+        -1,    361233,
+         0,       -50,
+         0,       946,
+        -1,      -140,
+       -70,       407,
+         0,   -450995,
+         0,      -368,
+         0,        54,
+         0,      -802,
+         0,       -96,
+         0,      1274,         0,     -5459,
+         0,      -614,         0,      2633,
+         0,       685,
+         0,      -915,
+         0,       -85,
+         0,        88,
+         0,       106,
+         0,       928,
+         0,      -726,         0,      1523,
+         0,      5715,
+         0,     -4338,         0,     18706,
+         0,      -135,
+         0,      -132,
+         0,      -158,
+         0,       -98,
+         0,       680,
+        -1,    138968,
+         0,      -192,
+         0,     -1698,
+         0,     -2734,         0,     11769,
+         0,         4,
+         0,       673,         0,     -2891,
+         0,       889,         0,     -3821,
+         0,       121,
+        -1,    143783,
+         0,       231,
+        -9,        51,
+         0,    -57413,
+         0,      -483,
+         0,      -407,
+         0,       676,         0,     -2902,
+         0,       531,
+         0,       445,
+         0,       672,
+         0,     19336,
+         0,        70,
+         0,    -39976,
+         0,       -68,
+         0,      4203,
+         0,      -406,
+         0,       446,
+         0,      -108,
+         0,        79,
+         0,        84,
+         0,       734,
+         0,       255,
+         0,      3944,
+         0,      -655,         0,      2825,
+         0,      -109,
+         0,      -234,
+         0,        57,
+         0,     19773,
+         0,     -2013,
+         0,       958,
+         0,      -521,
+         0,      -757,
+         0,     10594,
+         0,     -9901,
+         0,       199,
+         0,      -275,
+         0,        64,
+         0,        54,
+         0,       165,
+         0,      1110,
+         0,     -3286,
+         0,       909,
+         0,        54,
+         0,        87,
+         0,       258,
+         0,      1261,
+         0,       -51,
+         0,       336,
+         0,      -114,
+         0,      2185,
+         0,      -850,
+         0,        75,
+         0,       -69,
+         0,      -103,
+         0,       776,
+         0,     -1238,
+         0,       137,
+         0,        67,
+         0,      -260,
+         0,       130,
+         0,        49,
+         0,       228,
+         0,       215,
+         0,      -178,
+         0,        57,
+         0,      -133,
+};
+static long lrtabb[] = {-1};
+static long lrtabr[] = {
+     -5422,     -2120,      1077,       772,
+        39,        75,         3,        10,
+      -468,      -326,      -113,       -78,
+        -4,        -2,
+         1,         3,
+        29,        24,         4,         2,
+         1,         0,
+        -9,         7,        -2,         0,
+       -32,       -13,        -3,        -3,
+       233,       126,        89,        77,
+       -33,        16,
+         3,        -3,         0,        -1,
+         2,         0,
+         0,         1,
+         4,         9,         1,         1,
+        16,        -1,         0,        18,
+         3,         2,
+         0,         0,
+         0,         0,
+         0,         0,
+         0,         0,
+         0,        -1,
+       -22,        -5,
+        10,         3,         1,         1,
+       -15,         7,        -2,         1,
+        -8,       -11,        -1,        -2,
+        -1,         1,
+        46,       -58,       126,       -23,
+         4,         8,
+        35,         8,        10,       -17,
+         0,         0,
+         0,         0,
+       -10,        -7,
+         0,         0,
+       -23,         3,       151,        10,
+      -327,         0,
+         4,        -5,         6,         5,
+         1,         0,
+        -1,        -3,
+         0,         0,
+         0,         1,
+      -185,         0,
+        -3,       -24,        -5,        -2,
+     -1062,         3,      4560,         0,
+        -3,         0,
+         4,         1,
+         8,        -1,         2,         4,
+         0,         1,
+         0,        -1,
+         0,         0,
+        -1,         0,
+         0,         1,
+         0,         0,
+        -1,        -1,
+       277,         3,      -583,         1,
+        -1,         4,       -32,         7,
+         0,       -34,
+         1,        -1,
+    -23685,         0,
+        -1,        -2,
+        -1,        -7,
+        -5,        -4,
+         0,         2,
+        -2,         0,
+        -5,        -1,
+        35,         0,
+         0,         2,
+       202,         0,
+       180,         0,
+         0,        -1,
+        -3,        -6,
+      -193,         0,       770,        -1,
+        -2,        -4,
+       -32,        23,       -28,       -46,
+       -13,        -9,
+       -54,        10,        -1,       -61,
+    -44895,         0,
+      -230,         5,
+        -1,        -4,
+       -71,         0,
+       -15,         0,
+         1,         0,
+        15,        11,        -3,         6,
+         2,        -3,         4,        -1,
+      2576,      -138,    -19881,       -47,
+    -65906,        -1,    261925,        -4,
+        -2,        -7,         4,        -2,
+         0,         0,
+        -1,         0,
+         1,        -3,
+       172,        -2,      -727,         0,
+         4,         1,
+       324,         0,
+      -139,         1,
+         1,         3,
+      -276,         0,
+         5,         3,
+         9,         0,
+        -1,        10,
+       -37,         0,
+         5,        -1,
+        76,       -10,
+   1318810,         1,
+        12,        -1,
+       -38,         1,
+      -141,         0,       611,         0,
+         0,       -11,
+         4,         0,
+      -627,         2,     -2882,        -3,
+      5711,        -2,
+       -48,        -7,
+     55294,         0,
+         2,        -7,
+        31,         0,
+        34,         0,
+      -259,         0,
+       -55,         2,
+         6,         3,
+     -4273,        20,    -13554,         3,
+     53878,         0,
+       -46,         0,
+       -85,         0,       114,         0,
+       -45,         0,
+      -818,         0,      3520,         0,
+        34,         0,
+      -157,         0,
+        29,         0,
+      -878,         0,      1838,         0,
+      -428,         0,
+       161,         0,
+        24,         0,
+        65,         0,
+        19,         0,
+        15,         0,
+        12,         0,
+       -26,         0,
+       -14,         0,
+      -149,         0,
+       584,         0,      -793,         0,
+         4,       -23,
+      -238,         0,
+       -18,        -5,
+        45,         0,
+        -7,        42,
+        79,         0,
+     -1723,         0,
+      2895,        -6,     13362,        -4,
+    -26525,        -1,
+        -2,        57,
+       291,         0,
+        52,        -3,
+      -327,         5,
+     -2755,         0,
+       -63,         9,
+         5,       -33,
+      -261,        -1,      1122,         0,
+       621,        -4,
+      -227,         0,
+      1077,         0,
+      -167,         0,
+        85,         0,
+        -4,        23,
+        -5,        32,
+         3,        30,
+       -32,        14,
+     64607,       141,    204958,        59,
+   -815115,         2,
+       -37,        -1,
+        15,       -15,
+        12,        24,
+        48,        -1,
+       235,         4,
+       843,       -25,
+      4621,         0,
+       -17,       191,
+        45,        34,
+        95,       159,
+      -132,         0,
+        13,        20,
+        32,         0,
+      -540,         0,
+        29,         0,
+        37,        25,
+         8,        19,
+     22127,         0,
+       -35,        -5,
+       232,       -48,         7,       262,
+      5428,         3,    -11342,         1,
+       -45,         0,
+       -21,       -49,
+      -100,       -21,
+      -626,         1,      2665,         0,
+       532,        -2,
+       235,       -12,
+      -111,      -105,
+       774,         1,
+      -283,        17,
+        29,        20,
+         3,        27,
+        47,        -2,
+       -43,      -192,       -87,       136,
+      -269,     -1264,       646,      -330,
+       -79,        73,       -33,        -9,
+        60,      -205,        61,         4,
+      -584,       -85,      -182,      -555,
+      -780,       -57,     -3488,       -45,
+ -19818328,        -4,
+       583,        93,       182,       555,
+       -59,       208,       -60,        -4,
+        23,        17,
+       235,      1133,      -608,       302,
+        41,       174,        84,      -137,
+         6,       -53,
+        63,        13,
+      -392,        52,
+       -10,       -27,
+        -3,       -27,
+       199,       -31,
+        99,        97,
+      -218,        -3,
+       209,         0,
+        84,        18,
+        16,        40,
+         2,       -30,
+        14,      -154,
+        30,         0,
+        -2,        24,
+      -108,         0,
+       -24,       -16,
+       262,        -2,
+        55,         0,
+      -304,         0,
+         2,        25,
+     55112,        95,    175036,        11,
+   -694477,         5,
+        41,         0,
+       -38,       -76,
+       199,         1,
+       679,       -14,
+       -17,       -12,
+    582619,         1,
+       -16,       191,
+        38,        27,
+      -234,         2,
+       -60,         0,
+        80,       163,
+    -10296,        48,    -32526,        13,
+    129703,         8,
+     -1366,         0,
+      -741,         0,
+      -646,         0,
+        25,         6,
+        33,        23,
+        10,        43,
+       -31,         0,
+        -6,         0,
+       -12,       147,
+        59,         0,
+       287,       -42,        -7,       297,
+       -59,         0,
+        -4,       -42,
+       -27,       -81,
+       -69,       -22,
+        27,         0,
+      -423,        -2,      1779,        -1,
+       -57,        15,
+         5,       -23,
+        94,       182,
+      -197,      -250,
+        24,         1,
+       -18,       -30,
+       581,       -98,     -2473,      -303,
+        -2,        43,
+      -277,        70,       -92,      -136,
+      -681,       925,     -2165,       384,
+        -8,       -12,
+       382,        82,
+        -4,        35,
+       -45,       -31,
+      -286,        48,         3,      -328,
+       -55,       -17,
+         8,       -28,
+      -106,       175,
+     -6735,      1601,     -2832,     -6052,
+      3495,     -1730,
+       -25,       -17,
+      -574,       944,      -354,      -112,
+      -579,       476,      -308,      -625,
+     -2411,      7074,     -1529,      2828,
+     -1335,       247,-112000844,        -1,
+       545,      -409,       305,       637,
+       572,      -950,       356,       106,
+        48,        44,
+      1170,      5974,     -3298,      1624,
+     -4538,      -106,      -996,       294,
+        92,      -139,
+       -12,        28,
+        50,        16,
+         2,       -38,
+       169,      -133,        22,        -3,
+        38,         1,
+       305,         7,
+         4,       -44,
+       175,       116,
+        59,         1,
+      -573,        81,      2453,       297,
+        29,        11,
+      5674,        -8,
+       -27,         9,
+       173,      -173,       215,       228,
+       -87,      -184,
+       102,        -5,
+      3206,         2,
+       -53,         2,
+      7159,        -7,     22505,       -19,
+    -89344,        -3,
+        67,        22,
+        24,        79,
+       -40,       -50,
+        94,         0,
+       186,         0,
+     -6063,         0,     12612,        -5,
+      -271,        35,         7,      -278,
+      -479,       -74,
+    426754,         0,
+         8,      -116,
+       -10,       -47,
+       -31,       -22,
+       645,         0,
+       426,         0,
+      -213,         0,       903,         0,
+       -67,      -133,
+       -33,       -23,
+        13,      -152,
+     -9316,         0,
+        29,        -3,
+      -564,        11,
+      -167,         0,
+       -34,         0,
+       114,        12,
+         4,       -44,
+    -44561,        42,   -141493,        25,
+    561256,        -2,
+        -1,       -24,
+      -261,         0,
+       211,         0,
+     -4263,         0,
+      -262,         1,
+      1842,         0,
+       202,         0,
+        41,        -6,
+     77165,         0,
+       176,        -1,
+        39,         1,
+       -24,         0,
+       118,         0,
+     -2991,        -4,      6245,        -1,
+     46886,         0,
+       -75,         0,
+      -100,         0,
+        40,         0,
+        75,         0,
+      -618,         0,      2652,         0,
+       112,         0,
+      1780,         0,
+        30,         0,
+        49,         0,
+        86,         0,
+        33,         0,
+       -30,         0,
+       -95,         0,
+       277,         0,      -580,         0,
+       -35,         0,
+      -319,         0,
+      1622,         1,     -2201,         0,
+        79,         0,
+        10,       -57,
+      2363,         0,    -10162,         0,
+       -41,       -12,
+        62,         0,
+        30,         1,
+       -14,        89,
+     -2721,         0,
+      5780,       -19,     26674,       -10,
+    -52964,        -2,
+        -5,        30,
+        -4,       111,
+      -317,        -1,      1369,         0,
+        93,        -6,
+      -564,         9,
+   -115913,         0,
+      -113,        15,
+        10,       -62,
+        99,         0,
+       891,        -7,
+        36,         0,
+       108,         0,
+       -42,        -2,
+         7,        75,
+       -50,        21,
+     86822,       104,    275441,        65,
+  -1096109,         1,
+       -56,         3,
+        31,        66,
+        63,        -1,
+       307,         7,
+      1097,       -34,
+     17453,         0,
+       -22,       250,
+        57,        43,
+       120,       200,
+      -297,         0,      1269,         0,
+       166,         0,
+      -662,         0,
+        40,        28,
+      1521,         0,
+       -23,       288,
+       351,        -2,      -729,         0,
+       -22,       -52,
+       -96,       -21,
+      -139,        -1,       589,         0,
+        35,         0,
+       210,         7,
+      -118,      -119,
+        62,         0,
+      -583,       -26,
+       -42,         5,
+       -73,       152,
+      -330,     -1759,       983,      -479,
+       -23,       -19,
+      -522,       -15,      -185,      -533,
+       739,      1559,     -1300,       614,
+     -7332,        52, -15836758,         0,
+       524,        16,       185,       532,
+        23,        18,
+       330,      1751,      -978,       476,
+        73,      -151,
+       519,        18,
+        38,         0,
+       105,       113,
+      -178,       -37,
+        26,         0,
+       262,         1,     -1139,         0,
+        71,        17,
+        16,        42,
+       151,         0,
+        16,      -148,
+      4147,         0,
+       149,         0,
+       -30,         0,
+      2980,         9,      9454,         2,
+    -37519,         0,
+       -28,       -49,
+        37,        -1,
+         2,       -31,
+     33870,         0,
+      -208,         1,
+       -59,         1,
+    -13105,        68,    -41564,        21,
+    165148,         3,
+     -1022,         0,
+       -40,         0,
+      -132,         0,
+      -228,         0,
+        95,         0,
+      -138,       -16,
+      -126,        16,
+        24,         5,
+       -57,      -346,       191,       -94,
+       -14,       -11,
+       -12,       -37,
+  -3053364,        -1,
+        13,        36,
+        17,        13,
+        51,       327,      -179,        90,
+       138,        16,
+       233,         0,
+        62,         0,
+      1164,         0,     -5000,         0,
+      -407,       117,       770,         9,
+        -4,         1,        21,         2,
+         1,         0,
+    -16869,         0,
+        -1,         0,
+         1,         0,
+        35,         0,
+       -78,         0,
+        78,         0,
+      -533,         0,
+       -31,         1,
+     -2448,        -6,     -7768,        -1,
+     30812,         0,
+        37,         0,
+      -227,         0,
+       197,         0,      -846,         0,
+       -77,         0,
+      4171,         0,
+       -67,         0,
+       287,         0,
+      2532,         0,
+       -19,         0,
+       -40,         0,
+       -56,         0,
+       128,         0,
+        83,         0,
+       -45,         0,
+       -36,         0,
+       -92,         0,
+      -134,         0,
+       714,         0,     -1495,         0,
+        32,         0,
+      -981,         0,
+        15,         0,
+      -166,         0,
+       -59,         0,
+      4923,         0,    -21203,         0,
+       246,         0,
+        15,         0,
+       104,         0,
+      1683,         0,     -3523,         0,
+      -865,         0,
+       -25,         1,
+   -186329,        -1,
+        10,         0,
+        50,         0,
+        53,         0,
+      5455,       -45,     17271,       -10,
+    -68747,         0,
+        69,        -2,
+     -7604,         0,
+      -724,         1,      3101,         0,
+       -46,         0,       200,         0,
+       -44,         0,
+        97,         0,
+       -53,         0,
+        62,         0,
+       -54,        -4,
+        88,       -24,
+        -9,       -36,
+      -581,        27,   -914711,         3,
+         8,        35,
+       -86,        24,
+        51,         3,
+        48,         0,
+        26,         0,
+       133,         1,      -577,         0,
+       105,         0,
+        -3,        -1,
+      3194,         0,
+       528,         0,     -2263,         0,
+      2028,         0,
+     -3266,         1,     14016,         0,
+        10,         0,       -41,         0,
+      -100,         0,
+       -32,         0,
+   -124348,         0,
+        16,         0,
+      -325,         0,
+        50,        -1,
+         1,         0,
+      -553,         0,
+         0,         0,
+         0,         0,
+         2,         0,
+       -34,         0,
+      -444,         0,      1902,         0,
+         9,         0,       -37,         0,
+       254,         0,
+       156,         0,
+        -2,         0,
+       -35,         0,
+       -48,         0,
+      -368,         0,
+       327,         0,      -686,         0,
+     -2263,         0,
+      1952,         0,     -8418,         0,
+       -13,         0,
+        52,         0,
+         9,         0,
+        21,         0,
+      -261,         0,
+    -62404,         0,
+         0,         0,
+        79,         0,
+      1056,         0,     -4547,         0,
+      -351,         0,
+      -305,         0,      1310,         0,
+        -1,         0,         6,         0,
+         0,         0,
+    -55953,         0,
+       -80,         0,
+         0,         0,
+       168,         0,
+      -147,         0,
+       127,         0,
+      -265,         0,      1138,         0,
+        -1,         0,
+        -9,         0,
+        -8,         0,
+     -5984,         0,
+       -22,         0,
+        -5,         0,
+         0,         0,
+         0,         0,
+       127,         0,
+        -2,         0,
+        10,         0,
+       -31,         0,
+       -29,         0,
+      -286,         0,
+       -98,         0,
+     -1535,         0,
+       252,         0,     -1087,         0,
+        43,         0,
+         4,         0,
+       -19,         0,
+     -7620,         0,
+        29,         0,
+      -322,         0,
+       203,         0,
+         0,         0,
+     -3587,         0,
+        10,         0,
+         0,         0,
+        94,         0,
+         0,         0,
+        -1,         0,
+        -1,         0,
+      -315,         0,
+         1,         0,
+         0,         0,
+         0,         0,
+       -30,         0,
+       -94,         0,
+      -460,         0,
+         1,         0,
+      -114,         0,
+         0,         0,
+      -746,         0,
+         4,         0,
+       -23,         0,
+        24,         0,
+         0,         0,
+      -237,         0,
+         1,         0,
+         0,         0,
+       -18,         0,
+         0,         0,
+         0,         0,
+       -16,         0,
+       -76,         0,
+       -67,         0,
+         0,         0,
+       -16,         0,
+         0,         0,
+};
+static CHAR lrargs[] = {
+  0,  3,
+  3,  4,  3, -8,  4,  3,  5,  1,
+  2,  2,  5, -5,  6,  2,
+  5, -1, 10,  2, 13, -1, 11,  3,  3, -7,  4,  0,
+  3,  1, 13, -1, 11,  2,  5,  1,
+  2,  4,  5,-10,  6,  0,
+  4,  2, 10, -2, 13, 14,  3,-23,  4,  1,
+  3,  3,  2, -7,  3,  4,  4,  1,
+  3, -1, 13, 18,  2,-16,  3,  2,
+  2,  8,  2,-13,  3,  1,
+  5,  2, 10, -2, 13,  2,  3, -3,  5,  1,  6,  0,
+  3, -1, 13, 26,  2,-29,  3,  0,
+  3,  1, 10, -1, 11,  2,  4,  1,
+  4,  1, 10, -1, 13,  3,  2, -4,  3,  1,
+  4,  1, 10, -1, 13,  3,  3, -4,  4,  0,
+  3, -1, 10, 15,  2,-12,  3,  0,
+  4,  2, 10, -3, 13, 24,  2,-24,  3,  0,
+  3, -1, 10, 23,  2,-25,  3,  0,
+  4,  1, 10, -1, 11,  1,  3,  1,  6,  0,
+  4,  2, 10, -2, 11,  5,  2, -6,  3,  0,
+  4,  2, 10, -2, 13,  6,  2, -8,  3,  0,
+  4, -2, 10,  1, 13, 12,  2, -8,  3,  1,
+  5, -1, 10,  1, 13, -1, 11, 20,  2,-20,  3,  1,
+  4, -2, 10,  1, 13,  3,  1, -1,  3,  1,
+  5,  2, 10, -2, 13,  2,  3, -5,  5,  5,  6,  0,
+  4,  2, 10, -2, 13,  2,  3, -3,  5,  1,
+  4,  2, 10, -2, 13,  6,  3, -8,  4,  0,
+  4, -2, 10,  1, 13, 20,  2,-21,  3,  1,
+  4,  1, 10, -1, 11,  1,  3,  1,  5,  0,
+  1,  1,  6,  0,
+  4,  2, 10, -2, 13,  5,  3, -6,  4,  0,
+  3,  3,  2, -5,  3,  2,  5,  0,
+  2, -1, 11,  1, 14,  1,
+  4,  2, 10, -2, 13,  2,  3, -2,  5,  0,
+  2,  1,  3, -2,  4,  1,
+  4,  1, 10, -1, 11,  5,  2, -7,  3,  0,
+  1,  1,  5,  0,
+  2,  7,  3,-13,  4,  0,
+  4, -2, 10,  1, 13, 15,  2,-13,  3,  0,
+  4,  2, 10, -2, 13,  3,  2, -3,  3,  0,
+  2, -2, 11,  2, 14,  1,
+  3,  1, 10,  1, 12, -1, 13,  1,
+  3, -1, 13, 21,  2,-21,  3,  0,
+  2,  3,  2, -5,  3,  0,
+  2,  2,  3, -4,  4,  1,
+  2,  5,  2, -8,  3,  0,
+  3, -1, 13, 23,  2,-24,  3,  0,
+  2,  6,  3,-11,  4,  0,
+  1,  2,  5,  0,
+  2,  3,  3, -6,  4,  0,
+  2,  5,  3, -9,  4,  0,
+  4,  1, 10, -1, 11,  1,  3, -2,  5,  0,
+  3,  2, 10,  2, 12, -2, 13,  1,
+  2,  2,  2, -3,  3,  2,
+  2,  4,  3, -7,  4,  0,
+  2,  2, 13, -2, 11,  0,
+  2,  3,  3, -5,  4,  0,
+  2,  1,  2, -2,  3,  0,
+  2,  2,  3, -3,  4,  0,
+  4,  1, 10, -1, 11,  4,  2, -5,  3,  0,
+  2,  1,  3, -1,  4,  0,
+  2,  4,  2, -6,  3,  0,
+  4,  2, 10, -2, 13,  2,  2, -2,  3,  0,
+  3,  1, 10, -1, 11,  1,  2,  0,
+  2,  1,  2, -1,  3,  0,
+  3,  1, 12,  2, 13, -2, 11,  0,
+  2,  5,  3, -8,  4,  0,
+  2,  1,  3, -3,  5,  0,
+  3,  2, 10,  1, 12, -2, 13,  1,
+  2,  4,  3, -6,  4,  0,
+  2,  1,  3, -2,  5,  1,
+  2,  3,  3, -4,  4,  0,
+  2,  3,  2, -4,  3,  1,
+  2,  1, 10, -1, 13,  0,
+  2,  1,  3, -1,  5,  0,
+  2,  1,  3, -2,  6,  0,
+  2,  2,  3, -2,  4,  0,
+  2,  1,  3, -1,  6,  0,
+  2,  8,  2,-14,  3,  0,
+  3,  1,  3,  2,  5, -5,  6,  1,
+  3,  5,  3, -8,  4,  3,  5,  1,
+  1,  1, 12,  3,
+  3,  3,  3, -8,  4,  3,  5,  1,
+  3,  1,  3, -2,  5,  5,  6,  0,
+  2,  8,  2,-12,  3,  0,
+  2,  1,  3,  1,  5,  0,
+  3,  2, 10,  1, 12, -2, 11,  1,
+  2,  5,  2, -7,  3,  0,
+  3,  1, 10,  1, 13, -2, 11,  0,
+  2,  2,  2, -2,  3,  0,
+  2,  5,  3, -7,  4,  0,
+  3,  1, 12, -2, 13,  2, 11,  0,
+  2,  4,  3, -5,  4,  0,
+  2,  3,  3, -3,  4,  0,
+  1,  1,  2,  0,
+  3,  3, 10,  1, 12, -3, 13,  0,
+  2,  2,  3, -4,  5,  0,
+  2,  2,  3, -3,  5,  0,
+  2,  2, 10, -2, 13,  0,
+  2,  2,  3, -2,  5,  0,
+  2,  3,  2, -3,  3,  0,
+  3,  1, 10, -1, 12, -1, 13,  1,
+  2,  2,  3, -1,  5,  0,
+  2,  2,  3, -2,  6,  0,
+  1,  2, 12,  2,
+  3, -2, 10,  1, 11,  1, 14,  0,
+  2,  2, 10, -2, 11,  0,
+  2,  2,  2, -1,  3,  0,
+  4, -2, 10,  2, 13,  1,  2, -1,  3,  0,
+  2,  4,  2, -4,  3,  0,
+  2,  3, 10, -3, 13,  0,
+  4, -2, 10,  2, 13,  1,  3, -1,  5,  0,
+  2,  3,  3, -3,  5,  0,
+  3,  2, 10, -1, 12, -2, 13,  2,
+  3,  3, 10, -1, 13, -2, 11,  0,
+  1,  3, 12,  1,
+  4, -2, 10,  2, 13,  2,  2, -2,  3,  0,
+  3,  2, 10, -1, 12, -2, 11,  1,
+  2,  5,  2, -5,  3,  0,
+  2,  4, 10, -4, 13,  0,
+  2,  6,  2, -6,  3,  0,
+  3,  2, 10, -2, 12, -2, 13,  1,
+  3,  4, 10, -2, 13, -2, 11,  0,
+  3,  2, 10, -2, 12, -2, 11,  0,
+  2,  7,  2, -7,  3,  0,
+  3,  2, 10, -3, 12, -2, 13,  0,
+  2,  8,  2, -8,  3,  0,
+  2,  9,  2, -9,  3,  0,
+  2, 10,  2,-10,  3,  0,
+  3,  2, 10, -4, 12, -1, 13,  0,
+  3,  4, 10, -2, 12, -3, 13,  0,
+  4,  4, 10, -1, 12, -1, 13, -2, 11,  0,
+  3,  2, 10, -3, 12, -1, 13,  1,
+  4, -2, 10,  1, 13,  3,  3, -2,  5,  0,
+  3,  4, 10, -1, 12, -3, 13,  0,
+  4, -2, 10,  1, 13,  3,  3, -3,  5,  0,
+  4,  2, 10, -2, 12,  1, 13, -2, 11,  0,
+  4, -2, 10,  1, 13,  2,  2, -1,  3,  0,
+  3,  3, 10, -1, 12, -2, 11,  0,
+  3,  4, 10, -1, 13, -2, 11,  0,
+  3,  2, 10, -2, 12, -1, 13,  2,
+  4, -2, 10,  1, 13,  2,  3, -1,  5,  0,
+  3,  3, 10, -1, 12, -2, 13,  0,
+  4, -2, 10,  1, 13,  3,  2, -3,  3,  0,
+  4, -2, 10,  1, 13,  2,  3, -2,  5,  0,
+  2,  4, 10, -3, 13,  0,
+  4, -2, 10,  1, 13,  2,  3, -3,  5,  0,
+  3, -2, 10,  1, 13,  1,  2,  0,
+  4,  2, 10, -1, 12,  1, 13, -2, 11,  1,
+  4, -2, 10,  1, 13,  2,  2, -2,  3,  0,
+  2,  3, 12, -1, 13,  0,
+  2,  3, 10, -2, 11,  0,
+  2,  1, 10, -2, 12,  0,
+  4,  4, 10,  1, 12, -1, 13, -2, 11,  0,
+  3, -1, 13,  3,  2, -2,  3,  0,
+  3, -1, 13,  3,  3, -2,  5,  0,
+  3, -2, 10, 18,  2,-15,  3,  0,
+  5,  2, 10, -1, 13,  3,  3, -8,  4,  3,  5,  0,
+  3,  2, 10, -1, 12, -1, 13,  2,
+  5, -2, 10,  1, 13,  5,  3, -8,  4,  3,  5,  0,
+  5, -2, 10,  1, 13,  1,  3,  2,  5, -5,  6,  0,
+  4,  2, 10, -2, 13, 18,  2,-17,  3,  0,
+  4, -2, 10,  1, 13,  1,  3, -1,  6,  0,
+  4, -2, 10,  1, 13,  2,  3, -2,  4,  0,
+  4, -2, 10,  1, 13,  1,  3, -1,  5,  0,
+  2,  3, 10, -2, 13,  0,
+  4, -2, 10,  1, 13,  3,  2, -4,  3,  0,
+  4, -2, 10,  1, 13,  3,  3, -4,  4,  0,
+  4, -2, 10,  1, 13,  1,  3, -2,  5,  0,
+  3,  4, 10,  1, 12, -3, 13,  0,
+  4, -2, 10,  1, 13,  1,  3, -3,  5,  0,
+  3, -1, 13,  4,  2, -4,  3,  0,
+  4, -2, 10,  1, 13,  1,  2, -1,  3,  0,
+  4, -2, 10,  1, 13,  1,  3, -1,  4,  0,
+  4, -2, 10,  1, 13,  2,  3, -3,  4,  0,
+  4, -2, 10,  1, 13,  3,  3, -5,  4,  0,
+  3,  2, 10,  1, 13, -2, 11,  0,
+  4, -2, 10, -1, 13,  1, 11,  1, 14,  0,
+  4, -2, 10,  1, 13,  2,  2, -3,  3,  1,
+  2,  2, 12, -1, 13,  1,
+  3,  3, 10,  1, 12, -2, 11,  0,
+  4,  2, 10, -1, 13,  2,  3, -4,  4,  0,
+  4,  2, 10, -1, 13,  3,  2, -5,  3,  0,
+  2,  1, 10, -1, 12,  1,
+  3, -1, 13,  3,  2, -3,  3,  0,
+  3, -2, 10,  1, 13,  1,  5,  0,
+  4,  2, 10, -1, 13,  1,  3, -2,  4,  0,
+  3, -1, 13,  2,  3, -2,  5,  0,
+  4,  2, 10, -1, 13, -1, 11,  1, 14,  0,
+  3, -1, 13,  5,  3, -6,  4,  0,
+  3, -2, 10,  1, 13,  1,  6,  0,
+  3, -1, 10,  1,  3, -1,  5,  0,
+  4, -2, 10,  1, 13,  8,  2,-13,  3,  1,
+  3, -2, 10, 18,  2,-16,  3,  1,
+  5, -2, 10,  1, 13,  3,  2, -7,  3,  4,  4,  1,
+  4,  2, 10, -1, 13,  2,  5, -5,  6,  1,
+  5,  2, 10, -1, 13,  4,  3, -8,  4,  3,  5,  1,
+  2,  2, 10, -1, 13,  2,
+  5, -2, 10,  1, 13,  4,  3, -8,  4,  3,  5,  1,
+  4, -2, 10,  1, 13,  2,  5, -5,  6,  1,
+  5,  2, 10, -1, 13,  3,  2, -7,  3,  4,  4,  0,
+  4,  2, 10, -2, 13, 18,  2,-16,  3,  1,
+  4,  2, 10, -1, 13,  8,  2,-13,  3,  1,
+  3, -1, 10,  3,  2, -4,  3,  0,
+  3, -1, 13,  6,  2, -8,  3,  0,
+  3, -1, 13,  2,  3, -3,  5,  0,
+  3, -1, 13,  6,  3, -8,  4,  0,
+  3,  2, 10, -1, 13,  1,  6,  0,
+  4, -2, 10,  1, 13, -1, 11,  1, 14,  0,
+  4, -2, 10,  1, 13,  1,  3, -2,  4,  0,
+  3,  2, 10, -1, 13,  1,  5,  0,
+  3,  3, 10,  1, 12, -2, 13,  0,
+  4, -2, 10,  1, 13,  3,  2, -5,  3,  0,
+  4, -2, 10,  1, 13,  2,  3, -4,  4,  0,
+  2, -1, 13,  1,  2,  0,
+  4,  2, 10, -1, 13,  2,  2, -3,  3,  0,
+  3, -1, 10,  1,  2, -1,  3,  0,
+  3, -1, 13,  4,  2, -5,  3,  0,
+  3,  2, 10, -3, 13,  2, 11,  0,
+  4,  2, 10, -1, 13,  2,  3, -3,  4,  0,
+  3, -1, 13,  2,  2, -2,  3,  0,
+  4,  2, 10, -1, 13,  1,  2, -1,  3,  0,
+  4,  2, 10,  1, 12,  1, 13, -2, 11,  0,
+  3, -2, 13, 18,  2,-15,  3,  0,
+  2,  1, 12, -1, 13,  2,
+  3, -1, 13,  1,  3, -1,  6,  0,
+  4,  2, 10, -1, 13,  1,  3, -2,  5,  0,
+  3, -1, 13,  2,  3, -2,  4,  0,
+  3, -1, 13,  1,  3, -1,  5,  0,
+  4,  2, 10, -1, 13,  3,  3, -4,  4,  0,
+  1,  1, 10,  0,
+  3, -1, 13,  3,  2, -4,  3,  0,
+  3, -1, 13,  3,  3, -4,  4,  0,
+  4,  2, 10, -1, 13,  1,  3, -1,  5,  0,
+  4,  2, 10, -1, 13,  2,  3, -2,  4,  0,
+  3, -1, 13,  1,  3, -2,  5,  0,
+  3,  2, 10,  1, 12, -1, 13,  2,
+  3,  1, 12,  1, 13, -2, 11,  0,
+  3, -1, 13,  1,  2, -1,  3,  0,
+  4,  2, 10, -1, 13,  2,  2, -2,  3,  0,
+  3, -1, 13,  4,  2, -6,  3,  0,
+  3, -1, 13,  2,  3, -3,  4,  0,
+  3,  1, 13,  1,  2, -2,  3,  0,
+  4,  2, 10, -1, 13,  3,  3, -3,  4,  0,
+  2,  3, 13, -2, 11,  0,
+  4,  2, 10, -1, 13,  4,  2, -5,  3,  0,
+  3,  1, 10,  1,  2, -1,  3,  0,
+  3, -1, 13,  2,  2, -3,  3,  1,
+  3,  2, 10,  2, 12, -3, 13,  0,
+  3,  2, 10, -1, 13,  1,  2,  0,
+  3,  1, 13,  2,  3, -4,  4,  0,
+  3,  1, 13,  3,  2, -5,  3,  0,
+  2, 21,  2,-21,  3,  0,
+  3,  1, 10,  1, 12, -2, 13,  1,
+  4,  2, 10, -1, 13,  2,  3, -4,  5,  0,
+  4,  2, 10, -1, 13,  7,  3,-10,  4,  0,
+  2, -1, 13,  1,  5,  0,
+  3,  1, 13,  1,  3, -2,  4,  0,
+  4,  2, 10, -3, 13,  2,  3, -2,  5,  0,
+  3,  1, 10,  1,  3, -2,  5,  0,
+  3,  1, 13, -1, 11,  1, 14,  1,
+  2, -1, 13,  1,  6,  0,
+  4,  2, 10, -1, 13,  6,  3, -8,  4,  1,
+  4,  2, 10, -1, 13,  2,  3, -3,  5,  1,
+  3, -1, 13,  8,  3,-15,  4,  0,
+  4,  2, 10, -1, 13,  6,  2, -8,  3,  0,
+  5,  2, 10, -1, 13, -2, 11,  5,  2, -6,  3,  0,
+  3,  1, 10,  3,  3, -4,  4,  0,
+  3,  1, 10,  3,  2, -4,  3,  1,
+  4,  1, 10, -1, 13, -1, 11,  2,  4,  0,
+  3, -2, 13, 26,  2,-29,  3,  0,
+  3, -1, 13,  8,  2,-13,  3,  0,
+  3, -2, 13, 18,  2,-16,  3,  2,
+  4, -1, 13,  3,  2, -7,  3,  4,  4,  0,
+  3,  1, 13,  2,  5, -5,  6,  1,
+  4,  1, 13,  4,  3, -8,  4,  3,  5,  1,
+  1,  1, 13,  3,
+  4, -1, 13,  4,  3, -8,  4,  3,  5,  1,
+  3, -1, 13,  2,  5, -5,  6,  1,
+  4,  1, 13,  3,  2, -7,  3,  4,  4,  0,
+  2, 18,  2,-16,  3,  1,
+  3,  1, 13,  8,  2,-13,  3,  2,
+  2, 26,  2,-29,  3,  0,
+  4,  1, 10,  1, 13, -1, 11,  2,  4,  0,
+  5,  2, 10,  1, 13, -2, 11,  5,  2, -6,  3,  0,
+  3,  1, 13,  8,  3,-15,  4,  1,
+  4,  2, 10, -3, 13,  2,  3, -3,  5,  0,
+  3,  1, 10,  1,  3, -1,  5,  0,
+  2,  1, 13,  1,  6,  0,
+  4,  2, 10, -1, 13,  5,  3, -6,  4,  0,
+  3,  1, 10,  2,  3, -2,  4,  0,
+  3, -1, 13, -1, 11,  1, 14,  1,
+  4,  2, 10, -1, 13,  2,  3, -5,  6,  0,
+  4,  2, 10, -1, 13,  2,  3, -2,  5,  0,
+  5,  2, 10, -1, 13,  2,  3, -4,  5,  5,  6,  0,
+  3, -1, 13,  1,  3, -2,  4,  1,
+  2,  1, 13,  1,  5,  0,
+  4,  2, 10, -1, 13,  4,  3, -4,  4,  0,
+  4,  2, 10, -1, 13,  3,  2, -3,  3,  0,
+  4,  2, 10,  2, 12, -1, 13, -2, 11,  0,
+  2,  1, 10,  1, 12,  2,
+  3, -1, 13,  3,  2, -5,  3,  0,
+  3, -1, 13,  2,  3, -4,  4,  0,
+  4,  2, 10, -1, 13,  2,  3, -1,  5,  0,
+  4,  2, 10, -1, 13,  2,  3, -2,  6,  0,
+  3,  1, 10,  1, 12, -2, 11,  0,
+  3,  2, 10,  2, 12, -1, 13,  1,
+  3,  1, 13,  2,  2, -3,  3,  1,
+  3, -1, 13,  1, 11,  1, 14,  0,
+  2,  1, 13, -2, 11,  0,
+  4,  2, 10, -1, 13,  5,  2, -6,  3,  0,
+  3, -1, 13,  1,  2, -2,  3,  0,
+  3,  1, 13,  2,  3, -3,  4,  0,
+  3,  1, 13,  1,  2, -1,  3,  0,
+  4,  2, 10, -1, 13,  4,  2, -4,  3,  0,
+  3,  2, 10,  1, 12, -3, 13,  1,
+  3,  1, 13,  1,  3, -2,  5,  0,
+  3,  1, 13,  3,  3, -4,  4,  0,
+  3,  1, 13,  3,  2, -4,  3,  0,
+  2,  1, 10, -2, 13,  0,
+  4,  2, 10, -1, 13,  3,  3, -4,  5,  0,
+  3,  1, 13,  1,  3, -1,  5,  0,
+  3,  1, 13,  2,  3, -2,  4,  0,
+  3,  1, 13,  1,  3, -1,  6,  0,
+  4,  2, 10, -1, 13,  3,  3, -3,  5,  0,
+  4,  2, 10, -1, 13,  6,  2, -7,  3,  0,
+  2,  1, 12,  1, 13,  2,
+  4,  2, 10, -1, 13,  3,  3, -2,  5,  0,
+  4,  2, 10,  1, 12, -1, 13, -2, 11,  0,
+  2,  1, 10,  2, 12,  0,
+  2,  1, 10, -2, 11,  0,
+  3,  1, 13,  2,  2, -2,  3,  0,
+  3,  1, 12, -1, 13,  2, 11,  0,
+  4,  2, 10, -1, 13,  5,  2, -5,  3,  0,
+  3,  1, 13,  2,  3, -3,  5,  0,
+  2,  2, 10, -3, 13,  0,
+  3,  1, 13,  2,  3, -2,  5,  0,
+  3,  1, 13,  3,  2, -3,  3,  0,
+  3,  1, 10, -1, 12, -2, 13,  0,
+  4,  2, 10, -1, 13,  6,  2, -6,  3,  0,
+  2,  2, 12,  1, 13,  1,
+  3,  2, 10, -1, 13, -2, 11,  0,
+  3,  1, 10, -1, 12, -2, 11,  0,
+  3,  2, 10,  1, 13, -4, 11,  0,
+  3,  1, 13,  4,  2, -4,  3,  0,
+  4,  2, 10, -1, 13,  7,  2, -7,  3,  0,
+  3,  2, 10, -1, 12, -3, 13,  1,
+  2,  3, 12,  1, 13,  0,
+  4,  2, 10, -1, 12, -1, 13, -2, 11,  0,
+  3,  1, 13,  5,  2, -5,  3,  0,
+  4,  2, 10, -1, 13,  8,  2, -8,  3,  0,
+  3,  2, 10, -2, 12, -3, 13,  0,
+  4,  2, 10, -1, 13,  9,  2, -9,  3,  0,
+  3,  4, 10, -3, 12, -2, 13,  0,
+  2,  2, 10, -4, 12,  0,
+  3,  4, 10, -2, 12, -2, 13,  1,
+  2,  6, 10, -4, 13,  0,
+  3,  4, 10, -1, 12, -2, 11,  0,
+  2,  2, 10, -3, 12,  1,
+  3,  3, 10, -2, 12, -1, 13,  0,
+  3, -2, 10,  3,  3, -2,  5,  0,
+  3,  4, 10, -1, 12, -2, 13,  1,
+  3, -2, 10,  3,  3, -3,  5,  0,
+  2,  5, 10, -3, 13,  0,
+  3, -2, 10,  4,  2, -4,  3,  0,
+  3, -2, 10,  2,  2, -1,  3,  0,
+  2,  4, 10, -2, 11,  0,
+  2,  2, 10, -2, 12,  2,
+  3, -2, 10,  3,  3, -2,  4,  0,
+  3, -2, 10,  2,  3, -1,  5,  0,
+  3,  3, 10, -1, 12, -1, 13,  1,
+  3, -2, 10,  3,  2, -3,  3,  0,
+  3, -2, 10,  2,  3, -2,  5,  0,
+  2,  4, 10, -2, 13,  0,
+  3, -2, 10,  2,  3, -3,  5,  0,
+  2, -2, 10,  1,  2,  0,
+  4,  2, 10, -1, 12,  2, 13, -2, 11,  0,
+  3, -2, 10,  2,  2, -2,  3,  0,
+  3,  3, 10,  1, 13, -2, 11,  0,
+  3,  4, 10,  1, 12, -2, 11,  0,
+  4,  2, 10, -1, 12, -1, 11,  1, 14,  0,
+  4, -2, 10, -1, 13, 18,  2,-15,  3,  0,
+  4,  2, 10,  3,  3, -8,  4,  3,  5,  0,
+  2,  2, 10, -1, 12,  2,
+  4, -2, 10,  5,  3, -8,  4,  3,  5,  0,
+  4,  2, 10, -1, 13, 18,  2,-17,  3,  0,
+  3, -2, 10,  1,  3, -1,  6,  0,
+  3, -2, 10,  2,  3, -2,  4,  0,
+  3, -2, 10,  1,  3, -1,  5,  0,
+  2,  3, 10, -1, 13,  0,
+  3, -2, 10,  3,  2, -4,  3,  0,
+  3, -2, 10,  3,  3, -4,  4,  0,
+  3, -2, 10,  1,  3, -2,  5,  0,
+  3,  4, 10,  1, 12, -2, 13,  1,
+  4,  2, 10, -1, 12, -2, 13,  2, 11,  0,
+  3, -2, 10,  1,  2, -1,  3,  0,
+  3, -2, 10,  2,  3, -3,  4,  0,
+  3,  2, 10,  2, 13, -2, 11,  0,
+  3, -2, 10,  2,  2, -3,  3,  0,
+  2,  2, 12, -2, 13,  1,
+  3,  2, 10,  2,  3, -4,  4,  0,
+  3,  2, 10,  3,  2, -5,  3,  0,
+  3,  1, 10, -1, 12,  1, 13,  1,
+  3, -2, 13,  3,  2, -3,  3,  0,
+  2, -2, 10,  1,  5,  0,
+  3,  2, 10,  1,  3, -2,  4,  0,
+  3, -2, 13,  2,  3, -2,  5,  0,
+  3,  2, 10, -1, 11,  1, 14,  0,
+  4,  4, 10, -2, 13,  2,  3, -3,  5,  0,
+  3, -2, 10,  8,  2,-13,  3,  0,
+  4, -2, 10, -1, 13, 18,  2,-16,  3,  1,
+  4, -2, 10,  3,  2, -7,  3,  4,  4,  0,
+  4,  2, 10,  4,  3, -8,  4,  3,  5,  1,
+  1,  2, 10,  3,
+  4, -2, 10,  4,  3, -8,  4,  3,  5,  1,
+  4,  2, 10,  3,  2, -7,  3,  4,  4,  0,
+  4,  2, 10, -1, 13, 18,  2,-16,  3,  1,
+  3,  2, 10,  8,  2,-13,  3,  0,
+  3, -2, 10, -1, 11,  1, 14,  0,
+  4,  4, 10, -2, 13,  2,  3, -2,  5,  0,
+  3, -2, 10,  1,  3, -2,  4,  0,
+  2,  2, 10,  1,  5,  0,
+  4,  4, 10, -2, 13,  3,  2, -3,  3,  0,
+  3,  3, 10,  1, 12, -1, 13,  1,
+  3, -2, 10,  3,  2, -5,  3,  0,
+  3, -2, 10,  2,  3, -4,  4,  0,
+  3,  4, 10,  2, 12, -2, 13,  0,
+  3,  2, 10,  2,  2, -3,  3,  0,
+  3,  2, 10, -2, 13,  2, 11,  0,
+  3,  2, 10,  1,  2, -1,  3,  0,
+  4,  2, 10,  1, 12,  2, 13, -2, 11,  0,
+  2,  1, 12, -2, 13,  2,
+  3,  2, 10,  1,  3, -2,  5,  0,
+  3, -2, 13,  1,  3, -1,  5,  0,
+  3,  2, 10,  3,  2, -4,  3,  0,
+  2,  1, 10,  1, 13,  0,
+  3,  2, 10,  1,  3, -1,  5,  0,
+  3,  2, 10,  2,  3, -2,  4,  0,
+  2,  2, 10,  1, 12,  2,
+  2,  1, 12, -2, 11,  0,
+  3, -2, 13,  1,  2, -1,  3,  0,
+  3,  1, 10, -1, 13,  2, 11,  0,
+  3,  2, 10,  2,  2, -2,  3,  0,
+  3,  1, 10,  1, 12, -3, 13,  0,
+  3,  2, 13, -1, 11,  1, 14,  0,
+  3,  2, 10,  2,  3, -3,  5,  0,
+  3,  2, 10,  6,  2, -8,  3,  0,
+  3, -3, 13, 18,  2,-16,  3,  1,
+  3,  2, 13,  2,  5, -5,  6,  0,
+  4,  2, 13,  4,  3, -8,  4,  3,  5,  0,
+  1,  2, 13,  0,
+  4, -2, 13,  4,  3, -8,  4,  3,  5,  0,
+  3, -2, 13,  2,  5, -5,  6,  0,
+  3,  1, 13, 18,  2,-16,  3,  1,
+  3, -2, 13, -1, 11,  1, 14,  0,
+  3,  2, 10,  2,  3, -2,  5,  0,
+  3,  2, 10,  3,  2, -3,  3,  0,
+  3,  1, 10,  1, 12,  1, 13,  1,
+  2,  2, 10,  2, 12,  1,
+  2,  1, 11,  1, 14,  1,
+  4, -1, 13, -2, 11, 18,  2,-16,  3,  0,
+  1,  2, 11,  0,
+  4, -1, 13,  2, 11, 18,  2,-16,  3,  0,
+  2, -3, 11,  1, 14,  0,
+  3,  2, 13,  1,  2, -1,  3,  0,
+  3,  2, 10,  4,  2, -4,  3,  0,
+  3,  2, 10,  1, 12, -4, 13,  0,
+  2,  1, 10, -3, 13,  0,
+  3,  2, 13,  1,  3, -1,  5,  0,
+  2,  1, 12,  2, 13,  2,
+  3,  1, 10,  2, 12,  1, 13,  0,
+  3,  1, 10, -1, 13, -2, 11,  0,
+  2,  1, 12,  2, 11,  1,
+  3,  2, 10,  5,  2, -5,  3,  0,
+  2,  2, 10, -4, 13,  0,
+  3,  2, 10,  6,  2, -6,  3,  0,
+  2,  2, 12,  2, 13,  0,
+  3,  2, 10, -2, 13, -2, 11,  0,
+  2,  2, 12,  2, 11,  0,
+  2,  2, 10, -4, 11,  0,
+  3,  2, 10,  7,  2, -7,  3,  0,
+  3,  2, 10, -1, 12, -4, 13,  0,
+  4,  2, 10, -1, 12, -2, 13, -2, 11,  0,
+  3,  2, 10,  8,  2, -8,  3,  0,
+  3,  2, 10,  9,  2, -9,  3,  0,
+  3,  4, 10, -3, 12, -1, 13,  0,
+  3,  6, 10, -1, 12, -3, 13,  0,
+  3,  4, 10, -2, 12, -1, 13,  1,
+  3,  5, 10, -1, 12, -2, 13,  0,
+  2,  6, 10, -3, 13,  0,
+  4,  4, 10, -1, 12,  1, 13, -2, 11,  0,
+  3,  2, 10, -3, 12,  1, 13,  0,
+  2,  3, 10, -2, 12,  0,
+  3,  4, 10, -1, 12, -1, 13,  1,
+  2,  5, 10, -2, 13,  0,
+  3,  6, 10,  1, 12, -3, 13,  0,
+  3,  4, 10,  1, 13, -2, 11,  0,
+  3,  2, 10, -2, 12,  1, 13,  1,
+  2,  3, 10, -1, 12,  0,
+  4, -2, 10, -1, 13,  2,  3, -2,  5,  0,
+  2,  4, 10, -1, 13,  0,
+  4,  2, 10, -2, 12, -1, 13,  2, 11,  0,
+  3,  4, 10, -3, 13,  2, 11,  0,
+  4, -2, 10, -1, 13,  2,  2, -2,  3,  0,
+  3,  2, 10, -1, 12,  1, 13,  2,
+  4, -2, 10, -1, 13,  1,  3, -1,  5,  0,
+  1,  3, 10,  0,
+  3,  4, 10,  1, 12, -1, 13,  1,
+  4,  2, 10, -1, 12, -1, 13,  2, 11,  1,
+  4, -2, 10, -1, 13,  1,  2, -1,  3,  0,
+  3,  2, 10,  3, 13, -2, 11,  0,
+  2,  2, 12, -3, 13,  0,
+  3,  1, 10, -1, 12,  2, 13,  0,
+  4,  2, 10,  1, 13, -1, 11,  1, 14,  0,
+  4, -2, 10, -2, 13, 18,  2,-16,  3,  0,
+  5,  2, 10,  1, 13,  4,  3, -8,  4,  3,  5,  0,
+  2,  2, 10,  1, 13,  1,
+  5, -2, 10, -1, 13,  4,  3, -8,  4,  3,  5,  0,
+  3,  2, 10, 18,  2,-16,  3,  0,
+  4, -2, 10, -1, 13, -1, 11,  1, 14,  0,
+  4,  4, 10, -1, 13,  2,  3, -2,  5,  0,
+  4,  4, 10, -1, 13,  3,  2, -3,  3,  0,
+  2,  3, 10,  1, 12,  1,
+  3,  4, 10,  2, 12, -1, 13,  0,
+  4,  2, 10, -1, 13,  1, 11,  1, 14,  0,
+  3,  2, 10, -1, 13,  2, 11,  0,
+  2,  1, 12, -3, 13,  1,
+  2,  1, 10,  2, 13,  0,
+  3,  2, 10,  1, 12,  1, 13,  1,
+  3,  1, 12, -1, 13, -2, 11,  1,
+  2,  1, 10,  2, 11,  0,
+  4,  2, 10,  1, 12, -1, 13,  2, 11,  0,
+  1,  3, 13,  0,
+  4,  2, 10,  1, 13,  2,  3, -2,  5,  0,
+  3,  1, 10,  1, 12,  2, 13,  0,
+  3,  2, 10,  2, 12,  1, 13,  0,
+  3,  1, 13,  1, 11,  1, 14,  0,
+  2,  1, 13,  2, 11,  0,
+  3,  1, 10,  1, 12,  2, 11,  0,
+  4,  2, 10,  2, 12, -1, 13,  2, 11,  0,
+  2,  1, 13, -4, 11,  0,
+  2,  1, 10, -4, 13,  0,
+  2,  1, 12,  3, 13,  1,
+  3,  1, 12,  1, 13,  2, 11,  1,
+  2,  2, 10, -5, 13,  0,
+  3,  2, 10, -3, 13, -2, 11,  0,
+  3,  2, 10, -1, 13, -4, 11,  0,
+  3,  6, 10, -2, 12, -2, 13,  0,
+  2,  4, 10, -3, 12,  0,
+  3,  6, 10, -1, 12, -2, 13,  0,
+  2,  4, 10, -2, 12,  1,
+  2,  6, 10, -2, 13,  0,
+  2,  4, 10, -1, 12,  1,
+  2,  5, 10, -1, 13,  0,
+  3,  6, 10,  1, 12, -2, 13,  0,
+  4,  4, 10, -1, 12, -2, 13,  2, 11,  0,
+  3,  4, 10,  2, 13, -2, 11,  0,
+  3,  2, 10, -2, 12,  2, 13,  0,
+  1,  4, 10,  0,
+  3,  2, 10, -2, 12,  2, 11,  0,
+  3,  4, 10, -2, 13,  2, 11,  0,
+  3,  2, 10, -1, 12,  2, 13,  1,
+  2,  3, 10,  1, 13,  0,
+  2,  4, 10,  1, 12,  1,
+  3,  2, 10, -1, 12,  2, 11,  1,
+  3,  3, 10, -1, 13,  2, 11,  0,
+  2,  2, 10,  2, 13,  0,
+  3,  3, 10,  1, 12,  1, 13,  0,
+  3,  2, 10,  1, 11,  1, 14,  0,
+  2,  2, 10,  2, 11,  0,
+  2,  1, 12, -4, 13,  0,
+  2,  1, 10,  3, 13,  0,
+  3,  2, 10,  1, 12,  2, 13,  1,
+  3,  1, 12, -2, 13, -2, 11,  0,
+  3,  1, 10,  1, 13,  2, 11,  0,
+  3,  2, 10,  1, 12,  2, 11,  0,
+  1,  4, 13,  0,
+  3,  1, 10,  1, 12,  3, 13,  0,
+  2,  2, 13,  2, 11,  0,
+  4,  1, 10,  1, 12,  1, 13,  2, 11,  0,
+  1,  4, 11,  0,
+  2,  1, 12,  4, 13,  0,
+  3,  1, 12,  2, 13,  2, 11,  0,
+  3,  2, 10, -4, 13, -2, 11,  0,
+  3,  6, 10, -2, 12, -1, 13,  0,
+  2,  8, 10, -3, 13,  0,
+  3,  6, 10, -1, 12, -1, 13,  0,
+  3,  4, 10, -2, 12,  1, 13,  0,
+  2,  6, 10, -1, 13,  0,
+  3,  4, 10, -1, 12,  1, 13,  1,
+  3,  6, 10,  1, 12, -1, 13,  0,
+  4,  4, 10, -1, 12, -1, 13,  2, 11,  0,
+  3,  2, 10, -2, 12,  3, 13,  0,
+  2,  4, 10,  1, 13,  0,
+  3,  4, 10, -1, 13,  2, 11,  0,
+  3,  2, 10, -1, 12,  3, 13,  0,
+  3,  4, 10,  1, 12,  1, 13,  0,
+  4,  2, 10, -1, 12,  1, 13,  2, 11,  0,
+  2,  2, 10,  3, 13,  0,
+  3,  2, 10,  1, 13,  2, 11,  0,
+  3,  2, 10, -1, 13,  4, 11,  0,
+  3,  2, 10,  1, 12,  3, 13,  0,
+  3,  1, 12, -3, 13, -2, 11,  0,
+  3,  1, 10,  2, 13,  2, 11,  0,
+  4,  2, 10,  1, 12,  1, 13,  2, 11,  0,
+  1,  5, 13,  0,
+  2,  3, 13,  2, 11,  0,
+  2,  1, 13,  4, 11,  0,
+  3,  1, 12,  3, 13,  2, 11,  0,
+  2,  8, 10, -2, 13,  0,
+  2,  6, 10, -1, 12,  0,
+  1,  6, 10,  0,
+  3,  6, 10, -2, 13,  2, 11,  0,
+  3,  4, 10, -1, 12,  2, 13,  0,
+  3,  4, 10, -1, 12,  2, 11,  0,
+  2,  4, 10,  2, 13,  0,
+  2,  4, 10,  2, 11,  0,
+  3,  2, 10, -1, 12,  4, 13,  0,
+  3,  4, 10,  1, 12,  2, 13,  0,
+  4,  2, 10, -1, 12,  2, 13,  2, 11,  0,
+  2,  2, 10,  4, 13,  0,
+  3,  2, 10,  2, 13,  2, 11,  0,
+  2,  2, 10,  4, 11,  0,
+  1,  6, 13,  0,
+  2,  4, 13,  2, 11,  0,
+  2,  2, 13,  4, 11,  0,
+  3,  6, 10, -1, 12,  1, 13,  0,
+  2,  6, 10,  1, 13,  0,
+  2,  4, 10,  3, 13,  0,
+  3,  4, 10,  1, 13,  2, 11,  0,
+  2,  2, 10,  5, 13,  0,
+  3,  2, 10,  3, 13,  2, 11,  0,
+ -1
+};
+
+static long btabr[] = {-1};
+static long btabb[] = {-1};
+static long btabl[] = {
+        -3,        -4,
+         4,     -1856,         0,      8043,
+        -9,     -1082,
+        -1,      -310,
+        -1,      -522,
+      -330,     -1449,      -853,      4656,
+       -66,         7,
+        -1,   9996928,
+       -66,         6,
+        23,       183,
+         0,       173,
+         0,       -56,
+         0,        50,
+         0,      -785,
+         1,        51,
+         0,       -60,
+         1,     11843,         0,    -50754,
+         0,      1834,         1,     -7910,
+         0,    -48060,
+         1,        56,
+         0,     13141,        -1,    -56318,
+         0,      2541,
+        -1,      -649,
+      -133,       778,
+       -46,         8,
+         1,   1665737,
+       -47,         7,
+         0,        65,
+         0,        45,
+         0,      -138,
+         0,     -1005,
+         0,     -2911,
+         0,       -47,
+         0,        96,
+         0,      -394,
+         2,        76,
+         2,    -17302,         0,     74337,
+         0,      -101,
+         0,        58,
+         0,      -171,
+         0,       -77,
+         0,     -1283,         0,      2686,
+         0,       -55,
+         0,        99,
+         0,        55,
+         0,       397,
+         0,       540,
+         0,       626,
+        -1,     -5188,         0,     10857,
+         0,      -216,
+        -2,      -123,
+         0,      6337,
+         2,       224,
+      -152,    -23472,       -29,    -74336,         0,    295775,
+       -20,       149,
+        -2,        84,
+         9,       304,
+         0,     -3051,
+       -70,        -6,
+       -57,        34,
+         0,      -638,
+         0,      -201,
+       -73,         9,
+         0,      -100,
+      -101,        -8,
+         0,       -57,
+         0,      -207,
+        -3,        80,
+       -45,        45,
+        -5,       102,
+       -59,       -23,
+        52,       201,
+       -48,       233,      -220,        71,
+         4,      2810,         0,   6236541,
+       -61,       218,      -216,        67,
+        51,       201,
+       -59,       -23,
+      -144,      -837,      -457,      3029,
+       -45,        42,
+       -15,        73,
+        -6,      -169,
+         0,       135,
+       -64,        -7,
+         0,    -16245,
+         0,       -81,
+       -74,       -10,
+         0,       702,         0,     -3013,
+         0,     -5889,
+         1,       141,
+        58,      9598,        12,     30443,         1,   -120946,
+        -1,       -84,
+        -2,     11246,        -1,    -48391,
+         0,      1393,
+         0,       200,
+      -136,       -17,
+         0,       558,
+       -64,        -8,
+         0,       -71,
+         0,    317577,
+       -28,       183,
+         1,       219,
+         0,       421,
+         0,      -133,
+       501,      -139,
+         3,       354,
+      -101,       -13,
+        74,         7,
+       144,       -84,
+        59,        -2,
+         1,        64,
+     -2931,     12559,     -4641,      2638,      -303,     -2058,
+       -13,      -100,      -123,       -79,
+    -19214,      6084,      1494,     26993,     15213,    -82219,
+        42,        52,        48,      -101,
+       -53,        -4,
+         4,        47,
+        58,      -131,
+        46,        14,
+       -21,        -6,
+     -1311,     -8791,     10198,     -4185,      2815,      5640,
+       167,       422,      -229,        83,
+      3140,        39,      1221,       120,        96,       -30,
+        -1, 184612405,
+       187,       416,      -226,        81,
+     -1985,    -10083,      9983,     -4464,      2807,      5643,
+       -21,        -9,
+       113,      -367,
+       120,       580,      -667,        27,
+         8,        66,
+       -56,        -6,
+       337,        95,
+       -87,      3303,
+        -1,        65,
+        68,      -374,
+         0,      -574,
+        15,       -94,
+         0,       -53,
+         0,     -1303,
+         0,      -236,
+       283,        36,
+        -1,       -54,
+       269,       -35,
+         0,       -83,
+         0,       -52,
+         0,       730,         0,     -3129,
+         0,       813,
+         0,     -4299,
+         1,        59,
+        -6,      5130,         1,     16239,        -1,    -64603,
+         0,       -80,
+        91,        12,
+         0,      -561,
+       133,       -17,
+         0,       250,
+       -12,        71,
+         0,    155664,
+        82,       -11,
+         0,       106,
+         0,      -604,
+         0,     21862,
+        55,        -7,
+         0,     -1514,         0,      6501,
+         0,       906,
+         0,       -68,
+         0,       241,
+         0,       366,
+         0,        70,
+         0,     -1382,         0,      5957,
+         0,       113,
+         0,       -51,
+         0,       -55,
+         0,       731,
+         0,      -264,
+         0,     65788,
+         1,     -1504,         0,      3147,
+         0,       217,
+         0,     -4105,         0,     17658,
+         1,        69,
+         0,     -3518,
+         0,     -1767,
+       -43,     -7044,       -10,    -22304,         0,     88685,
+         3,        91,
+         0,      -485,
+         0,       -57,
+        -1,    333548,
+       -24,       172,
+        11,       544,         1,     -1132,
+         0,       353,
+         0,      -188,
+         0,        53,
+         0,        77,
+       158,      -887,
+        35,       131,
+       -54,        13,
+         0,   1994821,
+       -53,        14,
+        36,       125,
+         2,        56,
+         0,      -243,
+         0,      -364,
+        -2,      1916,         0,     -8227,
+         0,     15700,        -1,    -67308,
+         1,        66,
+         0,    -53686,
+         1,      3058,         1,    -13177,
+         0,       -72,
+         0,       -72,
+         0,        61,
+         0,     15812,
+         0,       165,
+         8,       -96,
+       318,      1341,       803,     -4252,
+        24,       193,
+      1137,      -226,       310,       622,
+       -56,        30,
+        -3,  10101666,
+       -56,        30,
+      1096,      -225,       300,       600,
+       -31,       409,
+        -1,      -507,
+         0,      -287,
+         0,     -1869,         0,      8026,
+         1,       544,        -1,     -1133,
+         0,     27984,
+         0,       -62,
+         0,      -249,
+         0,       187,
+         0,     -1096,
+         1,        53,
+         2,     12388,         0,    -53107,
+         0,      -322,
+         0,       -94,
+         0,     15157,
+         0,      -582,
+         0,      3291,
+         0,       565,
+         0,       106,
+         0,       112,
+         0,       306,
+         0,       809,
+         0,       130,
+         0,      -961,         0,      4149,
+         0,       174,
+         0,      -105,
+         0,      2196,
+         0,        59,
+         0,     36737,
+        -1,     -1832,         0,      3835,
+         0,      -139,
+         0,     24138,
+         0,      1325,
+         1,        64,
+         0,      -361,
+         0,     -1162,
+       -44,     -6320,       -10,    -20003,         0,     79588,
+         2,        80,
+         0,     -2059,
+         0,      -304,
+         0,     21460,
+         0,      -166,
+         0,       -87,
+        89,      -493,
+        32,       114,
+        34,       510,         1,   1172616,
+        31,       113,
+        -1,        57,
+         0,       214,
+         0,      -656,
+         0,      -646,
+         0,      1850,         0,     -7931,
+         0,     -6674,
+         0,      2944,         0,    -12641,
+         0,       916,
+        45,      -255,
+        16,        60,
+        -1,    619116,
+        16,        57,
+         0,       -58,
+         0,      1045,
+         0,      -156,
+       -15,        88,
+         0,    -62964,
+         0,      -126,
+         0,      1490,         0,     -6387,
+         0,       119,
+         0,      1338,
+         0,       -56,
+         0,       204,
+         0,       153,
+         0,       940,
+         0,       251,
+         0,       312,
+         0,       584,
+         0,      -786,         0,      3388,
+         0,       -52,
+         0,      4733,
+         0,       618,
+         0,     29982,
+         0,       101,
+         0,      -174,
+         0,     -2637,         0,     11345,
+         0,      -284,
+         0,      -524,
+         0,      -121,
+         0,      1464,
+        11,       -60,
+        -1,    151205,
+         0,       139,
+         0,     -2448,
+         0,       -51,
+         0,      -768,
+         0,      -638,
+         0,       552,         0,     -2370,
+         0,        70,
+         0,        64,
+         0,        57,
+         0,     39840,
+         0,       104,
+         0,    -10194,
+         0,      -635,
+         0,        69,
+         0,       113,
+         0,        67,
+         0,        96,
+         0,       367,
+         0,       134,
+         0,       596,
+         0,        63,
+         0,      1622,
+         0,       483,
+         0,        72,
+         0,     11917,
+         0,       -63,
+         0,      1273,
+         0,       -66,
+         0,      -262,
+         0,       -97,
+         0,       103,
+         0,     15196,
+         0,     -1445,
+         0,       -66,
+         0,       -55,
+         0,      -323,
+         0,      2632,
+         0,     -1179,
+         0,        59,
+         0,       -56,
+         0,        78,
+         0,        65,
+         0,       422,
+         0,       309,
+         0,      2125,
+         0,       -66,
+         0,       124,
+         0,       -57,
+         0,      1379,
+         0,      -304,
+         0,       177,
+         0,      -118,
+         0,       146,
+         0,       283,
+         0,       119,
+};
+static CHAR bargs[] = {
+  0,  1,
+  3,  1, 10,  1, 12, -1, 11,  1,
+  4,  2, 10,  2, 12, -1, 13, -1, 11,  0,
+  5,  2, 10, -1, 13, -1, 11,  3,  2, -3,  3,  0,
+  5,  2, 10, -1, 13, -1, 11,  2,  3, -2,  5,  0,
+  2, -1, 13,  1, 14,  1,
+  5, -1, 13,  1, 11,  4,  3, -8,  4,  3,  5,  0,
+  2,  1, 13, -1, 11,  0,
+  5,  1, 13, -1, 11,  4,  3, -8,  4,  3,  5,  0,
+  5,  2, 10, -1, 13, -1, 11,  2,  3, -3,  5,  0,
+  4,  1, 10,  1, 12, -2, 13,  1, 11,  0,
+  4,  1, 13, -1, 11,  1,  2, -1,  3,  0,
+  5,  2, 10, -1, 13, -1, 11,  2,  2, -2,  3,  0,
+  3,  1, 10, -2, 13,  1, 11,  0,
+  4,  1, 13, -1, 11,  1,  3, -1,  5,  0,
+  4, -1, 13,  1, 11,  1,  2, -1,  3,  0,
+  3,  1, 12,  1, 13, -1, 11,  1,
+  4,  2, 10,  1, 12, -1, 13, -1, 11,  1,
+  2,  1, 10, -1, 11,  0,
+  4, -1, 13,  1, 11,  1,  3, -1,  5,  0,
+  3,  1, 12, -1, 13,  1, 11,  1,
+  3,  2, 10, -3, 13,  1, 11,  0,
+  3,  2, 12,  1, 13, -1, 11,  0,
+  3, -2, 10,  1, 13,  1, 14,  0,
+  6, -2, 10,  1, 13,  1, 11,  4,  3, -8,  4,  3,  5,  0,
+  3,  2, 10, -1, 13, -1, 11,  0,
+  6,  2, 10, -1, 13, -1, 11,  4,  3, -8,  4,  3,  5,  0,
+  4, -1, 13,  1, 11,  2,  3, -2,  5,  0,
+  4, -1, 13,  1, 11,  3,  2, -3,  3,  0,
+  3,  1, 10, -1, 12, -1, 11,  0,
+  3,  2, 12, -1, 13,  1, 11,  0,
+  3,  2, 10,  1, 13, -3, 11,  0,
+  5, -2, 10,  1, 13,  1, 11,  1,  2, -1,  3,  0,
+  4,  2, 10, -1, 12, -3, 13,  1, 11,  0,
+  3,  3, 10, -2, 13, -1, 11,  0,
+  5, -2, 10,  1, 13,  1, 11,  1,  3, -1,  5,  0,
+  4,  2, 10, -1, 12, -1, 13, -1, 11,  1,
+  2,  3, 10, -3, 11,  0,
+  5, -2, 10,  1, 13,  1, 11,  2,  2, -2,  3,  0,
+  4,  2, 10, -1, 12,  1, 13, -3, 11,  0,
+  3,  4, 10, -3, 13, -1, 11,  0,
+  4,  2, 10, -2, 12, -1, 13, -1, 11,  1,
+  3,  4, 10, -1, 13, -3, 11,  0,
+  4,  2, 10, -3, 12, -1, 13, -1, 11,  0,
+  3,  4, 10, -1, 12, -3, 11,  0,
+  3,  2, 10, -3, 12, -1, 11,  0,
+  4,  4, 10, -1, 12, -2, 13, -1, 11,  0,
+  2,  4, 10, -3, 11,  0,
+  3,  2, 10, -2, 12, -1, 11,  1,
+  4,  3, 10, -1, 12, -1, 13, -1, 11,  0,
+  4, -2, 10,  1, 11,  2,  3, -2,  5,  0,
+  3,  4, 10, -2, 13, -1, 11,  0,
+  4, -2, 10,  1, 11,  2,  2, -2,  3,  0,
+  3,  2, 10, -1, 12, -1, 11,  2,
+  3, -2, 10,  1, 12,  1, 14,  0,
+  4, -2, 10,  1, 11,  2,  3, -2,  4,  0,
+  4, -2, 10,  1, 11,  1,  3, -1,  5,  0,
+  3,  3, 10, -1, 13, -1, 11,  0,
+  4, -2, 10,  1, 11,  3,  2, -4,  3,  0,
+  4, -2, 10,  1, 11,  1,  3, -2,  5,  0,
+  4,  2, 10, -1, 12, -2, 13,  1, 11,  0,
+  4, -2, 10,  1, 11,  1,  2, -1,  3,  0,
+  2, -1, 10,  1,  2,  0,
+  3,  2, 10,  2, 13, -3, 11,  0,
+  4, -2, 10,  1, 11,  2,  2, -3,  3,  0,
+  3,  2, 12, -2, 13,  1, 11,  0,
+  4,  1, 10, -1, 12,  1, 13, -1, 11,  0,
+  3, -2, 10,  1, 11,  1,  5,  0,
+  4,  2, 10, -1, 11,  1,  3, -2,  4,  0,
+  3,  2, 10, -2, 11,  1, 14,  0,
+  4, -2, 10,  1, 11,  8,  2,-13,  3,  0,
+  5, -2, 10, -1, 13,  1, 11, 18,  2,-16,  3,  0,
+  5,  2, 10, -1, 11,  4,  3, -8,  4,  3,  5,  1,
+  2,  2, 10, -1, 11,  1,
+  5, -2, 10,  1, 11,  4,  3, -8,  4,  3,  5,  1,
+  5,  2, 10, -1, 13, -1, 11, 18,  2,-16,  3,  0,
+  4,  2, 10, -1, 11,  8,  2,-13,  3,  0,
+  2, -2, 10,  1, 14,  1,
+  4, -2, 10,  1, 11,  1,  3, -2,  4,  0,
+  3,  2, 10, -1, 11,  1,  5,  0,
+  2,  2, 12, -1, 11,  0,
+  4,  3, 10,  1, 12, -1, 13, -1, 11,  0,
+  4,  2, 10, -1, 11,  2,  2, -3,  3,  0,
+  3,  2, 10, -2, 13,  1, 11,  0,
+  4,  2, 10, -1, 11,  1,  2, -1,  3,  0,
+  3,  1, 10,  1,  2, -2,  3,  0,
+  3,  1, 12, -2, 13,  1, 11,  1,
+  3,  1, 10,  1, 13, -1, 11,  0,
+  4,  2, 10, -1, 11,  1,  3, -1,  5,  0,
+  3,  2, 10,  1, 12, -1, 11,  2,
+  3, -2, 10, -1, 12,  1, 14,  0,
+  2,  1, 12, -1, 11,  1,
+  3,  1, 10, -1, 13,  1, 11,  0,
+  4,  2, 10, -1, 11,  2,  2, -2,  3,  0,
+  3,  1, 10,  2,  2, -3,  3,  0,
+  4,  2, 10,  1, 12, -2, 13,  1, 11,  0,
+  3, -1, 10,  1,  2, -2,  3,  0,
+  3, -1, 11,  1,  2, -1,  3,  0,
+  2,  2, 13, -1, 11,  0,
+  2, -2, 13,  1, 14,  0,
+  4,  2, 10, -1, 11,  2,  3, -2,  5,  0,
+  4,  2, 10, -1, 11,  3,  2, -3,  3,  0,
+  4,  2, 10,  2, 12, -2, 13, -1, 11,  0,
+  3,  1, 10,  1,  3, -2,  5,  0,
+  4,  1, 10,  1, 12,  1, 13, -1, 11,  0,
+  3,  1, 10,  3,  2, -4,  3,  0,
+  3,  1, 10,  1,  3, -1,  5,  0,
+  3,  1, 10,  1,  3, -2,  6,  0,
+  3,  1, 10,  2,  3, -2,  4,  0,
+  4,  1, 10,  1, 12, -1, 13, -1, 11,  0,
+  3,  2, 10,  2, 12, -1, 11,  2,
+  4,  1, 10,  1,  3,  2,  5, -5,  6,  1,
+  1,  1, 14,  2,
+  3,  1, 10,  8,  2,-12,  3,  1,
+  5, -2, 10,  1, 13, -1, 11, 20,  2,-21,  3,  0,
+  5,  2, 10, -2, 13,  1, 11,  2,  3, -3,  5,  0,
+  3,  1, 10,  1,  3,  1,  6,  0,
+  4, -1, 13, -1, 11, 26,  2,-29,  3,  0,
+  3, -1, 11,  8,  2,-13,  3,  0,
+  4, -1, 13, -1, 11, 18,  2,-16,  3,  2,
+  4, -1, 13,  1, 11, 10,  2, -3,  3,  1,
+  1,  1, 11,  3,
+  4, -1, 13, -1, 11, 10,  2, -3,  3,  1,
+  4, -1, 13,  1, 11, 18,  2,-16,  3,  2,
+  3,  1, 11,  8,  2,-13,  3,  0,
+  2,  1, 10,  2,  4,  0,
+  4,  2, 10, -1, 11,  5,  2, -6,  3,  1,
+  5,  2, 10, -2, 13, -1, 11,  2,  3, -3,  5,  0,
+  5, -2, 10,  1, 13,  1, 11, 20,  2,-21,  3,  0,
+  3,  1, 10,  1,  3,  1,  5,  0,
+  2, -2, 11,  1, 14,  0,
+  5,  2, 10, -2, 13,  1, 11,  2,  3, -2,  5,  0,
+  3,  1, 10,  5,  2, -7,  3,  0,
+  4,  1, 10,  1, 12, -1, 13,  1, 11,  0,
+  3,  1, 10,  2,  2, -2,  3,  0,
+  4,  2, 10,  2, 12, -2, 13,  1, 11,  0,
+  2,  2, 13, -3, 11,  0,
+  4,  2, 10, -1, 11,  4,  2, -4,  3,  0,
+  3,  1, 10,  4,  2, -5,  3,  0,
+  3,  1, 10, -3, 13,  1, 11,  0,
+  2,  1, 10,  1,  2,  0,
+  3,  1, 11,  1,  2, -1,  3,  0,
+  4,  2, 10, -1, 11,  3,  3, -3,  5,  0,
+  3,  1, 12,  2, 13, -1, 11,  1,
+  4,  2, 10,  1, 12, -2, 13, -1, 11,  0,
+  3,  1, 10, -1, 13, -1, 11,  0,
+  3,  1, 11,  1,  3, -1,  5,  0,
+  2,  1, 12,  1, 11,  2,
+  4,  2, 10, -1, 11,  5,  2, -5,  3,  0,
+  3,  1, 10,  5,  2, -6,  3,  0,
+  3,  2, 10,  1, 12, -3, 11,  0,
+  3,  1, 10,  2,  2, -1,  3,  0,
+  3,  2, 10, -4, 13,  1, 11,  0,
+  3, -2, 10,  2, 13,  1, 14,  0,
+  3,  2, 10, -2, 13, -1, 11,  0,
+  3,  1, 10,  3,  2, -2,  3,  0,
+  4,  1, 10, -1, 12, -1, 13, -1, 11,  0,
+  2,  2, 12,  1, 11,  0,
+  2,  2, 10, -3, 11,  0,
+  3,  1, 10,  4,  2, -3,  3,  0,
+  4,  2, 10, -1, 12, -2, 13, -1, 11,  1,
+  3,  2, 10, -1, 12, -3, 11,  0,
+  3,  4, 10, -4, 13, -1, 11,  0,
+  4,  2, 10, -2, 12, -2, 13, -1, 11,  0,
+  4,  4, 10, -2, 12, -1, 13, -1, 11,  0,
+  3,  6, 10, -3, 13, -1, 11,  0,
+  4,  4, 10, -1, 12, -1, 13, -1, 11,  1,
+  4,  2, 10, -3, 12, -1, 13,  1, 11,  0,
+  3,  5, 10, -2, 13, -1, 11,  0,
+  3,  4, 10,  1, 13, -3, 11,  0,
+  4,  2, 10, -2, 12,  1, 13, -1, 11,  0,
+  3,  3, 10, -1, 12, -1, 11,  0,
+  3,  4, 10, -1, 13, -1, 11,  0,
+  4,  2, 10, -2, 12, -1, 13,  1, 11,  1,
+  3,  4, 10, -3, 13,  1, 11,  0,
+  4,  2, 10, -1, 12,  1, 13, -1, 11,  1,
+  5, -2, 10,  1, 13, -1, 11,  2,  2, -2,  3,  0,
+  2,  3, 10, -1, 11,  0,
+  4,  4, 10,  1, 12, -1, 13, -1, 11,  0,
+  4,  2, 10, -1, 12, -1, 13,  1, 11,  2,
+  5, -2, 10,  1, 13, -1, 11,  1,  3, -1,  5,  0,
+  3,  3, 10, -2, 13,  1, 11,  0,
+  5, -2, 10,  1, 13, -1, 11,  1,  2, -1,  3,  0,
+  3,  2, 10,  1, 13, -1, 11,  0,
+  3, -2, 10, -1, 13,  1, 14,  0,
+  3,  2, 12, -1, 13, -1, 11,  1,
+  3,  3, 10,  1, 12, -1, 11,  0,
+  3,  1, 10, -1, 12,  1, 11,  0,
+  4, -1, 13, -1, 11,  3,  2, -3,  3,  0,
+  4, -1, 13, -1, 11,  2,  3, -2,  5,  0,
+  3,  2, 10, -1, 13,  1, 14,  0,
+  4, -2, 10, -1, 11, 18,  2,-16,  3,  0,
+  6,  2, 10, -1, 13,  1, 11,  4,  3, -8,  4,  3,  5,  0,
+  3,  2, 10, -1, 13,  1, 11,  0,
+  6, -2, 10,  1, 13, -1, 11,  4,  3, -8,  4,  3,  5,  0,
+  5,  2, 10, -2, 13,  1, 11, 18,  2,-16,  3,  0,
+  4, -2, 10,  1, 13, -2, 11,  1, 14,  0,
+  3,  1, 12, -3, 13,  1, 11,  0,
+  3,  1, 10,  2, 13, -1, 11,  0,
+  4,  2, 10,  1, 12,  1, 13, -1, 11,  1,
+  3,  1, 12, -1, 13, -1, 11,  1,
+  4, -1, 13, -1, 11,  1,  3, -1,  5,  0,
+  2,  1, 10,  1, 11,  0,
+  4,  2, 10,  1, 12, -1, 13,  1, 11,  1,
+  3,  1, 12,  1, 13, -3, 11,  0,
+  4, -1, 13, -1, 11,  1,  2, -1,  3,  0,
+  5,  2, 10, -1, 13,  1, 11,  2,  2, -2,  3,  0,
+  2,  3, 13, -1, 11,  0,
+  4,  1, 10,  1, 12, -2, 13, -1, 11,  0,
+  4,  2, 10,  2, 12,  1, 13, -1, 11,  0,
+  2,  1, 13,  1, 14,  1,
+  5,  2, 10, -1, 13,  1, 11,  2,  3, -3,  5,  0,
+  4, -2, 13, -1, 11, 18,  2,-16,  3,  1,
+  5,  1, 13,  1, 11,  4,  3, -8,  4,  3,  5,  0,
+  2,  1, 13,  1, 11,  0,
+  5, -1, 13, -1, 11,  4,  3, -8,  4,  3,  5,  0,
+  3,  1, 11, 18,  2,-16,  3,  1,
+  3, -1, 13, -2, 11,  1, 14,  0,
+  5,  2, 10, -1, 13,  1, 11,  2,  3, -2,  5,  0,
+  5,  2, 10, -1, 13,  1, 11,  3,  2, -3,  3,  0,
+  3,  1, 10,  1, 12,  1, 11,  1,
+  4,  2, 10,  2, 12, -1, 13,  1, 11,  1,
+  2,  1, 13, -3, 11,  0,
+  4,  1, 13,  1, 11,  1,  2, -1,  3,  0,
+  3,  1, 12,  3, 13, -1, 11,  0,
+  4,  2, 10,  1, 12, -3, 13, -1, 11,  0,
+  3,  1, 10, -2, 13, -1, 11,  0,
+  4,  1, 13,  1, 11,  1,  3, -1,  5,  0,
+  3,  1, 12,  1, 13,  1, 11,  1,
+  2,  1, 10, -3, 11,  0,
+  3,  1, 12, -1, 13,  3, 11,  0,
+  3,  2, 10, -3, 13, -1, 11,  0,
+  3,  2, 12,  1, 13,  1, 11,  0,
+  3,  2, 10, -1, 13, -3, 11,  0,
+  4,  2, 10, -1, 12, -3, 13, -1, 11,  0,
+  4,  2, 10, -1, 12, -1, 13, -3, 11,  0,
+  4,  6, 10, -1, 12, -2, 13, -1, 11,  0,
+  3,  4, 10, -2, 12, -1, 11,  0,
+  3,  6, 10, -2, 13, -1, 11,  0,
+  4,  4, 10, -2, 12, -2, 13,  1, 11,  0,
+  3,  4, 10, -1, 12, -1, 11,  1,
+  3,  2, 10, -3, 12,  1, 11,  0,
+  3,  5, 10, -1, 13, -1, 11,  0,
+  4,  4, 10, -1, 12, -2, 13,  1, 11,  0,
+  4,  2, 10, -2, 12,  2, 13, -1, 11,  0,
+  2,  4, 10, -1, 11,  0,
+  3,  2, 10, -2, 12,  1, 11,  1,
+  4,  3, 10, -1, 12, -1, 13,  1, 11,  0,
+  3,  4, 10, -2, 13,  1, 11,  0,
+  4,  2, 10, -1, 12,  2, 13, -1, 11,  0,
+  4, -2, 10, -1, 11,  2,  2, -2,  3,  0,
+  3,  3, 10,  1, 13, -1, 11,  0,
+  3,  4, 10,  1, 12, -1, 11,  0,
+  3,  2, 10, -1, 12,  1, 11,  2,
+  4, -2, 10, -1, 11,  1,  3, -1,  5,  0,
+  3,  3, 10, -1, 13,  1, 11,  0,
+  4,  4, 10,  1, 12, -2, 13,  1, 11,  0,
+  3,  2, 10,  2, 13, -1, 11,  0,
+  3,  2, 12, -2, 13, -1, 11,  0,
+  4,  1, 10, -1, 12,  1, 13,  1, 11,  0,
+  2,  2, 10,  1, 14,  0,
+  5, -2, 10, -1, 13, -1, 11, 18,  2,-16,  3,  0,
+  2,  2, 10,  1, 11,  1,
+  5,  2, 10, -1, 13,  1, 11, 18,  2,-16,  3,  0,
+  3, -2, 10, -2, 11,  1, 14,  0,
+  4,  3, 10,  1, 12, -1, 13,  1, 11,  0,
+  3,  2, 10, -2, 13,  3, 11,  0,
+  4,  2, 10,  1, 12,  2, 13, -1, 11,  0,
+  3,  1, 12, -2, 13, -1, 11,  1,
+  3,  1, 10,  1, 13,  1, 11,  0,
+  3,  2, 10,  1, 12,  1, 11,  1,
+  2,  4, 13, -1, 11,  0,
+  2,  2, 13,  1, 14,  0,
+  4, -3, 13, -1, 11, 18,  2,-16,  3,  0,
+  2,  2, 13,  1, 11,  0,
+  4,  1, 13,  1, 11, 18,  2,-16,  3,  0,
+  4,  2, 10,  1, 11,  2,  3, -2,  5,  0,
+  4,  1, 10,  1, 12,  1, 13,  1, 11,  0,
+  3,  2, 10,  2, 12,  1, 11,  0,
+  2,  2, 11,  1, 14,  0,
+  1,  3, 11,  0,
+  3,  1, 10, -3, 13, -1, 11,  0,
+  3,  1, 12,  2, 13,  1, 11,  1,
+  2,  1, 12,  3, 11,  0,
+  3,  2, 10, -4, 13, -1, 11,  0,
+  3,  2, 12,  2, 13,  1, 11,  0,
+  3,  2, 10, -2, 13, -3, 11,  0,
+  4,  6, 10, -1, 12, -1, 13, -1, 11,  0,
+  3,  6, 10, -1, 13, -1, 11,  0,
+  4,  4, 10, -2, 12, -1, 13,  1, 11,  0,
+  3,  6, 10, -3, 13,  1, 11,  0,
+  4,  4, 10, -1, 12,  1, 13, -1, 11,  0,
+  4,  4, 10, -1, 12, -1, 13,  1, 11,  1,
+  3,  5, 10, -2, 13,  1, 11,  0,
+  3,  4, 10,  1, 13, -1, 11,  0,
+  4,  2, 10, -2, 12,  1, 13,  1, 11,  0,
+  3,  4, 10, -1, 13,  1, 11,  0,
+  4,  2, 10, -1, 12,  3, 13, -1, 11,  0,
+  4,  4, 10,  1, 12,  1, 13, -1, 11,  0,
+  4,  2, 10, -1, 12,  1, 13,  1, 11,  1,
+  2,  3, 10,  1, 11,  0,
+  4,  4, 10,  1, 12, -1, 13,  1, 11,  0,
+  4,  2, 10, -1, 12, -1, 13,  3, 11,  0,
+  3,  2, 10,  3, 13, -1, 11,  0,
+  3,  2, 10,  1, 13,  1, 14,  0,
+  3,  2, 10,  1, 13,  1, 11,  0,
+  3,  3, 10,  1, 12,  1, 11,  0,
+  3,  2, 10, -1, 13,  3, 11,  0,
+  4,  2, 10,  1, 12,  3, 13, -1, 11,  0,
+  3,  1, 12, -3, 13, -1, 11,  0,
+  3,  1, 10,  2, 13,  1, 11,  0,
+  4,  2, 10,  1, 12,  1, 13,  1, 11,  1,
+  3,  1, 12, -1, 13, -3, 11,  0,
+  2,  1, 10,  3, 11,  0,
+  2,  5, 13, -1, 11,  0,
+  2,  3, 13,  1, 11,  0,
+  4,  1, 10,  1, 12,  2, 13,  1, 11,  0,
+  2,  1, 13,  3, 11,  0,
+  3,  1, 12,  3, 13,  1, 11,  0,
+  3,  1, 12,  1, 13,  3, 11,  0,
+  3,  2, 10, -5, 13, -1, 11,  0,
+  3,  6, 10, -1, 12, -1, 11,  0,
+  4,  6, 10, -1, 12, -2, 13,  1, 11,  0,
+  2,  6, 10, -1, 11,  0,
+  3,  4, 10, -2, 12,  1, 11,  0,
+  3,  6, 10, -2, 13,  1, 11,  0,
+  4,  4, 10, -1, 12,  2, 13, -1, 11,  0,
+  3,  4, 10, -1, 12,  1, 11,  0,
+  3,  4, 10,  2, 13, -1, 11,  0,
+  4,  2, 10, -2, 12,  2, 13,  1, 11,  0,
+  2,  4, 10,  1, 11,  0,
+  3,  4, 10, -2, 13,  3, 11,  0,
+  4,  2, 10, -1, 12,  2, 13,  1, 11,  0,
+  3,  3, 10,  1, 13,  1, 11,  0,
+  3,  4, 10,  1, 12,  1, 11,  0,
+  3,  2, 10, -1, 12,  3, 11,  0,
+  3,  2, 10,  4, 13, -1, 11,  0,
+  3,  2, 10,  2, 13,  1, 11,  0,
+  2,  2, 10,  3, 11,  0,
+  3,  1, 12, -4, 13, -1, 11,  0,
+  3,  1, 10,  3, 13,  1, 11,  0,
+  4,  2, 10,  1, 12,  2, 13,  1, 11,  0,
+  2,  4, 13,  1, 11,  0,
+  2,  2, 13,  3, 11,  0,
+  1,  5, 11,  0,
+  3,  1, 12,  4, 13,  1, 11,  0,
+  4,  6, 10, -1, 12, -1, 13,  1, 11,  0,
+  3,  6, 10,  1, 13, -1, 11,  0,
+  3,  6, 10, -1, 13,  1, 11,  0,
+  4,  4, 10, -1, 12,  1, 13,  1, 11,  0,
+  3,  4, 10,  1, 13,  1, 11,  0,
+  3,  4, 10, -1, 13,  3, 11,  0,
+  4,  2, 10, -1, 12,  3, 13,  1, 11,  0,
+  4,  4, 10,  1, 12,  1, 13,  1, 11,  0,
+  3,  2, 10,  3, 13,  1, 11,  0,
+  3,  2, 10,  1, 13,  3, 11,  0,
+  2,  5, 13,  1, 11,  0,
+  2,  3, 13,  3, 11,  0,
+  2,  6, 10,  1, 11,  0,
+  3,  4, 10,  2, 13,  1, 11,  0,
+  3,  2, 10,  4, 13,  1, 11,  0,
+ -1
+};
+struct plantbl moonlr = {
+  {  3, 26, 29, 23,  5, 10,  0,  0,  0,  8,  4,  4,  6,  2,  0,  0,  0,  0,},
+ 3,
+ lrargs,
+ lrtabl,
+ lrtabb,
+ lrtabr,
+ 2.5735686895300000e-03,
+ 3.6525000000000000e+06,
+ 1.0000000000000000e-04,
+};
+
+struct plantbl moonlat = {
+  {  0, 26, 29,  8,  3,  5,  0,  0,  0,  6,  5,  3,  5,  1,  0,  0,  0,  0,},
+ 3,
+ bargs,
+ btabl,
+ btabb,
+ btabr,
+ 0.0000000000000000e+00,
+ 3.6525000000000000e+06,
+ 1.0000000000000000e-04,
+};
+
+
+/* Reduce arc seconds modulo 360 degrees
+   answer in arc seconds  */
+static double
+mods3600(x)
+     double x;
+{
+  double y;
+#if !defined(__STDC__)
+  double floor();
+#endif
+
+  y = x - 1296000. * floor( x/1296000.);
+  return(y);
+}
+
+
+/* Time argument is Julian ephemeris date.  */
+
+static void
+mean_elements (JED)
+     double JED;
+{
+  double x, T, T2;
+
+  /* Time variables.  T is in Julian centuries.  */
+  T = (JED - MOSHIER_J2000) / 36525.0;
+  T2 = T*T;
+
+  /* Mean longitudes of planets (Simon et al, 1994)
+     .047" subtracted from constant term for offset to DE403 origin. */
+
+  /* Mercury */
+  x = mods3600( 538101628.6889819 * T + 908103.213 );
+  x += (6.39e-6 * T
+	 - 0.0192789) * T2;
+  Args[0] = x;
+
+  /* Venus */
+  x = mods3600( 210664136.4335482 * T + 655127.236 );
+  x += (-6.27e-6  * T
+	 + 0.0059381) * T2;
+  Args[1] = x;
+
+  /* Earth  */
+  x = mods3600( 129597742.283429 * T + 361679.198 );
+  x += (-5.23e-6 * T
+	 - 2.04411e-2 ) * T2;
+  Ea_arcsec = x;
+  Args[2] = x;
+
+  /* Mars */
+  x = mods3600(  68905077.493988 * T +  1279558.751 );
+  x += (-1.043e-5 * T
+	 + 0.0094264) * T2;
+  Args[3] = x;
+
+  /* Jupiter */
+  x = mods3600( 10925660.377991 * T + 123665.420 );
+  x += ((((-3.4e-10 * T
+	    + 5.91e-8) * T
+	   + 4.667e-6) * T
+	  + 5.706e-5) * T
+         - 3.060378e-1)*T2;
+  Args[4] = x;
+
+   /* Saturn */
+  x = mods3600( 4399609.855372 * T + 180278.752 );
+  x += (((( 8.3e-10 * T
+	  - 1.452e-7) * T
+	  - 1.1484e-5) * T
+	   - 1.6618e-4) * T
+	 + 7.561614E-1)*T2;
+  Args[5] = x;
+
+  /* Uranus */
+  x = mods3600( 1542481.193933 * T + 1130597.971 )
+       + (0.00002156*T - 0.0175083)*T2;
+  Args[6] = x;
+
+  /* Neptune */
+  x = mods3600( 786550.320744 * T + 1095655.149 )
+       + (-0.00000895*T + 0.0021103)*T2;
+  Args[7] = x;
+
+  /* Copied from cmoon.c, DE404 version.  */
+  /* Mean elongation of moon = D */
+  x = mods3600( 1.6029616009939659e+09 * T + 1.0722612202445078e+06 );
+  x += (((((-3.207663637426e-013 * T
+	       + 2.555243317839e-011) * T
+	      + 2.560078201452e-009) * T
+	     - 3.702060118571e-005) * T
+            + 6.9492746836058421e-03) * T /* D, t^3 */
+           - 6.7352202374457519e+00) * T2; /* D, t^2 */
+  Args[9] = x;
+
+  /* Mean distance of moon from its ascending node = F */
+  x = mods3600( 1.7395272628437717e+09 * T + 3.3577951412884740e+05 );
+  x += ((((( 4.474984866301e-013 * T
+	       + 4.189032191814e-011) * T
+	       - 2.790392351314e-009) * T
+	      - 2.165750777942e-006) * T
+	      - 7.5311878482337989e-04) * T /* F, t^3 */
+	     - 1.3117809789650071e+01) * T2; /* F, t^2 */
+  NF_arcsec = x;
+  Args[10] = x;
+
+/* Mean anomaly of sun = l' (J. Laskar) */
+  x = mods3600(1.2959658102304320e+08 * T + 1.2871027407441526e+06);
+  x += ((((((((
+	       1.62e-20 * T
+	       - 1.0390e-17 ) * T
+	      - 3.83508e-15 ) * T
+	     + 4.237343e-13 ) * T
+	    + 8.8555011e-11 ) * T
+	   - 4.77258489e-8 ) * T
+	  - 1.1297037031e-5 ) * T
+	 + 8.7473717367324703e-05) * T
+	- 5.5281306421783094e-01) * T2;
+  Args[11] = x;
+
+  /* Mean anomaly of moon = l */
+  x = mods3600( 1.7179159228846793e+09 * T + 4.8586817465825332e+05 );
+  x += (((((-1.755312760154e-012) * T
+		+ 3.452144225877e-011 * T
+		- 2.506365935364e-008) * T
+	       - 2.536291235258e-004) * T
+              + 5.2099641302735818e-02) * T /* l, t^3 */
+             + 3.1501359071894147e+01) * T2; /* l, t^2 */
+  Args[12] = x;
+
+  /* Mean longitude of moon, re mean ecliptic and equinox of date = L  */
+  x = mods3600( 1.7325643720442266e+09 * T + 7.8593980921052420e+05);
+  x += ((((( 7.200592540556e-014 * T
+	     + 2.235210987108e-010) * T
+	    - 1.024222633731e-008) * T
+	   - 6.073960534117e-005) * T
+	 + 6.9017248528380490e-03) * T /* L, t^3 */
+	- 5.6550460027471399e+00) * T2; /* L, t^2 */
+  LP_equinox = x;
+  Args[13] = x;
+
+  /* Precession of the equinox  */
+ x = ((((((((( -8.66e-20*T - 4.759e-17)*T
+           + 2.424e-15)*T
+           + 1.3095e-12)*T
+           + 1.7451e-10)*T
+           - 1.8055e-8)*T
+           - 0.0000235316)*T
+           + 0.000076)*T
+           + 1.105414)*T
+           + 5028.791959)*T;
+  /* Moon's longitude re fixed J2000 equinox.  */
+ /*
+   Args[13] -= x;
+ */
+   pA_precession = x;
+
+  /*  OM = LP - NF; */
+
+  /* Free librations.  */
+  /*  LB 2.891725 years, psi amplitude 1.8" */
+  Args[14] = mods3600( 4.48175409e7 * T + 8.060457e5 );
+
+  /* 24.2 years */
+  Args[15] = mods3600(  5.36486787e6 * T - 391702.8 );
+
+#if 0
+  /* 27.34907 days */
+  Args[16] = mods3600( 1.7308227257e9 * T - 4.443583e5 );
+#endif
+  /* LA 74.7 years. */
+Args[17] = mods3600( 1.73573e6 * T );
+}
+
+
+/* Prepare lookup table of sin and cos ( i*Lj )
+ * for required multiple angles
+ */
+static int 
+sscc (k, arg, n)
+     int k;
+     double arg;
+     int n;
+{
+  double cu, su, cv, sv, s;
+  int i;
+
+  s = STR * arg;
+  su = sin (s);
+  cu = cos (s);
+  ss[k][0] = su;		/* sin(L) */
+  cc[k][0] = cu;		/* cos(L) */
+  sv = 2.0 * su * cu;
+  cv = cu * cu - su * su;
+  ss[k][1] = sv;		/* sin(2L) */
+  cc[k][1] = cv;
+  for (i = 2; i < n; i++)
+    {
+      s = su * cv + cu * sv;
+      cv = cu * cv - su * sv;
+      sv = s;
+      ss[k][i] = sv;		/* sin( i+1 L ) */
+      cc[k][i] = cv;
+    }
+  return (0);
+}
+
+/* Generic program to accumulate sum of trigonometric series
+   in two variables (e.g., longitude, radius)
+   of the same list of arguments.  */
+static int 
+g2plan (J, plan, pobj, flag)
+     double J;
+     struct plantbl *plan;
+     double pobj[];
+     int flag;
+{
+  int i, j, k, m, k1, ip, np, nt;
+  /* On some systems such as Silicon Graphics, char is unsigned
+     by default.  */
+  CHAR *p;
+  long *pl, *pr;
+  double su, cu, sv, cv;
+  double t, sl, sr;
+
+  mean_elements (J);
+  /* For librations, moon's longitude is sidereal.  */
+  if (flag)
+    Args[13] -= pA_precession;
+
+  T = (J - MOSHIER_J2000) / plan->timescale;
+  /* Calculate sin( i*MM ), etc. for needed multiple angles.  */
+  for (i = 0; i < NARGS; i++)
+    {
+      if ((j = plan->max_harmonic[i]) > 0)
+	{
+	  sscc (i, Args[i], j);
+	}
+    }
+
+  /* Point to start of table of arguments. */
+  p = plan->arg_tbl;
+  /* Point to tabulated cosine and sine amplitudes.  */
+  pl = plan->lon_tbl;
+  pr = plan->rad_tbl;
+  sl = 0.0;
+  sr = 0.0;
+
+  for (;;)
+    {
+      /* argument of sine and cosine */
+      /* Number of periodic arguments. */
+      np = *p++;
+      if (np < 0)
+	break;
+      if (np == 0)
+	{			/* It is a polynomial term.  */
+	  nt = *p++;
+	  /* Longitude polynomial. */
+	  cu = *pl++;
+	  for (ip = 0; ip < nt; ip++)
+	    {
+	      cu = cu * T + *pl++;
+	    }
+	  /*	  sl +=  mods3600 (cu); */
+	  sl += cu;
+	  /* Radius polynomial. */
+	  cu = *pr++;
+	  for (ip = 0; ip < nt; ip++)
+	    {
+	      cu = cu * T + *pr++;
+	    }
+	  sr += cu;
+	  continue;
+	}
+      k1 = 0;
+      cv = 0.0;
+      sv = 0.0;
+      for (ip = 0; ip < np; ip++)
+	{
+	  /* What harmonic.  */
+	  j = *p++;
+	  /* Which planet.  */
+	  m = *p++ - 1;
+	  if (j)
+	    {
+	      k = abs (j);
+	      k -= 1;
+	      su = ss[m][k];	/* sin(k*angle) */
+	      if (j < 0)
+		su = -su;
+	      cu = cc[m][k];
+	      if (k1 == 0)
+		{		/* set first angle */
+		  sv = su;
+		  cv = cu;
+		  k1 = 1;
+		}
+	      else
+		{		/* combine angles */
+		  t = su * cv + cu * sv;
+		  cv = cu * cv - su * sv;
+		  sv = t;
+		}
+	    }
+	}
+      /* Highest power of T.  */
+      nt = *p++;
+      /* Longitude. */
+      cu = *pl++;
+      su = *pl++;
+      for (ip = 0; ip < nt; ip++)
+	{
+	  cu = cu * T + *pl++;
+	  su = su * T + *pl++;
+	}
+      sl += cu * cv + su * sv;
+      /* Radius. */
+      cu = *pr++;
+      su = *pr++;
+      for (ip = 0; ip < nt; ip++)
+	{
+	  cu = cu * T + *pr++;
+	  su = su * T + *pr++;
+	}
+      sr += cu * cv + su * sv;
+    }
+  t = plan->trunclvl;
+  pobj[0] = t * sl;
+  pobj[2] = t * sr;
+  return (0);
+}
+
+
+
+/* Generic program to accumulate sum of trigonometric series
+   in one variable.  */
+
+static double
+g1plan (J, plan)
+     double J;
+     struct plantbl *plan;
+{
+  int i, j, k, m, k1, ip, np, nt;
+  /* On some systems such as Silicon Graphics, char is unsigned
+     by default.  */
+  CHAR *p;
+  long *pl;
+  double su, cu, sv, cv;
+  double t, sl;
+
+  T = (J - MOSHIER_J2000) / plan->timescale;
+  mean_elements (J);
+  /* Calculate sin( i*MM ), etc. for needed multiple angles.  */
+  for (i = 0; i < NARGS; i++)
+    {
+      if ((j = plan->max_harmonic[i]) > 0)
+	{
+	  sscc (i, Args[i], j);
+	}
+    }
+
+  /* Point to start of table of arguments. */
+  p = plan->arg_tbl;
+  /* Point to tabulated cosine and sine amplitudes.  */
+  pl = plan->lon_tbl;
+  sl = 0.0;
+
+  for (;;)
+    {
+      /* argument of sine and cosine */
+      /* Number of periodic arguments. */
+      np = *p++;
+      if (np < 0)
+	break;
+      if (np == 0)
+	{			/* It is a polynomial term.  */
+	  nt = *p++;
+	  cu = *pl++;
+	  for (ip = 0; ip < nt; ip++)
+	    {
+	      cu = cu * T + *pl++;
+	    }
+	  /*	  sl +=  mods3600 (cu); */
+	  sl += cu;
+	  continue;
+	}
+      k1 = 0;
+      cv = 0.0;
+      sv = 0.0;
+      for (ip = 0; ip < np; ip++)
+	{
+	  /* What harmonic.  */
+	  j = *p++;
+	  /* Which planet.  */
+	  m = *p++ - 1;
+	  if (j)
+	    {
+	      k = abs (j);
+	      k -= 1;
+	      su = ss[m][k];	/* sin(k*angle) */
+	      if (j < 0)
+		su = -su;
+	      cu = cc[m][k];
+	      if (k1 == 0)
+		{		/* set first angle */
+		  sv = su;
+		  cv = cu;
+		  k1 = 1;
+		}
+	      else
+		{		/* combine angles */
+		  t = su * cv + cu * sv;
+		  cv = cu * cv - su * sv;
+		  sv = t;
+		}
+	    }
+	}
+      /* Highest power of T.  */
+      nt = *p++;
+      /* Cosine and sine coefficients.  */
+      cu = *pl++;
+      su = *pl++;
+      for (ip = 0; ip < nt; ip++)
+	{
+	  cu = cu * T + *pl++;
+	  su = su * T + *pl++;
+	}
+      sl += cu * cv + su * sv;
+    }
+  return (plan->trunclvl * sl);
+}
+
+
+/* geocentric moon, mean ecliptic and equinox of date
+ * J is Julian Epemeris Date
+ * output in pobj[]:
+ * pobj[0]:  l in rad
+ * pobj[1]:  b in rad
+ * pobj[2]:  r in au
+ */
+static int 
+gecmoon (J, lrtab, lattab, pobj)
+     double J;
+     struct plantbl *lrtab, *lattab;
+     double pobj[];
+{
+  double x;
+
+  g2plan (J, lrtab, pobj, 0);
+  x = pobj[0];
+  x += LP_equinox;
+  if (x < -6.45e5)
+    x += 1.296e6;
+  if (x > 6.45e5)
+    x -= 1.296e6;
+  pobj[0] = STR * x;
+  x = g1plan (J, lattab);
+  pobj[1] = STR * x;
+  pobj[2] = (STR * pobj[2] + 1.0) * lrtab->distance;
+  return 0;
+}
+
+/*********** end stephen moshier's moon code ****************/
+
+static void moon_fast P_((double mjd, double *lam, double *bet,
+	double *hp, double *msp, double *mdp));
+
+/* previous version (elwood):
+ *
+ * given the mjd, find the geocentric ecliptic longitude, lam, and latitude,
+ *   bet, and horizontal parallax, hp for the moon. also return the sun's
+ *   mean anomaly, *msp, and the moon's mean anomaly, *mdp.
+ * N.B. series for long and lat are good to about 10 and 3 arcseconds. however,
+ *   math errors cause up to 100 and 30 arcseconds error, even if use double.
+ *   why?? suspect highly sensitive nature of difference used to get m1..6.
+ * N.B. still need to correct for nutation. then for topocentric location
+ *   further correct for parallax and refraction.
+ */
+static void
+moon_fast (mjd, lam, bet, hp, msp, mdp)
+double mjd;
+double *lam, *bet, *hp;
+double *msp, *mdp;
+{
+	double t, t2;
+	double ld;
+	double ms;
+	double md;
+	double de;
+	double f;
+	double n;
+	double a, sa, sn, b, sb, c, sc, e, e2, l, g, w1, w2;
+	double m1, m2, m3, m4, m5, m6;
+
+	t = mjd/36525.;
+	t2 = t*t;
+
+	m1 = mjd/27.32158213;
+	m1 = 360.0*(m1-(long)m1);
+	m2 = mjd/365.2596407;
+	m2 = 360.0*(m2-(long)m2);
+	m3 = mjd/27.55455094;
+	m3 = 360.0*(m3-(long)m3);
+	m4 = mjd/29.53058868;
+	m4 = 360.0*(m4-(long)m4);
+	m5 = mjd/27.21222039;
+	m5 = 360.0*(m5-(long)m5);
+	m6 = mjd/6798.363307;
+	m6 = 360.0*(m6-(long)m6);
+
+	ld = 270.434164+m1-(.001133-.0000019*t)*t2;
+	ms = 358.475833+m2-(.00015+.0000033*t)*t2;
+	md = 296.104608+m3+(.009192+.0000144*t)*t2;
+	de = 350.737486+m4-(.001436-.0000019*t)*t2;
+	f = 11.250889+m5-(.003211+.0000003*t)*t2;
+	n = 259.183275-m6+(.002078+.000022*t)*t2;
+
+	a = degrad(51.2+20.2*t);
+	sa = sin(a);
+	sn = sin(degrad(n));
+	b = 346.56+(132.87-.0091731*t)*t;
+	sb = .003964*sin(degrad(b));
+	c = degrad(n+275.05-2.3*t);
+	sc = sin(c);
+	ld = ld+.000233*sa+sb+.001964*sn;
+	ms = ms-.001778*sa;
+	md = md+.000817*sa+sb+.002541*sn;
+	f = f+sb-.024691*sn-.004328*sc;
+	de = de+.002011*sa+sb+.001964*sn;
+	e = 1-(.002495+7.52e-06*t)*t;
+	e2 = e*e;
+
+	ld = degrad(ld);
+	ms = degrad(ms);
+	n = degrad(n);
+	de = degrad(de);
+	f = degrad(f);
+	md = degrad(md);
+
+	l = 6.28875*sin(md)+1.27402*sin(2*de-md)+.658309*sin(2*de)+
+	    .213616*sin(2*md)-e*.185596*sin(ms)-.114336*sin(2*f)+
+	    .058793*sin(2*(de-md))+.057212*e*sin(2*de-ms-md)+
+	    .05332*sin(2*de+md)+.045874*e*sin(2*de-ms)+.041024*e*sin(md-ms);
+	l = l-.034718*sin(de)-e*.030465*sin(ms+md)+.015326*sin(2*(de-f))-
+	    .012528*sin(2*f+md)-.01098*sin(2*f-md)+.010674*sin(4*de-md)+
+	    .010034*sin(3*md)+.008548*sin(4*de-2*md)-e*.00791*sin(ms-md+2*de)-
+	    e*.006783*sin(2*de+ms);
+	l = l+.005162*sin(md-de)+e*.005*sin(ms+de)+.003862*sin(4*de)+
+	    e*.004049*sin(md-ms+2*de)+.003996*sin(2*(md+de))+
+	    .003665*sin(2*de-3*md)+e*.002695*sin(2*md-ms)+
+	    .002602*sin(md-2*(f+de))+e*.002396*sin(2*(de-md)-ms)-
+	    .002349*sin(md+de);
+	l = l+e2*.002249*sin(2*(de-ms))-e*.002125*sin(2*md+ms)-
+	    e2*.002079*sin(2*ms)+e2*.002059*sin(2*(de-ms)-md)-
+	    .001773*sin(md+2*(de-f))-.001595*sin(2*(f+de))+
+	    e*.00122*sin(4*de-ms-md)-.00111*sin(2*(md+f))+.000892*sin(md-3*de);
+	l = l-e*.000811*sin(ms+md+2*de)+e*.000761*sin(4*de-ms-2*md)+
+	     e2*.000704*sin(md-2*(ms+de))+e*.000693*sin(ms-2*(md-de))+
+	     e*.000598*sin(2*(de-f)-ms)+.00055*sin(md+4*de)+.000538*sin(4*md)+
+	     e*.000521*sin(4*de-ms)+.000486*sin(2*md-de);
+	l = l+e2*.000717*sin(md-2*ms);
+	*lam = ld+degrad(l);
+	range (lam, 2*PI);
+
+	g = 5.12819*sin(f)+.280606*sin(md+f)+.277693*sin(md-f)+
+	    .173238*sin(2*de-f)+.055413*sin(2*de+f-md)+.046272*sin(2*de-f-md)+
+	    .032573*sin(2*de+f)+.017198*sin(2*md+f)+.009267*sin(2*de+md-f)+
+	    .008823*sin(2*md-f)+e*.008247*sin(2*de-ms-f);
+	g = g+.004323*sin(2*(de-md)-f)+.0042*sin(2*de+f+md)+
+	    e*.003372*sin(f-ms-2*de)+e*.002472*sin(2*de+f-ms-md)+
+	    e*.002222*sin(2*de+f-ms)+e*.002072*sin(2*de-f-ms-md)+
+	    e*.001877*sin(f-ms+md)+.001828*sin(4*de-f-md)-e*.001803*sin(f+ms)-
+	    .00175*sin(3*f);
+	g = g+e*.00157*sin(md-ms-f)-.001487*sin(f+de)-e*.001481*sin(f+ms+md)+
+	     e*.001417*sin(f-ms-md)+e*.00135*sin(f-ms)+.00133*sin(f-de)+
+	     .001106*sin(f+3*md)+.00102*sin(4*de-f)+.000833*sin(f+4*de-md)+
+	     .000781*sin(md-3*f)+.00067*sin(f+4*de-2*md);
+	g = g+.000606*sin(2*de-3*f)+.000597*sin(2*(de+md)-f)+
+	    e*.000492*sin(2*de+md-ms-f)+.00045*sin(2*(md-de)-f)+
+	    .000439*sin(3*md-f)+.000423*sin(f+2*(de+md))+
+	    .000422*sin(2*de-f-3*md)-e*.000367*sin(ms+f+2*de-md)-
+	    e*.000353*sin(ms+f+2*de)+.000331*sin(f+4*de);
+	g = g+e*.000317*sin(2*de+f-ms+md)+e2*.000306*sin(2*(de-ms)-f)-
+	    .000283*sin(md+3*f);
+	w1 = .0004664*cos(n);
+	w2 = .0000754*cos(c);
+	*bet = degrad(g)*(1-w1-w2);
+
+	*hp = .950724+.051818*cos(md)+.009531*cos(2*de-md)+.007843*cos(2*de)+
+	      .002824*cos(2*md)+.000857*cos(2*de+md)+e*.000533*cos(2*de-ms)+
+	      e*.000401*cos(2*de-md-ms)+e*.00032*cos(md-ms)-.000271*cos(de)-
+	      e*.000264*cos(ms+md)-.000198*cos(2*f-md);
+	*hp = *hp+.000173*cos(3*md)+.000167*cos(4*de-md)-e*.000111*cos(ms)+
+	     .000103*cos(4*de-2*md)-.000084*cos(2*md-2*de)-
+	     e*.000083*cos(2*de+ms)+.000079*cos(2*de+2*md)+.000072*cos(4*de)+
+	     e*.000064*cos(2*de-ms+md)-e*.000063*cos(2*de+ms-md)+
+	     e*.000041*cos(ms+de);
+	*hp = *hp+e*.000035*cos(2*md-ms)-.000033*cos(3*md-2*de)-
+	     .00003*cos(md+de)-.000029*cos(2*(f-de))-e*.000029*cos(2*md+ms)+
+	     e2*.000026*cos(2*(de-ms))-.000023*cos(2*(f-de)+md)+
+	     e*.000019*cos(4*de-ms-md);
+	*hp = degrad(*hp);
+
+	*msp = ms;
+	*mdp = md;
+}
+
+
+#define EarthRadius 6378.16             /* Kilometers           */
+
+/* moon() - front end rountine to get moon position; stern
+ *
+ * given the mjd, find the geocentric ecliptic longitude, lam, and latitude,
+ *   bet, and geocentric distance, rho in a.u. for the moon.  also return
+ *   the sun's mean anomaly, *msp, and the moon's mean anomaly, *mdp.
+ *
+ * now uses Stephen Moshier's expansion and code.
+ *
+ * TODO: - clarify lunar aberration for apparent places
+ * 
+ * still need to correct for nutation. then for topocentric location
+ *   further correct for parallax and refraction.
+ * NB:  Do NOT correct for aberration - the geocentric moon frame moves
+ *	along with the earth.
+ */
+void
+moon (mjd, lam, bet, rho, msp, mdp)
+double mjd;
+double *lam, *bet, *rho;
+double *msp, *mdp;
+{
+	double pobj[3], dt;
+	double hp;
+
+	if (mjd >= MOSHIER_BEGIN && mjd <= MOSHIER_END) {
+		/* retard for light time */
+		moon_fast (mjd, lam, bet, &hp, msp, mdp);
+		*rho = EarthRadius/AUKM/sin(hp);
+		dt = *rho * 5.7755183e-3;       /* speed of light in a.u/day */
+		gecmoon(mjd + MJD0 - dt, &moonlr, &moonlat, pobj);
+
+		*lam = pobj[0];
+		range (lam, 2*PI);
+		*bet = pobj[1];
+		*rho = pobj[2];
+		*msp = STR * Args[11];	/* don't need range correction here */
+		*mdp = STR * Args[12];
+	} else {
+		moon_fast (mjd, lam, bet, &hp, msp, mdp);
+		*rho = EarthRadius/AUKM/sin(hp);
+
+	}
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: moon.c,v $ $Date: 2001-10-22 12:08:27 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/mooncolong.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/mooncolong.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/mooncolong.c	(revision 2309)
@@ -0,0 +1,264 @@
+/* code to compute lunar sunrise position and local sun angle.
+ */
+
+#include <stdio.h>
+#include <math.h>
+#if defined(__STDC__)
+#include <stdlib.h>
+#endif
+
+#include "P_.h"
+#include "astro.h"
+
+static void Librations P_((double RAD, double LAMH, double BH, double OM,
+    double F, double L, double L1, double *L0, double *B0));
+static void Moon P_((double RAD, double T, double T2, double LAM0, double R,
+    double M, double *F, double *L1, double *OM, double *LAM, double *B,
+    double *DR, double *LAMH, double *BH));
+static void Sun P_((double RAD, double T, double T2, double *L, double *M,
+    double *R, double *LAM0));
+
+/* given a Julian date and a lunar location, find selenographic colongitude of
+ * rising sun, lunar latitude of subsolar point, illuminated fraction, and alt
+ * of sun at the given location. Any pointer may be 0 if not interested.
+ * From Bruning and Talcott, October 1995 _Astronomy_, page 76.
+ * N.B. lunar coordinates use +E, but selenograhic colongs are +W.
+ */
+void
+moon_colong (jd, lt, lg, cp, kp, ap, sp)
+double jd;	/* jd */
+double lt, lg;	/* lat/long of location on moon, rads +N +E */
+double *cp;	/* selenographic colongitude (-lng of rising sun), rads */
+double *kp;	/* illuminated fraction of surface from Earth */
+double *ap;	/* sun altitude at location, rads */
+double *sp;	/* lunar latitude of subsolar point, rads */
+{
+	double RAD = .0174533;
+	double T;
+	double T2;
+	double L, M, R, LAM0;
+	double F, L1, OM, LAM, B, DR, LAMH, BH;
+	double L0, B0;
+	double TEMP;
+	double C0;
+	double PSI;
+	double NUM, DEN;
+	double I, K;
+	double THETA, ETA;
+	double H;
+
+	T = (jd - 2451545)/36525.0;
+	T2 = T * T;
+
+	Sun(RAD, T, T2, &L, &M, &R, &LAM0);
+	Moon(RAD, T, T2, LAM0, R, M, &F, &L1, &OM, &LAM, &B, &DR, &LAMH, &BH);
+	Librations(RAD, LAMH, BH, OM, F, L, L1, &L0, &B0);
+	if (sp)
+	    *sp = B0;
+
+	TEMP = L0 / 360;
+	L0 = ((TEMP) - (int)(TEMP)) * 360;
+	if (L0 < 0) L0 = L0 + 360;
+	if (L0 <= 90) C0 = 90 - L0; else C0 = 450 - L0;
+	if (cp) {
+	    *cp = degrad(C0);
+	    range (cp, 2*PI);	/* prefer 0..360 +W */
+	}
+
+	if (kp) {
+	    TEMP = cos(B * RAD) * cos(LAM - LAM0 * RAD);
+	    PSI = acos(TEMP);
+	    NUM = R * sin(PSI);
+	    DEN = DR - R * TEMP;
+	    I = atan(NUM / DEN);
+	    if (NUM * DEN < 0) I = I + 3.14159;
+	    if (NUM < 0) I = I + 3.14159;
+	    K = (1 + cos(I)) / 2;
+	    *kp = K;
+	}
+
+	if (ap) {
+	    THETA = lt;
+	    ETA = lg;
+	    C0 = C0 * RAD;
+	    TEMP = sin(B0) * sin(THETA) + cos(B0) * cos(THETA) * sin(C0+ETA);
+	    H = asin(TEMP);
+	    *ap = H;
+	}
+}
+
+static void
+Librations (RAD, LAMH, BH, OM, F, L, L1, L0, B0)
+double RAD;
+double LAMH;
+double BH;
+double OM;
+double F;
+double L;
+double L1;
+double *L0;
+double *B0;
+{ 
+	double I, PSI, W, NUM, DEN, A, TEMP;
+
+	/* inclination of lunar equator */
+	I = 1.54242 * RAD;
+
+	/* nutation in longitude, in arcseconds */
+	PSI = -17.2 * sin(OM) - 1.32 * sin(2 * L) - .23 * sin(2 * L1) +
+							    .21 * sin(2 * OM);
+	PSI = PSI * RAD / 3600;
+
+	/* optical librations */
+	W = (LAMH - PSI) - OM;
+	NUM = sin(W) * cos(BH) * cos(I) - sin(BH) * sin(I);
+	DEN = cos(W) * cos(BH);
+	A = atan(NUM / DEN);
+	if (NUM * DEN < 0) A = A + 3.14159;
+	if (NUM < 0) A = A + 3.14159;
+	*L0 = (A - F) / RAD;
+	TEMP = -sin(W) * cos(BH) * sin(I) - sin(BH) * cos(I);
+	*B0 = asin(TEMP);
+}
+
+static void
+Moon (RAD, T, T2, LAM0, R, M, F, L1, OM, LAM, B, DR, LAMH, BH)
+double RAD;
+double T;
+double T2;
+double LAM0;
+double R;
+double M;
+double *F;
+double *L1;
+double *OM;
+double *LAM;
+double *B;
+double *DR;
+double *LAMH;
+double *BH;
+{
+	double T3, M1, D2, SUMR, SUML, DIST;
+
+	T3 = T * T2; 
+
+	/* argument of the latitude of the Moon */
+	*F = (93.2721 + 483202 * T - .003403 * T2 - T3 / 3526000) * RAD;
+
+	/* mean longitude of the Moon */
+	*L1 = (218.316 + 481268. * T) * RAD;
+	
+	/* longitude of the ascending node of Moon's mean orbit */
+	*OM = (125.045 - 1934.14 * T + .002071 * T2 + T3 / 450000) * RAD;
+	
+	/* Moon's mean anomaly */
+	M1 = (134.963 + 477199 * T + .008997 * T2 + T3 / 69700) * RAD;
+	
+	/* mean elongation of the Moon */
+	D2 = (297.85 + 445267 * T - .00163 * T2 + T3 / 545900) * 2 * RAD;
+
+	/* Lunar distance */
+	SUMR = -20954 * cos(M1) - 3699 * cos(D2 - M1) - 2956 * cos(D2);
+	*DR = 385000 + SUMR;
+	
+	/* geocentric latitude */
+	*B = 5.128 * sin(*F) + .2806 * sin(M1 + *F) + .2777 * sin(M1 - *F) +
+							.1732 * sin(D2 - *F);
+	SUML = 6.289 * sin(M1) + 1.274 * sin(D2 - M1) + .6583 * sin(D2) +
+		.2136 * sin(2 * M1) - .1851 * sin(M) - .1143 * sin(2 * *F);
+	*LAM = *L1 + SUML * RAD;
+	DIST = *DR / R;
+	*LAMH = (LAM0 + 180 + DIST * cos(*B) * sin(LAM0 * RAD - *LAM) / RAD)
+									* RAD;
+	*BH = DIST * *B * RAD;
+}
+
+static void
+Sun (RAD, T, T2, L, M, R, LAM0)
+double RAD;
+double T;
+double T2;
+double *L;
+double *M;
+double *R;
+double *LAM0;
+{
+	double T3, C, V, E, THETA, OM;
+
+	T3 = T2 * T;
+
+	/* mean longitude of the Sun */
+	*L = 280.466 + 36000.8 * T;
+
+	/* mean anomaly of the Sun */
+	*M = 357.529 + 35999 * T - .0001536 * T2 + T3 / 24490000;
+	*M = *M * RAD;
+
+	/* correction for Sun's elliptical orbit */
+	C = (1.915 - .004817 * T - .000014 * T2) * sin(*M) +
+		    (.01999 - .000101 * T) * sin(2 * *M) + .00029 * sin(3 * *M);
+
+	/* true anomaly of the Sun */
+	V = *M + C * RAD;
+
+	/* eccentricity of Earth's orbit */
+	E = .01671 - .00004204 * T - .0000001236 * T2;
+
+	/* Sun-Earth distance */
+	*R = .99972 / (1 + E * cos(V)) * 145980000;
+
+	/* true geometric longitude of the Sun */
+	THETA = *L + C;
+
+	/* apparent longitude of the Sun */
+	OM = 125.04 - 1934.1 * T;
+	*LAM0 = THETA - .00569 - .00478 * sin(OM * RAD);
+}
+
+#ifdef TESTCOLONG
+
+/* insure 0 <= *v < r.
+ */
+void
+range (v, r)
+double *v, r;
+{
+	*v -= r*floor(*v/r);
+}
+
+/* To be sure the program is functioning properly, try the test case
+ * 2449992.5 (1 Oct 1995): the colongitude should be 3.69 degrees.
+ */
+int
+main (int ac, char *av[])
+{
+	double jd, lt, lg;
+	double c, k, a;
+
+	if (ac != 2) {
+	    fprintf (stderr, "%s: JD\n", av[0]);
+	    exit (1);
+	}
+
+	jd = atof(av[1]);
+
+	printf ("Latitude of lunar feature: ");
+	fscanf (stdin, "%lf", &lt);
+	lt = degrad(lt);
+	printf ("Longitude:                 ");
+	fscanf (stdin, "%lf", &lg);
+	lg = degrad(lg);
+
+	moon_colong (jd, lt, lg, &c, &k, &a);
+
+	printf ("Selenographic colongitude is %g\n", raddeg(c));
+	printf ("The illuminated fraction of the Moon is %g\n", k);
+	printf ("Altitude of Sun above feature is %g\n", raddeg(a));
+
+	return (0);
+}
+
+#endif
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: mooncolong.c,v $ $Date: 2001-10-22 12:08:27 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/nutation.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/nutation.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/nutation.c	(revision 2309)
@@ -0,0 +1,442 @@
+/* nutation (in IAU (1980) expression) and abberation; stern
+ * on an HP PA processor, this reproduces the Almanac nutation values
+ * (given to 0.001") EXACTLY over 750 days (1995 and 1996)
+ */
+#include <math.h>
+
+#include "P_.h"
+#include "astro.h"
+
+#define NUT_SCALE	1e4
+#define NUT_SERIES	106
+#define NUT_MAXMUL	4
+#define SECPERCIRC	(3600.*360.)
+
+/* Delaunay arguments, in arc seconds; they differ slightly from ELP82B */
+static double delaunay[5][4] = {
+    {485866.733,  1717915922.633, 31.310,  0.064}, /* M', moon mean anom */
+    {1287099.804, 129596581.224,  -0.577, -0.012}, /* M, sun mean anom */
+    {335778.877,  1739527263.137, -13.257, 0.011}, /* F, moon arg lat */
+    {1072261.307, 1602961601.328, -6.891,  0.019}, /* D, elong moon sun */
+    {450160.280,  -6962890.539,   7.455,   0.008}, /* Om, moon l asc node */
+};
+
+/* multipliers for Delaunay arguments */
+static short multarg[NUT_SERIES][5] = {
+	/* bounds:  -2..3, -2..2, -2/0/2/4, -4..4, 0..2 */
+    {0, 0, 0, 0, 1},
+    {0, 0, 0, 0, 2},
+    {-2, 0, 2, 0, 1},
+    {2, 0, -2, 0, 0},
+    {-2, 0, 2, 0, 2},
+    {1, -1, 0, -1, 0},
+    {0, -2, 2, -2, 1},
+    {2, 0, -2, 0, 1},
+    {0, 0, 2, -2, 2},
+    {0, 1, 0, 0, 0},
+    {0, 1, 2, -2, 2},
+    {0, -1, 2, -2, 2},
+    {0, 0, 2, -2, 1},
+    {2, 0, 0, -2, 0},
+    {0, 0, 2, -2, 0},
+    {0, 2, 0, 0, 0},
+    {0, 1, 0, 0, 1},
+    {0, 2, 2, -2, 2},
+    {0, -1, 0, 0, 1},
+    {-2, 0, 0, 2, 1},
+    {0, -1, 2, -2, 1},
+    {2, 0, 0, -2, 1},
+    {0, 1, 2, -2, 1},
+    {1, 0, 0, -1, 0},
+    {2, 1, 0, -2, 0},
+    {0, 0, -2, 2, 1},
+    {0, 1, -2, 2, 0},
+    {0, 1, 0, 0, 2},
+    {-1, 0, 0, 1, 1},
+    {0, 1, 2, -2, 0},
+    {0, 0, 2, 0, 2},
+    {1, 0, 0, 0, 0},
+    {0, 0, 2, 0, 1},
+    {1, 0, 2, 0, 2},
+    {1, 0, 0, -2, 0},
+    {-1, 0, 2, 0, 2},
+    {0, 0, 0, 2, 0},
+    {1, 0, 0, 0, 1},
+    {-1, 0, 0, 0, 1},
+    {-1, 0, 2, 2, 2},
+    {1, 0, 2, 0, 1},
+    {0, 0, 2, 2, 2},
+    {2, 0, 0, 0, 0},
+    {1, 0, 2, -2, 2},
+    {2, 0, 2, 0, 2},
+    {0, 0, 2, 0, 0},
+    {-1, 0, 2, 0, 1},
+    {-1, 0, 0, 2, 1},
+    {1, 0, 0, -2, 1},
+    {-1, 0, 2, 2, 1},
+    {1, 1, 0, -2, 0},
+    {0, 1, 2, 0, 2},
+    {0, -1, 2, 0, 2},
+    {1, 0, 2, 2, 2},
+    {1, 0, 0, 2, 0},
+    {2, 0, 2, -2, 2},
+    {0, 0, 0, 2, 1},
+    {0, 0, 2, 2, 1},
+    {1, 0, 2, -2, 1},
+    {0, 0, 0, -2, 1},
+    {1, -1, 0, 0, 0},
+    {2, 0, 2, 0, 1},
+    {0, 1, 0, -2, 0},
+    {1, 0, -2, 0, 0},
+    {0, 0, 0, 1, 0},
+    {1, 1, 0, 0, 0},
+    {1, 0, 2, 0, 0},
+    {1, -1, 2, 0, 2},
+    {-1, -1, 2, 2, 2},
+    {-2, 0, 0, 0, 1},
+    {3, 0, 2, 0, 2},
+    {0, -1, 2, 2, 2},
+    {1, 1, 2, 0, 2},
+    {-1, 0, 2, -2, 1},
+    {2, 0, 0, 0, 1},
+    {1, 0, 0, 0, 2},
+    {3, 0, 0, 0, 0},
+    {0, 0, 2, 1, 2},
+    {-1, 0, 0, 0, 2},
+    {1, 0, 0, -4, 0},
+    {-2, 0, 2, 2, 2},
+    {-1, 0, 2, 4, 2},
+    {2, 0, 0, -4, 0},
+    {1, 1, 2, -2, 2},
+    {1, 0, 2, 2, 1},
+    {-2, 0, 2, 4, 2},
+    {-1, 0, 4, 0, 2},
+    {1, -1, 0, -2, 0},
+    {2, 0, 2, -2, 1},
+    {2, 0, 2, 2, 2},
+    {1, 0, 0, 2, 1},
+    {0, 0, 4, -2, 2},
+    {3, 0, 2, -2, 2},
+    {1, 0, 2, -2, 0},
+    {0, 1, 2, 0, 1},
+    {-1, -1, 0, 2, 1},
+    {0, 0, -2, 0, 1},
+    {0, 0, 2, -1, 2},
+    {0, 1, 0, 2, 0},
+    {1, 0, -2, -2, 0},
+    {0, -1, 2, 0, 1},
+    {1, 1, 0, -2, 1},
+    {1, 0, -2, 2, 0},
+    {2, 0, 0, 2, 0},
+    {0, 0, 2, 4, 2},
+    {0, 1, 0, 1, 0}
+};
+
+/* amplitudes which  have secular terms; in 1/NUT_SCALE arc seconds
+ * {index, constant dPSI, T/10 in dPSI, constant in dEPS, T/10 in dEPS}
+ */
+static long ampsecul[][5] = {
+    {0  ,-171996 ,-1742 ,92025 ,89},
+    {1  ,2062    ,2     ,-895  ,5},
+    {8  ,-13187  ,-16   ,5736  ,-31},
+    {9  ,1426    ,-34   ,54    ,-1},
+    {10 ,-517    ,12    ,224   ,-6},
+    {11 ,217     ,-5    ,-95   ,3},
+    {12 ,129     ,1     ,-70   ,0},
+    {15 ,17      ,-1    ,0     ,0},
+    {17 ,-16     ,1     ,7     ,0},
+    {30 ,-2274   ,-2    ,977   ,-5},
+    {31 ,712     ,1     ,-7    ,0},
+    {32 ,-386    ,-4    ,200   ,0},
+    {33 ,-301    ,0     ,129   ,-1},
+    {37 ,63      ,1     ,-33   ,0},
+    {38 ,-58     ,-1    ,32    ,0},
+    /* termination */  { -1, }
+};
+
+/* amplitudes which only have constant terms; same unit as above
+ * {dPSI, dEPS}
+ * indexes which are already in ampsecul[][] are zeroed
+ */
+static short ampconst[NUT_SERIES][2] = {
+    {0,0},
+    {0,0},
+    {46,-24},
+    {11,0},
+    {-3,1},
+    {-3,0},
+    {-2,1},
+    {1,0},
+    {0,0},
+    {0,0},
+    {0,0},
+    {0,0},
+    {0,0},
+    {48,1},
+    {-22,0},
+    {0,0},
+    {-15,9},
+    {0,0},
+    {-12,6},
+    {-6,3},
+    {-5,3},
+    {4,-2},
+    {4,-2},
+    {-4,0},
+    {1,0},
+    {1,0},
+    {-1,0},
+    {1,0},
+    {1,0},
+    {-1,0},
+    {0,0},
+    {0,0},
+    {0,0},
+    {0,0},
+    {-158,-1},
+    {123,-53},
+    {63,-2},
+    {0,0},
+    {0,0},
+    {-59,26},
+    {-51,27},
+    {-38,16},
+    {29,-1},
+    {29,-12},
+    {-31,13},
+    {26,-1},
+    {21,-10},
+    {16,-8},
+    {-13,7},
+    {-10,5},
+    {-7,0},
+    {7,-3},
+    {-7,3},
+    {-8,3},
+    {6,0},
+    {6,-3},
+    {-6,3},
+    {-7,3},
+    {6,-3},
+    {-5,3},
+    {5,0},
+    {-5,3},
+    {-4,0},
+    {4,0},
+    {-4,0},
+    {-3,0},
+    {3,0},
+    {-3,1},
+    {-3,1},
+    {-2,1},
+    {-3,1},
+    {-3,1},
+    {2,-1},
+    {-2,1},
+    {2,-1},
+    {-2,1},
+    {2,0},
+    {2,-1},
+    {1,-1},
+    {-1,0},
+    {1,-1},
+    {-2,1},
+    {-1,0},
+    {1,-1},
+    {-1,1},
+    {-1,1},
+    {1,0},
+    {1,0},
+    {1,-1},
+    {-1,0},
+    {-1,0},
+    {1,0},
+    {1,0},
+    {-1,0},
+    {1,0},
+    {1,0},
+    {-1,0},
+    {-1,0},
+    {-1,0},
+    {-1,0},
+    {-1,0},
+    {-1,0},
+    {-1,0},
+    {1,0},
+    {-1,0},
+    {1,0}
+};
+
+/* given the modified JD, mjd, find the nutation in obliquity, *deps, and
+ * the nutation in longitude, *dpsi, each in radians.
+ */
+void
+nutation (mjd, deps, dpsi)
+double mjd;
+double *deps;	/* on input:  precision parameter in arc seconds */
+double *dpsi;
+{
+	static double lastmjd = -10000, lastdeps, lastdpsi;
+	double T, T2, T3, T10;			/* jul cent since J2000 */
+	double prec;				/* series precis in arc sec */
+	int i, isecul;				/* index in term table */
+	static double delcache[5][2*NUT_MAXMUL+1];
+			/* cache for multiples of delaunay args
+			 * [M',M,F,D,Om][-min*x, .. , 0, .., max*x]
+			 * make static to have unfilled fields cleared on init
+			 */
+
+	if (mjd == lastmjd) {
+	    *deps = lastdeps;
+	    *dpsi = lastdpsi;
+	    return;
+	}
+
+	prec = 0.0;
+
+#if 0	/* this is if deps should contain a precision value */
+	prec =* deps;
+	if (prec < 0.0 || prec > 1.0)	/* accept only sane value */
+		prec = 1.0;
+#endif
+
+	/* augment for abundance of small terms */
+	prec *= NUT_SCALE/10;
+
+	T = (mjd - J2000)/36525.;
+	T2 = T * T;
+	T3 = T2 * T;
+	T10 = T/10.;
+
+	/* calculate delaunay args and place in cache */
+	for (i = 0; i < 5; ++i) {
+	    double x;
+	    short j;
+
+	    x = delaunay[i][0] +
+		delaunay[i][1] * T +
+		delaunay[i][2] * T2 +
+		delaunay[i][3] * T3;
+
+	    /* convert to radians */
+	    x /= SECPERCIRC;
+	    x -= floor(x);
+	    x *= 2.*PI;
+
+	    /* fill cache table */
+	    for (j = 0; j <= 2*NUT_MAXMUL; ++j)
+		delcache[i][j] = (j - NUT_MAXMUL) * x;
+	}
+
+	/* find dpsi and deps */
+	lastdpsi = lastdeps = 0.;
+	for (i = isecul = 0; i < NUT_SERIES ; ++i) {
+	    double arg = 0., ampsin, ampcos;
+	    short j;
+
+	    if (ampconst[i][0] || ampconst[i][1]) {
+		/* take non-secular terms from simple array */
+		ampsin = ampconst[i][0];
+		ampcos = ampconst[i][1];
+	    } else {
+		/* secular terms from different array */
+		ampsin = ampsecul[isecul][1] + ampsecul[isecul][2] * T10;
+		ampcos = ampsecul[isecul][3] + ampsecul[isecul][4] * T10;
+		++isecul;
+	    }
+
+	    for (j = 0; j < 5; ++j)
+		arg += delcache[j][NUT_MAXMUL + multarg[i][j]];
+
+	    if (fabs(ampsin) >= prec)
+		lastdpsi += ampsin * sin(arg);
+
+	    if (fabs(ampcos) >= prec)
+		lastdeps += ampcos * cos(arg);
+
+	}
+
+	/* convert to radians.
+	 */
+	lastdpsi = degrad(lastdpsi/3600./NUT_SCALE);
+	lastdeps = degrad(lastdeps/3600./NUT_SCALE);
+
+	lastmjd = mjd;
+	*deps = lastdeps;
+	*dpsi = lastdpsi;
+}
+
+/* given the modified JD, mjd, correct, IN PLACE, the right ascension *ra
+ * and declination *dec (both in radians) for nutation.
+ */
+void
+nut_eq (mjd, ra, dec)
+double mjd, *ra, *dec;
+{
+	static double lastmjd = -10000;
+	static double a[3][3];		/* rotation matrix */
+	double xold, yold, zold, x, y, z;
+
+	if (mjd != lastmjd) {
+	    double epsilon, dpsi, deps;
+	    double se, ce, sp, cp, sede, cede;
+
+	    obliquity(mjd, &epsilon);
+	    nutation(mjd, &deps, &dpsi);
+
+	    /* the rotation matrix a applies the nutation correction to
+	     * a vector of equatoreal coordinates Xeq to Xeq' by 3 subsequent
+	     * rotations:  R1 - from equatoreal to ecliptic system by
+	     * rotation of angle epsilon about x, R2 - rotate ecliptic
+	     * system by -dpsi about its z, R3 - from ecliptic to equatoreal
+	     * by rotation of angle -(epsilon + deps)
+	     *
+	     *	Xeq' = A * Xeq = R3 * R2 * R1 * Xeq
+	     * 
+	     *		[ 1       0          0    ]
+	     * R1 =	[ 0   cos(eps)   sin(eps) ]
+	     *		[ 0  - sin(eps)  cos(eps) ]
+	     * 
+	     *		[ cos(dpsi)  - sin(dpsi)  0 ]
+	     * R2 =	[ sin(dpsi)   cos(dpsi)   0 ]
+	     *		[      0           0      1 ]
+	     * 
+	     *		[ 1         0                 0         ]
+	     * R3 =	[ 0  cos(eps + deps)  - sin(eps + deps) ]
+	     *		[ 0  sin(eps + deps)   cos(eps + deps)  ]
+	     * 
+	     * for efficiency, here is a explicitely:
+	     */
+	    
+	    se = sin(epsilon);
+	    ce = cos(epsilon);
+	    sp = sin(dpsi);
+	    cp = cos(dpsi);
+	    sede = sin(epsilon + deps);
+	    cede = cos(epsilon + deps);
+
+	    a[0][0] = cp;
+	    a[0][1] = -sp*ce;
+	    a[0][2] = -sp*se;
+
+	    a[1][0] = cede*sp;
+	    a[1][1] = cede*cp*ce+sede*se;
+	    a[1][2] = cede*cp*se-sede*ce;
+
+	    a[2][0] = sede*sp;
+	    a[2][1] = sede*cp*ce-cede*se;
+	    a[2][2] = sede*cp*se+cede*ce;
+
+	    lastmjd = mjd;
+	}
+
+	sphcart(*ra, *dec, 1.0, &xold, &yold, &zold);
+	x = a[0][0] * xold + a[0][1] * yold + a[0][2] * zold;
+	y = a[1][0] * xold + a[1][1] * yold + a[1][2] * zold;
+	z = a[2][0] * xold + a[2][1] * yold + a[2][2] * zold;
+	cartsph(x, y, z, ra, dec, &zold);	/* radius should be 1.0 */
+	if (*ra < 0.) *ra += 2.*PI;		/* make positive for display */
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: nutation.c,v $ $Date: 2001-10-22 12:08:27 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/obliq.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/obliq.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/obliq.c	(revision 2309)
@@ -0,0 +1,30 @@
+#include <stdio.h>
+
+#include "P_.h"
+#include "astro.h"
+
+/* given the modified Julian date, mjd, find the mean obliquity of the
+ * ecliptic, *eps, in radians.
+ *
+ * IAU expression (see e.g. Astron. Almanac 1984); stern
+ */
+void
+obliquity (mjd, eps)
+double mjd;
+double *eps;
+{
+	static double lastmjd = -16347, lasteps;
+
+	if (mjd != lastmjd) {
+	    double t = (mjd - J2000)/36525.;	/* centuries from J2000 */
+	    lasteps = degrad(23.4392911 +	/* 23^ 26' 21".448 */
+			    t * (-46.8150 +
+			    t * ( -0.00059 +
+			    t * (  0.001813 )))/3600.0);
+	    lastmjd = mjd;
+	}
+	*eps = lasteps;
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: obliq.c,v $ $Date: 2001-10-22 12:08:27 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/parallax.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/parallax.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/parallax.c	(revision 2309)
@@ -0,0 +1,44 @@
+#include <stdio.h>
+#include <math.h>
+
+#include "P_.h"
+#include "astro.h"
+
+
+/* given true ha and dec, tha and tdec, the geographical latitude, phi, the
+ * height above sea-level (as a fraction of the earths radius, 6378.16km),
+ * ht, and the geocentric distance rho in Earth radii(!), find the apparent
+ * ha and dec, aha and adec allowing for parallax.
+ * all angles in radians. ehp is the angle subtended at the body by the
+ * earth's equator.
+ */
+void
+ta_par (tha, tdec, phi, ht, rho, aha, adec)
+double tha, tdec, phi, ht, *rho;
+double *aha, *adec;
+{
+	static double last_phi = 1000.0, last_ht = -1000.0, xobs, zobs;
+	double x, y, z;	/* obj cartesian coord, in Earth radii */
+
+	/* avoid calcs involving the same phi and ht */
+	if (phi != last_phi || ht != last_ht) {
+	    double cphi, sphi, robs, e2 = (2 - 1/298.257)/298.257;
+	    cphi = cos(phi);
+	    sphi = sin(phi);
+	    robs = 1/sqrt(1 - e2 * sphi * sphi);
+
+	    /* observer coordinates: x to meridian, y east, z north */
+	    xobs = (robs + ht) * cphi;
+	    zobs = (robs*(1-e2) + ht) * sphi;
+	    last_phi  =  phi;
+	    last_ht  =  ht;
+	}
+
+	sphcart(-tha, tdec, *rho, &x, &y, &z);
+	cartsph(x - xobs, y, z - zobs, aha, adec, rho);
+	*aha *= -1;
+	range (aha, 2*PI);
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: parallax.c,v $ $Date: 2001-10-22 12:08:27 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/plans.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/plans.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/plans.c	(revision 2309)
@@ -0,0 +1,234 @@
+/* rewritten for Bureau des Longitude theories by Bretagnon and Chapront
+ * Michael Sternberg <sternberg@physik.tu-chemnitz.de>
+ */
+#include <stdio.h>
+#include <math.h>
+
+#include "P_.h"
+#include "astro.h"
+#include "vsop87.h"
+#include "chap95.h"
+
+static void pluto_ell P_((double mjd, double *ret));
+static void chap_trans P_((double mjd, double *ret));
+static void planpos P_((double mjd, int obj, double prec, double *ret));
+
+/* coordinate transformation
+ * from:
+ *	J2000.0 rectangular equatoreal			ret[{0,1,2}] = {x,y,z}
+ * to:
+ *	mean equinox of date spherical ecliptical	ret[{0,1,2}] = {l,b,r}
+ */
+static void
+chap_trans (mjd, ret)
+double mjd;	/* destination epoch */
+double *ret;	/* vector to be transformed _IN PLACE_ */
+{
+	double ra, dec, r, eps;
+	double sr, cr, sd, cd, se, ce;
+
+	cartsph(ret[0], ret[1], ret[2], &ra, &dec, &r);
+	precess(J2000, mjd, &ra, &dec);
+	obliquity(mjd, &eps);
+	sr = sin(ra); cr = cos(ra);
+	sd = sin(dec); cd = cos(dec);
+	se = sin(eps); ce = cos(eps);
+	ret[0] = atan2( sr * ce + sd/cd * se, cr);	/* long */
+	ret[1] = asin( sd * ce - cd * se * sr);		/* lat */
+	ret[2] = r;					/* radius */
+}
+
+/* low precision ecliptic coordinates of Pluto from mean orbit.
+ * Only for sake of completeness outside available perturbation theories.
+ */
+static void
+pluto_ell (mjd, ret)
+double mjd;	/* epoch */
+double *ret;	/* ecliptic coordinates {l,b,r} at equinox of date */
+{
+	/* mean orbital elements of Pluto.
+	 * The origin of these is somewhat obscure.
+	 */
+	double	a = 39.543,			/* semimajor axis, au */
+		e = 0.2490,			/* excentricity */
+		inc0 = 17.140,			/* inclination, deg */
+		Om0 = 110.307,			/* long asc node, deg */
+		omeg0 = 113.768,		/* arg of perihel, deg */
+		mjdp = 2448045.539 - MJD0,	/* epoch of perihel */
+		mjdeq = J2000,			/* equinox of elements */
+		n = 144.9600/36525.;            /* daily motion, deg */
+
+	double inc, Om, omeg;	/* orbital elements at epoch of date */
+	double ma, ea, nu;	/* mean, excentric and true anomaly */
+	double lo, slo, clo;	/* longitude in orbit from asc node */
+
+	reduce_elements(mjdeq, mjd, degrad(inc0), degrad(omeg0), degrad(Om0),
+				&inc, &omeg, &Om);
+	ma = degrad((mjd - mjdp) * n);
+	anomaly(ma, e, &nu, &ea);
+	ret[2] = a * (1.0 - e*cos(ea));			/* r */
+	lo = omeg + nu;
+	slo = sin(lo);
+	clo = cos(lo);
+	ret[1] = asin(slo * sin(inc));			/* b */
+	ret[0] = atan2(slo * cos(inc), clo) + Om;	/* l */
+}
+
+/*************************************************************/
+
+/* geometric heliocentric position of planet, mean ecliptic of date
+ * (not corrected for light-time)
+ */
+static void
+planpos (mjd, obj, prec, ret)
+double mjd;
+int obj;
+double prec;
+double *ret;
+{
+	if (mjd >= CHAP_BEGIN && mjd <= CHAP_END) {
+	    if (obj >= JUPITER) {		/* prefer Chapront */
+		chap95(mjd, obj, prec, ret);
+		chap_trans (mjd, ret);
+	    } else {				/* VSOP for inner planets */
+		vsop87(mjd, obj, prec, ret);
+	    }
+	} else {				/* outside Chapront time: */
+	    if (obj != PLUTO) {			/* VSOP for all but Pluto */
+		vsop87(mjd, obj, prec, ret);
+	    } else {				/* Pluto mean elliptic orbit */
+		pluto_ell(mjd, ret);
+	    }
+	}
+}
+
+/*************************************************************/
+
+/* visual elements of planets
+ * [planet][0] = angular size at 1 AU
+ * [planet][1] = magnitude at 1 AU from sun and earth and 0 deg phase angle
+ * [planet][2] = A
+ * [planet][3] = B
+ * [planet][4] = C
+ *   where mag correction = A*(i/100) + B*(i/100)^2 + C*(i/100)^3
+ *      i = angle between sun and earth from planet, degrees
+ * from Explanatory Supplement, 1992
+ */
+static double vis_elements[8][5] = {
+	/* Mercury */	{ 6.74, -0.36, 3.8, -2.73, 2.00},
+	/* Venus */	{ 16.92, -4.29, 0.09, 2.39, -.65},
+	/* Mars */	{ 9.36, -1.52, 1.60, 0., 0.},
+	/* Jupiter */	{ 196.74, -9.25, 0.50, 0., 0.},
+	/* Saturn */	{ 165.6, -8.88, 4.40, 0., 0.},
+	/* Uranus */	{ 65.8, -7.19, 0.28, 0., 0.},
+	/* Neptune */	{ 62.2, -6.87, 0., 0., 0.},
+	/* Pluto */	{ 8.2, -1.01, 4.1, 0., 0.}
+};
+
+/* given a modified Julian date, mjd, and a planet, p, find:
+ *   lpd0: heliocentric longitude, 
+ *   psi0: heliocentric latitude,
+ *   rp0:  distance from the sun to the planet, 
+ *   rho0: distance from the Earth to the planet,
+ *         none corrected for light time, ie, they are the true values for the
+ *         given instant.
+ *   lam:  geocentric ecliptic longitude, 
+ *   bet:  geocentric ecliptic latitude,
+ *         each corrected for light time, ie, they are the apparent values as
+ *	   seen from the center of the Earth for the given instant.
+ *   dia:  angular diameter in arcsec at 1 AU, 
+ *   mag:  visual magnitude
+ *
+ * all angles are in radians, all distances in AU.
+ *
+ * corrections for nutation and abberation must be made by the caller. The RA 
+ *   and DEC calculated from the fully-corrected ecliptic coordinates are then
+ *   the apparent geocentric coordinates. Further corrections can be made, if
+ *   required, for atmospheric refraction and geocentric parallax.
+ */
+void
+plans (mjd, p, lpd0, psi0, rp0, rho0, lam, bet, dia, mag)
+double mjd;
+int p;
+double *lpd0, *psi0, *rp0, *rho0, *lam, *bet, *dia, *mag;
+{
+	static double lastmjd = -10000;
+	static double lsn, bsn, rsn;	/* geocentric coords of sun */
+	static double xsn, ysn, zsn;	/* cartesian " */
+	double lp, bp, rp;		/* heliocentric coords of planet */
+	double xp, yp, zp, rho;		/* rect. coords and geocentric dist. */
+	double dt;			/* light time */
+	double *vp;			/* vis_elements[p] */
+	double ci, i;			/* sun/earth angle: cos, degrees */
+	int pass;
+
+	/* get sun cartesian; needed only once at mjd */
+	if (mjd != lastmjd) {
+	    sunpos (mjd, &lsn, &rsn, &bsn);
+	    sphcart (lsn, bsn, rsn, &xsn, &ysn, &zsn);
+            lastmjd = mjd;
+        }
+
+	/* first find the true position of the planet at mjd.
+	 * then repeat a second time for a slightly different time based
+	 * on the position found in the first pass to account for light-travel
+	 * time.
+	 */
+	dt = 0.0;
+	for (pass = 0; pass < 2; pass++) {
+	    double ret[6];
+
+	    /* get spherical coordinates of planet from precision routines,
+	     * retarded for light time in second pass;
+	     * alternative option:  vsop allows calculating rates.
+	     */
+	    planpos(mjd - dt, p, 0.0, ret);
+
+	    lp = ret[0];
+	    bp = ret[1];
+	    rp = ret[2];
+
+	    sphcart (lp, bp, rp, &xp, &yp, &zp);
+	    cartsph (xp + xsn, yp + ysn, zp + zsn, lam, bet, &rho);
+
+	    if (pass == 0) {
+		/* save heliocentric coordinates at first pass since, being
+		 * true, they are NOT to be corrected for light-travel time.
+		 */
+		*lpd0 = lp;
+		range (lpd0, 2.*PI);
+		*psi0 = bp;
+		*rp0 = rp;
+		*rho0 = rho;
+	    }
+
+	    /* when we view a planet we see it in the position it occupied
+	     * dt days ago, where rho is the distance between it and earth,
+	     * in AU. use this as the new time for the next pass.
+	     */
+	    dt = rho * 5.7755183e-3;
+	}
+
+	vp = vis_elements[p];
+	*dia = vp[0];
+
+	/* solve plane triangle, assume sun/earth dist == 1 */
+	ci = (rp*rp + rho*rho - 1)/(2*rp*rho);
+
+	/* expl supp equation for mag */
+	if (ci < -1) ci = -1;
+	if (ci >  1) ci =  1;
+	i = raddeg(acos(ci))/100.;
+	*mag = vp[1] + 5*log10(rho*rp) + i*(vp[2] + i*(vp[3] + i*vp[4]));
+
+	/* rings contribution if SATURN */
+	if (p == SATURN) {
+	    double et, st, set;
+	    satrings (bp, lp, rp, lsn+PI, rsn, mjd+MJD0, &et, &st);
+	    set = sin(fabs(et));
+	    *mag += (-2.60 + 1.25*set)*set;
+	}
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: plans.c,v $ $Date: 2001-10-22 12:08:27 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/precess.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/precess.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/precess.c	(revision 2309)
@@ -0,0 +1,148 @@
+#include <stdio.h>
+#include <math.h>
+
+#include "P_.h"
+#include "astro.h"
+
+static void precess_hiprec P_((double mjd1, double mjd2, double *ra,
+    double *dec));
+
+
+#define	DCOS(x)		cos(degrad(x))
+#define	DSIN(x)		sin(degrad(x))
+#define	DASIN(x)	raddeg(asin(x))
+#define	DATAN2(y,x)	raddeg(atan2((y),(x)))
+
+/* corrects ra and dec, both in radians, for precession from epoch 1 to epoch 2.
+ * the epochs are given by their modified JDs, mjd1 and mjd2, respectively.
+ * N.B. ra and dec are modifed IN PLACE.
+ */
+void
+precess (mjd1, mjd2, ra, dec)
+double mjd1, mjd2;	/* initial and final epoch modified JDs */
+double *ra, *dec;	/* ra/dec for mjd1 in, for mjd2 out */
+{
+	precess_hiprec (mjd1, mjd2, ra, dec);
+}
+
+/*
+ * Copyright (c) 1990 by Craig Counterman. All rights reserved.
+ *
+ * This software may be redistributed freely, not sold.
+ * This copyright notice and disclaimer of warranty must remain
+ *    unchanged. 
+ *
+ * No representation is made about the suitability of this
+ * software for any purpose.  It is provided "as is" without express or
+ * implied warranty, to the extent permitted by applicable law.
+ *
+ * Rigorous precession. From Astronomical Ephemeris 1989, p. B18
+ *
+ * 96-06-20 Hayo Hase <hase@wettzell.ifag.de>: theta_a corrected
+ */
+static void
+precess_hiprec (mjd1, mjd2, ra, dec)
+double mjd1, mjd2;	/* initial and final epoch modified JDs */
+double *ra, *dec;	/* ra/dec for mjd1 in, for mjd2 out */
+{
+	static double last_mjd1 = -213.432, last_from;
+	static double last_mjd2 = -213.432, last_to;
+	double zeta_A, z_A, theta_A;
+	double T;
+	double A, B, C;
+	double alpha, delta;
+	double alpha_in, delta_in;
+	double from_equinox, to_equinox;
+	double alpha2000, delta2000;
+
+	/* convert mjds to years;
+	 * avoid the remarkably expensive calls to mjd_year()
+	 */
+	if (last_mjd1 == mjd1)
+	    from_equinox = last_from;
+	else {
+	    mjd_year (mjd1, &from_equinox);
+	    last_mjd1 = mjd1;
+	    last_from = from_equinox;
+	}
+	if (last_mjd2 == mjd2)
+	    to_equinox = last_to;
+	else {
+	    mjd_year (mjd2, &to_equinox);
+	    last_mjd2 = mjd2;
+	    last_to = to_equinox;
+	}
+
+	/* convert coords in rads to degs */
+	alpha_in = raddeg(*ra);
+	delta_in = raddeg(*dec);
+
+	/* precession progresses about 1 arc second in .047 years */
+	/* From from_equinox to 2000.0 */
+	if (fabs (from_equinox-2000.0) > .02) {
+	    T = (from_equinox - 2000.0)/100.0;
+	    zeta_A  = 0.6406161* T + 0.0000839* T*T + 0.0000050* T*T*T;
+	    z_A     = 0.6406161* T + 0.0003041* T*T + 0.0000051* T*T*T;
+	    theta_A = 0.5567530* T - 0.0001185* T*T - 0.0000116* T*T*T;
+
+	    A = DSIN(alpha_in - z_A) * DCOS(delta_in);
+	    B = DCOS(alpha_in - z_A) * DCOS(theta_A) * DCOS(delta_in)
+	      + DSIN(theta_A) * DSIN(delta_in);
+	    C = -DCOS(alpha_in - z_A) * DSIN(theta_A) * DCOS(delta_in)
+	      + DCOS(theta_A) * DSIN(delta_in);
+
+	    alpha2000 = DATAN2(A,B) - zeta_A;
+	    range (&alpha2000, 360.0);
+	    delta2000 = DASIN(C);
+	} else {
+	    /* should get the same answer, but this could improve accruacy */
+	    alpha2000 = alpha_in;
+	    delta2000 = delta_in;
+	};
+
+
+	/* From 2000.0 to to_equinox */
+	if (fabs (to_equinox - 2000.0) > .02) {
+	    T = (to_equinox - 2000.0)/100.0;
+	    zeta_A  = 0.6406161* T + 0.0000839* T*T + 0.0000050* T*T*T;
+	    z_A     = 0.6406161* T + 0.0003041* T*T + 0.0000051* T*T*T;
+	    theta_A = 0.5567530* T - 0.0001185* T*T - 0.0000116* T*T*T;
+
+	    A = DSIN(alpha2000 + zeta_A) * DCOS(delta2000);
+	    B = DCOS(alpha2000 + zeta_A) * DCOS(theta_A) * DCOS(delta2000)
+	      - DSIN(theta_A) * DSIN(delta2000);
+	    C = DCOS(alpha2000 + zeta_A) * DSIN(theta_A) * DCOS(delta2000)
+	      + DCOS(theta_A) * DSIN(delta2000);
+
+	    alpha = DATAN2(A,B) + z_A;
+	    range(&alpha, 360.0);
+	    delta = DASIN(C);
+	} else {
+	    /* should get the same answer, but this could improve accruacy */
+	    alpha = alpha2000;
+	    delta = delta2000;
+	};
+
+	*ra = degrad(alpha);
+	*dec = degrad(delta);
+}
+
+#if 0
+static void
+precess_fast (mjd1, mjd2, ra, dec)
+double mjd1, mjd2;	/* initial and final epoch modified JDs */
+double *ra, *dec;	/* ra/dec for mjd1 in, for mjd2 out */
+{
+#define	N	degrad (20.0468/3600.0)
+#define	M	hrrad (3.07234/3600.0)
+	double nyrs;
+
+	nyrs = (mjd2 - mjd1)/365.2425;
+	*dec += N * cos(*ra) * nyrs;
+	*ra += (M + (N * sin(*ra) * tan(*dec))) * nyrs;
+	range (ra, 2.0*PI);
+}
+#endif
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: precess.c,v $ $Date: 2001-10-22 12:08:27 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/preferences.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/preferences.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/preferences.h	(revision 2309)
@@ -0,0 +1,32 @@
+/* global info for the preferences facility.
+ * N.B. many of these enums are used as indexes -- don't change without
+ *   checking where they are used!
+ */
+#ifndef _PREFERENCES_H
+#define _PREFERENCES_H
+
+typedef enum {
+    PREF_EQUATORIAL, PREF_UNITS, PREF_DATE_FORMAT, PREF_ZONE, PREF_DPYPREC,
+    PREF_MSG_BELL, PREF_PRE_FILL, PREF_TIPS, PREF_CONFIRM, PREF_WEEKSTART,
+    NPREFS
+} Preferences;
+
+typedef enum {PREF_GEO, PREF_TOPO} PrefEquatorial;
+typedef enum {PREF_ENGLISH, PREF_METRIC} PrefUnits;
+typedef enum {PREF_MDY, PREF_YMD, PREF_DMY} PrefDateFormat;
+typedef enum {PREF_LOCALTZ, PREF_UTCTZ} PrefStampZone;
+typedef enum {PREF_LOPREC, PREF_HIPREC} PrefDpyPrec;
+typedef enum {PREF_NOMSGBELL, PREF_MSGBELL} PrefMsgBell;
+typedef enum {PREF_PREFILL, PREF_NOPREFILL} PrefPreFill;
+typedef enum {PREF_TIPSON, PREF_NOTIPS} PrefTips;
+typedef enum {PREF_CONFIRMON, PREF_NOCONFIRM} PrefConfirm;
+typedef enum {PREF_SAT, PREF_SUN, PREF_MON} PrefWeekStart;
+
+extern int pref_get P_((Preferences p));
+extern int pref_set P_((Preferences p, int new));
+
+#endif /* _PREFERENCES_H */
+
+/* For RCS Only -- Do Not Edit
+ * @(#) $RCSfile: preferences.h,v $ $Date: 2001-10-22 12:08:27 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $
+ */
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/reduce.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/reduce.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/reduce.c	(revision 2309)
@@ -0,0 +1,77 @@
+#include <math.h>
+
+#include "P_.h"
+#include "astro.h"
+
+/* convert those orbital elements that change from epoch mjd0 to epoch mjd.
+ */
+void
+reduce_elements (mjd0, mjd, inc0, ap0, om0, inc, ap, om)
+double mjd0;	/* initial epoch */
+double mjd;	/* desired epoch */
+double inc0;	/* initial inclination, rads */
+double ap0;	/* initial argument of perihelion, as an mjd */
+double om0;	/* initial long of ascending node, rads */
+double *inc;	/* desired inclination, rads */
+double *ap;	/* desired epoch of perihelion, as an mjd */
+double *om;	/* desired long of ascending node, rads */
+{
+	double t0, t1;
+	double tt, tt2, t02, tt3;
+	double eta, th, th0;
+	double a, b;
+	double dap;
+	double cinc, sinc;
+	double ot, sot, cot, ot1;
+	double seta, ceta;
+
+	if (fabs(mjd - mjd0) < 1e-5) {
+	    /* sin(eta) blows for inc < 10 degrees -- anyway, no need */
+	    *inc = inc0;
+	    *ap = ap0;
+	    *om = om0;
+	    return;
+	}
+
+	t0 = mjd0/365250.0;
+	t1 = mjd/365250.0;
+
+	tt = t1-t0;
+	tt2 = tt*tt;
+        t02 = t0*t0;
+	tt3 = tt*tt2;
+        eta = (471.07-6.75*t0+.57*t02)*tt+(.57*t0-3.37)*tt2+.05*tt3;
+        th0 = 32869.0*t0+56*t02-(8694+55*t0)*tt+3*tt2;
+        eta = degrad(eta/3600.0);
+        th0 = degrad((th0/3600.0)+173.950833);
+        th = (50256.41+222.29*t0+.26*t02)*tt+(111.15+.26*t0)*tt2+.1*tt3;
+        th = th0+degrad(th/3600.0);
+	cinc = cos(inc0);
+        sinc = sin(inc0);
+	ot = om0-th0;
+	sot = sin(ot);
+        cot = cos(ot);
+	seta = sin(eta);
+        ceta = cos(eta);
+	a = sinc*sot;
+        b = ceta*sinc*cot-seta*cinc;
+	ot1 = atan(a/b);
+        if (b<0) ot1 += PI;
+        b = sinc*ceta-cinc*seta*cot;
+        a = -1*seta*sot;
+	dap = atan(a/b);
+        if (b<0) dap += PI;
+
+        *ap = ap0+dap;
+	range (ap, 2*PI);
+        *om = ot1+th;
+	range (om, 2*PI);
+
+        if (inc0<.175)
+	    *inc = asin(a/sin(dap));
+	else
+	    *inc = 1.570796327-asin((cinc*ceta)+(sinc*seta*cot));
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: reduce.c,v $ $Date: 2001-10-22 12:08:27 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/refract.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/refract.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/refract.c	(revision 2309)
@@ -0,0 +1,104 @@
+#include <stdio.h>
+#include <math.h>
+
+#include "P_.h"
+#include "astro.h"
+
+static void unrefractLT15 P_((double pr, double tr, double aa, double *ta));
+static void unrefractGE15 P_((double pr, double tr, double aa, double *ta));
+
+void
+unrefract (pr, tr, aa, ta)
+double pr, tr;
+double aa;
+double *ta;
+{
+#define	LTLIM	14.5
+#define	GELIM	15.5
+
+	double aadeg = raddeg(aa);
+
+	if (aadeg < LTLIM)
+	    unrefractLT15 (pr, tr, aa, ta);
+	else if (aadeg >= GELIM)
+	    unrefractGE15 (pr, tr, aa, ta);
+	else {
+	    /* smooth blend -- important for inverse */
+	    double taLT, taGE, p;
+
+	    unrefractLT15 (pr, tr, aa, &taLT);
+	    unrefractGE15 (pr, tr, aa, &taGE);
+	    p = (aadeg - LTLIM)/(GELIM - LTLIM);
+	    *ta = taLT + (taGE - taLT)*p;
+	}
+}
+
+static void
+unrefractGE15 (pr, tr, aa, ta)
+double pr, tr;
+double aa;
+double *ta;
+{
+	double r;
+	
+	r = 7.888888e-5*pr/((273+tr)*tan(aa));
+	*ta  =  aa - r;
+}
+
+static void
+unrefractLT15 (pr, tr, aa, ta)
+double pr, tr;
+double aa;
+double *ta;
+{
+	double aadeg = raddeg(aa);
+	double r, a, b;
+
+	a = ((2e-5*aadeg+1.96e-2)*aadeg+1.594e-1)*pr;
+	b = (273+tr)*((8.45e-2*aadeg+5.05e-1)*aadeg+1);
+	r = degrad(a/b);
+
+	*ta  =  (aa < 0 && r < 0) ? aa : aa - r;	/* 0 below ~5 degs */
+}
+
+/* correct the true altitude, ta, for refraction to the apparent altitude, aa,
+ * each in radians, given the local atmospheric pressure, pr, in mbars, and
+ * the temperature, tr, in degrees C.
+ */
+void
+refract (pr, tr, ta, aa)
+double pr, tr;
+double ta;
+double *aa;
+{
+#define	MAXRERR	degrad(0.1/3600.)	/* desired accuracy, rads */
+
+	double d, t, t0, a;
+
+	/* first guess of error is to go backwards.
+	 * make use that we know delta-apparent is always < delta-true.
+	 */
+	unrefract (pr, tr, ta, &t);
+	d = 0.8*(ta - t);
+	t0 = t;
+	a = ta;
+
+	/* use secant method to discover a value that unrefracts to ta.
+	 * max=7 ave=2.4 loops in hundreds of test cases.
+	 */
+	while (1) {
+	    a += d;
+	    unrefract (pr, tr, a, &t);
+	    if (fabs(ta-t) <= MAXRERR)
+		break;
+	    d *= -(ta - t)/(t0 - t);
+	    t0 = t;
+	}
+
+	*aa = a;
+
+#undef	MAXRERR
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: refract.c,v $ $Date: 2002-02-07 09:27:06 $ $Revision: 1.3 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/rings.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/rings.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/rings.c	(revision 2309)
@@ -0,0 +1,46 @@
+#include <stdio.h>
+#include <math.h>
+#if defined(__STDC__)
+#include <stdlib.h>
+#endif
+
+#include "P_.h"
+#include "astro.h"
+#include "circum.h"
+
+/*  RINGS OF SATURN by Olson, et al, BASIC Code from Sky & Telescope, May 1995.
+ *  As converted from BASIC to C by pmartz@dsd.es.com (Paul Martz)
+ *  Adapted to xephem by Elwood Charles Downey.
+ */
+void
+satrings (sb, sl, sr, el, er, JD, etiltp, stiltp)
+double sb, sl, sr;		/* Saturn hlat, hlong, sun dist */
+double el, er;			/* Earth hlong, sun dist */
+double JD;			/* Julian date */
+double *etiltp, *stiltp;	/* tilt from earth and sun, rads southward */
+{
+	double t, i, om;
+	double x, y, z;
+	double la, be;
+	double s, b, sp, bp;
+
+	t = (JD-2451545.)/365250.;
+	i = degrad(28.04922-.13*t+.0004*t*t);
+	om = degrad(169.53+13.826*t+.04*t*t);
+
+	x = sr*cos(sb)*cos(sl)-er*cos(el);
+	y = sr*cos(sb)*sin(sl)-er*sin(el);
+	z = sr*sin(sb);
+
+	la = atan(y/x);
+	if (x<0) la+=PI;
+	be = atan(z/sqrt(x*x+y*y));
+
+	s = sin(i)*cos(be)*sin(la-om)-cos(i)*sin(be);
+	b = atan(s/sqrt(1.-s*s));
+	sp = sin(i)*cos(sb)*sin(sl-om)-cos(i)*sin(sb);
+	bp = atan(sp/sqrt(1.-sp*sp));
+
+	*etiltp = b;
+	*stiltp = bp;
+}
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/riset.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/riset.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/riset.c	(revision 2309)
@@ -0,0 +1,105 @@
+#include <stdio.h>
+#include <math.h>
+
+#include "P_.h"
+#include "astro.h"
+
+/* given the true geocentric ra and dec of an object, the observer's latitude,
+ *   lat, and a horizon displacement correction, dis, all in radians, find the
+ *   local sidereal times and azimuths of rising and setting, lstr/s
+ *   and azr/s, also all in radians, respectively.
+ * dis is the vertical displacement from the true position of the horizon. it
+ *   is positive if the apparent position is higher than the true position.
+ *   said another way, it is positive if the shift causes the object to spend
+ *   longer above the horizon. for example, atmospheric refraction is typically
+ *   assumed to produce a vertical shift of 34 arc minutes at the horizon; dis
+ *   would then take on the value +9.89e-3 (radians). On the other hand, if
+ *   your horizon has hills such that your apparent horizon is, say, 1 degree
+ *   above sea level, you would allow for this by setting dis to -1.75e-2
+ *   (radians).
+ *
+ * This version contributed by Konrad Bernloehr, Nov. 1996
+ *
+ * status: 0=normal; 1=never rises; -1=circumpolar.
+ * In case of non-zero status, all other returned variables are undefined.
+ */
+void
+riset (ra, dec, lat, dis, lstr, lsts, azr, azs, status)
+double ra, dec;
+double lat, dis;
+double *lstr, *lsts;
+double *azr, *azs;
+int *status;
+{
+#define	EPS	(1e-9)	/* math rounding fudge - always the way, eh? */
+	double h;		/* hour angle */
+	double cos_h;		/* cos h */
+	double z;		/* zenith angle */
+	double zmin, zmax;	/* Minimum and maximum zenith angles */
+	double xaz, yaz;	/* components of az */
+	int shemi;		/* flag for southern hemisphere reflection */
+
+	/* reflect lat and dec if in southern hemisphere, then az back later */
+	if ((shemi= (lat < 0.)) != 0) {
+	    lat = -lat;
+	    dec = -dec;
+	}
+
+	/* establish zenith angle, and its extrema */
+	z = (PI/2.) + dis;
+	zmin = fabs (dec - lat);
+	zmax = PI - fabs(dec + lat);
+
+	/* first consider special cases.
+	 * these also avoid any boundary problems in subsequent computations.
+	 */
+	if (zmax <= z + EPS) {
+	    *status = -1;	/* never sets */
+	    return;
+	}
+	if (zmin >= z - EPS) {
+	    *status = 1;	/* never rises */
+	    return;
+	}
+
+	/* compute rising hour angle -- beware found off */
+	cos_h = (cos(z)-sin(lat)*sin(dec))/(cos(lat)*cos(dec));
+	if (cos_h >= 1.)
+	    h =  0.;
+	else if (cos_h <= -1.)
+	    h = PI;
+	else
+	    h = acos (cos_h);
+
+	/* compute setting azimuth -- beware found off */
+	xaz = sin(dec)*cos(lat)-cos(dec)*cos(h)*sin(lat);
+	yaz = -1.*cos(dec)*sin(h);
+	if (xaz == 0.) {
+	    if (yaz > 0)
+		*azs = PI/2;
+	    else
+		*azs = -PI/2;
+	} else
+	    *azs = atan2 (yaz, xaz);
+
+	/* reflect az back if southern */
+	if (shemi)
+	    *azs = PI - *azs;
+	range(azs, 2.*PI);
+
+	/* rising is just the opposite side */
+	*azr = 2.*PI - *azs;
+	range(azr, 2.*PI);
+
+	/* rise and set are just ha either side of ra */
+	*lstr = radhr(ra-h);
+	range(lstr,24.0);
+	*lsts = radhr(ra+h);
+	range(lsts,24.0);
+
+	/* OK */
+	*status = 0;
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: riset.c,v $ $Date: 2001-10-22 12:08:28 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/riset_cir.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/riset_cir.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/riset_cir.c	(revision 2309)
@@ -0,0 +1,387 @@
+/* find rise and set circumstances, ie, riset_cir() and related functions. */
+
+#include <stdio.h>
+#include <math.h>
+#if defined(__STDC__)
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+#include "P_.h"
+#include "astro.h"
+#include "circum.h"
+
+#define	TMACC	(10./3600./24.0)	/* convergence accuracy, days */
+
+static void e_riset_cir P_((Now *np, Obj *op, double dis, RiseSet *rp));
+static int find_0alt P_((double dt, double dis, Now *np, Obj *op));
+static int find_transit P_((double dt, Now *np, Obj *op));
+static int find_max P_((Now *np, Obj *op, double tr, double ts, double *tp,
+    double *alp));
+
+/* find where and when an object, op, will rise and set and
+ *   it's transit circumstances. all times are utc mjd, angles rads e of n.
+ * dis is the angle down from an ideal horizon, in rads (see riset()).
+ * N.B. dis should NOT include refraction, we do that here.
+ */
+void
+riset_cir (np, op, dis, rp)
+Now *np;
+Obj *op;
+double dis;
+RiseSet *rp;
+{
+	double mjdn;	/* mjd of local noon */
+	double lstn;	/* lst at local noon */
+	double lr, ls;	/* lst rise/set times */
+	double ar, as;	/* az of rise/set */
+	double ran;	/* RA at noon */
+	Now n;		/* copy to move time around */
+	Obj o;		/* copy to get circumstances at n */
+	int rss;	/* temp status */
+
+	/* work with local copies so we can move the time around */
+	(void) memcpy ((void *)&n, (void *)np, sizeof(n));
+	(void) memcpy ((void *)&o, (void *)op, sizeof(o));
+
+	/* fast Earth satellites need a different approach.
+	 * "fast" here is pretty arbitrary -- just too fast to work with the
+	 * iterative approach based on refining the times for a "fixed" object.
+	 */
+	if (op->o_type == EARTHSAT && op->es_n > FAST_SAT_RPD) {
+	    e_riset_cir (&n, &o, dis, rp);
+	    return;
+	}
+
+	/* assume no problems initially */
+	rp->rs_flags = 0;
+
+	/* start the iteration at local noon */
+	mjdn = mjd_day(mjd - tz/24.0) + tz/24.0 + 0.5;
+	n.n_mjd = mjdn;
+	now_lst (&n, &lstn);
+
+	/* first approximation is to find rise/set times of a fixed object
+	 * at the current epoch in its position at local noon.
+	 * N.B. add typical refraction for initial go/no-go test. if it
+	 *   passes, real code does refraction rigorously.
+	 */
+	n.n_mjd = mjdn;
+	if (obj_cir (&n, &o) < 0) {
+	    rp->rs_flags = RS_ERROR;
+	    return;
+	}
+	ran = o.s_gaera;
+	riset (o.s_gaera, o.s_gaedec, lat, dis+.01, &lr, &ls, &ar, &as, &rss);
+	switch (rss) {
+	case  0:  break;
+	case  1: rp->rs_flags = RS_NEVERUP; return;
+	case -1: rp->rs_flags = RS_CIRCUMPOLAR; goto dotransit;
+	default: rp->rs_flags = RS_ERROR; return;
+	}
+
+	/* iterate to find better rise time */
+	n.n_mjd = mjdn;
+	switch (find_0alt ((lr - lstn)/SIDRATE, dis, &n, &o)) {
+	case 0: /* ok */
+	    rp->rs_risetm = n.n_mjd;
+	    rp->rs_riseaz = o.s_az;
+	    break;
+	case -1: /* obj_cir error */
+	    rp->rs_flags |= RS_RISERR;
+	    break;
+	case -2: /* converged but not today */ /* FALLTHRU */
+	case -3: /* probably never up */
+	    rp->rs_flags |= RS_NORISE;
+	    break;
+	}
+
+	/* iterate to find better set time */
+	n.n_mjd = mjdn;
+	switch (find_0alt ((ls - lstn)/SIDRATE, dis, &n, &o)) {
+	case 0: /* ok */
+	    rp->rs_settm = n.n_mjd;
+	    rp->rs_setaz = o.s_az;
+	    break;
+	case -1: /* obj_cir error */
+	    rp->rs_flags |= RS_SETERR;
+	    break;
+	case -2: /* converged but not today */ /* FALLTHRU */
+	case -3: /* probably circumpolar */
+	    rp->rs_flags |= RS_NOSET;
+	    break;
+	}
+
+	/* can try transit even if rise or set failed */
+    dotransit:
+	n.n_mjd = mjdn;
+	switch (find_transit ((radhr(ran) - lstn)/SIDRATE, &n, &o)) {
+	case 0: /* ok */
+	    rp->rs_trantm = n.n_mjd;
+	    rp->rs_tranalt = o.s_alt;
+	    break;
+	case -1: /* did not converge */
+	    rp->rs_flags |= RS_TRANSERR;
+	    break;
+	case -2: /* converged but not today */
+	    rp->rs_flags |= RS_NOTRANS;
+	    break;
+	}
+}
+
+/* find local times when sun is dis rads below horizon.
+ */
+void
+twilight_cir (np, dis, dawn, dusk, status)
+Now *np;
+double dis;
+double *dawn, *dusk;
+int *status;
+{
+	RiseSet rs;
+	Obj o;
+
+	o.o_type = PLANET;
+	o.pl.pl_code = SUN;
+	(void) strcpy (o.o_name, "Sun");
+	riset_cir (np, &o, dis, &rs);
+	*dawn = rs.rs_risetm;
+	*dusk = rs.rs_settm;
+	*status = rs.rs_flags;
+}
+
+/* find where and when a fast-moving Earth satellite, op, will rise and set and
+ *   it's transit circumstances. all times are mjd, angles rads e of n.
+ * dis is the angle down from the local topo horizon, in rads (see riset()).
+ * idea is to walk forward in time looking for alt+dis==0 crossings.
+ * initial time step is a few degrees (based on average daily motion).
+ * we stop as soon as we see both a rise and set.
+ * N.B. we assume *np and *op are working copies we can mess up.
+ */
+static void
+e_riset_cir (np, op, dis, rp)
+Now *np;
+Obj *op;
+double dis;
+RiseSet *rp;
+{
+#define	DEGSTEP	5		/* time step is about this many degrees */
+	int steps;		/* max number of time steps */
+	double dt;		/* time change per step, days */
+	double t0, t1;		/* current and next mjd values */
+	double a0, a1;		/* altitude at t0 and t1 */
+	int rise, set;		/* flags to check when we find these events */
+	int i;
+
+	dt = DEGSTEP * (1.0/360.0/op->es_n);
+	steps = (int)(1.0/dt);
+	rise = set = 0;
+	rp->rs_flags = 0;
+
+	if (obj_cir (np, op) < 0) {
+	    rp->rs_flags |= RS_ERROR;
+	    return;
+	}
+
+	t0 = mjd;
+	a0 = op->s_alt + dis;
+
+	for (i = 0; i < steps && (!rise || !set); i++) {
+	    mjd = t1 = t0 + dt;
+	    if (obj_cir (np, op) < 0) {
+		rp->rs_flags |= RS_ERROR;
+		return;
+	    }
+	    a1 = op->s_alt + dis;
+
+	    if (a0 < 0 && a1 > 0 && !rise) {
+		/* found a rise event -- interate to refine */
+		switch (find_0alt (0.0, dis, np, op)) {
+		case 0: /* ok */
+		    rp->rs_risetm = np->n_mjd;
+		    rp->rs_riseaz = op->s_az;
+		    rise = 1;
+		    break;
+		case -1: /* obj_cir error */
+		    rp->rs_flags |= RS_RISERR;
+		    return;
+		case -2: /* converged but not today */ /* FALLTHRU */
+		case -3: /* probably never up */
+		    rp->rs_flags |= RS_NORISE;
+		    return;
+		}
+	    } else if (a0 > 0 && a1 < 0 && !set) {
+		/* found a setting event -- interate to refine */
+		switch (find_0alt (0.0, dis, np, op)) {
+		case 0: /* ok */
+		    rp->rs_settm = np->n_mjd;
+		    rp->rs_setaz = op->s_az;
+		    set = 1;
+		    break;
+		case -1: /* obj_cir error */
+		    rp->rs_flags |= RS_SETERR;
+		    return;
+		case -2: /* converged but not today */ /* FALLTHRU */
+		case -3: /* probably circumpolar */
+		    rp->rs_flags |= RS_NOSET;
+		    return;
+		}
+	    }
+
+	    t0 = t1;
+	    a0 = a1;
+	}
+
+	/* instead of transit, for satellites we find time of maximum
+	 * altitude, if we know both the rise and set times and the former
+	 * occurs before the latter.
+	 */
+	if (rise && set && rp->rs_risetm < rp->rs_settm) {
+	    double tt, al;
+	    if (find_max (np, op, rp->rs_risetm, rp->rs_settm, &tt, &al) < 0) {
+		rp->rs_flags |= RS_TRANSERR;
+		return;
+	    }
+	    rp->rs_trantm = tt;
+	    rp->rs_tranalt = al;
+	} else
+	    rp->rs_flags |= RS_NOTRANS;
+
+	/* check for some bad conditions */
+	if (!rise) {
+	    if (a0 > 0)
+		rp->rs_flags |= RS_CIRCUMPOLAR;
+	    else
+		rp->rs_flags |= RS_NORISE;
+	}
+	if (!set) {
+	    if (a0 < 0)
+		rp->rs_flags |= RS_NEVERUP;
+	    else
+		rp->rs_flags |= RS_NOSET;
+	}
+}
+
+/* given a Now at noon and a dt from noon, in hours, for a first approximation
+ * to a rise or set event, refine the event by searching for when alt+dis = 0.
+ * return 0: if find one within 12 hours of noon with np and op set to the
+ *    better time and circumstances;
+ * return -1: if error from obj_cir;
+ * return -2: if converges but not today;
+ * return -3: if does not converge at all (probably circumpolar or never up);
+ */
+static int
+find_0alt (dt, dis, np, op)
+double dt;	/* hours from noon to first guess at event */
+double dis;	/* horizon displacement, rads */
+Now *np;	/* working Now -- starts with mjd is noon, returns as answer */
+Obj *op;	/* working object -- returns as answer */
+{
+#define	MAXPASSES	20		/* max iterations to try */
+#define	FIRSTSTEP	(1.0/60.0/24.0)	/* first time step, days */
+
+	double a0 = 0;
+	double mjdn = mjd;
+	int npasses;
+
+	/* insure initial guess is today -- if not, move by 24 hours */
+	if (dt < -12.0)
+	    dt += 24.0;
+	if (dt > 12.0)
+	    dt -= 24.0;
+	
+	/* convert dt to days for remainder of algorithm */
+	dt /= 24.0;
+
+	/* use secant method to look for s_alt + dis == 0 */
+	npasses = 0;
+	do {
+	    double a1;
+
+	    mjd += dt;
+	    if (obj_cir (np, op) < 0)
+		return (-1);
+	    a1 = op->s_alt;
+
+	    dt = (npasses == 0) ? FIRSTSTEP : (dis+a1)*dt/(a0-a1);
+	    a0 = a1;
+
+	} while (++npasses < MAXPASSES && fabs(dt) > TMACC);
+
+	/* return codes */
+	if (npasses == MAXPASSES)
+	    return (-3);
+	return (fabs(mjdn-mjd) < .5 ? 0 : -2);
+
+#undef	MAXPASSES
+#undef	FIRSTSTEP
+}
+
+/* find when the given object transits. start the search when LST matches the
+ *   object's RA at noon.
+ * if ok, return 0 with np and op set to the transit conditions; if can't
+ *   converge return -1; if converges ok but not today return -2.
+ * N.B. we assume np is passed set to local noon.
+ */
+static int
+find_transit (dt, np, op)
+double dt;
+Now *np;
+Obj *op;
+{
+#define	MAXLOOPS	10
+#define	MAXERR		(0.25/60.)		/* hours */
+	double mjdn = mjd;
+	double lst;
+	int i;
+
+	/* insure initial guess is today -- if not, move by 24 hours */
+	if (dt < -12.0)
+	    dt += 24.0;
+	if (dt > 12.0)
+	    dt -= 24.0;
+
+	i = 0;
+	do {
+	    mjd += dt/24.0;
+	    if (obj_cir (np, op) < 0)
+		return (-1);
+	    now_lst (np, &lst);
+	    dt = (radhr(op->s_gaera) - lst);
+	    if (dt < -12.0)
+		dt += 24.0;
+	    if (dt > 12.0)
+		dt -= 24.0;
+	} while (++i < MAXLOOPS && fabs(dt) > MAXERR);
+
+	/* return codes */
+	if (i == MAXLOOPS)
+	    return (-1);
+	return (fabs(mjd - mjdn) < 0.5 ? 0 : -2);
+
+#undef	MAXLOOPS
+#undef	MAXERR
+}
+
+/* find the mjd time of max altitude between the given rise and set times.
+ * N.B. we assume *np and *op are working copies we can mess up.
+ * N.B. we just assume max occurs at the center time.
+ * return 0 if ok, else -1.
+ */
+static int
+find_max (np, op, tr, ts, tp, alp)
+Now *np;
+Obj *op;
+double tr, ts;		/* times of rise and set */
+double *tp, *alp;	/* time of max altitude, and that altitude */
+{
+	mjd = (ts + tr)/2;
+	if (obj_cir (np, op) < 0)
+	    return (-1);
+	*tp = mjd;
+	*alp = op->s_alt;
+	return (0);
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: riset_cir.c,v $ $Date: 2001-10-22 12:08:28 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/satlib.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/satlib.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/satlib.h	(revision 2309)
@@ -0,0 +1,206 @@
+#ifndef __SATLIB_H
+#define __SATLIB_H
+
+/* $Id: satlib.h,v 1.2 2001-10-22 12:08:28 cmv Exp $ */
+
+typedef struct _SatElem {
+    float  se_XMO;
+    float  se_XNODEO;
+    float  se_OMEGAO;
+    float  se_EO;
+    float  se_XINCL;
+    float  se_XNDD60;
+    float  se_BSTAR;
+    float  pad1;
+    double se_XNO;
+    double se_XNDT20;
+    double se_EPOCH;
+    struct {
+	unsigned int catno	: 21;
+	unsigned int classif	: 5;
+	unsigned int elnum	: 10;
+	unsigned int year	: 14;
+	unsigned int launch	: 10;
+	unsigned int piece	: 15;
+	unsigned int ephtype	: 4;
+	unsigned int orbit	: 17;
+    } se_id;
+} SatElem;
+
+#if 0
+struct sat_loc {
+    double sl_X;
+    double sl_XDOT;
+    double sl_Y;
+    double sl_YDOT;
+    double sl_Z;
+    double sl_ZDOT;
+};
+#endif
+
+struct sgp4_data {
+    unsigned int sgp4_flags;
+    unsigned int pad;
+    double sgp4_AODP;
+    double sgp4_AYCOF;
+    double sgp4_C1;
+    double sgp4_C4;
+    double sgp4_C5;
+    double sgp4_COSIO;
+    double sgp4_D2;
+    double sgp4_D3;
+    double sgp4_D4;
+    double sgp4_DELMO;
+    double sgp4_ETA;
+    double sgp4_OMGCOF;
+    double sgp4_OMGDOT;
+    double sgp4_SINIO;
+    double sgp4_SINMO;
+    double sgp4_T2COF;
+    double sgp4_T3COF;
+    double sgp4_T4COF;
+    double sgp4_T5COF;
+    double sgp4_X1MTH2;
+    double sgp4_X3THM1;
+    double sgp4_X7THM1;
+    double sgp4_XLCOF;
+    double sgp4_XMCOF;
+    double sgp4_XMDOT;
+    double sgp4_XNODCF;
+    double sgp4_XNODOT;
+    double sgp4_XNODP;
+};
+
+struct deep_data {
+    struct {
+	unsigned int IRESFL : 1;
+	unsigned int ISYNFL : 1;
+    } deep_flags;
+    double deep_s_SINIQ;
+    double deep_s_COSIQ;
+    double deep_s_OMGDT;
+    double deep_ATIME;
+    double deep_D2201;
+    double deep_D2211;
+    double deep_D3210;
+    double deep_D3222;
+    double deep_D4410;
+    double deep_D4422;
+    double deep_D5220;
+    double deep_D5232;
+    double deep_D5421;
+    double deep_D5433;
+    double deep_DEL1;
+    double deep_DEL2;
+    double deep_DEL3;
+    double deep_E3;
+    double deep_EE2;
+    double deep_FASX2;
+    double deep_FASX4;
+    double deep_FASX6;
+    double deep_OMEGAQ;
+    double deep_PE;
+    double deep_PINC;
+    double deep_PL;
+    double deep_SAVTSN;
+    double deep_SE2;
+    double deep_SE3;
+    double deep_SGH2;
+    double deep_SGH3;
+    double deep_SGH4;
+    double deep_SGHL;
+    double deep_SGHS;
+    double deep_SH2;
+    double deep_SH3;
+    double deep_SHS;
+    double deep_SHL;
+    double deep_SI2;
+    double deep_SI3;
+    double deep_SL2;
+    double deep_SL3;
+    double deep_SL4;
+    double deep_SSE;
+    double deep_SSG;
+    double deep_SSH;
+    double deep_SSI;
+    double deep_SSL;
+    double deep_STEP2;
+    double deep_STEPN;
+    double deep_STEPP;
+    double deep_THGR;
+    double deep_XFACT;
+    double deep_XGH2;
+    double deep_XGH3;
+    double deep_XGH4;
+    double deep_XH2;
+    double deep_XH3;
+    double deep_XI2;
+    double deep_XI3;
+    double deep_XL2;
+    double deep_XL3;
+    double deep_XL4;
+    double deep_XLAMO;
+    double deep_XLI;
+    double deep_XNI;
+    double deep_XNQ;
+    double deep_XQNCL;
+    double deep_ZMOL;
+    double deep_ZMOS;
+};
+
+struct sdp4_data {
+    double sdp4_AODP;	/* dpa */
+    double sdp4_AYCOF;
+    double sdp4_BETAO;	/* dpa */
+    double sdp4_BETAO2;	/* dpa */
+    double sdp4_C1;
+    double sdp4_C4;
+    double sdp4_COSG;	/* dpa */
+    double sdp4_COSIO;	/* dpa */
+    double sdp4_EOSQ;	/* dpa */
+    double sdp4_OMGDOT;	/* dpa */
+    double sdp4_SING;	/* dpa */
+    double sdp4_SINIO;	/* dpa */
+    double sdp4_T2COF;
+    double sdp4_THETA2;	/* dpa */
+    double sdp4_X1MTH2;
+    double sdp4_X3THM1;
+    double sdp4_X7THM1;
+    double sdp4_XLCOF;
+    double sdp4_XMDOT;	/* dpa */
+    double sdp4_XNODCF;
+    double sdp4_XNODOT;	/* dpa */
+    double sdp4_XNODP;	/* dpa */
+
+    double sdp4_XMDF_seco;
+    double sdp4_OMGADF_seco;
+    double sdp4_XNODE_seco;
+    double sdp4_EM_seco;
+    double sdp4_XINC_seco;
+    double sdp4_XN_seco;
+
+    double sdp4_E_pero;
+    double sdp4_XINC_pero;
+    double sdp4_OMGADF_pero;
+    double sdp4_XNODE_pero;
+    double sdp4_XMAM_pero;
+};
+
+typedef struct _SatData {
+    struct _SatElem *elem;
+    union {
+	struct sgp4_data *sgp4;
+	struct sdp4_data *sdp4;
+    } prop;
+    struct deep_data *deep;
+} SatData;
+
+void sgp4(SatData *sat, Vec3 *pos, Vec3 *dpos, double t);
+
+void sdp4(SatData *sat, Vec3 *pos, Vec3 *dpos, double TSINCE);
+
+#endif /* __SATLIB_H */
+
+/* For RCS Only -- Do Not Edit
+ * @(#) $RCSfile: satlib.h,v $ $Date: 2001-10-22 12:08:28 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $
+ */
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/satspec.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/satspec.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/satspec.h	(revision 2309)
@@ -0,0 +1,43 @@
+#ifndef __SATSPEC_H
+#define __SATSPEC_H
+
+/* $Id: satspec.h,v 1.2 2001-10-22 12:08:28 cmv Exp $ */
+
+#include "sattypes.h"
+#include "satlib.h"
+
+#define SGP4_SIMPLE	0x00000001
+
+extern void init_deep(struct deep_data *deep);
+void init_sdp4(struct sdp4_data *sdp);
+char *tleerr(int);
+int readtle(char *, char *, SatElem *);
+
+double current_jd();
+
+double ut1_to_gha(double);
+
+void smallsleep(double t);
+
+double epoch_jd(double);
+
+double actan(double sinx, double cosx);
+
+double thetag(double EP, double *DS50);
+
+void dpinit(SatData *sat, double EQSQ, double SINIQ, double COSIQ,
+	    double RTEQSQ, double AO, double COSQ2, double SINOMO,
+	    double COSOMO, double BSQ, double XLLDOT, double OMGDT,
+	    double XNODOT, double XNODP);
+
+void dpsec(SatData *sat, double *XLL, double *OMGASM, double *XNODES,
+	   double *EM, double *XINC, double *XN, double T);
+
+void dpper(SatData *sat, double *EM, double *XINC, double *OMGASM,
+	   double *XNODES, double *XLL, double T);
+
+#endif /* __SATSPEC_H */
+
+/* For RCS Only -- Do Not Edit
+ * @(#) $RCSfile: satspec.h,v $ $Date: 2001-10-22 12:08:28 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $
+ */
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/sattypes.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/sattypes.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/sattypes.h	(revision 2309)
@@ -0,0 +1,28 @@
+#ifndef __SATTYPES_H
+#define __SATTYPES_H
+
+/* $Id: sattypes.h,v 1.2 2001-10-22 12:08:28 cmv Exp $ */
+
+typedef struct _Vec3 {
+    double x, y, z;
+} Vec3;
+
+
+typedef struct _LookAngle {
+    double az;
+    double el;
+    double r;
+} LookAngle;
+
+
+typedef struct _Geoloc {
+    double lt;
+    double ln;
+    double h;
+} GeoLoc;
+
+#endif /* __SATTYPES_H */
+
+/* For RCS Only -- Do Not Edit
+ * @(#) $RCSfile: sattypes.h,v $ $Date: 2001-10-22 12:08:28 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $
+ */
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/sdp4.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/sdp4.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/sdp4.c	(revision 2309)
@@ -0,0 +1,434 @@
+#include <stdlib.h>
+#include <math.h>
+#undef SING
+
+#include "sattypes.h"
+#include "vector.h"
+#include "satspec.h"
+
+/*      SDP4                                               3 NOV 80 */
+/*      SUBROUTINE SDP4(IFLAG,TSINCE)
+      COMMON/E1/XMO,XNODEO,OMEGAO,EO,XINCL,XNO,XNDT2O,
+     1           XNDD6O,BSTAR,X,Y,Z,XDOT,YDOT,ZDOT,EPOCH,DS50
+      COMMON/C1/CK2,CK4,E6A,QOMS2T,S,TOTHRD,
+     1           XJ3,XKE,XKMPER,XMNPDA,AE
+      DOUBLE PRECISION EPOCH, DS50
+      */
+
+#define XMO	(sat->elem->se_XMO)
+#define XNODEO	(sat->elem->se_XNODEO)
+#define OMEGAO	(sat->elem->se_OMEGAO)
+#define EO	(sat->elem->se_EO)
+#define XINCL	(sat->elem->se_XINCL)
+#define XNO	(sat->elem->se_XNO)
+#define XNDT20	(sat->elem->se_XNDT20)
+#define XNDD60	(sat->elem->se_XNDD60)
+#define BSTAR	(sat->elem->se_BSTAR)
+#define EPOCH	(sat->elem->se_EPOCH)
+
+#define CK2	(5.413080e-04)
+#define CK4	(6.209887e-07)
+#define QOMS2T	(1.880279e-09)
+#define S	(1.012229e+00)
+
+#define AE (1.0)
+#define DE2RA (.174532925E-1)
+#define E6A (1.E-6)
+#define PI (3.14159265)
+#define PIO2 (1.57079633)
+#define QO (120.0)
+#define SO (78.0)
+#define TOTHRD (.66666667)
+#define TWOPI (6.2831853)
+#define X3PIO2 (4.71238898)
+#define XJ2 (1.082616E-3)
+#define XJ3 (-.253881E-5)
+#define XJ4 (-1.65597E-6)
+#define XKE (.743669161E-1)
+#define XKMPER (6378.135)
+#define XMNPDA (1440.)
+
+/* int IFLAG; */
+
+#define X	(pos->sl_X)
+#define XDOT	(pos->sl_XDOT)
+#define Y	(pos->sl_Y)
+#define YDOT	(pos->sl_YDOT)
+#define Z	(pos->sl_Z)
+#define ZDOT	(pos->sl_ZDOT)
+
+/* sat->prop.sdp4-> */
+#define AODP	(sat->prop.sdp4->sdp4_AODP)
+#define AYCOF	(sat->prop.sdp4->sdp4_AYCOF)
+#define BETAO	(sat->prop.sdp4->sdp4_BETAO)
+#define BETAO2	(sat->prop.sdp4->sdp4_BETAO2)
+#define C1	(sat->prop.sdp4->sdp4_C1)
+#define C4	(sat->prop.sdp4->sdp4_C4)
+#define COSG	(sat->prop.sdp4->sdp4_COSG)
+#define COSIO	(sat->prop.sdp4->sdp4_COSIO)
+#define EOSQ	(sat->prop.sdp4->sdp4_EOSQ)
+#define OMGDOT	(sat->prop.sdp4->sdp4_OMGDOT)
+#define SING	(sat->prop.sdp4->sdp4_SING)
+#define SINIO	(sat->prop.sdp4->sdp4_SINIO)
+#define T2COF	(sat->prop.sdp4->sdp4_T2COF)
+#define THETA2	(sat->prop.sdp4->sdp4_THETA2)
+#define X1MTH2	(sat->prop.sdp4->sdp4_X1MTH2)
+#define X3THM1	(sat->prop.sdp4->sdp4_X3THM1)
+#define X7THM1	(sat->prop.sdp4->sdp4_X7THM1)
+#define XLCOF	(sat->prop.sdp4->sdp4_XLCOF)
+#define XMDOT	(sat->prop.sdp4->sdp4_XMDOT)
+#define XNODCF	(sat->prop.sdp4->sdp4_XNODCF)
+#define XNODOT	(sat->prop.sdp4->sdp4_XNODOT)
+#define XNODP	(sat->prop.sdp4->sdp4_XNODP)
+
+#define XMDF_seco   (sat->prop.sdp4->sdp4_XMDF_seco)
+#define OMGADF_seco (sat->prop.sdp4->sdp4_OMGADF_seco)
+#define XNODE_seco  (sat->prop.sdp4->sdp4_XNODE_seco)
+#define EM_seco     (sat->prop.sdp4->sdp4_EM_seco)
+#define XINC_seco   (sat->prop.sdp4->sdp4_XINC_seco)
+#define XN_seco     (sat->prop.sdp4->sdp4_XN_seco)
+
+#define E_pero      (sat->prop.sdp4->sdp4_E_pero)
+#define XINC_pero   (sat->prop.sdp4->sdp4_XINC_pero)
+#define OMGADF_pero (sat->prop.sdp4->sdp4_OMGADF_pero)
+#define XNODE_pero  (sat->prop.sdp4->sdp4_XNODE_pero)
+#define XMAM_pero   (sat->prop.sdp4->sdp4_XMAM_pero)
+
+void
+sdp4 (sat, pos, dpos, TSINCE)
+SatData *sat;
+Vec3 *pos;
+Vec3 *dpos;
+double TSINCE;
+{
+    int i;
+
+    /* private temporary variables used only in init section */
+    double A1,A3OVK2,AO,C2,COEF,COEF1,DEL1,DELO,EETA,ETA,
+	ETASQ,PERIGE,PINVSQ,PSISQ,QOMS24,S4,THETA4,TSI,X1M5TH,XHDOT1;
+
+    /* private temporary variables */
+    double A,AXN,AYN,AYNL,BETA,BETAL,CAPU,COS2U,COSEPW,
+	COSIK,COSNOK,COSU,COSUK,E,ECOSE,ELSQ,EM=0,EPW,ESINE,OMGADF,PL,
+	R,RDOT,RDOTK,RFDOT,RFDOTK,RK,SIN2U,SINEPW,SINIK,SINNOK,
+	SINU,SINUK,TEMP,TEMP1,TEMP2,TEMP3,TEMP4,TEMP5,TEMP6,TEMPA,
+	TEMPE,TEMPL,TSQ,U,UK,UX,UY,UZ,VX,VY,VZ,XINC=0,XINCK,XL,XLL,XLT,
+	XMAM,XMDF,XMX,XMY,XN,XNODDF,XNODE,XNODEK;
+
+#if 0
+    A1=A3OVK2=AO=C2=COEF=COEF1=DEL1=DELO=EETA=ETA = signaling_nan();
+    ETASQ=PERIGE=PINVSQ=PSISQ=QOMS24=S4=THETA4=TSI=X1M5TH=XHDOT1 = signaling_nan();
+
+     A=AXN=AYN=AYNL=BETA=BETAL=CAPU=COS2U=COSEPW = signaling_nan();
+     COSIK=COSNOK=COSU=COSUK=E=ECOSE=ELSQ=EM=EPW=ESINE=OMGADF=PL = signaling_nan();
+     R=RDOT=RDOTK=RFDOT=RFDOTK=RK=SIN2U=SINEPW=SINIK=SINNOK = signaling_nan();
+     SINU=SINUK=TEMP=TEMP1=TEMP2=TEMP3=TEMP4=TEMP5=TEMP6=TEMPA = signaling_nan();
+     TEMPE=TEMPL=TSQ=U=UK=UX=UY=UZ=VX=VY=VZ=XINC=XINCK=XL=XLL=XLT = signaling_nan();
+     XMAM=XMDF=XMX=XMY=XN=XNODDF=XNODE=XNODEK = signaling_nan();
+#endif
+
+    if(TSINCE != 0.0 && !sat->prop.sdp4) {
+	/*
+	 * Yes, this is a recursive call.
+	 */
+	sdp4(sat, pos, dpos, 0.0);
+    }
+
+/*      IF  (IFLAG .EQ. 0) GO TO 100 */
+/*    if(!IFLAG) */
+    if(!sat->prop.sdp4) {
+	sat->prop.sdp4 = (struct sdp4_data *) malloc(sizeof(struct sdp4_data));
+
+/*	init_sdp4(sat->prop.sdp4); */
+
+/*      RECOVER ORIGINAL MEAN MOTION (XNODP) AND SEMIMAJOR AXIS (AODP) */
+/*      FROM INPUT ELEMENTS */
+
+	A1=pow((XKE/XNO), TOTHRD);
+	COSIO=cos(XINCL);
+	THETA2=COSIO*COSIO;
+	X3THM1=3.0 * THETA2 - 1.0;
+	EOSQ = EO * EO;
+	BETAO2 = 1.0 - EOSQ;
+	BETAO = sqrt(BETAO2);
+	DEL1 = 1.5 * CK2 * X3THM1 / (A1 * A1 * BETAO * BETAO2);
+	AO = A1 * (1.0 - DEL1 * (0.5 * TOTHRD +
+				DEL1 * (1.0 + 134.0 / 81.0 * DEL1)));
+	DELO = 1.5 * CK2 * X3THM1 / (AO * AO * BETAO * BETAO2);
+	XNODP = XNO / (1.0 + DELO);
+	AODP = AO / (1.0 - DELO);
+
+/*      INITIALIZATION */
+
+/*      FOR PERIGEE BELOW 156 KM, THE VALUES OF
+*      S AND QOMS2T ARE ALTERED */
+
+	S4 = S;
+	QOMS24 = QOMS2T;
+	PERIGE = (AODP * (1.0 - EO) - AE) * XKMPER;
+
+/*      IF(PERIGE .GE. 156.) GO TO 10 */
+
+	if(PERIGE < 156.0) {
+	    S4 = PERIGE - 78.0;
+
+	    if(PERIGE <= 98.0)  { /* GO TO 9 */
+		S4 = 20.0;
+	    }
+
+	    QOMS24 = pow((120.0 - S4) * AE / XKMPER, 4.0); /* 9 */
+	    S4 = S4 / XKMPER + AE;
+	}
+	PINVSQ = 1.0 / (AODP * AODP * BETAO2 * BETAO2); /* 10 */
+	SING = sin(OMEGAO);
+	COSG = cos(OMEGAO);
+	TSI = 1.0 / (AODP - S4);
+	ETA = AODP * EO * TSI;
+	ETASQ = ETA * ETA;
+	EETA = EO * ETA;
+	PSISQ = fabs(1.0 - ETASQ);
+	COEF = QOMS24 * pow(TSI, 4.0);
+	COEF1 = COEF / pow(PSISQ, 3.5);
+	C2 = COEF1 * XNODP * (AODP * (1.0 + 1.5 * ETASQ +
+				      EETA * (4.0 + ETASQ)) +
+			      .75 * CK2 * TSI / PSISQ * X3THM1 *
+			      (8.0 + 3.0 * ETASQ * (8.0 + ETASQ)));
+	C1 = BSTAR * C2;
+	SINIO = sin(XINCL);
+	A3OVK2 = -XJ3 / CK2 * AE * AE * AE; /* A3OVK2=-XJ3/CK2*AE**3; */
+	X1MTH2 = 1.0 - THETA2;
+	C4 = 2.0 * XNODP * COEF1 * AODP * BETAO2 *
+	    (ETA * (2.0 + .5 * ETASQ) + EO * (.5 + 2.0 * ETASQ) -
+	     2.0 * CK2 * TSI / (AODP * PSISQ) *
+	     (-3.0 * X3THM1 * (1.0 - 2.0 * EETA + ETASQ *
+			       (1.5 - .5 * EETA)) +
+	      .75 * X1MTH2 * (2.0 * ETASQ - EETA *
+			      (1.0 + ETASQ)) * cos(2.0 * OMEGAO)));
+	THETA4 = THETA2 * THETA2;
+	TEMP1 = 3.0 * CK2 * PINVSQ * XNODP;
+	TEMP2 = TEMP1 * CK2 * PINVSQ;
+	TEMP3 = 1.25 * CK4 * PINVSQ * PINVSQ * XNODP;
+	XMDOT = XNODP + 0.5 * TEMP1 * BETAO * X3THM1 + .0625 * TEMP2 * BETAO *
+	    (13.0 - 78.0 * THETA2 + 137.0 * THETA4);
+	X1M5TH=1.0 - 5.0 * THETA2;
+	OMGDOT = -.5 * TEMP1 * X1M5TH + .0625 * TEMP2 * 
+	    (7.0 - 114.0 * THETA2 + 395.0 * THETA4) +
+	    TEMP3 * (3.0 - 36.0 * THETA2 + 49.0 * THETA4);
+	XHDOT1 = -TEMP1 * COSIO;
+	XNODOT = XHDOT1 + (.5 * TEMP2 * (4.0 - 19.0 * THETA2) +
+			   2.0 * TEMP3 * (3.0 - 7.0 * THETA2)) * COSIO;
+	XNODCF = 3.5 * BETAO2 * XHDOT1 * C1;
+	T2COF = 1.5 * C1;
+	XLCOF = .125 * A3OVK2 * SINIO * (3.0 + 5.0 * COSIO) / (1.0 + COSIO);
+	AYCOF = .25 * A3OVK2 * SINIO;
+	X7THM1 = 7.0 * THETA2 - 1.0;
+/*   90 IFLAG=0 */
+
+#ifdef SDP_DEEP_DEBUG
+	printf("calling dpinit\n");
+	printf("%f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f\n",
+	       EOSQ,SINIO,COSIO,BETAO,AODP,THETA2,
+	       SING,COSG,BETAO2,XMDOT,OMGDOT,XNODOT,XNODP);
+#endif
+	dpinit(sat, EOSQ, SINIO, COSIO, BETAO, AODP, THETA2,
+	       SING, COSG, BETAO2, XMDOT, OMGDOT, XNODOT, XNODP);
+
+/*      CALL DPINIT(EOSQ,SINIO,COSIO,BETAO,AODP,THETA2,
+	1         SING,COSG,BETAO2,XMDOT,OMGDOT,XNODOT,XNODP) */
+
+/*      UPDATE FOR SECULAR GRAVITY AND ATMOSPHERIC DRAG */
+    }
+
+    XMDF = XMO + XMDOT * TSINCE; /* 100 */
+    OMGADF = OMEGAO + OMGDOT * TSINCE;
+    XNODDF = XNODEO + XNODOT * TSINCE;
+    TSQ = TSINCE * TSINCE;
+    XNODE = XNODDF + XNODCF * TSQ;
+    TEMPA = 1.0 - C1 * TSINCE;
+    TEMPE = BSTAR * C4 * TSINCE;
+    TEMPL = T2COF * TSQ;
+    XN = XNODP;
+
+    if(TSINCE == 0.0) {
+	XMDF_seco   = XMDF;
+	OMGADF_seco = OMGADF;
+	XNODE_seco  = XNODE;
+	EM_seco     = EM;
+	XINC_seco   = XINC;
+	XN_seco     = XN;
+    }
+
+    dpsec(sat, &XMDF, &OMGADF, &XNODE, &EM, &XINC, &XN, TSINCE);
+
+    if(TSINCE == 0.0) {
+	XMDF_seco   = XMDF - XMDF_seco;
+	OMGADF_seco = OMGADF - OMGADF_seco;
+	XNODE_seco  = XNODE - XNODE_seco;
+	EM_seco     = EM - EM_seco;
+	XINC_seco   = XINC - XINC_seco;
+	XN_seco     = XN - XN_seco;
+
+#if 0
+	printf("XMDF_seco   = %e\n", XMDF_seco);
+	printf("OMGADF_seco = %e\n", OMGADF_seco);
+	printf("XNODE_seco  = %e\n", XNODE_seco);
+	printf("EM_seco     = %e\n", EM_seco);
+	printf("XINC_seco   = %e\n", XINC_seco);
+	printf("XN_seco     = %e\n", XN_seco);
+#endif
+    }
+
+    /*
+    XMDF   -= XMDF_seco;
+    OMGADF -= OMGADF_seco;
+    XNODE  -= XNODE_seco;
+    EM     -= EM_seco;
+    XINC   -= XINC_seco;
+    XN     -= XN_seco;
+    */
+
+    A = pow(XKE/XN, TOTHRD) * TEMPA * TEMPA;
+    E = EM - TEMPE;
+#ifdef SDP_DEEP_DEBUG
+    printf("*** E = %f\n", E);
+#endif
+    XMAM = XMDF + XNODP * TEMPL;
+/*      CALL DPPER(E,XINC,OMGADF,XNODE,XMAM) */
+
+#ifdef SDP_DEEP_DEBUG
+    printf("%12s %12s %12s %12s %12s\n",
+	   "E", "XINC", "OMGADF", "XNODE", "XMAM");
+    printf("%12f %12f %12f %12f %12f\n",
+	   E, XINC, OMGADF, XNODE, XMAM);
+#endif
+
+    if(TSINCE == 0.0) {
+	E_pero      = E;
+	XINC_pero   = XINC;
+	OMGADF_pero = OMGADF;
+	XNODE_pero  = XNODE;
+	XMAM_pero   = XMAM;
+    }
+
+    dpper(sat, &E, &XINC, &OMGADF, &XNODE, &XMAM, TSINCE);
+
+    if(TSINCE == 0.0) {
+	E_pero      = E - E_pero;
+	XINC_pero   = XINC - XINC_pero;
+	OMGADF_pero = OMGADF - OMGADF_pero;
+	XNODE_pero  = XNODE - XNODE_pero;
+	XMAM_pero   = XMAM - XMAM_pero;
+
+#if 0
+	printf("E_pero      = %e\n", E_pero);
+	printf("XINC_pero   = %e\n", XINC_pero);
+	printf("OMGADF_pero = %e\n", OMGADF_pero);
+	printf("XNODE_pero  = %e\n", XNODE_pero);
+	printf("XMAM_pero   = %e\n\n", XMAM_pero);
+#endif
+    }
+
+    /*
+    E      -= E_pero;
+    XINC   -= XINC_pero;
+    OMGADF -= OMGADF_pero;
+    XNODE  -= XNODE_pero;
+    XMAM   -= XMAM_pero;
+    */
+    XL = XMAM + OMGADF + XNODE;
+    BETA = sqrt(1.0 - E * E);
+    XN = XKE / pow(A, 1.5);
+
+/*      LONG PERIOD PERIODICS */
+
+    AXN = E * cos(OMGADF);
+    TEMP=1./(A*BETA*BETA);
+    XLL=TEMP*XLCOF*AXN;
+    AYNL=TEMP*AYCOF;
+    XLT=XL+XLL;
+    AYN=E*sin(OMGADF)+AYNL;
+
+/*      SOLVE KEPLERS EQUATION */
+
+    CAPU=fmod(XLT-XNODE, TWOPI);
+    TEMP2=CAPU;
+/*      DO 130 I=1,10*/
+    for(i = 1; i < 10; i++) {
+	SINEPW=sin(TEMP2);
+      COSEPW=cos(TEMP2);
+      TEMP3=AXN*SINEPW;
+      TEMP4=AYN*COSEPW;
+      TEMP5=AXN*COSEPW;
+      TEMP6=AYN*SINEPW;
+      EPW=(CAPU-TEMP4+TEMP3-TEMP2)/(1.-TEMP5-TEMP6)+TEMP2;
+/*      IF(ABS(EPW-TEMP2) .LE. E6A) GO TO 140 */
+      if(fabs(EPW-TEMP2) <= E6A)
+	  break;
+      TEMP2=EPW; /* 130 */
+    }
+
+/*      SHORT PERIOD PRELIMINARY QUANTITIES */
+
+    ECOSE=TEMP5+TEMP6; /* 140  */
+    ESINE=TEMP3-TEMP4;
+    ELSQ=AXN*AXN+AYN*AYN;
+    TEMP=1.-ELSQ;
+    PL=A*TEMP;
+    R=A*(1.-ECOSE);
+    TEMP1=1./R;
+    RDOT=XKE*sqrt(A)*ESINE*TEMP1;
+    RFDOT=XKE*sqrt(PL)*TEMP1;
+    TEMP2=A*TEMP1;
+    BETAL=sqrt(TEMP);
+    TEMP3=1./(1.+BETAL);
+    COSU=TEMP2*(COSEPW-AXN+AYN*ESINE*TEMP3);
+    SINU=TEMP2*(SINEPW-AYN-AXN*ESINE*TEMP3);
+    U=actan(SINU,COSU);
+    SIN2U=2.*SINU*COSU;
+    COS2U=2.*COSU*COSU-1.0;
+    TEMP=1./PL;
+    TEMP1=CK2*TEMP;
+    TEMP2=TEMP1*TEMP;
+
+/*      UPDATE FOR SHORT PERIODICS */
+
+    RK=R*(1.-1.5*TEMP2*BETAL*X3THM1)+.5*TEMP1*X1MTH2*COS2U;
+    UK=U - .25 * TEMP2 * X7THM1 * SIN2U;
+    XNODEK=XNODE+1.5*TEMP2*COSIO*SIN2U;
+    XINCK=XINC+1.5*TEMP2*COSIO*SINIO*COS2U;
+    RDOTK=RDOT-XN*TEMP1*X1MTH2*SIN2U;
+    RFDOTK=RFDOT+XN*TEMP1*(X1MTH2*COS2U+1.5*X3THM1);
+
+/*      ORIENTATION VECTORS */
+    SINUK=sin(UK);
+    COSUK=cos(UK);
+    SINIK=sin(XINCK);
+    COSIK=cos(XINCK);
+    SINNOK=sin(XNODEK);
+    COSNOK=cos(XNODEK);
+    XMX=-SINNOK*COSIK;
+    XMY=COSNOK*COSIK;
+    UX=XMX*SINUK+COSNOK*COSUK;
+    UY=XMY*SINUK+SINNOK*COSUK;
+    UZ=SINIK*SINUK;
+    VX=XMX*COSUK-COSNOK*SINUK;
+    VY=XMY*COSUK-SINNOK*SINUK;
+    VZ=SINIK*COSUK;
+#if 0
+    printf("UX = %f VX = %f RK = %f RDOTK = %f RFDOTK = %f\n",
+	   UX, VX, RK, RDOTK, RFDOTK);
+#endif
+/*      POSITION AND VELOCITY */
+
+    pos->x = RK*UX;
+    pos->y = RK*UY;
+    pos->z = RK*UZ;
+    dpos->x = RDOTK*UX+RFDOTK*VX;
+    dpos->y = RDOTK*UY+RFDOTK*VY;
+    dpos->z = RDOTK*UZ+RFDOTK*VZ;
+/*      RETURN
+      END */
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: sdp4.c,v $ $Date: 2001-10-22 12:08:28 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/sgp4.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/sgp4.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/sgp4.c	(revision 2309)
@@ -0,0 +1,405 @@
+#include <stdlib.h>
+#include <math.h>
+
+#include "sattypes.h"
+#include "vector.h"
+#include "satspec.h"
+
+#define XMO (sat->elem->se_XMO)
+#define XNODEO (sat->elem->se_XNODEO)
+#define OMEGAO (sat->elem->se_OMEGAO)
+#define EO (sat->elem->se_EO)
+#define XINCL (sat->elem->se_XINCL)
+#define XNO (sat->elem->se_XNO)
+#define XNDT20 (sat->elem->se_XNDT20)
+#define XNDD60 (sat->elem->se_XNDD60)
+#define BSTAR (sat->elem->se_BSTAR)
+#define EPOCH (sat->elem->se_EPOCH)
+
+#define X (pos->sl_X)
+#define XDOT (pos->sl_XDOT)
+#define Y (pos->sl_Y)
+#define YDOT (pos->sl_YDOT)
+#define Z (pos->sl_Z)
+#define ZDOT (pos->sl_ZDOT)
+
+#define AODP (sat->prop.sgp4->sgp4_AODP)
+#define AYCOF (sat->prop.sgp4->sgp4_AYCOF)
+#define C1 (sat->prop.sgp4->sgp4_C1)
+#define C4 (sat->prop.sgp4->sgp4_C4)
+#define C5 (sat->prop.sgp4->sgp4_C5)
+#define COSIO (sat->prop.sgp4->sgp4_COSIO)
+#define D2 (sat->prop.sgp4->sgp4_D2)
+#define D3 (sat->prop.sgp4->sgp4_D3)
+#define D4 (sat->prop.sgp4->sgp4_D4)
+#define DELMO (sat->prop.sgp4->sgp4_DELMO)
+#define ETA (sat->prop.sgp4->sgp4_ETA)
+#define OMGCOF (sat->prop.sgp4->sgp4_OMGCOF)
+#define OMGDOT (sat->prop.sgp4->sgp4_OMGDOT)
+#define SINIO (sat->prop.sgp4->sgp4_SINIO)
+#define SINMO (sat->prop.sgp4->sgp4_SINMO)
+#define T2COF (sat->prop.sgp4->sgp4_T2COF)
+#define T3COF (sat->prop.sgp4->sgp4_T3COF)
+#define T4COF (sat->prop.sgp4->sgp4_T4COF)
+#define T5COF (sat->prop.sgp4->sgp4_T5COF)
+#define X1MTH2 (sat->prop.sgp4->sgp4_X1MTH2)
+#define X3THM1 (sat->prop.sgp4->sgp4_X3THM1)
+#define X7THM1 (sat->prop.sgp4->sgp4_X7THM1)
+#define XLCOF (sat->prop.sgp4->sgp4_XLCOF)
+#define XMCOF (sat->prop.sgp4->sgp4_XMCOF)
+#define XMDOT (sat->prop.sgp4->sgp4_XMDOT)
+#define XNODCF (sat->prop.sgp4->sgp4_XNODCF)
+#define XNODOT (sat->prop.sgp4->sgp4_XNODOT)
+#define XNODP (sat->prop.sgp4->sgp4_XNODP)
+
+#define CK2	 (5.413080e-04)
+#define CK4	 (6.209887e-07)
+#define QOMS2T	 (1.880279e-09)
+#define S	 (1.012229e+00)
+
+#define AE (1.0)
+#define DE2RA (.174532925E-1)
+#define E6A (1.E-6)
+#define PI (3.14159265)
+#define PIO2 (1.57079633)
+#define QO (120.0)
+#define SO (78.0)
+#define TOTHRD (.66666667)
+#define TWOPI (6.2831853)
+#define X3PIO2 (4.71238898)
+#define XJ2 (1.082616E-3)
+#define XJ3 (-.253881E-5)
+#define XJ4 (-1.65597E-6)
+#define XKE (.743669161E-1)
+#define XKMPER (6378.135)
+#define XMNPDA (1440.0)
+
+/* compute position and velocity vectors for the satellite defined in sat->elem
+ * at its epoch + TSINCE.
+ */
+void
+sgp4(sat, pos, dpos, TSINCE)
+SatData *sat;
+Vec3 *pos;
+Vec3 *dpos;
+double TSINCE;
+{
+    int i;
+
+    double A1, A3OVK2, AO, BETAO, BETAO2, C1SQ, C2, C3, COEF, COEF1,
+	DEL1, DELO, EETA, EOSQ, ETASQ, PERIGE, PINVSQ, PSISQ, QOMS24,
+	S4, TEMP, TEMP1, TEMP2, TEMP3, THETA2, THETA4, TSI, X1M5TH,
+	XHDOT1;
+
+    double A, AXN, AYN, AYNL, BETA, BETAL, CAPU, COS2U, COSEPW, COSIK,
+	COSNOK, COSU, COSUK, DELM, DELOMG, E, ECOSE, ELSQ, EPW, ESINE,
+	OMEGA, OMGADF, PL, R, RDOT, RDOTK, RFDOT, RFDOTK, RK, SIN2U,
+	SINEPW, SINIK, SINNOK, SINU, SINUK, TCUBE, TEMP4, TEMP5, TEMP6,
+	TEMPA, TEMPE, TEMPL, TFOUR, TSQ, U, UK, UX, UY, UZ, VX, VY, VZ,
+	XINCK, XL, XLL, XLT, XMDF, XMP, XMX, XMY, XN, XNODDF, XNODE,
+	XNODEK;
+
+#if 0
+    A1 = A3OVK2 = AO = BETAO = BETAO2 = C1SQ = C2 = C3 = COEF = COEF1 =
+	DEL1 = DELO = EETA = EOSQ = ETASQ = PERIGE = PINVSQ = PSISQ = QOMS24 =
+	S4 = TEMP = TEMP1 = TEMP2 = TEMP3 = THETA2 = THETA4 = TSI = X1M5TH =
+	XHDOT1 = signaling_nan();
+
+    A = AXN = AYN = AYNL = BETA = BETAL = CAPU = COS2U = COSEPW = COSIK =
+	COSNOK = COSU = COSUK = DELM = DELOMG = E = ECOSE = ELSQ = EPW =
+	ESINE =	OMEGA = OMGADF = PL = R = RDOT = RDOTK = RFDOT = RFDOTK =
+	RK = SIN2U = SINEPW = SINIK = SINNOK = SINU = SINUK = TCUBE = TEMP4 =
+	TEMP5 = TEMP6 =	TEMPA = TEMPE = TEMPL = TFOUR = TSQ = U = UK = UX =
+	UY = UZ = VX = VY = VZ = XINCK = XL = XLL = XLT = XMDF = XMP = XMX =
+	XMY = XN = XNODDF = XNODE = XNODEK = signaling_nan();
+#endif
+
+    if(!sat->prop.sgp4) {
+	sat->prop.sgp4 = (struct sgp4_data *) malloc(sizeof(struct sgp4_data));
+
+	/*
+	 * RECOVER ORIGINAL MEAN MOTION (XNODP) AND SEMIMAJOR AXIS (AODP)
+	 * FROM INPUT ELEMENTS
+	 */
+
+	A1 = pow((XKE/XNO), TOTHRD);
+	COSIO = cos(XINCL);
+	THETA2 = COSIO * COSIO;
+	X3THM1 = 3.0 * THETA2 - 1.0;
+	EOSQ = EO * EO;
+	BETAO2 = 1.0 - EOSQ;
+	BETAO = sqrt(BETAO2);
+	DEL1 = 1.5 * CK2 * X3THM1 / (A1 * A1 * BETAO * BETAO2);
+	AO = A1 * (1.0 - DEL1 * (.5 * TOTHRD +
+				 DEL1 * (1.0 + 134.0 /81.0 * DEL1)));
+	DELO = 1.5 * CK2 * X3THM1 / (AO * AO * BETAO * BETAO2);
+	XNODP = XNO / (1.0 + DELO);
+	AODP=AO / (1.0 - DELO);
+
+	/*
+	 * INITIALIZATION
+	 *
+	 * FOR PERIGEE LESS THAN 220 KILOMETERS, THE ISIMP FLAG IS SET AND
+	 * THE EQUATIONS ARE TRUNCATED TO LINEAR VARIATION IN SQRT A AND
+	 * QUADRATIC VARIATION IN MEAN ANOMALY.  ALSO, THE C3 TERM, THE
+	 * DELTA OMEGA TERM, AND THE DELTA M TERM ARE DROPPED.
+	 */
+
+	sat->prop.sgp4->sgp4_flags = 0;
+
+	/* IF((AODP*(1.-EO)/AE) .LT. (220./XKMPER+AE)) ISIMP=1 */
+
+	if((AODP * (1.0 - EO) / AE) < (220.0 / XKMPER + AE))
+	    sat->prop.sgp4->sgp4_flags |= SGP4_SIMPLE;
+
+	/*
+	 * FOR PERIGEE BELOW 156 KM, THE VALUES OF
+	 * S AND QOMS2T ARE ALTERED
+	 */
+
+	S4 = S;
+	QOMS24 = QOMS2T;
+	PERIGE = (AODP * (1.0 - EO) - AE) * XKMPER;
+
+	if(PERIGE < 156.0) {
+	    S4 = PERIGE - 78.0;
+
+	    if(PERIGE <= 98.0)
+		S4 = 20.0;
+
+	    QOMS24 = pow(((120.0 - S4) * AE / XKMPER), 4.0);
+	    S4 = S4 / XKMPER + AE;
+	}
+
+	PINVSQ=1.0 / (AODP * AODP * BETAO2 * BETAO2);
+	TSI = 1.0 / (AODP - S4);
+	ETA = AODP * EO * TSI;
+	ETASQ = ETA * ETA;
+	EETA = EO * ETA;
+
+	PSISQ = fabs(1.0 - ETASQ);
+
+	COEF = QOMS24 * pow(TSI, 4.0);
+	COEF1 = COEF / pow(PSISQ, 3.5);
+
+	C2 = COEF1 * XNODP * (AODP * (1.0 + 1.5 * ETASQ +
+				      EETA * (4.0 + ETASQ)) + .75 *
+			      CK2 * TSI /
+			      PSISQ * X3THM1 * (8.0 +
+						3.0 * ETASQ * (8.0 + ETASQ)));
+
+
+	C1 = BSTAR * C2;
+
+	SINIO = sin(XINCL);
+
+	A3OVK2 = -XJ3 / CK2 * pow(AE, 3.0);
+
+	C3 = COEF * TSI * A3OVK2 * XNODP * AE * SINIO / EO;
+
+	X1MTH2 = 1.0 - THETA2;
+	C4 = 2.0 * XNODP * COEF1 * AODP * BETAO2 *
+	    (ETA * (2.0 + .5 * ETASQ) + 
+	     EO * (.5 + 2.0 * ETASQ) -
+	     2.0 * CK2 * TSI / (AODP * PSISQ) *
+	     (-3.0 * X3THM1 * (1.0 - 2.0 * EETA + ETASQ * (1.5 - .5 * EETA)) +
+	      .75 * X1MTH2 * (2.0 * ETASQ - EETA * (1.0 + ETASQ)) * 
+	      cos(2.0 * OMEGAO)));
+
+	C5 = 2.0 * COEF1 * AODP * BETAO2 * (1.0 +
+					    2.75 * (ETASQ + EETA) +
+					    EETA * ETASQ);
+	THETA4 = THETA2 * THETA2;
+	TEMP1 = 3.0 * CK2 * PINVSQ * XNODP;
+	TEMP2 = TEMP1 * CK2 * PINVSQ;
+	TEMP3 = 1.25 * CK4 * PINVSQ * PINVSQ * XNODP;
+
+	XMDOT = XNODP +
+	    .5 * TEMP1 * BETAO * X3THM1 +
+	    .0625 * TEMP2 * BETAO * (13.0 - 78.0 * THETA2 + 137.0 * THETA4);
+
+	X1M5TH = 1.0 - 5.0 * THETA2;
+
+	OMGDOT = -.5 * TEMP1 * X1M5TH +
+	    .0625 * TEMP2 * (7.0 - 114.0 * THETA2 + 395.0 * THETA4) +
+	    TEMP3 * (3.0 - 36.0 * THETA2 + 49.0 * THETA4);
+
+	XHDOT1 = -TEMP1 * COSIO;
+
+	XNODOT = XHDOT1 + (.5 * TEMP2 * (4.0 - 19.0 * THETA2) +
+			   2.0 * TEMP3 * (3.0 - 7.0 * THETA2)) * COSIO;
+
+	OMGCOF = BSTAR * C3 * cos(OMEGAO);
+
+	XMCOF = -TOTHRD * COEF * BSTAR * AE / EETA;
+	XNODCF = 3.5 * BETAO2 * XHDOT1 * C1;
+	T2COF = 1.5 * C1;
+	XLCOF = .125 * A3OVK2 * SINIO * (3.0 + 5.0 *COSIO) / (1.0 + COSIO);
+
+	AYCOF = .25 * A3OVK2 * SINIO;
+	DELMO = pow(1.0 + ETA * cos(XMO), 3.0);
+	SINMO = sin(XMO);
+
+	X7THM1 = 7.0 * THETA2 - 1.0;
+
+/*      IF(ISIMP .EQ. 1) GO TO 90 */
+	if(!(sat->prop.sgp4->sgp4_flags & SGP4_SIMPLE)) {
+	    C1SQ = C1 * C1;
+	    D2 = 4.0 * AODP * TSI * C1SQ;
+	    TEMP = D2 * TSI * C1 / 3.0;
+	    D3 = (17.0 * AODP + S4) * TEMP;
+	    D4 = .5 * TEMP * AODP * TSI * (221.0 * AODP + 31.0 * S4) * C1;
+	    T3COF = D2 + 2.0 * C1SQ;
+	    T4COF = .25 * (3.0 * D3 + C1 * (12.0 * D2 + 10.0 * C1SQ));
+	    T5COF = .2 * (3.0 * D4 +
+			  12.0 * C1 * D3 +
+			  6.0 * D2 * D2 +
+			  15.0 * C1SQ * (2.0 * D2 + C1SQ));
+	}
+    }
+
+    /*
+     * UPDATE FOR SECULAR GRAVITY AND ATMOSPHERIC DRAG
+     */
+
+    XMDF = XMO + XMDOT * TSINCE;
+    OMGADF = OMEGAO + OMGDOT * TSINCE;
+    XNODDF = XNODEO + XNODOT * TSINCE;
+    OMEGA = OMGADF;
+    XMP = XMDF;
+    TSQ = TSINCE * TSINCE;
+    XNODE = XNODDF + XNODCF * TSQ;
+    TEMPA = 1.0 - C1 * TSINCE;
+    TEMPE = BSTAR * C4 * TSINCE;
+    TEMPL = T2COF * TSQ;
+    if(!(sat->prop.sgp4->sgp4_flags & SGP4_SIMPLE)) {
+	DELOMG = OMGCOF * TSINCE;
+	DELM = XMCOF * (pow(1.0 + ETA * cos(XMDF), 3) - DELMO);
+	TEMP = DELOMG + DELM;
+	XMP = XMDF + TEMP;
+	OMEGA = OMGADF - TEMP;
+	TCUBE = TSQ * TSINCE;
+	TFOUR = TSINCE * TCUBE;
+	TEMPA = TEMPA - D2 * TSQ - D3 * TCUBE - D4 * TFOUR;
+	TEMPE = TEMPE + BSTAR * C5 * (sin(XMP) - SINMO);
+	TEMPL = TEMPL + T3COF * TCUBE + TFOUR * (T4COF + TSINCE * T5COF);
+    }
+
+    A = AODP * TEMPA * TEMPA;
+    E = EO - TEMPE;
+    XL = XMP + OMEGA + XNODE + XNODP * TEMPL;
+    BETA = sqrt(1.0 - E * E);
+    XN = XKE / pow(A, 1.5);
+
+    /*
+     * LONG PERIOD PERIODICS
+     */
+
+    AXN = E * cos(OMEGA);
+    TEMP = 1.0 / (A * BETA * BETA);
+    XLL = TEMP * XLCOF * AXN;
+    AYNL = TEMP * AYCOF;
+    XLT = XL + XLL;
+    AYN = E * sin(OMEGA) + AYNL;
+
+    /*
+     * SOLVE KEPLERS EQUATION
+     */
+
+    CAPU = fmod(XLT - XNODE, TWOPI);
+    TEMP2 = CAPU;
+
+    for(i = 0; i < 10; i++) {
+	SINEPW = sin(TEMP2);
+	COSEPW = cos(TEMP2);
+	TEMP3 = AXN * SINEPW;
+	TEMP4 = AYN * COSEPW;
+	TEMP5 = AXN * COSEPW;
+	TEMP6 = AYN * SINEPW;
+	EPW = (CAPU - TEMP4 + TEMP3 - TEMP2) / (1.0 - TEMP5 - TEMP6) + TEMP2;
+
+	if(fabs(EPW - TEMP2) <= E6A)
+	    break;
+
+	TEMP2 = EPW;
+    }
+
+    /*
+     * SHORT PERIOD PRELIMINARY QUANTITIES
+     */
+
+    ECOSE = TEMP5 + TEMP6;
+    ESINE = TEMP3 - TEMP4;
+    ELSQ = AXN * AXN + AYN * AYN;
+    TEMP = 1.0 - ELSQ;
+    PL = A * TEMP;
+    R = A * (1.0 - ECOSE);
+
+    TEMP1 = 1.0 / R;
+    RDOT = XKE * sqrt(A) * ESINE * TEMP1;
+    RFDOT = XKE * sqrt(PL) * TEMP1;
+    TEMP2 = A * TEMP1;
+    BETAL = sqrt(TEMP);
+    TEMP3 = 1.0 / (1.0 + BETAL);
+
+    COSU = TEMP2 * (COSEPW - AXN + AYN * ESINE * TEMP3);
+    SINU = TEMP2 * (SINEPW - AYN - AXN * ESINE * TEMP3);
+
+    U = actan(SINU, COSU);
+
+    SIN2U = 2.0 * SINU * COSU;
+    COS2U = 2.0 * COSU * COSU - 1.0;
+
+    TEMP = 1.0 / PL;
+    TEMP1 = CK2 * TEMP;
+    TEMP2 = TEMP1 * TEMP;
+
+    /*
+     * UPDATE FOR SHORT PERIODICS
+     */
+
+    RK = R * (1.0 - 1.5 * TEMP2 * BETAL * X3THM1) +
+	.5 * TEMP1 * X1MTH2 * COS2U;
+
+    UK = U - .25 * TEMP2 * X7THM1 * SIN2U;
+ 
+   XNODEK = XNODE + 1.5 * TEMP2 * COSIO * SIN2U;
+   XINCK = XINCL + 1.5 * TEMP2 * COSIO * SINIO * COS2U;
+   RDOTK = RDOT - XN * TEMP1 * X1MTH2 * SIN2U;
+   RFDOTK = RFDOT + XN * TEMP1 * (X1MTH2 * COS2U + 1.5 * X3THM1);
+
+   /*
+    * ORIENTATION VECTORS
+    */
+
+   SINUK = sin(UK);
+   COSUK = cos(UK);
+   SINIK = sin(XINCK);
+   COSIK = cos(XINCK);
+   SINNOK = sin(XNODEK);
+   COSNOK = cos(XNODEK);
+
+   XMX = -SINNOK * COSIK;
+   XMY = COSNOK * COSIK;
+   UX = XMX * SINUK + COSNOK * COSUK;
+   UY = XMY * SINUK + SINNOK * COSUK;
+   UZ = SINIK * SINUK;
+   VX = XMX * COSUK - COSNOK * SINUK;
+   VY = XMY * COSUK - SINNOK * SINUK;
+   VZ = SINIK * COSUK;
+
+   /*
+    * POSITION AND VELOCITY
+    */
+
+   pos->x = RK * UX;
+   pos->y = RK * UY;
+   pos->z = RK * UZ;
+
+   dpos->x = RDOTK * UX + RFDOTK * VX;
+   dpos->y = RDOTK * UY + RFDOTK * VY;
+   dpos->z = RDOTK * UZ + RFDOTK * VZ;
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: sgp4.c,v $ $Date: 2001-10-22 12:08:28 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/sphcart.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/sphcart.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/sphcart.c	(revision 2309)
@@ -0,0 +1,42 @@
+#include <math.h>
+#include "P_.h"
+#include "astro.h"
+
+/* transformation from spherical to cartesian coordinates */
+void
+sphcart (l, b, r, x, y, z)
+double l, b, r;		/* source: spherical coordinates */
+double *x, *y, *z;	/* result: rectangular coordinates */
+{
+	double rcb = r * cos(b);
+
+	*x = rcb * cos(l);
+	*y = rcb * sin(l);
+	*z = r * sin(b);
+}
+
+/* transformation from cartesian to spherical coordinates */
+void
+cartsph (x, y, z, l, b, r)
+double x, y, z;		/* source: rectangular coordinates */
+double *l, *b, *r;	/* result: spherical coordinates */
+{
+	double rho = x*x + y*y;
+
+	if (rho > 1e-35) {	/* standard case: off axis */
+	    *l = atan2(y, x);
+	    range (l, 2*PI);
+	    *b = atan2(z, sqrt(rho));
+	    *r = sqrt(rho + z*z);
+	} else {		/* degenerate case; avoid math error */
+	    *l = 0.0;
+	    if (z == 0.0)
+		*b = 0.0;
+	    else
+		*b = (z > 0.0) ? PI/2. : -PI/2.;
+	    *r = fabs(z);
+	}
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: sphcart.c,v $ $Date: 2001-10-22 12:08:28 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/sun.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/sun.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/sun.c	(revision 2309)
@@ -0,0 +1,47 @@
+#include <stdio.h>
+#include <math.h>
+
+#include "P_.h"
+#include "astro.h"
+#include "vsop87.h"
+
+/* given the modified JD, mjd, return the true geocentric ecliptic longitude
+ *   of the sun for the mean equinox of the date, *lsn, in radians, the
+ *   sun-earth distance, *rsn, in AU, and the latitude *bsn, in radians
+ *   (since this is always <= 1.2 arcseconds, in can be neglected by
+ *   calling with bsn = NULL).
+ *
+ * if the APPARENT ecliptic longitude is required, correct the longitude for
+ *   nutation to the true equinox of date and for aberration (light travel time,
+ *   approximately  -9.27e7/186000/(3600*24*365)*2*pi = -9.93e-5 radians).
+ */
+void
+sunpos (mjd, lsn, rsn, bsn)
+double mjd;
+double *lsn, *rsn, *bsn;
+{
+	static double last_mjd = -3691, last_lsn, last_rsn, last_bsn;
+	double ret[6];
+
+	if (mjd == last_mjd) {
+	    *lsn = last_lsn;
+	    *rsn = last_rsn;
+	    if (bsn) *bsn = last_bsn;
+	    return;
+	}
+
+	vsop87(mjd, SUN, 0.0, ret);	/* full precision earth pos */
+
+	*lsn = ret[0] - PI;		/* revert to sun pos */
+	range (lsn, 2*PI);		/* normalise */
+
+	last_lsn = *lsn;		/* memorise */
+	last_rsn = *rsn = ret[2];
+	last_bsn = -ret[1];
+	last_mjd = mjd;
+
+	if (bsn) *bsn = last_bsn;	/* assign only if non-NULL pointer */
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: sun.c,v $ $Date: 2001-10-22 12:08:28 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/thetag.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/thetag.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/thetag.c	(revision 2309)
@@ -0,0 +1,90 @@
+#include <math.h>
+
+#include "deepconst.h"
+
+/* @(#) $Id: thetag.c,v 1.2 2001-10-22 12:08:28 cmv Exp $ */
+
+
+/*
+ *      FUNCTION THETAG(EP)
+ *      COMMON /E1/XMO,XNODEO,OMEGAO,EO,XINCL,XNO,XNDT2O,XNDD6O,BSTAR,
+ *     1 X,Y,Z,XDOT,YDOT,ZDOT,EPOCH,DS50
+ *      DOUBLE PRECISION EPOCH,D,THETA,TWOPI,YR,TEMP,EP,DS50
+ *      TWOPI=6.28318530717959D0
+ *      YR=(EP+2.D-7)*1.D-3
+ *      JY=YR
+ *      YR=JY
+ *      D=EP-YR*1.D3
+ *      IF(JY.LT.10) JY=JY+80
+ *      N=(JY-69)/4
+ *      IF(JY.LT.70) N=(JY-72)/4
+ *      DS50=7305.D0 + 365.D0*(JY-70) +N + D
+ *      THETA=1.72944494D0 + 6.3003880987D0*DS50
+ *      TEMP=THETA/TWOPI
+ *      I=TEMP
+ *      TEMP=I
+ *      THETAG=THETA-TEMP*TWOPI
+ *      IF(THETAG.LT.0.D0) THETAG=THETAG+TWOPI
+ *      RETURN
+ *      END
+ */
+
+/*       FUNCTION THETAG(EP) */
+double
+thetag(double EP, double *DS50)
+{
+    int JY, N, I;
+    double YR, D, THETA, TEMP, THETAG;
+
+    YR = (EP + 2.0E-7) * 1.0E-3;
+
+    JY = (int) YR;
+
+    YR = JY;
+
+    D = EP - YR * 1.0E3;
+
+    if(JY < 10)
+	JY += 80;
+
+    N = (JY - 69) / 4;
+
+    if(JY < 70)
+	N = (JY - 72) / 4;
+
+/*    printf("N = %d\n", N); */
+
+    *DS50 = 7305.0 + 365.0 * (JY-70) + N + D;
+
+/*    printf("DS50 = %f\n", *DS50); */
+
+    THETA = 1.72944494 + 6.3003880987 * *DS50;
+
+/*    printf("THETA = %f\n", THETA); */
+
+    TEMP = THETA / TWOPI;
+
+    I = (int)TEMP;
+    TEMP = I;
+
+    THETAG = THETA - TEMP * TWOPI;
+
+    if(THETAG < 0.0)
+	THETAG += TWOPI;
+
+    return THETAG;
+}
+
+#if 0
+void main(int argc, char **argv) {
+    double ds50, gwa;
+
+    if(argc >= 2) {
+	gwa = thetag(atof(argv[1]), &ds50);
+	printf("%f, %f\n", gwa, ds50);
+    }
+}
+#endif
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: thetag.c,v $ $Date: 2001-10-22 12:08:28 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/twobody.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/twobody.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/twobody.c	(revision 2309)
@@ -0,0 +1,238 @@
+/*
+ *
+ * TWOBODY.C
+ *
+ *  Computation of planetary position, two-body computation
+ *
+ *  Paul Schlyter, 1987-06-15
+ *
+ *  Decreased EPSILON from 2E-4 to 3E-8,  1988-12-05
+ *
+ *  1990-01-01:  Bug fix in almost parabolic orbits: now the routine
+ *       doesn't bomb there (an if block was too large)
+ *
+ *  2000-12-06:  Donated to Elwood Downey if he wants to use it in XEphem
+ */
+ 
+ 
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+ 
+ 
+/* Constants used when solving Kepler's equation */
+#define EPSILON   3E-8
+#define INFINITY  1E+10
+ 
+/* Math constants */
+#define PI      3.14159265358979323846
+#define RADEG   ( 180.0 / PI )
+#define DEGRAD  ( PI / 180.0 )
+ 
+/* Trig functions in degrees */
+#define sind(x)      sin(x*DEGRAD)
+#define cosd(x)      cos(x*DEGRAD)
+#define atand(x)     (RADEG*atan(x))
+#define atan2d(y,x)  (RADEG*atan2(y,x))
+ 
+/* Gauss' grav.-konstant */
+#define K    1.720209895E-2
+#define KD   ( K * 180.0 / PI )
+#define K2   ( K / 2.0 )
+ 
+ 
+ 
+ 
+static double cubroot( double x )
+/* Cubic root */
+{
+    double a,b;
+ 
+    if ( x == 0.0 )
+        return  0.0;
+    else
+    {
+        a = fabs(x);
+        b = exp( log(a) / 3.0 );
+        return  x > 0.0 ? b : -b;
+    }
+}  /* cubroot */
+ 
+ 
+static double rev180( double ang )
+/* Normalize angle to between +180 and -180 degrees */
+{
+    return  ang  -  360.0 * floor(ang*(1.0/360.0) + 0.5);
+}  /* rev180 */
+ 
+ 
+ 
+static double kepler( double m, double ex )
+/*
+ * Solves Kepler's equation
+ *  m      = mean anomaly
+ *  ex     = eccentricity
+ *  kepler = eccentric anomaly
+ */
+{
+    double m1, sinm, cosm, exd, exan, dexan, lim1, adko, adk, denom;
+    int converged;
+ 
+    m1 = rev180(m);
+    sinm = sind(m1);
+    cosm = cosd(m1);
+    /* 1st approximation: */
+    exan = atan2d(sinm,cosm-ex);
+    if ( ex > 0.008 )
+    { /* Iteration formula: */
+        exd = ex * RADEG;
+        lim1 = 1E-3 / ex;
+        adko = INFINITY;
+        denom = 1.0 - ex * cosd(exan);
+        do
+        {
+            dexan = (m1 + exd * sind(exan) - exan) / denom;
+            exan = exan + dexan;
+            adk = fabs(dexan);
+            converged = adk < EPSILON  ||  adk >= adko ;
+            adko = adk;
+            if ( !converged  &&  adk > lim1 )
+                denom = 1.0 - ex * cosd(exan);
+        } while ( !converged );
+    }
+    return  exan;
+}  /* kepler */
+ 
+ 
+static void vr( double *v, double *r, double m, double e, double a )
+/*
+ * Elliptic orbits only:
+ * computes: v = true anomaly   (degrees)
+ *           r = radius vector  (a.u.)
+ *   from:   m = mean anomaly   (degrees)
+ *           e = eccentricity
+ *           a = semimajor axis (a.u.)
+ */
+{
+    double ean, x, y;
+ 
+    ean = kepler(m,e);
+    x = a*(cosd(ean)-e);
+    y = a*sqrt(1.-e*e)*sind(ean);
+    *r = sqrt(x*x+y*y);
+    *v = atan2d(y,x);
+}  /* vr */
+ 
+ 
+void vrc( double *v, double *r, double tp, double e, double q )
+/*
+ * Elliptic, hyperbolic and near-parabolic orbits:
+ * computes: v  = true anomaly  (degrees)
+ *           r  = radius vector (a.u.)
+ *   from:   tp = time from perihelion (days)
+ *           e  = eccentricity
+ *           q  = perihelion distance (a.u.)
+ */
+{
+ 
+    double lambda;
+ 
+    double a, b, w, w2, w4, c, c1, c2, c3, c5, a0, a1, a2,
+           a3, m, n, g, adgg, adgg2, gs, dg;
+ 
+    if ( tp == 0.0 )  /* In perihelion */
+    {
+        *v = 0.0;
+        *r = q;
+        return;
+    }
+ 
+ 
+    lambda = (1.0-e) / (1.0+e);
+ 
+    if ( fabs(lambda) < 0.01 )
+    {  /* Near-parabolic orbits */
+        a = K2 * sqrt((1.0+e)/(q*q*q)) * tp;
+        b = sqrt( 1.0 + 2.25*a*a );
+        w = cubroot( b + 1.5*a ) - cubroot( b - 1.5*a );
+ 
+        /* Test if it's accuate enough to compute this as a near-parabolic orbit */
+        if ( fabs(w*w*lambda) > 0.2 )
+        {
+            if ( fabs(lambda) < 0.0002 )
+            {
+                /* Sorry, but we cannot compute this at all -- we must give up!
+                 *
+                 * This happens very rarely, in orbits having an eccentricity
+                 * some 2% away from 1.0 AND if the body is very very far from
+                 * perihelion.  E.g. a Kreutz sun-grazing comet having
+                 * eccentricity near 0.98 or 1.02, and being outside
+                 * the orbit of Pluto.  For any reasonable orbit this will
+                 * never happen in practice.
+                 *
+                 * You might want to code a more graceful error exit here though.
+                 *
+                 */
+                printf( "\nNear-parabolic orbit: inaccurate result."
+                        "\n  e = %f, lambda = %f, w = %f", e, lambda, w );
+                exit(1);
+            }
+            else
+            {
+                /* We cannot compute this as a near-parabolic orbit, so let's
+                   compute it as an elliptic or hyperbolic orbit instead. */
+                goto ellipse_hyperbola;
+            }
+        }
+ 
+        /* Go ahead computing the near-parabolic case */
+        c = 1.0 + 1.0 / (w*w);
+        c1 = 1.0 / c;
+        c2 = c1*c1;
+        c3 = c1*c2;
+        c5 = c3*c2;
+        w2 = w*w;
+        w4 = w2*w2;
+        a0 = w;
+        a1 = 2.0 * w * (0.33333333 + 0.2*w2) * c1;
+        a2 = 0.2 * w * (7.0 + 0.14285714 * (33.0*w2+7.4*w4)) * c3;
+        a3 = 0.022857143 * (108.0 + 37.177777*w2 + 5.1111111*w4) * c5;
+        w = (( lambda * a3 + a2 ) * lambda + a1 ) * lambda + a0;
+        w2 = w*w;
+        *v = 2.0 * atand(w);
+        *r = q * (1+w2) / ( 1.0 + w2*lambda );
+        return;  /* Near-parabolic orbit */
+    }
+ 
+ 
+ellipse_hyperbola:
+ 
+    if ( lambda > 0.0 )
+    {   /* Elliptic orbit: */
+        a = q / (1.0-e);            /* Semi-major axis */
+        m = KD * tp / sqrt(a*a*a);  /* Mean Anomaly */
+        vr( v, r, m, e, a );        /* Solve Kepler's equation, etc */
+    }
+    else
+    {   /* Hyperbolic orbit: */
+        a = q / (e-1.0);            /* Semi-major axis */
+        n = K * tp / sqrt(a*a*a);   /* "Daily motion" */
+        g = n/e;
+        adgg = INFINITY;
+        do  
+        {
+            adgg2 = adgg;
+            gs = sqrt(g*g+1.0);
+            dg = -( e*g - log(g+gs) - n ) / ( e - 1.0/gs );
+            g = g + dg;
+            adgg = fabs(dg/g);
+        } while ( adgg < adgg2  &&  adgg > 1E-5 );
+        gs = sqrt(g*g+1.0);
+        *v = 2.0 * atand( sqrt( (e+1.0)/(e-1.0) ) * g / (gs+1.0) );
+        *r = q * (1.0+e) / ( 1.0 + e*cosd(*v) );
+    }
+ 
+} /* vrc */
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: twobody.c,v $ $Date: 2001-10-22 12:08:28 $ $Revision: 1.1 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/utc_gst.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/utc_gst.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/utc_gst.c	(revision 2309)
@@ -0,0 +1,102 @@
+#include "P_.h"
+#include "astro.h"
+
+static double gmst0 P_((double mjd));
+
+/* given a modified julian date, mjd, and a universally coordinated time, utc,
+ * return greenwich mean siderial time, *gst.
+ * N.B. mjd must be at the beginning of the day.
+ */
+void
+utc_gst (mjd, utc, gst)
+double mjd;
+double utc;
+double *gst;
+{
+	static double lastmjd = -18981;
+	static double t0;
+
+	if (mjd != lastmjd) {
+	    t0 = gmst0(mjd);
+	    lastmjd = mjd;
+	}
+	*gst = (1.0/SIDRATE)*utc + t0;
+	range (gst, 24.0);
+}
+
+/* given a modified julian date, mjd, and a greenwich mean siderial time, gst,
+ * return universally coordinated time, *utc.
+ * N.B. mjd must be at the beginning of the day.
+ */
+void
+gst_utc (mjd, gst, utc)
+double mjd;
+double gst;
+double *utc;
+{
+	static double lastmjd = -10000;
+	static double t0;
+
+	if (mjd != lastmjd) {
+	    t0 = gmst0 (mjd);
+	    lastmjd = mjd;
+	}
+	*utc = gst - t0;
+	range (utc, 24.0);
+	*utc *= SIDRATE;
+}
+
+/* gmst0() - return Greenwich Mean Sidereal Time at 0h UT; stern
+ */
+static double
+gmst0 (mjd)
+double mjd;	/* date at 0h UT in julian days since MJD0 */
+{
+	double T, x;
+
+	T = ((int)(mjd - 0.5) + 0.5 - J2000)/36525.0;
+	x = 24110.54841 +
+		(8640184.812866 + (0.093104 - 6.2e-6 * T) * T) * T;
+	x /= 3600.0;
+	range(&x, 24.0);
+	return (x);
+}
+
+#ifdef TEST_GMST
+
+/* original routine by elwood; has a secular drift of 0.08s/cty */
+static double
+tnaught (mjd)
+double mjd;	/* julian days since 1900 jan 0.5 */
+{
+	double dmjd;
+	int m, y;
+	double d;
+	double t, t0;
+
+	mjd_cal (mjd, &m, &d, &y);
+	cal_mjd (1, 0., y, &dmjd);
+	t = dmjd/36525;
+	t0 = 6.57098e-2 * (mjd - dmjd) - 
+	     (24 - (6.6460656 + (5.1262e-2 + (t * 2.581e-5))*t) -
+		   (2400 * (t - (((double)y - 1900)/100))));
+	range(&t0, 24.0);
+	return (t0);
+}
+
+#include <stdlib.h>
+main(argc, argv)
+  int argc;
+  char *argv[];
+{
+	double mjd, gst;
+	while (scanf("%lf", &mjd) == 1) {
+		mjd -= MJD0;
+		gst = tnaught(mjd);
+		printf("%17.9f %10.7f %10.7f\n", mjd + MJD0, gst, gmst0(mjd));
+	}
+}
+#endif
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: utc_gst.c,v $ $Date: 2001-10-22 12:08:28 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/vector.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/vector.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/vector.h	(revision 2309)
@@ -0,0 +1,19 @@
+#ifndef __SATVECTOR_H
+#define __SATVECTOR_H
+
+/* $Id: vector.h,v 1.2 2001-10-22 12:08:28 cmv Exp $ */
+
+#define dotp(A,B) ((A).x*(B).x+(A).y*(B).y+(A).z*(B).z)
+
+#define crossp(A,B,C) {(C).x=(A).y*(B).z-(A).z*(B).y;(C).y=(A).z*(B).x-(A).x*(B).z;(C).z=(A).x*(B).y-(A).y*(B).x;}
+
+#define vecabs(V) (sqrt((V).x*(V).x+(V).y*(V).y+(V).z*(V).z))
+#define vecsq(V) ((V).x*(V).x+(V).y*(V).y+(V).z*(V).z)
+#define vecsub(A,B,C) {(C).x=(A).x-(B).x;(C).y=(A).y-(B).y;(C).z=(A).z-(B).z;}
+#define vecscale(A,k) {(A).x*=(k);(A).y*=(k);(A).z*=(k);}
+
+#endif /* __SATVECTOR_H */
+
+/* For RCS Only -- Do Not Edit
+ * @(#) $RCSfile: vector.h,v $ $Date: 2001-10-22 12:08:28 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $
+ */
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/vsop87.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/vsop87.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/vsop87.c	(revision 2309)
@@ -0,0 +1,213 @@
+/* VSOP87 planetary theory
+ *
+ * currently uses version VSOP87D:
+ * heliocentric spherical, mean ecliptic of date.
+ *
+ * calculation of rates (daily changes) is optional;
+ * see header file for the necessary #define's
+ *
+ * rough orientation on calculation time, miliseconds
+ * on an HP 715/75, all planets Mercury to Neptune, prec=0.0:
+ *
+ *      terms	with rates	without rates
+ * 	3598	11		7.1
+ *      31577	51		44
+ *
+ * with secular terms for JD 2232395.0  19/12/1399 0h TDB:
+ *
+ *	FULL PRECISION code (31577 terms), milliseconds
+ *	prec	terms	rates	no rates
+ *	1e-8	15086	62	36
+ *	1e-7	10105	44	25
+ *	1e-6	3725	20	13
+ *	1e-5	1324	11	7.8
+ *	1e-4	443	7.0	6.0
+ *	1e-3	139	6.0	5.0
+ *
+ *	REDUCED PRECISION code (3598 terms), milliseconds
+ *	prec	terms	rates	no rates
+ *	1e-7	2463	9.9	5.5
+ *	1e-6	1939	8.0	4.5
+ *	1e-5	1131	4.9	2.9
+ *	1e-4	443	2.2	1.5
+ *	1e-3	139	1.0	0.9
+ */
+
+#include <math.h>
+#include "P_.h"
+#include "astro.h"
+#include "vsop87.h"
+
+#define VSOP_A1000	365250.0	/* days per millenium */
+#define VSOP_MAXALPHA	5		/* max degree of time */
+
+/******************************************************************
+ * adapted from BdL FORTRAN Code; stern
+ *
+ *    Reference : Bureau des Longitudes - PBGF9502
+ *
+ *    Object :  calculate a VSOP87 position for a given time.
+ *
+ *    Input :
+ *
+ *    mjd      modified julian date, counted from J1900.0
+ *             time scale : dynamical time TDB.
+ *
+ *    obj	object number as in astro.h, NB: not for pluto
+ *
+ *    prec     relative precision
+ *
+ *             if prec is equal to 0 then the precision is the precision
+ *                p0 of the complete solution VSOP87.
+ *                Mercury    p0 =  0.6 10**-8
+ *                Venus      p0 =  2.5 10**-8
+ *                Earth      p0 =  2.5 10**-8
+ *                Mars       p0 = 10.0 10**-8
+ *                Jupiter    p0 = 35.0 10**-8
+ *                Saturn     p0 = 70.0 10**-8
+ *                Uranus     p0 =  8.0 10**-8
+ *                Neptune    p0 = 42.0 10**-8
+ *
+ *             if prec is not equal to 0, let us say in between p0 and
+ *             10**-3, the precision is :
+ *                for the positions :
+ *                - prec*a0 au for the distances.
+ *                - prec rad for the other variables.
+ *                for the velocities :
+ *                - prec*a0 au/day for the distances.
+ *                - prec rad/day for the other variables.
+ *                  a0 is the semi-major axis of the body.
+ *
+ *    Output :
+ *
+ *    ret[6]     array of the results (double).
+ *
+ *             for spherical coordinates :
+ *                 1: longitude (rd)
+ *                 2: latitude (rd)
+ *                 3: radius (au)
+ *		#if VSOP_GETRATE:
+ *                 4: longitude velocity (rad/day)
+ *                 5: latitude velocity (rad/day)
+ *                 6: radius velocity (au/day)
+ *
+ *    return:     error index (int)
+ *                 0: no error.
+ *		   2: object out of range [MERCURY .. NEPTUNE, SUN]
+ *		   3: precision out of range [0.0 .. 1e-3]
+ ******************************************************************/
+int
+vsop87 (mjd, obj, prec, ret)
+double mjd;
+int obj;
+double prec;
+double *ret;
+{
+    static double (*vx_map[])[3] = {		/* data tables */
+		vx_mercury, vx_venus, vx_mars, vx_jupiter,
+		vx_saturn, vx_uranus, vx_neptune, 0, vx_earth,
+	};
+    static int (*vn_map[])[3] = {		/* indexes */
+		vn_mercury, vn_venus, vn_mars, vn_jupiter,
+		vn_saturn, vn_uranus, vn_neptune, 0, vn_earth,
+	};
+    static double a0[] = {	/* semimajor axes; for precision ctrl only */
+	    0.39, 0.72, 1.5, 5.2, 9.6, 19.2, 30.1, 39.5, 1.0,
+	};
+    double (*vx_obj)[3] = vx_map[obj];		/* VSOP87 data and indexes */
+    int (*vn_obj)[3] = vn_map[obj];
+
+    double t[VSOP_MAXALPHA+1];			/* powers of time */
+    double t_abs[VSOP_MAXALPHA+1];		/* powers of abs(time) */
+    double q;					/* aux for precision control */
+    int i, cooidx, alpha;			/* misc indexes */
+
+    if (obj == PLUTO || obj > SUN)
+	return (2);
+
+    if (prec < 0.0 || prec > 1e-3)
+	return(3);
+
+    /* zero result array */
+    for (i = 0; i < 6; ++i) ret[i] = 0.0;
+
+    /* time and its powers */
+    t[0] = 1.0;
+    t[1] = (mjd - J2000)/VSOP_A1000;
+    for (i = 2; i <= VSOP_MAXALPHA; ++i) t[i] = t[i-1] * t[1];
+    t_abs[0] = 1.0;
+    for (i = 1; i <= VSOP_MAXALPHA; ++i) t_abs[i] = fabs(t[i]);
+
+    /* precision control */
+    q = -log10(prec + 1e-35) - 2;	/* decades below 1e-2 */
+    q = VSOP_ASCALE * prec / 10.0 / q;	/* reduce threshold progressively
+					 * for higher precision */
+
+    /* do the term summation; first the spatial dimensions */
+    for (cooidx = 0; cooidx < 3; ++cooidx) {
+
+	/* then the powers of time */
+	for (alpha = 0; vn_obj[alpha+1][cooidx] ; ++alpha) {
+	    double p, term, termdot;
+
+	    /* precision threshold */
+	    p= alpha ? q/(t_abs[alpha] + alpha*t_abs[alpha-1]*1e-4 + 1e-35) : q;
+#if VSOP_SPHERICAL
+	    if (cooidx == 2)	/* scale by semimajor axis for radius */
+#endif
+		p *= a0[obj];
+
+	    term = termdot = 0.0;
+	    for (i = vn_obj[alpha][cooidx]; i < vn_obj[alpha+1][cooidx]; ++i) {
+		double a, b, c, arg;
+
+		a = vx_obj[i][0];
+		if (a < p) continue;	/* ignore small terms */
+
+		b = vx_obj[i][1];
+		c = vx_obj[i][2];
+
+		arg = b + c * t[1];
+		term += a * cos(arg);
+#if VSOP_GETRATE
+		termdot += -c * a * sin(arg);
+#endif
+	    }
+
+	    ret[cooidx] += t[alpha] * term;
+#if VSOP_GETRATE
+	    ret[cooidx + 3] += t[alpha] * termdot +
+		    ((alpha > 0) ? alpha * t[alpha - 1] * term : 0.0);
+#endif
+	} /* alpha */
+    } /* cooidx */
+
+    for (i = 0; i < 6; ++i) ret[i] /= VSOP_ASCALE;
+
+#if VSOP_SPHERICAL
+    /* reduce longitude to 0..2pi */
+    ret[0] -= floor(ret[0]/(2.*PI)) * (2.*PI);
+#endif
+
+#if VSOP_GETRATE
+    /* convert millenium rate to day rate */
+    for (i = 3; i < 6; ++i) ret[i] /= VSOP_A1000;
+#endif
+
+#if VSOP_SPHERICAL
+    /* reduction from dynamical equinox of VSOP87 to FK5;
+     */
+    if (prec < 5e-7) {		/* 5e-7 rad = 0.1 arc seconds */
+	double L1, c1, s1;
+	L1 = ret[0] - degrad(13.97 * t[1] - 0.031 * t[2]);
+	c1 = cos(L1); s1 = sin(L1);
+	ret[0] += degrad(-0.09033 + 0.03916 * (c1 + s1) * tan(ret[1]))/3600.0;
+	ret[1] += degrad(0.03916 * (c1 - s1))/3600.0;
+    }
+#endif
+
+    return (0);
+}
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: vsop87.c,v $ $Date: 2001-10-22 12:08:28 $ $Revision: 1.3 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/vsop87.h
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/vsop87.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/vsop87.h	(revision 2309)
@@ -0,0 +1,93 @@
+/* Position of planets mercury to neptune; from:
+ftp://ftp.bdl.fr/pub/ephem/planets/vsop87/
+from README:
+
+==========================                         ===========================
+                              BUREAU DES LONGITUDES
+                            PLANETARY SOLUTION VSOP87
+                                  1996, January
+==========================                         ===========================
+
+These files and programs are associated to :
+
+Planetary Theories in rectangular and spherical variables: VSOP87 solution.
+    Bretagnon P., Francou G.
+    Astron. Astrophys. 202, 309 (1988).
+
+Theorie du mouvement de l'ensemble des planetes (VSOP82).
+    Bretagnon P.
+    Astron. Astrophys. 114, 278 (1982).
+
+==============================================================================
+
+Description:
+    The Planetary solutions VSOP87 (Variations Seculaires des Orbites
+    Planetaires) are analytical solutions of the motion of the planets in
+    different versions. The main version VSOP87 consists of the series in
+    elliptic elements as in the case of VSOP82 solution and the other
+    versions VSOP87 (A-B-C-D-E) are built in rectangular and spherical
+    variables.
+
+Authors' Address:
+    P. Bretagnon, G. Francou
+    Bureau des Longitudes, CNRS URA 707
+    77, Avenue Denfert-Rochereau
+    75014, Paris, France
+    Tel    : (33) 1 40 51 22 69  (33) 1 40 51 22 60
+    Fax    : (33) 1 46 33 28 34
+    E-mail : pierre@bdl.fr  francou@bdl.fr
+
+Contents:
+    The main version of VSOP87 is similar to the previous theory VSOP82.
+    In the both cases the constants of integration have been determined by
+    fitting to the numerical integration DE200 of the Jet Propulsion
+    Laboratory. The various versions of VSOP87 are different from one to
+    another in the type of coordinates and the reference frame.
+    VSOP87  : heliocentric elliptic    variables; equinox and ecliptic J2000.
+    VSOP87A : heliocentric rectangular variables; equinox and ecliptic J2000.
+    VSOP87B : heliocentric spherical   variables; equinox and ecliptic J2000.
+    VSOP87C : heliocentric rectangular variables; equinox and ecliptic of date.
+    VSOP87D : heliocentric spherical   variables; equinox and ecliptic of date.
+    VSOP87E : barycentric  rectangular variables; equinox and ecliptic J2000.
+...
+==============================================================================
+User feed-back is encouraged. Unless otherwise specified, send comments and bug
+reports to:                    E-mail     : comments@bdl.fr
+                               Fax        : (33) 1 46 33 28 34
+                               Postal mail: Bureau des longitudes
+                                            77 avenue Denfert Rochereau
+                                            F-75014 PARIS
+==============================================================================
+  implemented for C: stern
+*/
+
+#define VSOP_ASCALE	1e8	/* amplitude factor as stored */
+
+/* coding flags */
+#define VSOP_SPHERICAL	1	/* version in data.c uses spherical coords */
+#define VSOP_GETRATE	0	/* calculate time derivatives of coordinates */
+
+/* data tables */
+extern double vx_mercury[][3];
+extern int vn_mercury[][3];
+extern double vx_venus[][3];
+extern int vn_venus[][3];
+extern double vx_earth[][3];
+extern int vn_earth[][3];
+extern double vx_mars[][3];
+extern int vn_mars[][3];
+extern double vx_jupiter[][3];
+extern int vn_jupiter[][3];
+extern double vx_saturn[][3];
+extern int vn_saturn[][3];
+extern double vx_uranus[][3];
+extern int vn_uranus[][3];
+extern double vx_neptune[][3];
+extern int vn_neptune[][3];
+
+extern int vsop87 P_((double mjd, int obj, double prec, double *ret));
+
+
+/* For RCS Only -- Do Not Edit
+ * @(#) $RCSfile: vsop87.h,v $ $Date: 2001-10-22 12:08:28 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $
+ */
Index: /tags/V_Dec2002/SophyaExt/XephemAstroLib/vsop87_data.c
===================================================================
--- /tags/V_Dec2002/SophyaExt/XephemAstroLib/vsop87_data.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaExt/XephemAstroLib/vsop87_data.c	(revision 2309)
@@ -0,0 +1,6988 @@
+/*  data tables for planetary solution VSOP87
+ *
+ *  created by automatic conversion from original distribution files at
+ *  ftp://ftp.bdl.fr/pub/ephem/planets/vsop87/
+ *
+ *  Each coordinate is calculated as:
+ *
+ *	x = Sum{ T^alpha * A * cos( B + C*T ) }
+ * 
+ *  x is the coordinate in rad or a.u.
+ *  T is the VSOP time in Julian Millenia(!) since J2000.0
+ *  Note: the time argument in VSOP87 theory is equal to TAI + 32.184 s
+ *
+ *  A (scaled by VSOP_ASCALE), B, C given below for each x and alpha
+ *  run-of-the mill for each planet in one array vx_planet[][3].
+ *  The block-boundary indices for each spatial dimension are then listed
+ *  in a separate array vn_planet[][3].
+ *
+ *  Truncation errors given in comments are from the authors' empirical
+ *  formula:  2*sqrt(number of retained terms)*A[last retained]
+ */
+
+/*  version d4 (lbr)       
+ *  heliocentric dynamical ecliptic and equinox of the date
+ */
+
+double vx_earth[][3] = {
+	/* earth l, T^0 */
+	{ 175347045.7, 0, 0 },
+	{ 3341656.5, 4.66925680, 6283.07584999 },
+	{ 34894.3, 4.626102, 12566.151700 },
+	{ 3417.6, 2.82887, 3.52312 },
+	{ 3497.1, 2.74412, 5753.38488 },
+	{ 3135.9, 3.62767, 77713.77147 },
+	{ 2676.2, 4.41808, 7860.41939 },
+	{ 2342.7, 6.13516, 3930.20970 },
+	{ 1273.2, 2.03710, 529.69097 },
+	{ 1324.3, 0.74246, 11506.76977 },
+	{ 901.9, 2.0451, 26.2983 },
+	{ 1199.2, 1.10963, 1577.34354 },
+	{ 857.2, 3.5085, 398.1490 },
+	{ 779.8, 1.1788, 5223.6939 },
+	{ 990.2, 5.2327, 5884.9268 },
+	{ 753.1, 2.5334, 5507.5532 },
+	{ 505.3, 4.5829, 18849.2275 },
+	{ 492.4, 4.2051, 775.5226 },
+	{ 356.7, 2.9195, 0.0673 },
+	{ 284.1, 1.8987, 796.2980 },
+	{ 242.8, 0.3448, 5486.7778 },
+	{ 317.1, 5.8490, 11790.6291 },
+	{ 271.0, 0.3149, 10977.0788 },
+	{ 206.2, 4.8065, 2544.3144 },
+	{ 205.4, 1.8695, 5573.1428 },
+	{ 202.3, 2.4577, 6069.7768 },
+	{ 126.2, 1.0830, 20.7754 },
+	{ 155.5, 0.8331, 213.2991 },
+	{ 115.1, 0.6454, 0.9803 },
+	{ 102.9, 0.6360, 4694.0030 },
+	{ 101.7, 4.2668, 7.1135 },
+	{ 99.2, 6.210, 2146.165 },
+	{ 132.2, 3.4112, 2942.4634 },
+	{ 97.6, 0.681, 155.420 },
+	{ 85.1, 1.299, 6275.962 },
+	{ 74.7, 1.755, 5088.629 },
+	{ 101.9, 0.9757, 15720.8388 },
+	{ 84.7, 3.671, 71430.696 },
+	{ 73.5, 4.679, 801.821 },
+	{ 73.9, 3.503, 3154.687 },
+	{ 78.8, 3.037, 12036.461 },
+	{ 79.6, 1.808, 17260.155 },
+	{ 85.8, 5.983, 161000.686 },
+	{ 57.0, 2.784, 6286.599 },
+	{ 61.1, 1.818, 7084.897 },
+	{ 69.6, 0.833, 9437.763 },
+	{ 56.1, 4.387, 14143.495 },
+	{ 62.4, 3.978, 8827.390 },
+	{ 51.1, 0.283, 5856.478 },
+	{ 55.6, 3.470, 6279.553 },
+	{ 41.0, 5.368, 8429.241 },
+	{ 51.6, 1.333, 1748.016 },
+	{ 52.0, 0.189, 12139.554 },
+	{ 49.0, 0.487, 1194.447 },
+	{ 39.2, 6.168, 10447.388 },
+	{ 35.6, 1.776, 6812.767 },
+	{ 36.8, 6.041, 10213.286 },
+	{ 36.6, 2.570, 1059.382 },
+	{ 33.3, 0.593, 17789.846 },
+	{ 36.0, 1.709, 2352.866 },
+	{ 40.9, 2.399, 19651.048 },
+	{ 30.0, 2.740, 1349.867 },
+	{ 30.4, 0.443, 83996.847 },
+	{ 23.7, 0.485, 8031.092 },
+	{ 23.6, 2.065, 3340.612 },
+	{ 21.1, 4.148, 951.718 },
+	{ 24.7, 0.215, 3.590 },
+	{ 25.4, 3.165, 4690.480 },
+	{ 22.8, 5.222, 4705.732 },
+	{ 21.4, 1.426, 16730.464 },
+	{ 21.9, 5.556, 553.569 },
+	{ 17.5, 4.561, 135.065 },
+	{ 19.9, 5.222, 12168.003 },
+	{ 19.9, 5.775, 6309.374 },
+	{ 20.3, 0.371, 283.859 },
+	{ 14.4, 4.193, 242.729 },
+	{ 16.2, 5.988, 11769.854 },
+	{ 15.1, 4.196, 6256.778 },
+	{ 19.1, 3.822, 23581.258 },
+	{ 18.9, 5.386, 149854.400 },
+	{ 14.3, 3.724, 38.028 },
+	{ 17.9, 2.215, 13367.973 },
+	{ 12.1, 2.622, 955.600 },
+	{ 11.3, 0.177, 4164.312 },
+	{ 14.0, 4.401, 6681.225 },
+	{ 13.6, 1.889, 7632.943 },
+	{ 12.5, 1.131, 5.523 },
+	{ 10.5, 5.359, 1592.596 },
+	{ 9.8, 1.00, 11371.70 },
+	{ 9.2, 4.57, 4292.33 },
+	{ 10.3, 6.200, 6438.496 },
+	{ 12.0, 1.004, 632.784 },
+	{ 10.8, 0.327, 103.093 },
+	{ 8.4, 4.54, 25132.30 },
+	{ 10.0, 6.029, 5746.271 },
+	{ 8.4, 3.30, 7234.79 },
+	{ 8.0, 5.82, 28.45 },
+	{ 10.5, 0.939, 11926.254 },
+	{ 7.7, 3.12, 7238.68 },
+	{ 9.4, 2.62, 5760.50 },
+	{ 8.1, 6.11, 4732.03 },
+	{ 9.2, 0.48, 522.58 },
+	{ 9.8, 5.24, 27511.47 },
+	{ 7.9, 1.00, 5643.18 },
+	{ 8.1, 6.27, 426.60 },
+	{ 9.0, 5.34, 6386.17 },
+	{ 8.6, 4.17, 7058.60 },
+	{ 6.3, 4.72, 6836.65 },
+	{ 7.6, 3.97, 11499.66 },
+	{ 7.8, 2.96, 23013.54 },
+	{ 7.3, 0.61, 11513.88 },
+	{ 6.5, 5.79, 18073.70 },
+	{ 7.2, 4.00, 74.78 },
+	{ 7.3, 4.39, 316.39 },
+	{ 7.1, 0.32, 263.08 },
+	{ 6.6, 3.66, 17298.18 },
+	{ 6.8, 5.91, 90955.55 },
+	/* 117 terms retained, 442 terms dropped, error 0.3" */
+
+	/* earth l, T^1 */
+	{ 628331966747.5, 0, 0 },
+	{ 206058.9, 2.6782346, 6283.0758500 },
+	{ 4303.4, 2.63513, 12566.15170 },
+	{ 425.3, 1.5905, 3.5231 },
+	{ 109.0, 2.9662, 1577.3435 },
+	{ 93.5, 2.592, 18849.228 },
+	{ 119.3, 5.7956, 26.2983 },
+	{ 72.1, 1.138, 529.691 },
+	{ 67.8, 1.875, 398.149 },
+	{ 67.3, 4.409, 5507.553 },
+	{ 59.0, 2.888, 5223.694 },
+	{ 56.0, 2.175, 155.420 },
+	{ 45.4, 0.398, 796.298 },
+	{ 36.4, 0.466, 775.523 },
+	{ 29.0, 2.647, 7.114 },
+	{ 19.1, 1.846, 5486.778 },
+	{ 20.8, 5.341, 0.980 },
+	{ 18.5, 4.969, 213.299 },
+	{ 16.2, 0.032, 2544.314 },
+	{ 17.3, 2.991, 6275.962 },
+	{ 15.8, 1.430, 2146.165 },
+	{ 14.6, 1.205, 10977.079 },
+	{ 11.9, 3.258, 5088.629 },
+	{ 11.5, 2.075, 4694.003 },
+	{ 9.7, 4.24, 1349.87 },
+	{ 10.0, 1.303, 6286.599 },
+	{ 9.5, 2.70, 242.73 },
+	{ 12.5, 2.834, 1748.016 },
+	{ 11.8, 5.274, 1194.447 },
+	{ 8.6, 5.64, 951.72 },
+	{ 10.6, 0.766, 553.569 },
+	{ 7.6, 5.30, 2352.87 },
+	{ 5.8, 1.77, 1059.38 },
+	{ 6.4, 2.65, 9437.76 },
+	{ 5.2, 5.66, 71430.70 },
+	{ 5.3, 0.91, 3154.69 },
+	{ 6.1, 4.67, 4690.48 },
+	{ 4.3, 0.24, 6812.77 },
+	{ 5.0, 1.42, 6438.50 },
+	{ 4.3, 0.77, 10447.39 },
+	{ 5.2, 1.85, 801.82 },
+	{ 3.7, 2.00, 8031.09 },
+	{ 3.6, 2.43, 14143.50 },
+	{ 3.4, 3.86, 1592.60 },
+	{ 3.4, 0.89, 12036.46 },
+	{ 3.2, 3.19, 4705.73 },
+	{ 3.2, 0.62, 8429.24 },
+	{ 4.1, 5.24, 7084.90 },
+	{ 3.0, 6.07, 4292.33 },
+	{ 2.9, 2.32, 20.36 },
+	{ 3.5, 4.80, 6279.55 },
+	{ 2.9, 1.43, 5746.27 },
+	{ 2.7, 4.80, 7234.79 },
+	{ 2.5, 6.22, 6836.65 },
+	{ 2.7, 0.93, 5760.50 },
+	{ 3.2, 3.40, 7632.94 },
+	{ 2.3, 5.00, 17789.85 },
+	{ 2.1, 3.96, 10213.29 },
+	{ 2.1, 2.22, 5856.48 },
+	{ 2.3, 5.67, 11499.66 },
+	{ 2.1, 5.20, 11513.88 },
+	{ 1.9, 0.53, 3340.61 },
+	{ 1.9, 4.74, 83996.85 },
+	{ 2.1, 2.55, 25132.30 },
+	{ 1.8, 1.47, 4164.31 },
+	{ 1.8, 3.02, 5.52 },
+	{ 2.0, 0.91, 6256.78 },
+	{ 2.1, 2.27, 522.58 },
+	{ 1.8, 3.03, 5753.38 },
+	{ 1.6, 6.12, 5216.58 },
+	{ 1.6, 4.64, 3.29 },
+	/* 71 terms retained, 270 terms dropped, error 0.056"*T */
+
+	/* earth l, T^2 */
+	{ 52918.9, 0, 0 },
+	{ 8719.8, 1.07210, 6283.07585 },
+	{ 309.1, 0.8673, 12566.1517 },
+	{ 27.3, 0.053, 3.523 },
+	{ 16.3, 5.188, 26.298 },
+	{ 15.8, 3.685, 155.420 },
+	{ 9.5, 0.76, 18849.23 },
+	{ 8.9, 2.06, 77713.77 },
+	{ 7.0, 0.83, 775.52 },
+	{ 5.1, 4.66, 1577.34 },
+	{ 4.1, 1.03, 7.11 },
+	{ 3.5, 5.14, 796.30 },
+	{ 3.2, 6.05, 5507.55 },
+	{ 3.0, 1.19, 242.73 },
+	{ 2.9, 6.12, 529.69 },
+	{ 3.8, 3.44, 5573.14 },
+	{ 2.7, 0.31, 398.15 },
+	{ 2.4, 4.38, 5223.69 },
+	{ 2.5, 2.28, 553.57 },
+	{ 2.1, 3.75, 0.98 },
+	{ 1.7, 0.90, 951.72 },
+	{ 1.5, 5.76, 1349.87 },
+	{ 1.2, 2.97, 2146.17 },
+	{ 1.4, 4.36, 1748.02 },
+	{ 1.3, 3.72, 1194.45 },
+	{ 1.3, 2.95, 6438.50 },
+	{ 1.0, 5.99, 6286.60 },
+	{ 0.9, 4.80, 5088.63 },
+	{ 0.8, 3.31, 213.30 },
+	{ 1.1, 1.27, 161000.69 },
+	{ 0.8, 3.42, 5486.78 },
+	{ 1.0, 0.60, 3154.69 },
+	{ 0.9, 5.23, 7084.90 },
+	{ 0.6, 1.60, 2544.31 },
+	{ 0.7, 3.43, 4694.00 },
+	{ 0.6, 2.48, 10977.08 },
+	{ 0.7, 6.19, 4690.48 },
+	{ 0.6, 1.98, 801.82 },
+	{ 0.5, 1.44, 6836.65 },
+	{ 0.5, 2.34, 1592.60 },
+	{ 0.5, 1.31, 4292.33 },
+	{ 0.4, 0.04, 7234.79 },
+	{ 0.5, 3.81, 149854.40 },
+	{ 0.4, 4.94, 7632.94 },
+	/* 44 terms retained, 98 terms dropped, error 0.011"*T^2 */
+
+	/* earth l, T^3 */
+	{ 289.2, 5.8438, 6283.0758 },
+	{ 35.0, 0, 0 },
+	{ 16.8, 5.488, 12566.152 },
+	{ 3.0, 5.20, 155.42 },
+	{ 1.3, 4.72, 3.52 },
+	{ 0.6, 5.97, 242.73 },
+	{ 0.7, 5.30, 18849.23 },
+	{ 0.4, 3.79, 553.57 },
+	/* 8 terms retained, 14 terms dropped, error 0.005"*T^3 */
+
+	/* earth l, T^4 */
+	{ 114.1, 3.1416, 0 },
+	{ 7.7, 4.13, 6283.08 },
+	{ 0.8, 3.84, 12566.15 },
+	{ 0.4, 0.42, 155.42 },
+	/* 4 terms retained, 7 terms dropped, error 0.00032"*T^4 */
+
+	/* earth l, T^5 */
+	{ 0.9, 3.14, 0 },
+	{ 0.2, 2.77, 6283.08 },
+	{ 0.1, 2.01, 155.42 },
+	/* 3 terms retained, 2 terms dropped, error 0.00023"*T^5 */
+	/* end earth l */
+
+	/* earth b, T^0 */
+	{ 279.6, 3.1987, 84334.6616 },
+	{ 101.6, 5.4225, 5507.5532 },
+	{ 80.4, 3.880, 5223.694 },
+	{ 43.8, 3.704, 2352.866 },
+	{ 31.9, 4.000, 1577.344 },
+	{ 22.7, 3.985, 1047.747 },
+	{ 16.4, 3.565, 5856.478 },
+	{ 18.1, 4.984, 6283.076 },
+	{ 14.4, 3.703, 9437.763 },
+	{ 14.3, 3.411, 10213.286 },
+	{ 11.2, 4.828, 14143.495 },
+	{ 10.9, 2.086, 6812.767 },
+	{ 9.7, 3.47, 4694.00 },
+	{ 10.4, 4.057, 71092.881 },
+	{ 8.8, 4.44, 5753.38 },
+	{ 8.4, 4.99, 7084.90 },
+	{ 6.9, 4.33, 6275.96 },
+	{ 9.1, 1.14, 6620.89 },
+	{ 7.2, 3.60, 529.69 },
+	{ 7.7, 5.55, 167621.58 },
+	/* 20 terms retained, 164 terms dropped, error 0.15" */
+
+	/* earth b, T^1 */
+	{ 9.0, 3.90, 5507.55 },
+	{ 6.2, 1.73, 5223.69 },
+	{ 3.8, 5.24, 2352.87 },
+	{ 2.8, 2.47, 1577.34 },
+	{ 1.8, 0.42, 6283.08 },
+	/* 5 terms retained, 94 terms dropped, error 0.018"*T */
+
+	/* earth b, T^2 */
+	{ 1.7, 1.63, 84334.66 },
+	{ 0.5, 2.41, 1047.75 },
+	/* 2 terms retained, 47 terms dropped, error 0.0035"*T^2 */
+
+	/* earth b, T^3 */
+	/* 0 terms retained, 11 terms dropped, error 4.5e-05"*T^3 */
+
+	/* earth b, T^4 */
+	/* 0 terms retained, 5 terms dropped, error 1.7e-05"*T^4 */
+	/* end earth b */
+
+	/* earth r, T^0 */
+	{ 100013988.8, 0, 0 },
+	{ 1670699.6, 3.09846351, 6283.07584999 },
+	{ 13956.0, 3.055246, 12566.151700 },
+	{ 3083.7, 5.19847, 77713.77147 },
+	{ 1628.5, 1.17388, 5753.38488 },
+	{ 1575.6, 2.84685, 7860.41939 },
+	{ 924.8, 5.4529, 11506.7698 },
+	{ 542.4, 4.5641, 3930.2097 },
+	{ 472.1, 3.6610, 5884.9268 },
+	{ 328.8, 5.8998, 5223.6939 },
+	{ 346.0, 0.9637, 5507.5532 },
+	{ 306.8, 0.2987, 5573.1428 },
+	{ 174.8, 3.0119, 18849.2275 },
+	{ 243.2, 4.2735, 11790.6291 },
+	{ 211.8, 5.8471, 1577.3435 },
+	{ 185.8, 5.0219, 10977.0788 },
+	{ 109.8, 5.0551, 5486.7778 },
+	{ 98.3, 0.887, 6069.777 },
+	{ 86.5, 5.690, 15720.839 },
+	{ 85.8, 1.271, 161000.686 },
+	{ 62.9, 0.922, 529.691 },
+	{ 57.1, 2.014, 83996.847 },
+	{ 64.9, 0.273, 17260.155 },
+	{ 49.4, 3.245, 2544.314 },
+	{ 55.7, 5.242, 71430.696 },
+	{ 42.5, 6.011, 6275.962 },
+	{ 47.0, 2.578, 775.523 },
+	{ 39.0, 5.361, 4694.003 },
+	{ 44.7, 5.537, 9437.763 },
+	{ 35.7, 1.675, 12036.461 },
+	{ 31.9, 0.184, 5088.629 },
+	{ 31.8, 1.778, 398.149 },
+	{ 33.2, 0.244, 7084.897 },
+	{ 38.2, 2.393, 8827.390 },
+	{ 28.5, 1.213, 6286.599 },
+	{ 37.5, 0.830, 19651.048 },
+	{ 37.0, 4.901, 12139.554 },
+	{ 34.5, 1.843, 2942.463 },
+	{ 26.3, 4.589, 10447.388 },
+	{ 24.6, 3.787, 8429.241 },
+	{ 23.6, 0.269, 796.298 },
+	{ 27.8, 1.899, 6279.553 },
+	{ 23.9, 4.996, 5856.478 },
+	{ 20.3, 4.653, 2146.165 },
+	{ 23.3, 2.808, 14143.495 },
+	{ 22.1, 1.950, 3154.687 },
+	{ 19.5, 5.382, 2352.866 },
+	{ 18.0, 0.199, 6812.767 },
+	{ 17.2, 4.433, 10213.286 },
+	{ 16.2, 5.232, 17789.846 },
+	{ 17.3, 6.152, 16730.464 },
+	{ 13.8, 5.190, 8031.092 },
+	{ 18.8, 0.673, 149854.400 },
+	{ 18.3, 2.253, 23581.258 },
+	{ 13.6, 3.685, 4705.732 },
+	{ 13.1, 0.653, 13367.973 },
+	{ 10.4, 4.333, 11769.854 },
+	{ 10.0, 4.201, 6309.374 },
+	{ 10.2, 1.594, 4690.480 },
+	{ 7.6, 2.63, 6256.78 },
+	{ 9.7, 3.68, 27511.47 },
+	{ 6.7, 0.56, 3340.61 },
+	{ 8.7, 6.06, 1748.02 },
+	{ 7.8, 3.67, 12168.00 },
+	{ 6.6, 5.66, 11371.70 },
+	{ 7.7, 0.31, 7632.94 },
+	{ 6.6, 3.14, 801.82 },
+	{ 7.5, 5.65, 11926.25 },
+	{ 6.9, 2.92, 6681.22 },
+	{ 6.8, 1.42, 23013.54 },
+	{ 6.5, 2.65, 19804.83 },
+	/* 71 terms retained, 455 terms dropped, error 1.1e-06 a.u. */
+
+	/* earth r, T^1 */
+	{ 103018.6, 1.1074897, 6283.0758500 },
+	{ 1721.2, 1.06442, 12566.15170 },
+	{ 702.2, 3.1416, 0 },
+	{ 32.3, 1.022, 18849.228 },
+	{ 30.8, 2.844, 5507.553 },
+	{ 25.0, 1.319, 5223.694 },
+	{ 18.5, 1.424, 1577.344 },
+	{ 10.1, 5.914, 10977.079 },
+	{ 8.6, 0.27, 5486.78 },
+	{ 8.7, 1.42, 6275.96 },
+	{ 5.1, 1.69, 5088.63 },
+	{ 5.0, 6.01, 6286.60 },
+	{ 4.7, 5.99, 529.69 },
+	{ 4.4, 0.52, 4694.00 },
+	{ 3.9, 4.75, 2544.31 },
+	{ 3.8, 5.07, 796.30 },
+	{ 4.1, 1.08, 9437.76 },
+	{ 3.5, 0.02, 83996.85 },
+	{ 3.4, 0.95, 71430.70 },
+	{ 3.2, 6.16, 2146.17 },
+	{ 3.4, 5.41, 775.52 },
+	{ 2.9, 5.48, 10447.39 },
+	{ 2.5, 0.24, 398.15 },
+	{ 2.2, 4.95, 6812.77 },
+	{ 2.2, 0.42, 8031.09 },
+	{ 2.8, 3.42, 2352.87 },
+	{ 2.6, 6.13, 6438.50 },
+	{ 1.9, 5.31, 8429.24 },
+	{ 2.4, 3.09, 4690.48 },
+	{ 1.7, 1.54, 4705.73 },
+	{ 2.2, 3.69, 7084.90 },
+	{ 2.1, 1.28, 1748.02 },
+	{ 1.8, 3.23, 6279.55 },
+	{ 1.6, 4.10, 11499.66 },
+	{ 1.6, 5.54, 3154.69 },
+	{ 1.8, 1.82, 7632.94 },
+	/* 36 terms retained, 256 terms dropped, error 2.2e-07 a.u.*T */
+
+	/* earth r, T^2 */
+	{ 4359.4, 5.78455, 6283.07585 },
+	{ 123.6, 5.5793, 12566.1517 },
+	{ 12.3, 3.142, 0 },
+	{ 8.8, 3.63, 77713.77 },
+	{ 5.7, 1.87, 5573.14 },
+	{ 3.3, 5.47, 18849.23 },
+	{ 1.5, 4.48, 5507.55 },
+	{ 1.0, 2.81, 5223.69 },
+	{ 0.9, 3.11, 1577.34 },
+	{ 1.1, 2.84, 161000.69 },
+	{ 0.6, 5.47, 775.52 },
+	{ 0.6, 1.38, 6438.50 },
+	{ 0.5, 4.42, 6286.60 },
+	{ 0.4, 0.90, 10977.08 },
+	{ 0.4, 3.20, 5088.63 },
+	{ 0.5, 3.66, 7084.90 },
+	{ 0.5, 5.39, 149854.40 },
+	/* 17 terms retained, 122 terms dropped, error 3.9e-08 a.u.*T^2 */
+
+	/* earth r, T^3 */
+	{ 144.6, 4.2732, 6283.0758 },
+	{ 6.7, 3.92, 12566.15 },
+	{ 0.8, 0, 0 },
+	{ 0.2, 3.73, 18849.23 },
+	/* 4 terms retained, 23 terms dropped, error 1.1e-08 a.u.*T^3 */
+
+	/* earth r, T^4 */
+	{ 3.9, 2.56, 6283.08 },
+	{ 0.3, 2.27, 12566.15 },
+	{ 0.1, 3.44, 5573.14 },
+	/* 3 terms retained, 7 terms dropped, error 2.1e-09 a.u.*T^4 */
+
+	/* earth r, T^5 */
+	{ 0.1, 1.22, 6283.08 },
+	/* 1 terms retained, 2 terms dropped, error 2.4e-09 a.u.*T^5 */
+	/* end earth */
+};
+
+int vn_earth[][3] = {
+	/* addresses for earth l, b, r  */
+	/* T^0 */ { 0, 247, 274, },
+	/* T^1 */ { 117, 267, 345, },
+	/* T^2 */ { 188, 272, 381, },
+	/* T^3 */ { 232, 274, 398, },
+	/* T^4 */ { 240, 0, 402, },
+	/* T^5 */ { 244, 0, 405, },
+	/* end */ { 247, 0, 406, },
+	/* termination */ { 0, }
+};
+
+/*  version d4 (lbr)       
+ *  heliocentric dynamical ecliptic and equinox of the date
+ */
+
+double vx_jupiter[][3] = {
+	/* jupiter l, T^0 */
+	{ 59954691.5, 0, 0 },
+	{ 9695898.7, 5.06191793, 529.69096509 },
+	{ 573610.1, 1.4440621, 7.1135470 },
+	{ 306389.2, 5.4173473, 1059.3819302 },
+	{ 97178.3, 4.142647, 632.783739 },
+	{ 72903.1, 3.640429, 522.577418 },
+	{ 64264.0, 3.411452, 103.092774 },
+	{ 39806.1, 2.293767, 419.484644 },
+	{ 38857.8, 1.272317, 316.391870 },
+	{ 27964.6, 1.784546, 536.804512 },
+	{ 13589.7, 5.774810, 1589.072895 },
+	{ 8246.4, 3.58228, 206.18555 },
+	{ 8768.7, 3.63000, 949.17561 },
+	{ 7368.1, 5.08101, 735.87651 },
+	{ 6263.2, 0.02498, 213.29910 },
+	{ 6114.0, 4.51320, 1162.47470 },
+	{ 4905.4, 1.32085, 110.20632 },
+	{ 5305.3, 1.30671, 14.22709 },
+	{ 5305.5, 4.18625, 1052.26838 },
+	{ 4647.2, 4.69958, 3.93215 },
+	{ 3045.0, 4.31676, 426.59819 },
+	{ 2610.0, 1.56668, 846.08283 },
+	{ 2028.2, 1.06377, 3.18139 },
+	{ 1764.8, 2.14148, 1066.49548 },
+	{ 1723.0, 3.88036, 1265.56748 },
+	{ 1921.0, 0.97169, 639.89729 },
+	{ 1633.2, 3.58201, 515.46387 },
+	{ 1432.0, 4.29684, 625.67019 },
+	{ 973.3, 4.0976, 95.9792 },
+	{ 884.4, 2.4370, 412.3711 },
+	{ 732.9, 6.0853, 838.9693 },
+	{ 731.1, 3.8059, 1581.9593 },
+	{ 691.9, 6.1337, 2118.7639 },
+	{ 709.2, 1.2927, 742.9901 },
+	{ 614.5, 4.1085, 1478.8666 },
+	{ 495.2, 3.7557, 323.5054 },
+	{ 581.9, 4.5397, 309.2783 },
+	{ 375.7, 4.7030, 1368.6603 },
+	{ 389.9, 4.8972, 1692.1657 },
+	{ 341.0, 5.7145, 533.6231 },
+	{ 330.5, 4.7405, 0.0482 },
+	{ 440.9, 2.9582, 454.9094 },
+	{ 417.3, 1.0355, 2.4477 },
+	{ 244.2, 5.2202, 728.7630 },
+	{ 261.5, 1.8765, 0.9632 },
+	{ 256.6, 3.7241, 199.0720 },
+	{ 261.0, 0.8205, 380.1278 },
+	{ 220.4, 1.6512, 543.9181 },
+	{ 202.0, 1.8068, 1375.7738 },
+	{ 207.3, 1.8546, 525.7588 },
+	{ 197.0, 5.2925, 1155.3612 },
+	{ 235.1, 1.2269, 909.8187 },
+	{ 174.8, 5.9097, 956.2892 },
+	{ 149.4, 4.3775, 1685.0521 },
+	{ 175.2, 3.2263, 1898.3512 },
+	{ 175.2, 3.7297, 942.0621 },
+	{ 157.9, 4.3648, 1795.2584 },
+	{ 137.9, 1.3180, 1169.5883 },
+	{ 117.5, 2.5002, 1596.1864 },
+	{ 150.5, 3.9063, 74.7816 },
+	{ 116.8, 3.3892, 0.5213 },
+	{ 105.9, 4.5544, 526.5096 },
+	{ 130.5, 4.1687, 1045.1548 },
+	{ 141.4, 3.1357, 491.5579 },
+	{ 99.5, 1.421, 532.872 },
+	{ 96.1, 1.182, 117.320 },
+	{ 91.8, 0.858, 1272.681 },
+	{ 87.7, 1.217, 453.425 },
+	{ 68.5, 2.352, 2.921 },
+	{ 66.1, 5.344, 1471.753 },
+	{ 77.4, 4.427, 39.357 },
+	{ 72.0, 4.238, 2111.650 },
+	{ 63.4, 4.977, 0.751 },
+	{ 59.4, 4.111, 2001.444 },
+	{ 62.5, 0.512, 220.413 },
+	{ 66.5, 2.989, 2214.743 },
+	{ 60.2, 4.126, 4.193 },
+	{ 56.0, 1.155, 21.341 },
+	{ 52.9, 0.912, 10.295 },
+	{ 70.3, 5.142, 835.037 },
+	{ 51.9, 4.100, 1258.454 },
+	{ 46.4, 4.665, 5.629 },
+	{ 58.2, 5.866, 5753.385 },
+	{ 40.1, 4.688, 0.160 },
+	{ 46.7, 4.794, 305.346 },
+	{ 39.3, 4.254, 853.196 },
+	{ 46.0, 5.110, 4.666 },
+	{ 54.5, 1.571, 983.116 },
+	{ 38.9, 6.076, 518.645 },
+	{ 38.4, 2.438, 433.712 },
+	{ 46.8, 3.546, 5.417 },
+	{ 41.8, 4.680, 302.165 },
+	{ 35.9, 2.451, 430.530 },
+	{ 37.9, 0.211, 2648.455 },
+	{ 39.2, 1.718, 11.046 },
+	{ 37.6, 6.195, 831.856 },
+	{ 35.8, 4.615, 2008.558 },
+	{ 43.4, 0.150, 528.206 },
+	{ 31.6, 5.141, 1788.145 },
+	{ 29.8, 5.344, 2221.857 },
+	{ 32.8, 5.289, 88.866 },
+	{ 27.7, 1.852, 0.212 },
+	{ 25.8, 3.859, 2317.836 },
+	{ 33.8, 1.006, 9683.595 },
+	{ 27.1, 2.808, 18.159 },
+	{ 26.8, 1.776, 532.139 },
+	{ 26.1, 2.744, 2531.135 },
+	{ 30.8, 0.423, 1.484 },
+	{ 30.5, 3.667, 508.350 },
+	/* 109 terms retained, 651 terms dropped, error 1.3" */
+
+	/* jupiter l, T^1 */
+	{ 52993480757.5, 0, 0 },
+	{ 489741.2, 4.2206669, 529.6909651 },
+	{ 228918.5, 6.0264746, 7.1135470 },
+	{ 27655.4, 4.572660, 1059.381930 },
+	{ 20720.9, 5.459389, 522.577418 },
+	{ 12105.7, 0.169858, 536.804512 },
+	{ 6068.1, 4.42420, 103.09277 },
+	{ 5433.9, 3.98478, 419.48464 },
+	{ 4237.8, 5.89009, 14.22709 },
+	{ 2211.9, 5.26771, 206.18555 },
+	{ 1295.8, 5.55133, 3.18139 },
+	{ 1745.9, 4.92669, 1589.07290 },
+	{ 1163.4, 0.51451, 3.93215 },
+	{ 1007.2, 0.46478, 735.87651 },
+	{ 1173.1, 5.85647, 1052.26838 },
+	{ 847.7, 5.7581, 110.2063 },
+	{ 827.3, 4.8031, 213.2991 },
+	{ 1003.6, 3.15040, 426.59819 },
+	{ 1098.7, 5.30705, 515.46387 },
+	{ 816.4, 0.5864, 1066.4955 },
+	{ 725.4, 5.5183, 639.8973 },
+	{ 567.8, 5.9887, 625.6702 },
+	{ 474.2, 4.1325, 412.3711 },
+	{ 412.9, 5.7365, 95.9792 },
+	{ 335.8, 3.7325, 1162.4747 },
+	{ 345.2, 4.2416, 632.7837 },
+	{ 234.1, 6.2430, 309.2783 },
+	{ 194.8, 2.2188, 323.5054 },
+	{ 234.3, 4.0347, 949.1756 },
+	{ 183.9, 6.2796, 543.9181 },
+	{ 198.5, 1.5046, 838.9693 },
+	{ 186.9, 6.0862, 742.9901 },
+	{ 171.4, 5.4166, 199.0720 },
+	{ 130.8, 0.6264, 728.7630 },
+	{ 107.6, 4.4928, 956.2892 },
+	{ 115.4, 0.6802, 846.0828 },
+	{ 115.0, 5.2864, 2118.7639 },
+	{ 66.8, 5.734, 21.341 },
+	{ 69.6, 5.973, 532.872 },
+	{ 64.9, 6.088, 1581.959 },
+	{ 79.7, 5.824, 1045.155 },
+	{ 57.9, 0.995, 1596.186 },
+	{ 65.6, 0.129, 526.510 },
+	{ 58.5, 0.586, 1155.361 },
+	{ 56.6, 1.412, 533.623 },
+	{ 71.6, 5.342, 942.062 },
+	{ 57.4, 5.969, 1169.588 },
+	{ 54.9, 5.428, 10.295 },
+	{ 52.0, 0.230, 1368.660 },
+	{ 52.3, 5.727, 117.320 },
+	{ 50.4, 6.081, 525.759 },
+	{ 47.4, 3.626, 1478.867 },
+	{ 39.9, 4.162, 1692.166 },
+	{ 46.7, 0.511, 1265.567 },
+	{ 32.8, 5.036, 220.413 },
+	{ 33.6, 0.099, 302.165 },
+	{ 29.4, 3.359, 4.666 },
+	{ 29.3, 0.759, 88.866 },
+	{ 32.4, 5.375, 508.350 },
+	{ 29.5, 5.422, 1272.681 },
+	{ 21.8, 6.151, 1685.052 },
+	{ 25.2, 1.607, 831.856 },
+	{ 21.1, 5.863, 1258.454 },
+	{ 19.7, 2.172, 316.392 },
+	{ 17.9, 0.828, 433.712 },
+	{ 17.7, 5.955, 5.417 },
+	{ 17.2, 2.764, 853.196 },
+	{ 17.5, 0.707, 1471.753 },
+	{ 17.5, 0.498, 1375.774 },
+	{ 14.4, 0.915, 18.159 },
+	{ 14.1, 0.630, 2.921 },
+	{ 11.6, 4.304, 405.258 },
+	{ 11.7, 1.764, 380.128 },
+	{ 11.1, 5.567, 1574.846 },
+	{ 10.4, 0.314, 1361.547 },
+	{ 9.8, 5.90, 519.40 },
+	{ 9.8, 0.39, 1073.61 },
+	{ 9.3, 3.22, 1795.26 },
+	{ 8.9, 0.54, 1788.14 },
+	{ 8.4, 5.88, 2001.44 },
+	{ 8.1, 5.10, 1485.98 },
+	{ 7.7, 5.65, 2648.45 },
+	{ 6.7, 2.41, 4.19 },
+	{ 7.3, 6.19, 11.05 },
+	{ 6.3, 1.36, 1148.25 },
+	/* 85 terms retained, 284 terms dropped, error 0.24"*T */
+
+	/* jupiter l, T^2 */
+	{ 47233.6, 4.321483, 7.113547 },
+	{ 30629.1, 2.930214, 529.690965 },
+	{ 38965.5, 0, 0 },
+	{ 3189.3, 1.05505, 522.57742 },
+	{ 2723.4, 3.41412, 1059.38193 },
+	{ 2729.3, 4.84545, 536.80451 },
+	{ 1721.1, 4.18734, 14.22709 },
+	{ 383.3, 5.7679, 419.4846 },
+	{ 367.5, 6.0551, 103.0928 },
+	{ 377.5, 0.7605, 515.4639 },
+	{ 337.4, 3.7864, 3.1814 },
+	{ 308.2, 0.6936, 206.1855 },
+	{ 218.4, 3.8139, 1589.0729 },
+	{ 198.9, 5.3400, 1066.4955 },
+	{ 197.4, 2.4836, 3.9322 },
+	{ 146.2, 3.8137, 639.8973 },
+	{ 155.9, 1.4064, 1052.2684 },
+	{ 129.6, 5.8374, 412.3711 },
+	{ 141.9, 1.6344, 426.5982 },
+	{ 117.3, 1.4144, 625.6702 },
+	{ 96.7, 4.034, 110.206 },
+	{ 90.8, 1.106, 95.979 },
+	{ 78.8, 4.637, 543.918 },
+	{ 72.4, 2.217, 735.877 },
+	{ 87.3, 2.522, 632.784 },
+	{ 56.9, 3.123, 213.299 },
+	{ 48.6, 1.673, 309.278 },
+	{ 58.5, 0.832, 199.072 },
+	{ 40.1, 4.025, 21.341 },
+	{ 39.8, 0.624, 323.505 },
+	{ 35.7, 2.326, 728.763 },
+	{ 25.6, 2.512, 1162.475 },
+	{ 29.3, 3.608, 10.295 },
+	{ 23.6, 3.005, 956.289 },
+	{ 27.8, 3.240, 838.969 },
+	{ 26.0, 4.501, 742.990 },
+	{ 25.2, 1.219, 1045.155 },
+	{ 19.5, 4.290, 532.872 },
+	{ 17.7, 0.810, 508.350 },
+	{ 15.4, 5.810, 1596.186 },
+	{ 17.1, 4.200, 2118.764 },
+	{ 17.0, 1.834, 526.510 },
+	{ 14.7, 4.000, 117.320 },
+	{ 13.6, 1.803, 302.165 },
+	{ 13.2, 2.519, 88.866 },
+	{ 12.8, 4.369, 1169.588 },
+	{ 15.3, 0.682, 942.062 },
+	{ 11.0, 4.436, 525.759 },
+	{ 13.9, 5.952, 316.392 },
+	{ 9.4, 2.18, 1155.36 },
+	{ 8.8, 3.29, 220.41 },
+	{ 7.8, 5.76, 846.08 },
+	{ 7.5, 2.71, 533.62 },
+	{ 9.7, 1.72, 1581.96 },
+	{ 8.7, 3.32, 831.86 },
+	{ 6.3, 0.50, 949.18 },
+	{ 6.7, 2.18, 1265.57 },
+	{ 5.4, 6.01, 405.26 },
+	{ 4.7, 1.41, 1258.45 },
+	{ 4.4, 3.02, 1692.17 },
+	{ 4.4, 5.48, 433.71 },
+	{ 4.3, 5.07, 1073.61 },
+	{ 4.2, 5.29, 18.16 },
+	{ 3.9, 1.27, 853.20 },
+	{ 5.4, 3.65, 1272.68 },
+	{ 4.4, 2.27, 1368.66 },
+	{ 3.5, 1.54, 519.40 },
+	{ 2.7, 2.10, 1478.87 },
+	{ 2.7, 1.06, 1574.85 },
+	{ 2.9, 2.05, 1361.55 },
+	{ 3.1, 0.99, 191.96 },
+	{ 2.5, 2.37, 1471.75 },
+	{ 2.2, 2.48, 721.65 },
+	{ 2.1, 3.71, 1485.98 },
+	{ 2.0, 1.88, 1685.05 },
+	{ 2.3, 3.03, 1148.25 },
+	{ 2.0, 6.17, 330.62 },
+	/* 77 terms retained, 114 terms dropped, error 0.074"*T^2 */
+
+	/* jupiter l, T^3 */
+	{ 6501.7, 2.59863, 7.11355 },
+	{ 1356.5, 1.34636, 529.69097 },
+	{ 470.7, 2.4750, 14.2271 },
+	{ 417.0, 3.2445, 536.8045 },
+	{ 352.9, 2.9736, 522.5774 },
+	{ 154.9, 2.0757, 1059.3819 },
+	{ 86.8, 2.514, 515.464 },
+	{ 33.5, 3.826, 1066.495 },
+	{ 44.4, 0, 0 },
+	{ 22.6, 2.982, 543.918 },
+	{ 23.7, 1.277, 412.371 },
+	{ 28.5, 2.448, 206.186 },
+	{ 19.8, 2.101, 639.897 },
+	{ 19.7, 1.403, 419.485 },
+	{ 18.8, 1.594, 103.093 },
+	{ 17.0, 2.302, 21.341 },
+	{ 16.8, 2.598, 1589.073 },
+	{ 16.2, 3.145, 625.670 },
+	{ 16.1, 3.360, 1052.268 },
+	{ 13.4, 2.760, 95.979 },
+	{ 13.2, 2.539, 199.072 },
+	{ 12.6, 6.266, 426.598 },
+	{ 8.6, 2.27, 110.21 },
+	{ 6.7, 3.43, 309.28 },
+	{ 8.7, 1.76, 10.29 },
+	{ 6.5, 4.04, 728.76 },
+	{ 5.4, 5.25, 323.51 },
+	{ 5.7, 2.52, 508.35 },
+	{ 5.4, 2.91, 1045.15 },
+	{ 4.0, 4.30, 88.87 },
+	{ 3.9, 3.52, 302.16 },
+	{ 3.8, 4.09, 735.88 },
+	{ 3.3, 1.43, 956.29 },
+	{ 2.8, 4.36, 1596.19 },
+	{ 2.7, 1.25, 213.30 },
+	{ 2.6, 2.24, 117.32 },
+	{ 2.4, 2.90, 742.99 },
+	{ 2.7, 5.02, 838.97 },
+	{ 1.9, 2.77, 1169.59 },
+	{ 2.3, 2.36, 942.06 },
+	{ 1.5, 1.61, 220.41 },
+	{ 1.5, 3.09, 2118.76 },
+	{ 1.9, 5.01, 831.86 },
+	{ 1.6, 1.40, 405.26 },
+	{ 1.3, 3.98, 1155.36 },
+	{ 1.2, 3.46, 1073.61 },
+	{ 1.0, 3.39, 532.87 },
+	{ 0.9, 2.70, 191.96 },
+	{ 0.8, 1.48, 632.78 },
+	{ 0.8, 1.11, 1162.47 },
+	{ 0.8, 3.30, 1258.45 },
+	{ 0.7, 5.90, 853.20 },
+	{ 0.8, 3.66, 1581.96 },
+	{ 0.7, 3.75, 433.71 },
+	{ 0.7, 2.93, 1574.85 },
+	{ 0.7, 3.53, 525.76 },
+	{ 0.6, 4.15, 721.65 },
+	{ 0.6, 4.69, 81.75 },
+	{ 0.7, 1.96, 1272.68 },
+	{ 0.5, 1.57, 949.18 },
+	{ 0.7, 2.02, 526.51 },
+	{ 0.5, 4.36, 1368.66 },
+	{ 0.5, 4.96, 1148.25 },
+	{ 0.5, 4.31, 330.62 },
+	{ 0.6, 2.28, 551.03 },
+	{ 0.5, 3.87, 1361.55 },
+	{ 0.4, 2.95, 1038.04 },
+	{ 0.4, 4.08, 1471.75 },
+	{ 0.4, 2.22, 539.99 },
+	{ 0.4, 4.53, 1464.64 },
+	/* 70 terms retained, 39 terms dropped, error 0.014"*T^3 */
+
+	/* jupiter l, T^4 */
+	{ 669.5, 0.8528, 7.1135 },
+	{ 100.0, 0.7426, 14.2271 },
+	{ 114.0, 3.1416, 0 },
+	{ 50.0, 1.653, 536.805 },
+	{ 43.6, 5.820, 529.691 },
+	{ 31.8, 4.858, 522.577 },
+	{ 14.7, 4.291, 515.464 },
+	{ 8.9, 0.71, 1059.38 },
+	{ 5.0, 1.30, 543.92 },
+	{ 4.5, 2.32, 1066.50 },
+	{ 4.3, 0.48, 21.34 },
+	{ 3.1, 3.00, 412.37 },
+	{ 2.1, 0.40, 639.90 },
+	{ 1.8, 4.91, 625.67 },
+	{ 1.9, 4.26, 199.07 },
+	{ 1.7, 4.26, 206.19 },
+	{ 1.4, 5.26, 1052.27 },
+	{ 1.2, 4.72, 95.98 },
+	{ 1.1, 1.29, 1589.07 },
+	{ 1.0, 4.78, 1045.15 },
+	{ 0.9, 6.06, 88.87 },
+	{ 0.9, 5.78, 728.76 },
+	{ 0.9, 4.55, 426.60 },
+	{ 0.8, 3.40, 419.48 },
+	{ 0.8, 3.55, 103.09 },
+	{ 0.7, 0.52, 110.21 },
+	{ 0.4, 5.23, 302.16 },
+	{ 0.4, 6.24, 956.29 },
+	{ 0.4, 5.25, 309.28 },
+	{ 0.4, 0.60, 117.32 },
+	{ 0.3, 4.78, 508.35 },
+	{ 0.3, 3.48, 323.51 },
+	{ 0.3, 2.96, 1596.19 },
+	{ 0.3, 4.33, 942.06 },
+	{ 0.3, 0.48, 831.86 },
+	{ 0.3, 1.80, 1073.61 },
+	{ 0.2, 0.44, 220.41 },
+	{ 0.2, 1.13, 1169.59 },
+	{ 0.2, 2.16, 1361.55 },
+	{ 0.2, 3.43, 1148.25 },
+	{ 0.2, 1.93, 2118.76 },
+	{ 0.2, 3.03, 1272.68 },
+	/* 42 terms retained, 3 terms dropped, error 0.0042"*T^4 */
+
+	/* jupiter l, T^5 */
+	{ 49.6, 5.257, 7.114 },
+	{ 15.8, 5.251, 14.227 },
+	{ 4.3, 0.01, 536.80 },
+	{ 1.5, 1.10, 522.58 },
+	{ 0.7, 5.86, 543.92 },
+	{ 0.7, 0.87, 515.46 },
+	{ 0.8, 3.14, 0 },
+	{ 0.5, 0.82, 1066.50 },
+	{ 0.3, 5.63, 1059.38 },
+	/* 9 terms retained, 1 terms dropped, error 0.0038"*T^5 */
+	/* end jupiter l */
+
+	/* jupiter b, T^0 */
+	{ 2268615.7, 3.55852607, 529.69096509 },
+	{ 109971.6, 3.9080935, 1059.3819302 },
+	{ 110090.4, 0, 0 },
+	{ 8101.4, 3.60510, 522.57742 },
+	{ 6044.0, 4.25883, 1589.07290 },
+	{ 6437.8, 0.30627, 536.80451 },
+	{ 1106.9, 2.98534, 1162.47470 },
+	{ 941.7, 2.9362, 1052.2684 },
+	{ 894.1, 1.7545, 7.1135 },
+	{ 767.3, 2.1547, 632.7837 },
+	{ 944.3, 1.6752, 426.5982 },
+	{ 684.2, 3.6781, 213.2991 },
+	{ 629.2, 0.6434, 1066.4955 },
+	{ 835.9, 5.1788, 103.0928 },
+	{ 531.7, 2.7031, 110.2063 },
+	{ 558.5, 0.0135, 846.0828 },
+	{ 464.4, 1.1734, 949.1756 },
+	{ 431.1, 2.6083, 419.4846 },
+	{ 351.4, 4.6106, 2118.7639 },
+	{ 123.1, 3.3497, 1692.1657 },
+	{ 115.0, 5.0489, 316.3919 },
+	{ 132.2, 4.7782, 742.9901 },
+	{ 103.4, 2.3188, 1478.8666 },
+	{ 116.4, 1.3869, 323.5054 },
+	{ 102.4, 3.1529, 1581.9593 },
+	{ 103.8, 3.7010, 515.4639 },
+	{ 78.7, 3.983, 1265.567 },
+	{ 69.9, 2.560, 956.289 },
+	{ 55.6, 0.375, 1375.774 },
+	{ 52.0, 0.990, 1596.186 },
+	{ 55.2, 0.402, 525.759 },
+	{ 63.5, 4.501, 735.877 },
+	{ 49.7, 0.186, 543.918 },
+	{ 48.8, 3.573, 533.623 },
+	{ 28.4, 1.535, 625.670 },
+	{ 29.2, 5.431, 206.186 },
+	/* 36 terms retained, 213 terms dropped, error 0.73" */
+
+	/* jupiter b, T^1 */
+	{ 177351.8, 5.7016649, 529.6909651 },
+	{ 3230.2, 5.77942, 1059.38193 },
+	{ 3081.4, 5.47464, 522.57742 },
+	{ 2211.9, 4.73477, 536.80451 },
+	{ 1694.2, 3.14159, 0 },
+	{ 346.4, 4.7460, 1052.2684 },
+	{ 234.3, 5.1886, 1066.4955 },
+	{ 196.2, 6.1855, 7.1135 },
+	{ 150.5, 3.9272, 1589.0729 },
+	{ 114.1, 3.4390, 632.7837 },
+	{ 96.7, 2.914, 949.176 },
+	{ 76.6, 2.505, 103.093 },
+	{ 81.7, 5.077, 1162.475 },
+	{ 76.6, 0.613, 419.485 },
+	{ 73.9, 5.500, 515.464 },
+	{ 49.9, 3.948, 735.877 },
+	{ 60.5, 5.447, 213.299 },
+	{ 36.6, 4.698, 543.918 },
+	{ 46.0, 0.539, 110.206 },
+	{ 45.1, 1.895, 846.083 },
+	{ 36.0, 6.110, 316.392 },
+	{ 32.0, 4.925, 1581.959 },
+	{ 21.0, 5.630, 1596.186 },
+	{ 23.2, 5.848, 323.505 },
+	{ 24.7, 3.941, 2118.764 },
+	{ 17.3, 5.653, 533.623 },
+	{ 16.5, 5.898, 526.510 },
+	{ 16.7, 5.667, 1265.567 },
+	{ 15.8, 4.433, 1045.155 },
+	{ 13.4, 4.302, 532.872 },
+	{ 11.7, 1.810, 956.289 },
+	{ 11.9, 4.301, 525.759 },
+	{ 9.5, 2.03, 206.19 },
+	{ 10.5, 6.155, 14.227 },
+	{ 8.4, 3.93, 1478.87 },
+	{ 8.1, 4.20, 1169.59 },
+	{ 7.7, 2.99, 942.06 },
+	{ 8.8, 1.56, 426.60 },
+	{ 8.9, 4.87, 1155.36 },
+	{ 7.8, 3.85, 625.67 },
+	/* 40 terms retained, 101 terms dropped, error 0.21"*T */
+
+	/* jupiter b, T^2 */
+	{ 8094.1, 1.46323, 529.69097 },
+	{ 742.4, 0.9569, 522.5774 },
+	{ 813.2, 3.1416, 0 },
+	{ 399.0, 2.8989, 536.8045 },
+	{ 342.2, 1.4468, 1059.3819 },
+	{ 73.9, 0.407, 1052.268 },
+	{ 46.2, 3.480, 1066.495 },
+	{ 29.3, 0.991, 515.464 },
+	{ 29.7, 1.925, 1589.073 },
+	{ 22.8, 4.271, 7.114 },
+	{ 13.9, 2.922, 543.918 },
+	{ 12.1, 5.222, 632.784 },
+	{ 10.7, 4.880, 949.176 },
+	{ 6.1, 6.21, 1045.15 },
+	{ 5.9, 0.53, 1581.96 },
+	{ 5.0, 1.43, 526.51 },
+	{ 4.6, 0.92, 1162.47 },
+	{ 4.5, 4.02, 1596.19 },
+	{ 5.1, 6.03, 735.88 },
+	{ 3.6, 4.54, 110.21 },
+	{ 3.4, 1.39, 533.62 },
+	{ 3.3, 4.40, 14.23 },
+	{ 3.4, 0.42, 419.48 },
+	{ 2.9, 2.06, 316.39 },
+	{ 2.5, 3.98, 323.51 },
+	{ 3.1, 2.48, 2118.76 },
+	{ 3.1, 2.40, 532.87 },
+	{ 2.2, 4.78, 942.06 },
+	{ 2.1, 3.89, 426.60 },
+	{ 2.3, 0.37, 1155.36 },
+	{ 2.0, 3.90, 846.08 },
+	{ 1.9, 1.20, 103.09 },
+	{ 1.7, 1.42, 1265.57 },
+	{ 2.3, 0.88, 213.30 },
+	{ 1.8, 5.80, 625.67 },
+	{ 1.7, 2.24, 525.76 },
+	/* 36 terms retained, 45 terms dropped, error 0.043"*T^2 */
+
+	/* jupiter b, T^3 */
+	{ 251.6, 3.3809, 529.6910 },
+	{ 121.7, 2.7331, 522.5774 },
+	{ 48.7, 1.037, 536.805 },
+	{ 11.0, 2.315, 1052.268 },
+	{ 8.1, 2.77, 515.46 },
+	{ 6.2, 1.78, 1066.50 },
+	{ 7.3, 4.25, 1059.38 },
+	{ 3.6, 1.13, 543.92 },
+	{ 2.8, 3.14, 0 },
+	{ 1.9, 2.29, 7.11 },
+	{ 1.6, 1.78, 1045.15 },
+	{ 0.9, 0.45, 632.78 },
+	{ 0.8, 0.31, 949.18 },
+	{ 0.7, 2.64, 14.23 },
+	{ 0.9, 0.33, 1589.07 },
+	{ 0.7, 2.37, 1581.96 },
+	{ 0.6, 2.48, 1596.19 },
+	{ 0.7, 1.53, 735.88 },
+	{ 0.5, 3.68, 419.48 },
+	{ 0.5, 0.27, 942.06 },
+	{ 0.5, 3.18, 526.51 },
+	{ 0.4, 2.88, 110.21 },
+	/* 22 terms retained, 20 terms dropped, error 0.0081"*T^3 */
+
+	/* jupiter b, T^4 */
+	{ 15.1, 4.530, 522.577 },
+	{ 5.4, 4.47, 529.69 },
+	{ 4.5, 5.44, 536.80 },
+	{ 3.4, 0, 0 },
+	{ 1.8, 4.52, 515.46 },
+	{ 1.3, 4.20, 1052.27 },
+	{ 0.8, 5.59, 543.92 },
+	{ 0.5, 0.06, 1066.50 },
+	{ 0.3, 3.67, 1059.38 },
+	{ 0.1, 3.56, 1045.15 },
+	{ 0.1, 5.70, 7.11 },
+	{ 0.1, 1.17, 14.23 },
+	/* 12 terms retained, 0 terms dropped, error 0.0017"*T^4 */
+
+	/* jupiter b, T^5 */
+	{ 1.4, 0.09, 522.58 },
+	{ 0.4, 0.01, 515.46 },
+	{ 0.3, 3.28, 536.80 },
+	{ 0.1, 0.34, 529.69 },
+	/* 4 terms retained, 1 terms dropped, error 0.0012"*T^5 */
+	/* end jupiter b */
+
+	/* jupiter r, T^0 */
+	{ 520887429.5, 0, 0 },
+	{ 25209327.0, 3.491086400, 529.690965095 },
+	{ 610599.9, 3.8411537, 1059.3819302 },
+	{ 282029.5, 2.5741988, 632.7837393 },
+	{ 187647.4, 2.0759038, 522.5774181 },
+	{ 86792.9, 0.710011, 419.484644 },
+	{ 72062.9, 0.214657, 536.804512 },
+	{ 65517.2, 5.979959, 316.391870 },
+	{ 29134.6, 1.677592, 103.092774 },
+	{ 30135.3, 2.161321, 949.175609 },
+	{ 23453.2, 3.540231, 735.876514 },
+	{ 22283.7, 4.193628, 1589.072895 },
+	{ 23947.3, 0.274579, 7.113547 },
+	{ 13032.6, 2.960431, 1162.474704 },
+	{ 9703.3, 1.90670, 206.18555 },
+	{ 12749.0, 2.715501, 1052.268383 },
+	{ 9161.4, 4.41353, 213.29910 },
+	{ 7894.5, 2.47908, 426.59819 },
+	{ 7058.0, 2.18185, 1265.56748 },
+	{ 6137.8, 6.26418, 846.08283 },
+	{ 5477.1, 5.65729, 639.89729 },
+	{ 3502.5, 0.56531, 1066.49548 },
+	{ 4136.9, 2.72220, 625.67019 },
+	{ 4170.0, 2.01605, 515.46387 },
+	{ 2500.0, 4.55182, 838.96929 },
+	{ 2617.0, 2.00994, 1581.95935 },
+	{ 1911.9, 0.85622, 412.37110 },
+	{ 2127.6, 6.12751, 742.99006 },
+	{ 1610.5, 3.08868, 1368.66025 },
+	{ 1479.5, 2.68026, 1478.86657 },
+	{ 1230.7, 1.89043, 323.50542 },
+	{ 1216.8, 1.80172, 110.20632 },
+	{ 961.1, 4.5488, 2118.7639 },
+	{ 885.7, 4.1479, 533.6231 },
+	{ 776.7, 3.6770, 728.7630 },
+	{ 998.6, 2.8721, 309.2783 },
+	{ 1015.0, 1.38673, 454.90937 },
+	{ 727.2, 3.9882, 1155.3612 },
+	{ 655.3, 2.7907, 1685.0521 },
+	{ 821.5, 1.5934, 1898.3512 },
+	{ 620.8, 4.8228, 956.2892 },
+	{ 654.0, 3.3815, 1692.1657 },
+	{ 812.0, 5.9409, 909.8187 },
+	{ 562.1, 0.0810, 543.9181 },
+	{ 542.2, 0.2836, 525.7588 },
+	{ 457.9, 0.1272, 1375.7738 },
+	{ 614.8, 2.2762, 942.0621 },
+	{ 435.8, 2.6027, 95.9792 },
+	{ 496.1, 5.5301, 380.1278 },
+	{ 470.0, 2.8190, 1795.2584 },
+	{ 445.0, 0.1462, 14.2271 },
+	{ 290.9, 3.8934, 1471.7530 },
+	{ 276.6, 2.5224, 2001.4440 },
+	{ 275.1, 2.9886, 526.5096 },
+	{ 293.9, 2.0494, 199.0720 },
+	{ 291.0, 6.0313, 1169.5883 },
+	{ 338.3, 2.7987, 1045.1548 },
+	{ 257.5, 6.1340, 532.8724 },
+	{ 319.0, 1.3480, 2214.7431 },
+	{ 309.4, 5.3686, 1272.6810 },
+	{ 345.8, 1.5640, 491.5579 },
+	{ 303.4, 1.1541, 5753.3849 },
+	{ 192.3, 0.9200, 1596.1864 },
+	{ 215.4, 2.6357, 2111.6503 },
+	{ 200.7, 2.3726, 1258.4539 },
+	{ 239.0, 3.5740, 835.0371 },
+	{ 197.1, 5.9286, 453.4249 },
+	{ 139.4, 3.6396, 1788.1449 },
+	{ 191.4, 6.2825, 983.1159 },
+	{ 176.6, 2.5767, 9683.5946 },
+	{ 123.6, 2.2616, 2317.8359 },
+	{ 128.2, 4.6659, 831.8557 },
+	{ 112.4, 0.8560, 433.7117 },
+	{ 128.8, 1.1057, 2531.1350 },
+	{ 99.4, 4.503, 518.645 },
+	{ 93.9, 2.726, 853.196 },
+	{ 106.5, 5.8146, 220.4126 },
+	{ 120.2, 2.9516, 3.9322 },
+	{ 104.0, 2.2222, 74.7816 },
+	{ 81.7, 3.235, 1361.547 },
+	{ 112.5, 4.8622, 528.2065 },
+	{ 79.5, 0.885, 430.530 },
+	{ 85.8, 2.115, 1574.846 },
+	{ 85.7, 2.338, 2428.042 },
+	{ 68.3, 3.357, 2104.537 },
+	{ 69.6, 3.042, 302.165 },
+	{ 69.8, 3.224, 305.346 },
+	{ 69.6, 0.205, 532.139 },
+	{ 57.0, 2.002, 2634.228 },
+	{ 77.1, 2.098, 508.350 },
+	{ 56.7, 3.917, 2221.857 },
+	{ 58.3, 5.724, 628.852 },
+	{ 52.5, 4.025, 527.243 },
+	{ 63.6, 1.100, 1364.728 },
+	{ 53.6, 0.874, 2847.527 },
+	{ 59.6, 0.958, 494.266 },
+	{ 58.0, 3.458, 2008.558 },
+	{ 41.5, 3.520, 529.739 },
+	{ 44.7, 1.623, 984.600 },
+	{ 44.9, 4.901, 2648.455 },
+	{ 53.2, 1.198, 760.256 },
+	{ 44.4, 4.426, 1063.314 },
+	{ 37.6, 2.930, 1677.939 },
+	{ 41.5, 0.322, 529.643 },
+	{ 42.9, 0.031, 1439.510 },
+	{ 46.0, 2.543, 636.716 },
+	{ 40.2, 4.394, 1148.248 },
+	{ 38.8, 4.317, 149.563 },
+	{ 40.3, 2.101, 2744.434 },
+	{ 48.9, 5.603, 2810.921 },
+	{ 37.1, 5.078, 1905.465 },
+	{ 43.9, 1.245, 621.738 },
+	{ 34.0, 3.094, 2420.929 },
+	{ 36.8, 0.842, 530.654 },
+	{ 31.1, 5.358, 1485.980 },
+	{ 39.3, 4.708, 569.048 },
+	{ 39.7, 2.462, 355.749 },
+	{ 31.5, 6.193, 3.181 },
+	{ 28.4, 2.485, 519.396 },
+	{ 32.4, 2.733, 604.473 },
+	{ 27.1, 3.923, 2324.949 },
+	{ 26.8, 1.750, 2950.620 },
+	{ 29.0, 1.835, 1891.238 },
+	{ 26.5, 0.604, 1055.450 },
+	{ 33.5, 0.761, 643.829 },
+	{ 26.6, 1.036, 405.258 },
+	{ 25.5, 3.463, 458.842 },
+	{ 32.9, 3.186, 528.728 },
+	{ 25.7, 0.524, 511.532 },
+	{ 26.0, 1.336, 330.619 },
+	/* 130 terms retained, 615 terms dropped, error 6e-06 a.u. */
+
+	/* jupiter r, T^1 */
+	{ 1271801.6, 2.64937511, 529.69096509 },
+	{ 61661.8, 3.000763, 1059.381930 },
+	{ 53443.6, 3.897176, 522.577418 },
+	{ 31185.2, 4.882767, 536.804512 },
+	{ 41390.3, 0, 0 },
+	{ 11847.2, 2.413296, 419.484644 },
+	{ 9166.4, 4.75979, 7.11355 },
+	{ 3175.8, 2.79298, 103.09277 },
+	{ 3203.4, 5.21083, 735.87651 },
+	{ 3403.6, 3.34689, 1589.07290 },
+	{ 2600.0, 3.63435, 206.18555 },
+	{ 2412.2, 1.46947, 426.59819 },
+	{ 2806.1, 3.74224, 515.46387 },
+	{ 2676.6, 4.33053, 1052.26838 },
+	{ 2100.5, 3.92763, 639.89729 },
+	{ 1646.2, 5.30954, 1066.49548 },
+	{ 1641.3, 4.41629, 625.67019 },
+	{ 1049.9, 3.16114, 213.29910 },
+	{ 1024.8, 2.55433, 412.37110 },
+	{ 741.0, 2.1709, 1162.4747 },
+	{ 806.4, 2.6775, 632.7837 },
+	{ 676.9, 6.2495, 838.9693 },
+	{ 468.9, 4.7097, 543.9181 },
+	{ 444.7, 0.4028, 323.5054 },
+	{ 567.1, 4.5766, 742.9901 },
+	{ 415.9, 5.3684, 728.7630 },
+	{ 484.7, 2.4688, 949.1756 },
+	{ 337.6, 3.1678, 956.2892 },
+	{ 401.7, 4.6053, 309.2783 },
+	{ 347.4, 4.6815, 14.2271 },
+	{ 260.8, 5.3429, 846.0828 },
+	{ 220.1, 4.8421, 1368.6603 },
+	{ 203.2, 5.6000, 1155.3612 },
+	{ 246.6, 3.9231, 942.0621 },
+	{ 183.5, 4.2653, 95.9792 },
+	{ 180.1, 4.4017, 532.8724 },
+	{ 197.1, 3.7055, 2118.7639 },
+	{ 196.0, 3.7588, 199.0720 },
+	{ 200.2, 4.4389, 1045.1548 },
+	{ 170.2, 4.8465, 526.5096 },
+	{ 146.3, 6.1296, 533.6231 },
+	{ 133.5, 1.3225, 110.2063 },
+	{ 132.1, 4.5119, 525.7588 },
+	{ 123.9, 2.0429, 1478.8666 },
+	{ 121.9, 4.4058, 1169.5883 },
+	{ 115.3, 4.4674, 1581.9593 },
+	{ 98.5, 5.728, 1596.186 },
+	{ 91.6, 4.530, 1685.052 },
+	{ 110.6, 3.6250, 1272.6810 },
+	{ 80.5, 4.113, 1258.454 },
+	{ 79.6, 2.719, 1692.166 },
+	{ 100.2, 5.2469, 1265.5675 },
+	{ 77.9, 5.567, 1471.753 },
+	{ 85.8, 0.079, 831.856 },
+	{ 82.1, 3.808, 508.350 },
+	{ 55.3, 0.352, 316.392 },
+	{ 52.3, 5.531, 433.712 },
+	{ 55.8, 4.751, 302.165 },
+	{ 50.6, 4.856, 1375.774 },
+	{ 43.6, 4.944, 1361.547 },
+	{ 42.2, 1.224, 853.196 },
+	{ 37.7, 4.268, 2001.444 },
+	{ 49.4, 4.014, 220.413 },
+	{ 38.3, 5.330, 1788.145 },
+	{ 35.6, 1.762, 1795.258 },
+	{ 36.3, 3.850, 1574.846 },
+	{ 29.3, 5.166, 3.932 },
+	{ 25.2, 4.338, 519.396 },
+	{ 24.8, 2.729, 405.258 },
+	{ 27.0, 6.097, 1148.248 },
+	{ 22.6, 0.192, 380.128 },
+	{ 20.5, 4.329, 3.181 },
+	{ 19.9, 4.630, 1677.939 },
+	{ 19.5, 5.106, 1073.609 },
+	{ 18.4, 3.765, 1485.980 },
+	{ 18.9, 5.053, 2104.537 },
+	{ 17.0, 4.018, 2317.836 },
+	{ 16.7, 5.429, 88.866 },
+	{ 15.3, 2.927, 2008.558 },
+	{ 14.5, 3.633, 628.852 },
+	{ 14.6, 5.508, 721.649 },
+	{ 13.7, 4.876, 629.602 },
+	{ 18.5, 6.030, 330.619 },
+	{ 13.5, 1.385, 518.645 },
+	{ 15.7, 2.930, 1905.465 },
+	{ 12.5, 1.586, 2111.650 },
+	{ 12.3, 3.377, 635.965 },
+	{ 11.8, 4.085, 2648.455 },
+	{ 11.2, 4.626, 636.716 },
+	{ 14.3, 2.742, 2221.857 },
+	{ 11.2, 3.553, 1891.238 },
+	{ 13.1, 5.838, 1464.639 },
+	{ 11.4, 2.576, 511.532 },
+	{ 10.5, 0.499, 453.425 },
+	{ 9.7, 4.39, 1994.33 },
+	{ 10.1, 2.764, 423.417 },
+	{ 8.6, 5.16, 1056.20 },
+	{ 9.0, 4.79, 2420.93 },
+	{ 8.1, 3.73, 2634.23 },
+	{ 8.1, 1.29, 2428.04 },
+	{ 8.9, 1.86, 750.10 },
+	{ 8.9, 4.81, 1062.56 },
+	{ 8.6, 4.54, 21.34 },
+	{ 9.5, 4.33, 1802.37 },
+	{ 6.9, 5.97, 540.74 },
+	{ 7.3, 4.98, 1699.28 },
+	{ 7.1, 4.99, 1055.45 },
+	{ 7.2, 4.98, 1898.35 },
+	{ 6.5, 1.39, 422.67 },
+	{ 6.8, 2.91, 2324.95 },
+	{ 6.5, 4.57, 1038.04 },
+	{ 7.3, 3.02, 416.30 },
+	{ 6.6, 5.55, 1781.03 },
+	/* 113 terms retained, 268 terms dropped, error 1.4e-06 a.u.*T */
+
+	/* jupiter r, T^2 */
+	{ 79644.8, 1.358659, 529.690965 },
+	{ 8251.6, 5.77774, 522.57742 },
+	{ 7029.9, 3.27477, 536.80451 },
+	{ 5314.0, 1.83835, 1059.38193 },
+	{ 1860.8, 2.97682, 7.11355 },
+	{ 836.3, 4.1989, 419.4846 },
+	{ 964.5, 5.4803, 515.4639 },
+	{ 406.5, 3.7825, 1066.4955 },
+	{ 426.6, 2.2275, 639.8973 },
+	{ 377.3, 2.2425, 1589.0729 },
+	{ 497.9, 3.1416, 0 },
+	{ 339.0, 6.1269, 625.6702 },
+	{ 362.9, 5.3676, 206.1855 },
+	{ 342.0, 6.0992, 1052.2684 },
+	{ 279.9, 4.2616, 412.3711 },
+	{ 332.6, 0.0033, 426.5982 },
+	{ 229.8, 0.7053, 735.8765 },
+	{ 200.8, 3.0685, 543.9181 },
+	{ 199.8, 4.4288, 103.0928 },
+	{ 257.3, 0.9630, 632.7837 },
+	{ 138.6, 2.9324, 14.2271 },
+	{ 113.5, 0.7871, 728.7630 },
+	{ 86.0, 5.144, 323.505 },
+	{ 94.6, 1.705, 838.969 },
+	{ 83.5, 0.058, 309.278 },
+	{ 75.2, 1.605, 956.289 },
+	{ 70.5, 1.510, 213.299 },
+	{ 80.3, 2.981, 742.990 },
+	{ 56.2, 0.955, 1162.475 },
+	{ 61.6, 6.101, 1045.155 },
+	{ 66.6, 5.473, 199.072 },
+	{ 50.1, 2.721, 532.872 },
+	{ 51.9, 5.584, 942.062 },
+	{ 39.8, 5.946, 95.979 },
+	{ 44.5, 5.524, 508.350 },
+	{ 44.3, 0.271, 526.510 },
+	{ 29.9, 0.936, 1155.361 },
+	{ 28.4, 2.878, 525.759 },
+	{ 26.3, 4.269, 1596.186 },
+	{ 27.0, 2.806, 1169.588 },
+	{ 27.5, 2.648, 2118.764 },
+	{ 22.7, 0.178, 302.165 },
+	{ 29.3, 1.786, 831.856 },
+	{ 20.0, 0.043, 949.176 },
+	{ 19.9, 1.161, 533.623 },
+	{ 21.7, 1.888, 1272.681 },
+	{ 17.6, 4.150, 846.083 },
+	{ 17.1, 5.892, 1258.454 },
+	{ 21.4, 4.355, 316.392 },
+	{ 21.3, 0.544, 1265.567 },
+	{ 19.9, 0.065, 1581.959 },
+	{ 17.0, 0.534, 1368.660 },
+	{ 12.8, 3.900, 433.712 },
+	{ 13.1, 0.795, 110.206 },
+	{ 11.9, 0.407, 1361.547 },
+	{ 11.7, 4.444, 405.258 },
+	{ 12.0, 2.229, 220.413 },
+	{ 9.6, 6.01, 853.20 },
+	{ 10.2, 0.995, 1471.753 },
+	{ 9.0, 1.60, 1692.17 },
+	{ 8.7, 3.52, 1073.61 },
+	{ 8.3, 5.60, 1574.85 },
+	{ 9.0, 6.27, 519.40 },
+	{ 7.8, 0.65, 1478.87 },
+	{ 7.8, 0.18, 1685.05 },
+	{ 7.5, 0.88, 88.87 },
+	{ 7.3, 0.89, 721.65 },
+	{ 9.1, 1.51, 1148.25 },
+	{ 6.1, 2.50, 3.18 },
+	{ 7.0, 4.44, 330.62 },
+	{ 5.2, 2.79, 21.34 },
+	{ 5.1, 2.98, 1375.77 },
+	{ 4.9, 0.05, 1677.94 },
+	{ 4.7, 2.28, 1485.98 },
+	{ 4.7, 0.86, 3.93 },
+	{ 5.3, 0.85, 1788.14 },
+	{ 4.2, 0.41, 629.60 },
+	{ 4.2, 1.61, 635.97 },
+	{ 3.6, 2.71, 551.03 },
+	{ 3.3, 0.55, 1795.26 },
+	{ 4.4, 1.28, 1464.64 },
+	{ 3.3, 1.19, 1905.46 },
+	{ 3.2, 6.19, 1038.04 },
+	{ 3.1, 6.23, 2001.44 },
+	{ 3.4, 2.45, 539.99 },
+	{ 3.2, 5.55, 191.96 },
+	{ 2.6, 3.24, 1062.56 },
+	{ 2.6, 0.55, 2104.54 },
+	{ 2.2, 5.33, 1891.24 },
+	{ 2.7, 4.82, 416.30 },
+	{ 2.2, 1.72, 628.85 },
+	{ 2.3, 6.19, 1994.33 },
+	{ 2.3, 4.28, 963.40 },
+	{ 2.6, 0.03, 1898.35 },
+	{ 2.1, 3.33, 1699.28 },
+	{ 2.5, 2.40, 227.53 },
+	{ 2.5, 0.07, 750.10 },
+	{ 2.0, 0.29, 636.72 },
+	{ 1.9, 0.32, 295.05 },
+	{ 1.9, 3.44, 647.01 },
+	{ 1.9, 0.29, 2111.65 },
+	{ 1.9, 3.14, 611.44 },
+	{ 2.3, 1.95, 824.74 },
+	{ 1.9, 4.72, 2125.88 },
+	{ 2.5, 1.24, 2221.86 },
+	{ 1.8, 1.60, 2008.56 },
+	{ 1.6, 5.83, 422.67 },
+	{ 1.7, 2.32, 440.83 },
+	{ 1.6, 0.37, 1056.20 },
+	{ 1.6, 2.42, 10.29 },
+	{ 1.6, 3.52, 1055.45 },
+	{ 1.6, 5.76, 117.32 },
+	{ 1.6, 5.89, 2317.84 },
+	{ 2.0, 4.62, 423.42 },
+	{ 2.1, 1.05, 1781.03 },
+	{ 1.9, 1.12, 618.56 },
+	{ 1.9, 2.79, 1802.37 },
+	{ 1.8, 3.01, 2648.45 },
+	/* 118 terms retained, 72 terms dropped, error 3.9e-07 a.u.*T^2 */
+
+	/* jupiter r, T^3 */
+	{ 3519.3, 6.05801, 529.69097 },
+	{ 1073.2, 1.67321, 536.80451 },
+	{ 915.7, 1.4133, 522.5774 },
+	{ 341.6, 0.5230, 1059.3819 },
+	{ 254.9, 1.1963, 7.1135 },
+	{ 221.5, 0.9523, 515.4639 },
+	{ 69.1, 2.269, 1066.495 },
+	{ 89.7, 3.142, 0 },
+	{ 57.8, 1.414, 543.918 },
+	{ 57.7, 0.526, 639.897 },
+	{ 51.1, 5.980, 412.371 },
+	{ 46.9, 1.579, 625.670 },
+	{ 42.8, 6.117, 419.485 },
+	{ 37.5, 1.183, 14.227 },
+	{ 33.8, 1.667, 1052.268 },
+	{ 31.2, 1.043, 1589.073 },
+	{ 30.0, 4.632, 426.598 },
+	{ 33.5, 0.848, 206.186 },
+	{ 20.8, 2.501, 728.763 },
+	{ 14.5, 0.960, 508.350 },
+	{ 13.0, 1.502, 1045.155 },
+	{ 11.7, 3.555, 323.505 },
+	{ 12.3, 2.610, 735.877 },
+	{ 15.0, 0.891, 199.072 },
+	{ 11.2, 1.790, 309.278 },
+	{ 10.6, 6.278, 956.289 },
+	{ 9.8, 6.26, 103.09 },
+	{ 9.3, 3.45, 838.97 },
+	{ 6.7, 1.87, 302.16 },
+	{ 7.4, 1.28, 742.99 },
+	{ 7.2, 0.92, 942.06 },
+	{ 5.6, 1.38, 95.98 },
+	{ 6.8, 3.45, 831.86 },
+	{ 4.6, 2.83, 1596.19 },
+	{ 4.0, 1.21, 1169.59 },
+	{ 3.9, 5.99, 213.30 },
+	{ 3.6, 6.11, 405.26 },
+	{ 2.9, 2.33, 1155.36 },
+	{ 2.4, 1.87, 532.87 },
+	{ 2.4, 0.43, 220.41 },
+	{ 2.3, 1.95, 1073.61 },
+	{ 2.3, 0.09, 632.78 },
+	{ 2.2, 1.59, 2118.76 },
+	{ 2.4, 5.97, 1162.47 },
+	{ 2.1, 1.07, 21.34 },
+	{ 2.1, 1.51, 1258.45 },
+	{ 2.5, 0.35, 1272.68 },
+	{ 2.0, 5.94, 110.21 },
+	{ 2.0, 2.55, 88.87 },
+	{ 2.0, 2.16, 433.71 },
+	{ 2.0, 2.70, 721.65 },
+	{ 1.7, 4.46, 853.20 },
+	{ 1.9, 2.26, 1361.55 },
+	{ 1.7, 1.98, 525.76 },
+	{ 1.5, 0.12, 949.18 },
+	{ 2.0, 3.17, 1148.25 },
+	{ 1.7, 2.71, 330.62 },
+	{ 1.6, 0.47, 526.51 },
+	{ 1.2, 3.02, 963.40 },
+	{ 1.7, 0.44, 533.62 },
+	{ 1.2, 1.16, 1574.85 },
+	{ 1.1, 2.55, 846.08 },
+	{ 1.4, 1.17, 1038.04 },
+	{ 1.0, 2.70, 519.40 },
+	{ 1.4, 0.67, 551.03 },
+	{ 1.0, 4.17, 2627.11 },
+	{ 1.1, 1.07, 227.53 },
+	{ 0.9, 2.93, 1368.66 },
+	{ 0.8, 4.87, 611.44 },
+	{ 1.1, 1.79, 1581.96 },
+	{ 0.9, 4.91, 1670.83 },
+	{ 0.9, 3.69, 824.74 },
+	{ 0.8, 3.23, 2125.88 },
+	{ 0.8, 2.39, 2317.84 },
+	{ 0.9, 0.60, 539.99 },
+	{ 0.9, 4.52, 750.10 },
+	{ 0.8, 0.21, 1141.13 },
+	{ 0.8, 0.94, 191.96 },
+	{ 0.8, 2.25, 2538.25 },
+	{ 0.7, 0.67, 440.83 },
+	{ 0.7, 5.80, 1485.98 },
+	{ 0.6, 2.48, 1265.57 },
+	{ 0.6, 6.14, 1279.79 },
+	{ 0.6, 5.51, 2413.82 },
+	{ 0.6, 4.41, 1382.89 },
+	{ 0.6, 2.18, 1062.56 },
+	{ 0.6, 1.93, 2634.23 },
+	{ 0.5, 2.05, 295.05 },
+	{ 0.5, 2.32, 1471.75 },
+	{ 0.7, 2.27, 1699.28 },
+	{ 0.5, 1.96, 1677.94 },
+	{ 0.5, 4.36, 1692.17 },
+	{ 0.5, 2.50, 2207.63 },
+	{ 0.5, 5.77, 1478.87 },
+	{ 0.4, 5.99, 934.95 },
+	{ 0.4, 2.80, 81.75 },
+	{ 0.4, 3.94, 316.39 },
+	{ 0.5, 0.19, 10.29 },
+	/* 98 terms retained, 0 terms dropped, error 1e-07 a.u.*T^3 */
+
+	/* jupiter r, T^4 */
+	{ 128.6, 0.0842, 536.8045 },
+	{ 113.5, 4.2486, 529.6910 },
+	{ 82.7, 3.298, 522.577 },
+	{ 37.9, 2.733, 515.464 },
+	{ 26.7, 5.691, 7.114 },
+	{ 17.6, 5.400, 1059.382 },
+	{ 12.6, 6.016, 543.918 },
+	{ 9.3, 0.77, 1066.50 },
+	{ 8.1, 5.68, 14.23 },
+	{ 6.3, 5.12, 639.90 },
+	{ 7.0, 1.43, 412.37 },
+	{ 5.4, 3.34, 625.67 },
+	{ 2.9, 3.40, 1052.27 },
+	{ 2.6, 4.16, 728.76 },
+	{ 2.6, 2.90, 426.60 },
+	{ 2.3, 6.22, 1589.07 },
+	{ 2.1, 3.12, 1045.15 },
+	{ 1.7, 2.81, 206.19 },
+	{ 1.8, 2.60, 199.07 },
+	{ 1.8, 1.89, 419.48 },
+	{ 1.5, 1.33, 1596.19 },
+	{ 1.7, 0, 0 },
+	{ 1.0, 4.42, 956.29 },
+	{ 1.2, 5.16, 831.86 },
+	{ 0.9, 3.17, 508.35 },
+	{ 0.9, 5.79, 1169.59 },
+	{ 0.9, 1.87, 1148.25 },
+	{ 1.0, 0.67, 1361.55 },
+	{ 0.8, 1.48, 1272.68 },
+	{ 1.0, 5.47, 220.41 },
+	{ 0.8, 2.42, 117.32 },
+	{ 0.7, 0.50, 1073.61 },
+	{ 0.7, 3.53, 302.16 },
+	{ 0.7, 2.85, 191.96 },
+	{ 0.8, 2.20, 942.06 },
+	{ 0.8, 5.31, 551.03 },
+	{ 0.7, 3.72, 88.87 },
+	{ 0.5, 1.83, 647.01 },
+	{ 0.6, 0.86, 330.62 },
+	{ 0.5, 5.26, 21.34 },
+	{ 0.6, 3.82, 618.56 },
+	{ 0.5, 4.44, 110.21 },
+	{ 0.6, 1.59, 3.18 },
+	{ 0.6, 1.84, 10.29 },
+	{ 0.5, 1.53, 405.26 },
+	{ 0.5, 0.24, 433.71 },
+	/* 46 terms retained, 0 terms dropped, error 7.1e-08 a.u.*T^4 */
+
+	/* jupiter r, T^5 */
+	{ 11.2, 4.752, 536.805 },
+	{ 4.3, 5.92, 522.58 },
+	{ 2.1, 5.57, 515.46 },
+	{ 1.9, 4.30, 543.92 },
+	{ 1.9, 3.69, 7.11 },
+	{ 1.6, 5.49, 1066.50 },
+	{ 1.6, 4.13, 1059.38 },
+	{ 1.2, 3.78, 14.23 },
+	{ 1.0, 4.51, 529.69 },
+	/* 9 terms retained, 0 terms dropped, error 6.5e-08 a.u.*T^5 */
+	/* end jupiter */
+};
+
+int vn_jupiter[][3] = {
+	/* addresses for jupiter l, b, r  */
+	/* T^0 */ { 0, 392, 542, },
+	/* T^1 */ { 109, 428, 672, },
+	/* T^2 */ { 194, 468, 785, },
+	/* T^3 */ { 271, 504, 903, },
+	/* T^4 */ { 341, 526, 1001, },
+	/* T^5 */ { 383, 538, 1047, },
+	/* end */ { 392, 542, 1056, },
+	/* termination */ { 0, }
+};
+
+/*  version d4 (lbr)       
+ *  heliocentric dynamical ecliptic and equinox of the date
+ */
+
+double vx_mars[][3] = {
+	/* mars l, T^0 */
+	{ 620347711.6, 0, 0 },
+	{ 18656368.1, 5.050371003, 3340.612426700 },
+	{ 1108216.8, 5.40099837, 6681.22485340 },
+	{ 91798.4, 5.754787, 10021.837280 },
+	{ 27745.0, 5.970495, 3.523118 },
+	{ 10610.2, 2.939585, 2281.230497 },
+	{ 12315.9, 0.849561, 2810.921462 },
+	{ 8926.8, 4.15698, 0.01725 },
+	{ 8715.7, 6.11005, 13362.44971 },
+	{ 6797.6, 0.36462, 398.14900 },
+	{ 7774.9, 3.33969, 5621.84292 },
+	{ 3575.1, 1.66187, 2544.31442 },
+	{ 4161.1, 0.22815, 2942.46342 },
+	{ 3075.2, 0.85697, 191.44827 },
+	{ 2628.1, 0.64806, 3337.08931 },
+	{ 2937.5, 6.07894, 0.06731 },
+	{ 2389.4, 5.03896, 796.29801 },
+	{ 2579.8, 0.02997, 3344.13555 },
+	{ 1528.1, 1.14979, 6151.53389 },
+	{ 1798.8, 0.65634, 529.69097 },
+	{ 1264.4, 3.62275, 5092.15196 },
+	{ 1286.2, 3.06796, 2146.16542 },
+	{ 1546.4, 2.91580, 1751.53953 },
+	{ 1024.9, 3.69334, 8962.45535 },
+	{ 891.6, 0.1829, 16703.0621 },
+	{ 858.8, 2.4009, 2914.0142 },
+	{ 832.7, 2.4642, 3340.5952 },
+	{ 832.7, 4.4950, 3340.6297 },
+	{ 712.9, 3.6634, 1059.3819 },
+	{ 748.7, 3.8225, 155.4204 },
+	{ 723.9, 0.6750, 3738.7614 },
+	{ 635.6, 2.9218, 8432.7644 },
+	{ 655.2, 0.4886, 3127.3133 },
+	{ 550.5, 3.8100, 0.9803 },
+	{ 552.7, 4.4748, 1748.0164 },
+	{ 426.0, 0.5537, 6283.0758 },
+	{ 415.1, 0.4966, 213.2991 },
+	{ 472.2, 3.6255, 1194.4470 },
+	{ 306.6, 0.3805, 6684.7480 },
+	{ 312.1, 0.9985, 6677.7017 },
+	{ 293.2, 4.2213, 20.7754 },
+	{ 302.4, 4.4862, 3532.0607 },
+	{ 274.0, 0.5422, 3340.5451 },
+	{ 281.1, 5.8816, 1349.8674 },
+	{ 231.2, 1.2824, 3870.3034 },
+	{ 283.6, 5.7689, 3149.1642 },
+	{ 236.1, 5.7550, 3333.4989 },
+	{ 274.0, 0.1337, 3340.6797 },
+	{ 299.4, 2.7832, 6254.6267 },
+	{ 204.2, 2.8213, 1221.8486 },
+	{ 238.9, 5.3716, 4136.9104 },
+	{ 188.6, 1.4910, 9492.1463 },
+	{ 221.2, 3.5047, 382.8965 },
+	{ 179.2, 1.0056, 951.7184 },
+	{ 172.1, 0.4394, 5486.7778 },
+	{ 193.1, 3.3572, 3.5904 },
+	{ 144.3, 1.4187, 135.0651 },
+	{ 160.0, 3.9485, 4562.4610 },
+	{ 174.1, 2.4136, 553.5694 },
+	{ 131.0, 4.0449, 12303.0678 },
+	{ 138.2, 4.3015, 7.1135 },
+	{ 128.1, 1.8067, 5088.6288 },
+	{ 139.9, 3.3259, 2700.7151 },
+	{ 128.1, 2.2081, 1592.5960 },
+	{ 116.9, 3.1281, 7903.0734 },
+	{ 110.4, 1.0520, 242.7286 },
+	{ 113.5, 3.7007, 1589.0729 },
+	{ 100.1, 3.2434, 11773.3768 },
+	{ 95.6, 0.540, 20043.675 },
+	{ 98.9, 4.846, 6681.242 },
+	{ 104.5, 0.7854, 8827.3903 },
+	{ 84.2, 3.990, 4399.994 },
+	{ 86.9, 2.202, 11243.686 },
+	{ 71.4, 2.803, 3185.192 },
+	{ 72.1, 5.847, 5884.927 },
+	{ 73.5, 2.184, 8429.241 },
+	{ 98.9, 2.815, 6681.208 },
+	{ 68.4, 2.738, 2288.344 },
+	{ 86.8, 1.021, 7079.374 },
+	{ 65.3, 2.681, 28.449 },
+	{ 83.7, 3.203, 4690.480 },
+	{ 75.0, 0.766, 6467.926 },
+	{ 69.0, 3.764, 6041.328 },
+	{ 66.7, 0.736, 3723.509 },
+	{ 63.3, 4.528, 426.598 },
+	{ 61.7, 6.168, 2274.117 },
+	{ 52.3, 0.899, 9623.688 },
+	{ 55.5, 4.606, 4292.331 },
+	{ 51.3, 4.148, 3341.593 },
+	{ 56.6, 5.063, 15.252 },
+	{ 63.4, 0.913, 3553.912 },
+	{ 45.8, 0.788, 1990.745 },
+	{ 48.5, 3.957, 4535.059 },
+	{ 41.2, 6.020, 3894.182 },
+	{ 41.9, 3.583, 8031.092 },
+	{ 56.4, 1.687, 6872.673 },
+	{ 55.9, 3.463, 263.084 },
+	{ 51.7, 2.813, 3339.632 },
+	{ 40.7, 3.138, 9595.239 },
+	{ 38.1, 0.734, 10025.360 },
+	{ 39.5, 5.632, 3097.884 },
+	{ 44.2, 3.195, 5628.956 },
+	{ 36.7, 2.637, 692.158 },
+	{ 45.9, 0.287, 5614.729 },
+	{ 38.4, 5.829, 3191.049 },
+	{ 38.2, 2.348, 162.467 },
+	{ 32.6, 0.484, 6681.292 },
+	{ 37.1, 0.685, 2818.035 },
+	{ 31.2, 3.982, 20.355 },
+	{ 32.6, 0.893, 6681.158 },
+	{ 37.8, 4.155, 2803.808 },
+	{ 33.6, 6.120, 6489.777 },
+	{ 29.0, 2.427, 3319.837 },
+	{ 38.8, 1.352, 10018.314 },
+	{ 33.1, 1.140, 5.523 },
+	{ 27.6, 1.597, 7210.916 },
+	{ 28.7, 5.721, 7477.523 },
+	{ 34.0, 2.595, 11769.854 },
+	{ 25.4, 0.521, 10.637 },
+	{ 26.4, 1.345, 3496.033 },
+	{ 25.6, 0.250, 522.577 },
+	{ 27.3, 4.556, 3361.388 },
+	{ 27.5, 6.084, 6674.111 },
+	{ 25.5, 3.432, 3443.705 },
+	/* 124 terms retained, 1093 terms dropped, error 1.2" */
+
+	/* mars l, T^1 */
+	{ 334085627474.3, 0, 0 },
+	{ 1458227.1, 3.60426054, 3340.61242670 },
+	{ 164901.3, 3.9263125, 6681.2248534 },
+	{ 19963.3, 4.265941, 10021.837280 },
+	{ 3452.4, 4.73210, 3.52312 },
+	{ 2485.5, 4.61278, 13362.44971 },
+	{ 841.6, 4.4586, 2281.2305 },
+	{ 537.6, 5.0159, 398.1490 },
+	{ 521.0, 4.9942, 3344.1355 },
+	{ 432.6, 2.5607, 191.4483 },
+	{ 429.7, 5.3165, 155.4204 },
+	{ 381.7, 3.5388, 796.2980 },
+	{ 314.1, 4.9634, 16703.0621 },
+	{ 282.8, 3.1597, 2544.3144 },
+	{ 205.7, 4.5689, 2146.1654 },
+	{ 168.8, 1.3289, 3337.0893 },
+	{ 157.6, 4.1850, 1751.5395 },
+	{ 133.7, 2.2333, 0.9803 },
+	{ 116.6, 2.2135, 1059.3819 },
+	{ 117.6, 6.0241, 6151.5339 },
+	{ 113.6, 5.4280, 3738.7614 },
+	{ 133.6, 5.9742, 1748.0164 },
+	{ 91.1, 1.096, 1349.867 },
+	{ 83.3, 5.296, 6684.748 },
+	{ 113.9, 2.1287, 1194.4470 },
+	{ 80.8, 4.428, 529.691 },
+	{ 79.5, 2.249, 8962.455 },
+	{ 72.5, 5.842, 242.729 },
+	{ 72.9, 2.502, 951.718 },
+	{ 71.5, 3.856, 2914.014 },
+	{ 85.3, 3.909, 553.569 },
+	{ 67.6, 5.023, 382.897 },
+	{ 65.1, 1.018, 3340.595 },
+	{ 65.1, 3.049, 3340.630 },
+	{ 61.5, 4.152, 3149.164 },
+	{ 48.5, 4.874, 213.299 },
+	{ 46.6, 1.315, 3185.192 },
+	{ 56.5, 3.888, 4136.910 },
+	{ 47.6, 1.182, 3333.499 },
+	{ 41.3, 0.714, 1592.596 },
+	{ 40.1, 5.316, 20043.675 },
+	{ 40.3, 2.725, 7.114 },
+	{ 32.9, 5.411, 6283.076 },
+	{ 28.2, 0.045, 9492.146 },
+	{ 22.3, 5.885, 3870.303 },
+	{ 22.4, 5.466, 20.355 },
+	{ 22.6, 0.838, 3097.884 },
+	{ 21.4, 5.379, 3340.545 },
+	{ 23.3, 6.168, 3532.061 },
+	{ 26.6, 3.890, 1221.849 },
+	{ 22.8, 1.545, 2274.117 },
+	{ 20.4, 2.364, 1589.073 },
+	{ 20.2, 3.364, 5088.629 },
+	{ 26.6, 5.113, 2700.715 },
+	{ 19.7, 2.578, 12303.068 },
+	{ 19.5, 0.492, 6677.702 },
+	{ 21.1, 3.525, 15.252 },
+	{ 21.4, 4.971, 3340.680 },
+	{ 18.5, 5.579, 1990.745 },
+	{ 17.8, 6.125, 4292.331 },
+	{ 16.5, 2.603, 3341.593 },
+	{ 16.6, 1.255, 3894.182 },
+	{ 19.5, 2.531, 4399.994 },
+	{ 15.0, 1.035, 2288.344 },
+	{ 20.0, 4.731, 4690.480 },
+	{ 15.4, 2.470, 4535.059 },
+	{ 20.0, 5.787, 7079.374 },
+	{ 15.3, 2.265, 3723.509 },
+	{ 14.7, 3.370, 6681.242 },
+	{ 13.5, 2.123, 5486.778 },
+	{ 12.9, 5.619, 10025.360 },
+	{ 12.7, 2.950, 3496.033 },
+	{ 13.6, 1.977, 5614.729 },
+	{ 13.0, 1.514, 5628.956 },
+	{ 14.7, 1.339, 6681.208 },
+	{ 11.4, 6.234, 135.065 },
+	{ 13.3, 3.422, 5621.843 },
+	{ 10.9, 5.282, 2818.035 },
+	{ 11.8, 3.127, 426.598 },
+	{ 10.5, 2.736, 2787.043 },
+	{ 11.1, 5.842, 2803.808 },
+	{ 11.8, 2.586, 8432.764 },
+	{ 11.9, 5.476, 3553.912 },
+	{ 8.5, 1.91, 11773.38 },
+	{ 9.7, 4.53, 6489.78 },
+	{ 8.6, 3.16, 162.47 },
+	{ 11.0, 4.158, 2388.894 },
+	{ 8.1, 1.61, 2957.72 },
+	{ 8.8, 4.23, 7477.52 },
+	{ 8.0, 5.70, 6041.33 },
+	{ 8.3, 2.18, 23.88 },
+	{ 7.7, 5.72, 9623.69 },
+	{ 8.7, 4.44, 5092.15 },
+	{ 8.4, 3.16, 3347.73 },
+	{ 6.7, 5.08, 8031.09 },
+	{ 8.7, 4.33, 3339.63 },
+	{ 7.4, 6.18, 3583.34 },
+	{ 6.4, 2.12, 5884.93 },
+	/* 98 terms retained, 588 terms dropped, error 0.26"*T */
+
+	/* mars l, T^2 */
+	{ 58015.8, 2.049795, 3340.612427 },
+	{ 54187.6, 0, 0 },
+	{ 13908.4, 2.457424, 6681.224853 },
+	{ 2465.1, 2.80000, 10021.83728 },
+	{ 398.4, 3.1412, 13362.4497 },
+	{ 222.0, 3.1944, 3.5231 },
+	{ 121.0, 0.5433, 155.4204 },
+	{ 61.5, 3.485, 16703.062 },
+	{ 53.6, 3.542, 3344.136 },
+	{ 34.3, 6.002, 2281.230 },
+	{ 31.7, 4.140, 191.448 },
+	{ 29.8, 1.999, 796.298 },
+	{ 23.2, 4.334, 242.729 },
+	{ 21.7, 3.445, 398.149 },
+	{ 16.0, 6.110, 2146.165 },
+	{ 20.4, 5.422, 553.569 },
+	{ 14.9, 6.095, 3185.192 },
+	{ 16.2, 0.657, 0.980 },
+	{ 14.3, 2.619, 1349.867 },
+	{ 14.4, 4.019, 951.718 },
+	{ 11.9, 3.861, 6684.748 },
+	{ 15.6, 1.221, 1748.016 },
+	{ 11.3, 4.718, 2544.314 },
+	{ 13.4, 0.602, 1194.447 },
+	{ 10.4, 0.250, 382.897 },
+	{ 9.5, 0.68, 1059.38 },
+	{ 9.2, 3.83, 20043.67 },
+	{ 9.0, 3.88, 3738.76 },
+	{ 7.5, 5.46, 1751.54 },
+	{ 6.5, 5.48, 1592.60 },
+	{ 6.3, 2.34, 3097.88 },
+	{ 6.9, 2.58, 3149.16 },
+	{ 5.9, 1.15, 7.11 },
+	{ 6.7, 2.38, 4136.91 },
+	{ 4.6, 4.43, 6151.53 },
+	{ 4.2, 3.69, 5614.73 },
+	{ 4.8, 2.90, 3333.50 },
+	{ 4.0, 6.12, 5628.96 },
+	{ 3.7, 4.07, 1990.75 },
+	{ 3.6, 2.47, 529.69 },
+	{ 3.3, 0.68, 8962.46 },
+	{ 3.3, 2.80, 3894.18 },
+	{ 3.1, 4.57, 3496.03 },
+	{ 2.9, 5.41, 2914.01 },
+	{ 2.9, 1.23, 2787.04 },
+	{ 2.8, 1.39, 4292.33 },
+	{ 2.6, 1.04, 3341.59 },
+	{ 2.9, 3.41, 3337.09 },
+	{ 2.4, 0.96, 4535.06 },
+	{ 2.4, 4.85, 9492.15 },
+	{ 2.6, 5.75, 3340.60 },
+	{ 2.2, 3.26, 213.30 },
+	{ 2.6, 1.50, 3340.63 },
+	{ 2.3, 4.18, 10025.36 },
+	{ 2.6, 4.68, 3583.34 },
+	{ 2.6, 2.65, 2388.89 },
+	{ 1.8, 0.97, 1589.07 },
+	{ 2.4, 1.05, 4399.99 },
+	{ 2.4, 4.27, 7079.37 },
+	{ 2.2, 0.16, 6525.80 },
+	{ 2.3, 0.01, 4690.48 },
+	{ 1.6, 4.96, 5088.63 },
+	{ 1.6, 1.11, 12303.07 },
+	{ 2.1, 0.48, 2700.72 },
+	{ 1.6, 4.94, 1221.85 },
+	{ 1.8, 3.81, 3723.51 },
+	{ 1.8, 2.52, 2810.92 },
+	/* 67 terms retained, 243 terms dropped, error 0.06"*T^2 */
+
+	/* mars l, T^3 */
+	{ 1482.4, 0.44435, 3340.61243 },
+	{ 662.1, 0.8847, 6681.2249 },
+	{ 188.3, 1.2880, 10021.8373 },
+	{ 41.5, 1.649, 13362.450 },
+	{ 22.7, 2.053, 155.420 },
+	{ 26.0, 0, 0 },
+	{ 8.0, 2.00, 16703.06 },
+	{ 10.5, 1.580, 3.523 },
+	{ 4.9, 2.82, 242.73 },
+	{ 3.8, 2.02, 3344.14 },
+	{ 3.2, 4.59, 3185.19 },
+	{ 3.1, 0.65, 553.57 },
+	{ 1.7, 5.54, 951.72 },
+	{ 1.5, 5.72, 191.45 },
+	{ 1.4, 0.46, 796.30 },
+	{ 1.4, 2.34, 20043.67 },
+	{ 1.3, 5.36, 0.98 },
+	{ 1.2, 4.15, 1349.87 },
+	{ 1.1, 2.38, 6684.75 },
+	{ 1.0, 1.77, 382.90 },
+	{ 0.9, 5.34, 1194.45 },
+	{ 0.8, 2.75, 1748.02 },
+	{ 0.6, 6.11, 3496.03 },
+	{ 0.6, 1.85, 398.15 },
+	{ 0.6, 5.86, 7.11 },
+	{ 0.6, 3.18, 3583.34 },
+	{ 0.5, 5.98, 2787.04 },
+	{ 0.5, 1.01, 3149.16 },
+	{ 0.5, 4.93, 6525.80 },
+	{ 0.4, 1.27, 2281.23 },
+	{ 0.4, 2.33, 3738.76 },
+	{ 0.5, 0.84, 4136.91 },
+	/* 32 terms retained, 97 terms dropped, error 0.011"*T^3 */
+
+	/* mars l, T^4 */
+	{ 114.0, 3.1416, 0 },
+	{ 28.7, 5.637, 6681.225 },
+	{ 24.4, 5.139, 3340.612 },
+	{ 11.2, 6.032, 10021.837 },
+	{ 3.2, 3.56, 155.42 },
+	{ 3.3, 0.13, 13362.45 },
+	{ 0.8, 0.49, 16703.06 },
+	{ 0.8, 1.32, 242.73 },
+	{ 0.5, 3.06, 3185.19 },
+	{ 0.4, 2.16, 553.57 },
+	{ 0.3, 6.23, 3.52 },
+	{ 0.2, 0.44, 3344.14 },
+	{ 0.2, 0.82, 20043.67 },
+	{ 0.2, 3.74, 3496.03 },
+	{ 0.1, 1.67, 3583.34 },
+	/* 15 terms retained, 21 terms dropped, error 0.0019"*T^4 */
+
+	/* mars l, T^5 */
+	{ 0.7, 4.04, 6681.22 },
+	{ 0.9, 3.14, 0 },
+	{ 0.5, 4.49, 10021.84 },
+	{ 0.4, 5.07, 155.42 },
+	{ 0.2, 3.51, 3340.61 },
+	{ 0.2, 4.85, 13362.45 },
+	{ 0.1, 6.09, 242.73 },
+	/* 7 terms retained, 8 terms dropped, error 0.0012"*T^5 */
+	/* end mars l */
+
+	/* mars b, T^0 */
+	{ 3197135.0, 3.76832042, 3340.61242670 },
+	{ 298033.2, 4.1061700, 6681.2248534 },
+	{ 289104.7, 0, 0 },
+	{ 31365.5, 4.446511, 10021.837280 },
+	{ 3484.1, 4.78813, 13362.44971 },
+	{ 443.0, 5.6523, 3337.0893 },
+	{ 443.4, 5.0264, 3344.1355 },
+	{ 399.1, 5.1306, 16703.0621 },
+	{ 292.5, 3.7929, 2281.2305 },
+	{ 182.0, 6.1365, 6151.5339 },
+	{ 163.2, 4.2640, 529.6910 },
+	{ 159.7, 2.2319, 1059.3819 },
+	{ 139.3, 2.4180, 8962.4553 },
+	{ 149.3, 2.1650, 5621.8429 },
+	{ 142.7, 1.1822, 3340.5952 },
+	{ 142.7, 3.2129, 3340.6297 },
+	{ 82.5, 5.367, 6684.748 },
+	{ 73.6, 5.092, 398.149 },
+	{ 72.7, 5.538, 6283.076 },
+	{ 86.4, 5.744, 3738.761 },
+	{ 83.3, 5.989, 6677.702 },
+	{ 60.1, 3.680, 796.298 },
+	{ 63.1, 0.730, 5884.927 },
+	{ 62.3, 4.851, 2942.463 },
+	{ 47.0, 5.543, 3340.545 },
+	{ 47.0, 5.135, 3340.680 },
+	{ 46.6, 5.474, 20043.675 },
+	{ 45.6, 2.133, 2810.921 },
+	{ 41.3, 0.200, 9492.146 },
+	{ 47.2, 4.522, 3149.164 },
+	{ 38.5, 4.080, 4136.910 },
+	{ 33.1, 4.066, 1751.540 },
+	{ 29.7, 5.922, 3532.061 },
+	{ 32.7, 2.621, 2914.014 },
+	{ 29.5, 2.753, 12303.068 },
+	{ 28.2, 2.063, 5486.778 },
+	{ 28.6, 4.947, 3870.303 },
+	{ 26.6, 3.551, 6681.242 },
+	{ 26.6, 1.520, 6681.208 },
+	{ 26.1, 2.601, 4399.994 },
+	/* 40 terms retained, 401 terms dropped, error 0.69" */
+
+	/* mars b, T^1 */
+	{ 350068.8, 5.3684784, 3340.6124267 },
+	{ 14116.0, 3.141593, 0 },
+	{ 9670.8, 5.47878, 6681.22485 },
+	{ 1471.9, 3.20206, 10021.83728 },
+	{ 425.9, 3.4084, 13362.4497 },
+	{ 102.0, 0.7762, 3337.0893 },
+	{ 78.8, 3.718, 16703.062 },
+	{ 26.2, 2.483, 2281.230 },
+	{ 32.7, 3.458, 5621.843 },
+	{ 20.7, 1.441, 6151.534 },
+	{ 18.3, 6.031, 529.691 },
+	{ 15.7, 3.931, 8962.455 },
+	{ 17.0, 4.811, 3344.136 },
+	{ 13.1, 0.973, 6677.702 },
+	{ 15.6, 2.782, 3340.595 },
+	{ 15.6, 4.813, 3340.630 },
+	{ 13.8, 1.680, 3532.061 },
+	{ 12.7, 4.045, 20043.675 },
+	{ 14.3, 0.246, 2942.463 },
+	{ 12.5, 2.256, 5884.927 },
+	{ 8.8, 0.34, 398.15 },
+	{ 8.6, 1.75, 2544.31 },
+	{ 8.9, 5.95, 2810.92 },
+	{ 8.1, 0.84, 6283.08 },
+	{ 9.2, 4.35, 3496.03 },
+	{ 8.1, 4.30, 6684.75 },
+	/* 26 terms retained, 261 terms dropped, error 0.17"*T */
+
+	/* mars b, T^2 */
+	{ 16726.7, 0.602214, 3340.612427 },
+	{ 4986.8, 3.14159, 0 },
+	{ 302.1, 5.5587, 6681.2249 },
+	{ 25.8, 1.897, 13362.450 },
+	{ 21.5, 0.917, 10021.837 },
+	{ 11.8, 2.242, 3337.089 },
+	{ 8.0, 2.25, 16703.06 },
+	{ 3.0, 5.89, 3496.03 },
+	{ 2.4, 5.19, 5621.84 },
+	{ 1.8, 2.59, 20043.67 },
+	/* 10 terms retained, 120 terms dropped, error 0.024"*T^2 */
+
+	/* mars b, T^3 */
+	{ 606.5, 1.9805, 3340.6124 },
+	{ 42.6, 0, 0 },
+	{ 13.7, 1.796, 6681.225 },
+	{ 2.7, 3.45, 10021.84 },
+	{ 0.9, 3.75, 3337.09 },
+	{ 0.6, 0.11, 13362.45 },
+	{ 0.6, 1.14, 3496.03 },
+	{ 0.5, 0.71, 16703.06 },
+	/* 8 terms retained, 33 terms dropped, error 0.0059"*T^3 */
+
+	/* mars b, T^4 */
+	{ 11.3, 3.457, 3340.612 },
+	{ 13.4, 0, 0 },
+	{ 0.7, 0.50, 6681.22 },
+	{ 0.1, 1.05, 10021.84 },
+	{ 0.1, 2.66, 3496.03 },
+	/* 5 terms retained, 6 terms dropped, error 0.001"*T^4 */
+
+	/* mars b, T^5 */
+	{ 0.5, 4.87, 3340.61 },
+	/* 1 terms retained, 4 terms dropped, error 0.0027"*T^5 */
+	/* end mars b */
+
+	/* mars r, T^0 */
+	{ 153033488.3, 0, 0 },
+	{ 14184953.2, 3.479712835, 3340.612426700 },
+	{ 660776.4, 3.8178344, 6681.2248534 },
+	{ 46179.1, 4.155953, 10021.837280 },
+	{ 8109.7, 5.55958, 2810.92146 },
+	{ 7485.3, 1.77239, 5621.84292 },
+	{ 5523.2, 1.36436, 2281.23050 },
+	{ 3825.2, 4.49407, 13362.44971 },
+	{ 2306.5, 0.09082, 2544.31442 },
+	{ 1999.4, 5.36060, 3337.08931 },
+	{ 2484.4, 4.92546, 2942.46342 },
+	{ 1960.2, 4.74249, 3344.13555 },
+	{ 1167.1, 2.11262, 5092.15196 },
+	{ 1102.8, 5.00908, 398.14900 },
+	{ 899.1, 4.4079, 529.6910 },
+	{ 992.3, 5.8386, 6151.5339 },
+	{ 807.3, 2.1022, 1059.3819 },
+	{ 797.9, 3.4484, 796.2980 },
+	{ 741.0, 1.4991, 2146.1654 },
+	{ 692.3, 2.1338, 8962.4553 },
+	{ 633.1, 0.8935, 3340.5952 },
+	{ 725.6, 1.2452, 8432.7644 },
+	{ 633.1, 2.9243, 3340.6297 },
+	{ 574.4, 0.8290, 2914.0142 },
+	{ 526.2, 5.3829, 3738.7614 },
+	{ 630.0, 1.2874, 1751.5395 },
+	{ 472.8, 5.1985, 3127.3133 },
+	{ 348.1, 4.8322, 16703.0621 },
+	{ 283.7, 2.9069, 3532.0607 },
+	{ 279.6, 5.2575, 6283.0758 },
+	{ 233.8, 5.1055, 5486.7778 },
+	{ 219.4, 5.5834, 191.4483 },
+	{ 269.9, 3.7639, 5884.9268 },
+	{ 208.3, 5.2548, 3340.5451 },
+	{ 275.2, 2.9082, 1748.0164 },
+	{ 275.5, 1.2177, 6254.6267 },
+	{ 239.1, 2.0367, 1194.4470 },
+	{ 223.2, 4.1986, 3149.1642 },
+	{ 182.7, 5.0806, 6684.7480 },
+	{ 186.2, 5.6987, 6677.7017 },
+	{ 176.0, 5.9534, 3870.3034 },
+	{ 178.6, 4.1842, 3333.4989 },
+	{ 208.3, 4.8463, 3340.6797 },
+	{ 228.1, 3.2553, 6872.6731 },
+	{ 144.3, 0.2130, 5088.6288 },
+	{ 163.5, 3.7989, 4136.9104 },
+	{ 133.1, 1.5391, 7903.0734 },
+	{ 141.8, 2.4779, 4562.4610 },
+	{ 114.9, 4.3175, 1349.8674 },
+	{ 118.8, 2.1218, 1589.0729 },
+	{ 102.1, 6.1814, 9492.1463 },
+	{ 128.6, 5.4988, 8827.3903 },
+	{ 111.5, 0.5534, 11243.6858 },
+	{ 82.5, 1.622, 11773.377 },
+	{ 83.2, 0.616, 8429.241 },
+	{ 84.5, 0.623, 1592.596 },
+	{ 86.7, 1.750, 2700.715 },
+	{ 71.8, 2.475, 12303.068 },
+	{ 85.3, 1.616, 4690.480 },
+	{ 63.6, 2.673, 426.598 },
+	{ 68.6, 2.402, 4399.994 },
+	{ 58.6, 4.721, 213.299 },
+	{ 62.0, 1.101, 1221.849 },
+	{ 66.5, 2.213, 6041.328 },
+	{ 55.8, 1.233, 3185.192 },
+	{ 55.0, 5.727, 951.718 },
+	{ 52.4, 3.024, 4292.331 },
+	{ 55.7, 5.447, 3723.509 },
+	{ 59.0, 3.262, 6681.242 },
+	{ 44.6, 2.015, 8031.092 },
+	{ 59.0, 1.232, 6681.208 },
+	{ 42.4, 2.266, 155.420 },
+	{ 39.0, 2.578, 3341.593 },
+	{ 51.6, 5.723, 7079.374 },
+	{ 48.9, 5.616, 3553.912 },
+	{ 45.4, 5.433, 6467.926 },
+	{ 36.4, 4.439, 3894.182 },
+	{ 36.0, 1.160, 2288.344 },
+	{ 35.3, 5.490, 1990.745 },
+	{ 42.2, 1.633, 5628.956 },
+	{ 44.3, 5.003, 5614.729 },
+	{ 33.6, 5.170, 20043.675 },
+	{ 43.3, 1.037, 11769.854 },
+	{ 39.2, 1.242, 3339.632 },
+	{ 31.9, 4.593, 2274.117 },
+	{ 30.3, 2.442, 11371.705 },
+	{ 32.3, 2.382, 4535.059 },
+	{ 31.9, 4.375, 3.523 },
+	{ 29.3, 4.060, 3097.884 },
+	{ 32.0, 1.940, 382.897 },
+	{ 26.2, 5.585, 9623.688 },
+	{ 27.9, 4.258, 3191.049 },
+	{ 33.1, 0.855, 553.569 },
+	{ 27.5, 1.577, 9595.239 },
+	{ 25.2, 0.814, 10713.995 },
+	/* 95 terms retained, 1023 terms dropped, error 4.9e-06 a.u. */
+
+	/* mars r, T^1 */
+	{ 1107433.3, 2.03250525, 3340.61242670 },
+	{ 103175.9, 2.3707185, 6681.2248534 },
+	{ 12877.2, 0, 0 },
+	{ 10815.9, 2.708881, 10021.837280 },
+	{ 1194.5, 3.04702, 13362.44971 },
+	{ 438.6, 2.8884, 2281.2305 },
+	{ 395.7, 3.4232, 3344.1355 },
+	{ 182.6, 1.5843, 2544.3144 },
+	{ 135.8, 3.3851, 16703.0621 },
+	{ 128.2, 0.6299, 1059.3819 },
+	{ 127.1, 1.9539, 796.2980 },
+	{ 118.4, 2.9976, 2146.1654 },
+	{ 128.4, 6.0434, 3337.0893 },
+	{ 87.5, 3.421, 398.149 },
+	{ 83.0, 3.856, 3738.761 },
+	{ 75.6, 4.451, 6151.534 },
+	{ 72.0, 2.764, 529.691 },
+	{ 66.5, 2.549, 1751.540 },
+	{ 54.3, 0.678, 8962.455 },
+	{ 51.0, 3.726, 6684.748 },
+	{ 66.4, 4.406, 1748.016 },
+	{ 47.9, 2.285, 2914.014 },
+	{ 49.4, 5.730, 3340.595 },
+	{ 49.4, 1.477, 3340.630 },
+	{ 57.5, 0.544, 1194.447 },
+	{ 48.3, 2.581, 3149.164 },
+	{ 36.4, 6.027, 3185.192 },
+	{ 37.2, 5.814, 1349.867 },
+	{ 36.0, 5.895, 3333.499 },
+	{ 31.1, 0.978, 191.448 },
+	{ 39.0, 2.319, 4136.910 },
+	{ 27.2, 5.414, 1592.596 },
+	{ 24.3, 3.758, 155.420 },
+	{ 22.8, 1.748, 5088.629 },
+	{ 22.3, 0.939, 951.718 },
+	{ 21.7, 3.836, 6283.076 },
+	{ 21.3, 0.780, 1589.073 },
+	{ 21.6, 4.569, 3532.061 },
+	{ 18.0, 4.219, 3870.303 },
+	{ 18.2, 0.413, 5486.778 },
+	{ 16.3, 3.808, 3340.545 },
+	{ 16.8, 5.549, 3097.884 },
+	{ 16.9, 4.537, 4292.331 },
+	{ 15.8, 4.757, 9492.146 },
+	{ 15.7, 3.724, 20043.675 },
+	{ 20.4, 3.135, 4690.480 },
+	{ 14.7, 5.953, 3894.182 },
+	{ 16.3, 3.399, 3340.680 },
+	{ 14.3, 3.999, 1990.745 },
+	{ 16.5, 0.968, 4399.994 },
+	{ 13.0, 5.142, 6677.702 },
+	{ 12.5, 1.032, 3341.593 },
+	{ 16.5, 3.539, 2700.715 },
+	{ 16.2, 2.349, 553.569 },
+	{ 13.2, 0.415, 5614.729 },
+	{ 11.3, 1.024, 12303.068 },
+	{ 12.4, 6.231, 5628.956 },
+	{ 12.7, 0.690, 3723.509 },
+	{ 11.8, 6.253, 2274.117 },
+	{ 10.4, 1.233, 426.598 },
+	{ 11.2, 1.318, 3496.033 },
+	{ 10.3, 0.901, 4535.059 },
+	{ 12.2, 4.223, 7079.374 },
+	{ 9.8, 3.45, 382.90 },
+	{ 8.6, 1.16, 2787.04 },
+	{ 7.9, 5.74, 2288.34 },
+	{ 9.2, 1.82, 6681.24 },
+	{ 7.8, 4.15, 6041.33 },
+	{ 9.2, 6.07, 6681.21 },
+	{ 9.0, 2.58, 2388.89 },
+	{ 6.8, 0.24, 11773.38 },
+	{ 7.1, 3.51, 8031.09 },
+	{ 9.2, 3.90, 3553.91 },
+	{ 6.7, 4.26, 242.73 },
+	{ 7.2, 3.70, 2818.04 },
+	{ 6.5, 0.04, 2957.72 },
+	{ 8.8, 2.20, 1221.85 },
+	{ 6.5, 2.12, 8429.24 },
+	{ 6.8, 4.05, 10025.36 },
+	{ 7.3, 4.27, 2803.81 },
+	{ 7.7, 1.01, 8432.76 },
+	{ 6.3, 1.90, 5621.84 },
+	{ 6.3, 1.60, 3347.73 },
+	{ 6.5, 2.76, 3339.63 },
+	/* 84 terms retained, 512 terms dropped, error 1.2e-06 a.u.*T */
+
+	/* mars r, T^2 */
+	{ 44242.2, 0.479306, 3340.612427 },
+	{ 8138.0, 0.86998, 6681.22485 },
+	{ 1274.9, 1.22594, 10021.83728 },
+	{ 187.4, 1.5730, 13362.4497 },
+	{ 40.7, 1.971, 3344.136 },
+	{ 52.4, 3.142, 0 },
+	{ 26.6, 1.917, 16703.062 },
+	{ 17.8, 4.435, 2281.230 },
+	{ 11.7, 4.525, 3185.192 },
+	{ 10.2, 5.391, 1059.382 },
+	{ 9.9, 0.42, 796.30 },
+	{ 9.2, 4.54, 2146.17 },
+	{ 7.3, 3.14, 2544.31 },
+	{ 7.2, 2.29, 6684.75 },
+	{ 6.8, 5.27, 155.42 },
+	{ 6.5, 2.31, 3738.76 },
+	{ 7.8, 5.93, 1748.02 },
+	{ 5.8, 1.05, 1349.87 },
+	{ 6.7, 5.30, 1194.45 },
+	{ 4.7, 0.77, 3097.88 },
+	{ 5.4, 1.00, 3149.16 },
+	{ 4.4, 2.46, 951.72 },
+	{ 4.3, 3.90, 1592.60 },
+	{ 3.5, 1.85, 398.15 },
+	{ 3.7, 2.26, 20043.67 },
+	{ 3.4, 3.82, 1751.54 },
+	{ 4.6, 0.81, 4136.91 },
+	{ 3.2, 2.12, 5614.73 },
+	{ 3.6, 1.32, 3333.50 },
+	{ 2.9, 1.19, 529.69 },
+	{ 3.0, 2.86, 6151.53 },
+	{ 3.1, 4.55, 5628.96 },
+	{ 2.9, 1.20, 3894.18 },
+	{ 3.9, 3.86, 553.57 },
+	{ 2.8, 2.49, 1990.75 },
+	{ 2.7, 6.07, 4292.33 },
+	{ 2.7, 2.92, 3496.03 },
+	{ 2.4, 5.94, 2787.04 },
+	{ 2.3, 2.56, 191.45 },
+	{ 2.2, 5.37, 8962.46 },
+	{ 2.1, 2.75, 242.73 },
+	{ 2.2, 1.85, 3337.09 },
+	{ 2.0, 5.76, 3341.59 },
+	{ 2.0, 3.82, 2914.01 },
+	{ 1.8, 5.69, 1589.07 },
+	{ 1.8, 3.32, 5088.63 },
+	{ 2.4, 4.68, 4690.48 },
+	{ 2.0, 4.17, 3340.60 },
+	{ 2.0, 6.21, 3340.63 },
+	{ 1.6, 5.68, 4535.06 },
+	{ 2.2, 1.07, 2388.89 },
+	{ 2.0, 3.11, 3583.34 },
+	{ 2.0, 5.76, 4399.99 },
+	/* 53 terms retained, 260 terms dropped, error 2.9e-07 a.u.*T^2 */
+
+	/* mars r, T^3 */
+	{ 1113.1, 5.14987, 3340.61243 },
+	{ 424.4, 5.6134, 6681.2249 },
+	{ 100.0, 5.9973, 10021.8373 },
+	{ 19.6, 0.076, 13362.450 },
+	{ 3.5, 0.43, 16703.06 },
+	{ 4.7, 3.14, 0 },
+	{ 2.9, 0.45, 3344.14 },
+	{ 2.4, 3.02, 3185.19 },
+	{ 0.7, 0.81, 6684.75 },
+	{ 0.5, 3.87, 1059.38 },
+	{ 0.6, 0.78, 20043.67 },
+	{ 0.5, 4.52, 3496.03 },
+	{ 0.5, 1.61, 3583.34 },
+	{ 0.4, 5.72, 3149.16 },
+	/* 14 terms retained, 97 terms dropped, error 3.1e-08 a.u.*T^3 */
+
+	/* mars r, T^4 */
+	{ 19.6, 3.582, 3340.612 },
+	{ 16.3, 4.051, 6681.225 },
+	{ 5.8, 4.46, 10021.84 },
+	{ 1.5, 4.84, 13362.45 },
+	{ 0.4, 1.51, 3185.19 },
+	{ 0.3, 5.21, 16703.06 },
+	{ 0.2, 5.16, 3344.14 },
+	{ 0.1, 2.19, 3496.03 },
+	{ 0.1, 0, 0 },
+	/* 9 terms retained, 19 terms dropped, error 9.4e-09 a.u.*T^4 */
+
+	/* mars r, T^5 */
+	{ 0.5, 2.48, 6681.22 },
+	{ 0.3, 2.92, 10021.84 },
+	{ 0.1, 1.77, 3340.61 },
+	/* 3 terms retained, 6 terms dropped, error 4.6e-09 a.u.*T^5 */
+	/* end mars */
+};
+
+int vn_mars[][3] = {
+	/* addresses for mars l, b, r  */
+	/* T^0 */ { 0, 343, 433, },
+	/* T^1 */ { 124, 383, 528, },
+	/* T^2 */ { 222, 409, 612, },
+	/* T^3 */ { 289, 419, 665, },
+	/* T^4 */ { 321, 427, 679, },
+	/* T^5 */ { 336, 432, 688, },
+	/* end */ { 343, 433, 691, },
+	/* termination */ { 0, }
+};
+
+/*  version d4 (lbr)       
+ *  heliocentric dynamical ecliptic and equinox of the date
+ */
+
+double vx_mercury[][3] = {
+	/* mercury l, T^0 */
+	{ 440250710.1, 0, 0 },
+	{ 40989415.0, 1.483020342, 26087.903141574 },
+	{ 5046294.2, 4.47785490, 52175.80628315 },
+	{ 855346.8, 1.1652032, 78263.7094247 },
+	{ 165590.4, 4.1196916, 104351.6125663 },
+	{ 34561.9, 0.779308, 130439.515708 },
+	{ 7583.5, 3.71348, 156527.41885 },
+	{ 3559.7, 1.51203, 1109.37855 },
+	{ 1726.0, 0.35832, 182615.32199 },
+	{ 1803.5, 4.10333, 5661.33205 },
+	{ 1364.7, 4.59918, 27197.28169 },
+	{ 1589.9, 2.99510, 25028.52121 },
+	{ 1017.3, 0.88031, 31749.23519 },
+	{ 714.2, 1.5414, 24978.5246 },
+	{ 643.8, 5.3027, 21535.9496 },
+	{ 404.2, 3.2823, 208703.2251 },
+	{ 352.4, 5.2416, 20426.5711 },
+	{ 343.3, 5.7653, 955.5997 },
+	{ 339.2, 5.8633, 25558.2122 },
+	{ 451.1, 6.0499, 51116.4244 },
+	{ 325.3, 1.3367, 53285.1848 },
+	{ 259.6, 0.9873, 4551.9535 },
+	{ 345.2, 2.7921, 15874.6176 },
+	{ 272.9, 2.4945, 529.6910 },
+	{ 234.8, 0.2667, 11322.6641 },
+	{ 238.8, 0.1134, 1059.3819 },
+	{ 264.3, 3.9171, 57837.1383 },
+	{ 216.6, 0.6599, 13521.7514 },
+	{ 183.4, 2.6288, 27043.5029 },
+	{ 176.0, 4.5364, 51066.4277 },
+	{ 181.6, 2.4341, 25661.3050 },
+	{ 209.0, 2.0918, 47623.8528 },
+	{ 172.6, 2.4520, 24498.8302 },
+	{ 142.3, 3.3600, 37410.5672 },
+	{ 137.9, 0.2910, 10213.2855 },
+	{ 118.2, 2.7815, 77204.3275 },
+	{ 96.9, 6.204, 234791.128 },
+	{ 125.2, 3.7208, 39609.6546 },
+	{ 86.8, 2.642, 51646.115 },
+	{ 86.7, 1.960, 46514.474 },
+	{ 88.3, 5.413, 26617.594 },
+	{ 106.4, 4.2057, 19804.8273 },
+	{ 90.0, 5.852, 41962.521 },
+	{ 85.0, 4.331, 79373.088 },
+	{ 69.2, 4.194, 19.670 },
+	{ 63.5, 3.147, 7238.676 },
+	{ 68.5, 0.634, 83925.041 },
+	{ 69.7, 3.572, 25132.303 },
+	{ 59.5, 2.747, 16983.996 },
+	{ 64.8, 0.048, 33326.579 },
+	{ 55.4, 4.053, 30639.857 },
+	{ 54.4, 3.143, 27147.285 },
+	{ 47.6, 5.497, 3.881 },
+	{ 49.6, 3.990, 6770.711 },
+	{ 56.5, 5.119, 73711.756 },
+	{ 41.8, 5.642, 53131.406 },
+	{ 51.5, 5.478, 50586.733 },
+	{ 44.7, 1.224, 77154.331 },
+	{ 41.9, 5.193, 6283.076 },
+	{ 38.0, 2.431, 12566.152 },
+	{ 35.6, 0.814, 32858.614 },
+	{ 48.0, 5.493, 51749.208 },
+	{ 35.4, 3.370, 36301.189 },
+	{ 34.0, 2.786, 14765.239 },
+	{ 30.6, 5.840, 43071.899 },
+	{ 36.0, 1.424, 2218.757 },
+	{ 34.0, 0.475, 65697.558 },
+	{ 30.8, 5.770, 103292.231 },
+	{ 28.5, 0.650, 426.598 },
+	{ 26.2, 5.242, 22645.328 },
+	{ 26.3, 0.648, 1589.073 },
+	{ 29.5, 0.698, 213.299 },
+	{ 27.5, 0.980, 45892.730 },
+	{ 26.8, 1.061, 3442.575 },
+	{ 27.1, 0.085, 63498.470 },
+	/* 75 terms retained, 1305 terms dropped, error 0.97" */
+
+	/* mercury l, T^1 */
+	{ 2608814706222.7, 0, 0 },
+	{ 1126007.8, 6.21703971, 26087.90314157 },
+	{ 303471.4, 3.0556547, 52175.8062831 },
+	{ 80538.5, 6.104547, 78263.709425 },
+	{ 21245.0, 2.835319, 104351.612566 },
+	{ 5592.1, 5.82676, 130439.51571 },
+	{ 1472.2, 2.51845, 156527.41885 },
+	{ 352.2, 3.0524, 1109.3786 },
+	{ 388.3, 5.4804, 182615.3220 },
+	{ 93.5, 6.118, 27197.282 },
+	{ 90.6, 0.000, 24978.525 },
+	{ 102.7, 2.1488, 208703.2251 },
+	{ 51.9, 5.621, 5661.332 },
+	{ 44.4, 4.573, 25028.521 },
+	{ 28.1, 3.042, 51066.428 },
+	{ 22.0, 0.865, 955.600 },
+	{ 27.3, 5.092, 234791.128 },
+	{ 20.4, 3.715, 20426.571 },
+	{ 20.2, 0.519, 21535.950 },
+	{ 17.5, 5.727, 4551.953 },
+	{ 16.7, 1.351, 529.691 },
+	{ 15.3, 1.792, 11322.664 },
+	{ 15.4, 5.743, 19.670 },
+	{ 14.0, 3.594, 24498.830 },
+	{ 12.8, 2.696, 53285.185 },
+	{ 12.6, 3.895, 3.881 },
+	{ 12.6, 4.705, 1059.382 },
+	{ 8.0, 4.18, 26617.59 },
+	{ 7.9, 0.50, 46514.47 },
+	{ 8.0, 3.93, 27043.50 },
+	{ 7.7, 2.48, 57837.14 },
+	{ 8.6, 6.06, 77154.33 },
+	{ 6.8, 2.77, 7.11 },
+	{ 6.6, 5.53, 6770.71 },
+	{ 7.3, 1.75, 260879.03 },
+	{ 7.2, 2.98, 2218.76 },
+	{ 6.4, 2.14, 25132.30 },
+	/* 37 terms retained, 802 terms dropped, error 0.16"*T */
+
+	/* mercury l, T^2 */
+	{ 53049.8, 0, 0 },
+	{ 16903.7, 4.690723, 26087.903142 },
+	{ 7396.7, 1.34736, 52175.80628 },
+	{ 3018.3, 4.45644, 78263.70942 },
+	{ 1107.4, 1.26227, 104351.61257 },
+	{ 378.2, 4.3200, 130439.5157 },
+	{ 123.0, 1.0687, 156527.4188 },
+	{ 38.7, 4.080, 182615.322 },
+	{ 14.9, 4.633, 1109.379 },
+	{ 11.9, 0.792, 208703.225 },
+	{ 5.2, 4.72, 24978.52 },
+	{ 3.6, 3.77, 234791.13 },
+	{ 2.6, 1.44, 27197.28 },
+	{ 2.0, 1.50, 51066.43 },
+	/* 14 terms retained, 381 terms dropped, error 0.033"*T^2 */
+
+	/* mercury l, T^3 */
+	{ 188.1, 0.0347, 52175.8063 },
+	{ 142.2, 3.1251, 26087.9031 },
+	{ 96.9, 3.004, 78263.709 },
+	{ 43.7, 6.019, 104351.613 },
+	{ 35.4, 0, 0 },
+	{ 18.0, 2.775, 130439.516 },
+	{ 7.0, 5.82, 156527.42 },
+	{ 2.6, 2.57, 182615.32 },
+	{ 0.9, 5.59, 208703.23 },
+	/* 9 terms retained, 144 terms dropped, error 0.012"*T^3 */
+
+	/* mercury l, T^4 */
+	{ 114.1, 3.1416, 0 },
+	{ 3.2, 2.03, 26087.90 },
+	{ 1.9, 1.42, 78263.71 },
+	{ 1.7, 4.50, 52175.81 },
+	{ 1.2, 4.50, 104351.61 },
+	{ 0.6, 1.27, 130439.52 },
+	{ 0.3, 4.31, 156527.42 },
+	{ 0.1, 1.06, 182615.32 },
+	/* 8 terms retained, 20 terms dropped, error 0.0016"*T^4 */
+
+	/* mercury l, T^5 */
+	{ 0.9, 3.14, 0 },
+	/* 1 terms retained, 12 terms dropped, error 0.0051"*T^5 */
+	/* end mercury l */
+
+	/* mercury b, T^0 */
+	{ 11737529.0, 1.983574988, 26087.903141574 },
+	{ 2388077.0, 5.03738960, 52175.80628315 },
+	{ 1222839.5, 3.14159265, 0 },
+	{ 543251.8, 1.7964436, 78263.7094247 },
+	{ 129778.8, 4.8323250, 104351.6125663 },
+	{ 31866.9, 1.580885, 130439.515708 },
+	{ 7963.3, 4.60972, 156527.41885 },
+	{ 2014.2, 1.35324, 182615.32199 },
+	{ 514.0, 4.3784, 208703.2251 },
+	{ 207.7, 4.9177, 27197.2817 },
+	{ 208.6, 2.0202, 24978.5246 },
+	{ 132.0, 1.1191, 234791.1283 },
+	{ 100.5, 5.6568, 20426.5711 },
+	{ 121.4, 1.8127, 53285.1848 },
+	{ 91.6, 2.282, 25028.521 },
+	{ 99.2, 0.094, 51116.424 },
+	{ 94.6, 1.242, 31749.235 },
+	{ 78.8, 4.407, 57837.138 },
+	{ 77.7, 0.526, 1059.382 },
+	{ 84.3, 5.085, 51066.428 },
+	{ 49.9, 3.498, 5661.332 },
+	{ 46.5, 3.237, 77204.327 },
+	{ 44.8, 4.878, 79373.088 },
+	{ 40.8, 2.466, 46514.474 },
+	{ 37.4, 4.458, 4551.953 },
+	{ 34.1, 4.142, 260879.031 },
+	{ 35.9, 1.091, 1109.379 },
+	{ 32.0, 1.185, 83925.041 },
+	{ 31.0, 3.503, 21535.950 },
+	{ 31.8, 2.415, 47623.853 },
+	{ 28.7, 1.848, 77154.331 },
+	{ 25.8, 2.776, 27043.503 },
+	{ 25.2, 3.591, 27147.285 },
+	/* 33 terms retained, 785 terms dropped, error 0.61" */
+
+	/* mercury b, T^1 */
+	{ 429151.4, 3.5016978, 26087.9031416 },
+	{ 146233.7, 3.1415927, 0 },
+	{ 22675.3, 0.015154, 52175.806283 },
+	{ 10895.0, 0.485402, 78263.709425 },
+	{ 6353.5, 3.42944, 104351.61257 },
+	{ 2495.7, 0.16051, 130439.51571 },
+	{ 859.6, 3.1845, 156527.4188 },
+	{ 277.5, 6.2102, 182615.3220 },
+	{ 86.2, 2.952, 208703.225 },
+	{ 26.1, 5.977, 234791.128 },
+	{ 27.7, 0.291, 27197.282 },
+	{ 12.8, 3.377, 53285.185 },
+	{ 12.7, 0.538, 24978.525 },
+	{ 7.8, 2.72, 260879.03 },
+	{ 7.5, 3.58, 51066.43 },
+	/* 15 terms retained, 479 terms dropped, error 0.12"*T */
+
+	/* mercury b, T^2 */
+	{ 11830.9, 4.790656, 26087.903142 },
+	{ 1913.5, 0, 0 },
+	{ 1044.8, 1.21217, 52175.80628 },
+	{ 266.2, 4.4342, 78263.7094 },
+	{ 170.3, 1.6226, 104351.6126 },
+	{ 96.3, 4.800, 130439.516 },
+	{ 44.7, 1.608, 156527.419 },
+	{ 18.3, 4.669, 182615.322 },
+	{ 6.9, 1.43, 208703.23 },
+	{ 2.5, 4.47, 234791.13 },
+	{ 1.7, 1.83, 27197.28 },
+	/* 11 terms retained, 219 terms dropped, error 0.025"*T^2 */
+
+	/* mercury b, T^3 */
+	{ 235.4, 0.3539, 26087.9031 },
+	{ 160.5, 0, 0 },
+	{ 18.9, 4.363, 52175.806 },
+	{ 6.4, 2.51, 78263.71 },
+	{ 4.6, 6.14, 104351.61 },
+	{ 3.1, 3.12, 130439.52 },
+	{ 1.7, 6.27, 156527.42 },
+	{ 0.9, 3.08, 182615.32 },
+	/* 8 terms retained, 45 terms dropped, error 0.011"*T^3 */
+
+	/* mercury b, T^4 */
+	{ 4.3, 1.75, 26087.90 },
+	{ 1.0, 3.14, 0 },
+	{ 0.4, 4.03, 52175.81 },
+	{ 0.3, 0.21, 78263.71 },
+	{ 0.1, 3.75, 104351.61 },
+	/* 5 terms retained, 10 terms dropped, error 0.0012"*T^4 */
+
+	/* mercury b, T^5 */
+	{ 0.1, 3.95, 26087.90 },
+	/* 1 terms retained, 9 terms dropped, error 0.00062"*T^5 */
+	/* end mercury b */
+
+	/* mercury r, T^0 */
+	{ 39528271.7, 0, 0 },
+	{ 7834131.8, 6.19233723, 26087.90314157 },
+	{ 795525.6, 2.9598969, 52175.8062831 },
+	{ 121281.8, 6.0106415, 78263.7094247 },
+	{ 21922.0, 2.778201, 104351.612566 },
+	{ 4354.1, 5.82895, 130439.51571 },
+	{ 918.2, 2.5965, 156527.4188 },
+	{ 260.0, 3.0282, 27197.2817 },
+	{ 290.0, 1.4244, 25028.5212 },
+	{ 201.9, 5.6473, 182615.3220 },
+	{ 201.5, 5.5923, 31749.2352 },
+	{ 142.0, 6.2526, 24978.5246 },
+	{ 100.1, 3.7344, 21535.9496 },
+	{ 77.6, 3.670, 20426.571 },
+	{ 63.3, 4.299, 25558.212 },
+	{ 63.0, 4.766, 1059.382 },
+	{ 66.8, 2.525, 5661.332 },
+	{ 75.5, 4.474, 51116.424 },
+	{ 48.3, 6.068, 53285.185 },
+	{ 45.7, 2.415, 208703.225 },
+	{ 35.2, 1.059, 27043.503 },
+	{ 40.8, 2.359, 57837.138 },
+	{ 44.2, 1.220, 15874.618 },
+	{ 33.9, 0.864, 25661.305 },
+	{ 37.2, 0.517, 47623.853 },
+	{ 30.1, 1.795, 37410.567 },
+	{ 28.4, 3.021, 51066.428 },
+	{ 30.9, 0.884, 24498.830 },
+	{ 26.1, 2.150, 39609.655 },
+	/* 29 terms retained, 1186 terms dropped, error 2.9e-06 a.u. */
+
+	/* mercury r, T^1 */
+	{ 217347.7, 4.6561716, 26087.9031416 },
+	{ 44141.8, 1.423855, 52175.806283 },
+	{ 10094.5, 4.474663, 78263.709425 },
+	{ 2432.8, 1.24226, 104351.61257 },
+	{ 1624.4, 0, 0 },
+	{ 604.0, 4.2930, 130439.5157 },
+	{ 152.9, 1.0606, 156527.4188 },
+	{ 39.2, 4.111, 182615.322 },
+	{ 17.8, 4.544, 27197.282 },
+	{ 18.0, 4.712, 24978.525 },
+	{ 10.2, 0.879, 208703.225 },
+	{ 8.1, 3.01, 25028.52 },
+	/* 12 terms retained, 699 terms dropped, error 5.8e-07 a.u.*T */
+
+	/* mercury r, T^2 */
+	{ 3117.9, 3.08232, 26087.90314 },
+	{ 1245.4, 6.15183, 52175.80628 },
+	{ 424.8, 2.9258, 78263.7094 },
+	{ 136.1, 5.9798, 104351.6126 },
+	{ 42.2, 2.749, 130439.516 },
+	{ 21.8, 3.142, 0 },
+	{ 12.8, 5.801, 156527.419 },
+	{ 3.8, 2.57, 182615.32 },
+	/* 8 terms retained, 318 terms dropped, error 2.3e-07 a.u.*T^2 */
+
+	/* mercury r, T^3 */
+	{ 32.7, 1.680, 26087.903 },
+	{ 24.2, 4.634, 52175.806 },
+	{ 12.1, 1.390, 78263.709 },
+	{ 5.1, 4.44, 104351.61 },
+	{ 2.0, 1.21, 130439.52 },
+	{ 1.5, 3.14, 0 },
+	{ 0.7, 4.26, 156527.42 },
+	/* 7 terms retained, 112 terms dropped, error 4.1e-08 a.u.*T^3 */
+
+	/* mercury r, T^4 */
+	{ 0.4, 0.37, 26087.90 },
+	{ 0.4, 3.19, 52175.81 },
+	{ 0.3, 6.17, 78263.71 },
+	{ 0.1, 2.92, 104351.61 },
+	/* 4 terms retained, 14 terms dropped, error 6.7e-09 a.u.*T^4 */
+
+	/* mercury r, T^5 */
+	/* 0 terms retained, 10 terms dropped, error 1.2e-10 a.u.*T^5 */
+	/* end mercury */
+};
+
+int vn_mercury[][3] = {
+	/* addresses for mercury l, b, r  */
+	/* T^0 */ { 0, 144, 217, },
+	/* T^1 */ { 75, 177, 246, },
+	/* T^2 */ { 112, 192, 258, },
+	/* T^3 */ { 126, 203, 266, },
+	/* T^4 */ { 135, 211, 273, },
+	/* T^5 */ { 143, 216, 277, },
+	/* end */ { 144, 217, 0, },
+	/* termination */ { 0, }
+};
+
+/*  version d4 (lbr)       
+ *  heliocentric dynamical ecliptic and equinox of the date
+ */
+
+double vx_neptune[][3] = {
+	/* neptune l, T^0 */
+	{ 531188633.0, 0, 0 },
+	{ 1798475.5, 2.90101273, 38.13303564 },
+	{ 1019727.7, 0.48580924, 1.48447271 },
+	{ 124531.8, 4.8300809, 36.6485629 },
+	{ 42064.4, 5.410550, 2.968945 },
+	{ 37714.6, 6.092218, 35.164090 },
+	{ 33784.7, 1.244889, 76.266071 },
+	{ 16482.7, 0.000077, 491.557929 },
+	{ 9198.6, 4.93747, 39.61751 },
+	{ 8994.2, 0.27462, 175.16606 },
+	{ 4216.2, 1.98712, 73.29713 },
+	{ 3364.8, 1.03590, 33.67962 },
+	{ 2284.8, 4.20607, 4.45342 },
+	{ 1433.5, 2.78340, 74.78160 },
+	{ 900.2, 2.0761, 109.9457 },
+	{ 745.0, 3.1903, 71.8127 },
+	{ 506.2, 5.7479, 114.3991 },
+	{ 399.6, 0.3497, 1021.2489 },
+	{ 345.2, 3.4619, 41.1020 },
+	{ 306.3, 0.4968, 0.5213 },
+	{ 287.3, 4.5052, 0.0482 },
+	{ 323.0, 2.2482, 32.1951 },
+	{ 340.3, 3.3037, 77.7505 },
+	{ 266.6, 4.8893, 0.9632 },
+	{ 227.1, 1.7971, 453.4249 },
+	{ 244.7, 1.2469, 9.5612 },
+	{ 232.9, 2.5046, 137.0330 },
+	{ 282.2, 2.2457, 146.5943 },
+	{ 251.9, 5.7817, 388.4652 },
+	{ 150.2, 2.9971, 5.9379 },
+	{ 170.4, 3.3239, 108.4612 },
+	{ 151.4, 2.1915, 33.9402 },
+	{ 148.3, 0.8595, 111.4302 },
+	{ 118.7, 3.6771, 2.4477 },
+	{ 101.8, 5.7054, 0.1119 },
+	{ 97.9, 2.805, 8.077 },
+	{ 103.1, 4.4044, 70.3282 },
+	{ 103.3, 0.0408, 0.2606 },
+	{ 109.3, 2.4160, 183.2428 },
+	{ 73.9, 1.328, 529.691 },
+	{ 77.7, 4.164, 4.193 },
+	{ 86.4, 4.228, 490.073 },
+	{ 81.5, 5.199, 493.042 },
+	{ 71.5, 5.295, 350.332 },
+	{ 64.4, 3.545, 168.053 },
+	{ 62.6, 0.150, 182.280 },
+	{ 58.5, 3.501, 145.110 },
+	{ 48.3, 1.113, 112.915 },
+	{ 47.2, 4.574, 46.210 },
+	{ 39.1, 1.666, 213.299 },
+	{ 47.7, 0.129, 484.444 },
+	{ 46.9, 3.017, 498.671 },
+	{ 38.7, 2.387, 2.921 },
+	{ 47.0, 4.498, 173.682 },
+	{ 47.6, 2.584, 219.891 },
+	{ 44.7, 5.473, 176.651 },
+	{ 32.3, 3.458, 30.711 },
+	{ 28.2, 4.133, 6.592 },
+	/* 58 terms retained, 365 terms dropped, error 0.9" */
+
+	/* neptune l, T^1 */
+	{ 3837687716.7, 0, 0 },
+	{ 16604.2, 4.863191, 1.484473 },
+	{ 15807.1, 2.279235, 38.133036 },
+	{ 3334.7, 3.68200, 76.26607 },
+	{ 1305.8, 3.67321, 2.96895 },
+	{ 604.8, 1.5048, 35.1641 },
+	{ 178.6, 3.4532, 39.6175 },
+	{ 106.5, 2.4513, 4.4534 },
+	{ 105.7, 2.7548, 33.6796 },
+	{ 72.7, 5.487, 36.649 },
+	{ 57.1, 5.216, 0.521 },
+	{ 57.4, 1.858, 114.399 },
+	{ 35.4, 4.517, 74.782 },
+	{ 32.2, 5.904, 77.751 },
+	{ 29.9, 3.670, 388.465 },
+	{ 28.9, 5.169, 9.561 },
+	{ 28.7, 5.167, 2.448 },
+	{ 25.5, 5.245, 168.053 },
+	{ 24.9, 4.732, 182.280 },
+	{ 20.2, 5.789, 1021.249 },
+	{ 19.0, 1.830, 484.444 },
+	{ 18.7, 1.316, 498.671 },
+	{ 15.1, 4.950, 137.033 },
+	{ 15.1, 3.987, 32.195 },
+	{ 10.7, 2.441, 4.193 },
+	{ 11.7, 4.893, 71.813 },
+	{ 9.6, 1.23, 5.94 },
+	{ 9.6, 1.89, 41.10 },
+	{ 9.0, 0.02, 8.08 },
+	{ 9.9, 6.08, 7.11 },
+	{ 7.6, 5.51, 73.30 },
+	{ 7.0, 0.62, 2.92 },
+	/* 32 terms retained, 151 terms dropped, error 0.17"*T */
+
+	/* neptune l, T^2 */
+	{ 53892.6, 0, 0 },
+	{ 281.3, 1.1908, 38.1330 },
+	{ 295.7, 1.8552, 1.4845 },
+	{ 270.2, 5.7214, 76.2661 },
+	{ 23.0, 1.210, 2.969 },
+	{ 7.3, 0.54, 2.45 },
+	{ 9.1, 4.43, 35.16 },
+	{ 5.2, 0.67, 168.05 },
+	{ 5.2, 3.02, 182.28 },
+	{ 4.3, 3.84, 114.40 },
+	{ 3.9, 3.53, 484.44 },
+	{ 3.7, 5.90, 498.67 },
+	{ 3.0, 0.31, 4.45 },
+	{ 3.4, 0.56, 74.78 },
+	{ 3.3, 1.85, 175.17 },
+	{ 2.2, 1.89, 388.47 },
+	{ 2.2, 4.38, 7.11 },
+	{ 1.8, 3.49, 9.56 },
+	{ 2.5, 4.69, 491.56 },
+	{ 1.8, 5.12, 33.68 },
+	{ 2.2, 1.69, 77.75 },
+	{ 1.7, 2.56, 36.65 },
+	/* 22 terms retained, 35 terms dropped, error 0.033"*T^2 */
+
+	/* neptune l, T^3 */
+	{ 31.3, 0, 0 },
+	{ 12.5, 6.044, 1.484 },
+	{ 14.5, 1.353, 76.266 },
+	{ 11.5, 6.113, 38.133 },
+	{ 1.4, 4.94, 2.97 },
+	{ 0.7, 2.36, 168.05 },
+	{ 0.7, 1.27, 182.28 },
+	{ 0.5, 5.24, 484.44 },
+	{ 0.5, 4.17, 498.67 },
+	{ 0.7, 0.56, 31.02 },
+	/* 10 terms retained, 5 terms dropped, error 0.0091"*T^3 */
+
+	/* neptune l, T^4 */
+	{ 114.0, 3.1416, 0 },
+	{ 0.6, 3.18, 76.27 },
+	/* 2 terms retained, 0 terms dropped, error 0.0043"*T^4 */
+
+	/* neptune l, T^5 */
+	{ 0.9, 3.14, 0 },
+	/* 1 terms retained, 0 terms dropped, error 0.0051"*T^5 */
+	/* end neptune l */
+
+	/* neptune b, T^0 */
+	{ 3088622.9, 1.44104373, 38.13303564 },
+	{ 27780.1, 5.912719, 76.266071 },
+	{ 27623.6, 0, 0 },
+	{ 15355.5, 2.521238, 36.648563 },
+	{ 15448.1, 3.508771, 39.617508 },
+	{ 1999.9, 1.50999, 74.78160 },
+	{ 1967.5, 4.37778, 1.48447 },
+	{ 1015.1, 3.21561, 35.16409 },
+	{ 605.8, 2.8025, 73.2971 },
+	{ 594.9, 2.1289, 41.1020 },
+	{ 588.8, 3.1866, 2.9689 },
+	{ 401.8, 4.1688, 114.3991 },
+	{ 254.3, 3.2712, 453.4249 },
+	{ 261.6, 3.7672, 213.2991 },
+	{ 280.0, 1.6817, 77.7505 },
+	{ 205.6, 4.2565, 529.6910 },
+	{ 140.5, 3.5297, 137.0330 },
+	{ 98.5, 4.168, 33.680 },
+	{ 51.3, 1.951, 4.453 },
+	{ 68.0, 4.670, 71.813 },
+	{ 41.9, 5.418, 111.430 },
+	{ 41.8, 5.948, 112.915 },
+	{ 30.6, 0.936, 42.586 },
+	/* 23 terms retained, 149 terms dropped, error 0.62" */
+
+	/* neptune b, T^1 */
+	{ 227279.2, 3.8079309, 38.1330356 },
+	{ 1803.1, 1.97576, 76.26607 },
+	{ 1385.7, 4.82556, 36.64856 },
+	{ 1433.3, 3.14159, 0 },
+	{ 1073.3, 6.08054, 39.61751 },
+	{ 147.9, 3.8577, 74.7816 },
+	{ 136.4, 0.4776, 1.4845 },
+	{ 70.3, 6.188, 35.164 },
+	{ 51.9, 5.052, 73.297 },
+	{ 37.3, 4.895, 41.102 },
+	{ 42.6, 0.307, 114.399 },
+	{ 37.1, 5.760, 2.969 },
+	{ 26.4, 5.216, 213.299 },
+	{ 16.9, 4.265, 77.751 },
+	{ 18.7, 0.904, 453.425 },
+	{ 13.0, 6.177, 529.691 },
+	{ 10.5, 1.203, 137.033 },
+	/* 17 terms retained, 65 terms dropped, error 0.18"*T */
+
+	/* neptune b, T^2 */
+	{ 9690.8, 5.57124, 38.13304 },
+	{ 78.8, 3.627, 76.266 },
+	{ 71.5, 0.455, 36.649 },
+	{ 58.6, 3.142, 0 },
+	{ 29.9, 1.607, 39.618 },
+	{ 6.5, 5.61, 74.78 },
+	{ 5.8, 2.25, 1.48 },
+	{ 4.3, 1.68, 35.16 },
+	{ 3.5, 2.39, 114.40 },
+	{ 2.6, 0.65, 73.30 },
+	/* 10 terms retained, 15 terms dropped, error 0.036"*T^2 */
+
+	/* neptune b, T^3 */
+	{ 273.4, 1.0169, 38.1330 },
+	{ 2.3, 2.37, 36.65 },
+	{ 2.0, 5.33, 76.27 },
+	{ 2.4, 0, 0 },
+	{ 0.5, 3.22, 39.62 },
+	/* 5 terms retained, 4 terms dropped, error 0.0054"*T^3 */
+
+	/* neptune b, T^4 */
+	{ 5.7, 2.67, 38.13 },
+	/* 1 terms retained, 0 terms dropped, error 0.033"*T^4 */
+
+	/* neptune b, T^5 */
+	{ 0.1, 4.71, 38.13 },
+	/* 1 terms retained, 0 terms dropped, error 0.00066"*T^5 */
+	/* end neptune b */
+
+	/* neptune r, T^0 */
+	{ 3007013206.1, 0, 0 },
+	{ 27062259.5, 1.329994589, 38.133035638 },
+	{ 1691764.3, 3.25186139, 36.64856293 },
+	{ 807830.7, 5.1859284, 1.4844727 },
+	{ 537760.6, 4.5211390, 35.1640902 },
+	{ 495725.6, 1.5710565, 491.5579295 },
+	{ 274572.0, 1.8455226, 175.1660598 },
+	{ 135134.1, 3.3722061, 39.6175083 },
+	{ 121801.8, 5.7975444, 76.2660713 },
+	{ 100895.4, 0.3770275, 73.2971259 },
+	{ 69791.7, 3.796172, 2.968945 },
+	{ 46687.8, 5.749378, 33.679618 },
+	{ 24593.8, 0.508017, 109.945689 },
+	{ 16939.2, 1.594222, 71.812653 },
+	{ 14229.7, 1.077861, 74.781599 },
+	{ 12011.8, 1.920621, 1021.248895 },
+	{ 8394.7, 0.67817, 146.59425 },
+	{ 7571.8, 1.07149, 388.46516 },
+	{ 5720.9, 2.59060, 4.45342 },
+	{ 4839.7, 1.90686, 41.10198 },
+	{ 4483.5, 2.90573, 529.69097 },
+	{ 4270.2, 3.41344, 453.42489 },
+	{ 4353.8, 0.67986, 32.19514 },
+	{ 4420.8, 1.74994, 108.46122 },
+	{ 2881.1, 1.98600, 137.03302 },
+	{ 2635.5, 3.09756, 213.29910 },
+	{ 3380.9, 0.84811, 183.24281 },
+	{ 2878.9, 3.67416, 350.33212 },
+	{ 2306.3, 2.80963, 70.32818 },
+	{ 2530.1, 5.79840, 490.07346 },
+	{ 2523.1, 0.48631, 493.04240 },
+	{ 2087.3, 0.61858, 33.94025 },
+	{ 1976.5, 5.11703, 168.05251 },
+	{ 1905.3, 1.72186, 182.27961 },
+	{ 1654.0, 1.92783, 145.10978 },
+	{ 1435.1, 1.70005, 484.44438 },
+	{ 1403.0, 4.58914, 498.67148 },
+	{ 1499.2, 1.01623, 219.89138 },
+	{ 1398.9, 0.76220, 176.65053 },
+	{ 1403.4, 6.07659, 173.68159 },
+	{ 1128.6, 5.96661, 9.56123 },
+	{ 1228.3, 1.59881, 77.75054 },
+	{ 835.4, 3.9707, 114.3991 },
+	{ 811.2, 3.0026, 46.2098 },
+	{ 731.9, 2.1045, 181.7583 },
+	{ 615.8, 2.9787, 106.9767 },
+	{ 704.8, 1.1874, 256.5399 },
+	{ 502.0, 1.3866, 5.9379 },
+	{ 530.4, 4.2406, 111.4302 },
+	{ 437.1, 2.2703, 1550.9399 },
+	{ 400.2, 1.2561, 8.0768 },
+	{ 421.0, 1.8908, 30.7107 },
+	{ 382.5, 3.2997, 983.1159 },
+	{ 422.5, 5.5319, 525.4982 },
+	{ 355.4, 2.2785, 218.4069 },
+	{ 280.1, 1.5413, 98.9000 },
+	{ 314.5, 3.9593, 381.3516 },
+	{ 280.6, 4.5424, 44.7253 },
+	{ 267.7, 5.1332, 112.9146 },
+	{ 333.3, 5.7507, 39.0962 },
+	{ 291.6, 4.0240, 68.8437 },
+	{ 321.4, 1.5063, 454.9094 },
+	{ 309.2, 2.8545, 72.0733 },
+	{ 345.1, 1.3591, 293.1885 },
+	{ 307.4, 0.3196, 601.7643 },
+	{ 251.4, 3.5399, 312.1991 },
+	{ 248.2, 3.4108, 37.6118 },
+	{ 306.0, 2.7248, 6244.9428 },
+	{ 293.5, 4.8908, 528.2065 },
+	{ 234.5, 0.5923, 42.5865 },
+	{ 239.6, 3.1644, 143.6253 },
+	{ 214.5, 3.6248, 278.2588 },
+	{ 246.2, 1.0151, 141.2258 },
+	{ 174.1, 5.5501, 567.8240 },
+	{ 163.9, 2.1017, 2.4477 },
+	{ 162.9, 2.4895, 4.1928 },
+	{ 193.5, 1.5843, 138.5175 },
+	{ 155.3, 3.2843, 31.0195 },
+	{ 182.5, 2.4524, 255.0555 },
+	{ 177.8, 4.1477, 10175.1525 },
+	{ 174.4, 1.5304, 329.8371 },
+	{ 137.6, 3.3490, 0.9632 },
+	{ 161.0, 5.1666, 211.8146 },
+	{ 113.5, 4.9629, 148.0787 },
+	{ 128.8, 3.2552, 24.1184 },
+	{ 107.4, 3.2646, 1059.3819 },
+	{ 122.7, 5.3940, 62.2514 },
+	{ 120.5, 3.0805, 184.7273 },
+	{ 99.4, 1.929, 28.572 },
+	{ 97.7, 2.595, 6.592 },
+	{ 124.1, 3.1152, 221.3759 },
+	{ 124.7, 2.9704, 251.4321 },
+	{ 114.3, 0.2504, 594.6507 },
+	{ 111.0, 3.3428, 180.2739 },
+	{ 120.9, 1.9291, 25.6029 },
+	{ 104.7, 0.9488, 395.5787 },
+	{ 109.8, 5.4315, 494.5269 },
+	{ 96.9, 0.862, 1014.135 },
+	{ 98.7, 0.896, 488.589 },
+	{ 89.0, 4.781, 144.147 },
+	{ 107.9, 0.9870, 1124.3417 },
+	{ 97.1, 2.627, 291.704 },
+	{ 75.1, 5.889, 43.241 },
+	{ 93.7, 6.099, 526.722 },
+	{ 94.8, 0.207, 456.394 },
+	{ 70.0, 2.397, 426.598 },
+	{ 77.2, 4.211, 105.492 },
+	{ 89.9, 3.251, 258.024 },
+	{ 69.1, 4.930, 1028.362 },
+	{ 90.7, 1.695, 366.486 },
+	{ 74.2, 3.145, 82.858 },
+	{ 58.0, 0.862, 60.767 },
+	{ 78.7, 1.093, 700.664 },
+	{ 57.2, 0.813, 2.921 },
+	{ 63.4, 4.396, 149.563 },
+	{ 55.7, 3.890, 47.694 },
+	{ 56.4, 5.150, 0.521 },
+	{ 56.2, 5.430, 911.043 },
+	{ 61.7, 6.165, 1019.764 },
+	{ 70.5, 0.081, 40.581 },
+	{ 74.7, 4.859, 186.212 },
+	{ 61.9, 4.787, 11.046 },
+	{ 61.1, 0.837, 1022.733 },
+	{ 61.3, 5.702, 178.135 },
+	{ 52.9, 0.375, 27.087 },
+	{ 56.7, 3.523, 216.922 },
+	{ 48.8, 5.108, 64.960 },
+	{ 63.3, 4.394, 807.950 },
+	{ 64.1, 6.283, 7.114 },
+	{ 46.4, 1.347, 451.940 },
+	{ 60.5, 3.403, 294.673 },
+	{ 46.9, 0.170, 7.422 },
+	{ 56.8, 0.450, 140.002 },
+	{ 55.9, 1.068, 172.197 },
+	{ 53.8, 2.796, 328.353 },
+	{ 43.8, 6.047, 135.549 },
+	{ 49.5, 0.641, 41.054 },
+	{ 54.0, 2.918, 563.631 },
+	{ 43.0, 5.402, 487.365 },
+	{ 51.5, 0.091, 210.330 },
+	{ 41.9, 3.123, 29.226 },
+	{ 47.7, 3.907, 63.736 },
+	{ 41.6, 6.268, 32.716 },
+	{ 41.4, 4.455, 37.170 },
+	{ 40.7, 0.160, 79.235 },
+	{ 48.2, 1.842, 403.134 },
+	{ 36.9, 0.448, 30.056 },
+	{ 47.8, 0.881, 3302.479 },
+	{ 39.5, 3.506, 357.446 },
+	{ 42.1, 0.634, 343.219 },
+	{ 41.3, 1.364, 31.232 },
+	{ 42.6, 3.553, 38.654 },
+	{ 38.9, 5.267, 415.292 },
+	{ 39.0, 5.259, 386.981 },
+	{ 33.7, 5.244, 67.359 },
+	{ 40.9, 3.553, 331.322 },
+	{ 38.8, 1.123, 38.181 },
+	{ 37.5, 6.087, 35.425 },
+	{ 38.8, 4.679, 38.085 },
+	{ 38.2, 6.265, 389.950 },
+	{ 30.0, 4.458, 22.634 },
+	{ 31.4, 0.077, 12.530 },
+	{ 26.3, 4.596, 106.014 },
+	{ 27.5, 5.995, 206.186 },
+	{ 25.2, 4.499, 34.201 },
+	{ 29.0, 3.649, 253.571 },
+	{ 27.2, 4.379, 142.141 },
+	{ 30.6, 1.593, 348.848 },
+	{ 31.5, 1.051, 100.384 },
+	{ 26.3, 3.016, 365.001 },
+	{ 26.5, 3.614, 367.970 },
+	{ 25.5, 2.438, 351.817 },
+	{ 25.7, 2.005, 439.783 },
+	{ 25.4, 4.740, 1474.674 },
+	/* 174 terms retained, 433 terms dropped, error 6.7e-06 a.u. */
+
+	/* neptune r, T^1 */
+	{ 236338.5, 0.7049801, 38.1330356 },
+	{ 13220.3, 3.320155, 1.484473 },
+	{ 8621.9, 6.21629, 35.16409 },
+	{ 2701.7, 1.88141, 39.61751 },
+	{ 2153.2, 5.16874, 76.26607 },
+	{ 2154.7, 2.09431, 2.96895 },
+	{ 1463.9, 1.18417, 33.67962 },
+	{ 1603.2, 0, 0 },
+	{ 1135.8, 3.91891, 36.64856 },
+	{ 897.6, 5.2412, 388.4652 },
+	{ 789.9, 0.5332, 168.0525 },
+	{ 760.0, 0.0205, 182.2796 },
+	{ 607.2, 1.0771, 1021.2489 },
+	{ 571.6, 3.4006, 484.4444 },
+	{ 560.8, 2.8869, 498.6715 },
+	{ 490.2, 3.4683, 137.0330 },
+	{ 264.1, 0.8622, 4.4534 },
+	{ 270.5, 3.2736, 71.8127 },
+	{ 203.5, 2.4182, 32.1951 },
+	{ 155.4, 0.3654, 41.1020 },
+	{ 132.8, 3.6016, 9.5612 },
+	{ 93.6, 0.667, 46.210 },
+	{ 83.3, 3.260, 98.900 },
+	{ 72.2, 4.477, 601.764 },
+	{ 69.0, 1.463, 74.782 },
+	{ 87.0, 5.772, 381.352 },
+	{ 68.7, 4.526, 70.328 },
+	{ 64.7, 3.855, 73.297 },
+	{ 68.4, 3.395, 108.461 },
+	{ 53.4, 5.437, 395.579 },
+	{ 44.5, 3.614, 2.448 },
+	{ 41.2, 4.739, 8.077 },
+	{ 48.3, 1.986, 175.166 },
+	{ 41.7, 4.943, 31.019 },
+	{ 44.1, 1.417, 1550.940 },
+	{ 41.2, 1.420, 490.073 },
+	{ 41.1, 4.863, 493.042 },
+	{ 36.3, 5.308, 312.199 },
+	{ 36.3, 0.382, 77.751 },
+	{ 40.6, 2.272, 529.691 },
+	{ 32.4, 5.911, 5.938 },
+	{ 31.2, 2.705, 1014.135 },
+	{ 32.7, 5.221, 41.054 },
+	{ 36.1, 4.878, 491.558 },
+	{ 30.2, 3.633, 30.711 },
+	{ 30.0, 3.308, 1028.362 },
+	{ 27.0, 1.776, 44.725 },
+	{ 27.8, 4.556, 7.114 },
+	{ 27.5, 0.972, 33.940 },
+	{ 24.9, 3.101, 144.147 },
+	{ 26.0, 2.997, 60.767 },
+	{ 21.4, 4.713, 278.259 },
+	{ 21.3, 0.690, 251.432 },
+	{ 23.7, 5.120, 176.651 },
+	{ 21.4, 0.863, 4.193 },
+	{ 23.4, 1.650, 173.682 },
+	{ 24.2, 3.566, 145.110 },
+	{ 20.2, 5.615, 24.118 },
+	{ 27.0, 4.143, 453.425 },
+	{ 24.0, 1.007, 213.299 },
+	{ 18.3, 1.980, 72.073 },
+	{ 18.3, 6.173, 189.393 },
+	{ 19.2, 4.652, 106.977 },
+	{ 17.6, 1.603, 62.251 },
+	{ 16.5, 1.699, 357.446 },
+	{ 20.1, 3.295, 114.399 },
+	{ 15.4, 4.388, 25.603 },
+	{ 19.2, 2.200, 343.219 },
+	{ 15.1, 3.668, 0.521 },
+	{ 14.0, 0.553, 129.919 },
+	{ 13.4, 5.858, 68.844 },
+	{ 15.4, 4.207, 567.824 },
+	{ 12.7, 3.528, 477.331 },
+	{ 11.7, 5.576, 31.232 },
+	{ 11.5, 0.891, 594.651 },
+	{ 10.5, 4.356, 32.716 },
+	{ 10.8, 5.218, 26.827 },
+	{ 10.1, 1.981, 40.581 },
+	{ 10.5, 5.273, 2.921 },
+	{ 9.2, 0.50, 64.96 },
+	{ 9.2, 0.68, 160.94 },
+	{ 8.7, 5.81, 6.59 },
+	{ 10.1, 4.512, 28.572 },
+	{ 10.4, 5.189, 42.586 },
+	{ 9.9, 3.77, 181.76 },
+	{ 8.3, 2.82, 43.24 },
+	{ 9.8, 1.49, 47.69 },
+	{ 7.6, 4.08, 389.95 },
+	{ 8.0, 2.78, 505.79 },
+	{ 7.4, 2.36, 11.05 },
+	{ 7.3, 1.62, 135.55 },
+	{ 9.5, 0.27, 426.60 },
+	{ 7.2, 0.83, 911.04 },
+	{ 7.0, 1.87, 206.19 },
+	{ 6.9, 0.84, 82.86 },
+	{ 7.9, 1.87, 38.65 },
+	{ 6.7, 3.98, 12.53 },
+	{ 6.4, 0.90, 487.37 },
+	{ 6.7, 1.34, 220.41 },
+	{ 7.7, 5.13, 23.91 },
+	{ 7.1, 6.00, 639.90 },
+	{ 8.3, 3.86, 37.61 },
+	{ 6.4, 2.42, 1059.38 },
+	{ 6.8, 1.97, 45.25 },
+	{ 6.4, 4.08, 35.69 },
+	{ 6.4, 0.65, 350.33 },
+	/* 106 terms retained, 144 terms dropped, error 1.3e-06 a.u.*T */
+
+	/* neptune r, T^2 */
+	{ 4247.4, 5.89911, 38.13304 },
+	{ 217.6, 0.3458, 1.4845 },
+	{ 163.0, 2.2387, 168.0525 },
+	{ 156.3, 4.5941, 182.2796 },
+	{ 117.9, 5.1030, 484.4444 },
+	{ 112.4, 1.1900, 498.6715 },
+	{ 127.1, 2.8479, 35.1641 },
+	{ 99.5, 3.416, 175.166 },
+	{ 64.8, 3.462, 388.465 },
+	{ 77.3, 0.017, 491.558 },
+	{ 49.5, 4.070, 76.266 },
+	{ 39.3, 6.095, 1021.249 },
+	{ 36.5, 5.171, 137.033 },
+	{ 37.1, 5.973, 2.969 },
+	{ 30.5, 3.583, 33.680 },
+	{ 21.1, 0.768, 36.649 },
+	{ 13.9, 3.592, 395.579 },
+	{ 13.1, 5.093, 98.900 },
+	{ 11.4, 1.181, 381.352 },
+	{ 9.1, 2.35, 601.76 },
+	{ 8.5, 5.25, 2.45 },
+	{ 8.1, 4.96, 4.45 },
+	{ 7.4, 4.47, 189.39 },
+	{ 7.2, 1.92, 9.56 },
+	{ 7.3, 1.66, 1028.36 },
+	{ 8.1, 5.84, 220.41 },
+	{ 9.7, 0, 0 },
+	{ 6.6, 0.69, 144.15 },
+	{ 7.8, 1.14, 1059.38 },
+	{ 5.7, 6.25, 74.78 },
+	{ 5.6, 5.23, 46.21 },
+	{ 5.5, 4.59, 1014.14 },
+	{ 5.2, 5.23, 477.33 },
+	{ 5.5, 3.50, 183.76 },
+	{ 4.9, 3.53, 39.62 },
+	{ 4.8, 2.08, 41.10 },
+	{ 5.1, 0.20, 166.57 },
+	{ 4.8, 1.18, 169.54 },
+	{ 4.7, 1.51, 73.30 },
+	{ 6.1, 6.18, 71.81 },
+	{ 4.6, 3.92, 587.54 },
+	{ 5.8, 2.24, 176.65 },
+	{ 4.5, 2.84, 7.11 },
+	{ 4.3, 0.52, 446.31 },
+	{ 3.9, 0.26, 1550.94 },
+	{ 4.5, 3.01, 129.92 },
+	{ 3.7, 2.38, 160.94 },
+	{ 3.8, 3.79, 111.43 },
+	{ 4.1, 1.70, 983.12 },
+	{ 3.3, 1.08, 505.79 },
+	{ 4.0, 0.31, 494.74 },
+	{ 4.0, 5.97, 488.38 },
+	{ 3.9, 4.86, 60.77 },
+	{ 3.0, 2.02, 822.18 },
+	{ 4.0, 1.08, 374.24 },
+	{ 3.8, 5.23, 350.33 },
+	{ 2.8, 6.18, 704.86 },
+	{ 3.5, 0.79, 274.07 },
+	{ 2.8, 1.32, 386.98 },
+	{ 2.8, 5.37, 251.43 },
+	{ 3.1, 5.13, 426.60 },
+	{ 3.3, 5.61, 1124.34 },
+	{ 2.6, 0.68, 312.20 },
+	{ 2.6, 3.56, 567.82 },
+	{ 2.6, 1.46, 1035.48 },
+	{ 2.5, 5.19, 1227.43 },
+	{ 2.5, 4.12, 171.23 },
+	{ 2.5, 2.72, 179.10 },
+	{ 2.3, 0.96, 1019.76 },
+	{ 2.5, 0.70, 707.78 },
+	{ 2.5, 4.60, 693.55 },
+	{ 2.3, 0.74, 976.00 },
+	/* 72 terms retained, 0 terms dropped, error 3.8e-07 a.u.*T^2 */
+
+	/* neptune r, T^3 */
+	{ 166.3, 4.5524, 38.1330 },
+	{ 22.4, 3.948, 168.053 },
+	{ 21.3, 2.863, 182.280 },
+	{ 16.2, 0.542, 484.444 },
+	{ 15.6, 5.757, 498.671 },
+	{ 11.9, 4.403, 1.484 },
+	{ 6.4, 5.19, 31.02 },
+	{ 3.7, 5.91, 1007.02 },
+	{ 3.7, 1.63, 388.47 },
+	{ 3.2, 0.70, 1558.05 },
+	{ 3.2, 1.88, 522.58 },
+	{ 3.3, 2.94, 76.27 },
+	{ 2.7, 1.87, 402.69 },
+	{ 3.2, 0.79, 536.80 },
+	{ 2.6, 5.77, 343.22 },
+	{ 2.6, 4.65, 500.16 },
+	{ 2.5, 4.79, 482.96 },
+	{ 2.5, 1.73, 395.58 },
+	{ 2.7, 2.21, 446.31 },
+	{ 2.4, 5.77, 485.93 },
+	{ 2.9, 6.20, 815.06 },
+	{ 2.3, 3.67, 497.19 },
+	/* 22 terms retained, 0 terms dropped, error 2.2e-07 a.u.*T^3 */
+
+	/* neptune r, T^4 */
+	{ 4.2, 2.40, 477.33 },
+	{ 4.3, 0.10, 395.58 },
+	{ 3.5, 4.78, 1028.36 },
+	{ 3.2, 3.88, 505.79 },
+	{ 3.0, 1.04, 189.39 },
+	{ 2.3, 1.11, 182.28 },
+	{ 2.3, 5.68, 168.05 },
+	/* 7 terms retained, 0 terms dropped, error 1.3e-07 a.u.*T^4 */
+	/* end neptune */
+};
+
+int vn_neptune[][3] = {
+	/* addresses for neptune l, b, r  */
+	/* T^0 */ { 0, 125, 182, },
+	/* T^1 */ { 58, 148, 356, },
+	/* T^2 */ { 90, 165, 462, },
+	/* T^3 */ { 112, 175, 534, },
+	/* T^4 */ { 122, 180, 556, },
+	/* T^5 */ { 124, 181, 563, },
+	/* end */ { 125, 182, 0, },
+	/* termination */ { 0, }
+};
+
+/*  version d4 (lbr)       
+ *  heliocentric dynamical ecliptic and equinox of the date
+ */
+
+double vx_saturn[][3] = {
+	/* saturn l, T^0 */
+	{ 87401354.0, 0, 0 },
+	{ 11107659.8, 3.962050902, 213.299095438 },
+	{ 1414151.0, 4.58581516, 7.11354700 },
+	{ 398379.4, 0.5211203, 206.1855484 },
+	{ 350769.2, 3.3032990, 426.5981909 },
+	{ 206816.3, 0.2465837, 103.0927742 },
+	{ 79271.3, 3.840071, 220.412642 },
+	{ 23990.3, 4.669769, 110.206321 },
+	{ 16573.6, 0.437191, 419.484644 },
+	{ 14907.0, 5.769033, 316.391870 },
+	{ 15820.3, 0.938090, 632.783739 },
+	{ 14609.6, 1.565186, 3.932153 },
+	{ 13160.3, 4.448912, 14.227094 },
+	{ 15053.5, 2.716700, 639.897286 },
+	{ 13005.3, 5.981191, 11.045700 },
+	{ 10725.1, 3.129396, 202.253395 },
+	{ 5863.2, 0.23657, 529.69097 },
+	{ 5227.8, 4.20783, 3.18139 },
+	{ 6126.3, 1.76328, 277.03499 },
+	{ 5019.7, 3.17788, 433.71174 },
+	{ 4592.5, 0.61976, 199.07200 },
+	{ 4005.9, 2.24480, 63.73590 },
+	{ 2953.8, 0.98280, 95.97923 },
+	{ 3873.7, 3.22283, 138.51750 },
+	{ 2461.2, 2.03164, 735.87651 },
+	{ 3269.5, 0.77492, 949.17561 },
+	{ 1758.1, 3.26581, 522.57742 },
+	{ 1640.2, 5.50505, 846.08283 },
+	{ 1391.3, 4.02332, 323.50542 },
+	{ 1580.6, 4.37266, 309.27832 },
+	{ 1123.5, 2.83727, 415.55249 },
+	{ 1017.3, 3.71698, 227.52619 },
+	{ 848.6, 3.1915, 209.3669 },
+	{ 1087.2, 4.18343, 2.44768 },
+	{ 956.8, 0.5074, 1265.5675 },
+	{ 789.2, 5.0075, 0.9632 },
+	{ 687.0, 1.7471, 1052.2684 },
+	{ 654.5, 1.5989, 0.0482 },
+	{ 748.8, 2.1440, 853.1964 },
+	{ 634.0, 2.2989, 412.3711 },
+	{ 743.6, 5.2528, 224.3448 },
+	{ 852.7, 3.4214, 175.1661 },
+	{ 579.9, 3.0926, 74.7816 },
+	{ 624.9, 0.9705, 210.1177 },
+	{ 529.9, 4.4494, 117.3199 },
+	{ 542.6, 1.5182, 9.5612 },
+	{ 474.3, 5.4753, 742.9901 },
+	{ 448.5, 1.2899, 127.4718 },
+	{ 546.4, 2.1268, 350.3321 },
+	{ 478.1, 2.9649, 137.0330 },
+	{ 354.9, 3.0129, 838.9693 },
+	{ 451.8, 1.0444, 490.3341 },
+	{ 347.4, 1.5393, 340.7709 },
+	{ 343.5, 0.2460, 0.5213 },
+	{ 309.0, 3.4949, 216.4805 },
+	{ 322.2, 0.9614, 203.7379 },
+	{ 372.3, 2.2782, 217.2312 },
+	{ 321.5, 2.5718, 647.0108 },
+	{ 330.2, 0.2472, 1581.9593 },
+	{ 249.1, 1.4701, 1368.6603 },
+	{ 286.7, 2.3704, 351.8166 },
+	{ 220.2, 4.2042, 200.7689 },
+	{ 277.8, 0.4002, 211.8146 },
+	{ 204.5, 6.0108, 265.9893 },
+	{ 207.7, 0.4835, 1162.4747 },
+	{ 208.7, 1.3452, 625.6702 },
+	{ 182.5, 5.4912, 2.9208 },
+	{ 226.6, 4.9100, 12.5302 },
+	{ 207.7, 1.2830, 39.3569 },
+	{ 173.9, 1.8631, 0.7508 },
+	{ 184.7, 3.5034, 149.5632 },
+	{ 183.5, 0.9725, 4.1928 },
+	{ 146.1, 6.2310, 195.1398 },
+	{ 164.5, 0.4401, 5.4166 },
+	{ 147.5, 1.5353, 5.6291 },
+	{ 139.7, 4.2945, 21.3406 },
+	{ 131.3, 4.0683, 10.2949 },
+	{ 117.3, 2.6792, 1155.3612 },
+	{ 149.3, 5.7359, 52.6902 },
+	{ 122.4, 1.9759, 4.6659 },
+	{ 113.7, 5.5943, 1059.3819 },
+	{ 102.7, 1.1975, 1685.0521 },
+	{ 118.2, 5.3407, 554.0700 },
+	{ 109.3, 3.4381, 536.8045 },
+	{ 110.4, 0.1660, 1.4845 },
+	{ 125.0, 6.2774, 1898.3512 },
+	{ 89.9, 5.804, 114.138 },
+	{ 104.0, 2.1921, 88.8657 },
+	{ 112.4, 1.1050, 191.2077 },
+	{ 106.6, 4.0116, 956.2892 },
+	{ 91.4, 1.875, 38.133 },
+	{ 83.8, 5.488, 0.112 },
+	{ 83.5, 2.290, 628.852 },
+	{ 97.0, 4.537, 302.165 },
+	{ 100.6, 4.9651, 269.9214 },
+	{ 75.5, 2.180, 728.763 },
+	{ 96.3, 2.833, 275.551 },
+	{ 82.4, 3.055, 440.825 },
+	{ 73.9, 5.089, 1375.774 },
+	{ 71.6, 5.109, 65.220 },
+	{ 70.4, 4.868, 0.212 },
+	{ 69.8, 3.710, 14.978 },
+	{ 88.8, 3.863, 278.519 },
+	{ 68.1, 0.734, 1478.867 },
+	{ 66.5, 0.027, 70.849 },
+	{ 65.7, 2.022, 142.450 },
+	{ 75.8, 1.614, 284.149 },
+	{ 63.2, 3.495, 479.288 },
+	{ 62.5, 2.587, 422.666 },
+	{ 69.3, 3.440, 515.464 },
+	{ 79.0, 4.452, 35.425 },
+	{ 63.7, 3.317, 62.251 },
+	{ 52.9, 5.514, 0.261 },
+	{ 53.0, 3.185, 8.077 },
+	{ 54.5, 2.457, 22.091 },
+	{ 50.5, 4.267, 99.161 },
+	{ 55.2, 0.968, 942.062 },
+	{ 49.3, 2.386, 1471.753 },
+	{ 47.2, 2.025, 312.199 },
+	{ 61.1, 1.503, 210.851 },
+	{ 45.1, 0.931, 2001.444 },
+	{ 60.6, 2.687, 388.465 },
+	{ 43.5, 2.526, 288.081 },
+	{ 42.5, 3.818, 330.619 },
+	{ 39.9, 5.714, 408.439 },
+	{ 50.1, 6.032, 2214.743 },
+	{ 45.9, 0.542, 212.336 },
+	{ 54.2, 0.782, 191.958 },
+	{ 47.0, 4.599, 437.644 },
+	{ 42.4, 1.901, 430.530 },
+	{ 39.7, 1.633, 1066.495 },
+	{ 36.3, 0.848, 213.347 },
+	{ 35.5, 4.186, 215.747 },
+	{ 36.3, 3.933, 213.251 },
+	{ 38.0, 0.313, 423.417 },
+	{ 44.7, 1.125, 6.150 },
+	{ 37.9, 1.198, 2.708 },
+	{ 43.4, 1.374, 563.631 },
+	{ 43.8, 3.930, 525.498 },
+	{ 34.8, 1.016, 203.004 },
+	{ 31.8, 1.693, 0.160 },
+	{ 30.9, 6.135, 417.037 },
+	{ 36.4, 6.006, 18.159 },
+	{ 29.0, 1.197, 404.507 },
+	{ 32.8, 0.536, 107.025 },
+	{ 30.4, 0.723, 222.860 },
+	{ 32.6, 0.812, 1795.258 },
+	{ 37.8, 3.697, 1272.681 },
+	{ 27.7, 1.457, 7.162 },
+	{ 27.2, 1.897, 1045.155 },
+	{ 37.7, 4.520, 24.379 },
+	{ 34.9, 4.461, 214.262 },
+	{ 32.6, 0.664, 692.587 },
+	{ 30.3, 5.304, 33.940 },
+	{ 27.5, 6.227, 1.272 },
+	{ 26.7, 4.567, 7.065 },
+	{ 31.7, 5.498, 56.622 },
+	{ 28.1, 5.644, 128.956 },
+	{ 32.0, 5.223, 92.047 },
+	{ 27.0, 0.067, 205.222 },
+	{ 31.8, 5.592, 6069.777 },
+	{ 31.0, 0.372, 703.633 },
+	{ 29.4, 0.147, 131.404 },
+	{ 26.2, 5.413, 140.002 },
+	{ 25.7, 4.360, 32.243 },
+	/* 165 terms retained, 987 terms dropped, error 1.4" */
+
+	/* saturn l, T^1 */
+	{ 21354295596.0, 0, 0 },
+	{ 1296855.0, 1.82820545, 213.29909544 },
+	{ 564347.6, 2.8850014, 7.1135470 },
+	{ 98323.0, 1.080701, 426.598191 },
+	{ 107678.8, 2.2776991, 206.1855484 },
+	{ 40254.6, 2.041283, 220.412642 },
+	{ 19941.7, 1.279547, 103.092774 },
+	{ 10511.7, 2.748804, 14.227094 },
+	{ 6939.2, 0.40493, 639.89729 },
+	{ 4803.3, 2.44194, 419.48464 },
+	{ 4056.3, 2.92167, 110.20632 },
+	{ 3768.6, 3.64966, 3.93215 },
+	{ 3384.7, 2.41694, 3.18139 },
+	{ 3302.2, 1.26256, 433.71174 },
+	{ 3071.4, 2.32739, 199.07200 },
+	{ 1953.0, 3.56395, 11.04570 },
+	{ 1249.3, 2.62804, 95.97923 },
+	{ 921.7, 1.9609, 227.5262 },
+	{ 705.6, 4.4169, 529.6910 },
+	{ 649.7, 6.1742, 202.2534 },
+	{ 627.6, 6.1109, 309.2783 },
+	{ 486.8, 6.0400, 853.1964 },
+	{ 468.4, 4.6171, 63.7359 },
+	{ 478.5, 4.9878, 522.5774 },
+	{ 417.0, 2.1171, 323.5054 },
+	{ 407.6, 1.2995, 209.3669 },
+	{ 343.8, 3.9585, 412.3711 },
+	{ 339.7, 3.6340, 316.3919 },
+	{ 335.9, 3.7717, 735.8765 },
+	{ 331.9, 2.8608, 210.1177 },
+	{ 352.5, 2.3171, 632.7837 },
+	{ 289.4, 2.7326, 117.3199 },
+	{ 265.8, 0.5434, 647.0108 },
+	{ 230.5, 1.6443, 216.4805 },
+	{ 280.9, 5.7440, 2.4477 },
+	{ 191.7, 2.9651, 224.3448 },
+	{ 172.9, 4.0770, 846.0828 },
+	{ 167.1, 2.5975, 21.3406 },
+	{ 136.3, 2.2858, 10.2949 },
+	{ 131.4, 3.4411, 742.9901 },
+	{ 127.8, 4.0953, 217.2312 },
+	{ 108.9, 6.1614, 415.5525 },
+	{ 93.9, 3.484, 1052.268 },
+	{ 92.5, 3.948, 88.866 },
+	{ 97.6, 4.728, 838.969 },
+	{ 86.6, 1.220, 440.825 },
+	{ 83.5, 3.113, 625.670 },
+	{ 77.6, 6.244, 302.165 },
+	{ 61.6, 1.828, 195.140 },
+	{ 61.9, 4.293, 127.472 },
+	{ 67.1, 0.290, 4.666 },
+	{ 56.9, 5.019, 137.033 },
+	{ 54.2, 5.126, 490.334 },
+	{ 54.6, 0.284, 74.782 },
+	{ 51.4, 1.458, 536.805 },
+	{ 65.8, 5.648, 9.561 },
+	{ 57.8, 2.476, 191.958 },
+	{ 44.4, 2.709, 5.417 },
+	{ 46.8, 1.177, 149.563 },
+	{ 40.4, 3.889, 728.763 },
+	{ 37.8, 2.534, 12.530 },
+	{ 46.6, 5.148, 515.464 },
+	{ 45.9, 2.232, 956.289 },
+	{ 40.4, 0.413, 269.921 },
+	{ 37.2, 3.782, 2.921 },
+	{ 33.8, 3.211, 1368.660 },
+	{ 38.0, 0.647, 422.666 },
+	{ 32.9, 0.301, 351.817 },
+	{ 33.0, 5.430, 1066.495 },
+	{ 30.3, 2.841, 203.004 },
+	{ 35.1, 6.084, 5.629 },
+	{ 29.7, 3.391, 1059.382 },
+	{ 33.2, 4.641, 277.035 },
+	{ 31.9, 4.386, 1155.361 },
+	{ 28.9, 2.026, 330.619 },
+	{ 28.3, 2.742, 265.989 },
+	{ 30.1, 6.187, 284.149 },
+	{ 31.3, 2.435, 52.690 },
+	{ 26.5, 4.512, 340.771 },
+	{ 22.0, 5.144, 4.193 },
+	{ 22.2, 1.965, 203.738 },
+	{ 20.8, 6.160, 860.310 },
+	{ 21.7, 2.676, 942.062 },
+	{ 22.6, 5.886, 210.851 },
+	{ 19.8, 2.313, 437.644 },
+	{ 19.4, 4.766, 70.849 },
+	{ 19.3, 4.102, 18.159 },
+	{ 22.7, 4.137, 191.208 },
+	{ 18.2, 0.903, 429.780 },
+	{ 17.7, 1.850, 234.640 },
+	{ 17.5, 2.447, 423.417 },
+	{ 15.4, 4.238, 1162.475 },
+	{ 14.6, 3.597, 1045.155 },
+	{ 14.1, 2.943, 1685.052 },
+	{ 16.3, 4.057, 949.176 },
+	{ 13.3, 6.245, 38.133 },
+	{ 15.9, 1.064, 56.622 },
+	{ 14.1, 1.435, 408.439 },
+	{ 13.1, 5.758, 138.517 },
+	{ 15.8, 5.594, 6.150 },
+	{ 15.0, 5.772, 22.091 },
+	{ 16.0, 1.939, 1272.681 },
+	{ 16.8, 5.967, 628.852 },
+	{ 12.8, 4.247, 405.258 },
+	{ 13.6, 4.099, 1471.753 },
+	{ 15.1, 0.741, 200.769 },
+	{ 11.0, 1.550, 223.594 },
+	{ 11.7, 1.812, 124.433 },
+	{ 10.3, 3.468, 1375.774 },
+	{ 12.1, 1.857, 131.404 },
+	{ 10.1, 2.382, 107.025 },
+	{ 9.9, 3.95, 430.53 },
+	{ 9.8, 2.55, 99.91 },
+	{ 10.6, 5.367, 215.747 },
+	{ 12.1, 4.845, 831.856 },
+	{ 10.2, 6.077, 32.243 },
+	{ 9.2, 3.65, 142.45 },
+	{ 9.0, 1.24, 106.27 },
+	{ 9.3, 5.81, 7.16 },
+	{ 9.7, 1.39, 145.63 },
+	{ 8.4, 4.42, 703.63 },
+	{ 8.4, 5.64, 62.25 },
+	{ 8.2, 2.42, 1258.45 },
+	{ 7.8, 0.53, 654.12 },
+	{ 7.6, 3.75, 312.20 },
+	{ 7.2, 0.28, 0.75 },
+	{ 8.2, 6.22, 14.98 },
+	{ 7.1, 0.53, 388.47 },
+	{ 6.6, 3.49, 35.42 },
+	{ 9.0, 4.95, 208.63 },
+	{ 9.0, 0.08, 288.08 },
+	{ 6.4, 3.33, 1361.55 },
+	{ 6.5, 2.89, 114.14 },
+	{ 6.7, 0.24, 8.08 },
+	{ 7.3, 4.85, 222.86 },
+	{ 6.3, 3.81, 1788.14 },
+	{ 6.9, 2.05, 99.16 },
+	{ 6.6, 5.83, 483.22 },
+	/* 138 terms retained, 504 terms dropped, error 0.32"*T */
+
+	/* saturn l, T^2 */
+	{ 116441.2, 1.1798785, 7.1135470 },
+	{ 91920.8, 0.074253, 213.299095 },
+	{ 90592.3, 0, 0 },
+	{ 15276.9, 4.064920, 206.185548 },
+	{ 10631.4, 0.257783, 220.412642 },
+	{ 10605.0, 5.409636, 426.598191 },
+	{ 4265.4, 1.04596, 14.22709 },
+	{ 1215.5, 2.91860, 103.09277 },
+	{ 1164.7, 4.60942, 639.89729 },
+	{ 1082.0, 5.69130, 433.71174 },
+	{ 1020.1, 0.63369, 3.18139 },
+	{ 1044.8, 4.04206, 199.07200 },
+	{ 633.6, 4.3883, 419.4846 },
+	{ 549.3, 5.5730, 3.9322 },
+	{ 456.9, 1.2684, 110.2063 },
+	{ 425.1, 0.2094, 227.5262 },
+	{ 273.7, 4.2884, 95.9792 },
+	{ 161.6, 1.3814, 11.0457 },
+	{ 129.5, 1.5659, 309.2783 },
+	{ 117.0, 3.8812, 853.1964 },
+	{ 105.4, 4.9000, 647.0108 },
+	{ 101.0, 0.8927, 21.3406 },
+	{ 95.2, 5.626, 412.371 },
+	{ 81.9, 1.025, 117.320 },
+	{ 74.9, 4.762, 210.118 },
+	{ 82.7, 6.050, 216.480 },
+	{ 95.7, 2.911, 316.392 },
+	{ 63.7, 0.352, 323.505 },
+	{ 84.9, 5.735, 209.367 },
+	{ 60.6, 4.875, 632.784 },
+	{ 66.5, 0.483, 10.295 },
+	{ 67.2, 0.456, 522.577 },
+	{ 53.3, 2.747, 529.691 },
+	{ 45.8, 5.693, 440.825 },
+	{ 45.3, 1.669, 202.253 },
+	{ 42.3, 5.708, 88.866 },
+	{ 32.1, 0.071, 63.736 },
+	{ 31.6, 1.672, 302.165 },
+	{ 31.1, 4.164, 191.958 },
+	{ 24.6, 5.656, 735.877 },
+	{ 26.6, 0.833, 224.345 },
+	{ 20.1, 5.944, 217.231 },
+	{ 17.5, 4.900, 625.670 },
+	{ 17.1, 1.626, 742.990 },
+	{ 13.7, 3.765, 195.140 },
+	{ 12.2, 4.718, 203.004 },
+	{ 11.9, 0.126, 234.640 },
+	{ 16.0, 0.579, 515.464 },
+	{ 11.2, 5.922, 536.805 },
+	{ 14.1, 0.207, 838.969 },
+	{ 11.0, 5.602, 728.763 },
+	{ 11.7, 3.121, 846.083 },
+	{ 10.0, 4.155, 860.310 },
+	{ 10.6, 3.203, 1066.495 },
+	{ 10.1, 0.257, 330.619 },
+	{ 9.5, 0.46, 956.29 },
+	{ 10.2, 4.987, 422.666 },
+	{ 8.3, 2.14, 269.92 },
+	{ 7.2, 5.40, 1052.27 },
+	{ 7.7, 5.25, 429.78 },
+	{ 6.4, 4.46, 284.15 },
+	{ 5.9, 5.41, 149.56 },
+	{ 7.5, 4.03, 9.56 },
+	{ 5.8, 4.29, 415.55 },
+	{ 6.1, 5.93, 405.26 },
+	{ 5.7, 0.02, 124.43 },
+	{ 5.7, 6.02, 223.59 },
+	{ 4.8, 4.93, 654.12 },
+	{ 4.7, 2.27, 18.16 },
+	{ 4.5, 4.41, 942.06 },
+	{ 5.6, 0.30, 127.47 },
+	{ 5.5, 5.54, 949.18 },
+	{ 4.1, 4.69, 74.78 },
+	{ 4.1, 5.31, 1045.15 },
+	{ 4.2, 2.89, 56.62 },
+	{ 4.9, 3.20, 277.03 },
+	{ 3.9, 3.30, 490.33 },
+	{ 3.9, 6.10, 81.75 },
+	{ 3.8, 4.93, 52.69 },
+	{ 4.6, 6.14, 1155.36 },
+	{ 3.7, 0.41, 137.03 },
+	{ 3.4, 4.29, 99.91 },
+	{ 3.6, 0.20, 1272.68 },
+	{ 3.9, 0.37, 12.53 },
+	{ 3.2, 1.57, 1059.38 },
+	{ 4.1, 0.29, 831.86 },
+	{ 3.7, 0.15, 437.64 },
+	{ 2.9, 3.13, 70.85 },
+	{ 2.8, 0.33, 191.21 },
+	{ 2.7, 1.88, 295.05 },
+	{ 3.5, 4.77, 423.42 },
+	{ 2.6, 5.15, 1368.66 },
+	{ 2.5, 3.90, 210.85 },
+	{ 2.5, 1.59, 32.24 },
+	{ 2.6, 3.59, 131.40 },
+	{ 2.3, 4.77, 351.82 },
+	{ 2.4, 5.83, 106.27 },
+	{ 2.2, 5.98, 6062.66 },
+	{ 2.2, 2.06, 6076.89 },
+	{ 2.2, 5.95, 145.63 },
+	{ 2.7, 3.38, 408.44 },
+	{ 2.3, 3.14, 22.09 },
+	{ 2.1, 1.12, 9992.87 },
+	{ 2.1, 3.48, 10007.10 },
+	{ 2.6, 5.12, 265.99 },
+	{ 1.8, 4.15, 1258.45 },
+	{ 1.8, 5.05, 1361.55 },
+	{ 1.8, 4.14, 107.02 },
+	{ 1.9, 4.52, 138.52 },
+	{ 1.7, 1.36, 231.46 },
+	{ 2.0, 5.87, 1471.75 },
+	{ 2.1, 5.23, 1265.57 },
+	{ 1.6, 5.62, 447.94 },
+	{ 1.6, 3.75, 628.85 },
+	{ 1.7, 6.24, 1148.25 },
+	/* 115 terms retained, 206 terms dropped, error 0.074"*T^2 */
+
+	/* saturn l, T^3 */
+	{ 16038.7, 5.739454, 7.113547 },
+	{ 4249.8, 4.58540, 213.29910 },
+	{ 1906.5, 4.76082, 220.41264 },
+	{ 1465.7, 5.91327, 206.18555 },
+	{ 1162.0, 5.61973, 14.22709 },
+	{ 1066.6, 3.60817, 426.59819 },
+	{ 239.4, 3.8609, 433.7117 },
+	{ 237.0, 5.7683, 199.0720 },
+	{ 165.6, 5.1164, 3.1814 },
+	{ 131.4, 4.7433, 227.5262 },
+	{ 151.4, 2.7359, 639.8973 },
+	{ 61.6, 4.743, 103.093 },
+	{ 63.4, 0.229, 419.485 },
+	{ 40.4, 5.473, 21.341 },
+	{ 40.2, 5.964, 95.979 },
+	{ 38.7, 5.834, 110.206 },
+	{ 28.0, 3.012, 647.011 },
+	{ 25.0, 0.988, 3.932 },
+	{ 18.1, 1.025, 412.371 },
+	{ 17.9, 3.319, 309.278 },
+	{ 16.2, 3.898, 440.825 },
+	{ 15.8, 5.617, 117.320 },
+	{ 19.0, 1.916, 853.196 },
+	{ 18.3, 4.967, 10.295 },
+	{ 12.9, 1.181, 88.866 },
+	{ 17.9, 4.204, 216.480 },
+	{ 11.5, 5.575, 11.046 },
+	{ 10.5, 5.929, 191.958 },
+	{ 10.4, 3.948, 209.367 },
+	{ 8.7, 3.39, 302.16 },
+	{ 7.6, 4.88, 323.51 },
+	{ 6.7, 0.38, 632.78 },
+	{ 5.9, 1.06, 210.12 },
+	{ 5.4, 4.64, 234.64 },
+	{ 6.3, 2.25, 522.58 },
+	{ 3.6, 2.31, 515.46 },
+	{ 3.2, 2.20, 860.31 },
+	{ 3.7, 3.14, 0 },
+	{ 2.6, 4.93, 224.34 },
+	{ 2.5, 0.42, 625.67 },
+	{ 2.2, 3.20, 202.25 },
+	{ 2.4, 4.77, 330.62 },
+	{ 2.9, 0.59, 529.69 },
+	{ 2.0, 4.40, 124.43 },
+	{ 2.2, 1.35, 405.26 },
+	{ 2.3, 3.35, 429.78 },
+	{ 2.0, 3.07, 654.12 },
+	{ 2.0, 1.03, 728.76 },
+	{ 1.9, 3.09, 422.67 },
+	{ 1.8, 4.15, 536.80 },
+	{ 2.2, 1.19, 1066.50 },
+	{ 2.1, 4.16, 223.59 },
+	{ 1.5, 0.38, 316.39 },
+	{ 1.7, 5.83, 195.14 },
+	{ 1.5, 1.58, 81.75 },
+	{ 1.6, 6.04, 742.99 },
+	{ 1.3, 1.66, 63.74 },
+	{ 1.3, 5.02, 956.29 },
+	{ 1.4, 2.11, 838.97 },
+	{ 1.2, 3.88, 269.92 },
+	{ 1.0, 3.73, 295.05 },
+	{ 1.3, 1.38, 735.88 },
+	{ 1.3, 2.33, 217.23 },
+	{ 0.9, 2.76, 284.15 },
+	{ 0.9, 0.71, 846.08 },
+	{ 0.9, 3.84, 447.94 },
+	{ 0.9, 3.31, 18.16 },
+	{ 0.8, 4.71, 56.62 },
+	{ 0.9, 2.02, 831.86 },
+	{ 0.8, 0.80, 1045.15 },
+	{ 0.7, 4.27, 437.64 },
+	{ 0.7, 6.18, 942.06 },
+	{ 0.8, 2.41, 203.00 },
+	{ 0.7, 1.65, 423.42 },
+	{ 0.5, 2.86, 184.84 },
+	{ 0.5, 6.26, 1059.38 },
+	{ 0.5, 3.43, 149.56 },
+	{ 0.5, 4.88, 1272.68 },
+	{ 0.4, 5.40, 408.44 },
+	{ 0.4, 4.06, 543.92 },
+	{ 0.4, 1.69, 1155.36 },
+	{ 0.4, 1.22, 1052.27 },
+	/* 82 terms retained, 66 terms dropped, error 0.015"*T^3 */
+
+	/* saturn l, T^4 */
+	{ 1661.9, 3.99826, 7.11355 },
+	{ 257.1, 2.9844, 220.4126 },
+	{ 236.3, 3.9024, 14.2271 },
+	{ 149.4, 2.7411, 213.2991 },
+	{ 109.6, 1.5152, 206.1855 },
+	{ 114.0, 3.1416, 0 },
+	{ 68.4, 1.721, 426.598 },
+	{ 37.7, 1.238, 199.072 },
+	{ 40.1, 2.046, 433.712 },
+	{ 31.2, 3.011, 227.526 },
+	{ 15.1, 0.829, 639.897 },
+	{ 9.4, 3.71, 21.34 },
+	{ 5.7, 2.42, 419.48 },
+	{ 4.5, 1.45, 95.98 },
+	{ 5.6, 1.16, 647.01 },
+	{ 4.5, 2.12, 440.83 },
+	{ 3.2, 4.09, 110.21 },
+	{ 2.9, 2.77, 412.37 },
+	{ 2.8, 3.01, 88.87 },
+	{ 2.6, 0.00, 853.20 },
+	{ 2.6, 0.39, 103.09 },
+	{ 1.9, 5.08, 309.28 },
+	{ 2.2, 3.78, 117.32 },
+	{ 1.8, 5.19, 302.16 },
+	{ 1.9, 2.83, 234.64 },
+	{ 1.8, 2.24, 216.48 },
+	{ 1.2, 1.55, 191.96 },
+	{ 0.8, 3.45, 323.51 },
+	{ 0.8, 4.83, 210.12 },
+	{ 0.6, 4.19, 515.46 },
+	{ 0.6, 2.29, 209.37 },
+	{ 0.6, 4.03, 522.58 },
+	{ 0.6, 2.38, 632.78 },
+	{ 0.6, 0.30, 860.31 },
+	{ 0.6, 2.17, 124.43 },
+	{ 0.4, 2.24, 447.94 },
+	{ 0.4, 5.45, 1066.50 },
+	{ 0.5, 1.27, 654.12 },
+	{ 0.5, 3.20, 405.26 },
+	{ 0.4, 3.12, 330.62 },
+	{ 0.4, 3.39, 81.75 },
+	{ 0.3, 4.12, 838.97 },
+	{ 0.3, 3.18, 529.69 },
+	{ 0.3, 1.41, 429.78 },
+	{ 0.3, 3.19, 1464.64 },
+	{ 0.3, 2.94, 728.76 },
+	{ 0.2, 3.67, 1148.25 },
+	{ 0.3, 2.58, 1045.15 },
+	{ 0.2, 3.58, 1155.36 },
+	{ 0.3, 2.05, 1677.94 },
+	{ 0.2, 2.62, 536.80 },
+	{ 0.3, 2.48, 625.67 },
+	{ 0.2, 4.39, 1574.85 },
+	{ 0.2, 1.26, 422.67 },
+	{ 0.2, 2.33, 223.59 },
+	{ 0.2, 1.09, 742.99 },
+	{ 0.2, 0.70, 824.74 },
+	{ 0.2, 5.03, 203.00 },
+	{ 0.2, 0.40, 867.42 },
+	{ 0.2, 3.68, 831.86 },
+	{ 0.2, 5.75, 1073.61 },
+	{ 0.2, 3.02, 1781.03 },
+	{ 0.1, 2.28, 295.05 },
+	{ 0.1, 3.48, 956.29 },
+	{ 0.2, 1.91, 942.06 },
+	{ 0.1, 6.17, 316.39 },
+	/* 66 terms retained, 2 terms dropped, error 0.0049"*T^4 */
+
+	/* saturn l, T^5 */
+	{ 123.6, 2.2592, 7.1135 },
+	{ 34.2, 2.163, 14.227 },
+	{ 27.5, 1.199, 220.413 },
+	{ 5.8, 1.22, 227.53 },
+	{ 5.3, 0.24, 433.71 },
+	{ 3.7, 6.23, 426.60 },
+	{ 3.1, 2.97, 199.07 },
+	{ 2.9, 4.29, 206.19 },
+	{ 1.6, 6.25, 213.30 },
+	{ 1.3, 5.28, 639.90 },
+	{ 0.9, 5.57, 647.01 },
+	{ 0.8, 6.18, 191.96 },
+	{ 0.8, 0.69, 302.16 },
+	{ 1.0, 0.24, 440.83 },
+	{ 1.0, 3.14, 0 },
+	{ 0.5, 4.88, 88.87 },
+	{ 0.5, 4.78, 419.48 },
+	{ 0.3, 4.32, 853.20 },
+	{ 0.4, 5.70, 654.12 },
+	{ 0.2, 2.05, 323.51 },
+	{ 0.3, 1.11, 234.64 },
+	{ 0.2, 0.89, 309.28 },
+	{ 0.3, 5.10, 95.98 },
+	{ 0.2, 2.40, 515.46 },
+	{ 0.2, 4.70, 860.31 },
+	{ 0.1, 0.49, 117.32 },
+	/* 26 terms retained, 1 terms dropped, error 0.0022"*T^5 */
+	/* end saturn l */
+
+	/* saturn b, T^0 */
+	{ 4330678.0, 3.60284428, 213.29909544 },
+	{ 240348.3, 2.8523849, 426.5981909 },
+	{ 84745.9, 0, 0 },
+	{ 30863.4, 3.484415, 220.412642 },
+	{ 34116.1, 0.572973, 206.185548 },
+	{ 14734.1, 2.118466, 639.897286 },
+	{ 9916.7, 5.79003, 419.48464 },
+	{ 6993.6, 4.73605, 7.11355 },
+	{ 4807.6, 5.43305, 316.39187 },
+	{ 4788.4, 4.96513, 110.20632 },
+	{ 3432.1, 2.73256, 433.71174 },
+	{ 1506.1, 6.01305, 103.09277 },
+	{ 1060.3, 5.63099, 529.69097 },
+	{ 969.1, 5.2043, 632.7837 },
+	{ 942.1, 1.3965, 853.1964 },
+	{ 707.6, 3.8030, 323.5054 },
+	{ 552.3, 5.1315, 202.2534 },
+	{ 399.7, 3.3589, 227.5262 },
+	{ 316.1, 1.9972, 647.0108 },
+	{ 319.4, 3.6257, 209.3669 },
+	{ 284.5, 4.8865, 224.3448 },
+	{ 314.2, 0.4651, 217.2312 },
+	{ 236.4, 2.1389, 11.0457 },
+	{ 215.4, 5.9498, 846.0828 },
+	{ 208.5, 2.1200, 415.5525 },
+	{ 179.0, 2.9536, 63.7359 },
+	{ 207.2, 0.7302, 199.0720 },
+	{ 139.1, 1.9982, 735.8765 },
+	{ 134.9, 5.2450, 742.9901 },
+	{ 140.6, 0.6442, 490.3341 },
+	{ 121.7, 3.1154, 522.5774 },
+	{ 139.2, 4.5954, 14.2271 },
+	{ 115.5, 3.1089, 216.4805 },
+	{ 114.2, 0.9626, 210.1177 },
+	{ 96.4, 4.482, 117.320 },
+	{ 80.6, 1.317, 277.035 },
+	{ 73.0, 3.060, 536.805 },
+	{ 69.3, 4.924, 309.278 },
+	{ 74.3, 2.894, 149.563 },
+	{ 68.0, 2.180, 351.817 },
+	{ 61.7, 0.677, 1066.495 },
+	{ 56.6, 2.610, 440.825 },
+	{ 48.9, 5.787, 95.979 },
+	{ 48.2, 2.182, 74.782 },
+	{ 38.3, 5.292, 1059.382 },
+	{ 36.3, 1.633, 628.852 },
+	{ 35.1, 1.713, 1052.268 },
+	{ 34.3, 2.457, 422.666 },
+	{ 34.3, 5.980, 412.371 },
+	{ 33.8, 1.141, 949.176 },
+	{ 31.6, 4.147, 437.644 },
+	{ 36.8, 6.278, 1162.475 },
+	{ 27.0, 1.272, 860.310 },
+	/* 53 terms retained, 447 terms dropped, error 0.82" */
+
+	/* saturn b, T^1 */
+	{ 397555.0, 5.3328999, 213.2990954 },
+	{ 49478.6, 3.141593, 0 },
+	{ 18571.6, 6.099192, 426.598191 },
+	{ 14800.6, 2.305861, 206.185548 },
+	{ 9644.0, 1.69675, 220.41264 },
+	{ 3757.2, 1.25430, 419.48464 },
+	{ 2716.6, 5.91167, 639.89729 },
+	{ 1455.3, 0.85162, 433.71174 },
+	{ 1290.6, 2.91771, 7.11355 },
+	{ 852.6, 0.4357, 316.3919 },
+	{ 284.4, 1.6188, 227.5262 },
+	{ 292.2, 5.3157, 853.1964 },
+	{ 275.1, 3.8886, 103.0928 },
+	{ 297.7, 0.9191, 632.7837 },
+	{ 172.4, 0.0522, 647.0108 },
+	{ 127.7, 1.2071, 529.6910 },
+	{ 166.2, 2.4435, 199.0720 },
+	{ 158.2, 5.2085, 110.2063 },
+	{ 109.8, 2.4570, 217.2312 },
+	{ 81.8, 2.758, 210.118 },
+	{ 81.0, 2.860, 14.227 },
+	{ 68.7, 1.655, 202.253 },
+	{ 59.3, 1.824, 323.505 },
+	{ 65.2, 1.255, 216.480 },
+	{ 61.0, 1.253, 209.367 },
+	{ 46.4, 0.815, 440.825 },
+	{ 36.2, 1.819, 224.345 },
+	{ 34.0, 2.840, 117.320 },
+	{ 32.2, 1.187, 846.083 },
+	{ 33.1, 1.306, 412.371 },
+	{ 27.3, 4.647, 1066.495 },
+	{ 22.8, 4.129, 415.552 },
+	{ 27.1, 4.442, 11.046 },
+	{ 18.1, 5.564, 860.310 },
+	{ 20.9, 1.410, 309.278 },
+	{ 14.9, 1.343, 95.979 },
+	{ 15.3, 1.224, 63.736 },
+	{ 14.6, 1.008, 536.805 },
+	{ 12.8, 2.271, 742.990 },
+	{ 12.8, 4.889, 522.577 },
+	{ 13.1, 2.460, 490.334 },
+	{ 11.9, 1.873, 423.417 },
+	{ 13.0, 3.217, 277.035 },
+	{ 9.9, 3.12, 625.67 },
+	{ 12.7, 0.295, 422.666 },
+	{ 9.6, 1.75, 330.62 },
+	{ 8.1, 2.42, 430.53 },
+	{ 8.2, 4.68, 215.75 },
+	{ 9.0, 0.46, 429.78 },
+	{ 6.5, 3.01, 949.18 },
+	{ 7.3, 5.97, 149.56 },
+	{ 6.6, 3.91, 351.82 },
+	{ 6.8, 1.52, 437.64 },
+	/* 53 terms retained, 207 terms dropped, error 0.21"*T */
+
+	/* saturn b, T^2 */
+	{ 20630.0, 0.504824, 213.299095 },
+	{ 3719.6, 3.99833, 206.18555 },
+	{ 1627.2, 6.18190, 220.41264 },
+	{ 1346.1, 0, 0 },
+	{ 705.8, 3.0391, 419.4846 },
+	{ 365.0, 5.0993, 426.5982 },
+	{ 329.6, 5.2790, 433.7117 },
+	{ 219.3, 3.8284, 639.8973 },
+	{ 139.4, 1.0427, 7.1135 },
+	{ 104.0, 6.1573, 227.5262 },
+	{ 93.0, 1.980, 316.392 },
+	{ 71.2, 4.148, 199.072 },
+	{ 51.9, 2.884, 632.784 },
+	{ 49.0, 4.434, 647.011 },
+	{ 41.4, 3.159, 853.196 },
+	{ 28.6, 4.530, 210.118 },
+	{ 24.0, 1.116, 14.227 },
+	{ 20.5, 4.351, 217.231 },
+	{ 19.5, 5.308, 440.825 },
+	{ 18.3, 0.854, 110.206 },
+	{ 15.7, 4.258, 103.093 },
+	{ 16.8, 5.681, 216.480 },
+	{ 13.6, 2.999, 412.371 },
+	{ 11.6, 2.527, 529.691 },
+	{ 8.0, 3.32, 202.25 },
+	{ 6.6, 0.29, 323.51 },
+	{ 6.3, 1.16, 117.32 },
+	{ 5.9, 3.58, 309.28 },
+	{ 6.6, 5.56, 209.37 },
+	{ 5.6, 2.48, 1066.50 },
+	{ 6.2, 3.61, 860.31 },
+	{ 4.2, 3.02, 846.08 },
+	{ 3.6, 4.80, 625.67 },
+	{ 3.4, 3.77, 423.42 },
+	{ 3.4, 6.04, 234.64 },
+	{ 2.6, 5.64, 735.88 },
+	{ 2.8, 4.82, 429.78 },
+	{ 2.8, 4.48, 654.12 },
+	{ 2.6, 0.22, 522.58 },
+	{ 2.6, 3.29, 95.98 },
+	{ 2.4, 0.03, 415.55 },
+	{ 2.1, 4.56, 422.67 },
+	{ 2.3, 6.25, 330.62 },
+	{ 1.8, 5.53, 536.80 },
+	{ 1.8, 5.06, 277.03 },
+	{ 1.6, 5.54, 224.34 },
+	/* 46 terms retained, 65 terms dropped, error 0.045"*T^2 */
+
+	/* saturn b, T^3 */
+	{ 666.3, 1.9901, 213.2991 },
+	{ 632.4, 5.6978, 206.1855 },
+	{ 398.1, 0, 0 },
+	{ 187.8, 4.3378, 220.4126 },
+	{ 91.9, 4.841, 419.485 },
+	{ 42.4, 2.381, 426.598 },
+	{ 51.5, 3.421, 433.712 },
+	{ 25.7, 4.402, 227.526 },
+	{ 20.6, 5.853, 199.072 },
+	{ 18.1, 1.993, 639.897 },
+	{ 10.9, 5.373, 7.114 },
+	{ 9.6, 2.55, 647.01 },
+	{ 7.1, 3.46, 316.39 },
+	{ 6.0, 4.80, 632.78 },
+	{ 5.8, 0.02, 210.12 },
+	{ 4.9, 5.64, 14.23 },
+	{ 4.5, 1.22, 853.20 },
+	{ 5.5, 3.52, 440.83 },
+	{ 3.5, 4.71, 412.37 },
+	{ 2.9, 0.63, 103.09 },
+	{ 2.2, 3.72, 216.48 },
+	{ 2.0, 6.11, 217.23 },
+	{ 1.4, 1.69, 860.31 },
+	{ 1.2, 4.31, 234.64 },
+	{ 1.2, 5.75, 309.28 },
+	{ 0.8, 5.69, 117.32 },
+	{ 0.7, 0.60, 1066.50 },
+	{ 0.7, 0.22, 625.67 },
+	{ 0.8, 5.48, 202.25 },
+	{ 0.9, 2.66, 654.12 },
+	{ 0.5, 2.86, 429.78 },
+	{ 0.5, 4.18, 529.69 },
+	{ 0.5, 4.52, 323.51 },
+	/* 33 terms retained, 25 terms dropped, error 0.012"*T^3 */
+
+	/* saturn b, T^4 */
+	{ 80.4, 1.119, 206.186 },
+	{ 31.7, 3.122, 213.299 },
+	{ 17.1, 2.481, 220.413 },
+	{ 11.8, 3.142, 0 },
+	{ 9.0, 0.38, 419.48 },
+	{ 6.2, 1.56, 433.71 },
+	{ 4.7, 1.28, 199.07 },
+	{ 4.8, 2.63, 227.53 },
+	{ 1.5, 1.43, 426.60 },
+	{ 1.4, 0.67, 647.01 },
+	{ 1.1, 6.18, 639.90 },
+	{ 1.1, 1.72, 440.83 },
+	{ 0.7, 3.85, 14.23 },
+	{ 0.7, 3.49, 7.11 },
+	{ 0.5, 0.47, 632.78 },
+	{ 0.5, 0.31, 412.37 },
+	{ 0.3, 5.86, 853.20 },
+	{ 0.3, 2.50, 234.64 },
+	{ 0.2, 5.39, 316.39 },
+	{ 0.2, 2.11, 210.12 },
+	{ 0.2, 6.10, 860.31 },
+	{ 0.2, 5.95, 216.48 },
+	{ 0.1, 1.99, 625.67 },
+	{ 0.1, 0.86, 654.12 },
+	{ 0.1, 5.04, 117.32 },
+	{ 0.1, 0.45, 110.21 },
+	/* 26 terms retained, 0 terms dropped, error 0.0025"*T^4 */
+
+	/* saturn b, T^5 */
+	{ 7.9, 2.82, 206.19 },
+	{ 1.0, 0.51, 220.41 },
+	{ 0.8, 2.99, 199.07 },
+	{ 1.0, 3.14, 0 },
+	{ 0.6, 5.96, 433.71 },
+	{ 0.6, 0.78, 227.53 },
+	{ 0.4, 2.39, 419.48 },
+	{ 0.1, 5.11, 647.01 },
+	/* 8 terms retained, 3 terms dropped, error 0.0012"*T^5 */
+	/* end saturn b */
+
+	/* saturn r, T^0 */
+	{ 955758135.8, 0, 0 },
+	{ 52921382.5, 2.392262197, 213.299095438 },
+	{ 1873679.9, 5.23549605, 206.18554844 },
+	{ 1464664.0, 1.64763045, 426.59819088 },
+	{ 821891.1, 5.9352003, 316.3918697 },
+	{ 547506.9, 5.0153263, 103.0927742 },
+	{ 371684.4, 2.2711483, 220.4126424 },
+	{ 361778.4, 3.1390430, 7.1135470 },
+	{ 140617.5, 5.7040665, 632.7837393 },
+	{ 108974.7, 3.2931360, 110.2063212 },
+	{ 69007.0, 5.940996, 419.484644 },
+	{ 61053.3, 0.940378, 639.897286 },
+	{ 48913.0, 1.557334, 202.253395 },
+	{ 34143.8, 0.195186, 277.034994 },
+	{ 32401.7, 5.470846, 949.175609 },
+	{ 20936.6, 0.463492, 735.876514 },
+	{ 20839.1, 1.521026, 433.711738 },
+	{ 20746.7, 5.332557, 199.072001 },
+	{ 15298.5, 3.059437, 529.690965 },
+	{ 14296.5, 2.604335, 323.505417 },
+	{ 11993.3, 5.980514, 846.082835 },
+	{ 11380.3, 1.731057, 522.577418 },
+	{ 12884.1, 1.648923, 138.517497 },
+	{ 7752.8, 5.85191, 95.97923 },
+	{ 9796.1, 5.20476, 1265.56748 },
+	{ 6466.0, 0.17733, 1052.26838 },
+	{ 6770.6, 3.00433, 14.22709 },
+	{ 5850.4, 1.45520, 415.55249 },
+	{ 5307.5, 0.59738, 63.73590 },
+	{ 4695.7, 2.14919, 227.52619 },
+	{ 4044.0, 1.64010, 209.36694 },
+	{ 3688.1, 0.78016, 412.37110 },
+	{ 3376.5, 3.69528, 224.34480 },
+	{ 2885.3, 1.38764, 838.96929 },
+	{ 2976.0, 5.68468, 210.11770 },
+	{ 3419.6, 4.94549, 1581.95935 },
+	{ 3460.9, 1.85089, 175.16606 },
+	{ 3400.6, 0.55387, 350.33212 },
+	{ 2507.6, 3.53852, 742.99006 },
+	{ 2448.3, 6.18412, 1368.66025 },
+	{ 2406.1, 2.96559, 117.31987 },
+	{ 2881.2, 0.17961, 853.19638 },
+	{ 2174.0, 0.01509, 340.77089 },
+	{ 2024.5, 5.05411, 11.04570 },
+	{ 1740.3, 2.34657, 309.27832 },
+	{ 1861.4, 5.93362, 625.67019 },
+	{ 1888.4, 0.02968, 3.93215 },
+	{ 1610.9, 1.17302, 74.78160 },
+	{ 1462.6, 1.92588, 216.48049 },
+	{ 1474.5, 5.67670, 203.73787 },
+	{ 1395.1, 5.93669, 127.47180 },
+	{ 1781.2, 0.76314, 217.23125 },
+	{ 1817.2, 5.77713, 490.33409 },
+	{ 1472.4, 1.40065, 137.03302 },
+	{ 1304.1, 0.77236, 647.01083 },
+	{ 1149.8, 5.74021, 1162.47470 },
+	{ 1126.7, 4.46708, 265.98929 },
+	{ 1277.5, 2.98413, 1059.38193 },
+	{ 1207.1, 0.75286, 351.81659 },
+	{ 1071.4, 1.13567, 1155.36116 },
+	{ 1020.9, 5.91234, 1685.05212 },
+	{ 1315.0, 5.11203, 211.81462 },
+	{ 1295.6, 4.69184, 1898.35122 },
+	{ 1099.0, 1.81765, 149.56320 },
+	{ 998.5, 2.6313, 200.7689 },
+	{ 985.9, 2.2599, 956.2892 },
+	{ 932.4, 3.6698, 554.0700 },
+	{ 664.5, 0.6030, 728.7630 },
+	{ 659.8, 4.6664, 195.1398 },
+	{ 617.7, 5.6209, 942.0621 },
+	{ 626.4, 5.9421, 1478.8666 },
+	{ 482.2, 1.8407, 479.2884 },
+	{ 487.7, 2.7937, 3.1814 },
+	{ 470.1, 0.8385, 1471.7530 },
+	{ 451.8, 5.6447, 2001.4440 },
+	{ 553.1, 3.4109, 269.9214 },
+	{ 534.4, 1.2644, 275.5505 },
+	{ 472.6, 1.8820, 515.4639 },
+	{ 405.4, 1.6400, 536.8045 },
+	{ 517.2, 4.4431, 2214.7431 },
+	{ 452.8, 3.0035, 302.1648 },
+	{ 494.3, 2.2863, 278.5195 },
+	{ 489.8, 5.8063, 191.2077 },
+	{ 427.5, 0.0574, 284.1485 },
+	{ 339.8, 1.4020, 440.8253 },
+	{ 340.6, 0.8909, 628.8516 },
+	{ 386.0, 1.9970, 1272.6810 },
+	{ 288.3, 1.1216, 422.6660 },
+	{ 294.4, 0.4258, 312.1991 },
+	{ 262.5, 0.3175, 1045.1548 },
+	{ 295.3, 0.6714, 88.8657 },
+	{ 343.0, 5.8560, 1795.2584 },
+	{ 341.1, 2.3759, 525.4982 },
+	{ 234.0, 4.2276, 114.1385 },
+	{ 223.7, 2.2813, 330.6190 },
+	{ 275.8, 0.4783, 38.1330 },
+	{ 224.6, 0.5475, 1788.1449 },
+	{ 303.3, 0.8795, 6069.7768 },
+	{ 292.1, 6.2142, 210.8514 },
+	{ 226.1, 0.3750, 142.4497 },
+	{ 277.3, 5.3192, 692.5875 },
+	{ 242.9, 5.3719, 1258.4539 },
+	{ 205.6, 0.9576, 288.0807 },
+	{ 207.6, 5.3813, 2317.8359 },
+	{ 186.8, 6.0359, 404.5068 },
+	{ 218.5, 5.2561, 212.3359 },
+	{ 222.2, 5.9459, 39.3569 },
+	{ 179.7, 4.4105, 408.4389 },
+	{ 241.4, 1.1253, 388.4652 },
+	{ 197.1, 3.9014, 52.6902 },
+	{ 236.6, 0.9080, 1375.7738 },
+	{ 171.9, 5.5632, 213.3473 },
+	{ 169.9, 2.8567, 99.1606 },
+	{ 214.4, 4.2025, 2531.1350 },
+	{ 172.0, 2.3654, 213.2509 },
+	{ 165.7, 2.6368, 215.7468 },
+	{ 230.9, 5.4946, 191.9585 },
+	{ 177.6, 0.3816, 430.5303 },
+	{ 191.5, 2.9591, 437.6439 },
+	{ 163.2, 3.4583, 617.8059 },
+	{ 162.3, 5.7305, 203.0042 },
+	{ 175.1, 5.7140, 1066.4955 },
+	{ 183.0, 5.6685, 2111.6503 },
+	{ 150.1, 4.4066, 417.0370 },
+	{ 187.9, 6.0792, 563.6312 },
+	{ 145.1, 5.0818, 423.4168 },
+	{ 137.5, 5.4391, 222.8603 },
+	{ 172.8, 1.8492, 1589.0729 },
+	{ 165.5, 2.8913, 214.2623 },
+	{ 145.7, 1.5657, 831.8557 },
+	{ 176.9, 2.3032, 9999.9865 },
+	{ 128.9, 2.5534, 414.0680 },
+	{ 120.1, 0.0433, 1361.5467 },
+	{ 143.4, 0.9982, 76.2661 },
+	{ 108.7, 2.0928, 207.6700 },
+	{ 132.1, 2.8590, 312.4597 },
+	{ 112.2, 0.2622, 2104.5368 },
+	{ 125.2, 4.7835, 205.2223 },
+	{ 104.4, 3.6367, 65.2204 },
+	{ 107.4, 3.6706, 212.7778 },
+	{ 108.6, 2.8549, 21.3406 },
+	{ 97.7, 5.122, 2634.228 },
+	{ 109.1, 1.6323, 208.6332 },
+	{ 96.9, 4.199, 305.346 },
+	{ 96.5, 2.560, 1692.166 },
+	{ 85.8, 4.545, 210.378 },
+	{ 99.2, 5.138, 1574.846 },
+	{ 112.5, 5.0311, 703.6332 },
+	{ 84.0, 1.183, 429.780 },
+	{ 89.0, 5.388, 107.025 },
+	{ 110.2, 2.4366, 355.7487 },
+	{ 90.7, 4.209, 213.820 },
+	{ 95.9, 5.446, 2428.042 },
+	{ 94.1, 2.398, 483.221 },
+	{ 85.6, 0.034, 860.310 },
+	{ 88.8, 4.058, 128.956 },
+	{ 82.0, 1.665, 62.251 },
+	{ 91.2, 3.969, 2847.527 },
+	{ 84.0, 4.608, 177.874 },
+	{ 88.4, 3.868, 140.002 },
+	{ 93.3, 0.738, 831.105 },
+	{ 91.9, 2.950, 35.425 },
+	{ 87.1, 1.334, 1905.465 },
+	{ 96.6, 4.844, 131.404 },
+	{ 71.0, 0.993, 405.258 },
+	{ 95.3, 2.515, 2.448 },
+	{ 72.5, 4.632, 245.542 },
+	{ 82.6, 1.528, 145.631 },
+	{ 76.7, 3.152, 767.369 },
+	{ 70.3, 4.043, 173.942 },
+	{ 86.0, 2.301, 85.827 },
+	{ 66.5, 4.751, 70.849 },
+	{ 65.8, 2.469, 280.967 },
+	{ 64.8, 0.093, 9.561 },
+	{ 71.6, 0.012, 565.116 },
+	{ 66.5, 1.080, 339.286 },
+	{ 63.5, 2.017, 234.640 },
+	{ 60.8, 5.120, 756.323 },
+	{ 58.1, 6.057, 1677.939 },
+	{ 64.2, 1.286, 1148.248 },
+	{ 73.1, 4.378, 425.114 },
+	{ 55.0, 3.859, 342.255 },
+	{ 57.1, 6.267, 2420.929 },
+	{ 64.1, 4.099, 327.438 },
+	{ 55.3, 1.605, 543.024 },
+	{ 58.0, 5.473, 347.884 },
+	{ 73.6, 3.723, 92.047 },
+	{ 73.8, 3.570, 1.484 },
+	{ 64.9, 2.447, 267.474 },
+	{ 54.4, 3.715, 344.703 },
+	{ 49.8, 3.935, 192.692 },
+	{ 49.5, 3.228, 333.657 },
+	{ 47.5, 3.929, 199.284 },
+	{ 49.4, 4.903, 217.492 },
+	{ 62.7, 4.401, 214.784 },
+	{ 46.4, 2.094, 212.548 },
+	{ 46.3, 2.640, 10.295 },
+	{ 54.3, 1.072, 362.862 },
+	{ 58.7, 2.623, 225.829 },
+	{ 48.5, 3.152, 216.220 },
+	{ 46.3, 4.862, 2950.620 },
+	{ 46.0, 4.973, 198.321 },
+	{ 46.7, 2.450, 207.149 },
+	{ 44.9, 1.776, 223.594 },
+	{ 44.5, 5.560, 264.505 },
+	{ 55.9, 4.295, 329.725 },
+	{ 49.6, 5.208, 2744.434 },
+	{ 58.8, 4.231, 700.664 },
+	{ 52.6, 3.792, 343.219 },
+	{ 41.5, 0.745, 125.987 },
+	{ 47.8, 2.393, 207.882 },
+	{ 56.2, 2.072, 124.433 },
+	{ 43.3, 1.837, 106.274 },
+	{ 39.8, 4.009, 12.530 },
+	{ 53.9, 4.979, 134.585 },
+	{ 50.1, 5.759, 320.324 },
+	{ 45.0, 5.357, 218.928 },
+	{ 41.1, 4.923, 1891.238 },
+	{ 46.5, 2.066, 2008.558 },
+	{ 42.9, 0.399, 357.446 },
+	{ 38.0, 2.065, 247.239 },
+	{ 48.7, 5.328, 3127.313 },
+	{ 34.6, 5.626, 99.911 },
+	{ 41.1, 2.473, 237.678 },
+	{ 40.8, 4.084, 621.738 },
+	{ 34.2, 0.731, 750.104 },
+	{ 34.0, 5.313, 206.234 },
+	{ 36.5, 1.688, 22.091 },
+	{ 39.4, 3.457, 241.610 },
+	{ 34.8, 2.248, 487.365 },
+	{ 33.0, 4.866, 209.106 },
+	{ 32.6, 2.227, 319.573 },
+	{ 39.0, 3.739, 3163.919 },
+	{ 32.7, 1.066, 252.656 },
+	{ 38.7, 4.396, 18.159 },
+	{ 34.5, 1.826, 380.128 },
+	{ 41.5, 0.081, 210.330 },
+	{ 33.5, 5.805, 251.432 },
+	{ 31.2, 1.965, 244.319 },
+	{ 30.5, 2.269, 1169.588 },
+	{ 34.8, 5.963, 217.965 },
+	{ 38.5, 4.437, 160.609 },
+	{ 36.0, 3.833, 56.622 },
+	{ 31.0, 4.899, 144.147 },
+	{ 32.3, 3.582, 231.458 },
+	{ 28.8, 5.801, 1994.330 },
+	{ 32.2, 2.132, 206.137 },
+	{ 32.6, 1.931, 98.900 },
+	{ 34.9, 5.653, 497.448 },
+	{ 28.9, 2.217, 14.978 },
+	{ 31.6, 3.818, 73.297 },
+	{ 32.2, 0.998, 1464.639 },
+	{ 29.2, 5.984, 2737.321 },
+	{ 36.7, 4.755, 348.848 },
+	{ 28.7, 1.687, 78.714 },
+	{ 27.5, 6.121, 214.050 },
+	{ 28.8, 0.044, 5.629 },
+	{ 27.2, 0.246, 313.210 },
+	{ 32.4, 3.779, 33.940 },
+	{ 27.1, 5.203, 148.079 },
+	{ 35.0, 3.439, 273.103 },
+	{ 33.1, 2.447, 969.622 },
+	{ 27.7, 1.446, 258.876 },
+	{ 27.2, 4.259, 179.359 },
+	{ 27.9, 0.788, 546.956 },
+	{ 29.1, 4.839, 905.887 },
+	{ 27.4, 2.449, 254.944 },
+	{ 34.3, 6.009, 166.829 },
+	{ 28.9, 6.029, 188.920 },
+	{ 26.0, 0.650, 654.124 },
+	{ 33.6, 1.237, 2221.857 },
+	{ 27.8, 5.178, 5.417 },
+	{ 25.6, 3.359, 0.963 },
+	{ 28.8, 0.755, 488.850 },
+	{ 31.2, 2.053, 282.452 },
+	{ 25.4, 5.290, 636.716 },
+	{ 25.3, 4.970, 3060.826 },
+	{ 29.6, 3.927, 206.707 },
+	{ 28.3, 2.721, 32.243 },
+	{ 26.9, 2.863, 24.379 },
+	{ 28.3, 4.731, 552.586 },
+	{ 25.3, 5.120, 168.053 },
+	{ 26.4, 1.593, 491.819 },
+	{ 27.1, 5.537, 555.554 },
+	{ 27.3, 3.579, 561.184 },
+	{ 25.2, 1.781, 182.280 },
+	{ 25.6, 1.621, 2324.949 },
+	{ 25.6, 2.099, 248.724 },
+	/* 288 terms retained, 917 terms dropped, error 8.7e-06 a.u. */
+
+	/* saturn r, T^1 */
+	{ 6182981.3, 0.25843515, 213.29909544 },
+	{ 506577.6, 0.7111465, 206.1855484 },
+	{ 341394.1, 5.7963577, 426.5981909 },
+	{ 188491.4, 0.4721572, 220.4126424 },
+	{ 186261.5, 3.1415927, 0 },
+	{ 143891.2, 1.4074486, 7.1135470 },
+	{ 49621.1, 6.017445, 103.092774 },
+	{ 20928.2, 5.092457, 639.897286 },
+	{ 19952.6, 1.175601, 419.484644 },
+	{ 18839.6, 1.608196, 110.206321 },
+	{ 12892.8, 5.943303, 433.711738 },
+	{ 13876.6, 0.758862, 199.072001 },
+	{ 5396.7, 1.28852, 14.22709 },
+	{ 4869.3, 0.86794, 323.50542 },
+	{ 4247.5, 0.39299, 227.52619 },
+	{ 3252.1, 1.25853, 95.97923 },
+	{ 2856.0, 2.16731, 735.87651 },
+	{ 2909.4, 4.60679, 202.25340 },
+	{ 3081.4, 3.43663, 522.57742 },
+	{ 1987.7, 2.45054, 412.37110 },
+	{ 1941.3, 6.02393, 209.36694 },
+	{ 1581.4, 1.29192, 210.11770 },
+	{ 1339.5, 4.30802, 853.19638 },
+	{ 1315.6, 1.25296, 117.31987 },
+	{ 1203.1, 1.86655, 316.39187 },
+	{ 1091.1, 0.07527, 216.48049 },
+	{ 954.4, 5.1517, 647.0108 },
+	{ 966.0, 0.4799, 632.7837 },
+	{ 881.8, 1.8847, 1052.2684 },
+	{ 874.2, 1.4022, 224.3448 },
+	{ 897.5, 0.9834, 529.6910 },
+	{ 784.9, 3.0638, 838.9693 },
+	{ 739.9, 1.3823, 625.6702 },
+	{ 613.0, 3.0331, 63.7359 },
+	{ 658.2, 4.1436, 309.2783 },
+	{ 649.6, 1.7249, 742.9901 },
+	{ 599.2, 2.5492, 217.2312 },
+	{ 502.9, 2.1296, 3.9322 },
+	{ 413.0, 4.5933, 415.5525 },
+	{ 356.1, 2.3031, 728.7630 },
+	{ 344.8, 5.8879, 440.8253 },
+	{ 395.0, 0.5335, 956.2892 },
+	{ 335.5, 1.6161, 1368.6603 },
+	{ 362.8, 4.7069, 302.1648 },
+	{ 321.6, 0.9793, 3.1814 },
+	{ 277.8, 0.2601, 195.1398 },
+	{ 291.2, 2.8313, 1155.3612 },
+	{ 265.0, 2.4267, 88.8657 },
+	{ 264.9, 5.8286, 149.5632 },
+	{ 316.8, 3.5840, 515.4639 },
+	{ 294.3, 2.8163, 11.0457 },
+	{ 244.9, 1.0449, 942.0621 },
+	{ 215.4, 3.5654, 490.3341 },
+	{ 264.0, 1.2855, 1059.3819 },
+	{ 246.2, 0.9073, 191.9585 },
+	{ 222.1, 5.1319, 269.9214 },
+	{ 195.0, 4.5667, 846.0828 },
+	{ 182.8, 2.6791, 127.4718 },
+	{ 181.6, 4.9343, 74.7816 },
+	{ 174.7, 3.4456, 137.0330 },
+	{ 165.5, 5.9978, 536.8045 },
+	{ 154.8, 1.1972, 265.9893 },
+	{ 169.7, 4.6346, 284.1485 },
+	{ 151.5, 0.5293, 330.6190 },
+	{ 152.5, 5.4389, 422.6660 },
+	{ 157.7, 2.9956, 340.7709 },
+	{ 140.6, 2.0207, 1045.1548 },
+	{ 139.8, 1.3528, 1685.0521 },
+	{ 141.0, 1.2710, 203.0042 },
+	{ 136.0, 5.0168, 351.8166 },
+	{ 153.4, 0.2697, 1272.6810 },
+	{ 129.5, 1.1434, 21.3406 },
+	{ 127.8, 2.5388, 1471.7530 },
+	{ 126.5, 3.0031, 277.0350 },
+	{ 100.3, 3.6136, 1066.4955 },
+	{ 103.2, 0.3818, 203.7379 },
+	{ 107.5, 4.3187, 210.8514 },
+	{ 95.9, 0.795, 1258.454 },
+	{ 82.7, 0.282, 234.640 },
+	{ 98.0, 2.561, 191.208 },
+	{ 97.4, 3.262, 831.856 },
+	{ 72.2, 4.380, 860.310 },
+	{ 70.6, 0.732, 437.644 },
+	{ 70.4, 0.877, 423.417 },
+	{ 72.1, 5.580, 429.780 },
+	{ 73.3, 0.625, 1375.774 },
+	{ 66.4, 2.684, 405.258 },
+	{ 63.8, 1.751, 1361.547 },
+	{ 61.6, 1.093, 2001.444 },
+	{ 67.0, 0.069, 408.439 },
+	{ 68.9, 2.471, 949.176 },
+	{ 60.5, 2.251, 1788.145 },
+	{ 67.1, 5.454, 200.769 },
+	{ 65.6, 0.055, 1589.073 },
+	{ 49.3, 4.172, 138.517 },
+	{ 50.6, 6.269, 223.594 },
+	{ 55.2, 4.595, 628.852 },
+	{ 47.9, 0.839, 10.295 },
+	{ 46.7, 2.173, 312.199 },
+	{ 54.2, 0.284, 124.433 },
+	{ 49.5, 3.800, 215.747 },
+	{ 40.1, 5.182, 1478.867 },
+	{ 39.3, 0.563, 1574.846 },
+	{ 35.0, 4.685, 38.133 },
+	{ 42.8, 2.986, 1148.248 },
+	{ 36.5, 0.635, 52.690 },
+	{ 39.8, 0.284, 131.404 },
+	{ 31.8, 5.190, 76.266 },
+	{ 33.0, 1.980, 142.450 },
+	{ 42.1, 4.830, 288.081 },
+	{ 30.8, 1.479, 1677.939 },
+	{ 42.8, 3.382, 208.633 },
+	{ 29.2, 5.099, 654.124 },
+	{ 29.2, 4.957, 1795.258 },
+	{ 29.1, 2.747, 404.507 },
+	{ 32.7, 6.121, 145.631 },
+	{ 28.0, 0.832, 2317.836 },
+	{ 27.7, 2.244, 430.530 },
+	{ 29.9, 1.964, 2104.537 },
+	{ 33.0, 3.282, 222.860 },
+	{ 31.8, 6.025, 1905.465 },
+	{ 27.0, 5.243, 388.465 },
+	{ 26.5, 0.996, 107.025 },
+	{ 25.4, 2.873, 703.633 },
+	{ 24.9, 1.077, 99.911 },
+	{ 25.0, 6.240, 106.274 },
+	{ 24.9, 0.810, 312.460 },
+	{ 24.3, 0.549, 214.262 },
+	{ 28.4, 0.826, 1692.166 },
+	{ 23.2, 5.080, 479.288 },
+	{ 24.4, 3.106, 212.336 },
+	{ 22.0, 6.067, 85.827 },
+	{ 22.0, 3.899, 563.631 },
+	{ 22.6, 4.867, 295.051 },
+	{ 21.3, 5.108, 333.657 },
+	{ 26.0, 2.208, 1265.567 },
+	{ 20.9, 3.289, 70.849 },
+	{ 21.5, 3.795, 347.884 },
+	{ 22.1, 4.227, 217.965 },
+	{ 20.6, 1.687, 231.458 },
+	{ 21.4, 3.089, 554.070 },
+	{ 21.3, 0.389, 319.573 },
+	{ 20.5, 2.457, 18.159 },
+	{ 26.1, 4.276, 483.221 },
+	{ 20.7, 5.121, 362.862 },
+	{ 22.0, 5.512, 343.219 },
+	{ 19.4, 2.024, 313.210 },
+	{ 20.2, 5.085, 750.104 },
+	{ 20.1, 3.430, 213.347 },
+	{ 24.2, 0.648, 207.882 },
+	{ 22.0, 0.729, 99.161 },
+	{ 21.1, 2.693, 1464.639 },
+	{ 17.2, 4.715, 2111.650 },
+	{ 18.5, 0.048, 245.542 },
+	{ 17.5, 3.837, 497.448 },
+	{ 16.1, 4.224, 565.116 },
+	{ 21.6, 4.166, 2.448 },
+	{ 16.0, 0.274, 225.829 },
+	{ 16.8, 1.411, 114.138 },
+	{ 15.6, 2.828, 81.752 },
+	{ 15.5, 1.206, 1994.330 },
+	{ 15.2, 3.846, 1162.475 },
+	{ 16.4, 3.048, 134.585 },
+	{ 15.9, 0.330, 1891.238 },
+	{ 20.4, 0.232, 213.251 },
+	{ 16.3, 1.706, 2420.929 },
+	{ 16.3, 4.942, 357.446 },
+	{ 18.1, 5.695, 56.622 },
+	{ 13.7, 0.572, 2634.228 },
+	{ 17.4, 3.553, 218.928 },
+	{ 13.7, 5.705, 92.047 },
+	{ 15.3, 1.313, 216.220 },
+	{ 12.5, 5.192, 635.965 },
+	{ 12.8, 1.602, 320.324 },
+	{ 13.0, 0.451, 1169.588 },
+	{ 12.0, 5.949, 543.918 },
+	{ 11.8, 2.803, 217.492 },
+	{ 14.7, 5.565, 344.703 },
+	{ 12.8, 1.636, 273.103 },
+	{ 11.9, 2.462, 721.649 },
+	{ 13.3, 5.756, 2221.857 },
+	{ 14.5, 0.453, 2008.558 },
+	{ 11.8, 1.757, 160.609 },
+	{ 12.4, 1.015, 329.725 },
+	{ 10.7, 1.581, 212.778 },
+	{ 12.8, 1.920, 1581.959 },
+	{ 11.9, 4.447, 32.243 },
+	{ 11.9, 5.107, 4.666 },
+	{ 11.9, 4.308, 618.557 },
+	{ 10.0, 0.487, 305.346 },
+	{ 12.8, 3.744, 508.350 },
+	{ 10.7, 0.766, 218.716 },
+	{ 11.4, 3.000, 198.321 },
+	{ 10.2, 2.409, 546.956 },
+	{ 10.0, 2.639, 416.303 },
+	{ 9.3, 5.46, 414.07 },
+	{ 9.3, 4.46, 2428.04 },
+	{ 9.9, 4.05, 62.25 },
+	{ 12.8, 3.433, 258.876 },
+	{ 9.7, 1.61, 327.44 },
+	{ 11.2, 2.407, 1781.031 },
+	{ 10.6, 2.075, 213.820 },
+	{ 9.1, 2.92, 1279.79 },
+	{ 9.5, 1.10, 113.39 },
+	{ 9.8, 3.28, 275.55 },
+	{ 11.3, 1.894, 561.184 },
+	{ 8.6, 2.18, 425.11 },
+	{ 8.6, 1.95, 35.42 },
+	{ 10.2, 0.090, 182.280 },
+	{ 11.8, 3.713, 350.332 },
+	{ 8.6, 1.83, 629.60 },
+	{ 8.4, 3.77, 251.43 },
+	{ 8.5, 0.36, 617.81 },
+	{ 8.2, 5.31, 65.22 },
+	{ 8.3, 1.38, 1.48 },
+	{ 8.0, 5.14, 22.09 },
+	{ 8.4, 0.92, 1485.98 },
+	{ 8.0, 0.94, 2310.72 },
+	{ 8.9, 0.54, 168.05 },
+	{ 8.2, 3.46, 424.15 },
+	{ 8.0, 3.38, 144.15 },
+	{ 7.9, 5.14, 358.93 },
+	{ 8.9, 6.14, 621.74 },
+	{ 7.5, 5.75, 447.94 },
+	{ 7.5, 2.19, 264.50 },
+	{ 8.1, 1.43, 2737.32 },
+	{ 8.2, 0.96, 767.37 },
+	{ 8.2, 0.35, 278.52 },
+	{ 8.2, 5.44, 254.94 },
+	{ 6.8, 1.20, 5.42 },
+	{ 8.9, 4.88, 120.36 },
+	{ 7.8, 4.56, 280.97 },
+	{ 6.6, 3.50, 9.56 },
+	{ 6.4, 0.33, 2950.62 },
+	{ 6.9, 3.39, 98.90 },
+	{ 7.4, 4.52, 5.63 },
+	{ 8.0, 0.94, 636.72 },
+	{ 7.2, 3.85, 214.05 },
+	{ 6.4, 2.12, 274.07 },
+	{ 6.5, 5.31, 6076.89 },
+	{ 6.4, 0.45, 10007.10 },
+	{ 6.3, 3.21, 219.45 },
+	{ 6.7, 1.65, 1898.35 },
+	{ 7.6, 0.10, 2324.95 },
+	{ 6.3, 0.76, 210.38 },
+	{ 6.6, 1.79, 12.53 },
+	/* 246 terms retained, 393 terms dropped, error 2.1e-06 a.u.*T */
+
+	/* saturn r, T^2 */
+	{ 436902.5, 4.7867167, 213.2990954 },
+	{ 71922.8, 2.500700, 206.185548 },
+	{ 49766.8, 4.971682, 220.412642 },
+	{ 43220.9, 3.869404, 426.598191 },
+	{ 29645.6, 5.963103, 7.113547 },
+	{ 4141.6, 4.10671, 433.71174 },
+	{ 4720.9, 2.47528, 199.07200 },
+	{ 3789.4, 3.09771, 639.89729 },
+	{ 2964.0, 1.37206, 103.09277 },
+	{ 2556.4, 2.85066, 419.48464 },
+	{ 2208.5, 6.27589, 110.20632 },
+	{ 2187.6, 5.85546, 14.22709 },
+	{ 1956.9, 4.92449, 227.52619 },
+	{ 2326.8, 0, 0 },
+	{ 923.8, 5.4639, 323.5054 },
+	{ 705.9, 2.9708, 95.9792 },
+	{ 546.1, 4.1285, 412.3711 },
+	{ 373.8, 5.8344, 117.3199 },
+	{ 360.9, 3.2770, 647.0108 },
+	{ 356.3, 3.1915, 210.1177 },
+	{ 390.6, 4.4811, 216.4805 },
+	{ 431.5, 5.1783, 522.5774 },
+	{ 325.6, 2.2687, 853.1964 },
+	{ 405.0, 4.1729, 209.3669 },
+	{ 204.5, 0.0877, 202.2534 },
+	{ 206.9, 4.0219, 735.8765 },
+	{ 178.5, 4.0972, 440.8253 },
+	{ 180.1, 3.5970, 632.7837 },
+	{ 153.7, 3.1347, 625.6702 },
+	{ 147.8, 0.1361, 302.1648 },
+	{ 123.2, 4.1890, 88.8657 },
+	{ 133.1, 2.5935, 191.9585 },
+	{ 100.4, 5.4606, 3.1814 },
+	{ 132.0, 5.9329, 309.2783 },
+	{ 97.2, 4.018, 728.763 },
+	{ 110.7, 4.7785, 838.9693 },
+	{ 119.1, 5.5539, 224.3448 },
+	{ 93.9, 4.384, 217.231 },
+	{ 108.7, 5.2931, 515.4639 },
+	{ 78.6, 5.725, 21.341 },
+	{ 81.5, 5.109, 956.289 },
+	{ 96.4, 6.259, 742.990 },
+	{ 69.2, 4.049, 3.932 },
+	{ 65.2, 3.777, 1052.268 },
+	{ 64.1, 5.812, 529.691 },
+	{ 62.5, 2.184, 195.140 },
+	{ 57.0, 3.147, 203.004 },
+	{ 56.0, 4.841, 234.640 },
+	{ 52.9, 5.078, 330.619 },
+	{ 50.6, 2.773, 942.062 },
+	{ 41.6, 4.790, 63.736 },
+	{ 44.9, 0.565, 269.921 },
+	{ 41.4, 3.735, 316.392 },
+	{ 52.8, 3.926, 949.176 },
+	{ 38.4, 3.740, 1045.155 },
+	{ 37.6, 4.189, 536.805 },
+	{ 35.3, 2.908, 284.149 },
+	{ 33.6, 3.805, 149.563 },
+	{ 41.1, 4.579, 1155.361 },
+	{ 30.4, 2.481, 860.310 },
+	{ 31.4, 4.841, 1272.681 },
+	{ 30.2, 4.352, 405.258 },
+	{ 39.4, 3.509, 422.666 },
+	{ 29.7, 1.589, 1066.495 },
+	{ 35.2, 5.945, 1059.382 },
+	{ 25.8, 3.549, 1368.660 },
+	{ 26.3, 4.816, 124.433 },
+	{ 30.0, 3.663, 429.780 },
+	{ 33.0, 4.969, 831.856 },
+	{ 24.3, 5.311, 10.295 },
+	{ 26.3, 4.453, 223.594 },
+	{ 22.1, 2.761, 415.552 },
+	{ 27.2, 1.663, 277.035 },
+	{ 21.6, 1.038, 11.046 },
+	{ 19.7, 2.522, 1258.454 },
+	{ 17.1, 3.277, 654.124 },
+	{ 17.3, 3.494, 1361.547 },
+	{ 16.1, 1.734, 490.334 },
+	{ 21.1, 3.621, 1265.567 },
+	{ 17.7, 4.311, 1471.753 },
+	{ 13.5, 0.323, 295.051 },
+	{ 12.6, 3.138, 74.782 },
+	{ 12.0, 2.329, 210.851 },
+	{ 15.1, 3.596, 265.989 },
+	{ 13.0, 4.624, 1589.073 },
+	{ 15.4, 5.013, 127.472 },
+	{ 11.2, 4.550, 81.752 },
+	{ 13.4, 4.887, 437.644 },
+	{ 10.7, 5.052, 191.208 },
+	{ 14.0, 3.050, 423.417 },
+	{ 10.6, 5.028, 137.033 },
+	{ 14.4, 4.687, 1148.248 },
+	{ 13.5, 1.903, 408.439 },
+	{ 10.1, 5.204, 340.771 },
+	{ 10.3, 3.345, 1685.052 },
+	{ 9.6, 3.17, 351.82 },
+	{ 11.3, 5.478, 1375.774 },
+	{ 8.6, 2.81, 99.91 },
+	{ 8.5, 3.23, 1677.94 },
+	{ 7.9, 2.36, 1574.85 },
+	{ 7.6, 6.08, 231.46 },
+	{ 9.2, 3.40, 1581.96 },
+	{ 7.3, 2.00, 131.40 },
+	{ 8.2, 4.04, 1788.14 },
+	{ 7.6, 3.68, 846.08 },
+	{ 6.7, 4.37, 145.63 },
+	{ 7.5, 3.29, 750.10 },
+	{ 6.4, 4.00, 447.94 },
+	{ 6.2, 4.56, 106.27 },
+	{ 6.5, 1.34, 215.75 },
+	{ 6.5, 3.78, 313.21 },
+	{ 6.0, 0.55, 18.16 },
+	{ 6.2, 2.85, 138.52 },
+	{ 6.8, 4.83, 319.57 },
+	{ 6.7, 5.43, 508.35 },
+	{ 7.2, 4.38, 1464.64 },
+	{ 5.8, 4.14, 543.92 },
+	{ 5.7, 4.35, 1905.46 },
+	{ 5.1, 2.64, 288.08 },
+	{ 5.3, 3.63, 6076.89 },
+	{ 5.5, 4.20, 721.65 },
+	{ 5.1, 5.05, 10007.10 },
+	{ 5.5, 1.13, 56.62 },
+	{ 4.8, 3.30, 76.27 },
+	{ 4.9, 6.18, 483.22 },
+	{ 5.0, 2.45, 628.85 },
+	{ 4.5, 1.20, 200.77 },
+	{ 4.8, 3.12, 2001.44 },
+	{ 4.7, 1.27, 6062.66 },
+	{ 4.8, 5.78, 184.84 },
+	{ 4.8, 0.76, 333.66 },
+	{ 4.5, 0.95, 343.22 },
+	{ 4.5, 2.69, 9992.87 },
+	{ 4.4, 0.80, 222.86 },
+	{ 4.9, 5.92, 618.56 },
+	{ 4.1, 1.92, 497.45 },
+	{ 5.1, 4.50, 416.30 },
+	{ 4.1, 1.98, 347.88 },
+	{ 4.0, 2.88, 38.13 },
+	{ 4.1, 2.90, 107.02 },
+	{ 4.0, 2.93, 1994.33 },
+	{ 4.9, 3.12, 1898.35 },
+	{ 3.7, 3.25, 362.86 },
+	{ 3.8, 0.88, 703.63 },
+	{ 3.6, 3.48, 388.47 },
+	{ 3.6, 4.08, 430.53 },
+	{ 3.6, 0.05, 32.24 },
+	{ 3.6, 5.46, 6283.08 },
+	{ 3.5, 1.82, 70.85 },
+	{ 3.8, 3.12, 635.97 },
+	{ 3.4, 0.55, 10213.29 },
+	{ 3.4, 3.52, 629.60 },
+	{ 3.4, 3.28, 357.45 },
+	{ 3.3, 1.98, 203.74 },
+	{ 3.1, 2.18, 1891.24 },
+	{ 3.2, 1.26, 134.59 },
+	{ 4.0, 5.45, 1692.17 },
+	{ 3.2, 2.46, 867.42 },
+	{ 3.4, 4.21, 337.73 },
+	{ 3.0, 2.19, 217.96 },
+	{ 3.6, 5.55, 113.39 },
+	{ 3.7, 3.79, 2104.54 },
+	{ 3.1, 4.09, 1478.87 },
+	{ 2.9, 3.91, 312.20 },
+	{ 3.2, 3.92, 1038.04 },
+	{ 4.0, 5.18, 404.51 },
+	{ 3.9, 4.12, 1781.03 },
+	{ 3.1, 1.61, 1073.61 },
+	{ 3.1, 5.01, 312.46 },
+	{ 3.0, 5.46, 258.88 },
+	{ 2.9, 2.38, 181.06 },
+	{ 3.0, 0.89, 1279.79 },
+	{ 2.7, 0.01, 195.89 },
+	{ 3.1, 5.60, 216.22 },
+	{ 2.6, 6.13, 273.10 },
+	{ 2.7, 2.32, 565.12 },
+	{ 3.2, 3.88, 85.83 },
+	{ 2.7, 5.74, 160.61 },
+	{ 2.9, 4.75, 213.25 },
+	{ 2.5, 5.30, 444.76 },
+	{ 2.8, 5.09, 1169.59 },
+	{ 2.9, 1.67, 213.35 },
+	{ 2.9, 4.21, 650.94 },
+	{ 3.0, 2.55, 6069.78 },
+	{ 3.1, 2.67, 52.69 },
+	{ 2.4, 0.90, 121.25 },
+	{ 3.0, 3.97, 9999.99 },
+	{ 3.1, 0.41, 561.18 },
+	{ 2.4, 4.74, 218.72 },
+	{ 2.6, 1.13, 344.70 },
+	{ 2.3, 4.08, 131.55 },
+	{ 2.2, 3.38, 22.09 },
+	{ 2.1, 3.32, 358.93 },
+	{ 2.7, 1.69, 208.63 },
+	{ 2.6, 5.10, 824.74 },
+	{ 2.2, 2.60, 305.35 },
+	{ 2.1, 3.37, 320.32 },
+	{ 2.7, 3.62, 436.89 },
+	{ 2.5, 2.96, 2214.74 },
+	{ 2.7, 2.88, 643.08 },
+	{ 2.1, 1.61, 218.93 },
+	{ 2.0, 4.63, 188.03 },
+	{ 2.4, 3.46, 6275.96 },
+	{ 2.0, 2.29, 2627.11 },
+	{ 1.9, 5.67, 28.45 },
+	{ 1.9, 4.26, 546.96 },
+	{ 2.5, 3.58, 2420.93 },
+	{ 1.9, 1.31, 212.34 },
+	{ 1.9, 1.59, 424.15 },
+	{ 1.9, 3.58, 329.73 },
+	{ 2.1, 3.95, 1795.26 },
+	{ 2.2, 4.22, 2221.86 },
+	{ 1.9, 1.69, 350.33 },
+	{ 1.8, 2.07, 144.15 },
+	{ 1.9, 4.61, 182.28 },
+	{ 2.2, 5.18, 99.16 },
+	{ 1.8, 2.73, 291.26 },
+	{ 2.2, 5.43, 207.88 },
+	{ 1.8, 2.24, 168.05 },
+	{ 1.7, 1.32, 219.45 },
+	{ 1.7, 5.56, 92.80 },
+	{ 1.7, 1.95, 129.92 },
+	{ 2.1, 4.85, 1141.13 },
+	{ 1.8, 5.05, 214.26 },
+	{ 1.8, 2.86, 636.72 },
+	{ 1.9, 2.90, 2310.72 },
+	{ 1.8, 5.35, 45.58 },
+	{ 1.7, 6.14, 554.07 },
+	{ 1.6, 4.51, 210.38 },
+	{ 1.7, 3.55, 1354.43 },
+	{ 1.9, 3.01, 2317.84 },
+	{ 1.6, 1.16, 235.39 },
+	{ 1.9, 4.13, 225.83 },
+	{ 1.6, 3.30, 1670.83 },
+	{ 1.9, 0.18, 12.53 },
+	{ 1.6, 5.73, 1485.98 },
+	{ 1.7, 3.44, 2428.04 },
+	{ 1.8, 2.70, 12.74 },
+	{ 1.7, 4.98, 2008.56 },
+	/* 239 terms retained, 103 terms dropped, error 5.2e-07 a.u.*T^2 */
+
+	/* saturn r, T^3 */
+	{ 20315.0, 3.021866, 213.299095 },
+	{ 8923.6, 3.19144, 220.41264 },
+	{ 6908.7, 4.35175, 206.18555 },
+	{ 4087.1, 4.22407, 7.11355 },
+	{ 3879.0, 2.01056, 426.59819 },
+	{ 1070.8, 4.20360, 199.07200 },
+	{ 907.3, 2.2834, 433.7117 },
+	{ 606.1, 3.1746, 227.5262 },
+	{ 596.6, 4.1346, 14.2271 },
+	{ 483.2, 1.1735, 639.8973 },
+	{ 393.2, 0, 0 },
+	{ 229.5, 4.6984, 419.4846 },
+	{ 188.2, 4.5900, 110.2063 },
+	{ 149.5, 3.2020, 103.0928 },
+	{ 121.4, 3.7683, 323.5054 },
+	{ 101.2, 5.8188, 412.3711 },
+	{ 102.1, 4.7097, 95.9792 },
+	{ 93.1, 1.435, 647.011 },
+	{ 72.6, 4.154, 117.320 },
+	{ 84.3, 2.635, 216.480 },
+	{ 62.2, 2.312, 440.825 },
+	{ 45.1, 4.373, 191.958 },
+	{ 49.5, 2.389, 209.367 },
+	{ 54.8, 0.305, 853.196 },
+	{ 40.5, 1.838, 302.165 },
+	{ 38.1, 5.945, 88.866 },
+	{ 32.2, 4.011, 21.341 },
+	{ 40.7, 0.688, 522.577 },
+	{ 28.2, 5.772, 210.118 },
+	{ 25.0, 3.062, 234.640 },
+	{ 20.8, 4.926, 625.670 },
+	{ 25.1, 0.731, 515.464 },
+	{ 17.5, 5.731, 728.763 },
+	{ 18.0, 1.456, 309.278 },
+	{ 16.9, 3.528, 3.181 },
+	{ 13.4, 3.365, 330.619 },
+	{ 11.1, 3.372, 224.345 },
+	{ 11.1, 3.417, 956.289 },
+	{ 10.0, 1.588, 202.253 },
+	{ 11.6, 5.991, 735.877 },
+	{ 10.5, 6.069, 405.258 },
+	{ 9.1, 2.94, 124.43 },
+	{ 8.7, 4.65, 632.78 },
+	{ 10.0, 0.582, 860.310 },
+	{ 7.5, 4.51, 942.06 },
+	{ 10.1, 0.283, 838.969 },
+	{ 9.2, 2.57, 223.59 },
+	{ 8.7, 1.76, 429.78 },
+	{ 7.6, 1.46, 654.12 },
+	{ 7.1, 5.47, 1045.15 },
+	{ 7.0, 1.52, 422.67 },
+	{ 8.1, 4.48, 742.99 },
+	{ 6.8, 4.83, 316.39 },
+	{ 7.7, 0.44, 831.86 },
+	{ 7.9, 4.20, 195.14 },
+	{ 6.1, 2.34, 269.92 },
+	{ 5.6, 1.15, 284.15 },
+	{ 5.6, 4.18, 529.69 },
+	{ 5.0, 2.12, 295.05 },
+	{ 6.6, 3.42, 10.29 },
+	{ 5.5, 2.47, 536.80 },
+	{ 6.2, 6.01, 1066.50 },
+	{ 5.6, 0.83, 217.23 },
+	{ 4.3, 3.23, 1272.68 },
+	{ 4.5, 0.92, 203.00 },
+	{ 3.3, 4.33, 1258.45 },
+	{ 3.7, 0.06, 81.75 },
+	{ 4.0, 0.11, 1155.36 },
+	{ 3.8, 6.01, 1052.27 },
+	{ 2.9, 5.64, 3.93 },
+	{ 3.0, 2.19, 447.94 },
+	{ 3.0, 1.89, 149.56 },
+	{ 3.1, 0.19, 1148.25 },
+	{ 2.8, 0.92, 508.35 },
+	{ 2.8, 4.97, 1677.94 },
+	{ 2.6, 3.00, 1589.07 },
+	{ 2.9, 5.41, 1361.55 },
+	{ 2.3, 1.30, 184.84 },
+	{ 2.5, 3.71, 408.44 },
+	{ 2.5, 3.22, 319.57 },
+	{ 2.6, 2.31, 543.92 },
+	{ 2.3, 5.88, 721.65 },
+	{ 2.0, 0.52, 416.30 },
+	{ 2.5, 4.24, 1059.38 },
+	{ 1.9, 2.41, 337.73 },
+	{ 1.9, 0.54, 635.97 },
+	{ 1.9, 5.62, 11.05 },
+	{ 2.4, 5.73, 313.21 },
+	{ 1.9, 2.41, 131.55 },
+	{ 1.7, 4.58, 1994.33 },
+	{ 1.9, 5.17, 2854.64 },
+	{ 1.9, 6.23, 1471.75 },
+	{ 2.0, 6.18, 1464.64 },
+	{ 1.8, 5.59, 1038.04 },
+	{ 1.5, 0.61, 210.85 },
+	{ 1.6, 1.75, 195.89 },
+	{ 1.6, 0.56, 2324.95 },
+	{ 1.5, 0.27, 497.45 },
+	{ 1.7, 2.58, 2090.31 },
+	{ 1.8, 1.82, 436.89 },
+	{ 1.6, 6.15, 490.33 },
+	{ 1.8, 6.12, 1073.61 },
+	{ 1.5, 0.85, 415.55 },
+	{ 1.6, 2.95, 437.64 },
+	{ 1.4, 4.12, 1574.85 },
+	{ 1.6, 5.97, 1781.03 },
+	{ 1.5, 3.85, 1251.34 },
+	{ 1.4, 5.33, 2538.25 },
+	{ 1.8, 1.51, 750.10 },
+	{ 1.5, 3.29, 1884.12 },
+	{ 1.5, 0.99, 643.08 },
+	{ 1.3, 3.79, 1567.73 },
+	{ 1.7, 0.03, 423.42 },
+	{ 1.5, 5.35, 1354.43 },
+	{ 1.4, 0.70, 867.42 },
+	{ 1.1, 1.80, 618.56 },
+	{ 1.1, 4.70, 113.39 },
+	{ 1.1, 3.96, 1891.24 },
+	{ 1.5, 1.50, 430.53 },
+	{ 1.1, 5.13, 25.27 },
+	{ 1.2, 2.97, 241.75 },
+	{ 1.3, 2.29, 2420.93 },
+	{ 1.1, 0.05, 63.74 },
+	{ 1.4, 5.58, 1382.89 },
+	{ 1.1, 3.11, 2200.52 },
+	{ 1.1, 0.79, 127.47 },
+	{ 1.0, 5.85, 215.75 },
+	{ 1.1, 3.73, 131.40 },
+	{ 1.2, 0.48, 824.74 },
+	{ 1.1, 3.78, 1375.77 },
+	{ 1.0, 5.91, 265.99 },
+	{ 1.2, 1.41, 2634.23 },
+	{ 1.1, 4.80, 1987.22 },
+	{ 0.9, 6.26, 2015.67 },
+	{ 1.0, 1.09, 362.86 },
+	{ 1.1, 5.42, 1279.79 },
+	{ 0.9, 1.92, 483.22 },
+	{ 0.9, 2.97, 934.95 },
+	{ 0.9, 2.66, 145.63 },
+	{ 0.9, 6.26, 2.45 },
+	{ 1.1, 4.48, 2214.74 },
+	{ 1.0, 0.74, 16.67 },
+	{ 1.0, 4.06, 231.46 },
+	{ 0.9, 0.09, 628.85 },
+	{ 0.9, 5.99, 2524.02 },
+	{ 0.9, 3.16, 2207.63 },
+	{ 0.8, 1.24, 74.78 },
+	{ 0.8, 2.90, 2008.56 },
+	{ 0.8, 2.28, 1478.87 },
+	{ 1.0, 5.33, 2428.04 },
+	{ 0.8, 2.38, 2228.97 },
+	{ 0.8, 4.70, 1670.83 },
+	{ 1.0, 4.23, 1802.37 },
+	{ 0.8, 5.87, 1368.66 },
+	{ 0.7, 5.92, 1685.05 },
+	{ 0.8, 1.16, 3053.71 },
+	{ 0.7, 3.13, 56.62 },
+	/* 157 terms retained, 0 terms dropped, error 1.7e-07 a.u.*T^3 */
+
+	/* saturn r, T^4 */
+	{ 1202.0, 1.41499, 220.41264 },
+	{ 707.8, 1.1615, 213.2991 },
+	{ 516.1, 6.2397, 206.1855 },
+	{ 426.7, 2.4692, 7.1135 },
+	{ 267.7, 0.1866, 426.5982 },
+	{ 170.2, 5.9593, 199.0720 },
+	{ 145.1, 1.4421, 227.5262 },
+	{ 150.3, 0.4797, 433.7117 },
+	{ 121.0, 2.4053, 14.2271 },
+	{ 47.3, 5.569, 639.897 },
+	{ 15.7, 2.901, 110.206 },
+	{ 16.7, 0.529, 440.825 },
+	{ 19.0, 5.856, 647.011 },
+	{ 14.1, 1.303, 412.371 },
+	{ 12.7, 2.093, 323.505 },
+	{ 14.7, 0.299, 419.485 },
+	{ 11.1, 2.463, 117.320 },
+	{ 11.3, 0.218, 95.979 },
+	{ 9.2, 2.28, 21.34 },
+	{ 9.2, 1.56, 88.87 },
+	{ 9.0, 0.68, 216.48 },
+	{ 7.7, 3.59, 302.16 },
+	{ 7.8, 4.49, 853.20 },
+	{ 8.4, 1.27, 234.64 },
+	{ 9.6, 3.14, 0 },
+	{ 4.8, 2.59, 515.46 },
+	{ 6.1, 5.17, 103.09 },
+	{ 4.4, 0.02, 191.96 },
+	{ 4.4, 1.60, 330.62 },
+	{ 3.7, 3.30, 210.12 },
+	{ 4.4, 5.97, 654.12 },
+	{ 4.4, 4.97, 860.31 },
+	{ 3.2, 2.73, 522.58 },
+	{ 4.0, 1.60, 405.26 },
+	{ 3.1, 0.75, 209.37 },
+	{ 2.5, 1.19, 124.43 },
+	{ 3.1, 1.32, 728.76 },
+	{ 2.2, 3.28, 203.00 },
+	{ 2.1, 6.15, 429.78 },
+	{ 2.1, 0.75, 295.05 },
+	{ 2.0, 3.89, 1066.50 },
+	{ 2.2, 0.49, 447.94 },
+	{ 2.2, 0.73, 625.67 },
+	{ 1.8, 0.09, 942.06 },
+	{ 1.7, 1.40, 224.34 },
+	{ 1.6, 3.02, 184.84 },
+	{ 1.8, 0.82, 223.59 },
+	{ 1.9, 2.00, 831.86 },
+	{ 1.6, 5.41, 824.74 },
+	{ 1.5, 5.96, 422.67 },
+	{ 1.1, 1.12, 838.97 },
+	{ 1.2, 1.90, 956.29 },
+	{ 1.5, 2.12, 529.69 },
+	{ 1.4, 0.72, 536.80 },
+	{ 1.1, 0.89, 721.65 },
+	{ 1.3, 1.65, 17.41 },
+	{ 1.2, 5.97, 195.14 },
+	{ 1.0, 5.36, 316.39 },
+	{ 1.0, 3.06, 1574.85 },
+	{ 1.1, 1.59, 735.88 },
+	{ 0.8, 4.93, 56.62 },
+	{ 0.8, 2.72, 508.35 },
+	{ 1.0, 1.01, 1045.15 },
+	{ 0.7, 1.11, 1169.59 },
+	/* 64 terms retained, 0 terms dropped, error 1.2e-07 a.u.*T^4 */
+
+	/* saturn r, T^5 */
+	{ 128.6, 5.9128, 220.4126 },
+	{ 32.3, 0.693, 7.114 },
+	{ 26.7, 5.914, 227.526 },
+	{ 19.9, 0.674, 14.227 },
+	{ 20.2, 4.951, 433.712 },
+	{ 13.5, 1.457, 199.072 },
+	{ 14.1, 2.671, 206.186 },
+	{ 13.4, 4.588, 426.598 },
+	{ 7.3, 4.63, 213.30 },
+	{ 4.9, 3.61, 639.90 },
+	{ 3.1, 4.66, 191.96 },
+	{ 2.9, 0.49, 323.51 },
+	{ 3.8, 4.90, 440.83 },
+	{ 3.3, 4.07, 647.01 },
+	{ 2.9, 3.18, 419.48 },
+	{ 2.3, 3.70, 88.87 },
+	{ 1.9, 5.33, 302.16 },
+	{ 2.1, 3.32, 95.98 },
+	{ 1.6, 2.67, 853.20 },
+	{ 2.0, 0.56, 117.32 },
+	{ 1.6, 0.86, 515.46 },
+	{ 1.7, 0, 0 },
+	{ 1.1, 5.98, 3.18 },
+	{ 1.3, 5.83, 234.64 },
+	{ 0.9, 5.23, 216.48 },
+	{ 1.1, 0.16, 412.37 },
+	{ 0.8, 0.37, 28.45 },
+	{ 0.8, 5.05, 124.43 },
+	/* 28 terms retained, 0 terms dropped, error 9e-08 a.u.*T^5 */
+	/* end saturn */
+};
+
+int vn_saturn[][3] = {
+	/* addresses for saturn l, b, r  */
+	/* T^0 */ { 0, 592, 811, },
+	/* T^1 */ { 165, 645, 1099, },
+	/* T^2 */ { 303, 698, 1345, },
+	/* T^3 */ { 418, 744, 1584, },
+	/* T^4 */ { 500, 777, 1741, },
+	/* T^5 */ { 566, 803, 1805, },
+	/* end */ { 592, 811, 1833, },
+	/* termination */ { 0, }
+};
+
+/*  version d4 (lbr)       
+ *  heliocentric dynamical ecliptic and equinox of the date
+ */
+
+double vx_uranus[][3] = {
+	/* uranus l, T^0 */
+	{ 548129294.3, 0, 0 },
+	{ 9260408.3, 0.89106422, 74.78159857 },
+	{ 1504247.8, 3.62719262, 1.48447271 },
+	{ 365981.7, 1.8996219, 73.2971259 },
+	{ 272328.1, 3.3582371, 149.5631971 },
+	{ 70328.5, 5.392544, 63.735898 },
+	{ 68892.6, 6.092925, 76.266071 },
+	{ 61998.6, 2.269520, 2.968945 },
+	{ 61950.7, 2.850989, 11.045700 },
+	{ 26468.9, 3.141521, 71.812653 },
+	{ 25710.5, 6.113798, 454.909367 },
+	{ 21078.9, 4.360595, 148.078724 },
+	{ 17818.7, 1.744370, 36.648563 },
+	{ 14613.5, 4.737320, 3.932153 },
+	{ 11162.5, 5.826820, 224.344796 },
+	{ 10997.9, 0.488655, 138.517497 },
+	{ 9527.5, 2.95517, 35.16409 },
+	{ 7545.5, 5.23626, 109.94569 },
+	{ 4220.2, 3.23329, 70.84945 },
+	{ 4051.9, 2.27754, 151.04767 },
+	{ 3354.6, 1.06549, 4.45342 },
+	{ 2926.7, 4.62904, 9.56123 },
+	{ 3490.4, 5.48306, 146.59425 },
+	{ 3144.1, 4.75199, 77.75054 },
+	{ 2922.4, 5.35237, 85.82730 },
+	{ 2272.8, 4.36601, 70.32818 },
+	{ 2051.2, 1.51774, 0.11187 },
+	{ 2148.6, 0.60746, 38.13304 },
+	{ 1991.7, 4.92437, 277.03499 },
+	{ 1376.2, 2.04281, 65.22037 },
+	{ 1666.9, 3.62745, 380.12777 },
+	{ 1284.2, 3.11346, 202.25340 },
+	{ 1150.4, 0.93344, 3.18139 },
+	{ 1533.2, 2.58593, 52.69020 },
+	{ 1281.6, 0.54270, 222.86032 },
+	{ 1372.1, 4.19642, 111.43016 },
+	{ 1221.0, 0.19901, 108.46122 },
+	{ 946.2, 1.1925, 127.4718 },
+	{ 1151.0, 4.17898, 33.67962 },
+	{ 1244.3, 0.91613, 2.44768 },
+	{ 1072.0, 0.23565, 62.25143 },
+	{ 1090.5, 1.77502, 12.53017 },
+	{ 707.9, 5.1829, 213.2991 },
+	{ 653.4, 0.9659, 78.7138 },
+	{ 627.6, 0.1821, 984.6003 },
+	{ 524.5, 2.0128, 299.1264 },
+	{ 559.4, 3.3578, 0.5213 },
+	{ 606.8, 5.4321, 529.6910 },
+	{ 404.9, 5.9869, 8.0768 },
+	{ 467.2, 0.4148, 145.1098 },
+	{ 471.3, 1.4066, 184.7273 },
+	{ 483.2, 2.1055, 0.9632 },
+	{ 395.6, 5.8704, 351.8166 },
+	{ 433.5, 5.5214, 183.2428 },
+	{ 309.9, 5.8330, 145.6310 },
+	{ 378.6, 2.3498, 56.6224 },
+	{ 399.0, 0.3381, 415.5525 },
+	{ 300.4, 5.6435, 22.0914 },
+	{ 249.2, 4.7462, 225.8293 },
+	{ 239.3, 2.3505, 137.0330 },
+	{ 294.2, 5.8392, 39.6175 },
+	{ 216.5, 4.7785, 340.7709 },
+	{ 251.8, 1.6370, 221.3759 },
+	{ 219.6, 1.9221, 67.6681 },
+	{ 202.0, 1.2969, 0.0482 },
+	{ 224.1, 0.5157, 84.3428 },
+	{ 216.5, 6.1421, 5.9379 },
+	{ 222.6, 2.8431, 0.2606 },
+	{ 207.8, 5.5802, 68.8437 },
+	{ 187.5, 1.3192, 0.1601 },
+	{ 158.0, 0.7381, 54.1747 },
+	{ 199.1, 0.9563, 152.5321 },
+	{ 168.6, 5.8787, 18.1592 },
+	{ 170.3, 3.6772, 5.4166 },
+	{ 193.7, 1.8880, 456.3938 },
+	{ 193.0, 0.9162, 453.4249 },
+	{ 181.9, 3.5362, 79.2350 },
+	{ 173.1, 1.5386, 160.6089 },
+	{ 164.6, 1.4238, 106.9767 },
+	{ 172.0, 5.6795, 219.8914 },
+	{ 162.8, 3.0503, 112.9146 },
+	{ 146.7, 1.2630, 59.8037 },
+	{ 139.5, 5.3860, 32.1951 },
+	{ 138.6, 4.2599, 909.8187 },
+	{ 143.1, 1.3000, 35.4247 },
+	{ 123.8, 1.3736, 7.1135 },
+	{ 104.4, 5.0282, 0.7508 },
+	{ 103.3, 0.6810, 14.9779 },
+	{ 94.7, 0.907, 74.670 },
+	{ 83.0, 2.928, 265.989 },
+	{ 110.2, 2.0269, 554.0700 },
+	{ 94.2, 3.943, 74.893 },
+	{ 79.9, 1.014, 6.592 },
+	{ 109.4, 5.7058, 77.9630 },
+	{ 85.9, 1.706, 82.858 },
+	{ 103.6, 1.4577, 24.3790 },
+	{ 74.7, 4.632, 69.365 },
+	{ 79.9, 3.010, 297.642 },
+	{ 84.5, 0.369, 186.212 },
+	{ 88.8, 0.525, 181.758 },
+	{ 70.3, 1.190, 66.705 },
+	{ 70.0, 0.875, 305.346 },
+	{ 69.9, 3.761, 131.404 },
+	{ 84.6, 5.887, 256.540 },
+	{ 74.3, 6.243, 447.796 },
+	{ 62.3, 0.169, 479.288 },
+	{ 72.7, 2.849, 462.023 },
+	{ 69.1, 4.439, 39.357 },
+	{ 76.6, 4.587, 6.220 },
+	{ 73.4, 4.276, 87.312 },
+	{ 55.3, 1.496, 71.600 },
+	{ 57.3, 1.630, 143.625 },
+	{ 61.7, 3.186, 77.229 },
+	{ 57.6, 3.672, 51.206 },
+	{ 50.3, 1.123, 20.607 },
+	{ 53.7, 5.519, 128.956 },
+	{ 57.9, 2.669, 381.612 },
+	{ 58.1, 1.586, 60.767 },
+	{ 45.4, 0.481, 14.015 },
+	{ 37.6, 6.068, 211.815 },
+	{ 38.6, 3.436, 153.495 },
+	{ 46.1, 4.362, 75.745 },
+	{ 40.1, 4.573, 46.210 },
+	{ 34.2, 2.940, 140.002 },
+	{ 38.7, 5.589, 99.161 },
+	{ 34.8, 1.028, 203.738 },
+	{ 40.0, 0.699, 218.407 },
+	{ 32.5, 4.216, 200.769 },
+	{ 31.9, 5.510, 72.334 },
+	{ 41.7, 3.824, 81.001 },
+	{ 34.8, 0.394, 1.373 },
+	{ 39.8, 6.056, 293.189 },
+	{ 27.6, 2.183, 125.987 },
+	{ 36.3, 1.666, 258.024 },
+	{ 35.4, 1.967, 835.037 },
+	{ 35.4, 3.723, 692.587 },
+	{ 27.3, 2.102, 209.367 },
+	{ 26.5, 4.483, 373.908 },
+	{ 34.5, 1.079, 191.208 },
+	{ 29.9, 3.874, 259.509 },
+	{ 26.2, 3.632, 490.334 },
+	{ 25.8, 0.545, 41.644 },
+	{ 27.0, 6.277, 28.572 },
+	{ 26.4, 5.811, 75.303 },
+	{ 34.2, 6.056, 275.551 },
+	{ 29.9, 1.888, 269.921 },
+	{ 26.2, 6.201, 134.585 },
+	{ 25.2, 5.425, 116.426 },
+	{ 26.5, 4.772, 284.149 },
+	{ 27.0, 4.753, 41.102 },
+	{ 28.9, 0.171, 528.206 },
+	{ 25.8, 0.746, 278.519 },
+	/* 152 terms retained, 795 terms dropped, error 1.3" */
+
+	/* uranus l, T^1 */
+	{ 7502543121.6, 0, 0 },
+	{ 154458.2, 5.2420166, 74.7815986 },
+	{ 24456.4, 1.712557, 1.484473 },
+	{ 9257.8, 0.42845, 11.04570 },
+	{ 8266.0, 1.50220, 63.73590 },
+	{ 7841.7, 1.31984, 149.56320 },
+	{ 3899.1, 0.46484, 3.93215 },
+	{ 2283.8, 4.17368, 76.26607 },
+	{ 1926.6, 0.53013, 2.96895 },
+	{ 1232.7, 1.58634, 70.84945 },
+	{ 791.2, 5.4364, 3.1814 },
+	{ 767.0, 1.9956, 73.2971 },
+	{ 481.7, 2.9840, 85.8273 },
+	{ 449.8, 4.1383, 138.5175 },
+	{ 445.6, 3.7230, 224.3448 },
+	{ 426.6, 4.7313, 71.8127 },
+	{ 347.7, 2.4537, 9.5612 },
+	{ 353.8, 2.5832, 148.0787 },
+	{ 317.1, 5.5786, 52.6902 },
+	{ 179.9, 5.6837, 12.5302 },
+	{ 171.1, 3.0006, 78.7138 },
+	{ 205.6, 2.3626, 2.4477 },
+	{ 158.0, 2.9093, 0.9632 },
+	{ 189.1, 4.2024, 56.6224 },
+	{ 154.7, 5.5908, 4.4534 },
+	{ 183.8, 0.2837, 151.0477 },
+	{ 143.5, 2.5905, 62.2514 },
+	{ 152.0, 2.9422, 77.7505 },
+	{ 153.5, 4.6519, 35.1641 },
+	{ 121.5, 4.1484, 127.4718 },
+	{ 115.5, 3.7322, 65.2204 },
+	{ 102.0, 4.1875, 145.6310 },
+	{ 101.7, 6.0339, 0.1119 },
+	{ 88.2, 3.990, 18.159 },
+	{ 87.5, 6.155, 202.253 },
+	{ 80.5, 2.641, 22.091 },
+	{ 72.0, 6.045, 70.328 },
+	{ 68.6, 4.051, 77.963 },
+	{ 59.2, 3.704, 67.668 },
+	{ 47.3, 3.543, 351.817 },
+	{ 42.5, 5.724, 5.417 },
+	{ 44.3, 5.909, 7.114 },
+	{ 35.6, 3.292, 8.077 },
+	{ 35.5, 3.328, 71.600 },
+	{ 36.1, 5.900, 33.680 },
+	{ 30.6, 5.464, 160.609 },
+	{ 31.5, 5.620, 984.600 },
+	{ 38.5, 4.915, 222.860 },
+	{ 35.0, 5.080, 38.133 },
+	{ 30.8, 5.496, 59.804 },
+	{ 28.9, 4.519, 84.343 },
+	{ 26.6, 5.541, 131.404 },
+	{ 29.9, 1.660, 447.796 },
+	{ 29.2, 1.147, 462.023 },
+	{ 25.8, 4.994, 137.033 },
+	{ 25.4, 5.736, 380.128 },
+	{ 21.7, 2.806, 69.365 },
+	{ 26.6, 6.146, 299.126 },
+	{ 23.0, 2.249, 111.430 },
+	{ 19.2, 3.556, 54.175 },
+	{ 21.8, 0.933, 213.299 },
+	{ 19.3, 1.862, 108.461 },
+	{ 16.2, 3.102, 14.978 },
+	{ 13.1, 1.954, 87.312 },
+	{ 13.9, 1.541, 340.771 },
+	{ 13.5, 4.385, 5.938 },
+	{ 13.1, 5.883, 6.220 },
+	{ 11.8, 0.326, 35.425 },
+	{ 11.0, 1.692, 45.577 },
+	{ 12.4, 0.328, 51.206 },
+	{ 10.9, 5.971, 265.989 },
+	{ 11.4, 3.378, 72.334 },
+	{ 12.0, 3.604, 269.921 },
+	{ 11.7, 1.745, 79.235 },
+	{ 13.8, 2.690, 225.829 },
+	{ 12.0, 5.344, 152.532 },
+	{ 9.9, 5.50, 153.50 },
+	{ 10.4, 4.169, 24.379 },
+	{ 10.6, 3.069, 284.149 },
+	{ 9.6, 0.50, 209.37 },
+	{ 9.3, 3.54, 41.64 },
+	{ 9.5, 5.60, 82.86 },
+	{ 9.7, 1.01, 68.84 },
+	{ 9.2, 4.49, 20.61 },
+	{ 10.2, 3.518, 529.691 },
+	{ 8.6, 3.89, 60.77 },
+	{ 10.0, 4.648, 77.229 },
+	{ 8.7, 1.97, 195.14 },
+	{ 8.4, 4.41, 134.59 },
+	{ 9.3, 3.93, 39.62 },
+	{ 7.8, 5.36, 75.74 },
+	{ 7.7, 5.77, 73.82 },
+	{ 7.7, 4.44, 14.01 },
+	{ 8.4, 2.44, 146.59 },
+	{ 8.0, 5.73, 184.73 },
+	{ 7.5, 2.19, 145.11 },
+	{ 6.4, 0.85, 32.20 },
+	{ 6.3, 2.17, 74.89 },
+	{ 7.9, 0.17, 120.36 },
+	{ 7.0, 4.12, 191.21 },
+	{ 6.9, 2.13, 116.43 },
+	/* 101 terms retained, 325 terms dropped, error 0.29"*T */
+
+	/* uranus l, T^2 */
+	{ 53033.3, 0, 0 },
+	{ 2357.6, 2.26015, 74.78160 },
+	{ 769.1, 4.5256, 11.0457 },
+	{ 551.5, 3.2581, 63.7359 },
+	{ 541.5, 2.2757, 3.9322 },
+	{ 529.5, 4.9235, 1.4845 },
+	{ 257.5, 3.6906, 3.1814 },
+	{ 238.8, 5.8581, 149.5632 },
+	{ 181.9, 6.2176, 70.8494 },
+	{ 49.4, 6.031, 56.622 },
+	{ 53.5, 1.442, 76.266 },
+	{ 38.2, 1.785, 52.690 },
+	{ 44.8, 3.909, 2.448 },
+	{ 44.5, 0.812, 85.827 },
+	{ 37.4, 4.462, 2.969 },
+	{ 33.0, 0.864, 9.561 },
+	{ 24.3, 2.107, 18.159 },
+	{ 29.4, 5.098, 73.297 },
+	{ 22.1, 4.817, 78.714 },
+	{ 22.5, 5.993, 138.517 },
+	{ 17.2, 2.535, 145.631 },
+	{ 21.4, 2.399, 77.963 },
+	{ 20.6, 2.169, 224.345 },
+	{ 16.8, 3.466, 12.530 },
+	{ 12.0, 0.019, 22.091 },
+	{ 10.5, 4.456, 62.251 },
+	{ 11.0, 0.085, 127.472 },
+	{ 8.7, 4.26, 7.11 },
+	{ 10.5, 5.165, 71.600 },
+	{ 7.2, 1.25, 5.42 },
+	{ 8.4, 5.50, 67.67 },
+	{ 6.1, 5.45, 65.22 },
+	{ 6.0, 4.52, 151.05 },
+	{ 5.7, 1.83, 202.25 },
+	{ 6.1, 3.36, 447.80 },
+	{ 6.0, 5.73, 462.02 },
+	{ 5.1, 3.52, 59.80 },
+	{ 5.2, 1.06, 131.40 },
+	{ 6.0, 5.61, 148.08 },
+	{ 5.1, 3.36, 4.45 },
+	{ 4.8, 1.20, 71.81 },
+	{ 4.0, 0.68, 77.75 },
+	{ 3.7, 1.76, 351.82 },
+	{ 3.1, 3.84, 45.58 },
+	{ 3.0, 3.32, 160.61 },
+	{ 3.0, 6.15, 77.23 },
+	{ 3.6, 4.57, 454.91 },
+	{ 2.7, 5.36, 269.92 },
+	{ 2.5, 1.05, 69.36 },
+	{ 2.3, 2.69, 84.34 },
+	{ 2.2, 5.08, 14.98 },
+	{ 2.2, 1.39, 284.15 },
+	{ 2.1, 4.35, 984.60 },
+	{ 2.1, 2.32, 120.36 },
+	{ 1.9, 5.70, 54.17 },
+	{ 2.0, 3.87, 195.14 },
+	{ 1.6, 5.08, 209.37 },
+	{ 1.6, 0.49, 137.03 },
+	{ 1.6, 2.91, 51.21 },
+	{ 1.7, 6.26, 41.64 },
+	{ 2.1, 1.24, 35.16 },
+	{ 1.7, 6.28, 277.03 },
+	/* 62 terms retained, 89 terms dropped, error 0.055"*T^2 */
+
+	/* uranus l, T^3 */
+	{ 120.9, 0.0242, 74.7816 },
+	{ 68.1, 4.121, 3.932 },
+	{ 52.8, 2.390, 11.046 },
+	{ 43.8, 2.960, 1.484 },
+	{ 45.3, 2.044, 3.181 },
+	{ 45.8, 0, 0 },
+	{ 25.0, 4.887, 63.736 },
+	{ 21.1, 4.545, 70.849 },
+	{ 19.9, 2.313, 149.563 },
+	{ 8.9, 1.58, 56.62 },
+	{ 4.3, 0.23, 18.16 },
+	{ 3.6, 5.39, 76.27 },
+	{ 3.5, 4.98, 85.83 },
+	{ 3.5, 4.13, 52.69 },
+	{ 3.6, 0.95, 77.96 },
+	{ 2.3, 0.86, 145.63 },
+	{ 2.7, 0.37, 78.71 },
+	{ 1.9, 2.68, 7.11 },
+	{ 2.2, 5.66, 9.56 },
+	{ 1.4, 4.87, 224.34 },
+	{ 1.3, 1.25, 12.53 },
+	{ 1.6, 0.49, 71.60 },
+	{ 1.5, 5.20, 73.30 },
+	{ 1.2, 3.93, 22.09 },
+	{ 0.9, 2.19, 127.47 },
+	{ 0.8, 3.98, 462.02 },
+	{ 0.8, 5.06, 447.80 },
+	{ 0.7, 0.35, 5.63 },
+	{ 0.7, 1.06, 138.52 },
+	{ 0.7, 2.94, 131.40 },
+	{ 0.5, 1.59, 151.05 },
+	{ 0.4, 4.33, 120.36 },
+	/* 32 terms retained, 14 terms dropped, error 0.0098"*T^3 */
+
+	/* uranus l, T^4 */
+	{ 113.9, 3.1416, 0 },
+	{ 5.6, 4.58, 74.78 },
+	{ 3.2, 0.35, 11.05 },
+	{ 1.2, 3.42, 56.62 },
+	{ 0.6, 4.66, 18.16 },
+	{ 0.2, 3.80, 149.56 },
+	{ 0.1, 4.36, 63.74 },
+	/* 7 terms retained, 0 terms dropped, error 0.0016"*T^4 */
+
+	/* uranus l, T^5 */
+	{ 0.9, 3.14, 0 },
+	/* 1 terms retained, 0 terms dropped, error 0.0051"*T^5 */
+	/* end uranus l */
+
+	/* uranus b, T^0 */
+	{ 1346277.6, 2.61877811, 74.78159857 },
+	{ 62341.4, 5.081112, 149.563197 },
+	{ 61601.2, 3.141593, 0 },
+	{ 9963.7, 1.61604, 76.26607 },
+	{ 9926.2, 0.57630, 73.29713 },
+	{ 3259.5, 1.26119, 224.34480 },
+	{ 2972.3, 2.24367, 1.48447 },
+	{ 2010.3, 6.05550, 148.07872 },
+	{ 1522.2, 0.27960, 63.73590 },
+	{ 924.1, 4.0382, 151.0477 },
+	{ 760.6, 6.1400, 71.8127 },
+	{ 420.3, 5.2128, 11.0457 },
+	{ 430.7, 3.5545, 213.2991 },
+	{ 436.8, 3.3808, 529.6910 },
+	{ 522.3, 3.3209, 138.5175 },
+	{ 434.6, 0.3407, 77.7505 },
+	{ 462.6, 0.7426, 85.8273 },
+	{ 232.6, 2.2572, 222.8603 },
+	{ 215.8, 1.5912, 38.1330 },
+	{ 244.7, 0.7880, 2.9689 },
+	{ 179.9, 3.7249, 299.1264 },
+	{ 174.9, 1.2355, 146.5943 },
+	{ 173.7, 1.9365, 380.1278 },
+	{ 160.4, 5.3364, 111.4302 },
+	{ 144.1, 5.9624, 35.1641 },
+	{ 102.0, 2.6188, 78.7138 },
+	{ 116.4, 5.7388, 70.8494 },
+	{ 106.4, 0.9410, 70.3282 },
+	{ 86.2, 0.703, 39.618 },
+	{ 72.6, 0.206, 225.829 },
+	{ 71.2, 0.833, 109.946 },
+	{ 57.5, 2.670, 108.461 },
+	{ 54.3, 3.352, 184.727 },
+	{ 44.5, 2.744, 152.532 },
+	{ 38.6, 5.174, 202.253 },
+	{ 39.2, 2.171, 351.817 },
+	{ 41.3, 3.221, 160.609 },
+	{ 35.1, 4.001, 112.915 },
+	{ 33.1, 3.614, 221.376 },
+	{ 31.3, 2.720, 145.110 },
+	{ 37.3, 4.021, 52.690 },
+	{ 32.0, 1.292, 145.631 },
+	{ 27.6, 3.701, 36.649 },
+	/* 43 terms retained, 240 terms dropped, error 0.75" */
+
+	/* uranus b, T^1 */
+	{ 206366.2, 4.1239431, 74.7815986 },
+	{ 8563.2, 0.33820, 149.56320 },
+	{ 1725.7, 2.12193, 73.29713 },
+	{ 1368.9, 3.06862, 76.26607 },
+	{ 1374.4, 0, 0 },
+	{ 399.8, 2.8477, 224.3448 },
+	{ 450.6, 3.7766, 1.4845 },
+	{ 307.2, 1.2546, 148.0787 },
+	{ 154.3, 3.7858, 63.7359 },
+	{ 110.9, 5.3289, 138.5175 },
+	{ 112.4, 5.5730, 151.0477 },
+	{ 83.5, 3.592, 71.813 },
+	{ 55.6, 3.401, 85.827 },
+	{ 41.4, 4.455, 78.714 },
+	{ 53.7, 1.705, 77.751 },
+	{ 41.9, 1.215, 11.046 },
+	{ 32.0, 3.774, 222.860 },
+	{ 30.3, 2.564, 2.969 },
+	{ 27.0, 5.337, 213.299 },
+	{ 26.2, 0.416, 380.128 },
+	{ 20.1, 5.931, 529.691 },
+	{ 23.0, 2.489, 146.594 },
+	{ 19.6, 5.372, 299.126 },
+	{ 20.4, 3.702, 70.849 },
+	{ 19.1, 1.092, 111.430 },
+	{ 19.4, 3.830, 38.133 },
+	{ 10.8, 2.663, 3.932 },
+	{ 10.2, 2.313, 109.946 },
+	{ 9.4, 2.77, 39.62 },
+	{ 7.7, 1.81, 225.83 },
+	{ 8.1, 4.69, 184.73 },
+	{ 6.6, 5.50, 35.16 },
+	{ 7.4, 1.18, 65.22 },
+	{ 6.5, 4.98, 71.60 },
+	/* 34 terms retained, 120 terms dropped, error 0.16"*T */
+
+	/* uranus b, T^2 */
+	{ 9211.7, 5.80044, 74.78160 },
+	{ 556.9, 0, 0 },
+	{ 286.3, 2.1773, 149.5632 },
+	{ 95.0, 3.842, 73.297 },
+	{ 45.4, 4.878, 76.266 },
+	{ 20.1, 5.463, 1.484 },
+	{ 14.8, 0.880, 138.517 },
+	{ 14.0, 5.072, 63.736 },
+	{ 14.3, 2.845, 148.079 },
+	{ 10.1, 5.003, 224.345 },
+	{ 8.3, 6.27, 78.71 },
+	{ 4.7, 5.16, 71.81 },
+	{ 3.8, 6.28, 85.83 },
+	{ 3.5, 3.53, 11.05 },
+	{ 2.6, 1.44, 151.05 },
+	{ 2.4, 4.23, 3.93 },
+	{ 2.6, 0.41, 71.60 },
+	/* 17 terms retained, 43 terms dropped, error 0.045"*T^2 */
+
+	/* uranus b, T^3 */
+	{ 267.8, 1.2510, 74.7816 },
+	{ 11.0, 3.142, 0 },
+	{ 6.2, 4.01, 149.56 },
+	{ 3.4, 5.78, 73.30 },
+	{ 1.6, 1.06, 63.74 },
+	{ 1.3, 1.67, 78.71 },
+	{ 1.2, 2.59, 138.52 },
+	{ 1.1, 0.29, 76.27 },
+	{ 0.6, 1.87, 71.60 },
+	{ 0.6, 0.80, 1.48 },
+	{ 0.5, 4.43, 148.08 },
+	/* 11 terms retained, 5 terms dropped, error 0.0067"*T^3 */
+
+	/* uranus b, T^4 */
+	{ 5.7, 2.85, 74.78 },
+	{ 0.3, 3.14, 0 },
+	/* 2 terms retained, 0 terms dropped, error 0.0021"*T^4 */
+	/* end uranus b */
+
+	/* uranus r, T^0 */
+	{ 1921264847.9, 0, 0 },
+	{ 88784984.1, 5.603775270, 74.781598567 },
+	{ 3440835.5, 0.32836099, 73.29712586 },
+	{ 2055653.5, 1.78295170, 149.56319713 },
+	{ 649321.9, 4.5224730, 76.2660713 },
+	{ 602248.1, 3.8600382, 63.7358983 },
+	{ 496404.2, 1.4013993, 454.9093665 },
+	{ 338525.5, 1.5800268, 138.5174969 },
+	{ 243508.2, 1.5708660, 71.8126532 },
+	{ 190521.9, 1.9980936, 1.4844727 },
+	{ 161858.3, 2.7913786, 148.0787244 },
+	{ 143705.9, 1.3836857, 11.0457003 },
+	{ 93192.4, 0.174372, 36.648563 },
+	{ 71424.3, 4.245093, 224.344796 },
+	{ 89805.8, 3.661054, 109.945689 },
+	{ 39009.6, 1.669711, 70.849445 },
+	{ 46677.3, 1.399766, 35.164090 },
+	{ 39025.7, 3.362347, 277.034994 },
+	{ 36755.2, 3.886489, 146.594252 },
+	{ 30348.9, 0.701004, 151.047670 },
+	{ 29156.3, 3.180562, 77.750544 },
+	{ 20471.6, 1.555890, 202.253395 },
+	{ 25620.4, 5.256563, 380.127768 },
+	{ 25785.8, 3.785377, 85.827299 },
+	{ 22637.2, 0.725191, 529.690965 },
+	{ 20473.2, 2.796398, 70.328180 },
+	{ 17900.6, 0.554555, 2.968945 },
+	{ 12328.2, 5.960392, 127.471797 },
+	{ 14701.6, 4.904344, 108.461216 },
+	{ 11494.7, 0.437740, 65.220371 },
+	{ 15502.8, 5.354050, 38.133036 },
+	{ 10792.7, 1.421049, 213.299095 },
+	{ 11696.1, 3.298256, 3.932153 },
+	{ 11959.4, 1.750441, 984.600332 },
+	{ 12896.5, 2.621540, 111.430161 },
+	{ 11853.0, 0.993428, 52.690198 },
+	{ 9111.4, 4.99639, 62.25143 },
+	{ 8420.6, 5.25351, 222.86032 },
+	{ 7449.1, 0.79492, 351.81659 },
+	{ 8402.1, 5.03878, 415.55249 },
+	{ 6046.4, 5.67961, 78.71375 },
+	{ 5524.1, 3.11499, 9.56123 },
+	{ 7329.5, 3.97278, 183.24281 },
+	{ 5444.9, 5.10576, 145.10978 },
+	{ 5238.1, 2.62960, 33.67962 },
+	{ 4079.2, 3.22065, 340.77089 },
+	{ 3801.6, 6.10986, 184.72729 },
+	{ 3919.5, 4.25015, 39.61751 },
+	{ 2940.5, 2.14637, 137.03302 },
+	{ 3781.2, 3.45840, 456.39384 },
+	{ 2942.2, 0.42394, 299.12639 },
+	{ 3686.8, 2.48718, 453.42489 },
+	{ 3101.7, 4.14031, 219.89138 },
+	{ 2962.6, 0.82978, 56.62235 },
+	{ 2937.8, 3.67657, 140.00197 },
+	{ 2865.1, 0.30997, 12.53017 },
+	{ 2538.0, 4.85458, 131.40395 },
+	{ 1962.5, 5.24342, 84.34283 },
+	{ 2363.6, 0.44253, 554.06999 },
+	{ 1979.4, 6.12836, 106.97674 },
+	{ 2182.6, 2.94040, 305.34617 },
+	{ 1963.0, 0.04115, 221.37585 },
+	{ 1829.6, 4.01106, 68.84371 },
+	{ 1642.9, 0.35564, 67.66805 },
+	{ 1584.8, 3.16267, 225.82927 },
+	{ 1848.7, 2.91112, 909.81873 },
+	{ 1632.4, 4.23062, 22.09140 },
+	{ 1401.4, 1.39084, 265.98929 },
+	{ 1403.7, 5.63564, 4.45342 },
+	{ 1655.9, 1.96431, 79.23502 },
+	{ 1249.0, 5.44027, 54.17467 },
+	{ 1563.4, 1.47918, 112.91463 },
+	{ 1248.1, 4.88984, 479.28839 },
+	{ 1197.4, 2.52186, 145.63104 },
+	{ 1507.0, 5.24186, 181.75834 },
+	{ 1481.7, 5.66203, 152.53214 },
+	{ 1438.8, 1.53046, 447.79582 },
+	{ 1408.5, 4.41922, 462.02291 },
+	{ 1477.1, 4.32215, 256.53994 },
+	{ 1228.3, 5.97703, 59.80375 },
+	{ 1250.0, 6.24485, 160.60890 },
+	{ 906.5, 5.6203, 74.6697 },
+	{ 1090.7, 4.15394, 77.96299 },
+	{ 844.9, 0.1294, 82.8584 },
+	{ 900.4, 2.3732, 74.8935 },
+	{ 1072.0, 1.74287, 528.20649 },
+	{ 689.7, 3.0810, 69.3650 },
+	{ 593.8, 4.5007, 8.0768 },
+	{ 718.6, 4.0005, 128.9563 },
+	{ 699.6, 0.0399, 143.6253 },
+	{ 575.7, 5.8955, 66.7048 },
+	{ 759.0, 2.1370, 692.5875 },
+	{ 710.4, 5.4161, 218.4069 },
+	{ 548.7, 5.6281, 3.1814 },
+	{ 651.6, 4.4234, 18.1592 },
+	{ 539.8, 6.2079, 71.6002 },
+	{ 544.5, 5.6938, 203.7379 },
+	{ 710.3, 4.2197, 381.6122 },
+	{ 593.8, 3.8381, 32.1951 },
+	{ 710.1, 4.4897, 293.1885 },
+	{ 705.5, 0.4552, 835.0371 },
+	{ 588.0, 5.0825, 186.2118 },
+	{ 598.2, 0.3582, 269.9214 },
+	{ 641.9, 2.7113, 87.3118 },
+	{ 495.6, 2.6509, 200.7689 },
+	{ 630.3, 4.4615, 275.5505 },
+	{ 575.2, 5.5786, 2.4477 },
+	{ 569.9, 1.6393, 77.2293 },
+	{ 556.7, 1.0723, 1059.3819 },
+	{ 449.4, 0.2798, 617.8059 },
+	{ 463.6, 1.4345, 297.6419 },
+	{ 436.5, 0.5280, 209.3669 },
+	{ 463.9, 2.3544, 211.8146 },
+	{ 435.9, 2.1008, 1514.2913 },
+	{ 515.5, 3.2327, 284.1485 },
+	{ 454.9, 4.0836, 99.1606 },
+	{ 477.4, 2.8940, 39.3569 },
+	{ 542.3, 5.3948, 278.5195 },
+	{ 410.1, 3.0497, 404.5068 },
+	{ 367.8, 0.7116, 125.9873 },
+	{ 503.1, 5.8393, 191.2077 },
+	{ 487.5, 0.0640, 60.7670 },
+	{ 455.0, 2.5932, 490.3341 },
+	{ 436.3, 2.0818, 51.2057 },
+	{ 435.8, 2.7945, 75.7448 },
+	{ 323.5, 4.8290, 195.1398 },
+	{ 359.4, 0.0087, 35.4247 },
+	{ 429.3, 3.0803, 41.1020 },
+	{ 320.0, 5.4863, 14.9779 },
+	{ 414.3, 0.0901, 258.0244 },
+	{ 379.7, 0.0583, 378.6433 },
+	{ 420.1, 2.2539, 81.0014 },
+	{ 357.7, 4.7141, 173.9422 },
+	{ 358.9, 0.3521, 426.5982 },
+	{ 405.4, 6.1226, 24.3790 },
+	{ 365.2, 5.5948, 255.0555 },
+	{ 308.1, 3.9236, 116.4261 },
+	{ 325.7, 4.7200, 134.5853 },
+	{ 292.8, 3.9952, 72.3339 },
+	{ 386.5, 0.6862, 230.5646 },
+	{ 305.7, 3.7611, 344.7030 },
+	{ 287.0, 1.8499, 153.4954 },
+	{ 353.6, 4.6572, 329.8371 },
+	{ 302.1, 0.1319, 565.1157 },
+	{ 241.1, 1.6045, 81.3739 },
+	{ 249.8, 4.2421, 75.3029 },
+	{ 245.1, 5.9491, 20.6069 },
+	{ 248.3, 1.0628, 105.4923 },
+	{ 305.4, 2.5553, 6208.2943 },
+	{ 296.3, 4.2110, 1364.7281 },
+	{ 219.9, 2.9612, 120.3582 },
+	{ 233.6, 2.9707, 46.2098 },
+	{ 262.4, 3.8365, 831.1050 },
+	{ 233.5, 4.4812, 628.8516 },
+	{ 187.4, 3.0353, 135.5486 },
+	{ 216.8, 3.4291, 241.6103 },
+	{ 255.8, 1.1671, 177.8744 },
+	{ 220.5, 0.1963, 180.2739 },
+	{ 224.5, 0.4068, 114.3991 },
+	{ 205.4, 2.3038, 259.5089 },
+	{ 211.1, 4.9308, 103.0928 },
+	{ 175.8, 5.5082, 7.1135 },
+	{ 188.5, 2.2359, 5.4166 },
+	{ 171.7, 5.2173, 41.6445 },
+	{ 176.1, 1.9596, 756.3234 },
+	{ 170.4, 4.9498, 206.1855 },
+	{ 169.5, 4.0432, 55.6591 },
+	{ 219.0, 0.2479, 294.6730 },
+	{ 187.8, 2.0454, 408.4389 },
+	{ 182.3, 0.7073, 391.1735 },
+	{ 192.1, 5.7672, 291.7040 },
+	{ 153.7, 4.7066, 543.0243 },
+	{ 170.0, 4.5100, 288.0807 },
+	{ 164.1, 5.2253, 67.3592 },
+	{ 194.3, 6.1169, 414.0680 },
+	{ 168.0, 5.2581, 518.6453 },
+	{ 156.6, 0.6630, 220.4126 },
+	{ 182.3, 0.7838, 417.0370 },
+	{ 167.5, 4.9224, 422.6660 },
+	{ 170.8, 2.3093, 98.9000 },
+	{ 161.7, 3.2726, 443.8637 },
+	{ 132.8, 2.8888, 373.9080 },
+	{ 161.1, 3.8234, 451.9404 },
+	{ 179.3, 4.8241, 366.4856 },
+	{ 178.2, 3.9803, 10138.5039 },
+	{ 141.9, 1.2697, 159.1244 },
+	{ 153.8, 4.2785, 45.5767 },
+	{ 161.5, 4.9955, 73.8184 },
+	{ 146.3, 2.6566, 465.9551 },
+	{ 124.9, 4.3047, 339.2864 },
+	{ 154.6, 4.3205, 760.2555 },
+	{ 142.9, 2.0777, 457.8783 },
+	{ 152.4, 4.6474, 155.7830 },
+	{ 116.4, 4.4351, 5.9379 },
+	{ 113.4, 4.6535, 80.1982 },
+	{ 107.6, 3.7729, 142.4497 },
+	{ 133.7, 5.3089, 14.0146 },
+	{ 116.1, 2.5118, 296.1574 },
+	{ 129.1, 0.3628, 96.8730 },
+	{ 122.8, 2.3834, 141.4864 },
+	{ 101.4, 1.0574, 92.3077 },
+	{ 114.7, 6.2486, 767.3691 },
+	{ 113.3, 0.8305, 100.3845 },
+	{ 107.2, 2.3937, 347.8844 },
+	{ 95.4, 0.801, 342.255 },
+	{ 110.8, 0.3865, 216.9224 },
+	{ 127.0, 0.4236, 331.3215 },
+	{ 112.6, 0.0811, 558.0021 },
+	{ 103.2, 0.6979, 358.9301 },
+	{ 111.5, 0.7502, 80.7195 },
+	{ 90.9, 5.165, 144.147 },
+	{ 90.7, 0.220, 333.657 },
+	{ 98.6, 4.332, 74.521 },
+	{ 89.3, 2.189, 74.830 },
+	{ 117.2, 3.9497, 74.2603 },
+	{ 89.1, 5.878, 74.733 },
+	{ 97.3, 0.694, 977.487 },
+	{ 116.6, 1.8368, 1289.9465 },
+	{ 85.4, 5.803, 6.592 },
+	{ 86.8, 5.620, 300.611 },
+	{ 105.2, 5.9451, 328.3526 },
+	{ 112.1, 1.2117, 329.7252 },
+	{ 83.0, 2.208, 74.942 },
+	{ 94.3, 4.539, 28.572 },
+	{ 106.8, 1.8207, 306.8306 },
+	{ 103.6, 2.9937, 6.2198 },
+	{ 106.4, 0.8158, 1087.6931 },
+	{ 77.7, 2.734, 110.206 },
+	{ 98.4, 3.735, 75.042 },
+	{ 86.2, 2.833, 983.116 },
+	{ 89.0, 4.738, 604.473 },
+	{ 83.0, 1.883, 387.241 },
+	{ 90.2, 3.804, 986.085 },
+	{ 84.6, 1.258, 142.141 },
+	{ 74.7, 1.351, 350.332 },
+	{ 95.8, 5.548, 969.622 },
+	{ 90.3, 0.368, 0.963 },
+	{ 82.7, 5.856, 74.622 },
+	{ 75.8, 2.780, 88.115 },
+	{ 83.8, 1.844, 227.314 },
+	{ 70.7, 4.656, 44.725 },
+	{ 71.3, 3.650, 894.841 },
+	{ 94.1, 4.988, 403.134 },
+	{ 89.0, 4.439, 154.017 },
+	{ 79.4, 5.667, 267.474 },
+	{ 75.6, 5.410, 50.403 },
+	{ 68.6, 4.767, 991.714 },
+	{ 65.3, 0.693, 152.745 },
+	{ 63.0, 2.899, 79.889 },
+	{ 63.9, 0.098, 681.542 },
+	{ 80.1, 2.975, 526.722 },
+	{ 69.7, 3.953, 187.696 },
+	{ 59.5, 3.596, 58.107 },
+	{ 59.3, 0.509, 28.311 },
+	{ 68.6, 2.419, 235.390 },
+	{ 66.0, 5.046, 30.711 },
+	{ 70.2, 3.736, 546.956 },
+	{ 66.8, 0.855, 522.577 },
+	{ 63.0, 0.293, 119.507 },
+	{ 62.0, 2.316, 74.031 },
+	{ 71.4, 3.170, 23.576 },
+	{ 74.8, 5.368, 373.014 },
+	{ 64.2, 2.368, 157.640 },
+	{ 70.7, 0.558, 92.941 },
+	{ 55.8, 5.270, 874.394 },
+	{ 75.6, 4.663, 101.869 },
+	{ 73.7, 6.206, 312.460 },
+	{ 72.9, 0.584, 367.970 },
+	{ 53.2, 2.247, 17.526 },
+	{ 63.1, 4.596, 67.880 },
+	{ 60.5, 0.576, 253.571 },
+	{ 52.9, 2.459, 264.505 },
+	{ 70.2, 1.519, 552.586 },
+	{ 68.6, 2.445, 555.554 },
+	{ 62.8, 0.338, 561.184 },
+	{ 49.0, 1.092, 19.122 },
+	{ 64.6, 5.275, 68.189 },
+	{ 63.0, 5.359, 92.047 },
+	{ 47.7, 3.909, 192.692 },
+	{ 65.3, 4.236, 771.301 },
+	{ 65.2, 3.739, 536.805 },
+	{ 59.5, 6.106, 365.001 },
+	{ 52.2, 1.717, 905.887 },
+	{ 46.0, 3.871, 210.330 },
+	{ 46.4, 5.974, 477.804 },
+	{ 62.1, 2.675, 130.441 },
+	{ 46.0, 3.894, 48.758 },
+	{ 42.7, 3.815, 61.288 },
+	{ 53.9, 2.865, 353.301 },
+	{ 46.9, 1.000, 166.829 },
+	{ 42.2, 2.617, 90.823 },
+	{ 43.3, 4.158, 173.682 },
+	{ 41.3, 1.799, 149.451 },
+	{ 45.0, 1.766, 0.521 },
+	{ 51.9, 2.978, 383.097 },
+	{ 42.9, 1.574, 120.991 },
+	{ 49.6, 4.034, 303.862 },
+	{ 45.3, 3.584, 97.416 },
+	{ 38.7, 2.394, 31.493 },
+	{ 38.1, 5.795, 75.532 },
+	{ 50.1, 4.764, 911.303 },
+	{ 50.9, 5.155, 439.783 },
+	{ 43.1, 0.850, 58.319 },
+	{ 42.7, 5.173, 162.093 },
+	{ 50.3, 5.816, 66.917 },
+	{ 35.6, 1.874, 472.175 },
+	{ 50.0, 1.889, 42.586 },
+	{ 40.0, 1.743, 89.759 },
+	{ 45.3, 1.925, 55.138 },
+	{ 44.9, 1.484, 450.977 },
+	{ 34.3, 5.203, 316.392 },
+	{ 46.4, 0.339, 273.103 },
+	{ 37.2, 2.038, 117.911 },
+	{ 46.1, 5.623, 1819.637 },
+	{ 39.4, 4.194, 486.402 },
+	{ 41.0, 4.830, 149.675 },
+	{ 45.0, 0.727, 3265.831 },
+	{ 43.6, 0.753, 404.619 },
+	{ 31.8, 3.848, 20.447 },
+	{ 44.2, 4.368, 418.261 },
+	{ 37.9, 3.029, 167.089 },
+	{ 43.7, 1.573, 491.558 },
+	{ 34.0, 1.263, 260.993 },
+	{ 31.3, 4.161, 13.333 },
+	{ 40.0, 2.866, 468.243 },
+	{ 36.5, 2.588, 68.562 },
+	{ 32.4, 3.116, 103.353 },
+	{ 33.9, 0.156, 24.118 },
+	{ 35.9, 1.368, 59.282 },
+	{ 33.6, 0.755, 290.220 },
+	{ 29.8, 5.332, 1033.358 },
+	{ 32.0, 4.675, 205.222 },
+	{ 31.0, 4.628, 258.876 },
+	{ 35.3, 1.007, 1108.140 },
+	{ 33.4, 3.407, 43.129 },
+	{ 32.6, 5.255, 114.138 },
+	{ 29.8, 5.642, 254.944 },
+	{ 31.6, 3.782, 152.011 },
+	{ 31.0, 2.267, 104.008 },
+	{ 34.6, 5.173, 25.603 },
+	{ 28.4, 1.769, 820.059 },
+	{ 28.0, 3.925, 199.284 },
+	{ 29.0, 2.582, 76.479 },
+	{ 33.8, 5.794, 274.066 },
+	{ 29.4, 5.936, 280.967 },
+	{ 31.1, 1.394, 178.789 },
+	{ 30.1, 0.444, 27.087 },
+	{ 33.8, 6.262, 401.650 },
+	{ 27.5, 2.152, 480.773 },
+	{ 26.9, 2.513, 123.540 },
+	{ 26.1, 0.220, 286.596 },
+	{ 26.5, 3.882, 372.424 },
+	{ 34.0, 1.446, 88.796 },
+	{ 30.1, 0.827, 100.645 },
+	{ 27.7, 4.648, 198.321 },
+	{ 33.7, 1.143, 82.486 },
+	{ 26.5, 1.979, 95.389 },
+	{ 26.6, 0.399, 106.014 },
+	{ 27.0, 2.102, 1057.897 },
+	{ 31.0, 5.340, 476.431 },
+	{ 27.0, 0.713, 248.724 },
+	{ 29.1, 3.992, 908.334 },
+	{ 28.0, 3.465, 1439.510 },
+	{ 27.8, 4.124, 694.072 },
+	{ 25.5, 5.496, 115.884 },
+	{ 27.2, 5.761, 1215.165 },
+	{ 26.3, 2.775, 490.073 },
+	{ 26.4, 3.371, 49.721 },
+	{ 26.9, 3.260, 691.103 },
+	{ 25.0, 3.650, 73.409 },
+	/* 370 terms retained, 754 terms dropped, error 9.6e-06 a.u. */
+
+	/* uranus r, T^1 */
+	{ 1479896.4, 3.67205705, 74.78159857 },
+	{ 71212.1, 6.226010, 63.735898 },
+	{ 68627.0, 6.134113, 149.563197 },
+	{ 20857.3, 5.246255, 11.045700 },
+	{ 21468.2, 2.601767, 76.266071 },
+	{ 24059.6, 3.141593, 0 },
+	{ 11405.3, 0.018485, 70.849445 },
+	{ 7496.8, 0.42360, 73.29713 },
+	{ 4243.8, 1.41692, 85.82730 },
+	{ 3505.9, 2.58354, 138.51750 },
+	{ 3228.8, 5.25500, 3.93215 },
+	{ 3926.7, 3.15514, 71.81265 },
+	{ 3060.0, 0.15322, 1.48447 },
+	{ 3578.4, 2.31161, 224.34480 },
+	{ 2564.3, 0.98077, 148.07872 },
+	{ 2429.4, 3.99440, 52.69020 },
+	{ 1644.7, 2.65349, 127.47180 },
+	{ 1583.8, 1.43046, 78.71375 },
+	{ 1413.1, 4.57462, 202.25340 },
+	{ 1489.5, 2.67559, 56.62235 },
+	{ 1403.2, 1.36985, 77.75054 },
+	{ 1228.2, 1.04704, 62.25143 },
+	{ 1508.0, 5.05996, 151.04767 },
+	{ 992.1, 2.1717, 65.2204 },
+	{ 1032.7, 0.26459, 131.40395 },
+	{ 861.9, 5.0553, 351.8166 },
+	{ 744.4, 3.0764, 35.1641 },
+	{ 604.4, 0.9072, 984.6003 },
+	{ 646.9, 4.4729, 70.3282 },
+	{ 574.7, 3.2307, 447.7958 },
+	{ 687.5, 2.4991, 77.9630 },
+	{ 623.6, 0.8625, 9.5612 },
+	{ 527.8, 5.1514, 2.9689 },
+	{ 561.8, 2.7178, 462.0229 },
+	{ 530.4, 5.9166, 213.2991 },
+	{ 460.1, 4.2230, 12.5302 },
+	{ 494.3, 0.4629, 145.6310 },
+	{ 487.3, 0.7061, 380.1278 },
+	{ 380.9, 3.8509, 3.1814 },
+	{ 444.4, 2.1556, 67.6681 },
+	{ 338.8, 2.5382, 18.1592 },
+	{ 372.9, 5.0514, 529.6910 },
+	{ 348.3, 1.7487, 71.6002 },
+	{ 405.9, 1.2296, 22.0914 },
+	{ 268.9, 6.2407, 340.7709 },
+	{ 255.6, 2.9570, 84.3428 },
+	{ 259.5, 3.9205, 59.8037 },
+	{ 224.7, 3.9096, 160.6089 },
+	{ 221.7, 3.6473, 137.0330 },
+	{ 254.6, 3.5041, 38.1330 },
+	{ 238.3, 2.0488, 269.9214 },
+	{ 272.4, 3.3836, 222.8603 },
+	{ 200.6, 1.2486, 69.3650 },
+	{ 234.2, 0.2783, 108.4612 },
+	{ 188.5, 4.4131, 265.9893 },
+	{ 211.7, 0.6803, 111.4302 },
+	{ 205.9, 1.5338, 284.1485 },
+	{ 196.2, 4.7715, 299.1264 },
+	{ 153.1, 5.2176, 209.3669 },
+	{ 162.6, 4.3405, 33.6796 },
+	{ 150.6, 1.9897, 54.1747 },
+	{ 137.0, 0.4032, 195.1398 },
+	{ 117.2, 0.3965, 87.3118 },
+	{ 127.9, 2.4033, 39.6175 },
+	{ 104.2, 2.9215, 134.5853 },
+	{ 103.9, 1.8162, 72.3339 },
+	{ 105.7, 0.1707, 79.2350 },
+	{ 106.4, 0.6980, 2.4477 },
+	{ 95.3, 4.029, 82.858 },
+	{ 104.8, 4.4362, 305.3462 },
+	{ 93.8, 5.018, 51.206 },
+	{ 103.7, 2.5755, 191.2077 },
+	{ 106.7, 1.2300, 225.8293 },
+	{ 93.5, 3.093, 77.229 },
+	{ 97.4, 3.814, 152.532 },
+	{ 84.6, 5.725, 68.844 },
+	{ 77.4, 0.083, 45.577 },
+	{ 76.2, 4.204, 73.818 },
+	{ 86.2, 0.531, 145.110 },
+	{ 75.8, 3.786, 75.745 },
+	{ 77.6, 1.636, 479.288 },
+	{ 84.6, 0.617, 116.426 },
+	{ 100.2, 4.9408, 120.3582 },
+	{ 72.1, 4.305, 565.116 },
+	{ 70.7, 2.385, 60.767 },
+	{ 71.6, 3.939, 153.495 },
+	{ 84.6, 5.560, 344.703 },
+	{ 63.6, 1.937, 41.644 },
+	{ 71.6, 3.712, 408.439 },
+	{ 61.6, 3.900, 4.453 },
+	{ 65.0, 1.558, 106.977 },
+	{ 59.9, 0.601, 74.893 },
+	{ 62.0, 4.394, 453.425 },
+	{ 63.4, 4.192, 184.727 },
+	{ 62.3, 3.238, 422.666 },
+	{ 54.4, 3.725, 7.114 },
+	{ 52.5, 6.086, 404.507 },
+	{ 59.1, 1.556, 456.394 },
+	{ 52.6, 3.505, 125.987 },
+	{ 52.8, 5.201, 358.930 },
+	{ 58.1, 5.335, 220.413 },
+	{ 52.9, 4.448, 426.598 },
+	{ 50.9, 0.526, 490.334 },
+	{ 55.0, 1.601, 14.978 },
+	{ 49.5, 4.255, 5.417 },
+	{ 51.3, 0.368, 206.186 },
+	{ 51.8, 1.758, 8.077 },
+	{ 57.0, 0.841, 146.594 },
+	{ 49.1, 0.941, 99.161 },
+	{ 46.4, 5.351, 152.745 },
+	{ 48.0, 1.972, 288.081 },
+	{ 43.8, 3.037, 20.607 },
+	{ 49.5, 5.846, 112.915 },
+	{ 42.0, 0.046, 128.956 },
+	{ 48.6, 3.628, 81.001 },
+	{ 41.5, 2.337, 277.035 },
+	{ 40.0, 5.095, 35.425 },
+	{ 41.9, 2.511, 24.379 },
+	{ 38.3, 3.619, 173.942 },
+	{ 38.4, 2.060, 333.657 },
+	{ 42.6, 1.261, 1514.291 },
+	{ 38.9, 0.742, 347.884 },
+	{ 38.5, 4.951, 92.941 },
+	{ 33.2, 1.384, 74.670 },
+	{ 33.8, 3.684, 66.917 },
+	{ 39.0, 5.492, 200.769 },
+	{ 31.9, 0.540, 203.738 },
+	{ 33.3, 6.260, 1059.382 },
+	{ 30.8, 2.538, 977.487 },
+	{ 29.2, 5.431, 58.107 },
+	{ 30.1, 0.195, 387.241 },
+	{ 29.0, 3.105, 991.714 },
+	{ 35.6, 3.729, 96.873 },
+	{ 27.6, 0.371, 80.198 },
+	{ 32.5, 4.384, 221.376 },
+	{ 27.0, 1.356, 0.963 },
+	{ 31.3, 0.796, 373.014 },
+	{ 31.1, 2.054, 230.565 },
+	{ 25.9, 3.468, 144.147 },
+	{ 30.2, 0.714, 109.946 },
+	{ 24.7, 3.042, 14.015 },
+	{ 27.9, 4.766, 415.552 },
+	{ 25.1, 5.124, 81.374 },
+	{ 25.6, 2.569, 522.577 },
+	{ 24.4, 2.203, 628.852 },
+	{ 25.5, 1.795, 143.625 },
+	{ 24.2, 5.672, 443.864 },
+	{ 25.7, 5.432, 546.956 },
+	{ 24.2, 5.600, 32.195 },
+	{ 24.4, 3.303, 617.806 },
+	{ 23.5, 0.658, 46.210 },
+	{ 22.4, 4.821, 135.549 },
+	{ 27.2, 2.027, 536.805 },
+	{ 22.2, 4.617, 391.173 },
+	{ 22.0, 4.592, 241.610 },
+	{ 20.8, 0.244, 465.955 },
+	{ 27.3, 2.152, 140.002 },
+	{ 21.4, 5.272, 159.124 },
+	{ 23.6, 4.950, 561.184 },
+	{ 24.9, 0.546, 181.758 },
+	{ 23.0, 3.806, 55.138 },
+	{ 19.8, 1.303, 518.645 },
+	{ 19.3, 1.314, 543.024 },
+	{ 19.7, 4.909, 909.819 },
+	{ 20.8, 0.912, 76.479 },
+	{ 19.9, 0.665, 66.705 },
+	{ 19.0, 4.680, 98.900 },
+	{ 25.9, 4.529, 454.909 },
+	{ 21.9, 1.234, 41.102 },
+	{ 18.7, 6.096, 103.093 },
+	{ 18.2, 0.973, 55.659 },
+	{ 21.2, 4.194, 329.725 },
+	{ 19.4, 4.315, 6.220 },
+	{ 18.5, 5.786, 142.450 },
+	{ 22.6, 5.846, 297.642 },
+	{ 16.8, 6.091, 211.815 },
+	{ 16.4, 2.500, 61.288 },
+	{ 20.4, 3.161, 186.212 },
+	{ 16.0, 2.983, 81.895 },
+	{ 19.0, 6.012, 155.783 },
+	{ 17.7, 4.826, 273.103 },
+	{ 15.1, 3.656, 472.175 },
+	{ 18.4, 3.476, 36.649 },
+	{ 16.3, 0.131, 554.070 },
+	{ 18.6, 0.239, 23.576 },
+	{ 14.4, 2.694, 70.116 },
+	{ 15.2, 2.438, 486.402 },
+	{ 14.0, 5.124, 29.205 },
+	{ 15.8, 4.249, 146.382 },
+	{ 14.1, 1.557, 110.206 },
+	{ 17.5, 1.945, 835.037 },
+	{ 13.7, 1.638, 92.047 },
+	{ 13.8, 0.137, 235.390 },
+	{ 13.6, 2.854, 49.509 },
+	{ 12.6, 3.209, 100.384 },
+	{ 12.4, 2.886, 60.555 },
+	{ 15.0, 0.326, 259.509 },
+	{ 12.9, 2.776, 105.492 },
+	{ 12.3, 3.364, 440.682 },
+	{ 15.2, 0.256, 258.876 },
+	{ 12.1, 0.109, 157.640 },
+	{ 12.9, 0.307, 124.290 },
+	{ 10.9, 3.429, 33.137 },
+	{ 11.2, 4.988, 604.473 },
+	{ 10.8, 3.863, 767.369 },
+	{ 11.6, 2.605, 166.829 },
+	{ 10.2, 5.278, 264.505 },
+	{ 10.9, 0.641, 558.002 },
+	{ 12.3, 4.340, 16.675 },
+	{ 9.9, 0.67, 31.49 },
+	{ 12.6, 4.832, 114.399 },
+	{ 10.5, 0.204, 275.551 },
+	{ 11.3, 0.961, 373.908 },
+	{ 12.1, 1.917, 378.643 },
+	{ 12.2, 0.705, 218.407 },
+	{ 10.8, 5.745, 88.115 },
+	{ 9.5, 0.66, 353.30 },
+	{ 11.0, 2.630, 154.017 },
+	{ 9.1, 2.99, 681.54 },
+	{ 10.4, 2.331, 132.888 },
+	{ 9.2, 4.79, 216.48 },
+	{ 9.3, 0.76, 129.92 },
+	{ 8.9, 0.78, 67.36 },
+	{ 8.8, 6.13, 150.53 },
+	{ 9.6, 2.89, 67.88 },
+	{ 10.5, 0.369, 699.701 },
+	{ 9.3, 1.50, 19.64 },
+	{ 9.4, 5.26, 80.72 },
+	{ 10.1, 3.565, 278.519 },
+	{ 9.5, 3.06, 149.68 },
+	{ 9.2, 3.03, 162.09 },
+	{ 8.4, 2.18, 342.26 },
+	{ 9.2, 5.33, 152.01 },
+	{ 9.8, 2.44, 75.30 },
+	{ 10.0, 0.819, 339.286 },
+	{ 9.4, 1.94, 147.12 },
+	{ 7.9, 4.72, 106.01 },
+	{ 8.8, 0.02, 42.59 },
+	{ 7.8, 0.61, 135.34 },
+	{ 8.2, 2.60, 469.14 },
+	{ 10.1, 2.586, 50.403 },
+	{ 8.6, 5.69, 760.26 },
+	{ 7.5, 2.65, 5.94 },
+	{ 8.7, 0.54, 66.18 },
+	{ 8.0, 1.94, 180.27 },
+	{ 7.5, 5.95, 97.42 },
+	{ 7.6, 5.80, 450.98 },
+	{ 8.7, 3.70, 300.61 },
+	{ 7.7, 1.47, 32.24 },
+	{ 8.2, 2.31, 254.94 },
+	{ 8.5, 1.28, 39.36 },
+	{ 7.0, 0.68, 874.39 },
+	{ 8.9, 0.16, 43.13 },
+	{ 7.2, 4.98, 117.91 },
+	{ 7.4, 4.09, 92.31 },
+	{ 7.3, 5.04, 756.32 },
+	{ 8.5, 1.22, 79.45 },
+	{ 6.9, 6.04, 350.33 },
+	{ 8.8, 1.33, 48.76 },
+	{ 7.3, 3.33, 68.19 },
+	{ 6.8, 4.78, 142.66 },
+	{ 6.8, 3.90, 480.77 },
+	{ 7.1, 1.28, 68.56 },
+	{ 7.9, 4.30, 624.92 },
+	{ 6.7, 5.43, 610.69 },
+	{ 6.5, 5.44, 88.80 },
+	{ 7.6, 4.81, 312.46 },
+	{ 7.2, 3.18, 268.44 },
+	{ 8.1, 1.99, 692.59 },
+	{ 6.5, 1.05, 685.47 },
+	{ 6.6, 1.38, 291.26 },
+	{ 6.9, 2.59, 282.66 },
+	{ 7.1, 5.80, 468.24 },
+	{ 6.3, 2.58, 458.09 },
+	{ 7.6, 0.49, 296.16 },
+	{ 8.5, 0.01, 227.31 },
+	{ 6.5, 3.99, 42.54 },
+	{ 6.4, 1.04, 365.90 },
+	{ 8.2, 1.13, 69.15 },
+	{ 6.4, 0.16, 228.28 },
+	{ 8.0, 4.04, 183.24 },
+	{ 6.3, 3.52, 285.63 },
+	{ 6.9, 3.32, 306.83 },
+	{ 6.9, 1.34, 7.86 },
+	{ 6.5, 0.46, 106.27 },
+	{ 6.6, 5.25, 58.32 },
+	{ 6.4, 0.35, 411.62 },
+	{ 6.4, 5.19, 120.99 },
+	{ 7.0, 4.86, 419.48 },
+	{ 6.4, 2.78, 198.32 },
+	/* 290 terms retained, 224 terms dropped, error 2.2e-06 a.u.*T */
+
+	/* uranus r, T^2 */
+	{ 22439.9, 0.699531, 74.781599 },
+	{ 4727.0, 1.69902, 63.73590 },
+	{ 1681.9, 4.64834, 70.84945 },
+	{ 1433.8, 3.52120, 149.56320 },
+	{ 1649.6, 3.09660, 11.04570 },
+	{ 770.2, 0, 0 },
+	{ 461.0, 0.7668, 3.9322 },
+	{ 500.4, 6.1723, 76.2661 },
+	{ 390.4, 4.4961, 56.6224 },
+	{ 389.9, 5.5267, 85.8273 },
+	{ 292.1, 0.2039, 52.6902 },
+	{ 272.9, 3.8471, 138.5175 },
+	{ 286.6, 3.5336, 73.2971 },
+	{ 205.4, 3.2476, 78.7138 },
+	{ 219.7, 1.9642, 131.4039 },
+	{ 215.8, 0.8481, 77.9630 },
+	{ 128.8, 2.0815, 3.1814 },
+	{ 148.6, 4.8984, 127.4718 },
+	{ 117.5, 4.9341, 447.7958 },
+	{ 112.7, 1.0136, 462.0229 },
+	{ 98.9, 6.158, 224.345 },
+	{ 91.4, 0.680, 18.159 },
+	{ 89.2, 0.234, 202.253 },
+	{ 88.2, 2.931, 62.251 },
+	{ 114.1, 4.7874, 145.6310 },
+	{ 103.9, 3.5856, 71.6002 },
+	{ 61.8, 3.300, 351.817 },
+	{ 57.8, 4.907, 22.091 },
+	{ 64.4, 3.390, 1.484 },
+	{ 71.1, 6.105, 454.909 },
+	{ 51.0, 3.867, 65.220 },
+	{ 63.5, 3.962, 67.668 },
+	{ 59.0, 5.555, 9.561 },
+	{ 48.7, 3.747, 269.921 },
+	{ 43.6, 1.926, 59.804 },
+	{ 42.2, 2.617, 151.048 },
+	{ 42.4, 6.136, 284.149 },
+	{ 44.3, 5.900, 71.813 },
+	{ 37.3, 5.913, 984.600 },
+	{ 36.2, 5.403, 77.751 },
+	{ 42.0, 2.091, 12.530 },
+	{ 31.4, 4.592, 148.079 },
+	{ 31.3, 2.267, 195.140 },
+	{ 27.2, 3.532, 209.367 },
+	{ 28.2, 4.578, 77.229 },
+	{ 26.1, 0.660, 120.358 },
+	{ 24.4, 5.867, 69.365 },
+	{ 23.0, 1.038, 84.343 },
+	{ 22.7, 1.714, 160.609 },
+	{ 27.7, 4.915, 277.035 },
+	{ 20.8, 2.196, 45.577 },
+	{ 20.0, 2.321, 2.448 },
+	{ 16.6, 4.775, 213.299 },
+	{ 16.6, 1.856, 340.771 },
+	{ 17.2, 4.369, 54.175 },
+	{ 16.1, 3.646, 152.745 },
+	{ 14.8, 5.438, 408.439 },
+	{ 13.9, 3.385, 358.930 },
+	{ 13.3, 5.252, 137.033 },
+	{ 13.3, 1.263, 134.585 },
+	{ 12.9, 3.033, 92.941 },
+	{ 12.5, 1.332, 51.206 },
+	{ 13.4, 1.532, 422.666 },
+	{ 16.4, 0.402, 265.989 },
+	{ 12.0, 5.104, 191.208 },
+	{ 12.9, 4.432, 87.312 },
+	{ 11.4, 2.026, 7.114 },
+	{ 11.8, 4.656, 41.644 },
+	{ 12.0, 3.239, 116.426 },
+	{ 11.7, 3.733, 220.413 },
+	{ 11.6, 4.165, 60.555 },
+	{ 10.2, 0.329, 70.328 },
+	{ 11.3, 1.076, 72.334 },
+	{ 9.7, 3.06, 2.97 },
+	{ 9.3, 2.44, 565.12 },
+	{ 9.0, 5.19, 225.83 },
+	{ 10.3, 1.186, 344.703 },
+	{ 8.8, 6.01, 5.42 },
+	{ 8.5, 5.25, 347.88 },
+	{ 8.3, 3.72, 14.98 },
+	{ 8.3, 2.27, 299.13 },
+	{ 8.1, 5.72, 55.14 },
+	{ 7.8, 0.90, 222.86 },
+	{ 8.3, 4.49, 70.12 },
+	{ 8.8, 5.82, 153.50 },
+	{ 8.5, 3.91, 333.66 },
+	{ 9.9, 5.97, 35.16 },
+	{ 9.6, 0.39, 415.55 },
+	{ 7.1, 1.51, 991.71 },
+	{ 6.6, 1.18, 96.87 },
+	{ 8.1, 2.26, 206.19 },
+	{ 6.5, 2.99, 380.13 },
+	{ 9.0, 6.05, 146.38 },
+	{ 6.1, 0.06, 99.16 },
+	{ 5.8, 0.82, 142.45 },
+	{ 5.8, 4.63, 49.51 },
+	{ 5.6, 0.66, 58.11 },
+	{ 6.0, 2.49, 373.01 },
+	{ 5.7, 2.24, 80.20 },
+	{ 5.3, 5.07, 440.68 },
+	{ 5.2, 4.36, 977.49 },
+	{ 5.4, 0.85, 546.96 },
+	{ 5.8, 0.34, 536.80 },
+	{ 5.9, 5.48, 76.48 },
+	{ 5.3, 3.73, 23.58 },
+	{ 5.2, 4.14, 132.89 },
+	{ 5.3, 6.14, 39.62 },
+	{ 5.8, 3.40, 458.09 },
+	{ 5.0, 4.26, 522.58 },
+	{ 5.0, 4.79, 387.24 },
+	{ 5.2, 3.26, 561.18 },
+	{ 4.6, 1.69, 152.53 },
+	{ 5.3, 1.84, 124.29 },
+	{ 5.0, 0.37, 60.77 },
+	{ 4.5, 2.30, 312.46 },
+	{ 4.5, 0.46, 33.14 },
+	{ 5.7, 0.90, 81.90 },
+	{ 5.8, 0.92, 20.61 },
+	{ 5.7, 0.66, 38.13 },
+	{ 4.3, 3.55, 479.29 },
+	{ 4.2, 4.38, 79.24 },
+	{ 4.2, 1.65, 128.96 },
+	{ 5.1, 1.41, 144.15 },
+	{ 4.0, 6.07, 19.64 },
+	{ 4.0, 5.77, 288.08 },
+	{ 5.0, 3.00, 29.20 },
+	{ 3.8, 2.60, 426.60 },
+	{ 3.9, 3.20, 159.12 },
+	{ 3.9, 4.44, 141.70 },
+	{ 5.3, 4.08, 111.43 },
+	{ 4.6, 0.01, 298.23 },
+	{ 3.7, 5.28, 353.30 },
+	{ 3.9, 5.27, 521.09 },
+	{ 3.7, 5.15, 490.33 },
+	{ 4.0, 0.61, 152.01 },
+	{ 3.9, 1.34, 535.32 },
+	{ 4.4, 0.62, 827.17 },
+	{ 3.6, 4.72, 6.90 },
+	{ 3.6, 3.25, 230.56 },
+	{ 3.5, 0.79, 983.12 },
+	{ 4.5, 2.87, 129.92 },
+	{ 3.6, 5.59, 774.48 },
+	{ 3.5, 4.50, 376.20 },
+	{ 3.4, 2.56, 258.88 },
+	{ 4.4, 2.10, 404.51 },
+	{ 3.3, 0.90, 469.14 },
+	{ 3.3, 3.86, 42.54 },
+	{ 3.2, 2.76, 248.72 },
+	{ 3.2, 0.08, 1514.29 },
+	{ 3.8, 5.30, 369.08 },
+	{ 3.3, 2.25, 73.82 },
+	{ 3.1, 2.60, 433.71 },
+	{ 3.1, 4.55, 980.67 },
+	{ 3.1, 1.27, 200.77 },
+	{ 3.1, 1.71, 639.90 },
+	{ 3.1, 3.63, 16.67 },
+	{ 3.5, 4.94, 411.62 },
+	{ 3.5, 4.49, 881.51 },
+	{ 3.3, 5.59, 472.17 },
+	{ 3.0, 6.03, 291.26 },
+	{ 3.5, 2.17, 554.07 },
+	{ 3.1, 0.52, 1094.81 },
+	{ 3.3, 2.49, 451.73 },
+	{ 2.9, 0.50, 305.35 },
+	{ 3.1, 4.20, 146.59 },
+	{ 2.9, 2.45, 135.34 },
+	{ 3.0, 0.39, 25.27 },
+	{ 2.8, 2.53, 867.28 },
+	{ 2.7, 5.29, 125.99 },
+	{ 2.9, 4.71, 218.93 },
+	{ 2.8, 4.28, 350.33 },
+	{ 2.7, 1.99, 82.86 },
+	{ 2.9, 3.09, 216.48 },
+	{ 3.4, 3.68, 661.09 },
+	{ 2.9, 1.44, 381.61 },
+	{ 2.8, 0.39, 33.68 },
+	{ 2.8, 4.63, 1357.61 },
+	{ 3.4, 2.13, 685.47 },
+	{ 2.6, 5.93, 89.76 },
+	{ 2.7, 0.76, 486.40 },
+	{ 2.7, 4.16, 235.39 },
+	{ 2.6, 3.82, 550.89 },
+	{ 3.4, 3.17, 108.46 },
+	{ 2.6, 5.68, 24.38 },
+	{ 2.7, 1.87, 529.69 },
+	{ 2.6, 4.37, 1080.58 },
+	{ 2.4, 3.07, 391.17 },
+	{ 2.4, 5.74, 535.91 },
+	{ 2.3, 5.19, 1059.38 },
+	{ 2.6, 1.10, 913.00 },
+	{ 2.2, 6.10, 140.00 },
+	{ 3.1, 5.35, 681.54 },
+	/* 192 terms retained, 0 terms dropped, error 8.5e-07 a.u.*T^2 */
+
+	/* uranus r, T^3 */
+	{ 1164.4, 4.73453, 74.78160 },
+	{ 212.4, 3.3426, 63.7359 },
+	{ 196.4, 2.9800, 70.8494 },
+	{ 104.5, 0.9581, 11.0457 },
+	{ 71.7, 0.025, 56.622 },
+	{ 72.5, 0.997, 149.563 },
+	{ 54.9, 2.594, 3.932 },
+	{ 34.0, 3.816, 76.266 },
+	{ 32.1, 3.598, 131.404 },
+	{ 29.6, 3.441, 85.827 },
+	{ 36.4, 5.650, 77.963 },
+	{ 27.7, 0.428, 3.181 },
+	{ 27.5, 2.551, 52.690 },
+	{ 24.6, 5.140, 78.714 },
+	{ 19.4, 5.135, 18.159 },
+	{ 15.8, 0.371, 447.796 },
+	{ 15.4, 5.573, 462.023 },
+	{ 15.2, 3.860, 73.297 },
+	{ 15.5, 2.975, 145.631 },
+	{ 18.0, 0, 0 },
+	{ 16.0, 5.199, 71.600 },
+	{ 11.1, 6.032, 138.517 },
+	{ 10.5, 3.583, 224.345 },
+	{ 7.6, 1.45, 1.48 },
+	{ 8.1, 2.62, 22.09 },
+	{ 7.1, 5.44, 269.92 },
+	{ 6.5, 4.37, 284.15 },
+	{ 6.8, 0.01, 151.05 },
+	{ 8.1, 0.30, 127.47 },
+	{ 5.8, 4.23, 373.01 },
+	{ 5.0, 1.84, 202.25 },
+	{ 4.7, 2.78, 120.36 },
+	{ 5.1, 0.78, 62.25 },
+	{ 4.2, 1.84, 72.33 },
+	{ 3.9, 1.89, 209.37 },
+	{ 5.2, 4.16, 195.14 },
+	{ 3.6, 2.00, 65.22 },
+	{ 3.6, 3.93, 124.29 },
+	{ 3.8, 1.05, 92.94 },
+	{ 4.2, 3.96, 9.56 },
+	{ 3.5, 1.54, 148.08 },
+	{ 3.2, 2.99, 387.24 },
+	{ 4.0, 1.86, 152.74 },
+	{ 3.3, 1.41, 351.82 },
+	{ 3.6, 1.17, 153.50 },
+	{ 2.9, 6.04, 12.53 },
+	{ 2.7, 5.65, 134.59 },
+	{ 2.8, 0.79, 572.23 },
+	{ 3.1, 5.84, 160.61 },
+	{ 2.7, 1.99, 450.98 },
+	{ 2.7, 2.77, 213.30 },
+	{ 2.3, 1.68, 358.93 },
+	{ 2.3, 5.77, 84.34 },
+	{ 2.3, 4.81, 536.80 },
+	{ 2.2, 2.20, 465.96 },
+	/* 55 terms retained, 0 terms dropped, error 3.3e-07 a.u.*T^3 */
+
+	/* uranus r, T^4 */
+	{ 53.0, 3.008, 74.782 },
+	{ 9.9, 1.91, 56.62 },
+	{ 7.0, 5.09, 11.05 },
+	{ 6.7, 5.43, 149.56 },
+	{ 3.7, 5.23, 131.40 },
+	{ 3.4, 1.30, 85.83 },
+	{ 2.7, 0.44, 63.74 },
+	{ 2.3, 0.92, 145.63 },
+	{ 2.4, 6.21, 358.93 },
+	{ 2.3, 2.23, 440.68 },
+	{ 3.1, 3.14, 0 },
+	/* 11 terms retained, 0 terms dropped, error 2.1e-07 a.u.*T^4 */
+	/* end uranus */
+};
+
+int vn_uranus[][3] = {
+	/* addresses for uranus l, b, r  */
+	/* T^0 */ { 0, 355, 462, },
+	/* T^1 */ { 152, 398, 832, },
+	/* T^2 */ { 253, 432, 1122, },
+	/* T^3 */ { 315, 449, 1314, },
+	/* T^4 */ { 347, 460, 1369, },
+	/* T^5 */ { 354, 462, 1380, },
+	/* end */ { 355, 0, 0, },
+	/* termination */ { 0, }
+};
+
+/*  version d4 (lbr)       
+ *  heliocentric dynamical ecliptic and equinox of the date
+ */
+
+double vx_venus[][3] = {
+	/* venus l, T^0 */
+	{ 317614666.8, 0, 0 },
+	{ 1353968.4, 5.59313320, 10213.28554621 },
+	{ 89891.6, 5.306500, 20426.571092 },
+	{ 5477.2, 4.41631, 7860.41939 },
+	{ 3455.7, 2.69964, 11790.62909 },
+	{ 2372.1, 2.99378, 3930.20970 },
+	{ 1317.1, 5.18668, 26.29832 },
+	{ 1664.1, 4.25019, 1577.34354 },
+	{ 1438.3, 4.15745, 9683.59458 },
+	{ 1200.5, 6.15357, 30639.85664 },
+	{ 761.4, 1.9501, 529.6910 },
+	{ 707.7, 1.0647, 775.5226 },
+	{ 584.8, 3.9984, 191.4483 },
+	{ 769.3, 0.8163, 9437.7629 },
+	{ 499.9, 4.1234, 15720.8388 },
+	{ 326.2, 4.5906, 10404.7338 },
+	{ 429.5, 3.5864, 19367.1892 },
+	{ 327.0, 5.6774, 5507.5532 },
+	{ 231.9, 3.1625, 9153.9036 },
+	{ 179.7, 4.6534, 1109.3786 },
+	{ 128.3, 4.2260, 20.7754 },
+	{ 155.5, 5.5704, 19651.0485 },
+	{ 127.9, 0.9621, 5661.3320 },
+	{ 105.5, 1.5372, 801.8209 },
+	{ 85.7, 0.356, 3154.687 },
+	{ 99.1, 0.833, 213.299 },
+	{ 98.8, 5.394, 13367.973 },
+	{ 82.1, 3.216, 18837.498 },
+	{ 88.0, 3.889, 9999.986 },
+	{ 71.6, 0.111, 11015.106 },
+	{ 56.1, 4.240, 7.114 },
+	{ 70.2, 0.675, 23581.258 },
+	{ 50.8, 0.245, 11322.664 },
+	{ 46.1, 5.316, 18073.705 },
+	{ 44.6, 6.063, 40853.142 },
+	{ 42.6, 5.329, 2352.866 },
+	{ 42.6, 1.800, 7084.897 },
+	{ 41.2, 0.362, 382.897 },
+	{ 35.7, 2.704, 10206.172 },
+	{ 33.9, 2.023, 6283.076 },
+	{ 29.1, 3.592, 22003.915 },
+	{ 28.5, 2.224, 1059.382 },
+	{ 29.8, 4.022, 10239.584 },
+	{ 33.3, 2.100, 27511.468 },
+	{ 30.2, 4.942, 13745.346 },
+	{ 29.3, 3.514, 283.859 },
+	{ 26.3, 0.541, 17298.182 },
+	/* 47 terms retained, 320 terms dropped, error 0.75" */
+
+	/* venus l, T^1 */
+	{ 1021352943052.9, 0, 0 },
+	{ 95707.7, 2.464244, 10213.285546 },
+	{ 14445.0, 0.516246, 20426.571092 },
+	{ 213.4, 1.7955, 30639.8566 },
+	{ 151.7, 6.1064, 1577.3435 },
+	{ 173.9, 2.6554, 26.2983 },
+	{ 82.2, 5.702, 191.448 },
+	{ 69.7, 2.681, 9437.763 },
+	{ 52.4, 3.600, 775.523 },
+	{ 38.3, 1.034, 529.691 },
+	{ 29.6, 1.251, 5507.553 },
+	{ 25.1, 6.107, 10404.734 },
+	{ 17.8, 6.194, 1109.379 },
+	{ 16.5, 2.643, 7.114 },
+	{ 14.2, 5.451, 9153.904 },
+	{ 12.6, 1.245, 40853.142 },
+	{ 11.6, 4.976, 213.299 },
+	{ 12.6, 1.881, 382.897 },
+	{ 8.9, 0.95, 13367.97 },
+	{ 7.4, 4.39, 10206.17 },
+	{ 6.6, 2.28, 2352.87 },
+	{ 6.3, 4.08, 3154.69 },
+	{ 6.7, 5.06, 801.82 },
+	/* 23 terms retained, 192 terms dropped, error 0.14"*T */
+
+	/* venus l, T^2 */
+	{ 54127.1, 0, 0 },
+	{ 3891.5, 0.34514, 10213.28555 },
+	{ 1337.9, 2.02011, 20426.57109 },
+	{ 23.8, 2.046, 26.298 },
+	{ 19.3, 3.535, 30639.857 },
+	{ 10.0, 3.971, 775.523 },
+	{ 7.0, 1.52, 1577.34 },
+	{ 6.0, 1.00, 191.45 },
+	{ 3.2, 4.36, 9437.76 },
+	{ 2.1, 2.66, 40853.14 },
+	{ 1.9, 3.39, 382.90 },
+	/* 11 terms retained, 59 terms dropped, error 0.028"*T^2 */
+
+	/* venus l, T^3 */
+	{ 135.7, 4.8039, 10213.2855 },
+	{ 77.8, 3.669, 20426.571 },
+	{ 26.0, 0, 0 },
+	{ 1.2, 5.32, 30639.86 },
+	/* 4 terms retained, 5 terms dropped, error 0.011"*T^3 */
+
+	/* venus l, T^4 */
+	{ 114.0, 3.1416, 0 },
+	{ 3.2, 5.21, 20426.57 },
+	{ 1.7, 2.51, 10213.29 },
+	/* 3 terms retained, 2 terms dropped, error 0.014"*T^4 */
+
+	/* venus l, T^5 */
+	{ 0.9, 3.14, 0 },
+	{ 0.1, 0.55, 20426.57 },
+	{ 0.1, 1.91, 10213.29 },
+	/* 3 terms retained, 2 terms dropped, error 0.00097"*T^5 */
+	/* end venus l */
+
+	/* venus b, T^0 */
+	{ 5923638.5, 0.26702776, 10213.28554621 },
+	{ 40108.0, 1.147372, 20426.571092 },
+	{ 32814.9, 3.141593, 0 },
+	{ 1011.4, 1.08946, 30639.85664 },
+	{ 149.5, 6.2539, 18073.7049 },
+	{ 137.8, 0.8602, 1577.3435 },
+	{ 130.0, 3.6715, 9437.7629 },
+	{ 119.5, 3.7047, 2352.8662 },
+	{ 108.0, 4.5390, 22003.9146 },
+	{ 92.0, 1.540, 9153.904 },
+	{ 53.0, 2.281, 5507.553 },
+	{ 45.6, 0.723, 10239.584 },
+	{ 38.9, 2.934, 10186.987 },
+	{ 43.5, 6.140, 11790.629 },
+	{ 41.7, 5.991, 19896.880 },
+	{ 39.6, 3.868, 8635.942 },
+	{ 39.2, 3.950, 529.691 },
+	{ 33.3, 4.832, 14143.495 },
+	/* 18 terms retained, 192 terms dropped, error 0.6" */
+
+	/* venus b, T^1 */
+	{ 513347.6, 1.8036431, 10213.2855462 },
+	{ 4380.1, 3.38616, 20426.57109 },
+	{ 196.6, 2.5300, 30639.8566 },
+	{ 199.2, 0, 0 },
+	{ 14.0, 2.271, 9437.763 },
+	{ 13.0, 1.507, 18073.705 },
+	{ 11.9, 5.605, 1577.344 },
+	{ 10.3, 5.242, 2352.866 },
+	{ 9.3, 6.08, 22003.91 },
+	{ 7.4, 1.50, 11790.63 },
+	{ 8.0, 0.29, 9153.90 },
+	{ 7.5, 5.08, 10186.99 },
+	/* 12 terms retained, 121 terms dropped, error 0.11"*T */
+
+	/* venus b, T^2 */
+	{ 22377.7, 3.385091, 10213.285546 },
+	{ 281.7, 0, 0 },
+	{ 173.2, 5.2556, 20426.5711 },
+	{ 26.9, 3.870, 30639.857 },
+	/* 4 terms retained, 55 terms dropped, error 0.25"*T^2 */
+
+	/* venus b, T^3 */
+	{ 646.7, 4.9917, 10213.2855 },
+	{ 20.0, 3.142, 0 },
+	{ 5.5, 0.77, 20426.57 },
+	{ 2.5, 5.44, 30639.86 },
+	/* 4 terms retained, 11 terms dropped, error 0.023"*T^3 */
+
+	/* venus b, T^4 */
+	{ 14.1, 0.315, 10213.286 },
+	{ 0.2, 2.35, 20426.57 },
+	{ 0.2, 0.74, 30639.86 },
+	{ 0.2, 3.14, 0 },
+	/* 4 terms retained, 1 terms dropped, error 0.002"*T^4 */
+
+	/* venus b, T^5 */
+	{ 0.2, 2.05, 10213.29 },
+	/* 1 terms retained, 3 terms dropped, error 0.0014"*T^5 */
+	/* end venus b */
+
+	/* venus r, T^0 */
+	{ 72334820.9, 0, 0 },
+	{ 489824.2, 4.0215183, 10213.2855462 },
+	{ 1658.1, 4.90207, 20426.57109 },
+	{ 1632.1, 2.84549, 7860.41939 },
+	{ 1378.0, 1.12847, 11790.62909 },
+	{ 498.4, 2.5868, 9683.5946 },
+	{ 374.0, 1.4231, 3930.2097 },
+	{ 263.6, 5.5294, 9437.7629 },
+	{ 237.5, 2.5514, 15720.8388 },
+	{ 222.0, 2.0135, 19367.1892 },
+	{ 119.5, 3.0198, 10404.7338 },
+	{ 125.9, 2.7277, 1577.3435 },
+	{ 76.2, 1.596, 9153.904 },
+	{ 85.3, 3.986, 19651.048 },
+	{ 74.3, 4.120, 5507.553 },
+	{ 41.9, 1.643, 18837.498 },
+	{ 42.5, 3.819, 13367.973 },
+	{ 39.4, 5.390, 23581.258 },
+	{ 29.0, 5.677, 5661.332 },
+	{ 27.6, 5.724, 775.523 },
+	{ 27.3, 4.822, 11015.106 },
+	{ 31.3, 2.318, 9999.986 },
+	/* 22 terms retained, 308 terms dropped, error 3e-06 a.u. */
+
+	/* venus r, T^1 */
+	{ 34551.0, 0.891987, 10213.285546 },
+	{ 234.2, 1.7722, 20426.5711 },
+	{ 234.0, 3.1416, 0 },
+	{ 23.9, 1.113, 9437.763 },
+	{ 10.6, 4.592, 1577.344 },
+	{ 9.1, 4.54, 10404.73 },
+	{ 6.6, 5.98, 5507.55 },
+	/* 7 terms retained, 173 terms dropped, error 3.7e-07 a.u.*T */
+
+	/* venus r, T^2 */
+	{ 1406.6, 5.06366, 10213.28555 },
+	{ 15.5, 5.473, 20426.571 },
+	{ 13.1, 0, 0 },
+	/* 3 terms retained, 60 terms dropped, error 5.2e-07 a.u.*T^2 */
+
+	/* venus r, T^3 */
+	{ 49.6, 3.223, 10213.286 },
+	{ 0.8, 3.21, 20426.57 },
+	/* 2 terms retained, 5 terms dropped, error 2.9e-08 a.u.*T^3 */
+
+	/* venus r, T^4 */
+	{ 0.6, 0.92, 10213.29 },
+	/* 1 terms retained, 2 terms dropped, error 1.6e-08 a.u.*T^4 */
+
+	/* venus r, T^5 */
+	/* 0 terms retained, 2 terms dropped, error 9e-10 a.u.*T^5 */
+	/* end venus */
+};
+
+int vn_venus[][3] = {
+	/* addresses for venus l, b, r  */
+	/* T^0 */ { 0, 91, 134, },
+	/* T^1 */ { 47, 109, 156, },
+	/* T^2 */ { 70, 121, 163, },
+	/* T^3 */ { 81, 125, 166, },
+	/* T^4 */ { 85, 129, 168, },
+	/* T^5 */ { 88, 133, 169, },
+	/* end */ { 91, 134, 0, },
+	/* termination */ { 0, }
+};
+
+
+/* For RCS Only -- Do Not Edit */
+static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: vsop87_data.c,v $ $Date: 2001-10-22 12:08:28 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
Index: /tags/V_Dec2002/SophyaLib/BaseTools/Makefile
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/Makefile	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/Makefile	(revision 2309)
@@ -0,0 +1,34 @@
+include ../Mgr/Makefile.h
+ 
+all: $(LIB)libBaseTools.a
+clean:
+	rm -f $(OBJ)datatype.o $(OBJ)dvlist.o $(OBJ)fiondblock.o $(OBJ)mutyv.o $(OBJ)ndatablock.o $(OBJ)pexceptions.o $(OBJ)ppersist.o $(OBJ)sophyainit.o $(OBJ)gnumd5.o $(OBJ)srandgen.o
+	rm -f $(LIB)libBaseTools.a
+$(LIB)libBaseTools.a : $(OBJ)datatype.o $(OBJ)dvlist.o $(OBJ)fiondblock.o $(OBJ)gnumd5.o $(OBJ)mutyv.o $(OBJ)ndatablock.o $(OBJ)pexceptions.o $(OBJ)ppersist.o $(OBJ)sophyainit.o $(OBJ)srandgen.o
+	$(ARCXX) $(ARCXXFLAGS) $@ $($(ARARGS))
+ifeq ($(CXX),cxx)
+	$(CXX) $? $(CPPFLAGS) $(CXXFLAGS) -o $(OBJ)xx.x -Hf
+endif 
+ 
+$(OBJ)datatype.o: datatype.cc datatype.h \
+ $(INC)machdefs.h
+$(OBJ)dvlist.o: dvlist.cc $(INC)machdefs.h dvlist.h \
+ objfio.h anydataobj.h ppersist.h pexceptions.h gnumd5.h mutyv.h \
+ $(INC)strutil.h
+$(OBJ)fiondblock.o: fiondblock.cc $(INC)machdefs.h \
+ pexceptions.h fiondblock.h ppersist.h gnumd5.h ndatablock.h \
+ anydataobj.h piocmplx.h
+$(OBJ)mutyv.o: mutyv.cc mutyv.h $(INC)machdefs.h
+$(OBJ)ndatablock.o: ndatablock.cc $(INC)machdefs.h \
+ pexceptions.h ndatablock.h anydataobj.h
+$(OBJ)pexceptions.o: pexceptions.cc pexceptions.h \
+ $(INC)machdefs.h
+$(OBJ)ppersist.o: ppersist.cc $(INC)machdefs.h \
+ pexceptions.h ppersist.h gnumd5.h anydataobj.h
+$(OBJ)sophyainit.o: sophyainit.cc $(INC)machdefs.h \
+ sophyainit.h pexceptions.h ppersist.h gnumd5.h fiondblock.h \
+ ndatablock.h anydataobj.h dvlist.h objfio.h mutyv.h sversion.h
+$(OBJ)gnumd5.o: gnumd5.c $(INC)machdefs.h bithelp.h \
+ gnumd5.h
+$(OBJ)srandgen.o: srandgen.c $(INC)machdefs.h \
+ srandgen.h smathconst.h
Index: /tags/V_Dec2002/SophyaLib/BaseTools/Makefile.am
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/Makefile.am	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/Makefile.am	(revision 2309)
@@ -0,0 +1,5 @@
+lib_LIBRARIES = libSysTools.a
+
+libSysTools_a_SOURCES = gnumd5.c srandgen.c strutil.c timing.c ctimer.cc datacards.cc datatype.cc dvlist.cc fiondblock.cc mutyv.cc ndatablock.cc pdlmgr.cc periodic.cc pexceptions.cc ppersist.cc psighand.cc sophyainit.cc strutilxx.cc utils.cc
+
+DEFS = -I.. -I../include
Index: /tags/V_Dec2002/SophyaLib/BaseTools/anydataobj.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/anydataobj.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/anydataobj.h	(revision 2309)
@@ -0,0 +1,22 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Ancetre commun de tous les objets pour rtti
+//                          R.Ansari          04/99
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+#ifndef ANYDATAOBJ_H_SEEN
+#define ANYDATAOBJ_H_SEEN
+
+#include "machdefs.h"
+
+namespace SOPHYA {
+
+//! Ancestor class for all data objects (for RTTI).
+
+class AnyDataObj {
+public:
+  AnyDataObj() { } 
+  virtual ~AnyDataObj() { }
+};
+
+}
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/BaseTools/basetools.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/basetools.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/basetools.h	(revision 2309)
@@ -0,0 +1,23 @@
+#ifndef BASETOOLS_H
+#define BASETOOLS_H
+
+/*!
+   \defgroup BaseTools BaseTools module
+   This module contains classes and functions which define the 
+   general framework for \b Sophya package such as the simple
+   persistence, serialisation mechanism through \b PPersist,
+   \b POutPersist, \b PInPersist classes. It contains also
+   few utility classes such as the \b NDataBlock<T>, (template 
+   numerical arrays with reference counting and sharing).
+*/
+
+#include "sophyainit.h"
+#include "ppersist.h"
+#include "ndatablock.h"
+#include "anydataobj.h"
+#include "dvlist.h"
+#include "perrors.h"
+#include "srandgen.h"
+#include "datatype.h"
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/BaseTools/bithelp.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/bithelp.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/bithelp.h	(revision 2309)
@@ -0,0 +1,41 @@
+/* bithelp.h  -  Some bit manipulation helpers
+ *	Copyright (C) 1999 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+#ifndef G10_BITHELP_H
+#define G10_BITHELP_H
+
+
+/****************
+ * Rotate a 32 bit integer by n bytes
+ */
+#if defined(__GNUC__) && defined(__i386__)
+static inline uint_4
+rol( uint_4 x, int n)
+{
+	__asm__("roll %%cl,%0"
+		:"=r" (x)
+		:"0" (x),"c" (n));
+	return x;
+}
+#else
+#define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
+#endif
+
+
+#endif /*G10_BITHELP_H*/
Index: /tags/V_Dec2002/SophyaLib/BaseTools/complexios.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/complexios.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/complexios.h	(revision 2309)
@@ -0,0 +1,18 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Gestion d impression des complex sur les streams
+//                         C.Magneville          04/99
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef COMPLEXIOS_H
+#define COMPLEXIOS_H
+
+#include "machdefs.h"
+#include <iostream.h>
+
+#if defined(NO_IOS_COMPLEX)
+template<class T> 
+inline ostream& operator << (ostream& os, const complex<T>& c)
+           {os<<"("<<c.real()<<","<<c.imag()<<")"; return os;}
+#endif
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/BaseTools/datatype.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/datatype.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/datatype.cc	(revision 2309)
@@ -0,0 +1,109 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe pour nom, taille, ... de types de donnees
+//                         C.Magneville         10/2000
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "datatype.h"
+
+#include <complex>
+
+template <class T>
+DataTypeInfo<T>::DataTypeInfo()
+{
+}
+
+string DataTypeInfo<uint_1>::getTypeName() { return("uint_1"); }
+string DataTypeInfo<uint_2>::getTypeName() { return("uint_2"); }
+string DataTypeInfo<int_2>::getTypeName() { return("int_2"); }
+string DataTypeInfo<int_4>::getTypeName() { return("int_4"); }
+string DataTypeInfo<int_8>::getTypeName() { return("int_8"); }
+string DataTypeInfo<uint_4>::getTypeName() { return("uint_4"); }
+string DataTypeInfo<uint_8>::getTypeName() { return("uint_8"); }
+string DataTypeInfo<r_4>::getTypeName() { return("r_4"); }
+string DataTypeInfo<r_8>::getTypeName() { return("r_8"); }
+string DataTypeInfo< complex<r_4> >::getTypeName() { return(" complex<r_4> "); }
+string DataTypeInfo< complex<r_8> >::getTypeName() { return(" complex<r_8> "); }
+
+
+
+string DecodeGCCTypeName(string gcctype)
+// seulement pour gcc/g++ qui ne code pas correctement
+{
+#if defined(__GNUG__)
+  string type("");
+  const char* str = gcctype.c_str();
+  int lstr = (int) strlen(str);
+  if(lstr<=0) return string("Linux Decoding error: lstr<=0");
+
+  // Le dernier caractere donne le type
+  lstr--;
+  if     (str[lstr]=='v') type = "void";
+  else if(str[lstr]=='b') type = "bool";
+  else if(str[lstr]=='c') type = "char";
+  else if(str[lstr]=='s') type = "short";
+  else if(str[lstr]=='i') type = "int";
+  else if(str[lstr]=='l') type = "long";
+  else if(str[lstr]=='x') type = "long long";
+  else if(str[lstr]=='f') type = "float";
+  else if(str[lstr]=='d') type = "double";
+  else if(str[lstr]=='r') type = "long double";
+  else return string("Linux Decoding error: bad last char");
+  if(lstr==0) return type;
+
+  // Les caracteres precedents donnent: signed, unsigned, *, & ou const.
+  // Mais si on a un Z, alors c'est un complexe (code ...t7complex1Z...)
+  for(int i=0; i<(int)strlen(str); i++) {
+    lstr--;
+    if     (str[lstr]=='U') type = "unsigned " + type;
+    else if(str[lstr]=='S') type = "signed " + type;
+    else if(str[lstr]=='P') type = type + "*";
+    else if(str[lstr]=='R') type = type + "&";
+    else if(str[lstr]=='C') type = "const " + type;
+    else if(str[lstr]=='Z') {  // Complexe
+      type = "complex<" + type + ">";
+      for(int j=0;j<(int)strlen(str);j++) {
+        if     (str[j]=='P') type = type + "*";
+        else if(str[j]=='R') type = type + "&";
+        else if(str[j]=='C') type = "const " + type;
+        else if(str[j]=='t') break;
+        else return string("Linux Decoding error: bad char 1,2 for Z");
+      }
+      break;
+    }
+    else return string("Linux Decoding error: bad last-1,last-2 char");
+    if(lstr==0) break;
+  }
+
+return type;
+#else
+return gcctype;
+#endif
+}
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template DataTypeInfo<uint_1>
+#pragma define_template DataTypeInfo<uint_2>
+#pragma define_template DataTypeInfo<int_2>
+#pragma define_template DataTypeInfo<int_4>
+#pragma define_template DataTypeInfo<int_8>
+#pragma define_template DataTypeInfo<uint_4>
+#pragma define_template DataTypeInfo<uint_8>
+#pragma define_template DataTypeInfo<r_4>
+#pragma define_template DataTypeInfo<r_8>
+#pragma define_template DataTypeInfo< complex<r_4> >
+#pragma define_template DataTypeInfo< complex<r_8> >
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class DataTypeInfo<uint_1>;
+template class DataTypeInfo<uint_2>;
+template class DataTypeInfo<int_2>;
+template class DataTypeInfo<int_4>;
+template class DataTypeInfo<int_8>;
+template class DataTypeInfo<uint_4>;
+template class DataTypeInfo<uint_8>;
+template class DataTypeInfo<r_4>;
+template class DataTypeInfo<r_8>;
+template class DataTypeInfo< complex<r_4> >;
+template class DataTypeInfo< complex<r_8> >;
+#endif
Index: /tags/V_Dec2002/SophyaLib/BaseTools/datatype.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/datatype.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/datatype.h	(revision 2309)
@@ -0,0 +1,26 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe pour nom, taille, ... de types de donnees
+//                         C.Magneville         10/2000
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef DATATYPE_H
+#define DATATYPE_H
+
+#include "machdefs.h"
+
+#include <string>
+
+namespace SOPHYA {
+
+template <class T>
+class DataTypeInfo {
+public:
+  static string getTypeName();
+  DataTypeInfo();
+};
+
+string DecodeGCCTypeName(string gcctype);
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/BaseTools/dvlist.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/dvlist.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/dvlist.cc	(revision 2309)
@@ -0,0 +1,599 @@
+//  Classe Dynamic Variable List (DVList) de PEIDA
+//                  R. Ansari  1997
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "machdefs.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "dvlist.h"
+#include "strutil.h"
+
+//++
+// Class	DVList
+// Lib		BaseTools
+// include	dvlist.h
+//
+//	Cette classe permet de gérer une ensemble de variables (ou paramètres)
+//	pouvant être définies dynamiquement à l'execution. Le nom des 
+//	variables ne doit pas contenir de blancs ("<espace>") et est 
+//	limité à 64 caractères maximum. Cette classe 
+//	offre la possibilité de sauvegarder l'ensemble 
+//	des variables (Nom, Type, Valeur) dans un fichier, ou de
+//	recréer l'objet DVList et l'ensemble de ses variables à 
+//	partir d'un fichier (Objet PPersist). Une zone commentaire (max=320 c.) 
+//	est associée à chaque objet DVList, accessible à travers  
+//	la méthode "Comment()". Les objets de cette classe sont  
+//	en particulier destinés à être inclus dans d'autres objets 
+//	PPersist plus complexes. La classe DVList gère des 
+//	variables de type entier ("int_8"), réél double précision ("r_8")
+//	et de type chaine de caracteres ("string, char*", maxi 30 caracteres ).
+//	Une classe intermédiaire (*MuTyV*) est utilisée pour représenter une 
+//	variable et fournit les services de conversion entre les différents types.
+//--
+//--
+//++
+// Links	Parents
+// PPersist
+//--
+
+
+static MuTyV ddvdum(-9.e19);
+
+
+/*!
+   \class SOPHYA::DVList
+   \ingroup BaseTools
+   This class can be used to construct list of values associated with names.
+   Variables names should not contain space characters and is limited to 64
+   characters. The DVList class uses \b SOPHYA::MuTyV objects to hold values
+   of type string, integer (\b int_8) or float (\b r_8). A comment string
+   can be associated with each variable name. A global comment string
+   can be attached to the DVList object. DVList objects can conveniently be 
+   used to represent FITS headers. The class \b SOPHYA::ObjFileIO<DVList>
+   handles serialisation for DVList. (See SOPHYA::PPersist ).
+   \sa SOPHYA::ObjFileIO<DVList>
+
+   \code
+   //  ------- Using DVList objects ------ 
+   DVList  dvl;
+   dvl("toto") = 14;      // Integer type value (=14) named toto
+   dvl("titi") = 25.5;    // float type value (=25.5) named titi
+   dvl("tata") = "Bonjour !"; // string type value (="Bonjour !") named tata 
+   // Upper and lower case letters are distinguished
+   dvl("hello") = 88;
+   dvl("Hello") = 77.77;    
+   dvl.Comment() = "DVList test object, with values named hello, Hello ";
+   // Saving the dvl object into a PPF file 
+   POutStream os("dvl.ppf");
+   os << dvl;
+   //  later on ...
+   DVList dvlr; 
+   PInStream is("dvl.ppf");
+   is << dvlr;
+   int k = dvlr["toto"] ;     //  k = 14
+   r_8 b = dvlr["titi"] ;     //  b = 25.5
+   string s =  dvlr["tata"] ; //  s = "Bonjour !"
+   int m =  dvlr["hello"] ;   //  m = 88
+
+   \endcode
+*/
+
+//++
+// Titre	Constructeurs
+//--
+
+//++
+// DVList()
+//	Constructeur par défaut
+// DVList(DVList& cfd)
+//	Constructeur par copie. Le nouvel objet est une copie complète de "cfd"
+// DVList(char* flnm)
+//	Constructeur avec initialisation à partir du contenu du fichier (PPF)
+//	"flnm". Le fichier doit avoir été créé par la méthode "Write()"
+//--
+
+/* --Methode-- */
+/*! Default constructor */
+DVList::DVList()
+{
+comment = "";
+}
+
+/* --Methode-- */
+/*! copy constructor */
+DVList::DVList(const DVList& dvl)
+{
+Merge(dvl);
+}
+
+/* --Methode-- */
+/*! Copy constructor - Object initialized using the PPF file \b flnm */
+DVList::DVList(char *flnm)
+{
+PInPersist s(flnm);
+ObjFileIO<DVList> fiodvl(this);
+fiodvl.Read(s);
+}
+
+
+/* --Methode-- */
+DVList::~DVList()
+{
+}
+
+//++
+// Titre	Gestion des variables et opérateurs
+//--
+
+//++
+// void  Clear()
+//	Supprime la définition de toutes les variables de l'objet.
+// DVList&  Merge(const DVList& lv)
+//	Fusionne l'objet avec la liste des variables de l'objet "lv"
+// DVList&  operator= (const DVList& cofr)
+//	Remplace la liste des variables de l'objet par celle de l'objet "cofr".   
+//--
+
+/* --Methode-- */
+/*! Copy operator - Replaces the variables list with the list from \b dvl */
+DVList&     DVList::operator= (const DVList& dvl)
+{
+Clear();
+return(Merge(dvl));
+}
+
+
+/* --Methode-- */
+/*! Resets the object and clears the variable list and global comment */
+void        DVList::Clear()
+{
+mvlist.erase(mvlist.begin(), mvlist.end());
+comment = "";
+}
+
+/* --Methode-- */
+/*! Appends the values from the object \b dvl to the objects list */
+DVList&     DVList::Merge(const DVList& dvl)
+{
+ValList::const_iterator it;
+for(it = dvl.mvlist.begin(); it != dvl.mvlist.end(); it++)
+  {
+  switch ((*it).second.elval.Type()) 
+    {
+    case MuTyV::MTVInteger :
+      SetI((*it).first, (*it).second.elval.GetIntPart());
+      break;
+    case  MuTyV::MTVFloat : 
+      SetD((*it).first, (*it).second.elval.GetRealPart());
+      break;
+    case MuTyV::MTVComplex : 
+      SetZ((*it).first, complex<r_8>((*it).second.elval.GetRealPart(), (*it).second.elval.GetImagPart()));
+      break;
+    case MuTyV::MTVString : 
+      SetS((*it).first, *((*it).second.elval.GetStringPointer()));
+      break;
+    default :
+      break;
+    }
+  SetComment((*it).first, (*it).second.elcomm);
+  }
+comment = comment + "\n" + dvl.comment;
+return(*this);
+}
+
+
+//++
+// int_8   GetI(string const& key, int_8  def=-1)
+// r_8     GetD(string const& key, r_8 def=-9.e19)
+// string  GetS(string const& key, char* def="")
+//	Retourne la valeur de la variable de nom "key" et de type entier, réél, 
+//	chaine de caracteres.
+//	Si la variable n'existe pas, la valeur par défaut "def" est renvoyée.
+// string  GetComment(string const& key)
+//	Retourne le commentaire associé à la variable de nom "key".
+//--
+
+/* --Methode-- */
+/*! Returns the value corresponding to name \b key, converted to integer
+    Default value \b def is returned if name \b key not found */
+int_8       DVList::GetI(string const& key, int_8 def) const
+{
+ValList::const_iterator it = mvlist.find(key);
+if (it == mvlist.end())  return(def);
+return( (int_8)((*it).second.elval) );
+}
+
+/* --Methode-- */
+/*! Returns the value corresponding to name \b key, converted to double
+    Default value \b def is returned if name \b key not found */
+r_8      DVList::GetD(string const& key, r_8 def) const
+{
+ValList::const_iterator it = mvlist.find(key);
+if (it == mvlist.end())  return(def);
+return( (r_8)((*it).second.elval) );
+}
+
+/* --Methode-- */
+/*! Returns the value corresponding to name \b key, converted to complex
+    Default value \b def is returned if name \b key not found */
+complex<r_8>       DVList::GetZ(string const& key, complex<r_8> def) const
+{
+ValList::const_iterator it = mvlist.find(key);
+if (it == mvlist.end())  return(def);
+/*  
+    Appel explicite de l'operateur de conversion 
+    suite a la suggestion de M. Reinecke, Reza 31/7/2002 
+#if defined(__GNUG__)
+complex<r_8> z;
+z = (*it).second.elval;
+return(z);
+#else
+return( (complex<r_8>)(*it).second.elval );
+#endif
+   --- Appel explicite de l'operateur de conversion sur l'objet MuTyV 
+*/
+return( (*it).second.elval.operator complex<r_8>() );
+}
+
+/* --Methode-- */
+/*! Returns the value corresponding to name \b key, converted to string
+    Default value \b def is returned if name \b key not found */
+string      DVList::GetS(string const& key, char* def) const
+{
+ValList::const_iterator it = mvlist.find(key);
+if (it == mvlist.end())  return(def);
+return( (string)((*it).second.elval) );
+}
+
+/* --Methode-- */
+/*! Returns the comment associated with name \b key */ 
+string      DVList::GetComment(string const& key) const
+{
+ValList::const_iterator it = mvlist.find(key);
+if (it == mvlist.end())  return("");
+return((*it).second.elcomm);
+}
+
+//++
+// void  SetI(string const& key, int_8  val)
+// void  SetD(string const& key, r_8 val)
+// void  SetZ(string const& key, complex<r_8> val)
+// void  SetS(string const& key, char*  val)
+// void  SetS(string const& key, string val)
+//	Crée la variable de nom "key", de type entier, double, complexe, string et 
+//	lui attribue la valeur "val". Si une variable du même nom existe, 
+//	sa valeur et eventuellement son type sont modifiés.  Les noms de
+//	variables ne doivent pas contenir de caractères spéciaux, 
+//	en particulier pas de CR/LF.
+// void  SetComment(string const& key, string const& comm)
+//	Modifie le commentaire associé à la variable de nom "key", si
+//	celle-ci existe. Le texte du commentaire ne doit pas contenir
+//	de caractères spéciaux, et en particulier pas de CR/LF. 
+//--
+
+/* --Methode-- */
+/*! Removes the definition and value associated with the name \b key. 
+  Return \c true if the \b key is found in the list, \c false otherwise. */
+bool        DVList::DeleteKey(string const& key)
+{
+ValList::iterator it = mvlist.find(key);
+if (it == mvlist.end())  return(false);
+mvlist.erase(it);
+return(true);
+}
+
+/* --Methode-- */
+/*!  Return \c true if the \b key is found in the list, \c false otherwise. */
+bool        DVList::HasKey(string const& key) const
+{
+ValList::const_iterator it = mvlist.find(key);
+if (it == mvlist.end())  return(false);
+return(true);
+}
+
+
+/* --Methode-- */
+/*! Appends or sets the integer value \b val in the list with name \b key */
+void        DVList::SetI(string const& key, int_8 val)
+{
+Get(key) = (int_8)val;
+}
+
+/* --Methode-- */
+void        DVList::SetD(string const& key, r_8 val)
+/*! Appends or sets the double value \b val in the list with name \b key */
+{
+Get(key) = (r_8)val;
+}
+
+/* --Methode-- */
+void        DVList::SetZ(string const& key, complex<r_8> val)
+/*! Appends or sets the complex value \b val in the list with name \b key */
+{
+Get(key) = val;
+}
+
+/* --Methode-- */
+/*! Appends or sets the string value \b val in the list with name \b key */
+void        DVList::SetS(string const& key, char const* val)
+{
+MuTyV div(val);
+Get(key) = div;
+}
+
+/* --Methode-- */
+/*! Appends or sets the string value \b val in the list with name \b key */
+void        DVList::SetS(string const& key, string const& val)
+{
+MuTyV div(val);
+Get(key) = div;
+}
+
+/* --Methode-- */
+/*! Assigns the comment \b comm with the name \b key . 
+    Does nothing if the entry with name is not present in the list   */
+void        DVList::SetComment(string const& key, string const& comm)
+{
+ValList::iterator it = mvlist.find(key);
+if (it == mvlist.end())  return;
+(*it).second.elcomm = comm;
+}
+
+//++
+// MuTyV&  Get(string const& key) 
+//	Renvoie une référence sur l'objet "MuTyV" de la liste avec le nom "key".
+//	Si cet objet (variable) n'existe pas, il est créé.
+// MuTyV&     operator()  (string const& key) 
+// MuTyV&     operator[]  (string const& key) 
+//
+//	Renvoie la variable de nom "key". Equivalent à "Get(key)". 
+// string&  Comment()
+//	Renvoie une référence sur le champ commentaire de l'objet.
+//--
+
+/* --Methode-- */
+/*!  Return the MuTyV value associated with name \b key .
+     Integer 0 is returned if \b key is not present in the list   */
+MuTyV       DVList::Get(string const& key) const
+{
+ValList::const_iterator it = mvlist.find(key);
+if (it == mvlist.end()) return(MuTyV( (int_8) 0));
+else return((*it).second.elval);
+}
+
+/* --Methode-- */
+/*!  Return the MuTyV value associated with name \b key .
+     Adds an entry of type integer in the list if \b key is not present in the list   */
+MuTyV&      DVList::Get(string const& key)
+{
+size_t l = key.length();
+if ( (l < 1) || (key.find_first_of(" ") < l) )  return(ddvdum);
+// dvlElement xxx = {(int_8)0 , ""};  marche pas sur mac/CW (!) - cf DY
+dvlElement xxx; xxx.elval = (int_8)0;  xxx.elcomm = "";
+ValList::iterator it = mvlist.find(key);
+if (it == mvlist.end()) mvlist[key] = xxx;  
+it = mvlist.find(key);
+if (it == mvlist.end()) return(ddvdum); 
+else return((*it).second.elval);
+}
+
+//++
+// Titre	Entrée-Sortie
+//--
+
+//++
+//  void  Print()
+//	Imprime (sur "cout") la liste des variables et leurs valeurs.
+//  void  Print(ostream& os)
+//	Imprime sur le flot "os" la liste des variables et leurs valeurs.
+//  ostream&    operator << (ostream& s, DVList& dvl)
+//	sortie sur flot "s" (Appel a "Print(s)").
+//--
+
+/* --Methode-- */
+/*! Prints a brief description of object on on the output stream \b os */
+void        DVList::Show(ostream& os) const
+{
+os << "DVList::Show() - NVar= " << (int)mvlist.size() << "\n";
+os << comment << endl;
+}
+
+/* --Methode-- */
+/*! Prints the list of variables on the output stream \b os */
+void        DVList::Print(ostream& os) const
+{
+os << "DVList::Print() - NVar= " << (int)mvlist.size() << "\n";
+if (comment.length() > 0)  os << comment << endl;
+char buff[1024];
+ValList::const_iterator it;
+for(it = mvlist.begin(); it != mvlist.end(); it++)  {
+  switch ((*it).second.elval.Type()) 
+    {
+    case MuTyV::MTVInteger :
+      sprintf(buff, "%s = %ld (int) %s\n", (*it).first.substr(0,64).c_str(), 
+	      (long)((*it).second.elval.GetIntPart()), (*it).second.elcomm.substr(0,128).c_str());
+      break;
+    case MuTyV::MTVFloat : 
+      sprintf(buff, "%s = %.20g (double) %s\n", (*it).first.substr(0,64).c_str(), 
+	      (*it).second.elval.GetRealPart(), (*it).second.elcomm.substr(0,128).c_str());
+      break;
+    case MuTyV::MTVComplex : 
+      sprintf(buff, "%s = %.20g %.20g i (complex) %s\n", (*it).first.substr(0,64).c_str(), 
+	      (*it).second.elval.GetRealPart(), (*it).second.elval.GetImagPart(), (*it).second.elcomm.substr(0,128).c_str());
+      break;
+    case MuTyV::MTVString : 
+      sprintf(buff, "%s = %s (string) %s\n", (*it).first.substr(0,64).c_str(), 
+	      (*it).second.elval.GetStringPointer()->substr(0,800).c_str(), (*it).second.elcomm.substr(0,128).c_str());
+      break;
+    default :
+      break;
+    }
+  os << (string)buff;
+  }
+os << endl;
+}
+
+
+//++
+// Titre	Exemples
+//	Utilisation des objets *MuTyV* :
+//|	MuTyV mvu;         // Declaration d'une variable 
+//|	mvu = 60;          // mvu est de type entier (= 60)
+//|	mvu = 66.6;        // et double (= 66.6) maintenant ...   
+//|	MuTyV mvi(14);     // On construit une variable entiere = 14
+//|	r_4 x = mvi;     // x vaut 14.0
+//|	MuTyV mvd(44.4);   // Variable double = 44.4
+//|	int k = mvd;       // k vaut 44  
+//|	MuTyV mvs("Bonjour, Ca va ?");   // Variable chaine de caracteres 
+//|	string s = mvs;    // s vaut "Bonjour, Ca va ?"  
+//	Utilisation des *DVList* :		 
+//|	DVList  dvl;
+//|	dvl("toto") = 14;
+//|	dvl("titi") = 25.5;
+//|	dvl("tata") = "Bonjour, Ca va ?";
+//	Majuscules et minuscules sont differenciees pour les noms, pas de blanc ...
+//|	dvl("hello") = 88;
+//|	dvl("Hello") = 77.77;
+//|	dvl.Comment() = "Test d'objet DVList, avec variables hello, Hello ";
+//|	dvl.Write("dvlist.ppf");
+//	Plus loin, ou dans un autre programme, on relit le fichier fabrique plus haut 
+//|	DVList dvlr("dvlist.ppf");
+//|	int k = dvlr["toto"] ;     //  k = 14
+//|	r_8 b = dvlr["titi"] ;  //  b = 25.5
+//|	string s =  dvlr["tata"] ; //  s = "Bonjour, Ca va ?"
+//|	r_4 c = dvlr["Hello"] ;  //  c = 77.77
+//|	int l =  dvlr["Hello"] ;   //  l = 77
+//|	int m =  dvlr["hello"] ;   //  m = 88
+//--
+
+
+//----------------------------------------------------------
+// Classe pour la gestion de persistance
+// ObjFileIO<DVList>
+//----------------------------------------------------------
+
+/* --Methode-- */
+void        ObjFileIO<DVList>::WriteSelf(POutPersist& s) const
+{
+char buf[1024];
+string sfw;
+int lc = dobj->Comment().length();
+//  itab -  0 : Version,  1 : NVar,  2  : Comment length, 3 reserved
+uint_4 itab[4];
+itab[0] = 2;  // Version number = 2 
+itab[1] = dobj->Size(); 
+itab[2] = lc; 
+itab[3] = 0;
+s.Put(itab, 4);
+
+if (lc > 0) s.PutStr(dobj->Comment());
+sfw = "\n----Variable-List---------------\n";  
+s.PutStr(sfw);
+
+DVList::ValList::const_iterator it;
+for(it = dobj->Begin(); it != dobj->End(); it++)  {
+  switch ((*it).second.elval.Type()) {
+    case MuTyV::MTVInteger :
+      sprintf(buf,"I %s %ld\n", (*it).first.substr(0,64).c_str(), (long)((*it).second.elval.GetIntPart()) );
+      sfw = buf;  s.PutStr(sfw);
+      break;
+    case MuTyV::MTVFloat : 
+      sprintf(buf,"F %s %.20g\n", (*it).first.substr(0,64).c_str(), (*it).second.elval.GetRealPart() );
+      sfw = buf;  s.PutStr(sfw);
+      break;
+    case MuTyV::MTVComplex : 
+      sprintf(buf,"Z %s %.20g %.20g\n", (*it).first.substr(0,64).c_str(), (*it).second.elval.GetRealPart(), 
+                                      (*it).second.elval.GetImagPart());
+      sfw = buf;  s.PutStr(sfw);
+      break;
+    case MuTyV::MTVString : 
+      sprintf(buf,"S %s %s\n", (*it).first.substr(0,64).c_str(), (*it).second.elval.GetStringPointer()->substr(0,960).c_str() );
+      sfw = buf;  s.PutStr(sfw);
+      break;
+    default :
+      break;
+  }
+// Ecriture eventuelle du commentaire associe
+  if ((*it).second.elcomm.length() > 0) {
+    sprintf(buf,"# %s", (*it).second.elcomm.substr(0,256).c_str());
+    sfw = buf;  s.PutStr(sfw);
+  }
+}
+
+sfw = "ZZZZZ--End-of-Varible-List------"; s.PutStr(sfw);
+}
+
+/* --Methode-- */
+void        ObjFileIO<DVList>::ReadSelf(PInPersist& s)
+{
+char buf[1024];
+string sfr;
+int_8 j,iv,k;
+r_8 dv, dvi;
+bool ok=true;
+buf[0] = '\0';
+dobj->Clear();
+
+//  itab -  0 : Version,  1 : NVar,  2  : Comment length, 3 reserved
+uint_4 itab[4];
+s.Get(itab, 4);
+if (itab[2] > 0) {  // Il y a un champ commentaire a lire 
+  s.GetStr(sfr);
+  dobj->Comment() = sfr;
+  }
+
+s.GetStr(sfr);  // Pour lire les "------- "
+
+string key="";
+while(ok) {
+  s.GetStr(sfr);
+  strncpy(buf, sfr.c_str(), 1024);
+  buf[1023] = '\0';
+  j = strlen(buf)-1;
+  if ( (j >= 0) && (buf[j] == '\n') )  buf[j] = '\0';
+  if (strncmp(buf,"ZZZZZ",5) == 0)  { ok=false; break; }
+  if (buf[0] == '#') {
+    dobj->SetComment(key, buf+2);
+    continue;
+  }
+  j = posc(buf+2, ' ')+2;
+  buf[j] = '\0';
+  switch (buf[0]) {
+    case 'I' :
+      iv = (int_8)atol(buf+j+1);
+      key = buf+2;
+      dobj->SetI(key, iv);
+      break;
+    case 'F' :
+      dv = atof(buf+j+1);
+      key = buf+2;
+      dobj->SetD(key, dv);
+      break;
+    case 'Z' :
+      k = posc(buf+j+1, ' ')+j+1;
+      buf[k] = '\0';
+      dv = atof(buf+j+1);
+      dvi = atof(buf+k+1);
+      key = buf+2;
+      dobj->SetZ(key, complex<r_8>(dv, dvi));
+      break;
+    case  'S' :
+      key = buf+2;
+      dobj->SetS(key, buf+j+1);
+      break;
+    default :
+      break;
+    }
+  }
+if (dobj->Size() != itab[1])  // Probleme !!!
+  throw FileFormatExc("ObjFileIO<DVList>::ReadSelf() Error in Nb. Variables !");
+}
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template ObjFileIO<DVList>
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class ObjFileIO<DVList>;
+#endif
Index: /tags/V_Dec2002/SophyaLib/BaseTools/dvlist.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/dvlist.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/dvlist.h	(revision 2309)
@@ -0,0 +1,116 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe DVList : Liste dynamique de variables (valeurs) 
+// identifiees par un nom    Reza Ansari - Dec 96
+
+#ifndef DVLIST_H_SEEN
+#define DVLIST_H_SEEN
+
+#include "objfio.h"
+
+#include <stdio.h>
+#include <iostream.h>
+
+#include "mutyv.h"
+#include <list>
+#include <map>
+
+namespace SOPHYA {
+
+//  Classe liste de variables  Dynamic Variable List  
+
+//! Dynamic Variable List class. 
+class DVList : public AnyDataObj {
+public:
+
+                    DVList();
+                    DVList(const DVList&);
+                    DVList(char *flnm);
+
+  virtual           ~DVList();
+
+  DVList&           operator= (const DVList&);
+
+  void              Clear();
+  DVList&           Merge(const DVList&);
+
+  //! Returns the number of elements (variables) in DVList object 
+  inline int	    Size() { return(mvlist.size()); }
+  //! Returns the number of elements (variables) in DVList object 
+  inline int	    NVar() { return(mvlist.size()); }
+
+  int_8             GetI(string const& key, int_8 def=-1) const;
+  r_8               GetD(string const& key, r_8 def=-9.e19) const;
+  complex<r_8>      GetZ(string const& key, complex<r_8> def=-9.e19) const;
+  string            GetS(string const& key, char* def="") const;
+  string            GetComment(string const& key) const;
+
+  bool              DeleteKey(string const& key);
+  bool              HasKey(string const& key) const;
+
+  void              SetI(string const& key, int_8 val);
+  void              SetD(string const& key, r_8 val);
+  void              SetZ(string const& key, complex<r_8> val);
+  void              SetS(string const& key, char const*  val);
+  void              SetS(string const& key, string const& val);
+  void              SetComment(string const& key, string const& comm);
+
+  MuTyV             Get(string const& key) const ;
+  MuTyV&            Get(string const& key);
+/*! Returns the value associated with the name \b key */
+  inline MuTyV      operator()  (string const& key) const { return Get(key); }
+/*! Returns the value associated with the name \b key */
+  inline MuTyV      operator[]  (string const& key) const { return Get(key); }
+/*! Returns the global comment string associated with the object */
+  inline string     Comment() const { return(comment); }
+/*! Returns the value associated with the name \b key */
+  inline MuTyV&     operator()  (string const& key)  { return Get(key); }
+/*! Returns the value associated with the name \b key */
+  inline MuTyV&     operator[]  (string const& key)  { return Get(key); }
+/*! Returns the global comment string associated with the object */
+  inline string&    Comment() { return(comment); }
+
+/*! Prints a brief description of object on \b cout */
+  inline  void      Show() const { Show(cout); }
+  virtual void      Show(ostream& os)  const;
+/*! Prints the list of variables on \b cout */
+  inline  void      Print() const  { Print(cout); }  
+  virtual void      Print(ostream& os)  const;
+
+// Chaque element dans un DVList est constitue desormais d'un MuTyV
+// et d'une chaine de caracteres (commentaire) regroupe dans la structure
+// dvlElement. Ces elements sont associes aux noms de variables dans un 
+// map<...> ValList.            Reza 02/2000
+
+  struct dvlElement {MuTyV elval; string elcomm; } ;
+  typedef map<string, dvlElement, less<string> >  ValList; 
+/*! Returns an iterator pointing on the first variable in the list */
+  inline ValList::const_iterator Begin() { return(mvlist.begin()); } 
+/*! Returns the iterator end value */
+  inline ValList::const_iterator End() { return(mvlist.end()); } 
+  
+
+private:
+  
+  ValList mvlist;
+  string comment;
+};
+
+/*! operator << overloading - Prints the list on the stream \b s */
+inline ostream& operator << (ostream& s, DVList const & dvl)
+  {  dvl.Print(s);  return(s);  }
+
+/*! Writes the object in the POutPersist stream \b os */
+inline POutPersist& operator << (POutPersist& os, DVList & obj)
+{ ObjFileIO<DVList> fio(&obj);  fio.Write(os);  return(os); }
+/*! Reads the object from the PInPersist stream \b is */
+inline PInPersist& operator >> (PInPersist& is, DVList & obj)
+{ ObjFileIO<DVList> fio(&obj);  fio.Read(is);  return(is); }
+
+// Classe pour la gestion de persistance
+// ObjFileIO<DVList>
+
+} // namespace SOPHYA
+
+#endif /* DVLIST_H__SEEN */
+
+
Index: /tags/V_Dec2002/SophyaLib/BaseTools/fiondblock.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/fiondblock.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/fiondblock.cc	(revision 2309)
@@ -0,0 +1,169 @@
+// Classe pour la gestion de persistance pour NDataBlock<T>
+//                         C.Magneville          04/99-03/2000
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream.h>
+#include <complex>
+#include "pexceptions.h"
+#include "fiondblock.h"
+#include "datatype.h"
+#include <typeinfo>
+
+////////////////////////////////////////////////////////////////
+// -------------------------------------------------------------------------
+//   Les objets delegues pour la gestion de persistance 
+// -------------------------------------------------------------------------
+
+/*
+template <class T>
+void ObjFileIO< NDataBlock<T> >::ReadSelf(PInPersist& is)
+template <class T>
+void ObjFileIO< NDataBlock<T> >::WriteSelf(POutPersist& os)
+*/
+
+// Pour pouvoir ecrire des tableaux de complex, en attendant 
+// PIn/POutPersist::Get/Put(complex<>)
+#include "piocmplx.h"
+
+template <class T>
+FIO_NDataBlock<T>::FIO_NDataBlock()
+{
+dobj=new NDataBlock<T>;
+ownobj=true;
+}
+
+template <class T>
+FIO_NDataBlock<T>::FIO_NDataBlock(string const & filename) 
+{
+dobj=new NDataBlock<T>;
+ownobj=true; 
+Read(filename);
+}
+
+template <class T>
+FIO_NDataBlock<T>::FIO_NDataBlock(const NDataBlock<T> & obj) 
+{ 
+dobj = new NDataBlock<T>(obj);
+ownobj=true; 
+}
+
+template <class T>
+FIO_NDataBlock<T>::FIO_NDataBlock(NDataBlock<T> * obj) 
+{ 
+dobj = obj;
+ownobj=false; 
+}
+
+template <class T>
+FIO_NDataBlock<T>::~FIO_NDataBlock()
+{
+if (ownobj && dobj) delete dobj;
+}
+
+template <class T>
+AnyDataObj* FIO_NDataBlock<T>::DataObj()
+{
+return(dobj);
+}
+
+template <class T>
+void FIO_NDataBlock<T>::SetDataObj(AnyDataObj & o)
+{
+NDataBlock<T> * po = dynamic_cast< NDataBlock<T> * >(&o);
+if (po == NULL) {
+  char buff[160];
+  sprintf(buff,"FIO_NDataBlock<T><%s>::SetDataObj(%s) - Object type  error ! ",
+	  DataTypeInfo<T>::getTypeName().c_str(), typeid(o).name());
+  throw TypeMismatchExc(PExcLongMessage(buff));    
+}
+if (ownobj && dobj) delete dobj;
+dobj = po; ownobj = false;
+} 
+
+template <class T>
+uint_8 FIO_NDataBlock<T>::getMemOId() const
+{
+  uint_8 rv = 0;
+  if (dobj) rv = (uint_8)(dobj->DRefId());
+  return(rv);
+}
+
+template <class T>
+void FIO_NDataBlock<T>::ShareDataReference(PPersist & pp)
+{
+  FIO_NDataBlock<T> *ppo = dynamic_cast< FIO_NDataBlock<T> * >(&pp);
+  if (ppo == NULL) throw TypeMismatchExc("FIO_NDataBlock<T>::ShareDataReference() - Type Mismatch Error");
+  if (ppo->dobj) {
+    if (dobj == NULL) { dobj = new NDataBlock<T>; ownobj = true; } 
+    dobj->Share(*(ppo->dobj));
+  }
+}
+
+template <class T>
+PPersist* FIO_NDataBlock<T>::CloneSharedReference()
+{
+  FIO_NDataBlock<T> * ppo = new FIO_NDataBlock<T>;
+  if (dobj) (ppo->dobj)->Share(*dobj);
+  return(ppo);
+}
+
+template <class T>
+void FIO_NDataBlock<T>::ReadSelf(PInPersist& is)
+{
+// On lit les 3 premiers uint_8
+uint_8 itab[3];
+is.Get(itab, 3);
+if (dobj == NULL) dobj = new NDataBlock<T>(itab[1]);
+else if (itab[1] != dobj->Size()) dobj->ReSize(itab[1]);
+// On lit le tableau de nombres
+PIOSReadArray(is, dobj->Data(), dobj->Size()); 
+}
+
+
+template <class T>
+void FIO_NDataBlock<T>::WriteSelf(POutPersist& os) const
+{
+if (dobj == NULL)   return;  // Attention - $CHECK$ Reza 26/04/99
+//  On ecrit 3 uint_8 
+//  0 : Numero de version,  1 : Taille,  2  reserve a l
+uint_8 itab[3];
+itab[0] = 1;
+itab[1] = dobj->Size();
+itab[2] = 0;
+os.Put(itab, 3);
+//  On ecrit le tableau de nombres 
+PIOSWriteArray(os, dobj->Data(), dobj->Size()); 
+}
+
+///////////////////////////////////////////////////////////////
+#ifdef __CXX_PRAGMA_TEMPLATES__
+// Instances des delegues FileIO (PPersist)
+#pragma define_template FIO_NDataBlock<uint_1>
+#pragma define_template FIO_NDataBlock<uint_2>
+#pragma define_template FIO_NDataBlock<int_2>
+#pragma define_template FIO_NDataBlock<int_4>
+#pragma define_template FIO_NDataBlock<int_8>
+#pragma define_template FIO_NDataBlock<uint_4>
+#pragma define_template FIO_NDataBlock<uint_8>
+#pragma define_template FIO_NDataBlock<r_8>
+#pragma define_template FIO_NDataBlock<r_4>
+#pragma define_template FIO_NDataBlock< complex<r_4> >
+#pragma define_template FIO_NDataBlock< complex<r_8> >
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+// Instances des delegues FileIO (PPersist)
+template class FIO_NDataBlock<uint_1>;
+template class FIO_NDataBlock<uint_2>;
+template class FIO_NDataBlock<int_2>;
+template class FIO_NDataBlock<int_4>;
+template class FIO_NDataBlock<int_8>;
+template class FIO_NDataBlock<uint_4>;
+template class FIO_NDataBlock<uint_8>;
+template class FIO_NDataBlock<r_8>;
+template class FIO_NDataBlock<r_4>;
+template class FIO_NDataBlock< complex<r_4> >;
+template class FIO_NDataBlock< complex<r_8> >;
+#endif
Index: /tags/V_Dec2002/SophyaLib/BaseTools/fiondblock.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/fiondblock.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/fiondblock.h	(revision 2309)
@@ -0,0 +1,48 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe pour la gestion de persistance pour NDataBlock<T>
+//                         C.Magneville          04/99-03/2000
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef FIONDATABLOCK_H
+#define FIONDATABLOCK_H
+
+#include "machdefs.h"
+#include "ppersist.h"
+#include "ndatablock.h"
+#include <iostream.h>
+
+namespace SOPHYA {
+
+template <class T>
+class FIO_NDataBlock : public  PPersist  {
+public:
+  FIO_NDataBlock();
+  FIO_NDataBlock(string const & filename); 
+  FIO_NDataBlock(const NDataBlock<T> & obj);
+  FIO_NDataBlock(NDataBlock<T> * obj);
+  virtual ~FIO_NDataBlock();
+  virtual AnyDataObj* DataObj();
+  virtual void        SetDataObj(AnyDataObj & o);
+  inline operator NDataBlock<T>() { return(*dobj); }
+
+  virtual uint_8     getMemOId() const ;      
+  virtual void       ShareDataReference(PPersist &);       
+  virtual PPersist*  CloneSharedReference();
+
+protected :
+  virtual void       ReadSelf(PInPersist&);           
+  virtual void       WriteSelf(POutPersist&) const;  
+  NDataBlock<T> * dobj;
+  bool ownobj;
+};
+
+template <class T>
+inline POutPersist& operator << (POutPersist& os, NDataBlock<T> & obj)
+{ FIO_NDataBlock<T> fio(&obj);  fio.Write(os);  return(os); }
+template <class T>
+inline PInPersist& operator >> (PInPersist& is, NDataBlock<T> & obj)
+{ FIO_NDataBlock<T> fio(&obj);  fio.Read(is);  return(is); }
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/BaseTools/gnumd5.c
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/gnumd5.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/gnumd5.c	(revision 2309)
@@ -0,0 +1,416 @@
+/* md5.c - MD5 Message-Digest Algorithm
+ *	Copyright (C) 1995, 1996, 1998, 1999 Free Software Foundation, Inc.
+ *
+ * according to the definition of MD5 in RFC 1321 from April 1992.
+ * NOTE: This is *not* the same file as the one from glibc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.  */
+/* heavily modified for GnuPG by <werner.koch@guug.de> */
+/* Modified by Eric.Aubourg@cea.fr for SOPHYA */
+
+/* Test values:
+ * ""                  D4 1D 8C D9 8F 00 B2 04  E9 80 09 98 EC F8 42 7E
+ * "a"                 0C C1 75 B9 C0 F1 B6 A8  31 C3 99 E2 69 77 26 61
+ * "abc                90 01 50 98 3C D2 4F B0  D6 96 3F 7D 28 E1 7F 72
+ * "message digest"    F9 6B 69 7D 7C B7 93 8D  52 5A 2F 31 AA F1 61 D0
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "machdefs.h"
+#include "bithelp.h" 
+#include "gnumd5.h"
+
+#define DIM(v) (sizeof(v)/sizeof((v)[0]))
+
+#if SWAP==0
+#define BIG_ENDIAN_HOST 1
+#endif
+
+
+/* 
+typedef struct {
+  uint_4 A,B,C,D;	   chaining variables 
+  uint_4  nblocks;
+  uint_1 buf[64];
+  int  count;
+} MD5_CONTEXT;
+*/
+
+void
+md5_init( MD5_CONTEXT *ctx )
+{
+    ctx->A = 0x67452301;
+    ctx->B = 0xefcdab89;
+    ctx->C = 0x98badcfe;
+    ctx->D = 0x10325476;
+
+    ctx->nblocks = 0;
+    ctx->count = 0;
+}
+
+
+
+
+/* These are the four functions used in the four steps of the MD5 algorithm
+   and defined in the RFC 1321.  The first function is a little bit optimized
+   (as found in Colin Plumbs public domain implementation).  */
+/* #define FF(b, c, d) ((b & c) | (~b & d)) */
+#define FF(b, c, d) (d ^ (b & (c ^ d)))
+#define FG(b, c, d) FF (d, b, c)
+#define FH(b, c, d) (b ^ c ^ d)
+#define FI(b, c, d) (c ^ (b | ~d))
+
+
+/****************
+ * transform n*64 bytes
+ */
+static void
+/*transform( MD5_CONTEXT *ctx, const void *buffer, size_t len )*/
+transform( MD5_CONTEXT *ctx, uint_1 *data )
+{
+    uint_4 correct_words[16];
+    uint_4 A = ctx->A;
+    uint_4 B = ctx->B;
+    uint_4 C = ctx->C;
+    uint_4 D = ctx->D;
+    uint_4 *cwp = correct_words;
+
+#ifdef BIG_ENDIAN_HOST
+    { int i;
+      uint_1 *p2, *p1;
+      for(i=0, p1=data, p2=(uint_1*)correct_words; i < 16; i++, p2 += 4 ) {
+	p2[3] = *p1++;
+	p2[2] = *p1++;
+	p2[1] = *p1++;
+	p2[0] = *p1++;
+      }
+    }
+#else
+    memcpy( correct_words, data, 64 );
+#endif
+
+
+#define OP(a, b, c, d, s, T)					    \
+  do								    \
+    {								    \
+      a += FF (b, c, d) + (*cwp++) + T; 	    \
+      a = rol(a, s);						    \
+      a += b;							    \
+    }								    \
+  while (0)
+
+    /* Before we start, one word about the strange constants.
+       They are defined in RFC 1321 as
+
+       T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
+     */
+
+    /* Round 1.  */
+    OP (A, B, C, D,  7, 0xd76aa478);
+    OP (D, A, B, C, 12, 0xe8c7b756);
+    OP (C, D, A, B, 17, 0x242070db);
+    OP (B, C, D, A, 22, 0xc1bdceee);
+    OP (A, B, C, D,  7, 0xf57c0faf);
+    OP (D, A, B, C, 12, 0x4787c62a);
+    OP (C, D, A, B, 17, 0xa8304613);
+    OP (B, C, D, A, 22, 0xfd469501);
+    OP (A, B, C, D,  7, 0x698098d8);
+    OP (D, A, B, C, 12, 0x8b44f7af);
+    OP (C, D, A, B, 17, 0xffff5bb1);
+    OP (B, C, D, A, 22, 0x895cd7be);
+    OP (A, B, C, D,  7, 0x6b901122);
+    OP (D, A, B, C, 12, 0xfd987193);
+    OP (C, D, A, B, 17, 0xa679438e);
+    OP (B, C, D, A, 22, 0x49b40821);
+
+#undef OP
+#define OP(f, a, b, c, d, k, s, T)  \
+    do								      \
+      { 							      \
+	a += f (b, c, d) + correct_words[k] + T;		      \
+	a = rol(a, s);						      \
+	a += b; 						      \
+      } 							      \
+    while (0)
+
+    /* Round 2.  */
+    OP (FG, A, B, C, D,  1,  5, 0xf61e2562);
+    OP (FG, D, A, B, C,  6,  9, 0xc040b340);
+    OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
+    OP (FG, B, C, D, A,  0, 20, 0xe9b6c7aa);
+    OP (FG, A, B, C, D,  5,  5, 0xd62f105d);
+    OP (FG, D, A, B, C, 10,  9, 0x02441453);
+    OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
+    OP (FG, B, C, D, A,  4, 20, 0xe7d3fbc8);
+    OP (FG, A, B, C, D,  9,  5, 0x21e1cde6);
+    OP (FG, D, A, B, C, 14,  9, 0xc33707d6);
+    OP (FG, C, D, A, B,  3, 14, 0xf4d50d87);
+    OP (FG, B, C, D, A,  8, 20, 0x455a14ed);
+    OP (FG, A, B, C, D, 13,  5, 0xa9e3e905);
+    OP (FG, D, A, B, C,  2,  9, 0xfcefa3f8);
+    OP (FG, C, D, A, B,  7, 14, 0x676f02d9);
+    OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
+
+    /* Round 3.  */
+    OP (FH, A, B, C, D,  5,  4, 0xfffa3942);
+    OP (FH, D, A, B, C,  8, 11, 0x8771f681);
+    OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
+    OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
+    OP (FH, A, B, C, D,  1,  4, 0xa4beea44);
+    OP (FH, D, A, B, C,  4, 11, 0x4bdecfa9);
+    OP (FH, C, D, A, B,  7, 16, 0xf6bb4b60);
+    OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
+    OP (FH, A, B, C, D, 13,  4, 0x289b7ec6);
+    OP (FH, D, A, B, C,  0, 11, 0xeaa127fa);
+    OP (FH, C, D, A, B,  3, 16, 0xd4ef3085);
+    OP (FH, B, C, D, A,  6, 23, 0x04881d05);
+    OP (FH, A, B, C, D,  9,  4, 0xd9d4d039);
+    OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
+    OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
+    OP (FH, B, C, D, A,  2, 23, 0xc4ac5665);
+
+    /* Round 4.  */
+    OP (FI, A, B, C, D,  0,  6, 0xf4292244);
+    OP (FI, D, A, B, C,  7, 10, 0x432aff97);
+    OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
+    OP (FI, B, C, D, A,  5, 21, 0xfc93a039);
+    OP (FI, A, B, C, D, 12,  6, 0x655b59c3);
+    OP (FI, D, A, B, C,  3, 10, 0x8f0ccc92);
+    OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
+    OP (FI, B, C, D, A,  1, 21, 0x85845dd1);
+    OP (FI, A, B, C, D,  8,  6, 0x6fa87e4f);
+    OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
+    OP (FI, C, D, A, B,  6, 15, 0xa3014314);
+    OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
+    OP (FI, A, B, C, D,  4,  6, 0xf7537e82);
+    OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
+    OP (FI, C, D, A, B,  2, 15, 0x2ad7d2bb);
+    OP (FI, B, C, D, A,  9, 21, 0xeb86d391);
+
+    /* Put checksum in context given as argument.  */
+    ctx->A += A;
+    ctx->B += B;
+    ctx->C += C;
+    ctx->D += D;
+}
+
+
+
+/* The routine updates the message-digest context to
+ * account for the presence of each of the characters inBuf[0..inLen-1]
+ * in the message whose digest is being computed.
+ */
+void
+md5_write( MD5_CONTEXT *hd, uint_1 *inbuf, size_t inlen)
+{
+    if( hd->count == 64 ) { /* flush the buffer */
+	transform( hd, hd->buf );
+	hd->count = 0;
+	hd->nblocks++;
+    }
+    if( !inbuf )
+	return;
+    if( hd->count ) {
+	for( ; inlen && hd->count < 64; inlen-- )
+	    hd->buf[hd->count++] = *inbuf++;
+	md5_write( hd, NULL, 0 );
+	if( !inlen )
+	    return;
+    }
+
+    while( inlen >= 64 ) {
+	transform( hd, inbuf );
+	hd->count = 0;
+	hd->nblocks++;
+	inlen -= 64;
+	inbuf += 64;
+    }
+    for( ; inlen && hd->count < 64; inlen-- )
+	hd->buf[hd->count++] = *inbuf++;
+
+}
+
+
+
+/* The routine final terminates the message-digest computation and
+ * ends with the desired message digest in mdContext->digest[0...15].
+ * The handle is prepared for a new MD5 cycle.
+ * Returns 16 bytes representing the digest.
+ */
+
+void
+md5_final( MD5_CONTEXT *hd )
+{
+    uint_4 t, msb, lsb;
+    uint_1 *p;
+
+    md5_write(hd, NULL, 0); /* flush */;
+
+    msb = 0;
+    t = hd->nblocks;
+    if( (lsb = t << 6) < t ) /* multiply by 64 to make a byte count */
+	msb++;
+    msb += t >> 26;
+    t = lsb;
+    if( (lsb = t + hd->count) < t ) /* add the count */
+	msb++;
+    t = lsb;
+    if( (lsb = t << 3) < t ) /* multiply by 8 to make a bit count */
+	msb++;
+    msb += t >> 29;
+
+    if( hd->count < 56 ) { /* enough room */
+	hd->buf[hd->count++] = 0x80; /* pad */
+	while( hd->count < 56 )
+	    hd->buf[hd->count++] = 0;  /* pad */
+    }
+    else { /* need one extra block */
+	hd->buf[hd->count++] = 0x80; /* pad character */
+	while( hd->count < 64 )
+	    hd->buf[hd->count++] = 0;
+	md5_write(hd, NULL, 0);  /* flush */;
+	memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
+    }
+    /* append the 64 bit count */
+    hd->buf[56] = lsb	   ;
+    hd->buf[57] = lsb >>  8;
+    hd->buf[58] = lsb >> 16;
+    hd->buf[59] = lsb >> 24;
+    hd->buf[60] = msb	   ;
+    hd->buf[61] = msb >>  8;
+    hd->buf[62] = msb >> 16;
+    hd->buf[63] = msb >> 24;
+    transform( hd, hd->buf );
+
+    p = hd->buf;
+#ifdef BIG_ENDIAN_HOST
+#define X(a) do { *p++ = hd->##a	  ; *p++ = hd->##a >> 8;      \
+		      *p++ = hd->##a >> 16; *p++ = hd->##a >> 24; } while(0)
+#else /* little endian */
+    /*#define X(a) do { *(uint_4*)p = hd->##a ; p += 4; } while(0)*/
+    /* Unixware's cpp doesn't like the above construct so we do it his way:
+     * (reported by Allan Clark) */
+#define X(a) do { *(uint_4*)p = (*hd).a ; p += 4; } while(0)
+#endif
+    X(A);
+    X(B);
+    X(C);
+    X(D);
+#undef X
+
+}
+
+static uint_1 *
+md5_read( MD5_CONTEXT *hd )
+{
+    return hd->buf;
+}
+
+/****************
+ * Return some information about the algorithm.  We need algo here to
+ * distinguish different flavors of the algorithm.
+ * Returns: A pointer to string describing the algorithm or NULL if
+ *	    the ALGO is invalid.
+ */
+static const char *
+md5_get_info( int algo, size_t *contextsize,
+	       uint_1 **r_asnoid, int *r_asnlen, int *r_mdlen,
+	       void (**r_init)( void *c ),
+	       void (**r_write)( void *c, uint_1 *buf, size_t nbytes ),
+	       void (**r_final)( void *c ),
+	       uint_1 *(**r_read)( void *c )
+	     )
+{
+    static uint_1 asn[18] = /* Object ID is 1.2.840.113549.2.5 */
+		    { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48,
+		      0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 };
+
+    if( algo != 1 )
+	return NULL;
+
+    *contextsize = sizeof(MD5_CONTEXT);
+    *r_asnoid = asn;
+    *r_asnlen = DIM(asn);
+    *r_mdlen = 16;
+    *r_init  = (void (*)(void *))md5_init;
+    *r_write = (void (*)(void *, uint_1*, size_t))md5_write;
+    *r_final = (void (*)(void *))md5_final;
+    *r_read  = (uint_1 *(*)(void *))md5_read;
+
+    return "MD5";
+}
+
+
+#ifndef IS_MODULE
+static
+#endif
+const char * const gnupgext_version = "MD5 ($Revision: 1.4 $)";
+
+static struct {
+    int class;
+    int version;
+    int  value;
+    void (*func)(void);
+} func_table[] = {
+    { 10, 1, 0, (void(*)(void))md5_get_info },
+    { 11, 1, 1 },
+};
+
+
+#ifndef IS_MODULE
+static
+#endif
+void *
+gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
+{
+    void *ret;
+    int i = *sequence;
+
+    do {
+	if( i >= DIM(func_table) || i < 0 )
+	    return NULL;
+	*class = func_table[i].class;
+	*vers  = func_table[i].version;
+	switch( *class ) {
+	  case 11: case 21: case 31: ret = &func_table[i].value; break;
+	  default:		     ret = func_table[i].func; break;
+	}
+	i++;
+    } while( what && what != *class );
+
+    *sequence = i;
+    return ret;
+}
+
+
+
+/*
+#ifndef IS_MODULE
+void
+md5_constructor(void)
+{
+    register_internal_cipher_extension( gnupgext_version, gnupgext_enum_func );
+}
+#endif
+*/
+
+
+/* end of file */
Index: /tags/V_Dec2002/SophyaLib/BaseTools/gnumd5.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/gnumd5.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/gnumd5.h	(revision 2309)
@@ -0,0 +1,35 @@
+#ifndef GNUMD5_H
+#define GNUMD5_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+    uint_8 mem_align;     /* To force memory alignment on SunOS 22/02/2001 */
+    uint_1 buf[64];
+    uint_4 A,B,C,D;	  /* chaining variables */
+    uint_4  nblocks;
+    int  count;
+} MD5_CONTEXT;
+
+
+void
+md5_init( MD5_CONTEXT *ctx );
+
+void
+md5_write( MD5_CONTEXT *hd, uint_1 *inbuf, size_t inlen);
+
+void
+md5_final( MD5_CONTEXT *hd );
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/BaseTools/hashtable.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/hashtable.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/hashtable.h	(revision 2309)
@@ -0,0 +1,195 @@
+// This may look like C code, but it is really -*- C++ -*-
+
+// This is a hash table. Some implementations of the STL have one, like the
+// Modena Standard Library.
+
+#ifndef HASHTABLE_H_SEEN
+#define HASHTABLE_H_SEEN
+
+#include "machdefs.h"
+#include "pexceptions.h"
+
+namespace SOPHYA {
+
+template <class T, class K>
+struct HashtableEntry {
+  uint_4         hash;
+  K              key;
+  T              value;
+  HashtableEntry<T,K> *next;
+};
+
+
+template <class T, class K>
+class Hashtable {
+public:
+  typedef uint_4 (*HashFunction)(K const& key);
+
+  Hashtable(uint_4 initialCapacity, float loadFactor) {
+    Init(initialCapacity,loadFactor);
+  }
+  
+  Hashtable(int initialCapacity) {
+    Init(initialCapacity, 0.75);
+  }
+  
+  Hashtable() {
+    Init(101, 0.75);
+  }
+
+  ~Hashtable() {
+    for (int i = count ; i-- > 0 ;) {
+      for (HashtableEntry<T,K>* e = table[i] ; e != NULL ; ) {
+	HashtableEntry<T,K>* ee = e->next;
+	delete e;
+	e = ee;
+      }
+    }
+    delete[] table;
+  }
+
+  void setHash(HashFunction f) {
+    hf = f;
+  }
+
+  uint_4 size() {
+    return count;
+  }
+
+  bool contains(T const& value) {
+    for (int i = count ; i-- > 0 ;) {
+      for (HashtableEntry<T,K>* e = table[i] ; e != NULL ; e = e->next) {
+	if (e->value == value) {
+	  return true;
+	}
+      }
+    }
+    return false;
+  }
+  
+  bool containsKey(K const& key) {
+    uint_4 hash = hf(key);
+    uint_4 index = (hash & 0x7FFFFFFF) % length;
+    for (HashtableEntry<T,K>* e = table[index] ; e != NULL ; e = e->next) {
+      if ((e->hash == hash) && e->key == key) {
+	return true;
+      }
+    }
+    return false;
+  }
+  
+  T const& get(K const& key) {
+    uint_4 hash = hf(key);
+    uint_4 index = (hash & 0x7FFFFFFF) % length;
+    for (HashtableEntry<T,K>* e = table[index] ; e != NULL ; e = e->next) {
+      if ((e->hash == hash) && e->key == key) {
+	return e->value;
+      }
+    }
+    throw(NotFoundExc("Hashtable::get"));
+  }
+  
+  
+  void put(K const& key, T const& value) {
+    // Makes sure the key is not already in the hashtable.
+    uint_4 hash = hf(key);
+    uint_4 index = (hash & 0x7FFFFFFF) % length;
+    for (HashtableEntry<T,K>* e = table[index] ; e != NULL ; e = e->next) {
+      if ((e->hash == hash) && e-> key == key) {
+	//T const& old = e.value;
+	e->value = value;
+	//return old;
+      }
+    }
+    
+    if (count >= threshold) {
+      // Rehash the table if the threshold is exceeded
+      rehash();
+      return;// put(key, value);
+    } 
+
+    // Creates the new entry.
+    HashtableEntry<T,K>* e = new HashtableEntry<T,K>;
+    e->hash = hash;
+    e->key = key;
+    e->value = value;
+    e->next = table[index];
+    table[index] = e;
+    count++;
+    //return null;
+  }
+  
+  
+  void remove(K const& key) {
+    uint_4 hash = hf(key);
+    uint_4 index = (hash & 0x7FFFFFFF) % tab.length;
+    for (HashtableEntry<T,K>* e = table[index], prev = null ; e != null ; prev = e, e = e->next) {
+      if ((e>hash == hash) && e>key == key) {
+	if (prev != NULL) {
+	  prev->next = e->next;
+	} else {
+	  table[index] = e->next;
+	}
+	count--;
+	//return e.value;
+      }
+    }
+    //return null;
+  }
+  
+private:
+  
+  void Init(uint_4 initialCapacity, float loadFactor) {
+    if ((initialCapacity == 0) || (loadFactor <= 0.0)) {
+      throw ParmError("Hashtable::Hashtable");
+    }
+    this->loadFactor = loadFactor;
+    this->length = initialCapacity;
+    this->count = 0;
+    table = new (HashtableEntry<T,K>*[initialCapacity]);
+    for (int i=0; i<length; i++) table[i] = NULL;
+    threshold = (uint_4)(initialCapacity * loadFactor);
+    hf = defaultHash;
+  }
+
+  static uint_4 defaultHash(K const& key) {
+    if (sizeof(K) <= sizeof(void*))
+      return (uint_4)(uint_8)(key);
+    else
+      return (uint_4)(uint_8)(&key);
+  }
+
+  void rehash() {
+    uint_4 oldCapacity = length;
+    HashtableEntry<T,K>** oldTable = table;
+
+    uint_4 newCapacity = oldCapacity * 2 + 1;
+    HashtableEntry<T,K>** newTable = new (HashtableEntry<T,K>*[newCapacity]);
+
+    threshold = (int)(newCapacity * loadFactor);
+    table = newTable;
+    length = newCapacity;
+
+    for (int i = oldCapacity ; i-- > 0 ;) {
+      for (HashtableEntry<T,K>* old = oldTable[i] ; old != NULL ; ) {
+	HashtableEntry<T,K>* e = old;
+	old = old->next;
+	
+	int index = (e->hash & 0x7FFFFFFF) % newCapacity;
+	e->next = newTable[index];
+	newTable[index] = e;
+      }
+    }
+    delete[] oldTable;
+  }
+  
+  HashtableEntry<T,K>  **table;
+  uint_4         length;
+  uint_4         count;
+  uint_4         threshold;
+  float          loadFactor;
+  HashFunction   hf;
+};
+}
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/BaseTools/history_eros
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/history_eros	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/history_eros	(revision 2309)
@@ -0,0 +1,55 @@
+SysTools from LibsUtil
+machdefs.h from machine.h defs.h
+-----------> defs.h
+   Repository revision:	1.21	/projects/Eros/CVSEros/LibsUtil/defs.h,v
+   MAJ                  1.24
+-----------> machine.h
+   Repository revision:	1.9	/projects/Eros/CVSEros/LibsUtil/machine.h,v
+   MAJ                  1.12
+-----------> timing.c
+   Repository revision:	1.2	/projects/Eros/CVSEros/LibsUtil/timing.c,v
+   OK                   1.2
+-----------> timing.h
+   Repository revision:	1.2	/projects/Eros/CVSEros/LibsUtil/timing.h,v
+   OK                   1.2
+SysTools from Outils++
+-----------> ctimer.cc
+   Repository revision:	1.11	/projects/Eros/CVSEros/CodeCxx/Outils/ctimer.cc,v
+   OK                   1.11
+-----------> ctimer.h
+   Repository revision:	1.9	/projects/Eros/CVSEros/CodeCxx/Outils/ctimer.h,v
+   OK                   1.11
+-----------> exceptions.cc
+   Repository revision:	1.7	/projects/Eros/CVSEros/CodeCxx/Outils/exceptions.cc,v
+   OK                   1.8     modifs pour CCPN AIX pas mis
+-----------> exceptions.h
+   Repository revision:	1.8	/projects/Eros/CVSEros/CodeCxx/Outils/exceptions.h,v
+   OK                   1.8
+-----------> pdlmgr.cc
+   Repository revision:	1.2	/projects/Eros/CVSEros/CodeCxx/Outils/pdlmgr.cc,v
+   MAJ                  1.6
+-----------> pdlmgr.h
+   Repository revision:	1.2	/projects/Eros/CVSEros/CodeCxx/Outils/pdlmgr.h,v
+   MAJ                  1.4
+-----------> peidainit.h
+   Repository revision:	1.6	/projects/Eros/CVSEros/CodeCxx/Outils/peidainit.h,v
+-----------> periodic.cc
+   Repository revision:	1.4	/projects/Eros/CVSEros/CodeCxx/Outils/periodic.cc,v
+-----------> periodic.h
+   Repository revision:	1.4	/projects/Eros/CVSEros/CodeCxx/Outils/periodic.h,v
+   MAJ                  1.5
+-----------> perrors.h
+   Repository revision:	1.4	/projects/Eros/CVSEros/CodeCxx/Outils/perrors.h,v
+   OK                   1.5     Attention  COMPATIBLE_ASSERT pas mis
+-----------> ppersist.cc
+   Repository revision:	1.40	/projects/Eros/CVSEros/CodeCxx/Outils/ppersist.cc,v
+   MAJ - OK             1.43    Attention aux asserts
+-----------> ppersist.h
+   Repository revision:	1.23	/projects/Eros/CVSEros/CodeCxx/Outils/ppersist.h,v
+   MAJ                  1.25
+-----------> psighand.cc
+   Repository revision:	1.2	/projects/Eros/CVSEros/CodeCxx/Outils/psighand.cc,v
+   MAJ                  1.3
+-----------> psighand.h
+   Repository revision:	1.1	/projects/Eros/CVSEros/CodeCxx/Outils/psighand.h,v
+   MAJ                  1.2
Index: /tags/V_Dec2002/SophyaLib/BaseTools/machdefs_ac.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/machdefs_ac.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/machdefs_ac.h	(revision 2309)
@@ -0,0 +1,294 @@
+#ifndef MACHDEFS_SEEN
+#define MACHDEFS_SEEN
+
+#include <config.h>
+
+/***********************************************************************/
+/* Find hardware, OS and compiler combination                          */
+/***********************************************************************/
+
+#if defined(OSF1) 
+#define MACH_ALPHA
+#define OS_OSF1
+#endif
+
+#if defined(_AIX) || defined(AIX)
+#define MACH_IBMRS
+#define OS_AIX
+#endif
+
+#if defined(__hpux__) || defined(HPUX)
+#define MACH_HP
+#define OS_HPUX
+#endif
+
+#ifdef __MWERKS__
+#define MACH_POWERMAC
+#define OS_MACOS
+#endif
+
+#if defined(SunOS)  || defined ( sun )
+#define MACH_SUN
+#define OS_SOLARIS
+#endif
+
+#ifdef IRIX64
+#define MACH_SGI
+#define OS_IRIX64
+#endif
+
+#if defined(Linux)  || defined(linux)
+#if defined(__alpha__)
+#define MACH_ALPHA
+#elif defined(powerpc)
+#define MACH_POWERPC
+#elif defined(__i386__)
+#define MACH_INTEL
+#else
+#error Undefined Platform (machine) type with linux in machdefs.h
+#endif
+#define OS_LINUX
+#endif
+
+
+/***********************************************************************/
+/* Hardware/OS dependent stuff                                         */
+/***********************************************************************/
+
+typedef signed char int_1;
+typedef unsigned char uint_1;
+
+#if (SIZEOF_SHORT == 2)
+typedef short int_2;
+typedef unsigned short uint_2;
+#elif (SIZEOF_INT == 2)
+typedef int int_2;
+typedef unsigned int uint_2;
+#else
+#error "no size 2 integer"
+#endif
+
+#if (SIZEOF_INT == 4)
+typedef int int_4;
+typedef unsigned int uint_4;
+#elif (SIZEOF_LONG == 4)
+typedef long int_4;
+typedef unsigned long uint_4;
+#else
+#error "no size 4 integer"
+#endif
+
+#if (SIZEOF_LONG_LONG == 8)
+typedef long long int_8;
+typedef unsigned long long uint_8;
+#elif (SIZEOF_LONG == 9)
+typedef long int_8;
+typedef unsigned long uint_8;
+#else
+#error "no size 8 integer"
+#endif
+
+
+#if (SIZEOF_FLOAT == 4)
+typedef float r_4;
+#else
+#error "no size 4 float"
+#endif
+
+#if (SIZEOF_DOUBLE == 8)
+typedef double r_8;
+#else
+#error "no size 8 float"
+#endif
+
+#ifdef WORDS_BIGENDIAN
+#define  SWAP 0
+#define  SWAPDEFAUT 0
+#define  IS_BIG_ENDIAN 1
+#else
+#define  SWAP 1
+#define  SWAPDEFAUT 1
+#define  IS_BIG_ENDIAN 0
+#endif
+
+
+
+
+/***********************************************************************/
+/* Find Compiler                                                       */
+/***********************************************************************/
+
+/*    __MWERKS__   : Metrowerks Codewarrior (>= PRO 4)                 */
+/*    __DECCXX     : DEC CXX, version >= 6 is required                 */
+/*    __GNUG__     : GNU C++ 2.8.1, egcs ??                            */
+/*    __aCC__      : aCC on HP                                         */
+/*    __KCC__      : KCC, version >= 3.3 is required                   */
+/*    __SGICC__    : SGI (IRIX64) CC compiler                          */
+
+/***********************************************************************/
+/* Compiler-specific stuff                                             */
+/***********************************************************************/
+
+/* Some features will be *required* for Planck. Which ones ?               */
+  
+/*   ANSI_TEMPLATES        : use ANSI syntax for explicit templates        */
+/*   GNUG_TEMPLATES        : use GNU syntax for explicit templates         */
+/*   PRAGMA_TEMPLATES      : use pragma template, a la cxx                 */
+/*   COMPILER_EXCEPTIONS   : knows about exceptions  --- required ?        */ 
+/*   STREAMPOS_IS_CLASS    : streampos is a real class                     */
+/*   ITER_TAG              : use iter_tag for iterator qualifiers in STL   */
+/*   NO_STRSTREAM          : does not have strstream                       */
+/*   NO_EXPLICIT           : does not know about explicit keyword          */
+/*   HAS_IOS_BIN                                                           */
+/*   HAS_IOS_NOCREATE                                                      */
+/*   HAS_VEC_NEW           : operator new[]                                */
+/*   CC_HAS_RTTI_SUPPORT     has Run Time Type Identification support      */
+/*   ANSI_IO               : rdbuf()->pubseekoff rather than seekg         */
+/*   HAS_STR_NPOS          : has string::npos and not a global NPOS        */
+/*   NO_IOS_COMPLEX        : does not have operator << defined for complex */
+
+
+/* The following is true for most compilers */
+
+#ifndef HAS_VEC_NEW
+#define HAS_VEC_NEW
+#endif
+
+#ifndef COMPILER_EXCEPTIONS
+#define COMPILER_EXCEPTIONS
+#endif
+
+#ifndef  CC_HAS_RTTI_SUPPORT 
+#define  CC_HAS_RTTI_SUPPORT 
+#endif
+
+/* now the specific things */
+
+#ifdef __MWERKS__
+#define ANSI_TEMPLATES
+#undef  HAS_VEC_NEW
+#define NO_STRSTREAM
+//#define STREAMPOS_IS_CLASS
+#define ITER_TAG
+#define HAS_IOS_BIN 
+#define HAS_IOS_NOCREATE 
+#define HAS_STR_NPOS
+#endif
+
+#ifdef __GNUG__
+#define ANSI_TEMPLATES
+// #define GNU_TEMPLATES
+#define HAS_STR_NPOS
+#define HAS_IOS_BIN
+#define HAS_IOS_NOCREATE
+#endif
+
+#ifdef __DECCXX
+#define HAS_STR_NPOS
+#define ITER_TAG
+#define __CXX_PRAGMA_TEMPLATES__
+#define PRAGMA_TEMPLATES
+#endif
+
+#if defined (__aCC__)  
+#ifndef ANSI_TEMPLATES
+#define ANSI_TEMPLATES
+#endif
+#endif
+
+#if defined(__KCC__)
+/* KCC V 3.2 ne compile pas  i/ostream s ; long p = s.tellg();  OK en  V 3.3 */
+#define HAS_STR_NPOS
+#ifndef ANSI_TEMPLATES
+#define ANSI_TEMPLATES
+#endif
+#endif
+
+#if defined(__SGICC__)
+#define HAS_STR_NPOS
+#ifndef ANSI_TEMPLATES
+#define ANSI_TEMPLATES
+#endif
+#endif
+
+/* Get things has homogeneous as possible between compilers */
+
+#ifdef HAS_STR_NPOS
+#define NPOS string::npos
+#else
+#define NPOS (size_t)-1
+#endif
+
+#ifndef __GNUG__
+#define __PRETTY_FUNCTION__ __FILE__ " __LINE__ "
+#ifndef __FUNCTION__
+#define __FUNCTION__ __FILE__ " __LINE__ "
+#endif
+#ifndef __KCC__
+#define __attribute__(_x_)
+#endif
+#endif
+
+#ifdef NO_EXPLICIT
+#define explicit
+#endif
+
+#ifdef HAS_IOS_BIN
+#define IOS_BIN ios::binary
+#else
+#define IOS_BIN 0
+#endif
+
+#ifdef ANSI_IO
+#define seekg(p_, m_) rdbuf()->pubseekoff(p_,m_)
+#define seekp(p_, m_) rdbuf()->pubseekoff(p_,m_)
+#endif
+
+#ifdef __MWERKS__
+//#define hypot(_x_,_y_) sqrt((_x_)*(_x_) + (_y_)*(_y_))
+#define random() (rand()*65538.0 + rand()*2. + rand())
+#define srandom srand
+#define initstate(seed, tab, n) srand(seed)
+#define nice(_x)
+
+#ifdef __cplusplus
+#include <string.h>
+#include <string>
+inline bool operator< (string const& s1, string const& s2)
+{ return (strcmp(s1.c_str(), s2.c_str()) < 0); }
+#endif
+#endif
+
+
+/********************************************************/
+/* Outil d'impressions pour debug */
+#define PR(_data_)  {cout<<" "<<#_data_<<" "<<_data_;}
+#define CR {cout<<"\n"<<flush;}
+/* ********************************************************/
+
+/* ---- Activation des flags de debug/bound checking  ----- */
+#ifdef SOPHYA_DEBUG
+#define SO_BOUNDCHECKING
+#endif
+
+/* ---- La taille et les index des tableaux ---- */
+#ifdef SGI_ARCH64
+typedef int_8 sa_size_t ;
+#else
+typedef int_4 sa_size_t ;
+#endif
+
+
+/* Compatibilite, avant de migrer tout le code en "PLANCK" */
+
+#ifdef __cplusplus
+/* Standard C++ library classes are in the namespace std  */
+namespace std { }
+using namespace std;
+/*  SOPHYA classes are in namespace SOPHYA  */
+namespace SOPHYA {}
+using namespace SOPHYA;
+#define EXPLICIT explicit
+#endif
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/BaseTools/machdefs_mkmf.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/machdefs_mkmf.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/machdefs_mkmf.h	(revision 2309)
@@ -0,0 +1,397 @@
+#ifndef MACHDEFS_SEEN
+#define MACHDEFS_SEEN
+
+/***********************************************************************/
+/* Find hardware, OS and compiler combination                          */
+/***********************************************************************/
+
+#if defined(OSF1) 
+#define MACH_ALPHA
+#define OS_OSF1
+#endif
+
+#if defined(_AIX) || defined(AIX)
+#define MACH_IBMRS
+#define OS_AIX
+#endif
+
+#if defined(__hpux__) || defined(HPUX)
+#define MACH_HP
+#define OS_HPUX
+#endif
+
+#ifdef __MWERKS__
+#define MACH_POWERMAC
+#define OS_MACOS
+#endif
+
+#if defined(SunOS)  || defined ( sun )
+#define MACH_SUN
+#define OS_SOLARIS
+#endif
+
+#ifdef IRIX64
+#define MACH_SGI
+#define OS_IRIX64
+#endif
+
+#ifdef __APPLE__
+#ifdef __MACH__
+#define MACH_POWERPC
+#define OS_MACOSX
+#endif
+#endif
+
+#if defined(Linux)  || defined(linux)
+#if defined(__alpha__)
+#define MACH_ALPHA
+#elif defined(powerpc)
+#define MACH_POWERPC
+#elif defined(__i386__)
+#define MACH_INTEL
+#else
+#error Undefined Platform (machine) type with linux in machdefs.h
+#endif
+#define OS_LINUX
+#endif
+
+
+/***********************************************************************/
+/* Hardware/OS dependent stuff                                         */
+/***********************************************************************/
+
+#if defined(OS_OSF1)
+
+  typedef signed char int_1;
+  typedef unsigned char uint_1;
+  typedef int int_4;
+  typedef unsigned int uint_4;
+  typedef short int_2;
+  typedef unsigned short uint_2;
+  typedef float r_4;
+  typedef double r_8;
+  typedef long long int_8;
+  typedef unsigned long long uint_8;
+
+#define  SWAP 1
+#define  SWAPDEFAUT 1
+
+#elif  defined(OS_HPUX)
+
+  typedef signed char int_1;
+  typedef unsigned char uint_1;
+  typedef int int_4 ;
+  typedef unsigned int uint_4;
+  typedef short int_2;
+  typedef unsigned short uint_2;
+  typedef float r_4;
+  typedef double r_8;
+  typedef long long int_8;
+  typedef unsigned long long uint_8;
+
+#define  SWAP 0
+#define  SWAPDEFAUT   0
+
+
+#elif  defined( OS_AIX )
+
+  typedef signed char int_1;
+  typedef unsigned char uint_1;
+  typedef int int_4;
+  typedef unsigned int uint_4;
+  typedef short int_2;
+  typedef unsigned short uint_2;
+  typedef float r_4;
+  typedef double r_8;
+  typedef long long int_8;
+  typedef unsigned long long uint_8;
+
+#define  SWAP 0
+#define  SWAPDEFAUT   0
+
+/* Check for solaris on intel... */
+#elif  defined( OS_SOLARIS ) && defined( MACH_SUN )
+
+  typedef signed char int_1;
+  typedef unsigned char uint_1;
+  typedef int int_4;
+  typedef unsigned int uint_4;
+  typedef short int_2;
+  typedef unsigned short uint_2;
+  typedef float r_4;
+  typedef double r_8;
+  typedef long long int_8;
+  typedef unsigned long long uint_8;
+
+#define  SWAP 0
+#define  SWAPDEFAUT   0
+
+#elif  defined( OS_IRIX64 )
+
+  typedef signed char int_1;
+  typedef unsigned char uint_1;
+  typedef int int_4;
+  typedef unsigned int uint_4;
+  typedef short int_2;
+  typedef unsigned short uint_2;
+  typedef float r_4;
+  typedef double r_8;
+  typedef long long int_8;
+  typedef unsigned long long uint_8;
+
+#define  SWAP 0
+#define  SWAPDEFAUT   0
+
+/* Check linux on other machines than Intel */
+#elif defined(OS_LINUX)
+/* Sizes OK for PowerPC, Alpha, Intel    */
+/* On Alpha, long is 8 bytes             */
+  typedef signed char int_1;
+  typedef unsigned char uint_1;
+  typedef int int_4;
+  typedef unsigned int uint_4;
+  typedef short int_2;
+  typedef unsigned short uint_2;
+  typedef float r_4;
+  typedef double r_8;
+  typedef long long int_8;
+  typedef unsigned long long uint_8;
+
+#if defined(powerpc) || (__alpha__)
+#define SWAP 0
+#define SWAPDEFAUT 0
+#else
+#define  SWAP 1
+#define  SWAPDEFAUT   1
+#endif
+
+#elif defined(OS_MACOS)
+
+  typedef signed char int_1;
+  typedef unsigned char uint_1;
+  typedef long int_4;
+  typedef unsigned long uint_4;
+  typedef short int_2;
+  typedef unsigned short uint_2;
+  typedef float r_4;
+  typedef double r_8;
+  typedef long long int_8;
+  typedef unsigned long long uint_8;
+
+#define  SWAP 0
+#define  SWAPDEFAUT   0
+
+#elif defined(OS_MACOSX)
+
+  typedef signed char int_1;
+  typedef unsigned char uint_1;
+  typedef int int_4;
+  typedef unsigned int uint_4;
+  typedef short int_2;
+  typedef unsigned short uint_2;
+  typedef float r_4;
+  typedef double r_8;
+  typedef long long int_8;
+  typedef unsigned long long uint_8;
+
+#define  SWAP 0
+#define  SWAPDEFAUT   0
+
+
+#else
+#error  Undefined Machine/OS type in machdefs.h
+#endif
+
+
+
+#if SWAP==1
+#define IS_BIG_ENDIAN 0
+#else
+#define IS_BIG_ENDIAN 1
+#endif
+
+
+/***********************************************************************/
+/* Find Compiler                                                       */
+/***********************************************************************/
+
+/*    __MWERKS__   : Metrowerks Codewarrior (>= PRO 4)                 */
+/*    __DECCXX     : DEC CXX, version >= 6 is required                 */
+/*    __GNUG__     : GNU C++ 2.8.1, egcs ??                            */
+/*    __aCC__      : aCC on HP                                         */
+/*    __KCC__      : KCC, version >= 3.3 is required                   */
+/*    __SGICC__    : SGI (IRIX64) CC compiler                          */
+
+/***********************************************************************/
+/* Compiler-specific stuff                                             */
+/***********************************************************************/
+
+/* Some features will be *required* for Planck. Which ones ?               */
+  
+/*   ANSI_TEMPLATES        : use ANSI syntax for explicit templates        */
+/*   GNUG_TEMPLATES        : use GNU syntax for explicit templates         */
+/*   PRAGMA_TEMPLATES      : use pragma template, a la cxx                 */
+/*   COMPILER_EXCEPTIONS   : knows about exceptions  --- required ?        */ 
+/*   STREAMPOS_IS_CLASS    : streampos is a real class                     */
+/*   ITER_TAG              : use iter_tag for iterator qualifiers in STL   */
+/*   NO_STRSTREAM          : does not have strstream                       */
+/*   NO_EXPLICIT           : does not know about explicit keyword          */
+/*   HAS_IOS_BIN                                                           */
+/*   HAS_IOS_NOCREATE                                                      */
+/*   HAS_VEC_NEW           : operator new[]                                */
+/*   CC_HAS_RTTI_SUPPORT     has Run Time Type Identification support      */
+/*   ANSI_IO               : rdbuf()->pubseekoff rather than seekg         */
+/*   HAS_STR_NPOS          : has string::npos and not a global NPOS        */
+/*   NO_IOS_COMPLEX        : does not have operator << defined for complex */
+
+
+/* The following is true for most compilers */
+
+#ifndef HAS_VEC_NEW
+#define HAS_VEC_NEW
+#endif
+
+#ifndef COMPILER_EXCEPTIONS
+#define COMPILER_EXCEPTIONS
+#endif
+
+#ifndef  CC_HAS_RTTI_SUPPORT 
+#define  CC_HAS_RTTI_SUPPORT 
+#endif
+
+/* now the specific things */
+
+#ifdef __MWERKS__
+#define ANSI_TEMPLATES
+#undef  HAS_VEC_NEW
+#define NO_STRSTREAM
+//#define STREAMPOS_IS_CLASS
+#define ITER_TAG
+#define HAS_IOS_BIN 
+#define HAS_IOS_NOCREATE 
+#define HAS_STR_NPOS
+#endif
+
+#ifdef __GNUG__
+#define ANSI_TEMPLATES
+// #define GNU_TEMPLATES
+#define HAS_STR_NPOS
+#define HAS_IOS_BIN
+#define HAS_IOS_NOCREATE
+#endif
+
+#ifdef __DECCXX
+#define HAS_STR_NPOS
+#define ITER_TAG
+#define __CXX_PRAGMA_TEMPLATES__
+#define PRAGMA_TEMPLATES
+#endif
+
+#if defined (__aCC__)  
+#ifndef ANSI_TEMPLATES
+#define ANSI_TEMPLATES
+#endif
+#endif
+
+#if defined(__KCC__)
+/* KCC V 3.2 ne compile pas  i/ostream s ; long p = s.tellg();  OK en  V 3.3 */
+#define HAS_STR_NPOS
+#ifndef ANSI_TEMPLATES
+#define ANSI_TEMPLATES
+#endif
+#endif
+
+#if defined(__SGICC__)
+#define HAS_STR_NPOS
+#ifndef ANSI_TEMPLATES
+#define ANSI_TEMPLATES
+#endif
+#endif
+
+/* Get things has homogeneous as possible between compilers */
+
+#ifdef HAS_STR_NPOS
+#define NPOS string::npos
+#else
+#define NPOS (size_t)-1
+#endif
+
+#ifndef __GNUG__
+#define __PRETTY_FUNCTION__ __FILE__ " __LINE__ "
+#ifndef __FUNCTION__
+#define __FUNCTION__ __FILE__ " __LINE__ "
+#endif
+#ifndef __KCC__
+#define __attribute__(_x_)
+#endif
+#endif
+
+#ifdef NO_EXPLICIT
+#define explicit
+#endif
+
+#ifdef HAS_IOS_BIN
+#define IOS_BIN ios::binary
+#else
+#define IOS_BIN 0
+#endif
+
+#ifdef ANSI_IO
+#define seekg(p_, m_) rdbuf()->pubseekoff(p_,m_)
+#define seekp(p_, m_) rdbuf()->pubseekoff(p_,m_)
+#endif
+
+#ifdef __MWERKS__
+//#define hypot(_x_,_y_) sqrt((_x_)*(_x_) + (_y_)*(_y_))
+#define random() (rand()*65538.0 + rand()*2. + rand())
+#define srandom srand
+#define initstate(seed, tab, n) srand(seed)
+#define nice(_x)
+
+#ifdef __cplusplus
+#include <string.h>
+#include <string>
+inline bool operator< (string const& s1, string const& s2)
+{ return (strcmp(s1.c_str(), s2.c_str()) < 0); }
+#endif
+#endif
+
+#ifdef OS_MACOSX
+#define NO_VALUES_H
+#include "osx_values.h"
+/* Faute de mieux pour le moment : */
+#define drand48() ((double)(random())/LONG_MAX)
+#endif
+
+
+/********************************************************/
+/* Outil d'impressions pour debug */
+#define PR(_data_)  {cout<<" "<<#_data_<<" "<<_data_;}
+#define CR {cout<<"\n"<<flush;}
+/* ********************************************************/
+
+/* ---- Activation des flags de debug/bound checking  ----- */
+#ifdef SOPHYA_DEBUG
+#define SO_BOUNDCHECKING
+#endif
+
+/* ---- La taille et les index des tableaux ---- */
+#ifdef SGI_ARCH64
+typedef int_8 sa_size_t ;
+#else
+typedef int_4 sa_size_t ;
+#endif
+
+/* Compatibilite, avant de migrer tout le code en "PLANCK" */
+
+#ifdef __cplusplus
+/* Standard C++ library classes are in the namespace std  */
+namespace std { }
+using namespace std;
+/*  SOPHYA classes are in namespace SOPHYA  */
+namespace SOPHYA {}
+using namespace SOPHYA;
+#define EXPLICIT explicit
+#endif
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/BaseTools/mutyv.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/mutyv.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/mutyv.cc	(revision 2309)
@@ -0,0 +1,155 @@
+// Classe MuTyV : Variable multi-type numerique
+//                  R. Ansari  1997-2000
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+
+#include "mutyv.h"
+#include <stdio.h>
+
+#include <iostream.h>
+#include <string.h>
+
+/*!
+   \class SOPHYA::MuTyV
+   \ingroup BaseTools
+   Simple utility class which can be used to hold values of type
+   string, integer (\b int_8) or float (\b r_8) as well as complex,
+   It provides also easy conversion methods between these types. 
+
+   \code
+   //  ------- Using MuTyV objects ------- 
+   MuTyV mvu;         // MuTyV variable declaration 
+   mvu = 60;          // mvu contains the integer value 60
+   mvu = 66.6;        // and now the double value 66.6 
+   string ds = mvu;   // ds contains the string "66.6"
+   MuTyV mvi(14);     // New MuTyV variable containing integer value 14
+   r_4 x = mvi;       // x has the value 14.0
+   MuTyV mvs("Bonjour !");  // mvs contains the string "Bonjour !"
+   string s = mvs;          // s contains "Bonjour !"
+  
+   \endcode
+*/
+
+
+static void mutyv_decodestr(string const &, double& r, double& im);
+static inline void mutyv_decodestr_cp(const char * si, double& r, double& im)
+{
+  r = im = 0.;
+  string s = si;
+  mutyv_decodestr(s, r, im);
+}
+
+/* --Methode-- */
+MuTyV::MuTyV(MuTyV const & a)
+{
+  typ = a.typ;  iv = a.iv;  dv = a.dv;  dv_im = a.dv_im; 
+  if (typ == MTVString)  strv = new string(*(a.strv));
+  else strv = NULL;
+}
+
+/* --Methode-- */
+MuTyV::~MuTyV()
+{
+  if (strv) delete strv;
+}
+
+/* --Methode-- */
+MuTyV::MuTyV(char const* s)
+{
+  typ = MTVString;
+  strv = new string(s);
+  mutyv_decodestr(s, dv, dv_im);
+  iv = (int_8)dv;
+}
+
+/* --Methode-- */
+MuTyV::MuTyV(string const& s)
+{
+  typ = MTVString;
+  strv = new string(s);
+  mutyv_decodestr(s.c_str(), dv, dv_im);
+  iv = (int_8)dv;
+}
+
+/* --Methode-- */
+MuTyV & MuTyV::operator= (MuTyV const & a)
+{
+  typ = a.typ;  iv = a.iv;  dv = a.dv;  dv_im = a.dv_im; 
+  if (typ == MTVString)  { 
+    if (strv) *strv = *(a.strv);  
+    else strv = new string(*(a.strv));
+  }
+  return(*this);
+}
+
+/* --Methode-- */
+char * MuTyV::operator= (char* s)
+{
+  typ = MTVString;
+  if (strv) *strv = s;  
+  else strv = new string(s);
+  mutyv_decodestr(s, dv, dv_im);
+  iv = (int_8)dv;
+  return(s);
+}
+
+/* --Methode-- */
+string & MuTyV::operator= (string& s)
+{
+  typ = MTVString;
+  if (strv) *strv = s;  
+  else strv = new string(s);
+  mutyv_decodestr(s.c_str(), dv, dv_im);
+  iv = (int_8)dv;
+  return(s);
+}
+
+/* --Methode-- */
+MuTyV::operator string() const 
+{
+  if (typ == MTVString)  return(*strv);
+  else {
+    char buff[96];
+    if (typ == MTVInteger)  sprintf(buff,"%ld", (long)iv);
+    else if (typ == MTVFloat) sprintf(buff,"%g", dv);
+    else if (typ == MTVComplex) sprintf(buff,"(%g,%g)", dv, dv_im);
+    else buff[0] = '\0';
+    return(string(buff));
+  }
+}
+
+
+
+static void mutyv_decodestr(string const & s, double& r, double& im)
+  // decodage d'une chaine contenant une ou deux valeurs
+{
+  r = im = 0.;
+  size_t l = s.length();
+  size_t p = s.find_first_not_of(" \t",0);
+  size_t q,q2;
+  if (p >= l) return;
+  if (s[p] == '(') {  // C'est un complexe
+    if ((q2=s.find(')',p)) >= l)  return; 
+    size_t pz = s.find_first_not_of(" \t",p+1);
+    size_t qz = q2;
+    if ((q=s.find(',',pz)) < q2) qz = q;
+    if (isdigit(s[pz]) || !(s[pz] == '+') || (s[pz] == '-') )  
+      r = atof(s.substr(pz,qz-pz).c_str());
+    else return;
+    if (qz == q) {
+      pz = s.find_first_not_of(" \t",qz+1);
+      if (isdigit(s[pz]) || (s[pz] == '+') || (s[pz] == '-') )  
+	im = atof(s.substr(pz,q2-pz).c_str());      
+    }
+  }
+
+  q = s.find_first_of(" \t",p+1);
+  if (!isdigit(s[p]) && !(s[p] == '+') && !(s[p] == '-') )
+    return;
+  r = atof(s.substr(p,q-p).c_str());
+  im = 0.;
+}
+
+
+
+
Index: /tags/V_Dec2002/SophyaLib/BaseTools/mutyv.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/mutyv.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/mutyv.h	(revision 2309)
@@ -0,0 +1,96 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe MuTyV : Variable multi-type numerique
+//                               Reza Ansari - 96-2000
+
+#ifndef MUTYV_H_SEEN
+#define MUTYV_H_SEEN
+
+#include "machdefs.h"
+
+#include <string>
+#include <complex>
+#include <iostream.h>
+
+namespace SOPHYA {
+
+// Classe utilitaire pour manipuler des variables typees 
+//! A simple class for holding string, integer, float and complex type values.
+
+class MuTyV {
+public:
+
+  enum MTVType {
+    MTVInteger,
+    MTVFloat,
+    MTVComplex,
+    MTVString
+  };
+
+  inline MuTyV() { typ = MTVInteger; iv = 0;  dv = dv_im = 0.;  strv = NULL; }
+         MuTyV(MuTyV const & a);
+  inline MuTyV(uint_2 i) { typ = MTVInteger; iv = (int_8)i;  dv = (r_8)i;  dv_im = 0.;  strv = NULL; }
+  inline MuTyV(uint_8 i) { typ = MTVInteger; iv = (int_8)i;  dv = (r_8)i;  dv_im = 0.;  strv = NULL; }
+  inline MuTyV(int_4 i)  { typ = MTVInteger; iv = (int_8)i;  dv = (r_8)i;  dv_im = 0.;  strv = NULL; }
+  inline MuTyV(int_8 i)  { typ = MTVInteger; iv = i;  dv = (r_8)i;  dv_im = 0.;  strv = NULL; }
+  inline MuTyV(r_4 f) { typ = MTVFloat; dv = (r_8)f; iv = (int_8)f;  dv_im = 0.;  strv = NULL; } 
+  inline MuTyV(r_8 d) { typ = MTVFloat; dv = d;  iv = (int_8)d;  dv_im = 0.;  strv = NULL; } 
+  inline MuTyV(complex<r_4> const& z) { typ = MTVComplex; dv = (r_8)z.real();  dv_im = z.imag();  
+                                 iv = (int_8)dv;  strv = NULL; } 
+  inline MuTyV(complex<r_8> const& z) { typ = MTVComplex; dv = z.real();  dv_im = z.imag();  
+                                 iv = (int_8)dv;  strv = NULL; } 
+
+         MuTyV(char const* s);  
+         MuTyV(string const& s); 
+ 
+         ~MuTyV();
+ 
+         MuTyV & operator= (MuTyV const & a);
+  inline MuTyV & operator= (uint_2 v)  { typ = MTVInteger; iv = (int_8)v;  dv = (r_8)v;  dv_im = 0.;  return(*this); }
+  inline MuTyV & operator= (uint_8 v)  { typ = MTVInteger; iv = (int_8)v;  dv = (r_8)v;  dv_im = 0.;  return(*this); }
+  inline MuTyV & operator= (int_4 v)  { typ = MTVInteger; iv = (int_8)v;  dv = (r_8)v;  dv_im = 0.;  return(*this); }
+  inline MuTyV & operator= (int_8 v)  { typ = MTVInteger; iv = v;  dv = (r_8)v; dv_im = 0.;  return(*this); }
+  inline MuTyV & operator= (r_4 v)  { typ = MTVFloat; dv = (r_8)v; iv = (int_8)v;  dv_im = 0.;  return(*this); }
+  inline MuTyV & operator= (r_8 v) { typ = MTVFloat; dv = v; iv = (int_8)v;  dv_im = 0.;  return(*this); }
+  inline MuTyV & operator= (complex<r_4> const& v) { typ = MTVComplex; dv = (r_8)v.real();  dv_im = v.imag();
+                                                    iv = (int_8)dv;  return(*this); }
+  inline MuTyV & operator= (complex<r_8> const& v) { typ = MTVComplex; dv = (r_8)v.real();  dv_im = v.imag();
+                                                    iv = (int_8)dv;  return(*this); }
+         char*  operator= (char* s);
+         string& operator= (string& s);
+
+  inline operator uint_2() const { return((uint_2)iv); }
+  inline operator uint_4() const { return((uint_4)iv); }
+  inline operator uint_8() const { return((uint_8)iv); }
+  inline operator int_4()  const { return((int_4)iv); }
+  inline operator int_8()  const { return(iv); }
+  inline operator r_4() const  { return((r_4)dv); }
+  inline operator r_8() const  { return(dv); }
+  inline operator complex<r_4>() const { return(complex<r_4>((r_4)dv, (r_4)dv_im)); }
+  inline operator complex<r_8>() const { return(complex<r_8>(dv, dv_im)); }
+
+         operator string() const ; 
+
+  inline MTVType Type() const { return typ; }
+  inline int_8   GetIntPart() const { return iv; }
+  inline r_8     GetRealPart() const { return dv; }
+  inline r_8     GetImagPart() const { return dv_im; }
+  inline string*  GetStringPointer() const { return (strv); } 
+
+protected:
+  int_8 iv;
+  r_8 dv;
+  r_8 dv_im;   /* for holding imaginary part of a complex */
+  string * strv; 
+  MTVType typ;
+
+};
+
+inline ostream& operator << (ostream& s, MuTyV const & mtv)
+{  s << (string)mtv;   return(s); }
+ 
+
+} // namespace SOPHYA
+
+#endif /* MUTYV_H_SEEN */
+
+
Index: /tags/V_Dec2002/SophyaLib/BaseTools/ndatablock.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/ndatablock.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/ndatablock.cc	(revision 2309)
@@ -0,0 +1,794 @@
+// Gestion de block de donnees avec partage de references
+// malheureusement tres mal concu...  C.Magneville 04/99
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream.h>
+#include <complex>
+#include "pexceptions.h"
+#include "ndatablock.h"
+
+/*!
+  \class SOPHYA::NDataBlock
+  \ingroup BaseTools
+  Management of data blocks
+*/
+
+//////////////////////////////////
+// Fonctionnement en mode debug //
+//////////////////////////////////
+
+template <class T> int    NDataBlock<T>::Debug_NDataBlock = 0;
+template <class T> size_t NDataBlock<T>::NallocData       = 0;
+template <class T> size_t NDataBlock<T>::NallocSRef       = 0;
+
+//! Set debug (and level print) for allocation and references debug.
+/*!
+  \param prtlevel : activate/des-activate debug mode
+                    and select print level
+
+  \arg prtlevel <= 0 : no debug
+  \arg prtlevel == 1 : debug activated, no print
+  \arg prtlevel >=2  : debug activated,
+       print infos in all routines that have something to do with
+       allocations or des-allocation of datas or references.
+ */
+template <class T>
+void NDataBlock<T>::SetPrintDebug(int prtdbglevel)
+{
+  Debug_NDataBlock = prtdbglevel;
+}
+
+//! Reset debug counter values.
+/*!
+  \param nallocdata : reset number of allocated data structures to \b nallocdata
+  \param nallocsref : reset number of allocated references to \b nallocsref
+  \warning In principle this routine should not be use (only experts)
+ */
+template <class T>
+void NDataBlock<T>::ResetDebug(size_t nallocdata, size_t nallocsref)
+{
+NallocData = nallocdata;
+NallocSRef = nallocsref;
+}
+
+//! Print debug current status.
+/*!
+  Print debug current status for number of allocated
+  data structures and number of allocated references.
+ */
+template <class T>
+void NDataBlock<T>::PrintDebug()
+{
+cout<<"... ... ... NallocData = "<<NallocData
+    <<"  ,  NallocSRef = "<<NallocSRef
+    <<" ... ... ..."<<endl;
+}
+
+///////////////////////////
+// Createur, Destructeur //
+///////////////////////////
+
+//! Constructor for \b n datas
+template <class T>
+NDataBlock<T>::NDataBlock(size_t n)
+// Createur d'une structure de "n" donnees
+: mSz(0), mSRef(NULL), mIsTemp(false)
+{
+if(Debug_NDataBlock>1)
+  cout<<"?_NDataBlock::NDataBlock("<<this<<",n="<<n<<")"<<endl;
+
+Alloc(n, NULL, NULL, true);   // allocation et mise a zero
+}
+
+//! Constructor for \b n datas shared with external
+/*!
+  Datas are previously allocated by an other external source.
+  \warning This require particular care (see Alloc)
+  \sa Alloc
+ */
+template <class T>
+NDataBlock<T>::NDataBlock(size_t n, T* data, Bridge* br)
+// Createur d'une structure de "n" donnees, avec donnees preallouees.
+// Attention createur TRES DANGEREUX (Voir explications dans Alloc()).
+: mSz(0), mSRef(NULL), mIsTemp(false)
+{
+if(Debug_NDataBlock>1)
+  cout<<"?_NDataBlock::NDataBlock("<<this
+      <<",data="<<data<<",br="<<br<<")"<<endl;
+
+Alloc(n,data,br);
+}
+
+//! Default constructor
+template <class T>
+NDataBlock<T>::NDataBlock()
+// Createur par default
+: mSz(0), mSRef(NULL), mIsTemp(false)
+{
+if(Debug_NDataBlock>1)
+  cout<<"?_NDataBlock::NDataBlock("<<this<<") default"<<endl;
+}
+
+//! Copy constructor
+/*!
+  \warning datas are \b SHARED with \b a.
+ */
+template <class T>
+NDataBlock<T>::NDataBlock(const NDataBlock<T>& a)
+// Createur par copie: partage les donnees dans tous les cas
+: mSz(0), mSRef(NULL), mIsTemp(false)
+{
+if(Debug_NDataBlock>1)
+  cout<<"?_NDataBlock::NDataBlock("<<this<<",&a="<<&a<<" a.mSz="<<a.mSz<<")"<<endl;
+
+if(a.mSRef && a.mSz>0) Share(a);
+}
+
+//! Copy constructor with \b share option
+/*!
+  \warning datas are shared if \b share is \b true, cloned if not.
+ */
+template <class T>
+NDataBlock<T>::NDataBlock(const NDataBlock<T>& a,bool share)
+// Createur avec choix de partager ou non selon "share"
+: mSz(0), mSRef(NULL), mIsTemp(false)
+{
+if(Debug_NDataBlock>1)
+  cout<<"?_NDataBlock::NDataBlock("<<this<<",&a="<<&a
+      <<",sh=<<"<<share<<")"<<endl;
+
+if(a.mSRef && a.mSz>0) {if(share) Share(a); else Clone(a);}
+}
+
+//! Destructor
+template <class T>
+NDataBlock<T>::~NDataBlock()
+// Destructeur
+{
+if(Debug_NDataBlock>1)
+  cout<<"?_NDataBlock::~NDataBlock("<<this<<")"<<endl;
+
+Delete();
+}
+
+////////////////////////
+// Gestion de donnees //
+////////////////////////
+
+//! Clone datas from \b a
+template <class T>
+void NDataBlock<T>::Clone(const NDataBlock<T>& a)
+// Clone: copie de donnees a partir de "a"
+{
+if(Debug_NDataBlock>1)
+  cout<<"?_NDataBlock::Clone("<<this<<","<<&a<<") a.(mSz="
+      <<a.mSz<<" mSRef="<<a.mSRef<<" IsTemp="<<a.IsTemp()
+      <<"), mSz="<<mSz<<" mSRef="<<mSRef<<" IsTemp="<<mIsTemp<<endl;
+
+if(&a==NULL) throw(NullPtrError("NDataBlock::Clone  &a==NULL\n"));
+if(!a.mSRef || a.mSz==0) throw(NullPtrError("NDataBlock::Clone a.mSz=0\n"));
+Alloc(a.mSz, NULL, NULL, false);  // pas de mise a zero 
+memcpy(Data(),a.Data(),mSz*sizeof(T));
+}
+
+//! Share datas with \b a
+template <class T>
+void NDataBlock<T>::Share(const NDataBlock<T>& a)
+// Share: Partage les donnees avec "a"
+{
+if(Debug_NDataBlock>1) {
+  cout<<"?_NDataBlock::Share("<<this<<","<<&a<<")";
+  if(&a!=NULL) cout<<" a.(mSz="<<a.mSz<<" mSRef="<<a.mSRef
+                   <<" IsTemp="<<a.IsTemp()<<")";
+  cout<<", mSz="<<mSz<<" mSRef="<<mSRef<<" IsTemp="<<mIsTemp<<endl;
+}
+
+if(&a==NULL) throw(NullPtrError("NDataBlock::Share  &a==NULL\n"));
+if(!a.mSRef || a.mSz==0) throw(NullPtrError("NDataBlock::Share a.mSz=0\n"));
+if(mSRef) Delete();
+mSz = a.mSz; mSRef = a.mSRef; mSRef->nref++;
+
+if(Debug_NDataBlock>1)
+  cout<<"...?_NDataBlock::Share mSz="<<mSz<<" mSRef="<<mSRef
+      <<" mSRef->nref="<<mSRef->nref<<" mSRef->data="<< mSRef->data
+      <<" mSRef->bridge="<<mSRef->bridge
+      <<" IsTemp="<<mIsTemp<<endl;
+}
+
+//! \b Share with \b a if \b temporary, \b clone from \b a if not.
+/*! \warning For most purposes, users don't have to worry with
+             the "temporary" nature of a NDataBlock. That is used
+             internaly to avoid memory allocation in operation
+             like A = B + C + D for instance. The method is not
+             protected to allow users to write complicated functions
+             on NDataBlock.
+  \verbatim
+  ----------------------------------------------------------
+  Pourquoi une complication avec la notion de "temporaire" :
+  ----------------------------------------------------------
+  - Le constructeur par copie partageant les donnees,
+    dans une methode un { NDataBlock<T> result; ...; return result;}
+    ne va pas allouer de la memoire pour retourner "result".
+  - La gestion de temporaire sert quand on enchaine plusieurs
+    operations sur la meme ligne, par exemple : A = B+C+D;
+    Dans ce cas l'objet CD=C+D est d'abord alloue et rempli
+    avec C+D, puis CD est mis a "temporaire".
+    Quand on ajoute B a CD, la methode d'addition va se rendre compte
+    que CD est "temporaire" et additionner B "in-place" dans CD
+    sans allouer une fois de plus de la place (pas d'allocation
+    de place BCD pour mettre B+CD mais une operation CD += B).
+    Si la notion d'objet "temporaire" n'avait pas ete consideree
+    l'addition A = B+C+D aurait alloue de la place pour "CD=C+D"
+    puis pour BCD=B+CD : 2 allocations auraient ete necessaires
+    contre 1 seule dans notre cas de geston de "temporaire".
+  \endverbatim
+*/
+template <class T>
+void NDataBlock<T>::CloneOrShare(const NDataBlock<T>& a)
+// CloneOrShare: Share si "a" temporaire, Clone sinon.
+{
+if(Debug_NDataBlock>1)
+  cout<<"?_NDataBlock::CloneOrShare("<<this<<","<<&a<<")"<<endl;
+
+if(&a==NULL) throw(NullPtrError("NDataBlock::CloneOrShare  &a==NULL\n"));
+if(a.IsTemp()) Share(a); else Clone(a);
+}
+
+////////////////////////////////////////////////////////////
+// Allocation , destruction , remplissage et reallocation //
+////////////////////////////////////////////////////////////
+
+//! Allocation management
+/*!
+   Allocation d'un NOUVEL espace de stoquage de "n" donnees
+   \verbatim
+   Si data==NULL : allocation de l'espace memoire 
+      si zero == true , l'espace est remplis de zeros
+      data!=NULL : partage des donnees avec l'adresse data
+   Si br==NULL   : les donnees nous appartiennent
+      br!=NULL   : les donnees ne nous appartiennent pas (ex: Blitz)
+  
+   Exemple: on veut connecter a un tableau de T*
+   > float *x = new float[5]; ... remplissage de x[] ...;
+   1- On veut que NDataBlock NE DESALLOUE PAS le tableau "x[]"
+      a- Premiere solution
+         > NDataBlock A(5,x,new Bridge);
+         ......
+         > delete [] x;
+            - Il faut deleter x[] explicitement.
+            - Le destructeur de "A" ne detruit pas x[].
+            ATTENTION: Une fois x[] detruit, "A" ne peut
+                       plus acceder les donnees!
+            - Bridge est detruit par le destructeur de "A"
+      b- Autre solution:
+         > NDataBlock A(5); A.FillFrom(5,x);
+         > delete [] x;
+         ......
+            - Il faut deleter x[] explicitement.
+            - "A" possede une copie en local de x[].
+            - Le destructeur de "A" ne detruit pas x[] mais la copie locale.
+   2- On veut que NDataBlock desalloue le tableau
+         > NDataBlock A(5,x);
+            - Ne Pas Faire "delete [] x;"
+            - "A" partage les donnees avec x[].
+            - Le destructeur de "A" detruit x[].
+  
+   --- REMARQUE SUR LE DANGER DE CERTAINES SITUATIONS (CMV):
+   1-/ x = new float[n1]; NDataBlock A(n2,x);
+       1er danger: si n2>n1 depassement de tableaux (core dump)
+       2sd danger: celui qui alloue x[] ne doit pas faire le "delete"
+                   en desaccord avec toutes les regles de bonne conduite.
+   2-/ float x[5]={1,2,3,4,5}; {NDataBlock A(n2,&x[0]);} cout<<x[2];
+       Ici, a la sortie du bloc {}, le destructeur de "A" va detruire
+       l'adresse de &x[0]: je n'ose imaginer que ca se fasse sans probleme
+       et de toute facon, cout<<x[2]; va surement faire des etincelles.
+   3-/ x = new float[n1]; NDataBlock A(n2,x,new Bridge);
+       1er danger: si n2>n1 depassement de tableaux (core dump)
+       2sd danger: si la methode bridgee (blitz?) detruit x[]
+                   "A" n'a plus de donnees connectees!
+   --- CONCLUSION
+   Cette classe est franchement merdique.
+   - On peut accepter la prise de risque liee a NDataBlock(n2,x,new Bridge);
+     car je ne vois pas comment on pourrait faire autrement pour connecter
+     un tableau de type blitz par exemple.
+   - Par contre le createur NDataBlock(n2,x); doit etre interdit
+     dans sa forme actelle car trop dangereux et il me semble inutile.
+   - Dans cette nouvelle optique:
+     NDataBlock(n2,x,new Bridge) et NDataBlock(n2,x) disparaissent
+     On remplace par NDataBlock(n2,x) {Alloc(n2,x,new Bridge);}
+        qui force le Bridge dans tout les cas puisque NDataBlock
+        ne possede pas les donnees.
+     Mais puis-je encore le faire vu que NDataBlock est a la base
+     de TVector,TMatrix et qu'il faut donc reprendre tout le code DPC
+   - Quoiqu'il arrive Alloc est une methode privee et peut donc rester
+     sous sa forme actuelle.
+              
+   \endverbatim
+ */
+
+static uint_8 _ndrefid_ = 0; // Identificateur de NDREF cree 
+
+template <class T>
+void NDataBlock<T>::Alloc(size_t n,T* data,Bridge* br,bool zero)
+{
+if(Debug_NDataBlock>1)
+  cout<<"?_NDataBlock::Alloc("<<this<<","
+      <<n<<","<<data<<","<<br<<") mSz="<<mSz
+      <<" mSRef="<<mSRef<<" IsTemp="<<mIsTemp<<endl;
+
+if(br && !data)
+  throw(NullPtrError("NDataBlock::Alloc br!=NULL && data==NULL\n"));
+if(n==0) throw(SzMismatchError("NDataBlock::Alloc n==0\n"));
+if(mSRef) Delete();
+mSz = n;
+mSRef = new NDREF;
+mSRef->nref = 1;
+mSRef->dsid = ++_ndrefid_;
+if(data) mSRef->data = data;
+else {mSRef->data = new T[n]; if (zero) memset(mSRef->data,0,n*sizeof(T));}
+mSRef->bridge = br;
+
+if(Debug_NDataBlock>0) {
+  // Meme dans le cas data!=0 et br==0 (connexion d'un tableau
+  // avec destruction geree par ~NDataBlock (cas 2-) on compte
+  // comme si on avait fait une allocation du tableau (ce qui a ete
+  // fait au niveau du dessus!).
+  if(!br) NallocData++; NallocSRef++;
+  if(Debug_NDataBlock>1)
+    cout<<"...?_NDataBlock::Alloc mSz="<<mSz<<" mSRef="<<mSRef
+        <<" mSRef->nref="<<mSRef->nref<<" mSRef->data="<<mSRef->data
+        <<" mSRef->bridge="<<mSRef->bridge
+        <<" IsTemp="<<mIsTemp
+        <<" Total("<<NallocData<<","<<NallocSRef<<")"<<endl;
+}
+}
+
+//! Management of de-allocation
+template <class T>
+void NDataBlock<T>::Delete(void)
+// Pour detruire les pointeurs en tenant compte des references
+{
+if(Debug_NDataBlock>1) {
+  cout<<"?_NDataBlock::Delete("<<this<<") mSz="<<mSz
+      <<" mSRef="<<mSRef<<" IsTemp="<<mIsTemp;
+  if(mSRef)
+    cout<<" mSRef->nref="<<mSRef->nref<<" mSRef->data="
+        <<mSRef->data<<" mSRef->bridge="<<mSRef->bridge;
+  cout<<endl;
+}
+
+if(mSRef==NULL) return;
+
+mSRef->nref--;
+if(mSRef->nref != 0) {
+
+if(Debug_NDataBlock>1)
+  cout<<"...?_NDataBlock::Delete() pas de desallocation il reste nref="
+      <<mSRef->nref<<" Total("<<NallocData<<","<<NallocSRef<<")"<<endl;
+
+  mSz = 0; mSRef=NULL;
+  return;
+}
+
+if(Debug_NDataBlock>0) {
+  if(!mSRef->bridge) NallocData--; NallocSRef--;
+  if(Debug_NDataBlock>1)
+    cout<<"...?_NDataBlock::Delete() desallocation complete il reste nref="
+        <<mSRef->nref<<" Total("<<NallocData<<","<<NallocSRef<<")"<<endl;
+}
+
+// Si il y a un Bridge les donnees ne n'appartiennent pas, on detruit le Bridge
+// sinon, les donnees ont ete allouees par nos soins, on libere l'espace
+if(mSRef->bridge) delete mSRef->bridge; else delete [] mSRef->data;
+mSRef->bridge=NULL; mSRef->data=NULL;
+delete mSRef; mSRef=NULL; mSz = 0;
+}
+
+//! Fill dats of this NDataBlock with the \b n datas pointed by \b data
+/*!
+  \warning If class empty : allocate space in memory
+  \warning If class already connected : overwrite with minimum size
+           (\b n or \b mSz)
+ */
+template <class T>
+void NDataBlock<T>::FillFrom(size_t n,T* data)
+// Remplissage par un tableau de donnees
+// - Si classe vide : creation de l'espace memoire
+// - Si classe connectee : on ecrit selon la longueur minimale
+//                         (cad this->mSz ou "n")
+{
+if(data==NULL) throw(NullPtrError("NDataBlock::FillFrom  data==NULL\n"));
+if(n==0) throw(ParmError("NDataBlock::FillFrom  n<=0\n"));
+if(mSRef==NULL) Alloc(n, NULL, NULL, false);  // Pas de mise a zero
+if(mSz<n) n = mSz;
+memcpy(Data(),data,n*sizeof(T));
+}
+
+//! Re-allocate space for \b nnew datas
+/*!
+  \param nnnew : new size
+  \param force : to manage the way re-allocation will be done (see after).
+  \verbatim
+  Re-allocation de "nnew" place memoire pour les donnees
+  avec conservation des "nold" donnees precedentes si possible.
+  "force" gere la re-allocation de la place memoire pour les donnees.
+  Divers cas se presentent:
+  a-/ *** nnew>nold force=quelconque ***
+      place re-allouee, donnees [0,nold[ copiees, surplus [nold,new[ mis a zero
+  b-/ *** nnew<=nold force=true ***
+      place re-allouee, donnees [0,nnew[ copiees, pas de surplus
+  c-/ *** nnew<=nold force=false ***
+      place non re-allouee, seule la valeur de la taille est diminuee
+  - On tient compte du partage des donnees dans tous les cas.
+  - Si il n'y a pas de donnees connectees a la classe, on re-alloue
+    dans tous les cas
+  \endverbatim
+ */
+template <class T>
+void NDataBlock<T>::Realloc(size_t nnew,bool force)
+{
+if(nnew==0) throw(ParmError("NDataBlock::Realloc  n<=0\n"));
+
+// Cas sans re-allocation memoire
+if(mSRef && nnew<=mSz && ! force) { mSz=nnew; return;}
+
+// Cas avec re-allocation memoire
+size_t ncop;
+if(!mSRef || mSz==0) ncop=0; else if(mSz<nnew) ncop=mSz; else ncop=nnew;
+T* dataloc = new T[nnew];
+if(ncop>0) memcpy(dataloc,mSRef->data,ncop*sizeof(T));
+if(nnew>ncop) memset(dataloc+ncop,0,(nnew-ncop)*sizeof(T));
+Alloc(nnew,dataloc,NULL); //Alloc gere partage de reference et bridge
+}
+
+////////////////
+// Impression //
+////////////////
+
+//! Give infos and print \b n datas beginning at \b i1 on stream \b os.
+template <class T>
+void NDataBlock<T>::Print(ostream& os,size_t i1,size_t n) const
+// Impression de n elements a partir de i1
+{
+size_t nr = 0;
+T* p = NULL; Bridge* br = NULL;
+if(mSRef) {nr = mSRef->nref; p = mSRef->data; br = mSRef->bridge;}
+os<<"NDataBlock::Print("<<this<<",Sz="<<mSz<<",IsTemp="<<mIsTemp<<")\n"
+  <<"            mSRef="<<mSRef<<"(nref="<<nr<<",data="<<p
+  <<",bridge="<<br<<")"<<endl;
+if(i1>=mSz || n<=0 || !p) return;
+size_t i2 = i1+n; if(i2>mSz) i2=mSz;
+size_t im = 1; bool enl=false;
+while(i1<i2) {
+  enl = false;
+  os<<" "<<(*this)(i1);  i1++;
+  if(im==8) {os<<"\n"; im=1; enl=true;} else im++;
+}
+if(!enl) os<<endl;
+}
+
+//////////////////////////////////////////////
+// Calcul de la somme / produit des donnees //
+//////////////////////////////////////////////
+
+//! Return sum of \b n datas beginning at data \b i1.
+template <class T>
+T NDataBlock<T>::Sum(size_t i1,size_t n) const
+// Somme des elements de i1 a i1+n-1
+{
+if(i1>=mSz) return 0;
+if(n>mSz) n = mSz; if(n==0) n = mSz-i1;
+T const *p=Begin()+i1, *pe=p+n;
+T val = 0;
+while (p<pe) val += *p++;
+return val;
+}
+
+//! Return product of \b n datas beginning at data \b i1.
+template <class T>
+T NDataBlock<T>::Product(size_t i1,size_t n) const
+// Produit des elements de i1 a i1+n-1
+{
+if(i1>=mSz) return 0;
+if(n>mSz) n = mSz; if(n==0) n = mSz-i1;
+T const *p=Begin()+i1, *pe=p+n;
+T val = 0;
+while (p<pe) val *= *p++;
+return val;
+}
+
+///////////////////////////////////////////////////////////////
+// Surcharge de = : NDataBlock=NDataBlock; NDataBlock=<T> b; //
+///////////////////////////////////////////////////////////////
+
+//! Operator = : ND = NDa
+/*! \warning Datas are copied (cloned) from \b a. */
+template <class T>
+NDataBlock<T>& NDataBlock<T>::operator = (const NDataBlock<T>& a)
+// Affectation: partage des donnees si "a" temporaire, clone sinon.
+{
+if(Debug_NDataBlock>1)
+  cout<<"?_NDataBlock::operator=("<<this<<","<<&a<<") a.(mSz="
+      <<a.mSz<<" mSRef="<<a.mSRef<<" IsTemp="<<a.IsTemp()
+      <<"), mSz="<<mSz<<" mSRef="<<mSRef<<" IsTemp="<<mIsTemp<<endl;
+
+if(this == &a) return *this;
+if(a.mSz==0)
+  throw(SzMismatchError("NDataBlock::operator=A null size \n"));
+if (mSz==0) { CloneOrShare(a); return *this; }
+if (a.mSz != mSz)
+  throw(SzMismatchError("NDataBlock::operator=A Unequal sizes \n"));
+memcpy(Data(),a.Data(),mSz*sizeof(T));
+return *this;
+}
+
+//! Operator = : ND = \b v (at dats set to \b v).
+template <class T>
+NDataBlock<T>& NDataBlock<T>::operator = (T v)
+// Affectation de tous les elements a une constante "v"
+{
+if(Debug_NDataBlock>1)
+  cout<<"?_NDataBlock::operator=("<<this<<","<<v<<")"
+      <<" mSz="<<mSz<<" mSRef="<<mSRef<<" IsTemp="<<mIsTemp<<endl;
+
+if(mSz==0) throw(SzMismatchError("NDataBlock::operator=v null size\n"));
+T *p=Begin(), *pe=End(); while (p<pe) *p++ = v;
+return *this;
+}
+
+//////////////////////////////////////////////////////////////
+// Surcharge de +=,-=,*=,/= (INPLACE): NDataBlock += <T> b; //
+//////////////////////////////////////////////////////////////
+
+//! Add a constant : ND += b
+template <class T>
+NDataBlock<T>& NDataBlock<T>::operator += (T b)
+{
+if(mSz==0) throw(SzMismatchError("NDataBlock::operator+=v null size\n"));
+T *p=Begin(), *pe=End(); while (p<pe) *p++ += b;
+return *this;
+}
+
+//! Substract a constant : ND -= b
+template <class T>
+NDataBlock<T>& NDataBlock<T>::operator -= (T b)
+{
+if(mSz==0) throw(SzMismatchError("NDataBlock::operator-=v null size\n"));
+T *p=Begin(), *pe=End(); while (p<pe) *p++ -= b;
+return *this;
+}
+
+//! Multiply by a constant : ND *= b
+template <class T>
+NDataBlock<T>& NDataBlock<T>::operator *= (T b)
+{
+if(mSz==0) throw(SzMismatchError("NDataBlock::operator*=v null size\n"));
+T *p=Begin(), *pe=End(); while (p<pe) *p++ *= b;
+return *this;
+}
+
+//! Divide by a constant : ND /= b
+template <class T>
+NDataBlock<T>& NDataBlock<T>::operator /= (T b)
+{
+if(b==(T) 0) throw(ParmError("NDataBlock::operator/=v divide by zero\n"));
+if(mSz==0) throw(SzMismatchError("NDataBlock::operator/=v null size\n"));
+T *p=Begin(), *pe=End(); while (p<pe) *p++ /= b;
+return *this;
+}
+
+////////////////////////////////////////////////////////////////////
+// Surcharge de +=,-=,*=,/= (INPLACE): NDataBlock += NDataBlock1; //
+////////////////////////////////////////////////////////////////////
+
+//! Add a NDataBlock : ND += NDa
+template <class T>
+NDataBlock<T>& NDataBlock<T>::operator += (const NDataBlock<T>& a)
+{
+if(mSz==0 || mSz!=a.mSz)
+  throw(SzMismatchError("NDataBlock::operator+=A size mismatch/null"));
+T *p=Begin(), *pe=End();
+T const * pa=a.Begin();
+while (p<pe) *p++ += *pa++;
+return *this;
+}
+
+//! Substract a NDataBlock : ND -= NDa
+template <class T>
+NDataBlock<T>& NDataBlock<T>::operator -= (const NDataBlock<T>& a)
+{
+if(mSz==0 || mSz!=a.mSz)
+  throw(SzMismatchError("NDataBlock::operator-=A size mismatch/null"));
+T *p=Begin(), *pe=End();
+T const *pa=a.Begin();
+while (p<pe) *p++ -= *pa++;
+return *this;
+}
+
+//! Multiply by a NDataBlock : ND *= NDa
+template <class T>
+NDataBlock<T>& NDataBlock<T>::operator *= (const NDataBlock<T>& a)
+{
+if(mSz==0 || mSz!=a.mSz)
+  throw(SzMismatchError("NDataBlock::operator*=A size mismatch/null"));
+T *p=Begin(), *pe=End();
+T const *pa=a.Begin();
+while (p<pe) *p++ *= *pa++;
+return *this;
+}
+
+//! Divide by a NDataBlock : ND /= NDa
+template <class T>
+NDataBlock<T>& NDataBlock<T>::operator /= (const NDataBlock<T>& a)
+// Attention, aucune protection si un element de "a" est nul.
+{
+if(mSz==0 || mSz!=a.mSz)
+  throw(SzMismatchError("NDataBlock::operator/=A size mismatch/null"));
+T *p=Begin(), *pe=End();
+T const *pa=a.Begin();
+while (p<pe) *p++ /= *pa++; // Division par zero non protegee
+return *this;
+}
+
+//////////////////////////////////////////////////////////////////
+// Pour surcharge de +,-,*,/ : NDataBlock = NDataBlock1+<T>b;   //
+//                             NDataBlock = <T>b+NDataBlock1;   //
+// Pour la notion de "temporaire" voir blabla dans CloneOrShare //
+//////////////////////////////////////////////////////////////////
+
+//! Add a constant and return NDataBlock : NDret = ND + b
+template <class T>
+NDataBlock<T> NDataBlock<T>::Add(T b) const
+// Pour A+b
+{
+NDataBlock<T> result; 
+result.CloneOrShare(*this); result.SetTemp(true);
+result += b;
+return result;
+}
+
+//! Substract a constant and return NDataBlock : NDret = ND - b or NDret = b - ND
+/*! Substract a constant or from a constant
+   \param fginv==false : performs NDret = ND - b (default)
+   \param fginv==true : performs NDret = b - ND
+*/
+template <class T>
+NDataBlock<T> NDataBlock<T>::Sub(T b,bool fginv) const
+// Pour A-b sauf si fginv==true b-A (- n'est pas commutatif!)
+{
+NDataBlock<T> result; 
+result.CloneOrShare(*this); result.SetTemp(true);
+if(fginv) {
+  T *p=result.Begin(), *pe=result.End();
+  T const *pa=this->Begin();
+  while(p<pe) {*p++ = b - *pa++;}
+} else result -= b;
+return result;
+}
+
+//! Multiply by a constant and return NDataBlock : NDret = ND * b
+template <class T>
+NDataBlock<T> NDataBlock<T>::Mul(T b) const
+// Pour A*b
+{
+NDataBlock<T> result; 
+result.CloneOrShare(*this); result.SetTemp(true);
+result *= b;
+return result;
+}
+
+//! Divide by a constant and return NDataBlock : NDret = ND / b or NDret = b / ND
+/*! Divide by a constant or from a constant
+   \param fginv==false : performs NDret = ND / b (default)
+   \param fginv==true : performs NDret = b / ND
+*/
+template <class T>
+NDataBlock<T> NDataBlock<T>::Div(T b,bool fginv) const
+// Pour A/b sauf si fginv==true b/A (/ n'est pas commutatif!)
+{
+NDataBlock<T> result; 
+result.CloneOrShare(*this); result.SetTemp(true);
+ if(fginv) {
+  T *p=result.Begin(), *pe=result.End();
+  T const *pa = this->Begin();
+  while(p<pe) {*p++ = b / *pa++;} // Division par zero non protegee
+} else {
+  if( b == (T) 0 ) throw MathExc("NDataBlock<T>::Div(T)  - Divide by zero ! ");
+  result /= b;
+}
+return result;
+}
+
+///////////////////////////////////////////////////////////////////////
+// Pour surcharge de +,-,*,/ : NDataBlock = NDataBlock1+NDataBlock2; //
+///////////////////////////////////////////////////////////////////////
+
+//! Add a NDataBlock and return a NDataBlock: ND = NDthis + NDb
+template <class T>
+NDataBlock<T> NDataBlock<T>::Add(const NDataBlock<T>& b) const
+// Pour A+B
+{
+if(mSz!=b.mSz)
+  throw(SzMismatchError("NDataBlock operator C=A+B size mismatch/null\n"));
+NDataBlock<T> result; result.SetTemp(true);
+if(b.IsTemp()) {result.Share(b);            result += *this;}
+  else         {result.CloneOrShare(*this); result += b;}
+return result;
+}
+
+//! Multiply by a NDataBlock and return a NDataBlock: ND = NDthis * NDb
+template <class T>
+NDataBlock<T> NDataBlock<T>::Mul(const NDataBlock<T>& b) const
+// Pour A*B
+{
+if(mSz!=b.mSz)
+  throw(SzMismatchError("NDataBlock operator C=A*B size mismatch/null\n"));
+NDataBlock<T> result; result.SetTemp(true);
+if(b.IsTemp()) {result.Share(b);            result *= *this;}
+  else         {result.CloneOrShare(*this); result *= b;}
+return result;
+}
+
+//! Substract a NDataBlock and return a NDataBlock: ND = NDthis - NDb
+template <class T>
+NDataBlock<T> NDataBlock<T>::Sub(const NDataBlock<T>& b) const
+// Pour A-B
+{
+if(mSz!=b.mSz)
+  throw(SzMismatchError("NDataBlock operator C=A-B size mismatch/null\n"));
+NDataBlock<T> result; result.SetTemp(true);
+if(b.IsTemp()) {
+  result.Share(b);
+  T *p=result.Begin(), *pe=result.End(); T const *pa=Begin();
+  while(p<pe) {*p = *pa++  - *p; p++;}
+} else {result.CloneOrShare(*this); result -= b;}
+return result;
+}
+
+//! Divide by a NDataBlock and return a NDataBlock: ND = NDthis / NDb
+template <class T>
+NDataBlock<T> NDataBlock<T>::Div(const NDataBlock<T>& b) const
+// Pour A/B
+{
+if(mSz!=b.mSz)
+  throw(SzMismatchError("NDataBlock operator C=A/B size mismatch/null\n"));
+NDataBlock<T> result; result.SetTemp(true);
+if(b.IsTemp()) {
+  result.Share(b);
+  T *p=result.Begin(), *pe=result.End(); T const *pa=Begin();
+  while(p<pe) {*p = *pa++  / *p; p++;} // Division par zero non protegee
+} else {result.CloneOrShare(*this); result /= b;}
+return result;
+}
+
+
+///////////////////////////////////////////////////////////////
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template NDataBlock<uint_1>
+#pragma define_template NDataBlock<uint_2>
+#pragma define_template NDataBlock<int_2>
+#pragma define_template NDataBlock<int_4>
+#pragma define_template NDataBlock<int_8>
+#pragma define_template NDataBlock<uint_4>
+#pragma define_template NDataBlock<uint_8>
+#pragma define_template NDataBlock<r_4>
+#pragma define_template NDataBlock<r_8>
+#pragma define_template NDataBlock< complex<r_4> >
+#pragma define_template NDataBlock< complex<r_8> >
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class NDataBlock<uint_1>;
+template class NDataBlock<uint_2>;
+template class NDataBlock<int_2>;
+template class NDataBlock<int_4>;
+template class NDataBlock<int_8>;
+template class NDataBlock<uint_4>;
+template class NDataBlock<uint_8>;
+template class NDataBlock<r_4>;
+template class NDataBlock<r_8>;
+template class NDataBlock< complex<r_4> >;
+template class NDataBlock< complex<r_8> >;
+#endif
Index: /tags/V_Dec2002/SophyaLib/BaseTools/ndatablock.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/ndatablock.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/ndatablock.h	(revision 2309)
@@ -0,0 +1,227 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Gestion de block de donnees avec partage de references
+//                         C.Magneville          04/99
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+#ifndef NDATABLOCK_H
+#define NDATABLOCK_H
+
+#include "machdefs.h"
+#include <stdlib.h>        /* pour que size_t soit defini */
+#include "anydataobj.h"
+#include <iostream.h>
+
+namespace SOPHYA {
+
+////////////////////////////////////////////////////////////////
+//// ------------------- Class Bridge ----------------------- //
+////////////////////////////////////////////////////////////////
+/*!
+  \class Bridge
+  \ingroup BaseTools
+  This class is use by NDataBlock. It allows sharing of datas
+  with external structures : by example, if you want to connect
+  a Blitz data structure with a NDataBlock or a TMatrix or ...
+  \sa NDataBlock
+*/
+
+// Classe pour permettre de partager des donnees avec 
+// un autre systeme de gestion de references (ex avec Blitz)
+//! Empty class which allows data sharing with external structures (for NDataBlock)
+class Bridge {
+public:
+  Bridge() { } 
+  virtual ~Bridge() { }
+};
+
+////////////////////////////////////////////////////////////////
+//// ----------------- Class NDataBlock --------------------- //
+////////////////////////////////////////////////////////////////
+
+// classe de container avec partage de reference
+//! Container of data with reference sharing
+template <class T>
+class NDataBlock : public AnyDataObj {
+
+public:
+
+  // Methodes statiques pour debug.
+  static void SetPrintDebug(int prtdbglevel=1);
+  static void ResetDebug(size_t nallocdata=0, size_t nallocsref=0);
+  static void PrintDebug();
+
+  // Creation / destruction 
+  NDataBlock(size_t n);
+  NDataBlock(size_t n, T* data, Bridge* br=NULL);
+  NDataBlock();
+  NDataBlock(const NDataBlock<T>& a);
+  NDataBlock(const NDataBlock<T>& a,bool share);
+  virtual ~NDataBlock();
+
+  // Temporaire?
+  //! Return true if data block is temporay
+  inline bool IsTemp(void) const {return mIsTemp;}
+  //! Set temporary caracter of data block
+  inline void SetTemp(bool temp=false) const {mIsTemp = temp;}
+  // Depuis que le createur par copie partage les donnees
+  // la seule utilisation de SetTemp et pour faire les operations du type:
+  // NDataBlock = NDataBlock + NDataBlock + NDataBlock ...
+
+  // Gestion taille/Remplissage
+  void Clone(const NDataBlock<T>& a);
+  void CloneOrShare(const NDataBlock<T>& a);
+  void Share(const NDataBlock<T>& a);
+  void FillFrom(size_t n,T* data);
+  //! Re-set all data values to \b v
+  inline void Reset(T v=0)
+         {if(mSz==0) return; T *p=Begin(),*pe=End(); while(p<pe) *p++=v;}
+
+  // ReSize redimmensionne une structure pour "n" donnees.
+  // Les donnees precedentes sont perdues (pour cette classe)
+  // et le nouveau tableau mis a zero. La nouvelle structure de
+  // donnees n'a qu'une reference (celle de cette classe).
+  //! Re-size the data structure
+  /*! Old datas are lost (for this class). The new values are set to zero.
+    The new data structure has only one reference (itself!). */
+  inline void ReSize(size_t n) {Alloc(n);}
+
+  void Realloc(size_t nnew,bool force=false);
+  
+  // Informations pointeur/data
+  //! Return pointer on data structure.
+  inline T* Data()
+         {if(mSRef) return mSRef->data; else return NULL;}
+  //! Return pointer on data structure.
+  inline T* Data() const
+         {if(mSRef) return mSRef->data; else return NULL;}
+  //! Return the size of the data structure
+  inline size_t Size() const    {return mSz;}
+  //! Return the \b i th element of  the data structure
+  inline T& operator()(size_t i)       {return *(mSRef->data+i);}
+  //! Return the \b i th element of  the data structure
+  inline T  operator()(size_t i) const {return *(mSRef->data+i);}
+  //! Return pointer to the beginning of the data structure.
+  inline T*        Begin()        {return mSRef->data;}
+  //! Return pointer to the beginning of the data structure.
+  inline T const*  Begin() const  {return mSRef->data;} 
+  //! Return pointer to the end of the data structure.
+  inline T*        End()          {return mSRef->data+mSz;}
+  //! Return pointer to the end of the data structure.
+  inline T const*  End() const    {return mSRef->data+mSz;}
+  //! Return the number of references to the data structure
+  inline size_t NRef() const {if(mSRef) return 0; else return mSRef->nref;}
+
+  // Impression
+  void Print(ostream& os, size_t i1=0,size_t n=10) const;
+  //! print infos and datas (from \b i1 to \b i2) on stdout.
+  inline void Print(size_t i1=0,size_t n=0) const {Print(cout,i1,n);}
+
+  //
+  T Sum(size_t i1=0,size_t n=0) const;
+  T Product(size_t i1=0,size_t n=0) const;
+
+  // Surcharge d'operateurs INPLACE: A = x , A = B , A @= x , A @= B
+  NDataBlock<T>& operator = (const NDataBlock<T>& a);
+  NDataBlock<T>& operator = (T v);
+
+  NDataBlock<T>& operator += (T b);
+  NDataBlock<T>& operator -= (T b);
+  NDataBlock<T>& operator *= (T b);
+  NDataBlock<T>& operator /= (T b);
+
+  NDataBlock<T>& operator += (const NDataBlock<T>& a);
+  NDataBlock<T>& operator -= (const NDataBlock<T>& a);
+  NDataBlock<T>& operator *= (const NDataBlock<T>& a);
+  NDataBlock<T>& operator /= (const NDataBlock<T>& a);
+
+  // Surcharge d'operateurs: C = A @ x , C = A @ B
+  NDataBlock<T> Add(T b) const;
+  NDataBlock<T> Sub(T b,bool fginv=false) const;
+  NDataBlock<T> Mul(T b) const;
+  NDataBlock<T> Div(T b,bool fginv=false) const;
+
+  NDataBlock<T> Add(const NDataBlock<T>& b) const;
+  NDataBlock<T> Sub(const NDataBlock<T>& b) const;
+  NDataBlock<T> Mul(const NDataBlock<T>& b) const;
+  NDataBlock<T> Div(const NDataBlock<T>& b) const;
+
+  inline uint_8 DRefId() { return mSRef->dsid; }
+
+protected:
+  //! NDREF structure for reference management
+  typedef struct {
+    size_t nref;      //!< Number of references to the data structure
+    uint_8 dsid;      //!< Data structure Id - Used by FIO_NDataBlock
+    T* data;          //!< Pointer to data structure itself
+    Bridge* bridge;   //!< Pointer to a bridge for the data structure
+  } NDREF;
+
+  void Alloc(size_t n,T* data=NULL,Bridge* br=NULL, bool zero=true);
+  void Delete(void);
+
+  static int Debug_NDataBlock; //!< DEBUG: set debug level (all type<T> classes)
+  static size_t NallocData; //!< DEBUG: number of allocations (all type<T> classes)
+  static size_t NallocSRef; //!< DEBUG: number of references (all type<T> classes)
+
+  size_t       mSz;      //!< size of data structure
+  NDREF*       mSRef;    //!< NDREF structure for reference management
+  mutable bool mIsTemp;  //!< true if class is temporary
+};
+
+//! Define operator \<\< for printing
+template<class T>
+inline ostream& operator << (ostream& os, const NDataBlock<T>& a)
+                      {a.Print(os); return(os);}
+
+//! Add a constant to datas and return NDataBlock : ND = NDa + b
+template<class T>
+inline NDataBlock<T> operator + (const NDataBlock<T>& a,T b)
+                      {return a.Add(b);}
+//! Add a constant to datas and return NDataBlock : ND = b + NDa
+template<class T>
+inline NDataBlock<T> operator + (T b,const NDataBlock<T>& a)
+                      {return a.Add(b);}
+//! Substract a constant to datas and return NDataBlock : ND = NDa - b
+template<class T>
+inline NDataBlock<T> operator - (const NDataBlock<T>& a,T b)
+                      {return a.Sub(b);}
+//! Substract a constant to datas and return NDataBlock : ND = b - NDa
+template<class T>
+inline NDataBlock<T> operator - (T b,const NDataBlock<T>& a)
+                      {return a.Sub(b,true);}
+//! Multiply datas by a constant and return NDataBlock : ND = NDa * b
+template<class T>
+inline NDataBlock<T> operator * (const NDataBlock<T>& a,T b)
+                      {return a.Mul(b);}
+//! Multiply datas by a constant and return NDataBlock : ND = b * NDa
+template<class T>
+inline NDataBlock<T> operator * (T b,const NDataBlock<T>& a)
+                      {return a.Mul(b);}
+//! Divide datas by a constant and return NDataBlock : ND = NDa / b
+template<class T>
+inline NDataBlock<T> operator / (const NDataBlock<T>& a,T b)
+                      {return a.Div(b);}
+//! Divide a constant by datas and return NDataBlock : ND = b / NDa
+template<class T>
+inline NDataBlock<T> operator / (T b,const NDataBlock<T>& a)
+                      {return a.Div(b,true);}
+
+//! Add datas of two data blocks and return NDataBlock : ND = NDa + NDb
+template<class T>
+inline NDataBlock<T> operator + (const NDataBlock<T>& a,const NDataBlock<T>& b)
+                      {return a.Add(b);}
+//! Substract datas of two data blocks and return NDataBlock : ND = NDa - NDb
+template<class T>
+inline NDataBlock<T> operator - (const NDataBlock<T>& a,const NDataBlock<T>& b)
+                      {return a.Sub(b);}
+//! Multiply datas of two data blocks and return NDataBlock : ND = NDa * NDb
+template<class T>
+inline NDataBlock<T> operator * (const NDataBlock<T>& a,const NDataBlock<T>& b)
+                      {return a.Mul(b);}
+//! Divide datas of two data blocks and return NDataBlock : ND = NDa / NDb
+template<class T>
+inline NDataBlock<T> operator / (const NDataBlock<T>& a,const NDataBlock<T>& b)
+                      {return a.Div(b);}
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/BaseTools/objfio.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/objfio.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/objfio.h	(revision 2309)
@@ -0,0 +1,64 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe de gestion des I/O fichiers des objets 
+//                          R.Ansari          04/99
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef OBJFILEIO_H_SEEN
+#define OBJFILEIO_H_SEEN
+
+#include "machdefs.h"
+#include <stdio.h>
+#include "anydataobj.h"
+#include "ppersist.h"
+
+namespace SOPHYA {
+
+
+template <class T>
+class ObjFileIO : public PPersist {
+
+public :
+	    ObjFileIO() { dobj=new T; ownobj=true; }
+	    ObjFileIO(string const & filename) 
+                        { dobj=new T; ownobj=true; Read(filename); }
+	    ObjFileIO(const T & obj) { dobj = new T(obj); ownobj=true; }
+	    ObjFileIO(T * obj) { dobj = obj; ownobj=false; }
+  virtual   ~ObjFileIO() { if (ownobj && dobj) delete dobj; }
+
+  virtual   AnyDataObj* DataObj() { return(dobj); }
+  virtual   void        SetDataObj(AnyDataObj & o) 
+  {  
+    T * po = dynamic_cast< T * >(& o); 
+    if (po == NULL)  {
+      char buff[160];
+      sprintf(buff,"ObjFileIO<T>::SetDataObj(%s) - Object type  error ! ",
+	      typeid(o).name());
+      throw TypeMismatchExc(PExcLongMessage(buff));    
+    }
+    if (ownobj && dobj) delete dobj;  dobj = po; ownobj = false; 
+  }    
+  
+  inline operator T() { return(*dobj); }
+
+protected :
+  virtual void       ReadSelf(PInPersist&);           
+  virtual void       WriteSelf(POutPersist&) const;  
+
+  T * dobj;
+  bool ownobj;       // True si dobj obtenu par new
+};
+
+/*
+template <class T>
+inline POutPersist& operator << (POutPersist& os, T const & obj)
+{ ObjFileIO<T> fio((const_cast)&obj);  fio.Write(os);  return(os); } 
+
+template <class T>
+inline PInPersist& operator >> (PInPersist& is, T & obj)
+{ ObjFileIO<T> fio(&obj);  fio.Read(is);  return(is); }  
+*/
+
+
+} // Fin namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/BaseTools/objlist.list
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/objlist.list	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/objlist.list	(revision 2309)
@@ -0,0 +1,10 @@
+datatype.o
+dvlist.o
+fiondblock.o
+gnumd5.o
+mutyv.o
+ndatablock.o
+pexceptions.o
+ppersist.o
+sophyainit.o
+srandgen.o
Index: /tags/V_Dec2002/SophyaLib/BaseTools/osx_values.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/osx_values.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/osx_values.h	(revision 2309)
@@ -0,0 +1,23 @@
+#ifndef OSX_VALUES_H
+#define OSX_VALUES_H
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+
+#define BITSPERBYTE     8
+#define BITS(type)      (BITSPERBYTE * (long)sizeof (type))
+#define MAXDOUBLE       1.79769313486231570e+308
+#define MINDOUBLE       4.94065645841246544e-324
+#define _IEEE           1
+#define _DEXPLEN        11
+#define _HIDDENBIT      1
+#define DMINEXP (-(DMAXEXP + DSIGNIF - _HIDDENBIT - 3))
+#define DSIGNIF (BITS(double) - _DEXPLEN + _HIDDENBIT - 1)
+#define DMAXEXP ((1 << _DEXPLEN - 1) - 1 + _IEEE)
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/BaseTools/perrors.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/perrors.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/perrors.h	(revision 2309)
@@ -0,0 +1,1 @@
+#include "pexceptions.h"
Index: /tags/V_Dec2002/SophyaLib/BaseTools/pexceptions.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/pexceptions.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/pexceptions.cc	(revision 2309)
@@ -0,0 +1,33 @@
+#include "pexceptions.h"
+#include <iostream.h>
+#include <stdio.h>
+
+void PFailHandler(void); 
+
+// egcs ne semble pas connaitre set_new_handler (Reza 26/04/99)
+#ifdef __GNUG__
+void PFailHandler(void) {}
+void InitFailNewHandler() {}
+#else
+
+void PFailHandler(void)
+{
+  set_new_handler(NULL);
+  cerr << "Allocation exception -- out of memory" << endl;
+  throw(AllocationError("new"));
+}
+
+void InitFailNewHandler()
+{
+   set_new_handler(PFailHandler);
+}
+#endif
+
+string SOPHYA::BuildLongExceptionMessage(const char * s, const char *file, int line)
+{
+  char buff[32];
+  sprintf(buff," Line=%d", line);
+  string rs=s;
+  rs += " File="; rs += file; rs += buff;
+  return(rs);
+}
Index: /tags/V_Dec2002/SophyaLib/BaseTools/pexceptions.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/pexceptions.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/pexceptions.h	(revision 2309)
@@ -0,0 +1,243 @@
+// This may look like C code, but it is really -*- C++ -*-
+#ifndef PEXCEPTIONS_SEEN
+#define PEXCEPTIONS_SEEN
+
+#include "machdefs.h"
+#include <string>
+
+using namespace std;
+
+// Petit utilitaire pour accoler numero de ligne et nom de fichier aux messages
+// d'exception
+#define PExcLongMessage(a) BuildLongExceptionMessage(a,__FILE__,__LINE__)
+
+namespace SOPHYA {
+
+//! Utility function for appending a file name and line number to a message
+  string BuildLongExceptionMessage(const char * s, const char *file, int line);
+
+/*! \ingroup BaseTools
+    \brief Base exception class in Sophya
+
+    Ancestor for PError and PException
+    It has a message, and an id to give more
+    information on the exception.
+*/
+  class PThrowable {
+  public:
+    //! Constructor with the message and error-id (optional) specification
+    explicit PThrowable(const string& m, int ident=0) 
+      : msg(m), id(ident) {}
+    virtual ~PThrowable() { }
+    //! Returns the associated message string
+    virtual string const& Msg() const  {return msg;}
+    //! Returns the associated error-id
+    virtual int Id() const {return id; }
+  private:
+    string msg;
+    int    id;
+  };
+
+//  PThrowable
+//      PError
+//      PException
+  
+/*! \ingroup BaseTools 
+    \brief A PError is a serious logic error. Usually not caught... */
+  class PError : public PThrowable {
+  public:
+    explicit PError(const string& m, int id=0) : PThrowable(m,id) {}
+  };
+  
+/*! \ingroup BaseTools 
+    \brief A PException is not as serious... Can be caught. */
+  class PException : public PThrowable {
+  public:
+    explicit PException(const string& m, int id=0) : PThrowable(m,id) {}
+  };
+  
+//  ----   Errors ----
+//  PError
+//     AllocationError
+//     NullPtrError
+//     ForbiddenError
+//     AssertionFailedError
+
+/*! \ingroup BaseTools 
+    \brief Memory allocation failure */
+  class AllocationError : public PError {
+  public:
+    explicit AllocationError(const string& m, int id=0) : PError(m,id) {}
+  };
+  
+/*! \ingroup BaseTools 
+    \brief Null pointer error */
+  class NullPtrError : public PError {
+  public:
+    explicit NullPtrError(const string& m, int id=0) : PError(m,id) {}
+  };
+  
+  
+/*! \ingroup BaseTools 
+    \brief Calling a forbidden method, trying a forbidden operation */
+  class ForbiddenError : public PError {
+  public:
+    explicit ForbiddenError(const string& m, int id=0) : PError(m,id) {}
+  };
+
+  
+/*! \ingroup BaseTools 
+    \brief ASSERT macro failure. The message is the assertion... */
+  class AssertionFailedError : public PError {
+  public:
+    explicit AssertionFailedError(const string& m, int id=0) : PError(m,id) {}
+  };
+  
+  // Standard exceptions
+  //
+  // PException
+  //   IOExc
+  //     FileFormatExc
+  //   SzMismatchError
+  //   RangeCheckError
+  //   ParmError
+  //   TypeMismatchExc
+  //   MathExc
+  //     SingMatxExc
+  //   DuplicateIdExc
+  //   NotFoundExc
+  //   CaughtSignalExc
+  
+/*! \ingroup BaseTools 
+    \brief Generic IO Exception */
+  class IOExc : public PException {
+  public:
+    explicit IOExc(const string& m, int id=0) : PException(m,id) {}
+  };
+
+/*! \ingroup BaseTools 
+    \brief Bad file format */
+  class FileFormatExc : public IOExc {
+  public:
+    explicit FileFormatExc(const string& m, int id=0) : IOExc(m,id) {}
+  };
+
+/*! \ingroup BaseTools 
+    \brief Size mismatch between objects */
+  class SzMismatchError : public PException {
+  public:
+    explicit SzMismatchError(const string& m, int id=0) : PException(m,id) {}
+  };
+  
+/*! \ingroup BaseTools 
+    \brief Out of bounds for array, matrix, etc */
+  class RangeCheckError : public PException {
+  public:
+    explicit RangeCheckError(const string& m, int id=0) : PException(m,id) {}
+  };
+  
+/*! \ingroup BaseTools 
+    \brief Invalid parameter to method/constructor... */
+  class ParmError : public PException {
+  public:
+    explicit ParmError(const string& m, int id=0) : PException(m,id) {}
+  };
+
+/*! \ingroup BaseTools 
+    \brief Calling a non available / not implemented method */
+  class NotAvailableOperation : public PException {
+  public:
+    explicit NotAvailableOperation(const string& m, int id=0) : PException(m,id) {}
+  };
+
+/*! \ingroup BaseTools 
+    \brief Bad data type -> keep ? */
+  class TypeMismatchExc : public PException {
+  public:
+    explicit TypeMismatchExc(const string& m, int id=0) : PException(m,id) {}
+  };
+
+/*! \ingroup BaseTools 
+    \brief Math operation exception */
+  class MathExc : public PException {
+  public:
+    explicit MathExc(const string& m, int id=0) : PException(m,id) {}
+  };
+  
+/*! \ingroup BaseTools 
+    \brief Singular matrix  */
+  class SingMatrixExc : public MathExc {
+  public:
+    explicit SingMatrixExc(const string& m, int id=0) : MathExc(m,id) {}
+  };
+
+/*! \ingroup BaseTools 
+    \brief Duplicate identifier during registration */
+  class DuplicateIdExc : public PException {
+  public:
+    explicit DuplicateIdExc(const string& m, int id=0) : PException(m,id) {}
+  };
+  
+/*! \ingroup BaseTools 
+    \brief Not found identifier  */
+  class NotFoundExc : public PException {
+  public:
+    explicit NotFoundExc(const string& m, int id=0) : PException(m,id) {}
+  };
+  
+/*! \ingroup BaseTools 
+    \brief Generated exception when processing a signal */
+  class CaughtSignalExc : public PException {
+  public:
+    explicit CaughtSignalExc(const string& m, int id=0) : PException(m,id) {}
+  };
+    
+} // namespace SOPHYA
+
+
+#define ASSERT(_a_) if (!(_a_)) { \
+     cerr << "Assertion failed " #_a_ " file " __FILE__ " line " << __LINE__ \
+          << endl; \
+		     throw(AssertionFailedError(#_a_)); }
+   
+#define FAILNIL(_x_) \
+       {if (!(_x_)) throw(NullPtrError(#_x_))}
+
+void InitFailNewHandler();
+  
+     
+// Compatibility with EROS-PEIDA exceptions
+
+#define EXC_ABORT_NEG(_x)
+#define EXC_ABORT_ALL(_x)
+
+
+#define END_CONSTRUCTOR
+
+#define TRY try
+#define CATCH(_var) catch(long _var)
+#define CATCHALL catch(...)
+#define ENDTRY
+
+#define THROW(_i) throw( _i);
+
+#define THROW_ THROW(0)
+
+#define THROW_SAME throw;
+
+#define RETURN(x) return(x)
+#define RETURN_ return
+
+#define rangeCheckErr    RangeCheckError("")
+#define typeMismatchErr  TypeMismatchExc("")
+#define allocationErr    AllocationError("")
+#define parmErr          ParmError("")
+#define inconsistentErr  ParmError("")
+#define sizeMismatchErr  SzMismatchError("")
+#define fileErr          IOExc("")
+#define nullPtrErr       NullPtrError("")
+#define singMatxErr      SingMatrixExc("")
+
+#define DBASSERT(_x_) ASSERT(_x_)
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/BaseTools/piocmplx.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/piocmplx.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/piocmplx.h	(revision 2309)
@@ -0,0 +1,154 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Fonctions d'ecriture de tableaux numeriques
+#ifndef PIOCMPLX_H_SEEN
+#define PIOCMPLX_H_SEEN
+
+/*
+// Pour gerer les Persist I/O de tableaux numerique templates
+template <class T>
+void PIOSReadArray(PInPersist & is, T* arr, size_t n);
+template <class T>
+void PIOSWriteArray(POutPersist & os, T const * arr, size_t n);
+*/
+
+// Pour pouvoir ecrire des tableau de complex, en attendant 
+// PIn/POutPersist::Get/Put(complex<>)
+
+inline
+void PIOSReadArray(PInPersist & is, uint_1 * arr, size_t n)
+{
+is.GetBytes(arr, n);
+}
+
+inline
+void PIOSReadArray(PInPersist & is, uint_2 * arr, size_t n)
+{
+is.Get(arr, n);
+}
+
+inline
+void PIOSReadArray(PInPersist & is, int_2 * arr, size_t n)
+{
+is.Get(arr, n);
+}
+
+inline
+void PIOSReadArray(PInPersist & is, uint_4 * arr, size_t n)
+{
+is.Get(arr, n);
+}
+
+inline
+void PIOSReadArray(PInPersist & is, int_4 * arr, size_t n)
+{
+is.Get(arr, n);
+}
+
+inline
+void PIOSReadArray(PInPersist & is, uint_8 * arr, size_t n)
+{
+is.Get(arr, n);
+}
+
+inline
+void PIOSReadArray(PInPersist & is, int_8 * arr, size_t n)
+{
+is.Get(arr, n);
+}
+
+inline
+void PIOSReadArray(PInPersist & is, r_4 * arr, size_t n)
+{
+is.Get(arr, n);
+}
+
+inline
+void PIOSReadArray(PInPersist & is, r_8 * arr, size_t n)
+{
+is.Get(arr, n);
+}
+
+inline
+void PIOSReadArray(PInPersist & is, complex<float> * arr, size_t n)
+{
+r_4 * pr = (r_4 *)arr;
+is.Get(pr, n*2);
+}
+
+inline
+void PIOSReadArray(PInPersist & is, complex<double> * arr, size_t n)
+{
+r_8 * pr = (r_8 *)arr;
+is.Get(pr, n*2);
+}
+
+// Fonctions d ecriture de tableaux de nombre
+inline
+void PIOSWriteArray(POutPersist & os, uint_1 const * arr, size_t n)
+{
+os.PutBytes(arr, n);
+}
+
+inline
+void PIOSWriteArray(POutPersist & os, uint_2 const * arr, size_t n)
+{
+os.Put(arr, n);
+}
+
+inline
+void PIOSWriteArray(POutPersist & os, int_2 const * arr, size_t n)
+{
+os.Put(arr, n);
+}
+
+inline
+void PIOSWriteArray(POutPersist & os, uint_4 const * arr, size_t n)
+{
+os.Put(arr, n);
+}
+
+inline
+void PIOSWriteArray(POutPersist & os, int_4 const * arr, size_t n)
+{
+os.Put(arr, n);
+}
+
+inline
+void PIOSWriteArray(POutPersist & os, uint_8 const * arr, size_t n)
+{
+os.Put(arr, n);
+}
+
+inline
+void PIOSWriteArray(POutPersist & os, int_8 const * arr, size_t n)
+{
+os.Put(arr, n);
+}
+
+inline
+void PIOSWriteArray(POutPersist & os, r_4 const * arr, size_t n)
+{
+os.Put(arr, n);
+}
+
+inline
+void PIOSWriteArray(POutPersist & os, r_8 const * arr, size_t n)
+{
+os.Put(arr, n);
+}
+
+inline
+void PIOSWriteArray(POutPersist & os, complex<float> const * arr, size_t n)
+{
+r_4 const * pr = (r_4 const *)arr;
+os.Put(pr, n*2);
+}
+
+inline
+void PIOSWriteArray(POutPersist & os, complex<double> const * arr, size_t n)
+{
+r_8 const * pr = (r_8 const *)arr;
+os.Put(pr, n*2);
+}
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/BaseTools/ppersist.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/ppersist.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/ppersist.cc	(revision 2309)
@@ -0,0 +1,1741 @@
+#include "machdefs.h"
+#include <stdio.h>
+#include <sys/types.h>
+#include <time.h>
+#include "pexceptions.h"
+#include "ppersist.h"
+#include "anydataobj.h"
+#include <fstream.h>
+#include <iostream.h>
+#include <typeinfo>
+
+
+#ifdef __mac__
+#include "unixmac.h"
+#include <SIOUX.h>
+#endif
+
+//  strptime n'est pas defini sous Linux  - Reza Mars 2000
+#if defined(OS_LINUX) || defined(OS_MACOSX)
+extern "C" {
+char *strptime(const char *buf, const char *format, struct tm *tm);
+}
+#endif
+
+#define MAXTAGLEN 255
+
+//++
+// Class	PIOPersist
+// Lib		Outils++
+// include	ppersist.h
+//
+//	Root class for persistant files. Handles the registration of
+//	persistant classes
+//--
+
+//++
+// Links	See
+// PPersist
+// PInPersist
+// POutPersist
+//--
+
+
+MD5_CONTEXT PIOPersist::ctx;
+PIOPersist::ClassList * PIOPersist::ppclassList = NULL;   // $CHECK$ Reza 26/04/99
+map<string, uint_8> * PIOPersist::ppclassNameList = NULL;
+map<string, uint_8> * PIOPersist::dobjclassNameList = NULL;
+
+//++
+void
+PIOPersist::Initialize()
+//  Initialisation globale (objets statiques) $CHECK$ Reza 26/04/99
+//--
+{
+ppclassList = new PIOPersist::ClassList;
+ppclassNameList = new map<string, uint_8>;
+dobjclassNameList = new map<string, uint_8>;
+cout << " PIOPersist::Initialize() Starting Sophya Persistence management service " << endl;
+}
+
+//++
+void
+PIOPersist::RegisterPPHandlerClass(uint_8 classId, string ppclass_name, ClassCreatorFunc f)
+//
+//	Register a new persistence handler (PPersist) class.
+//	The classId is usually a hash of the class name, and
+//	ppclass_name is typeid(PPersistClass).name() .
+//	This method is called only through the PPersistRegistrar template
+//
+//--
+{
+  if (ppclassList->size() && (ppclassList->find(classId) != ppclassList->end()) ) {
+    cerr << "RegisterClass : Error, " << hex << classId << dec 
+	 << " already registered." << endl;
+    throw(DuplicateIdExc("PIOPersist::RegisterPPHandlerClass() Already registered (1)"));
+  }
+  if (ppclassNameList->size() && (ppclassNameList->find(ppclass_name) != ppclassNameList->end())) {
+    cerr << "RegisterClass : Error (2) " <<  ppclass_name 
+	 << " already registered." << endl;
+      throw(DuplicateIdExc("PIOPersist::RegisterPPHandlerClass() Already registered(2)"));
+    }
+  
+  (*ppclassList)[classId] = f;
+  (*ppclassNameList)[ppclass_name]  = classId;
+}
+
+//++
+void
+PIOPersist::RegisterDataObjClass(uint_8 classId, string class_name)
+//	Register a new DataObj class corresponding to a PPersist classId
+//	class_typename should be typeid(DataObject).name() 
+//--
+{
+  if (ppclassList->find(classId) == ppclassList->end() ) {
+    cerr << "PIOPersist::RegisterDataObjClass() Error (1) " 
+	 << hex << classId << dec << " Not Found !" << endl;
+    throw( NotFoundExc("PIOPersist::RegisterDataObjClass() Not found classId ") );
+  }
+  if (dobjclassNameList->size() && (dobjclassNameList->find(class_name) != dobjclassNameList->end())) {
+    cerr << "PIOPersist::RegisterDataObjClass() Error (2)" << class_name 
+	 << " already registered." << endl;
+      throw(DuplicateIdExc("PIOPersist::RegisterDataObjClass() - Already registered"));
+  }
+
+  (*dobjclassNameList)[class_name]  = classId;
+}
+
+//	class_typename should be typeid(DataObject).name(), to be 
+//	used by POutPersist::PutDataObject() methods.
+
+PIOPersist::ClassCreatorFunc
+PIOPersist::FindCreatorFunc(uint_8 classId)
+// Returns the PPersist class creator function for the specified classId
+{
+  ClassList::iterator i = ppclassList->find(classId);
+  if (i == ppclassList->end()) throw(NotFoundExc("PIOPersist::FindCreatorFunc() Not found classId"));
+  return (*i).second;
+}
+
+string 
+PIOPersist::getPPClassName(uint_8 classId)
+// Returns the PPersist class name for the specified classId
+{
+  map<string, uint_8>::iterator i;
+  for (i= ppclassNameList->begin(); i != ppclassNameList->end(); i++)
+    if ( (*i).second == classId ) return (*i).first;
+
+  throw(NotFoundExc("PIOPersist::getPPClassName() Not found classId"));
+}
+
+uint_8
+PIOPersist::getPPClassId(string const & typ_name)
+// Returns the classId for the specified PPersist class type name
+{
+  map<string, uint_8>::iterator i = ppclassNameList->find(typ_name);
+  if (i == ppclassNameList->end()) 
+    throw(NotFoundExc("PIOPersist::getPPClassId() Not found className"));
+  return (*i).second;
+}
+
+uint_8
+PIOPersist::getPPClassId(PPersist const & ppo)
+// Returns the classId for the specified PPersist class 
+{
+  string typ_name = typeid(ppo).name() ;
+  return (getPPClassId(typ_name) );
+}
+
+
+string 
+PIOPersist::getDataObjClassName(uint_8 classId)
+// Returns the PPersist class name for the specified classId
+{
+  map<string, uint_8>::iterator i;
+  for (i= dobjclassNameList->begin(); i != dobjclassNameList->end(); i++)
+    if ( (*i).second == classId ) return (*i).first;
+
+  throw(NotFoundExc("PIOPersist::getDataObjClassName() Not found classId"));
+}
+
+uint_8
+PIOPersist::getDataObjClassId(string const & typ_name)
+// Returns the classId for the specified PPersist class type name
+{
+  map<string, uint_8>::iterator i = dobjclassNameList->find(typ_name);
+  if (i == dobjclassNameList->end()) 
+    throw(NotFoundExc("PIOPersist::getDataObjClassId() Not found className"));
+  return (*i).second;
+}
+
+uint_8
+PIOPersist::getDataObjClassId(AnyDataObj const & o)
+// Returns the classId for the specified PPersist class 
+{
+  string typ_name = typeid(o).name() ;
+  return (getDataObjClassId(typ_name) );
+}
+
+
+static inline void bswap8(void* p)
+{
+  uint_8 tmp = *(uint_8*)p;
+  *(uint_8*)p = ((tmp >> (7*8)) & 0x000000FF) | 
+                ((tmp >> (5*8)) & 0x0000FF00) |
+                ((tmp >> (3*8)) & 0x00FF0000) |
+                ((tmp >> (1*8)) & 0xFF000000) |
+                ((tmp & 0xFF000000) << (1*8))  |
+                ((tmp & 0x00FF0000) << (3*8))  |
+                ((tmp & 0x0000FF00) << (5*8))  |
+                ((tmp & 0x000000FF) << (7*8));
+}
+
+static inline void bswap4(void* p)
+{
+  uint_4 tmp = *(uint_4*)p;
+  *(uint_4*)p = ((tmp >> 24) & 0x000000FF) | 
+                ((tmp >> 8)  & 0x0000FF00) |
+                ((tmp & 0x0000FF00) << 8)  |
+                ((tmp & 0x000000FF) << 24);
+}
+
+static inline void bswap2(void* p)
+{
+  uint_2 tmp = *(uint_2*)p;
+  *(uint_2*)p = ((tmp >> 8) & 0x00FF) | 
+                ((tmp & 0x00FF) << 8);
+}
+
+
+uint_8 PIOPersist::Hash(string const& typname) { 
+        md5_init(&ctx); 
+        md5_write(&ctx, (unsigned char*) typname.c_str(), typname.size()); 
+        md5_final(&ctx); 
+	uint_8 hash1 =   *((uint_8*) ctx.buf);
+	uint_8 hash2 =   *((uint_8*) (ctx.buf+8));
+#if IS_BIG_ENDIAN
+	bswap8(&hash1);
+	bswap8(&hash2);
+#endif
+	
+        return (hash1+hash2);
+}
+
+
+//++
+// Class	PPersist
+// Lib		Outils++
+// include	ppersist.h
+//
+//	Classe de base pour des objets persistants. Pour créer un objet
+//	persistant :
+//	- Hériter de PPersist.
+//	- Définir un numéro d'identification de la classe, unique dans Peida
+//	- Implémenter "ClassId()"
+//	- Implémenter "WriteSelf" et "ReadSelf", qui doivent écrire toutes les variables
+//	  membres que l'on souhaite écrire, et les relire dans le même ordre.
+//	  Pour écrire une référence à un objet : l'objet doit être un PPersist,
+//	  et il suffit d'appeler "Write" sur cet objet, et "PPersistMgr::ReadObject".
+//	  Si plusieurs objets font référence au même, pour éviter de l'écrire plusieurs
+//	  fois, il faut que cet objet soit un PShPersist.
+//	- Pour que le fichier soit portable, écrire et lire les variables membres en utilisant
+//	  les fonctions PutXX/GetXX de PInPersist/POutPersist.
+//
+//	Attention: les méthodes à redéfinir sont WriteSelf et ReadSelf, mais il ne faut jamais
+//	les appeler directement. Seuls Write et Read peuvent être appelées par l'utilisateur.
+//--
+
+//++
+// Links	See
+// PInPersist
+// POutPersist
+// PIOPersist
+//--
+  
+//++
+void
+PPersist::Write(string const& fn) const
+//
+//	Ecrit l'objet dans un nouveau fichier ppersist "fn".
+//--
+{
+  POutPersist of(fn);
+  Write(of);
+}
+
+//++
+void
+PPersist::Read(string const& fn) 
+//
+//	Relit l'objet dans le fichier ppersist "fn". Il faut connaître a priori
+//	le type de l'objet. Pour une relecture avec création automatique du bon
+//	objet, utiliser PPersistMgr::ReadObject.
+//--
+{
+  PInPersist inf(fn);
+  Read(inf);
+}
+
+//++
+void
+PPersist::Write(POutPersist& s) const
+//
+//	Ecrit l'objet dans le fichier PPersist.
+//--
+{
+   s.PutPPObject(this);
+}
+
+
+//++
+void
+PPersist::Read(PInPersist& s)
+//
+//	Relit l'objet dans le fichier ppersist. Il faut connaître a priori
+//	le type de l'objet. Pour une relecture avec création automatique du bon
+//	objet, utiliser PInPersist::ReadObject.
+//  Il faut qu'on soit un objet ecrit 
+//--
+{
+  // We should be the exact type  
+  // Check tag value
+  unsigned char ppstype,ppstag;
+  s.GetTypeTag(ppstype);
+  if ( (ppstype != PInPersist::PPS_OBJECT) && ( ppstype != PInPersist::PPS_REFERENCE ) ) {
+  }
+  if (ppstype == PInPersist::PPS_OBJECT) {
+    // Check class id
+    uint_8 classId;
+    s.GetRawU8(classId);
+    uint_8 oid,oid2;
+    s.GetRawU8(oid);
+    if (classId != PIOPersist::getPPClassId(*this) )
+      throw FileFormatExc("PPersist::Read (): not the same object type");  
+    ReadSelf(s);
+    // Read the ENDOBJECT 
+    s.GetRawUByte(ppstag);
+    if (ppstag != PInPersist::PPS_ENDOBJECT)
+      throw FileFormatExc("PPersist::Read() No PPS_ENDOBJECT tag");
+    s.GetRawU8(oid2);
+    if (oid2 != oid)
+      throw FileFormatExc("PPersist::Read() Inconsistent PPS-OId at PPS_ENDOBJECT ");
+    s.KeepOId(oid, *this);   // Object should be kept with its PPS_OId  (if oid > 0)
+  }
+  else if ( ppstype == PInPersist::PPS_REFERENCE ) 
+    s.ReadReference(*this);
+
+  else  throw FileFormatExc("PPersist::Read() : not an object in flow");
+
+}
+
+//++
+void
+PPersist::Write(POutPersist& s, string const& tag) const
+//
+//	Ecrit l'objet dans le fichier PPersist avec un tag 
+//--
+{
+  s.WriteTag(tag);
+  s.PutPPObject(this);
+}
+
+//++
+void
+PPersist::ReadAtTag(PInPersist& s, string const& tag)
+//
+//	Lit l'objet à la position du tag numéro "tagid".
+//--
+{
+  if (!s.GotoTag(tag))
+    throw NotFoundExc("PPersist::ReadAtTag  tag not found");
+  Read(s);
+}
+
+// Renvoie l'identificateur de l'objet  - par defaut=0
+
+uint_8 
+PPersist::getMemOId() const
+{
+  return(0);
+}
+
+// Ces deux methodes doivent etre redefinies si   getMemOId() renvoie non nul (>0)
+// ShareDataReference() et CloneSharedReference()
+void 
+PPersist::ShareDataReference(PPersist & pcs)
+{
+  throw NotAvailableOperation("PPersist::ShareDataReference() - Unsupported operation !");
+}
+
+PPersist *
+PPersist::CloneSharedReference()
+{
+  throw NotAvailableOperation("PPersist::CloneSharedReference() - Unsupported operation !");
+}
+
+//++
+//  virtual void PPersist::ReadSelf(PInPersist&)=0
+//	Méthode virtuelle pure à redéfinir. Elle est appelée par Read
+//	et PPersistMgr::ReadObject. Il faut relire les variables membres,
+//	dans l'ordre où elles ont été écrites par WriteSelf.
+//  virtual void PPersist::WriteSelf(POutPersist&) const=0
+//	Méthode virtuelle pure à redéfinir. Elle est appelée par Write.
+//	Il faut écrire les variables membres,
+//	dans l'ordre où elles seront relues par ReadSelf.
+//--
+
+
+
+//++
+// Class	PInPersist
+// Lib		Outils++
+// include	ppersist.h
+//
+//	Fichier d'objets persistants, en lecture.
+//--
+
+//++
+PInPersist::PInPersist(string const& flnm, bool scan)
+//
+//	Constructeur. Ouvre le fichier.
+//--
+{
+  s = new ifstream(flnm.c_str(),ios::in | IOS_BIN); 
+
+  // Read and check header
+
+  char rbuf[36];
+  GetRawBytes(rbuf, 32);
+  if (strncmp(rbuf,"SOS-SOPHYA-PPersistFile", 23) != 0)  {
+    throw FileFormatExc("PInPersist::PInPersist  bad header");
+  }
+  rbuf[32] = '\0';
+  version = atoi(rbuf+25);
+  if (version < 2) {
+    cerr << "PInPersist::PInPersist(" << flnm << ") Version(=" << version 
+	 << ") < 2 not supported !" << endl;
+    throw FileFormatExc("PInPersist::PInPersist() - Unsupported (Old) Version");
+  }
+  // read endianness
+  GetRawBytes(rbuf, 32);
+  if (strncmp(rbuf,"BIG-ENDIAN",10) == 0)
+    bigEndian = true;
+  else if (strncmp(rbuf,"LITTLE-ENDIAN",13) == 0)
+    bigEndian = false;
+  else {
+    throw FileFormatExc("PInPersist::PInPersist  bad header - endianness");
+  }
+
+  // read creation date
+  GetRawBytes(rbuf, 32);
+  rbuf[32] = '\0'; 
+  struct tm tm;
+  #if !(defined(__MWERKS__) || defined(OS_MACOSX))
+  strptime(rbuf,"%d/%m/%Y %H:%M:%S GMT",&tm);
+  #else
+  sscanf(rbuf,"%2d/%2d/%4d %2d:%2d:%2d GMT",&tm.tm_mday,&tm.tm_mon,&tm.tm_year,
+                                            &tm.tm_hour,&tm.tm_min,&tm.tm_sec);
+  tm.tm_mon  --;
+  tm.tm_year -= 1900;
+  #endif
+  creationdate = mktime(&tm);
+  filename = flnm;  // keep the filename
+  seqread = true;   // To flag non sequential reads
+  if (scan) Scan();
+}
+
+
+
+PInPersist::~PInPersist()
+{
+  ObjList::iterator i;
+  for(i=objList.begin(); i!= objList.end(); i++)  
+    if ((*i).second)  delete (*i).second;
+  delete s;
+}
+
+
+string 
+PInPersist::CreationDateStr()
+{
+  time_t cdt = CreationDate();
+  string cdate = ctime(&cdt);
+  return(cdate);
+}
+
+void
+PInPersist::Scan()
+{
+  // On cherche la liste des tags, a la fin du fichier
+
+  unsigned char ppstype;
+  size_t debut;
+#ifdef STREAMPOS_IS_CLASS
+  debut = s->tellg().offset();
+#else
+  debut = s->tellg();
+#endif
+
+  // Find tag entries at end of file
+#if (defined(Linux) || defined(Darwin)) &&  defined(__GNUG__)
+  // There seems to be a bug where seekg with ios::end under Linux  with g++
+  // So, we use seek with ios::beg
+  // The bug seems to be there also with Darwin/MacOSX
+  s->seekg(0, ios::end);
+  int_8 tagpos = s->tellg() - (sizeof(int_8)+1);
+  s->seekg(tagpos, ios::beg);
+#else
+  s->seekg(-(sizeof(int_8)+1), ios::end);
+#endif
+
+  GetTypeTag(ppstype);
+  if (ppstype != PPS_EOF)
+    throw FileFormatExc("PInPersist::Scan   corrupted file, no eof entry at end of file");
+
+  int_8 pos;
+  GetRawI8(pos);
+  if (pos < 0) {  // no tags
+    s->seekg(debut);
+    return;
+  }
+
+  char buffer[MAXTAGLEN+1];
+  s->seekg(pos);
+  while (true) {
+    GetTypeTag(ppstype);
+    if (ppstype == PPS_EOF) break;
+    
+    if (ppstype != PPS_TAG)
+      throw FileFormatExc("PInPersist::Scan   corrupted file, bad tag entry");
+
+    GetRawI8(pos);
+    int_4 len;
+    GetRawI4(len);
+    if (len > MAXTAGLEN) 
+      throw FileFormatExc("PInPersist::Scan   corrupted file, tag name too long");
+    GetRawBytes(buffer, len);
+    buffer[len] = '\0';
+
+    tags[buffer] = pos;
+  }
+  s->seekg(debut);
+}
+
+
+int
+PInPersist::NbTags()
+{
+  return tags.size();
+}
+
+bool 
+PInPersist::GotoTag(string const& name)
+{
+  map<string, int_8>::iterator i = tags.find(name);
+  if (i == tags.end()) 
+    return false;
+      //    throw NotFoundExc("PInPersist::GotoTag   tag not found");
+  s->seekg((*i).second);
+  seqread = false;
+  //  objList.clear(); $CHECK$ EA 171199 Ne pas faire ? Reza 03/2000 ?
+  return(true); 
+}
+
+bool
+PInPersist::GotoTagNum(int itag)
+{
+  if (itag<0 || itag >= (int)tags.size()) return false;
+  map<string, int_8>::iterator i = tags.begin();
+  for (int j=0; j<itag; j++) i++;
+  s->seekg((*i).second);
+  seqread = false;
+  // objList.clear();  $CHECK$ EA 171199  Ne pas faire ? Reza 03/2000 ?
+  return(true);
+}
+
+string
+PInPersist::GetTagName(int itag)
+{
+  if (itag<0 || itag >= (int)tags.size()) return "";
+  map<string, int_8>::iterator i = tags.begin();
+  for (int j=0; j<itag; j++) i++;
+  return((*i).first);
+}
+
+string
+PInPersist::GetTagClassName(int itag)
+{
+  // A faire
+//   if (itag<0 || itag >= (int)tags.size()) return "";
+//   map<string, int_8>::iterator i = tags.begin();
+//   for (int j=0; j<itag; j++) i++;
+//   uint_8 cid = (*i).second;
+//   return(GetClassName(cid));
+  return("");
+}
+
+static vector<string> * ret_tag_names = NULL;
+vector<string> const &
+PInPersist::GetTagNames()
+{
+if (ret_tag_names) delete ret_tag_names;
+ret_tag_names = new vector<string> ;
+map<string, int_8>::iterator i;
+for(i=tags.begin(); i!=tags.end(); i++) ret_tag_names->push_back((*i).first);
+return(*ret_tag_names);  
+}
+
+//++
+// void PInPersist::GetByte(char& c)
+// void PInPersist::GetBytes(void* ptr, size_t bytes)
+// void PInPersist::GetR4   (r_4& result)
+// void PInPersist::GetR4s  (r_4* tab, size_t n)
+// void PInPersist::GetR8   (r_8& result)
+// void PInPersist::GetR8s  (r_8* tab, size_t n)
+// void PInPersist::GetI2   (int_2& result)
+// void PInPersist::GetI2s  (int_2* tab, size_t n)
+// void PInPersist::GetU2   (uint_2& result)
+// void PInPersist::GetU2s  (uint_2* tab, size_t n)
+// void PInPersist::GetI4   (int_4& result)
+// void PInPersist::GetI4s  (int_4* tab, size_t n)
+// void PInPersist::GetU4   (uint_4& result)
+// void PInPersist::GetU4s  (uint_4* tab, size_t n)
+// void PInPersist::GetI8   (int_8& result)
+// void PInPersist::GetI8s  (int_8* tab, size_t n)
+// void PInPersist::GetU8   (uint_8& result)
+// void PInPersist::GetU8s  (uint_8* tab, size_t n)
+//	Lecture de données portables depuis le fichier PPersist. Pour chaque type
+//	de données, on peut lire une valeur, ou un tableau de valeurs.
+// void PInPersist::GetLine(char* ptr, size_t len)
+//	Lecture d'une ligne de texte depuis le fichier PPersist.
+//--
+
+
+void
+PInPersist::GetTypeTag(unsigned char& c) 
+{
+  c = PPS_TAG_MARK;
+  while (c == PPS_TAG_MARK) GetRawUByte(c);
+  //  while (c == PPS_TAG_MARK) {    Il ne faut plus faire ca !
+  //    objList.clear();             $CHECK$ Reza 03/2000
+  //    GetRawByte(c);
+  //  }
+}
+
+
+void
+PInPersist::GetRawByte(char& c)
+{
+  GetRawBytes(&c, 1);
+}
+
+void
+PInPersist::GetRawUByte(unsigned char& c)
+{
+  GetRawBytes(&c, 1);
+}
+
+void
+PInPersist::GetRawBytes(void* ptr, size_t bytes)
+{
+  s->read((char*)ptr, bytes);
+}
+
+void
+PInPersist::GetRawI2   (int_2& result)
+{
+  GetRawBytes(&result, sizeof(int_2));
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap2(&result);
+}
+
+void
+PInPersist::GetRawI4   (int_4& result)
+{
+  GetRawBytes(&result, sizeof(int_4));
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap4(&result);
+}
+
+void
+PInPersist::GetRawI8   (int_8& result)
+{
+  GetRawBytes(&result, sizeof(int_8));
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap8(&result);
+}
+
+void
+PInPersist::GetRawU8   (uint_8& result)
+{
+  GetRawBytes(&result, sizeof(uint_8));
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap8(&result);
+}
+
+void
+PInPersist::CheckTag(short datasz, short datatype)
+// datatype = PPS_DATATYPE_CHAR or PPS_DATATYPE_FLOAT or PPS_DATATYPE_INTEGER or PPS_DATATYPE_UNSIGNED
+{
+  unsigned char ppstype;
+  GetTypeTag(ppstype);
+  if (ppstype != PPS_SIMPLE + datasz + datatype)
+    throw FileFormatExc("PInPersist::CheckTag   bad type in ppersist file");
+}
+
+void
+PInPersist::CheckArrayTag(short datasz, size_t sz, short datatype)
+// datatype = PPS_DATATYPE_CHAR or PPS_DATATYPE_FLOAT or PPS_DATATYPE_INTEGER or PPS_DATATYPE_UNSIGNED
+{
+  unsigned char ppstype;
+  GetTypeTag(ppstype);
+  size_t filesz;
+  if (sz <= 0x7fffffff) {
+    if (ppstype != PPS_SIMPLE_ARRAY4 + datasz + datatype)
+      throw FileFormatExc("PInPersist::CheckArrayTag   bad type in ppersist file");
+    int_4 ff;
+    GetRawI4(ff); filesz=ff;
+  } else {
+    if (ppstype != PPS_SIMPLE_ARRAY8 + datasz + datatype)
+      throw FileFormatExc("PInPersist::CheckArrayTag   bad type in ppersist file");
+    uint_8 ff;
+    GetRawU8(ff); filesz=ff;
+  }
+  if (filesz != sz)
+    throw FileFormatExc("PInPersist::CheckArrayTag   bad array size in ppersist file");
+}
+
+void
+PInPersist::GetByte(char& c)
+{
+  CheckTag(1,PPS_DATATYPE_CHAR);
+  GetRawBytes(&c, 1);
+}
+
+
+void
+PInPersist::GetBytes(void* ptr, size_t bytes)
+{
+  CheckArrayTag(1, bytes, PPS_DATATYPE_CHAR);
+  GetRawBytes(ptr, bytes);
+}
+void
+PInPersist::GetR4   (r_4& result)
+{
+  CheckTag(4,PPS_DATATYPE_FLOAT);
+  GetRawBytes(&result, sizeof(r_4));
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap4(&result);
+}
+
+
+void
+PInPersist::GetR4s  (r_4* tab, size_t n)
+{
+  CheckArrayTag(4,n,PPS_DATATYPE_FLOAT);
+  GetRawBytes(tab, n*sizeof(r_4));
+  if (bigEndian == IS_BIG_ENDIAN) return;
+
+  for (unsigned int i=0; i<n; i++)
+    bswap4(tab+i);
+
+  return;
+}
+
+void
+PInPersist::GetR8   (r_8& result)
+{
+  CheckTag(8,PPS_DATATYPE_FLOAT);
+  GetRawBytes(&result, sizeof(r_8));
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap8(&result);
+}
+
+void
+PInPersist::GetR8s  (r_8* tab, size_t n)
+{
+  CheckArrayTag(8,n,PPS_DATATYPE_FLOAT);
+  GetRawBytes(tab, n*sizeof(r_8));
+  if (bigEndian == IS_BIG_ENDIAN) return;
+
+  for (unsigned int i=0; i<n; i++)
+    bswap8(tab+i);
+
+  return;
+}
+
+void
+PInPersist::GetI2   (int_2& result)
+{
+  CheckTag(2,PPS_DATATYPE_INTEGER);
+  GetRawBytes(&result, sizeof(int_2));
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap2(&result);
+}
+
+void
+PInPersist::GetI2s  (int_2* tab, size_t n)
+{
+  CheckArrayTag(2,n,PPS_DATATYPE_INTEGER);
+  GetRawBytes(tab, n*sizeof(int_2));
+  if (bigEndian == IS_BIG_ENDIAN) return;
+
+  for (unsigned int i=0; i<n; i++)
+    bswap2(tab+i);
+
+  return;
+}
+
+void
+PInPersist::GetU2   (uint_2& result)
+{
+  CheckTag(2,PPS_DATATYPE_UNSIGNED);
+  GetRawBytes(&result, sizeof(uint_2));
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap2(&result);
+}
+
+void
+PInPersist::GetU2s  (uint_2* tab, size_t n)
+{
+  CheckArrayTag(2,n,PPS_DATATYPE_UNSIGNED);
+  GetRawBytes(tab, n*sizeof(uint_2));
+  if (bigEndian == IS_BIG_ENDIAN) return;
+
+  for (unsigned int i=0; i<n; i++)
+    bswap2(tab+i);
+
+  return;
+}
+
+void
+PInPersist::GetI4   (int_4& result)
+{
+  CheckTag(4,PPS_DATATYPE_INTEGER);
+  GetRawBytes(&result, sizeof(int_4));
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap4(&result);
+}
+
+void
+PInPersist::GetI4s  (int_4* tab, size_t n)
+{
+  CheckArrayTag(4,n,PPS_DATATYPE_INTEGER);
+  GetRawBytes(tab, n*sizeof(int_4));
+  if (bigEndian == IS_BIG_ENDIAN) return;
+
+  for (unsigned int i=0; i<n; i++)
+    bswap4(tab+i);
+
+  return;
+}
+
+void
+PInPersist::GetU4   (uint_4& result)
+{
+  CheckTag(4,PPS_DATATYPE_UNSIGNED);
+  GetRawBytes(&result, sizeof(uint_4));
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap4(&result);
+}
+
+void
+PInPersist::GetU4s  (uint_4* tab, size_t n)
+{
+  CheckArrayTag(4,n,PPS_DATATYPE_UNSIGNED);
+  GetRawBytes(tab, n*sizeof(uint_4));
+  if (bigEndian == IS_BIG_ENDIAN) return;
+
+  for (unsigned int i=0; i<n; i++)
+    bswap4(tab+i);
+
+  return;
+}
+
+
+void
+PInPersist::GetI8   (int_8& result)
+{
+  CheckTag(8,PPS_DATATYPE_INTEGER);
+  GetRawBytes(&result, sizeof(int_8));
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap8(&result);
+}
+
+void
+PInPersist::GetI8s  (int_8* tab, size_t n)
+{
+  CheckArrayTag(8,n,PPS_DATATYPE_INTEGER);
+  GetRawBytes(tab, n*sizeof(int_8));
+  if (bigEndian == IS_BIG_ENDIAN) return;
+
+  for (unsigned int i=0; i<n; i++)
+    bswap8(tab+i);
+
+  return;
+}
+
+void
+PInPersist::GetU8   (uint_8& result)
+{
+  CheckTag(8,PPS_DATATYPE_UNSIGNED);
+  GetRawBytes(&result, sizeof(uint_8));
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap8(&result);
+}
+
+void
+PInPersist::GetU8s  (uint_8* tab, size_t n)
+{
+  CheckArrayTag(8,n,PPS_DATATYPE_UNSIGNED);
+  GetRawBytes(tab, n*sizeof(uint_8));
+  if (bigEndian == IS_BIG_ENDIAN) return;
+
+  for (unsigned int i=0; i<n; i++)
+    bswap8(tab+i);
+
+  return;
+}
+
+
+void
+PInPersist::GetLine(char* ptr, size_t len)
+{
+  string str;
+  GetStr(str);
+  strncpy(ptr, str.c_str(), len);
+  ptr[len] = '\0';
+}
+
+void
+PInPersist::GetStr(string& str)
+{
+  unsigned char ppstype;
+  GetTypeTag(ppstype);
+  if (ppstype != PPS_STRING) 
+    throw FileFormatExc("PInPersist::GetStr   bad type in ppersist file");
+  int_4 len;
+  GetRawI4(len);
+  char * buff = new char[len+1];
+  GetRawBytes(buff, len);
+  buff[len] = '\0';
+  str = buff;
+  delete[] buff;
+}
+
+
+PPersist*
+PInPersist::ReadObject()
+{
+  return(GetPPObject());
+}
+
+void 
+PInPersist::GetObject(AnyDataObj & o)
+{
+  GetPPObject(&o);
+  return;
+}
+
+void 
+PInPersist::GetObject(AnyDataObj & o, string tagname)
+{
+  GotoTag(tagname);
+  GetPPObject(&o);
+  return;
+}
+
+PPersist*
+PInPersist::GetPPObject(AnyDataObj * po)
+{
+  // Get tag
+  unsigned char ppstype;
+  GetTypeTag(ppstype);
+  if (ppstype != PPS_OBJECT && ppstype != PPS_REFERENCE && ppstype != PPS_NULL) {
+    throw FileFormatExc("PInPersist::ReadObject : not an object in flow");
+  }
+
+  if (ppstype == PPS_NULL) {
+    return NULL;
+  } else if (ppstype == PPS_OBJECT) {
+    // Get class id
+    uint_8 classId;
+    GetRawU8(classId);
+    uint_8 oid,oid2;
+    GetRawU8(oid);
+    
+    // Get factory method
+    ClassCreatorFunc f = FindCreatorFunc(classId);
+    if (!f) {
+      throw NotFoundExc("PInPersist::ReadObject   class not registered");
+    }
+    
+    // Create object
+    PPersist* object = f();
+    //  If a DataObject was specified , we assign it to the PPersistObject
+    if (po != NULL) object->SetDataObj(*po);
+
+    object->ReadSelf(*this);
+    unsigned char ppstag;
+    // Read the ENDOBJECT 
+    GetRawUByte(ppstag);
+    if (ppstag != PPS_ENDOBJECT)
+      throw FileFormatExc("PInPersist::ReadObject No PPS_ENDOBJECT tag");
+    GetRawU8(oid2);
+    if (oid2 != oid)
+      throw FileFormatExc("PInPersist::ReadObject Inconsistent PPS-OId at PPS_ENDOBJECT ");
+
+    KeepOId(oid, *object);
+    return object;
+  } 
+  else if (ppstype == PPS_REFERENCE) 
+    return ReadReference();
+
+  else throw FileFormatExc("PInPersist::ReadObject invalide Tag Type !");  
+}
+
+
+void
+PInPersist::AnalyseTags(int lev)
+{
+  unsigned char ppstag=0;
+  unsigned char ppst1,ppst2,ppst3;
+  uint_8 cpos,fsize;
+  uint_8 ui8,cid,oid;
+  int_4 i4;
+  int_8 i8;
+  char * buff;
+  string str;
+  
+  cout << "\n ---------------------------------------------------------- " << endl;
+  cout << " PInPersist::AnalyseTags(Level= " << lev << ")" << endl; 
+
+
+#ifdef STREAMPOS_IS_CLASS
+  cpos = s->tellg().offset();
+#else
+  cpos = s->tellg();
+#endif
+  s->seekg(0,ios::end);
+#ifdef STREAMPOS_IS_CLASS
+  fsize = s->tellg().offset();
+#else
+  fsize = s->tellg();
+#endif
+  s->seekg(cpos,ios::beg);
+
+  cout << "   Version= " << Version() << " FileSize= " << fsize 
+       << " Creation Date= " << CreationDateStr() <<  endl;
+  
+  uint_8 totntags = 0;
+  bool eofok = false;
+
+  while ( (ppstag != PPS_EOF) &&  (cpos < fsize) ) {
+#ifdef STREAMPOS_IS_CLASS
+  cpos = s->tellg().offset();
+#else
+  cpos = s->tellg();
+#endif
+    GetRawUByte(ppstag);
+    totntags++;
+
+    ppst1 = ppstag&0x0f;  // bits 0123
+    ppst2 = ppstag&0x30;  // bits     45
+    ppst3 = ppstag&0xc0;  // bits       67
+    if ((ppst2 == 0) && (ppst3 == 0) ) {
+      switch (ppst1) {
+
+      case PPS_NULL :
+	if (lev > 1)  cout << "<PPS_NULL> tag at position " << hex << cpos << dec << endl;
+	break;
+
+      case PPS_STRING :
+	GetRawI4(i4);
+	if (lev > 1)  cout << "<PPS_STRING> tag at position " << hex << cpos << dec 
+			   << " Length=" << i4 << endl;
+	s->seekg(i4,ios::cur);
+	break;
+
+      case PPS_OBJECT :
+	GetRawU8(cid);
+	GetRawU8(oid);
+	cout << "<PPS_OBJECT> tag at position " << hex << cpos << " ClassId= " << cid 
+	     << "  ObjectId= " << oid << dec << endl;
+	break;
+
+      case PPS_REFERENCE :
+	GetRawU8(oid);
+	GetRawI8(i8);
+	cout << "<PPS_REFERENCE> tag at position " << hex << cpos << "  ObjectId= " 
+	     << oid << "  OrigPos=" << i8 << dec << endl;
+	break;
+
+      case PPS_TAG_MARK :
+	cout << "<PPS_TAG_MARK> tag at position " << hex << cpos << dec << endl; 
+	break;
+     
+      case PPS_ENDOBJECT :
+	GetRawU8(oid);
+	cout << "<PPS_ENDOBJECT> tag at position " << hex << cpos << "  ObjectId= " 
+	     << oid << dec << endl;
+	break;
+
+      case PPS_TAG :
+	GetRawI8(i8);
+	GetRawI4(i4);
+	buff = new char[i4+1];
+	GetRawBytes(buff, i4); 
+        buff[i4] = '\0';  str = buff;
+	delete[] buff;
+	cout << "<PPS_TAG> tag at position " << hex << cpos << dec 
+	     << " Name= " << str << endl; 
+	break;
+
+      case PPS_EOF :
+	GetRawI8(i8);	
+	cout << "<PPS_EOF> tag at position " << hex << cpos  
+	     << " TagPos=" << i8 << dec << endl;
+	eofok = true;
+	break;
+
+      default :
+	cerr << " ERROR : Unexpected tag value " << hex << ppstag 
+	     << " At position" << cpos << dec << endl;
+	throw FileFormatExc("PInPersist::AnalyseTags() - Unexpected tag value !");
+      }
+    }
+    else {
+      string dtype = "???? x";
+      if (ppst3 == PPS_DATATYPE_CHAR) dtype = "CHAR x";
+      else if (ppst3 == PPS_DATATYPE_FLOAT) dtype = "FLOAT x";
+      else if (ppst3 == PPS_DATATYPE_INTEGER) dtype = "INTEGER x";
+      else if (ppst3 == PPS_DATATYPE_UNSIGNED) dtype = "UNSIGNED x";
+      int_4 dsize = ppst1;
+      char sb[16];
+      sprintf(sb, "%d", dsize);
+      dtype += sb;
+
+      switch (ppst2) {
+
+      case PPS_SIMPLE :
+	if (lev > 2)  cout << "<PPS_SIMPLE> tag at position " << hex << cpos << dec 
+			   << " DataType=" << dtype << endl;
+	s->seekg(dsize, ios::cur);
+	break;
+
+      case PPS_SIMPLE_ARRAY4 :
+	GetRawI4(i4);
+	if (lev > 0)  cout << "<PPS_SIMPLE_ARRAY4> tag at position " << hex << cpos << dec 
+			   << " DataType=" << dtype << " NElts= " << i4 << endl;
+	s->seekg((uint_8)dsize*(uint_8)i4, ios::cur);
+	break;
+
+      case PPS_SIMPLE_ARRAY8 :
+	GetRawU8(ui8);
+	if (lev > 0)  cout << "<PPS_SIMPLE_ARRAY8> tag at position " << hex << cpos << dec 
+			   << " DataType=" << dtype << " NElts= " << ui8 << endl;
+	s->seekg((uint_8)dsize*ui8, ios::cur);
+	break;
+      }
+    }
+  }
+  if (!eofok) 
+    throw FileFormatExc("PInPersist::AnalyseTags() - Not found <PPS_EOF> tag ");
+
+  cout << " PInPersist::AnalyseTags() - End - Total Number of Tags= " << totntags << endl; 
+  cout << " ---------------------------------------------------------- \n" << endl;
+  return;
+}
+
+void
+PInPersist::ReadReference(PPersist & ppo)
+{
+  PPersist * pr = ReadReference();
+  ppo.ShareDataReference(*pr);
+}
+
+
+PPersist *
+PInPersist::ReadReference()
+{
+  uint_8 oid;
+  int_8 pos;
+  GetRawU8(oid);
+  GetRawI8(pos);
+  //  cerr << " DBG - PInPersist::ReadReference-A "  << oid << " Pos= " << pos << endl; 
+  map<uint_8, PPersist *>::iterator i = objList.find(oid);
+  if (i != objList.end()) return (*i).second; 
+  else  {  // We may have skeeped it !
+    // Let's try to read it
+    int_8 cpos;
+#ifdef STREAMPOS_IS_CLASS
+    cpos = s->tellg().offset();
+#else
+    cpos = s->tellg();
+#endif
+    s->seekg(pos);
+    PPersist* ppo = ReadObject();
+    s->seekg(cpos);
+    delete ppo;
+    //    cerr << " DBG - PInPersist::ReadReference-B ... " << endl;  
+
+    map<uint_8, PPersist *>::iterator i2 = objList.find(oid);
+    if (i2 == objList.end()) 
+      throw FileFormatExc("PInPersist::ReadReference()   Not found PPS_OId ");
+    return (*i2).second; 
+  }
+}
+
+
+void
+PInPersist::KeepOId(uint_8 oid, PPersist & ppo)
+{
+  if ((oid&0x1) == 0)  return; // This is not an object which can be referenced
+  //  cerr << " DBG - PInPersist::KeepOId() " << oid << endl;
+  if ((objList.size() > 0) && (objList.find(oid) != objList.end()) ) {
+    //  Ceci ne devrait arriver que si on lit dans le desordre (avec GotoTag)
+    //  et pas avec une lecture sequentielle ...   Reza 03/2000
+    //  cerr << "PInPersist::KeepOId()/Warning - already present PPS_ObjectId ! " << oid << endl;
+    if (seqread) throw FileFormatExc("PInPersist::KeepOId() already present PPS_ObjectId ");
+    PPersist *pp = (*objList.find(oid)).second;
+    ppo.ShareDataReference(*pp);
+  }
+  else {
+    PPersist * npp = ppo.CloneSharedReference(); 
+    if (npp == NULL) throw PError("PInPersist::KeepOId() NULL returned by PPersist.Clone() ! ");
+    objList[oid] = npp;
+  }
+  return;
+}
+
+//++
+// Class	POutPersist
+// Lib		Outils++
+// include	ppersist.h
+//
+//	Fichier d'objets persistants, en écriture.
+//--
+
+
+//++
+//  POutPersist(string const& flnm, int endianness = PPersist::PPS_NATIVE)
+//
+//	Crée un nouveau fichier ppersist. Par défaut, il est petit=boutien
+//	sur machines petit-boutiennes, et gros-boutien sur machines
+//	gros-boutiennes. On peut explicitement spécifier PPersist::PPS_LITTLE_ENDIAN
+//	ou PPersist::PPS_BIG_ENDIAN.
+//--
+POutPersist::POutPersist(string const& flnm, int endianness)
+{
+  if (endianness == -1)
+    bigEndian = IS_BIG_ENDIAN;
+  else
+    bigEndian = endianness;
+
+  // PPS (POutPersist stream) Object Id initialisation
+  pps_OId = 0;
+  // Output stream creation
+  s = new ofstream(flnm.c_str(),ios::out | IOS_BIN);  
+
+  // Header
+  PutRawBytes("SOS-SOPHYA-PPersistFile V2               ",32);
+  PutRawBytes(bigEndian 
+	   ? "BIG-ENDIAN                             "
+	   : "LITTLE-ENDIAN                          ",32);
+
+// ---- GMT creation date of the file
+  time_t tm = time(NULL);
+  char datestring[33];
+  int l=strftime(datestring,32,"%d/%m/%Y %H:%M:%S GMT",gmtime(&tm));
+  for(int i=l; i<32; i++)  datestring[i] = ' ';
+  datestring[32] = '\0'; 
+  PutRawBytes(datestring, 32);
+  filename = flnm;
+}
+
+POutPersist::~POutPersist()
+{
+  if (tags.size() == 0) {
+    PutRawUByte(PPS_EOF);
+    PutRawI8(-1);
+  } else {
+    int_8 tagPos;
+#ifdef STREAMPOS_IS_CLASS
+    tagPos = s->tellp().offset();
+#else
+    tagPos = s->tellp();
+#endif
+    for (map<string,int_8>::iterator i = tags.begin(); i != tags.end(); i++) {
+      string name = (*i).first;
+      int_8 pos = (*i).second;
+      PutRawUByte(PPS_TAG);                       // This is a tag
+      PutRawI8(pos);                             // position of previous tag
+      PutRawI4(name.length());                   // length of the name
+      PutRawBytes(name.c_str(), name.length());  // name, without final "0".
+    }
+    PutRawUByte(PPS_EOF);
+    PutRawI8(tagPos);
+  }
+
+  delete s;   // Close the stream
+}
+
+
+void
+POutPersist::WriteTag(string const& name)
+{
+  if (name.length() > MAXTAGLEN) 
+    throw ParmError("POutPersist::WriteTag   tag name too long");
+
+  if (tags.find(name) != tags.end())
+    throw DuplicateIdExc("POutPersist::WriteTag   duplicate tag name");
+
+  // Get current file position
+  int_8 tagPos;
+
+  #ifdef STREAMPOS_IS_CLASS
+  tagPos = s->tellp().offset();
+  #else
+  tagPos = s->tellp();
+  #endif
+
+  tags[name] = tagPos;
+  PutRawUByte(PPS_TAG_MARK);                       // This is a tag
+  //  objList.clear(); // $CHECK$ EA 171199  - Ne pas faire ? Reza 03/2000
+}
+
+//++
+// void POutPersist::PutByte(char& c)
+// void POutPersist::PutBytes(void const* ptr, size_t bytes)
+// void POutPersist::PutR4   (r_4 result)
+// void POutPersist::PutR4s  (r_4 const* tab, size_t n)
+// void POutPersist::PutR8   (r_8 result)
+// void POutPersist::PutR8s  (r_8 const* tab, size_t n)
+// void POutPersist::PutI2   (int_2 result)
+// void POutPersist::PutI2s  (int_2 const* tab, size_t n)
+// void POutPersist::PutU2   (uint_2 result)
+// void POutPersist::PutU2s  (uint_2 const* tab, size_t n)
+// void POutPersist::PutI4   (int_4 result)
+// void POutPersist::PutI4s  (int_4 const* tab, size_t n)
+// void POutPersist::PutU4   (uint_4 result)
+// void POutPersist::PutU4s  (uint_4 const* tab, size_t n)
+// void POutPersist::PutI8   (int_8 result)
+// void POutPersist::PutI8s  (int_8 const* tab, size_t n)
+// void POutPersist::PutU8   (uint_8 result)
+// void POutPersist::PutU8s  (uint_8 const* tab, size_t n)
+// void POutPersist::PutStr  (string const&)
+//	Ecriture de données portables.. Pour chaque type
+//	de données, on peut écrire une valeur, ou un tableau de valeurs.
+// void POutPersist::PutLine(char const* ptr, size_t len)
+//	Ecriture d'une ligne de texte dans le fichier PPersist.
+//--
+
+
+
+
+void
+POutPersist::PutRawBytes(void const* ptr, size_t bytes)
+{
+  s->write((char const*)ptr, bytes);
+}
+
+void
+POutPersist::PutRawByte(char c)
+{
+  PutRawBytes(&c, 1);
+}
+
+void
+POutPersist::PutRawUByte(unsigned char c)
+{
+  PutRawBytes(&c, 1);
+}
+
+void
+POutPersist::PutRawI2   (int_2 val)
+{
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap2(&val);
+
+  PutRawBytes(&val, sizeof(int_2));
+}
+
+void
+POutPersist::PutRawI4   (int_4 val)
+{
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap4(&val);
+
+  PutRawBytes(&val, sizeof(int_4));
+}
+
+void
+POutPersist::PutRawI8   (int_8 val)
+{
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap8(&val);
+
+  PutRawBytes(&val, sizeof(int_8));
+}
+
+void
+POutPersist::PutRawU8   (uint_8 val)
+{
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap8(&val);
+
+  PutRawBytes(&val, sizeof(uint_8));
+}
+
+void
+POutPersist::PutArrayTag(short datasz, size_t sz, short datatype) 
+// datatype = PPS_DATATYPE_CHAR or PPS_DATATYPE_FLOAT or PPS_DATATYPE_INTEGER or PPS_DATATYPE_UNSIGNED
+{
+  if (sz <= 0x7fffffff) {
+    PutRawUByte(PPS_SIMPLE_ARRAY4 + datasz + datatype);
+    PutRawI4(sz);
+  } else {
+    PutRawUByte(PPS_SIMPLE_ARRAY8 + datasz + datatype);
+    PutRawU8(sz);
+  } 
+}
+
+void
+POutPersist::PutByte(char c)
+{
+  PutRawByte(PPS_SIMPLE + 1 + PPS_DATATYPE_CHAR);
+  PutRawBytes(&c, 1);
+}
+
+
+
+void
+POutPersist::PutBytes(void const* ptr, size_t bytes)
+{
+  PutArrayTag(1, bytes, PPS_DATATYPE_CHAR);
+  PutRawBytes(ptr, bytes);
+}
+
+void
+POutPersist::PutR4   (r_4 val)
+{
+  PutRawUByte(PPS_SIMPLE + 4 + PPS_DATATYPE_FLOAT);
+  
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap4(&val);
+
+  PutRawBytes(&val, sizeof(r_4));
+}
+
+void
+POutPersist::PutR4s  (r_4 const* tab, size_t n)
+{
+  PutArrayTag(4, n, PPS_DATATYPE_FLOAT);
+
+  if (bigEndian == IS_BIG_ENDIAN) {
+    PutRawBytes(tab, n*sizeof(r_4));
+  } else {
+    for (unsigned int i=0; i<n; i++) {
+      r_4 val = tab[i];
+      bswap4(&val);
+      PutRawBytes(&val, sizeof(r_4));
+    }
+  }
+}
+
+void
+POutPersist::PutR8   (r_8 val)
+{
+  PutRawUByte(PPS_SIMPLE + 8 + PPS_DATATYPE_FLOAT);
+
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap8(&val);
+
+  PutRawBytes(&val, sizeof(r_8));
+}
+
+void
+POutPersist::PutR8s  (r_8 const* tab, size_t n)
+{
+  PutArrayTag(8, n, PPS_DATATYPE_FLOAT);
+
+  if (bigEndian == IS_BIG_ENDIAN) {
+    PutRawBytes(tab, n*sizeof(r_8));
+  } else {
+    for (unsigned int i=0; i<n; i++) {
+      r_8 val = tab[i];
+      bswap8(&val);
+      PutRawBytes(&val, sizeof(r_8));
+    }
+  }
+}
+
+void
+POutPersist::PutI2   (int_2 val)
+{
+  PutRawUByte(PPS_SIMPLE + 2 + PPS_DATATYPE_INTEGER);
+
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap2(&val);
+
+  PutRawBytes(&val, sizeof(int_2));
+}
+
+void
+POutPersist::PutI2s  (int_2 const* tab, size_t n)
+{
+  PutArrayTag(2, n, PPS_DATATYPE_INTEGER);
+  
+  if (bigEndian == IS_BIG_ENDIAN) {
+    PutRawBytes(tab, n*sizeof(int_2));
+  } else {
+    for (unsigned int i=0; i<n; i++) {
+      int_2 val = tab[i];
+      bswap2(&val);
+      PutRawBytes(&val, sizeof(int_2));
+    }
+  }
+}
+
+void
+POutPersist::PutU2   (uint_2 val)
+{
+  PutRawUByte(PPS_SIMPLE + 2 + PPS_DATATYPE_UNSIGNED);
+
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap2(&val);
+
+  PutRawBytes(&val, sizeof(uint_2));
+}
+
+void
+POutPersist::PutU2s  (uint_2 const* tab, size_t n)
+{
+  PutArrayTag(2, n, PPS_DATATYPE_UNSIGNED);
+
+  if (bigEndian == IS_BIG_ENDIAN) {
+    PutRawBytes(tab, n*sizeof(uint_2));
+  } else {
+    for (unsigned int i=0; i<n; i++) {
+      uint_2 val = tab[i];
+      bswap2(&val);
+      PutRawBytes(&val, sizeof(uint_2));
+    }
+  }
+}
+
+void
+POutPersist::PutI4   (int_4 val)
+{
+  PutRawUByte(PPS_SIMPLE + 4 + PPS_DATATYPE_INTEGER);
+
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap4(&val);
+
+  PutRawBytes(&val, sizeof(int_4));
+}
+
+void
+POutPersist::PutI4s  (int_4 const* tab, size_t n)
+{
+  PutArrayTag(4, n, PPS_DATATYPE_INTEGER);
+
+  if (bigEndian == IS_BIG_ENDIAN) {
+    PutRawBytes(tab, n*sizeof(int_4));
+  } else {
+    for (unsigned int i=0; i<n; i++) {
+      int_4 val = tab[i];
+      bswap4(&val);
+      PutRawBytes(&val, sizeof(int_4));
+    }
+  }
+}
+
+void
+POutPersist::PutU4   (uint_4 val)
+{
+  PutRawUByte(PPS_SIMPLE + 4 + PPS_DATATYPE_UNSIGNED);
+
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap4(&val);
+
+  PutRawBytes(&val, sizeof(uint_4));
+}
+
+void
+POutPersist::PutU4s  (uint_4 const* tab, size_t n)
+{
+  PutArrayTag(4, n, PPS_DATATYPE_UNSIGNED);
+
+  if (bigEndian == IS_BIG_ENDIAN) {
+    PutRawBytes(tab, n*sizeof(uint_4));
+  } else {
+    for (unsigned int i=0; i<n; i++) {
+      uint_4 val = tab[i];
+      bswap4(&val);
+      PutRawBytes(&val, sizeof(uint_4));
+    }
+  }
+}
+
+void
+POutPersist::PutI8   (int_8 val)
+{
+  PutRawUByte(PPS_SIMPLE + 8 + PPS_DATATYPE_INTEGER);
+
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap8(&val);
+
+  PutRawBytes(&val, sizeof(int_8));
+}
+
+void
+POutPersist::PutI8s  (int_8 const* tab, size_t n)
+{
+  PutArrayTag(8, n, PPS_DATATYPE_INTEGER);
+
+  if (bigEndian == IS_BIG_ENDIAN) {
+    PutRawBytes(tab, n*sizeof(int_8));
+  } else {
+    for (unsigned int i=0; i<n; i++) {
+      int_8 val = tab[i];
+      bswap8(&val);
+      PutRawBytes(&val, sizeof(int_8));
+    }
+  }
+}
+
+void
+POutPersist::PutU8   (uint_8 val)
+{
+  PutRawUByte(PPS_SIMPLE + 8 + PPS_DATATYPE_UNSIGNED);
+
+  if (bigEndian != IS_BIG_ENDIAN)
+    bswap8(&val);
+
+  PutRawBytes(&val, sizeof(uint_8));
+}
+
+void
+POutPersist::PutU8s  (uint_8 const* tab, size_t n)
+{
+  PutArrayTag(8, n, PPS_DATATYPE_UNSIGNED);
+
+  if (bigEndian == IS_BIG_ENDIAN) {
+    PutRawBytes(tab, n*sizeof(uint_8));
+  } else {
+    for (unsigned int i=0; i<n; i++) {
+      uint_8 val = tab[i];
+      bswap8(&val);
+      PutRawBytes(&val, sizeof(uint_8));
+    }
+  }
+}
+
+void
+POutPersist::PutStr(string const& str) 
+{
+  PutRawUByte(PPS_STRING);
+  PutRawI4(str.length());
+  PutRawBytes(str.c_str(), str.length());
+}
+
+void
+POutPersist::PutLine(char const* ptr, size_t len)
+{
+  string str = ptr;
+  PutStr(str);
+}
+
+
+void
+POutPersist::PutObject(AnyDataObj & o)
+{
+  ClassCreatorFunc f = FindCreatorFunc(getDataObjClassId(o));
+  if (!f) 
+      throw NotFoundExc("PInPersist::PutObject()   class not registered");
+  PPersist* ppo = f();
+  ppo->SetDataObj(o);
+  PutPPObject(ppo);
+}
+
+void
+POutPersist::PutObject(AnyDataObj & o, string tagname)
+{
+  WriteTag(tagname);
+  PutObject(o);
+}
+
+
+void
+POutPersist::PutPPObject(PPersist const* obj) 
+{
+  if (serializeNullAndRepeat(obj)) return;  // NULL object or already written in stream
+
+  //   We have to write the object 
+  uint_8 oid = assignObjectId(obj);       // We assing a PPS Object Id 
+  PutRawUByte(PPS_OBJECT);         // We write the Object Tag
+  PutRawU8(getPPClassId(*obj));    // Writing the PPersist ClassId
+  PutRawU8(oid);                   // Write the PPS Object Id 
+  obj->WriteSelf(*this);
+  PutRawUByte(PPS_ENDOBJECT);      // We write the End-Of-Object Tag
+  PutRawU8(oid);                   // and again its PPS Object Id 
+}
+
+bool
+POutPersist::serializeNullAndRepeat(PPersist const* x)
+{
+  if (x == NULL) {
+    PutRawUByte(PPS_NULL);
+    return true;
+  }
+
+  int_8 pos;
+  uint_8 id = findObjectId(x, pos);
+  if (id > 0) {
+    PutRawUByte(PPS_REFERENCE);
+    PutRawU8(id);      // Writing the corresponding object Id
+    PutRawI8(pos);     // The original object position 
+    return true;
+  }
+  
+  return false;  // Object have to be written in stream ...
+}
+
+uint_8 
+POutPersist::assignObjectId(PPersist const* x)
+{
+  pps_OId += 16;  // We keep the three first bytes for future usage
+                  // Bit 1 non zero -> Object can be referenced 
+  uint_8 id = pps_OId;
+  uint_8 mid = x->getMemOId();
+  if (mid > 0) {
+    int_8 pos;
+    if (findObjectId(x,pos) > 0)  
+      throw PError("POutPersist::assignObjectId() Error - Already serialized object ! ");
+    id += 1;  // Bit 1 non zero -> Object can be referenced 
+    objreftag rt;
+    rt.ppsoid = id;
+#ifdef STREAMPOS_IS_CLASS
+    rt.ppspos = s->tellp().offset();
+#else
+    rt.ppspos = s->tellp();
+#endif
+    objList[mid] = rt;
+  }
+  return id;
+}
+
+uint_8 
+POutPersist::findObjectId(PPersist const* x, int_8 & pos)
+{
+  pos = -1;
+  uint_8 mid = x->getMemOId();
+  if (mid == 0)   return(0);
+  ObjList::iterator i = objList.find(mid);
+  if (i == objList.end()) return 0;
+  pos = (*i).second.ppspos;
+  return (*i).second.ppsoid;
+}
+
+
Index: /tags/V_Dec2002/SophyaLib/BaseTools/ppersist.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/ppersist.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/ppersist.h	(revision 2309)
@@ -0,0 +1,385 @@
+// This may look like C code, but it is really -*- C++ -*-
+
+#ifndef PPERSIST_H_SEEN
+#define PPERSIST_H_SEEN
+
+// Flat file persistance, similar to Java serialization
+//
+// E. Aubourg     CEA DAPNIA/SPP  1999
+// R. Ansari      LAL IN2P3/CNRS  03/2000
+
+
+#include "machdefs.h"
+#include "pexceptions.h"
+#include "gnumd5.h"
+
+
+#include <time.h>
+
+#include <string>
+#include <map>
+#include <vector>
+#include <typeinfo>
+
+
+// Classe de base pour les objets qui peuvent devenir PPersist
+
+namespace SOPHYA {
+  
+  class AnyDataObj;
+
+  class PIOPersist;
+  class PInPersist;
+  class POutPersist;
+  class PPersist;
+
+//! Persistent (delegate or mixin) base class 
+  class PPersist  {
+  public:
+    virtual           ~PPersist() {}
+// J'ajoute cette fonction pour assurer la compatibilite 
+// avec l'ancien PPersist d'Eros     (Reza 23/04/99)
+    virtual int_4      ClassId() const { return(0); }
+
+    void               Write(string const& fn) const;
+    void               Read(string const& fn);
+
+    virtual void       Write(POutPersist&) const;
+    void               Read(PInPersist& s);               // Reads the type tag and the object
+    void               Write(POutPersist&, string const& tag) const; 
+    void               ReadAtTag(PInPersist& s, string const& tag);
+
+    virtual AnyDataObj* DataObj()=0;       // Retourne l'objet reel 
+    virtual void       SetDataObj(AnyDataObj &)=0;     
+
+    virtual uint_8     getMemOId() const ;      // Renvoie l'identificateur de l'objet  - par defaut=0
+    // Ces deux methodes doivent etre redefinies si   getMemOId() renvoie non nul (>0)
+    virtual void       ShareDataReference(PPersist &);       
+    virtual PPersist*  CloneSharedReference();
+                                                // doit etre surcharge pour renvoyer un mem-oid correct
+  protected:  
+    virtual void       ReadSelf(PInPersist&)=0;           
+    virtual void       WriteSelf(POutPersist&) const=0;
+
+    friend class       PInPersist;
+    friend class       POutPersist;
+  };
+
+
+
+//! Ancestor for PInPersist and POutPersist PPF streams.
+// Handles (statically) the registration of classes.
+
+  class PIOPersist {
+  public:
+    enum                         {PPS_NATIVE = -1, PPS_LITTLE_ENDIAN = 0, PPS_BIG_ENDIAN = 1};
+    typedef PPersist*            (*ClassCreatorFunc)();
+  
+    static void                  RegisterPPHandlerClass(uint_8 classId, string ppclass_name, ClassCreatorFunc f);
+    static void                  RegisterDataObjClass(uint_8 classId, string class_name);
+
+    static ClassCreatorFunc      FindCreatorFunc(uint_8 classId);
+
+    static string                getPPClassName(uint_8 classId);
+    static uint_8                getPPClassId(string const & typ_name);
+    static uint_8                getPPClassId(PPersist const & ppo);
+    static string                getDataObjClassName(uint_8 classId);
+    static uint_8                getDataObjClassId(string const & typ_name);
+    static uint_8                getDataObjClassId(AnyDataObj const & o);
+
+    static uint_8 Hash(string const& typname);
+    static MD5_CONTEXT ctx;
+  
+    static void Initialize();   // Pour initialiser classList
+
+    string FileName() { return filename; }   // Retourne le nom de fichier
+
+  private:
+
+    typedef map<uint_8, ClassCreatorFunc, less<uint_8> > ClassList;  
+    // Pas de createur appele pour objets statiques sur Linux - $CHECK$ Reza 26/04/99
+    static ClassList *           ppclassList;      // PPersist class list  
+    static map<string, uint_8> * ppclassNameList;  // PPersist classId = f(PPersistClassName)
+    static map<string, uint_8> * dobjclassNameList;  // PPersist classId = f(DataObjClassName)
+
+  protected:
+
+    enum {PPS_NULL = 0,             // this is a null object
+	  PPS_STRING = 1,           // string, length (4b) + data
+	  PPS_OBJECT = 2,           // classId, data...
+	  PPS_REFERENCE = 3,        // objectId
+          PPS_TAG = 4,              // tag entries
+	  PPS_EOF = 5,              // Just before tag infomation, offset to PPS_TAG
+	  PPS_ENDOBJECT = 6,        // marks the end of a given object information
+          PPS_TAG_MARK = 7,         // To have a name tag, position marker in a file
+          PPS_SIMPLE = 16,          // 16 + number of bytes, up to 8 bytes
+          PPS_SIMPLE_ARRAY4 = 32,   // 32 + number of bytes, up to 8 bytes, then 4 bytes of length
+          PPS_SIMPLE_ARRAY8 = 48    // 48 + number of bytes, up to 8 bytes, then 8 bytes of length
+    };
+  // The following values are used with PPS_SIMPLE and PPS_SIMPLE_ARRAY (Using OR)
+   enum  {PPS_DATATYPE_CHAR = 0,        // 0  : DataType=character
+          PPS_DATATYPE_FLOAT = 64,      // 64 : DataType=float 
+          PPS_DATATYPE_INTEGER = 128,   // 128 :DataType=integer 
+          PPS_DATATYPE_UNSIGNED = 192   // 192 :DataType=Unsigned integer 
+   };
+
+    map<string, int_8> tags;
+    string filename;
+  };
+
+
+  // TBD : use hash tables instead of maps. Check hashtbl status in STL.
+
+//! Input stream for PPersit objects.
+  class PInPersist : public PIOPersist {
+  public:
+    PInPersist(string const& flnm, bool scan=true);
+    ~PInPersist();
+
+    bool   GotoTag(string const& name);
+    int    NbTags();
+    bool   GotoTagNum(int itag);  // 0..NbTags-1
+    string GetTagName(int itag);  // 0..NbTags-1
+    string GetTagClassName(int itag);  // 0..NbTags-1
+    vector<string> const &  GetTagNames();  
+
+    void   GetByte (char& c);
+    void   GetBytes(void* ptr, size_t bytes);
+    void   GetR4   (r_4&);
+    void   GetR4s  (r_4*, size_t);
+    void   GetR8   (r_8&);
+    void   GetR8s  (r_8*, size_t);
+    void   GetI2   (int_2&);
+    void   GetI2s  (int_2*, size_t);
+    void   GetU2   (uint_2&);
+    void   GetU2s  (uint_2*, size_t);
+    void   GetI4   (int_4&);
+    void   GetI4s  (int_4*, size_t);
+    void   GetU4   (uint_4&);
+    void   GetU4s  (uint_4*, size_t);
+    void   GetI8   (int_8&);
+    void   GetI8s  (int_8*, size_t);
+    void   GetU8   (uint_8&);
+    void   GetU8s  (uint_8*, size_t);
+    void   GetLine (char* ptr, size_t len);
+    void   GetStr  (string&);
+
+    void   Get(char&   c) {GetByte(c);}
+    void   Get(r_4&    x) {GetR4(x);}
+    void   Get(r_8&    x) {GetR8(x);}
+    void   Get(uint_2& x) {GetU2(x);}
+    void   Get(int_2&  x) {GetI2(x);}
+    void   Get(uint_4& x) {GetU4(x);}
+    void   Get(int_4&  x) {GetI4(x);}
+    void   Get(uint_8& x) {GetU8(x);}
+    void   Get(int_8&  x) {GetI8(x);}
+    void   Get(r_4*    x, size_t n) {GetR4s(x,n);}
+    void   Get(r_8*    x, size_t n) {GetR8s(x,n);}
+    void   Get(uint_2* x, size_t n) {GetU2s(x,n);}
+    void   Get(int_2*  x, size_t n) {GetI2s(x,n);}
+    void   Get(uint_4* x, size_t n) {GetU4s(x,n);}
+    void   Get(int_4*  x, size_t n) {GetI4s(x,n);}
+    void   Get(uint_8* x, size_t n) {GetU8s(x,n);}
+    void   Get(int_8*  x, size_t n) {GetI8s(x,n);}
+    void   Get(string& x) {GetStr(x);}
+  
+    //   Object Reading 
+    PPersist*  ReadObject();
+    void       GetObject(AnyDataObj & o);
+    void       GetObject(AnyDataObj & o, string  tagname);
+    PPersist*  GetPPObject(AnyDataObj * po=NULL);
+
+    int    Version() {return version;}
+    time_t CreationDate() { return creationdate; }
+    string CreationDateStr(); 
+
+    void   AnalyseTags(int lev=0);   // List (all or some) tags ...
+
+    //  Reza 03/2000
+    //  Methodes qui pourraient etre protected, mais doivent etre utilisables par PPersist 
+    void   ReadReference(PPersist & ppo);  // Fill the ppo object from the reference tag
+    PPersist * ReadReference();            // Creates object from the reference tag
+    void   KeepOId(uint_8 oid, PPersist & ppo);        // Keeps the ppo in the objList
+
+  protected:
+    void   CheckTag   (short datasz, short datatype);
+    void   CheckArrayTag(short datasz, size_t sz, short datatype);
+    void   GetTypeTag (unsigned char& c);
+    void   GetRawByte (char& c);
+    void   GetRawUByte (unsigned char& c);
+    void   GetRawBytes(void* ptr, size_t bytes);
+    void   GetRawI2   (int_2&);
+    void   GetRawI4   (int_4&);
+    void   GetRawI8   (int_8&);
+    void   GetRawU8   (uint_8&);
+
+    void   Scan();
+
+    istream* s;
+
+    bool bigEndian;
+    int version;
+
+    time_t creationdate;
+
+    // already read objects 
+    typedef map<uint_8, PPersist * > ObjList;
+    ObjList objList;
+    // Si on a fait une lecture non sequentielle  -> seqread = false
+    bool seqread;
+    friend class PPersist;
+  };
+
+//! Output stream for PPersit objects.
+  class POutPersist : public PIOPersist {
+  public:
+    POutPersist(string const& flnm, int endianness = PPS_NATIVE);
+    ~POutPersist();
+
+    void WriteTag(string const& name);
+  
+    void PutByte (char c);
+    void PutBytes(void const* ptr, size_t bytes);
+    void PutR4   (r_4);
+    void PutR4s  (r_4 const*, size_t);
+    void PutR8   (r_8);
+    void PutR8s  (r_8 const*, size_t);
+    void PutI2   (int_2);
+    void PutI2s  (int_2 const*, size_t);
+    void PutU2   (uint_2);
+    void PutU2s  (uint_2 const*, size_t);
+    void PutI4   (int_4);
+    void PutI4s  (int_4 const*, size_t);
+    void PutU4   (uint_4);
+    void PutU4s  (uint_4 const*, size_t);
+    void PutI8   (int_8);
+    void PutI8s  (int_8 const*, size_t);
+    void PutU8   (uint_8);
+    void PutU8s  (uint_8 const*, size_t);
+    void PutLine (char const* ptr, size_t len=0); // deprecated ?
+    void PutStr  (string const&);
+    void PutPPObject (PPersist const*); // Like doing Write(stream) on PPersist object
+
+    void PutObject(AnyDataObj & o);   // Creates the corresponding PPersist Object and call Write()
+    void PutObject(AnyDataObj & o, string tagname);
+
+    void   Put(char   c) {PutByte(c);}
+    void   Put(r_4    x) {PutR4(x);}
+    void   Put(r_8    x) {PutR8(x);}
+    void   Put(uint_2 x) {PutU2(x);}
+    void   Put(int_2  x) {PutI2(x);}
+    void   Put(uint_4 x) {PutU4(x);}
+    void   Put(int_4  x) {PutI4(x);}
+    void   Put(uint_8 x) {PutU8(x);}
+    void   Put(int_8  x) {PutI8(x);}
+    void   Put(r_4 const*    x, size_t n) {PutR4s(x,n);}
+    void   Put(r_8 const*    x, size_t n) {PutR8s(x,n);}
+    void   Put(uint_2 const* x, size_t n) {PutU2s(x,n);}
+    void   Put(int_2 const*  x, size_t n) {PutI2s(x,n);}
+    void   Put(uint_4 const* x, size_t n) {PutU4s(x,n);}
+    void   Put(int_4 const*  x, size_t n) {PutI4s(x,n);}
+    void   Put(uint_8 const* x, size_t n) {PutU8s(x,n);}
+    void   Put(int_8 const*  x, size_t n) {PutI8s(x,n);}
+    void   Put(string const& s) {PutStr(s);}
+    void   Put(PPersist const* x) {PutPPObject(x);}
+
+
+  protected:
+    ostream* s;
+    bool bigEndian;
+
+    void     PutArrayTag(short datasz, size_t sz, short datatype);
+    void     PutRawByte (char);
+    void     PutRawUByte (unsigned char);
+    void     PutRawI2   (int_2);
+    void     PutRawI4   (int_4);
+    void     PutRawI8   (int_8);
+    void     PutRawU8   (uint_8);
+    void     PutRawBytes(void const* ptr, size_t bytes);
+    bool     serializeNullAndRepeat(PPersist const* x);
+    uint_8   findObjectId(PPersist const* x, int_8 & pos);
+    uint_8   assignObjectId(PPersist const* x);
+
+    // objreftag contains the assigned POutStream Object Id and the stream position 
+    // of the original written object
+    typedef struct { uint_8 ppsoid; int_8 ppspos; } objreftag;
+    // already serialized objects are kept in a map as a function of the Objects memory Id
+    typedef map<uint_8, objreftag, less<uint_8> >  ObjList;
+    ObjList objList;
+    uint_8 pps_OId;    // PPS Object Id 
+  };
+  
+  
+#define RAWPERSISTIO(_Type_,_xtyp_)                                             \
+  inline POutPersist& operator << (POutPersist& c, _Type_ const& data)            \
+  {                                                                               \
+    c.Put##_xtyp_(data);                                                          \
+    return c;                                                                     \
+  }                                                                               \
+                                                                                \
+  inline PInPersist& operator >> (PInPersist& c, _Type_& data)                    \
+  {                                                                               \
+    c.Get##_xtyp_(data);                                                          \
+    return c;                                                                     \
+  }                                                                               
+
+  RAWPERSISTIO(int_4,I4);
+  RAWPERSISTIO(uint_4,U4);
+  RAWPERSISTIO(int_2,I2);
+  RAWPERSISTIO(uint_2,U2);
+  RAWPERSISTIO(char,Byte);
+  RAWPERSISTIO(r_4,R4);
+  RAWPERSISTIO(r_8,R8);
+  
+#if 0
+#define STRUCTPERSISTIO(_Type_, _field_, _size_)                                \
+  inline POutPersist& operator << (POutPersist& c, _Type_ const& data)            \
+  {                                                                               \
+    c.PutBytes(&data._field_, _size_);                                            \
+    return c;                                                                     \
+  }                                                                               \
+                                                                                \
+  inline PInPersist& operator >> (PInPersist& c, _Type_& data)                    \
+  {                                                                               \
+    c.GetBytes(&data._field_, _size_);                                            \
+    return c;                                                                     \
+  }                                                                               
+
+#endif
+  
+
+// --- Cela risque d'etre dangereux --- On le laisse au niveau des DataObj
+//                           Reza 24/3/2000 
+//   inline POutPersist& operator << (POutPersist& c, PPersist const& obj)
+//     {
+//       obj.Write(c);
+//       return c;
+//     }
+  
+//   inline PInPersist& operator >> (PInPersist& c, PPersist& obj)
+//     {
+//       obj.Read(c);
+//       return c;
+//     }
+
+  // Utility class to
+  //   - compute the class ID from a MD5 hash of the class name
+  //   - register classes with PIOPersist, through PPRegister macro
+
+//! template class for handling the PPersist registration mechanism.
+  template <class T>
+    class PPersistRegistrar {
+    public:
+      static PPersist* Create() {return new T();}
+      static void Register(string id) { PIOPersist::RegisterPPHandlerClass(Hash(id), typeid(T).name(), Create); }
+      static uint_8 Hash(string id) {
+	return PIOPersist::Hash(id);
+      }
+    };
+  
+#define PPRegister(className) PPersistRegistrar<className>::Register(#className);
+#define DObjRegister(ppclassName, className) PIOPersist::RegisterDataObjClass(PIOPersist::Hash(#ppclassName), typeid(className).name());
+
+} // namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/BaseTools/rcptr.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/rcptr.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/rcptr.h	(revision 2309)
@@ -0,0 +1,121 @@
+// This may look like C code, but it is really -*- C++ -*-
+
+#ifndef RCPTR_H
+#define RCPTR_H
+
+// This implements a very simple "smart pointer" with reference counting.
+// Many refinements are possible
+
+// Principle :  use RCPtr<T> instead of T*
+// To use with type X, define
+//  typedef RCPtr<X> Xp;
+//  When creating a new object, use
+//    Xp xp = new X(...);
+// xp can be used like a X*   xp->field, xp->method(), *xp ...
+//    can be passed by reference, copied, etc
+// the object is destroyed when the last Xp is destroyed.
+
+// The class RCCPtr<X> is a const smart pointer, to be used like
+// a X const *.
+
+// Eric Aubourg  1999   CEA/DAPNIA/SPP
+
+
+template <class T> class RCCPtr;
+
+template <class T>
+class RCPtr {
+public:
+  RCPtr(T* obj=0) {
+    x = obj;
+    cnt = new int;
+    *cnt = 1;
+  }
+  
+  RCPtr(RCPtr<T> const& other) {
+    x = other.x;
+    cnt = other.cnt;
+    (*cnt)++;
+  }
+
+  RCPtr<T>& operator = (RCPtr<T> const& other) {
+    (*cnt)--;
+    if (!*cnt) {
+      delete x;
+      delete cnt;
+    }
+    x = other.x;
+    cnt = other.cnt;
+    (*cnt)++;
+    return *this;
+  }
+  
+  ~RCPtr() {
+    (*cnt)--;
+    if (!*cnt) {
+      delete x;
+      delete cnt;
+    }
+  }
+
+  T* operator->() {return x;}
+  T& operator*()  {return *x;}
+
+private:
+  T* x;                  // the object we are referring
+  int* cnt;              // how many smart pointers ?
+  friend class RCCPtr<T>;
+};
+
+
+// A const smart pointer
+template <class T>
+class RCCPtr {
+public:
+  RCCPtr(T const* obj=0) {
+    x = obj;
+    cnt = new int;
+    *cnt = 1;
+  }
+  
+  RCCPtr(RCCPtr<T> const& other) {
+    x = other.x;
+    cnt = other.cnt;
+    (*cnt)++;
+  }
+
+  RCCPtr(RCPtr<T> const& other) {
+    x = other.x;
+    cnt = other.cnt;
+    (*cnt)++;
+  }
+
+  RCCPtr<T>& operator = (RCCPtr<T> const& other) {
+    (*cnt)--;
+    if (!*cnt) {
+      delete (T*) x;
+      delete cnt;
+    }
+    x = other.x;
+    cnt = other.cnt;
+    (*cnt)++;
+    return *this;
+  }
+  
+  ~RCCPtr() {
+    (*cnt)--;
+    if (!*cnt) {
+      delete (T*) x;
+      delete cnt;
+    }
+  }
+
+  T const* operator->() {return x;}
+  T const& operator*()  {return *x;}
+
+private:
+  T const * x;           // the object we are referring
+  int* cnt;              // how many smart pointers ?
+};
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/BaseTools/smathconst.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/smathconst.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/smathconst.h	(revision 2309)
@@ -0,0 +1,53 @@
+/* quelques  constantes mathematiques utiles */
+#ifndef SMATHCONST_H_SEEN
+#define SMATHCONST_H_SEEN
+
+#include "machdefs.h"
+#ifndef NO_VALUES_H
+#include <values.h>
+#else
+#include <math.h>
+#endif
+
+/* EA conflit entre les diverses copies de nbmath.h, nbconst.h... A nettoyer... */
+#undef  Pi   
+#undef  Pis2
+#undef  DeuxPi 
+#undef  SPi   
+#undef  S2Pi   
+#undef  Rac2   
+#undef  Log2   
+#undef  LnPi   
+#undef  LgPi   
+#undef  Ln10   
+#undef  DftoDm 
+#undef  Hln2pi 
+#undef  JourSec 
+#undef  AnSec  
+
+#undef  GRAND  
+#undef  GRAND2 
+#undef  IGRAND 
+
+#define  Pi     (double) ( 3.14159265358979310e+00)  /* c'est Pi */
+#define  Pis2   (double) (1.57079632679489655)       /* c'est Pi/2 */
+#define  DeuxPi (double) ( 6.28318530717958620e+00)  /* c'est 2*Pi */
+#define  SPi    (double) ( 1.77245385090551590e+00)  /* c'est sqrt(Pi) */
+#define  S2Pi   (double) ( 2.50662827463100020e+00)  /* c'est sqrt(2*Pi) */
+#define  Rac2   (double) ( 1.41421356237309510e+00)  /* c'est sqrt(2) */
+#define  Log2   (double) ( 3.01029995663981200e-01)  /* c'est log10(2) */
+#define  LnPi   (double) ( 1.14472988584940020e+00)  /* c'est ln(Pi) */
+#define  LgPi   (double) ( 4.97149872694133850e-01)  /* c'est log10(Pi) */
+#define  Ln10   (double) ( 2.30258509299404590e+00)  /* c'est ln(10) */
+#define  DftoDm (double) ( 1.08573620475812940e+00)  /* c'est 2.5/ln(10) */
+#define  Hln2pi (double) ( 9.18938533204672670e-01)  /* c'est Ln(2*pi)/2 */
+
+#define  JourSec (float) (86400.000000) /* nombre de secondes dans 24H */
+#define  AnSec  (int) (31557600) /* nombre de secondes dans 365.25 jours */
+
+#define  GRAND  (float)  (1.e+35)
+#define  GRAND2 (double) (1.e+35)
+#define  IGRAND (int_4) (2147483647)
+
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/BaseTools/sophyainit.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/sophyainit.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/sophyainit.cc	(revision 2309)
@@ -0,0 +1,151 @@
+#include "machdefs.h"
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <complex>
+
+#include "sophyainit.h"
+
+#include "pexceptions.h"
+
+#include "ppersist.h"
+#include "fiondblock.h"
+#include "dvlist.h"
+
+#include "sversion.h"
+
+// ---  Classe d'initialisation de SOPHYA, (PPersistMgr en particulier)
+int SophyaInitiator::FgInit = 0;
+
+/*!
+   \namespace SOPHYA
+   \brief This is the namespace for the whole Sophya package
+*/
+
+/*!
+  \class SOPHYA::SophyaInitiator
+  \ingroup BaseTools
+  Each Sophya module may contain an initialiser class which should
+  be a sub-class of SophyaInitiator.  
+*/
+
+SophyaInitiator::SophyaInitiator()
+{
+#if defined(Darwin)
+  // Il semble y avoir un probleme sous MacOSX ...
+  if (FgInit == 0) 
+    cout << " SophyaInitiator::SophyaInitiator() BaseTools Init" << endl;
+#endif
+  FgInit++;
+  if (FgInit > 1)  return;
+
+  InitFailNewHandler();
+
+  #ifdef xx__mac__
+  //InitToolBox();
+  //SIOUXSettings.initializeTB = FALSE;
+  SIOUXSettings.autocloseonquit = FALSE;
+  SIOUXSettings.asktosaveonclose = FALSE;
+  SIOUXSettings.showstatusline = TRUE;
+  #endif
+
+  PIOPersist::Initialize();
+  PPRegister(FIO_NDataBlock<uint_1>);
+  DObjRegister(FIO_NDataBlock<uint_1>, NDataBlock<uint_1>);
+  PPRegister(FIO_NDataBlock<uint_2>);
+  DObjRegister(FIO_NDataBlock<uint_2>, NDataBlock<uint_2>);
+  PPRegister(FIO_NDataBlock<int_2>);
+  DObjRegister(FIO_NDataBlock<int_2>, NDataBlock<int_2>);
+  PPRegister(FIO_NDataBlock<int_4>);
+  DObjRegister(FIO_NDataBlock<int_4>, NDataBlock<int_4>);
+  PPRegister(FIO_NDataBlock<int_8>);
+  DObjRegister(FIO_NDataBlock<int_8>, NDataBlock<int_8>);
+  PPRegister(FIO_NDataBlock<uint_4>);
+  DObjRegister(FIO_NDataBlock<uint_4>, NDataBlock<uint_4>);
+  PPRegister(FIO_NDataBlock<uint_8>);
+  DObjRegister(FIO_NDataBlock<uint_8>, NDataBlock<uint_8>);
+  PPRegister(FIO_NDataBlock<r_4>);
+  DObjRegister(FIO_NDataBlock<r_4>, NDataBlock<r_4>);
+  PPRegister(FIO_NDataBlock<r_8>);
+  DObjRegister(FIO_NDataBlock<r_8>, NDataBlock<r_8>);
+  PPRegister(FIO_NDataBlock< complex<r_4> >);
+  DObjRegister(FIO_NDataBlock< complex<r_4> >, NDataBlock< complex<r_4> >);
+  PPRegister(FIO_NDataBlock< complex<r_8> >);
+  DObjRegister(FIO_NDataBlock< complex<r_8> >, NDataBlock< complex<r_8> >);
+
+  PPRegister(ObjFileIO<DVList>);
+  DObjRegister(ObjFileIO<DVList>, DVList);
+
+
+#if (!defined(__GNUG__) && !defined(__MWERKS__) && !defined(HPUX))
+  // pas de bufferisation pour printf   cmv 18/3/97 selon E.A.
+  // setvbuf(stdout,NULL,_IOLBF,0); setvbuf(stderr,NULL,_IOLBF,0);
+  setlinebuf(stdout);
+  setlinebuf(stderr);
+#endif
+
+  // si var env SOPHYA_NOPRTVER definie pas de print
+  if(!getenv("SOPHYA_NOPRTVER")) Version(true);
+
+  int pnice;
+  char* snice = getenv("SOPHYA_NICE");
+  if (!snice) pnice=8;
+  else pnice = atoi(snice);
+  nice(pnice);
+
+}
+
+SophyaInitiator::~SophyaInitiator()
+{
+  FgInit--;
+/*
+  if (FgInit == 0)
+    {
+    delete PPersistMgr::classList; PPersistMgr::classList = NULL;
+    delete PShPersist::objList;    PShPersist::objList = NULL;
+    }
+    */
+}
+
+double SophyaInitiator::Version(bool fgprt)
+{
+if (fgprt) {
+  char* compiler = 0;
+  #ifdef __GNUG__
+  compiler = "gcc " __VERSION__;
+  #endif
+  #ifdef __DECCXX
+  compiler = "cxx " ;
+  #endif
+  #ifdef __aCC__
+  compiler = const_cast<char *>("HP-aCC ") ;
+  #endif
+  #ifdef __KCC__
+  compiler = const_cast<char *>("KCC ") ;
+  #endif
+  #ifdef __SGICC__
+  #ifdef SGI_ARCH64
+  compiler = const_cast<char *>("SGI-CC (-64) ") ;
+  #else
+  compiler = const_cast<char *>("SGI-CC ") ;
+  #endif
+  #endif
+  #ifdef __MWERKS__
+  compiler = const_cast<char *>("Codewarrior ");
+  #endif
+  fprintf(stderr,"SOPHYA Version %4.1f Revision %d (%s) -- %s %s %s\n",
+          SOPHYA_VERSION, SOPHYA_REVISION, SOPHYA_TAG,
+          __DATE__, __TIME__, compiler);
+}
+return(SOPHYA_VERSION + (SOPHYA_REVISION/1000.));
+}
+
+double SOPHYA::SophyaVersion()
+{
+return(SOPHYA_VERSION + (SOPHYA_REVISION/1000.));
+}
+ 
+// On met un objet initiator en statique, pour les loaders qui savent 
+// appeler le constructeur des objets statiques   Reza 08/98
+static SophyaInitiator psophyainit;
Index: /tags/V_Dec2002/SophyaLib/BaseTools/sophyainit.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/sophyainit.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/sophyainit.h	(revision 2309)
@@ -0,0 +1,31 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe d'initialiseur de module de SOPHYA
+
+#ifndef SOPHYAINIT_H_SEEN
+#define SOPHYAINIT_H_SEEN
+
+#include "machdefs.h"
+
+namespace SOPHYA {
+
+void PrintSophyaVersion(void);
+double SophyaVersion(void); /* Version + (Revision/1000) */
+
+// Classe d''initialisation pour les modules SOPHYA
+
+//! Initializer class for sophya modules
+class SophyaInitiator {
+private:
+  static int FgInit;
+public:
+  			SophyaInitiator();
+  virtual		~SophyaInitiator();
+  virtual double 	Version(bool fgprt=true);
+};
+
+#define SophyaInit() SophyaInitiator sophyainitiator
+
+} // Fin du namespace
+
+#endif
+
Index: /tags/V_Dec2002/SophyaLib/BaseTools/srandgen.c
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/srandgen.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/srandgen.c	(revision 2309)
@@ -0,0 +1,614 @@
+#include "machdefs.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <sys/time.h>
+#include "srandgen.h"
+#include "smathconst.h"
+
+static double GAU_RANGE=6.;
+
+/* 
+++ 
+  Module 	Tirages aleatoires (C)
+  Lib	LibsUtil
+  include	nbrandom.h
+--
+*/
+
+/*
+++
+  frand01()
+	tirage aleatoire entre 0 et 1, retourne float  
+  drand01()
+	tirage aleatoire entre 0 et 1, retourne double  
+  rand01()
+	 c'est le defaut: drand01()
+  frandpm1()
+	tirage aleatoire entre -1 et 1, retourne float
+  drandpm1()
+	tirage aleatoire entre -1 et 1, retourne double
+  ranfpm1()
+	c'est le defaut: drandpm1()
+--
+*/
+
+/*! \ingroup  BaseTools
+    \fn frand01
+    Returns a random number (float) with flat distribution between 0 ... 1
+*/
+/*! \ingroup  BaseTools
+    \fn drand01
+    Returns a random number (double) with flat distribution between 0 ... 1
+*/
+/*! \ingroup  BaseTools
+    \fn frandpm1() 
+    Returns a random number (float) with flat distribution between -1 ... 1
+*/
+/*! \ingroup  BaseTools
+    \fn drandpm1() 
+    Returns a random number (double) with flat distribution between -1 ... 1  
+*/
+
+/*=========================================================================*/
+/*
+++
+  void Ini_Ranf_Quick(long seed_val, int lp)
+	Initialisation rapide du generateur (drand48) par un entier
+	de 32 bits de type long (cf srand48).
+--
+*/
+
+/*! \ingroup  BaseTools
+    Fast initialisation of the random number generator \c (drand48) 
+    using a \c long type value (cf \c srand48 )
+*/
+void Ini_Ranf_Quick(long seed_val, int lp)
+{
+if(lp) printf("Ini_Ranf_Quick: %d\n",(int) seed_val);
+srand48(seed_val);
+return;
+}
+
+/*=========================================================================*/
+/*
+++
+  void Ini_Ranf(unsigned short seed_16v[3], int lp)
+	Initialisation complete du generateur (drand48) par
+	48 bits (cf seed48).
+--
+*/
+/*! \ingroup  BaseTools
+    complete initialisation of the random number generator \c (drand48) 
+    using a \c using 48 bits (cf \c seed48 )
+*/
+void Ini_Ranf(unsigned short seed_16v[3], int lp)
+{
+if(lp) printf("Ini_Ranf: %d %d %d\n"
+             ,seed_16v[0],seed_16v[1],seed_16v[2]);
+seed48(seed_16v);
+return;
+}
+
+/*=========================================================================*/
+/*
+++
+  void Get_Ranf(unsigned short seed_16v[3], int lp)
+	Recuperation de l'etat du generateur (drand48) sur
+	de 48 bits (cf seed48).
+--
+*/
+/*! \ingroup  BaseTools
+    Returns the status (48 bits) of the random number generator \c (drand48) 
+    (cf \c seed48 )
+*/
+void Get_Ranf(unsigned short seed_16v[3], int lp)
+{
+unsigned short seed[3] = {0,0,0};
+unsigned short *p;
+p = seed48(seed);
+memcpy(seed_16v,p,3*sizeof(unsigned short));
+if(lp) printf("Get_Ranf: %d %d %d\n"
+             ,seed_16v[0],seed_16v[1],seed_16v[2]);
+/* on re-initialise a ce qui etait avant */
+seed48(seed_16v);
+return;
+}
+
+/*=========================================================================*/
+/*
+++
+  void Auto_Ini_Ranf(int lp)
+	Initialisation automatique (pseudo) aleatoire du generateur.
+	L'initialiseur est donne par le nombre de millisecondes
+	ecoulees depuis le dernier jour multiple de 23 du nombre de jours
+	depuis le 0 heure le 1er Janvier 1970 UTC (cf gettimeofday).
+	Pour retomber sur la meme initialisation
+	il faut generer deux aleatoires a moins de 1/1000 seconde
+	ou generer le deuxieme aleatoire 23 jours apres le premier
+	a la meme heure (a 1/1000 de seconde pres). La fonction
+	d'initialisation utilisee est Ini_Ranf_Quick(long).
+--
+*/
+/*! \ingroup  BaseTools
+    Automatic initialisation using the present time
+*/
+void Auto_Ini_Ranf(int lp)
+{
+struct timeval now;
+long nj,nj23,seed=0;
+double buf;
+
+gettimeofday (&now,0);
+
+/* dans 32 bits signes on met environ 23 jours a 1/1000 de seconde pres! */
+/* Nombre de jours depuis l'origine */
+nj = (long) now.tv_sec / 86400;
+/* Nombre de jours depuis le dernier jour multiple de 23 jours */
+nj23 = nj % 23;
+/* nombre de secondes depuis le dernier jour multiple de 23 jours */
+buf = (double) (nj23*86400 + (now.tv_sec-nj*86400));
+/* nombre de milliemes de secondes depuis ... */
+buf = buf*1000. +  now.tv_usec/1000.;
+seed = (long) buf;
+
+if(lp) {
+  printf("Auto_Ini_Ranf: date %ld s %ld 10^-6 sec seed=%ld:\n"
+        ,(long)now.tv_sec,(long)now.tv_usec,seed);
+  if(lp>1) printf("... njours=%ld nj23=%ld buf=%.20g\n",nj,nj23,buf);
+}
+Ini_Ranf_Quick(seed,lp);
+return;
+}
+
+/*=========================================================================*/
+/*
+++
+  void SetGauRange(double range)
+	Generation de distribution gaussienne:
+	Changement de l'initialisation de l'excursion du tirage
+	en nombre de sigmas
+--
+*/
+void SetGauRange(double range)
+{
+GAU_RANGE = range;
+}
+
+/*=========================================================================*/
+/*
+++
+  float NorRand(void)
+	Generation aleatoire gaussienne normee centree
+--
+*/
+/*! \ingroup  BaseTools
+    Normal (Gaussian) random number generator (Mean=0., Sigma=1.)
+*/
+float NorRand(void)
+{
+double x,A,B;
+
+LAB10:
+A = drand01();
+if ( A == 0. ) goto LAB10;
+B = drand01();
+x = sqrt(-2.*log(A))*cos(DeuxPi*B);
+return( (float) x );
+}
+
+/*=========================================================================*/
+/*
+++
+  float NorRand1(void)
+	Generation aleatoire gaussienne normee centree
+	la distribution est limitee entre +/- GAU_RANGE (obsolete).
+--
+*/
+float NorRand1(void)
+{
+double b, x, y, gauss;
+
+b = 1./sqrt(2.*M_PI);
+LAB10:
+x = GAU_RANGE*drandpm1();
+y = drand01()*b;
+gauss = b*exp(-x*x/2.);
+if ( gauss-y < 0. ) goto LAB10 ;
+return( (float) x );
+}
+
+/*=========================================================================*/
+/*
+++
+  double GauRnd(double am, double s)
+	Generation aleatoire gaussienne de centre "am" et de sigma "s".
+--
+*/
+/*! \ingroup  BaseTools
+    Normal (Gaussian) random number generator with the specified mean
+    (\c am ) and sigma (\c s )
+*/
+double GauRnd(double am, double s)
+{
+double x,A,B;
+
+LAB10:
+A = drand01();
+if ( A == 0. ) goto LAB10;
+B = drand01();
+x = am + s * sqrt(-2.*log(A))*cos(DeuxPi*B);
+return(x);
+}
+
+/*=========================================================================*/
+/*
+++
+  double GauRnd1(double am, double s)
+	Generation aleatoire gaussienne de centre "am" et de
+	sigma "s" la distribution est limitee entre am +/- GAU_RANGE (obsolete).
+--
+*/
+double GauRnd1(double am, double s)
+{
+double s2, b, x, y, gauss;
+
+s2 = 2.*s*s;
+b = 1./sqrt(2.*M_PI*s);
+LAB10:
+x = am + GAU_RANGE*s*drandpm1();
+y = drand01()*b;
+gauss = b*exp(-(x-am)*(x-am)/s2);
+if ( gauss-y < 0. ) goto LAB10 ;
+return(x);
+}
+
+/*==========================================================================*/
+/*
+++
+  void NormGau(double *x,double *y,double mx,double my,double sa,double sb,double teta);
+	Tirage de 2 nombres aleatoires x et y distribues sur une gaussienne 2D
+	de centre (x=mx,y=my), de sigmas grand axe et petit axe (sa,sb)
+	et dont le grand axe fait un angle teta (radian) avec l'axe des x.
+--
+*/
+/*
+++
+| - La densite de probabilite (normalisee a 1) sur laquelle on tire est:
+| N*exp[-0.5*{ (A/sa)**2+(C/sc)**2 }],  N=1/(2Pi*sa*sc)
+| ou A et B sont les coordonnees selon le grand axe et le petit axe
+| et teta = angle(x,A), le resultat subit ensuite une rotation d'angle teta.
+| - La matrice des covariances C des variables A,B est:
+|   | sa^2   0   |
+|   |            |  et det(C) = (1-ro^2)*sa^2*sb^2
+|   |  0    sb^2 |
+| - La distribution x,y resultante est:
+| N*exp[-0.5*{[(dx/sx)^2-2*ro/(sx*sy)*dx*dy+(dy/sy)^2]/(1-ro^2)}]
+| ou N est donne dans NormCo et sx,sy,ro sont calcules a partir
+| de sa,sc,teta (voir fonctions paramga ou gaparam). La matrice des
+| covariances des variables x,y est donnee dans la fonction NormCo.
+--
+*/
+void NormGau(double *x,double *y
+            ,double mx,double my,double sa,double sb,double teta)
+{
+double c,s,X,Y;
+
+LAB10:
+ s = drand01();
+ if ( s == 0. ) goto LAB10;
+s = sqrt(-2.*log(s));
+c = DeuxPi * drand01();
+
+X = sa*s*cos(c);
+Y = sb*s*sin(c);
+
+c = cos(teta); s = sin(teta);
+*x = mx + c*X - s*Y;
+*y = my + s*X + c*Y;
+}
+
+/*==========================================================================*/
+/*
+++
+  int NormCo(double *x,double *y,double mx,double my,double sx,double sy,double ro)
+	Tirage de 2 nombres aleatoires x et y distribues sur une gaussienne 2D
+	de centre (mx,my), de coefficient de correlation rho (ro) et telle que
+	les sigmas finals des variables x et y soient sx,sy (ce sont
+	les valeurs des distributions marginales des variables aleatoires x et y
+	c'est a dire les sigmas des projections x et y de l'histogramme 2D
+	de la gaussienne). Retourne 0 si ok.
+--
+*/
+/*
+++
+| - La densite de probabilite (normalisee a 1) sur laquelle on tire est:
+|   N*exp[-0.5*{[(dx/sx)^2-2*ro/(sx*sy)*dx*dy+(dy/sy)^2]/(1-ro^2)}]
+|     avec dx = x-mx, dy = y-my et N = 1/[2Pi*sx*sy*sqrt(1-ro^2)]
+| - Dans ce cas la distribution marginale est (ex en X):
+|   1/(sqrt(2Pi)*sx) * exp[-0.5*{dx^2/sx^2}]
+| - La matrice des covariances C des variables x,y est:
+|   |   sx^2      ro*sx*sy |
+|   |                      |  et det(C) = (1-ro^2)*sx^2*sy^2
+|   | ro*sx*sy      sy^2   |
+| - La matrice inverse C^(-1) est:
+|   |   1/sx^2      -ro/(sx*sy) |
+|   |                           | * 1/(1-ro^2)
+|   | -ro/(sx*sy)      1/sy^2   |
+--
+*/
+/*
+++
+| - Remarque:
+| le sigma que l'on obtient quand on fait une coupe de la gaussienne 2D
+| en y=0 (ou x=0) est: SX0(y=0) = sx*sqrt(1-ro^2) different de sx
+|                      SY0(x=0) = sy*sqrt(1-ro^2) different de sy
+| La distribution qui correspond a des sigmas SX0,SY0
+| pour les coupes en y=0,x=0 de la gaussienne 2D serait:
+|   N*exp[-0.5*{ (dx/SX0)^2-2*ro/(SX0*SY0)*dx*dy+(dy/SY0)^2 }]
+| avec N = sqrt(1-ro^2)/(2Pi*SX0*SY0) et les variances
+| des variables x,y sont toujours
+|  sx=SX0/sqrt(1-ro^2), sy=SY0/sqrt(1-ro^2)
+--
+*/
+int NormCo(double *x,double *y
+          ,double mx,double my,double sx,double sy,double ro)
+{
+double a,b,sa;
+if( ro <= -1. || ro >= 1. ) return(1);
+LAB10:
+ b = drand01();
+ if ( b == 0. ) goto LAB10;
+b = sqrt(-2.*log(b));
+a = DeuxPi * drand01();
+sa = sin(a);
+
+*x = mx + sx*b*(sqrt(1.-ro*ro)*cos(a)+ro*sa);
+*y = my + sy*b*sa;
+
+return(0);
+}
+
+/*==========================================================================*/
+/*
+++
+  Titre	Exemple d'utilisation des aleatoires avec initialisation.
+--
+*/
+/*
+++
+|   #include "nbrandom.h"
+|   
+|   void main() {
+|   long i,ini=123456789;
+|   unsigned short seed[3];
+|   
+|   printf(" 1./ ==> test nitialisation par un long\n");
+|   Ini_Ranf_Quick(ini,1);
+|   for(i=0;i<10;i++) printf("%d  -> %f\n",i,ranf01());
+--
+*/
+/*
+++
+|   
+|   printf("\n 2./ ==> test initialisation par tableau de 3 unsigned short\n");
+|   Ini_Ranf_Quick(ini,1);
+|   for(i=0;i<5;i++) printf("%d  -> %f\n",i,ranf01());
+|   Get_Ranf(seed,1);
+|   for(i=5;i<10;i++) printf("%d  -> %f\n",i,ranf01());
+|   Ini_Ranf(seed,1);
+|   for(i=5;i<10;i++) printf("%d  -> %f\n",i,ranf01());
+|   Get_Ranf(seed,1);
+--
+*/
+/*
+++
+|   
+|   printf("\n 3./ ==> test initialisation automatique\n");
+|   Auto_Ini_Ranf(2);
+|   for(i=0;i<5;i++) printf("%d  -> %f\n",i,ranf01());
+|   i=0; while(i<10000000) i++;
+|   Auto_Ini_Ranf(2);
+|   for(i=0;i<5;i++) printf("%d  -> %f\n",i,ranf01());
+|   i=0; while(i<10000000) i++;
+|   Auto_Ini_Ranf(2);
+|   for(i=0;i<5;i++) printf("%d  -> %f\n",i,ranf01());
+|   }
+--
+*/
+/*
+++
+|    1./ ==> test initialisation par un long
+|   Ini_Ranf_Quick: 123456789
+|   0  -> 0.052468
+|   1  -> 0.025444
+|   2  -> 0.099272
+|   3  -> 0.436130
+|   4  -> 0.327740
+|   5  -> 0.821202
+|   6  -> 0.560493
+|   7  -> 0.018157
+|   8  -> 0.872758
+|   9  -> 0.652496
+--
+*/
+/*
+++
+|   
+|    2./ ==> test initialisation par tableau de 3 unsigned short
+|   Ini_Ranf_Quick: 123456789
+|   0  -> 0.052468
+|   1  -> 0.025444
+|   2  -> 0.099272
+|   3  -> 0.436130
+|   4  -> 0.327740
+--
+*/
+/*
+++
+|   Get_Ranf: 36117 51106 21478
+|   5  -> 0.821202
+|   6  -> 0.560493
+|   7  -> 0.018157
+|   8  -> 0.872758
+|   9  -> 0.652496
+--
+*/
+/*
+++
+|   Ini_Ranf: 36117 51106 21478
+|   5  -> 0.821202
+|   6  -> 0.560493
+|   7  -> 0.018157
+|   8  -> 0.872758
+|   9  -> 0.652496
+|   Get_Ranf: 16576 62373 42761
+--
+*/
+/*
+++
+|   
+|    3./ ==> test initialisation automatique
+|   Auto_Ini_Ranf: date 887117206 s 868138 10^-6 sec seed=826006868:
+|   ... njours=10267 nj23=9 buf=826006868.13800001
+|   Ini_Ranf_Quick: 826006868
+|   0  -> 0.798860
+|   1  -> 0.342478
+|   2  -> 0.401300
+|   3  -> 0.442912
+|   4  -> 0.170912
+--
+*/
+/*
+++
+|   Auto_Ini_Ranf: date 887117207 s 188779 10^-6 sec seed=826007188:
+|   ... njours=10267 nj23=9 buf=826007188.77900004
+|   Ini_Ranf_Quick: 826007188
+|   0  -> 0.455599
+|   1  -> 0.811427
+|   2  -> 0.703880
+|   3  -> 0.409569
+|   4  -> 0.390399
+--
+*/
+/*
+++
+|   Auto_Ini_Ranf: date 887117207 s 489750 10^-6 sec seed=826007489:
+|   ... njours=10267 nj23=9 buf=826007489.75
+|   Ini_Ranf_Quick: 826007489
+|   0  -> 0.567094
+|   1  -> 0.893156
+|   2  -> 0.975995
+|   3  -> 0.531331
+|   4  -> 0.834354
+--
+*/
+/*==========================================================================*/
+
+/*==========================================================================*/
+/* 
+++ 
+  Module 	Tirages aleatoires selon une fonction (C)
+  Lib	LibsUtil
+  include	nbrandom.h
+--
+*/
+/*
+++
+  TIREALEA *init_tirage_alea(int nbin,double xmin,double xmax,double (*fonc) (double))
+	Initialise la structure qui va permettre le tirage aleatoire
+	d'un nombre compris entre xmin et xmax selon la
+	distribution fonc (histo de nbin bins)
+--
+*/
+TIREALEA *init_tirage_alea(int nbin,double xmin,double xmax,double (*fonc) (double))
+{
+int sof,i;
+double x;
+struct tirage_alea *t;
+
+if ( xmax-xmin<0.) return(NULL);
+
+if(nbin<=3) nbin=50;
+
+sof = sizeof(struct tirage_alea);
+if( (t = (struct tirage_alea*)malloc(sof) ) == NULL ) {
+  printf("impossible d'allouer *tirage_alea par malloc \n");
+  return(NULL);
+}
+
+t->Nbin=nbin; t->Min=xmin; t->Max=xmax; t->Lbin=(xmax-xmin) /nbin;
+
+sof = nbin * sizeof(double);
+if( (t->Tab = (double*)malloc(sof) ) == NULL ) {
+  printf("impossible d'allouer *tirage_alea.Tab par malloc \n");
+  return(NULL);
+}
+
+x = xmin + .5*t->Lbin;
+t->Tab[0] =  fonc(x);
+for(i=1;i<nbin;i++) {
+  x = xmin + (i+.5)*t->Lbin;
+  t->Tab[i] = t->Tab[i-1] + fonc(x);
+}
+
+for(i=0;i<nbin-1;i++)  t->Tab[i] /= t->Tab[nbin-1];
+t->Tab[nbin-1] = 1.;
+
+return(t);
+}
+
+/*==========================================================================*/
+/*
+++
+  double tirage_alea( TIREALEA *alea )
+	tirage aleatoire d'un nombre compris entre xmin et xmax
+	selon la fonction fonc (cf init_tirage_alea).
+--
+*/
+double tirage_alea( TIREALEA *alea )
+{ 
+int i,ibin = -1;
+double z,t1,t2,x1,x2,t;
+
+z=drand01();
+/* protections z<=0 ou z>=1 */
+if( z <= 0. ) return ( alea->Min );
+if( z >= 1. ) return ( alea->Max );
+/* cas z <= tab[0] */
+if(z <= alea->Tab[0]) {
+  t = alea->Min + (alea->Lbin/2.)/alea->Tab[0] * z;
+  return (t);
+}
+
+/* recherche du premier bin plus grand que z */
+for(i=0;i<alea->Nbin;i++) {
+  ibin=i;
+  if ( z < alea->Tab[i] ) break;
+}
+
+/* extrapolation pour trouver la valeur du tirage aleatoire */
+if( ibin == alea->Nbin-1 ) ibin--;
+t1=alea->Tab[ibin];
+x1 = alea->Min + (ibin+0.5) * alea->Lbin;
+t2=alea->Tab[ibin+1];
+x2 = x1 + alea->Lbin;
+t = x1 + (x2-x1)/(t2-t1) *(z-t1);
+if ( t < alea->Min ) t = alea->Min;
+if ( t > alea->Max ) t = alea->Max;
+return(t);
+}
+
+/*==========================================================================*/
+/*
+++
+  int end_tirage_alea( TIREALEA *alea )
+	De-allocation de la structure qui a permis le tirage aleatoire.
+--
+*/
+int end_tirage_alea( TIREALEA *alea )
+{ 
+if ( alea != NULL ) { free(alea); return(0);}
+  else return(-1);
+}
Index: /tags/V_Dec2002/SophyaLib/BaseTools/srandgen.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/srandgen.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/srandgen.h	(revision 2309)
@@ -0,0 +1,57 @@
+/* fonctions pour generateurs aleatoires     */
+/*                         cmv  23/06/94     */
+/*  R.Ansari 04/2000  Copie de nbrand.h .c   */
+
+#ifndef SRANDGEN_H_SEEN
+#define SRANDGEN_H_SEEN
+
+#include "machdefs.h"
+#include <stdlib.h>
+#ifdef __MWERKS__
+#include "unixmac.h"
+#endif
+
+#define frand01() ( (float) drand48() )
+#define drand01() ( drand48() )
+#define ranf01() drand01()
+
+#define frandpm1() ( 2. * frand01() - 1.)
+#define drandpm1() ( 2. * drand01() - 1.)
+#define ranfpm1() drandpm1()
+
+struct tirage_alea {
+  int Nbin;
+  double Min,Max,Lbin;
+  double *Tab;
+};
+typedef struct tirage_alea TIREALEA;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void Ini_Ranf_Quick(long seed_val, int lp);
+void Ini_Ranf(unsigned short seed_16v[3], int lp);
+void Get_Ranf(unsigned short seed_16v[3], int lp);
+void Auto_Ini_Ranf(int lp);
+
+void SetGauRange(double range);
+float NorRand1(void);
+double GauRnd1(double am, double s);
+float NorRand(void);
+double GauRnd(double am, double s);
+int NormCo(double *a,double *b
+          ,double mx,double my,double sx,double sy,double ro);
+void NormGau(double *x,double *y
+            ,double mx,double my,double sa,double sb,double teta);
+
+TIREALEA *init_tirage_alea(int nbin,double xmin,double xmax,double (*fonc) (double));
+double tirage_alea(TIREALEA *alea);
+int end_tirage_alea(TIREALEA *alea);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Index: /tags/V_Dec2002/SophyaLib/BaseTools/sversion.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/BaseTools/sversion.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/BaseTools/sversion.h	(revision 2309)
@@ -0,0 +1,8 @@
+#ifndef SVERSION_H
+#define SVERSION_H
+
+#define SOPHYA_VERSION   1.5
+#define SOPHYA_REVISION  00
+#define SOPHYA_TAG       "V_Dec2002"
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/HiStats/Makefile
===================================================================
--- /tags/V_Dec2002/SophyaLib/HiStats/Makefile	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/HiStats/Makefile	(revision 2309)
@@ -0,0 +1,120 @@
+include ../Mgr/Makefile.h
+ 
+all: $(LIB)libHiStats.a
+clean:
+	rm -f $(OBJ)hisprof.o $(OBJ)histinit.o $(OBJ)histos.o $(OBJ)histos2.o $(OBJ)ntupintf.o $(OBJ)ntuple.o $(OBJ)proxtuple.o $(OBJ)xntuple.o
+	rm -f $(LIB)libHiStats.a
+$(LIB)libHiStats.a : $(OBJ)hisprof.o $(OBJ)histinit.o $(OBJ)histos.o $(OBJ)histos2.o $(OBJ)ntupintf.o $(OBJ)ntuple.o $(OBJ)proxtuple.o $(OBJ)xntuple.o
+	$(ARCXX) $(ARCXXFLAGS) $@ $($(ARARGS))
+ifeq ($(CXX),cxx)
+	$(CXX) $? $(CPPFLAGS) $(CXXFLAGS) -o $(OBJ)xx.x -Hf
+endif 
+ 
+$(OBJ)hisprof.o: hisprof.cc $(INC)machdefs.h \
+ hisprof.h $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)pexceptions.h \
+ $(INC)fmath.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h histos.h
+$(OBJ)histinit.o: histinit.cc $(INC)machdefs.h \
+ histinit.h $(INC)ntoolsinit.h \
+ $(INC)tarrinit.h \
+ $(INC)sophyainit.h histos.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)fmath.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h histos2.h hisprof.h ntuple.h \
+ ntupintf.h xntuple.h
+$(OBJ)histos.o: histos.cc $(INC)machdefs.h histos.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)fmath.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)poly.h \
+ $(INC)strutil.h
+$(OBJ)histos2.o: histos2.cc $(INC)machdefs.h \
+ histos2.h $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)pexceptions.h \
+ $(INC)fmath.h histos.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h
+$(OBJ)ntupintf.o: ntupintf.cc ntupintf.h \
+ $(INC)machdefs.h
+$(OBJ)ntuple.o: ntuple.cc $(INC)strutil.h \
+ $(INC)perrors.h \
+ $(INC)pexceptions.h \
+ $(INC)machdefs.h ntuple.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h ntupintf.h \
+ $(INC)dvlist.h \
+ $(INC)mutyv.h
+$(OBJ)proxtuple.o: proxtuple.cc proxtuple.h ntuple.h \
+ $(INC)objfio.h \
+ $(INC)machdefs.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h ntupintf.h \
+ $(INC)dvlist.h \
+ $(INC)mutyv.h
+$(OBJ)xntuple.o: xntuple.cc $(INC)ppersist.h \
+ $(INC)machdefs.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)perrors.h xntuple.h ntupintf.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h
Index: /tags/V_Dec2002/SophyaLib/HiStats/Makefile.am
===================================================================
--- /tags/V_Dec2002/SophyaLib/HiStats/Makefile.am	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/HiStats/Makefile.am	(revision 2309)
@@ -0,0 +1,7 @@
+lib_LIBRARIES = libHiStats.a
+
+libHiStats_a_SOURCES = \
+hisprof.cc  histinit.cc  histos.cc  histos2.cc  ntuple.cc  xntuple.cc
+
+
+DEFS = -I.. -I../include
Index: /tags/V_Dec2002/SophyaLib/HiStats/hbook.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/HiStats/hbook.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/HiStats/hbook.h	(revision 2309)
@@ -0,0 +1,83 @@
+/* link to hbook     */
+/*      CMV  94      */
+
+#ifndef HBOOK_H_SEEN
+#define HBOOK_H_SEEN
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void hbandx_(int_4 *,r_4 *,r_4 *,r_4 *);
+void hbandy_(int_4 *,r_4 *,r_4 *,r_4 *);
+
+void hbarx_(int_4 *);
+void hbary_(int_4 *);
+
+void hbfun1_(int_4 *,char *,int_4 *,r_4 *,r_4 *,r_4 fun(r_4 *),int_4);
+void hbfun2_(int_4 *,char *,int_4 *,r_4 *,r_4 *,int_4 *,r_4 *,r_4 *
+            ,r_4 fun(r_4 *,r_4 *),int_4);
+void hbigbi_(int_4 *,int_4 *);
+void hbook1_(int_4 *,char *,int_4 *,r_4 *,r_4 *,r_4 *,int_4);
+void hbook2_(int_4 *,char *,int_4 *,r_4 *,r_4 *
+            ,int_4 *,r_4 *,r_4 *,r_4 *,int_4);
+void hbpro_(int_4 *,r_4 *);
+void hbprof_(int_4 *,char *,int_4 *,r_4 *,r_4 *
+            ,r_4 *,r_4 *,char *,int_4,int_4);
+void hbprox_(int_4 *,r_4 *);
+void hbproy_(int_4 *,r_4 *);
+void hbslix_(int_4 *,int_4 *,r_4 *);
+void hbsliy_(int_4 *,int_4 *,r_4 *);
+void hcdir_(char *,char *,int_4,int_4);
+void hdelet_(int_4 *);
+void hfill_(int_4 *,r_4 *,r_4 *,r_4 *);
+void hfithn_(int_4 *,char *,char *,int_4 *,r_4 *
+            ,r_4 *,r_4 *,r_4 *,r_4 *,r_4 *,int_4,int_4);
+void hfn_(int_4 *,r_4 *);
+void hfunc_(int_4 *,r_4 fun(r_4 *));
+void hgive_(int_4 *,char *,int_4 *,r_4 *,r_4 *
+                          ,int_4 *,r_4 *,r_4 *,int_4 *,int_4 *);
+void hgn_(int_4 *,int_4 *,int_4 *,r_4 *,int_4 *);
+void hgnf_(int_4 *,int_4 *,r_4 *,int_4 *);
+void hgnpar_(int_4 *,char *,int_4);
+r_4 hi_(int_4 *,int_4 *);
+void hidopt_(int_4 *,char *,int_4);
+r_4 hie_(int_4 *,int_4 *);
+r_4 hif_(int_4 *,int_4 *);
+r_4 hij_(int_4 *,int_4 *,int_4 *);
+void hijxy_(int_4 *,int_4 *,int_4 *,r_4 *,r_4 *);
+void hix_(int_4 *,int_4 *,r_4 *);
+void hldir_(char *,char *,int_4,int_4);
+void hmdir_(char *,char *,int_4,int_4);
+r_4 hmax_(int_4 *);
+void hmaxim_(int_4 *,r_4 *);
+r_4 hmin_(int_4 *);
+void hminim_(int_4 *,r_4 *);
+void hnorma_(int_4 *,r_4 *);
+void hnoent_(int_4 *,int_4 *);
+void hpak_(int_4 *,r_4 *);
+void hpake_(int_4 *,r_4 *);
+void hprint_(int_4 *);
+void hrend_(char *,int_4);
+void hrin_(int_4 *,int_4 *,int_4 *);
+r_4 hrndm1_(int_4 *);
+void hrndm2_(int_4 *,r_4 *,r_4 *);
+void hropen_(int_4 *,char *,char *,char *,int_4 *,int_4 *,int_4,int_4,int_4);
+void hrout_(int_4 *,int_4 *,char *,int_4);
+void hscale_(int_4 *,r_4 *);
+r_4 hstati_(int_4 *,int_4 *,char *,int_4 *,int_4);
+r_4 hsum_(int_4 *);
+void hunpak_(int_4 *,r_4 *,char *,int_4 *,int_4);
+void hunpke_(int_4 *,r_4 *,char *,int_4 *,int_4);
+r_4 hx_(int_4 *,r_4 *);
+r_4 hxe_(int_4 *,r_4 *);
+r_4 hxi_(int_4 *,r_4 *,int_4 *);
+r_4 hxyij_(int_4 *,r_4 *,r_4 *,int_4 *,int_4 *);
+r_4 hxy_(int_4 *,r_4 *,r_4 *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Index: /tags/V_Dec2002/SophyaLib/HiStats/hisprof.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/HiStats/hisprof.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/HiStats/hisprof.cc	(revision 2309)
@@ -0,0 +1,401 @@
+#include "machdefs.h"
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+#include "hisprof.h"
+#include "perrors.h"
+
+/*!
+  \class SOPHYA::HProf
+  \ingroup HiStats
+  Classe de profil d'histogrammes.
+*/
+
+/********* Methode *********/
+/*!
+  Constructeur par defaut.
+*/
+HProf::HProf()
+: Histo()
+, SumY(NULL), SumY2(NULL), SumW(NULL), Ok(false), YMin(1.), YMax(-1.), Opt(0)
+{
+ END_CONSTRUCTOR
+}
+
+/********* Methode *********/
+/*!
+  Constructeur. Histogramme de profil de ``nBin'' bins entre ``xMin''
+  et ``xMax'' avec coupure d'acceptance sur y entre ``yMin'' et ``yMax''.
+  Si yMin>=yMax alors pas de coupure d'acceptance sur y.
+  Par defaut l'erreur du profil represente la dispersion dans le bin,
+  SetErrOpt(1) permet de demander de calculer l'erreur sur la moyenne.
+*/
+HProf::HProf(r_8 xMin, r_8 xMax, int_4 nBin, r_8 yMin, r_8 yMax)
+: Histo(xMin,xMax,nBin)
+, SumY( (nBin>0) ? new r_8[nBin] : NULL)
+, SumY2((nBin>0) ? new r_8[nBin] : NULL)
+, SumW( (nBin>0) ? new r_8[nBin] : NULL)
+, Ok(false), YMin(yMin), YMax(yMax), Opt(0)
+{
+  Histo::Errors();
+  Zero();
+  END_CONSTRUCTOR
+}
+
+/********* Methode *********/
+/*!
+  Constructeur.
+*/
+HProf::HProf(r_4 xMin, r_4 xMax, int_4 nBin, r_4 yMin, r_4 yMax)
+: Histo((r_8)xMin,(r_8)xMax,nBin)
+, SumY( (nBin>0) ? new r_8[nBin] : NULL)
+, SumY2((nBin>0) ? new r_8[nBin] : NULL)
+, SumW( (nBin>0) ? new r_8[nBin] : NULL)
+, Ok(false), YMin((r_8)yMin), YMax((r_8)yMax), Opt(0)
+{
+  Histo::Errors();
+  Zero();
+  END_CONSTRUCTOR
+}
+
+/********* Methode *********/
+/*!
+  Constructeur par copie.
+*/
+HProf::HProf(const HProf& H)
+: Histo(H)
+, SumY((H.mBins>0)  ? new r_8[H.mBins] : NULL)
+, SumY2((H.mBins>0) ? new r_8[H.mBins] : NULL)
+, SumW((H.mBins>0)  ? new r_8[H.mBins] : NULL)
+, Ok(H.Ok), YMin(H.YMin), YMax(H.YMax), Opt(H.Opt)
+{
+  if(mBins>0) {
+    memcpy(SumY,  H.SumY,  mBins*sizeof(r_8));
+    memcpy(SumY2, H.SumY2, mBins*sizeof(r_8));
+    memcpy(SumW,  H.SumW,  mBins*sizeof(r_8));
+  }
+  UpdateHisto();
+  END_CONSTRUCTOR
+}
+
+/********* Methode *********/
+/*!
+  Des-allocation
+*/
+void HProf::Delete()
+{
+  if( SumY  != NULL ) { delete[] SumY;  SumY = NULL;}
+  if( SumY2 != NULL ) { delete[] SumY2; SumY2 = NULL;}
+  if( SumW  != NULL ) { delete[] SumW;  SumW = NULL;}
+  Ok = false;
+}
+
+/********* Methode *********/
+/*!
+  Destructeur
+*/
+HProf::~HProf()
+{
+Delete();
+}
+
+/********* Methode *********/
+/*!
+Calcule la partie histogramme du profile si elle n'est pas a jour.
+*/
+void HProf::UpdateHisto(bool force) const
+{
+if(!Ok || force) updatehisto();
+}
+
+/********* Methode *********/
+/*!
+  Remise a zero
+*/
+void HProf::Zero()
+{
+  memset(SumY,  0, mBins*sizeof(r_8));
+  memset(SumY2, 0, mBins*sizeof(r_8));
+  memset(SumW,  0, mBins*sizeof(r_8));
+  Ok = false;
+  Histo::Zero();
+}
+
+
+/********* Methode *********/
+/*!
+  Pour changer l'option de calcul de l'erreur du profile.
+  Si ``spread'' = true alors l'erreur represente la dispersion
+  des donnees dans le bin, si = false elle represente l'erreur
+  sur la moyenne du bin.
+  \verbatim
+    - Pour le bin (j):
+    H(j) = sum(y), E(j) = sum(y^2), L(j) = sum(w)
+    ->  s(j) = sqrt(E(j)/L(j) - (H(j)/L(j))^2)  dispersion
+    ->  e(j) = s(j)/sqrt(L(j)) erreur sur la moyenne
+    spread=true:  opt=0 : dispersion des donnees dans le bin = s(j)
+    spread=false: opt=1 : erreur sur la moyenne du bin = e(j)
+  \endverbatim
+*/
+void HProf::SetErrOpt(bool spread)
+{
+uint_2 opt = (spread) ? 0 : 1;
+if(opt!=Opt) {Opt=opt; Ok=false;}
+}
+
+/********* Methode *********/
+/*!
+  Pour mettre a jour l'histogramme de profil.
+  Il est important d'appeler cette methode si on veut
+  utiliser les methodes de la classe Histo qui ne sont
+  pas redefinies dans la classe HProf.
+  En effet, pour des raisons de precision la classe
+  HProf travaille avec des tableaux en double precision
+  et seulement au moment ou l'on a besoin de l'histogramme
+  ce dernier est rempli avec les valeurs demandees (moyenne
+  et dispersion/erreur sur la moyenne).
+*/
+void HProf::updatehisto() const
+{
+r_8 m,e2;
+if(mBins>0) for(int_4 i=0;i<mBins;i++) {
+  if(SumW[i]<=0.) {
+    m = e2 = 0.;
+  } else {
+    m  = SumY[i]/SumW[i];
+    e2 = SumY2[i]/SumW[i] - m*m;
+    if(Opt) e2 /= SumW[i];
+  }
+  mData[i] = m;
+  mErr2[i] = e2;
+}
+Ok = true;
+// Attention, a cause de "WriteSelf const" updatehisto doit etre "const".
+// Comme on veut modifier Ok, on est oblige de faire cette entourloupe:
+HProf *buff = (HProf *) this;
+buff->Ok = true;
+}
+
+/********* Methode *********/
+/*!
+  Addition au contenu de l'histo pour abscisse x de la valeur y et poids w
+*/
+void HProf::Add(r_8 x, r_8 y, r_8 w)
+{
+  if(YMax>YMin && (y<YMin || YMax<y)) return;
+  int_4 numBin = FindBin(x);
+  if (numBin<0) mUnder += w;
+  else if (numBin>=mBins) mOver += w;
+  else {
+    Ok = false;
+    y *= w;
+    SumY[numBin]  += y;
+    SumY2[numBin] += y*y;
+    SumW[numBin]  += w;
+    nHist += w;
+    nEntries++;
+  }
+}
+
+/********* Methode *********/
+/*!
+  Addition au contenu de l'histo bin numBin de la valeur y poids w
+*/
+void HProf::AddBin(int_4 numBin, r_8 y, r_8 w)
+{
+  if(YMax>YMin && (y<YMin || YMax<y)) return;
+  if (numBin<0) mUnder += w;
+  else if (numBin>=mBins) mOver += w;
+  else {
+    Ok = false;
+    y *= w;
+    SumY[numBin]  += y;
+    SumY2[numBin] += y*y;
+    SumW[numBin]  += w;
+    nHist += w;
+    nEntries++;
+  }
+}
+
+/********* Methode *********/
+/*!
+  Operateur HProf H = H1
+*/
+HProf& HProf::operator = (const HProf& h)
+{
+if(this == &h) return *this;
+if( h.mBins > mBins ) Delete();
+Histo *hthis = (Histo *) this;
+*hthis = (Histo) h;
+if(!SumY)  SumY  = new r_8[mBins];
+if(!SumY2) SumY2 = new r_8[mBins];
+if(!SumW)  SumW  = new r_8[mBins];
+memcpy(SumY,  h.SumY,  mBins*sizeof(r_8));
+memcpy(SumY2, h.SumY2, mBins*sizeof(r_8));
+memcpy(SumW,  h.SumW,  mBins*sizeof(r_8));
+Ok = h.Ok;
+YMin = h.YMin;
+YMax = h.YMax;
+Opt = h.Opt;
+
+return *this;
+}
+
+/********* Methode *********/
+/*!
+  Operateur HProf H += H1
+
+  Attention dans cette addition il n'y a pas de gestion
+  des YMin et YMax. L'addition est faite meme si les limites
+  en Y de ``a'' sont differentes de celles de ``this''.
+*/
+HProf& HProf::operator += (const HProf& a)
+{
+if(mBins!=a.mBins) THROW(sizeMismatchErr);
+Histo *hthis = (Histo *) this;
+*hthis += (Histo) a;
+if(mBins>0) for(int_4 i=0;i<mBins;i++) {
+  SumY[i]  += a.SumY[i];
+  SumY2[i] += a.SumY2[i];
+  SumW[i]  += a.SumW[i];
+}
+updatehisto();
+
+return *this;
+}
+
+/********* Methode *********/
+/*!
+  Pour rebinner l'histogramme de profile sur nbinew bins
+*/
+void HProf::HRebin(int_4 nbinew)
+{
+  if( mBins <= 0 ) return; // createur par default
+  if( nbinew <= 0 ) return;
+
+  // memorisation de l'HProf original
+  HProf H(*this);
+
+  // Rebin de la partie Histo
+  int_4 binold = mBins;
+  Histo::HRebin(nbinew);
+
+  // Le nombre de bins est il plus grand ??
+  if( mBins > binold ) {
+    delete [] SumY;  SumY  = new r_8[nbinew]; memset(SumY, 0,mBins*sizeof(r_8));
+    delete [] SumY2; SumY2 = new r_8[nbinew]; memset(SumY2,0,mBins*sizeof(r_8));
+    delete [] SumW;  SumW  = new r_8[nbinew]; memset(SumW, 0,mBins*sizeof(r_8));
+  }
+
+  // Remplissage des parties propres au HPprof
+  for(int_4 i=0;i<mBins;i++) {
+    r_8 xmi = BinLowEdge(i);
+    r_8 xma = BinHighEdge(i);
+    int_4 imi =  H.FindBin(xmi);
+    if( imi < 0 ) imi = 0;
+    int_4 ima =  H.FindBin(xma);
+    if( ima >= H.mBins ) ima = H.mBins-1;
+    r_8 wY = 0., wY2 = 0., wW = 0.;
+    if( ima == imi ) {
+      wY  = H.SumY[imi]  * binWidth/H.binWidth;
+      wY2 = H.SumY2[imi] * binWidth/H.binWidth;
+      wW  = H.SumW[imi]  * binWidth/H.binWidth;
+    } else {
+      wY  += H.SumY[imi]  * (H.BinHighEdge(imi)-xmi)/H.binWidth;
+      wY  += H.SumY[ima]  * (xma -H.BinLowEdge(ima))/H.binWidth;
+      wY2 += H.SumY2[imi] * (H.BinHighEdge(imi)-xmi)/H.binWidth;
+      wY2 += H.SumY2[ima] * (xma -H.BinLowEdge(ima))/H.binWidth;
+      wW  += H.SumW[imi]  * (H.BinHighEdge(imi)-xmi)/H.binWidth;
+      wW  += H.SumW[ima]  * (xma -H.BinLowEdge(ima))/H.binWidth;
+      if(ima>imi+1) for(int_4 ii=imi+1;ii<ima;ii++)
+	{wY += H.SumY[ii]; wY2 += H.SumY2[ii]; wW += H.SumW[ii];}
+    }
+    SumY[i] += wY; SumY2[i] += wY2; SumW[i] += wW;
+  }
+  // On synchronise les tableaux Sum?? et l'Histogramme
+  updatehisto();
+}
+
+void HProf::Show(ostream & os) const
+{
+  UpdateHisto();
+  Histo::Show(os);
+}
+
+///////////////////////////////////////////////////////////
+// --------------------------------------------------------
+//   Les objets delegues pour la gestion de persistance 
+// --------------------------------------------------------
+///////////////////////////////////////////////////////////
+
+
+void ObjFileIO<HProf>::ReadSelf(PInPersist& is)
+{
+char strg[256];
+
+if(dobj==NULL) dobj=new HProf;
+  else         dobj->Delete();
+
+// Lecture entete
+is.GetLine(strg,255);
+
+// Lecture des valeurs
+is.Get(dobj->mBins);
+is.Get(dobj->YMin);
+is.Get(dobj->YMax);
+is.Get(dobj->Opt);
+dobj->Ok = true;
+
+// Lecture des donnees propres a l'histogramme de profil.
+is.GetLine(strg,255);
+dobj->SumY  = new r_8[dobj->mBins];
+dobj->SumY2 = new r_8[dobj->mBins];
+dobj->SumW  = new r_8[dobj->mBins];
+is.Get(dobj->SumY,  dobj->mBins);
+is.Get(dobj->SumY2, dobj->mBins);
+is.Get(dobj->SumW,  dobj->mBins);
+
+// Lecture de l'histogramme
+is >> (Histo&)(*dobj);
+return;
+}
+
+void ObjFileIO<HProf>::WriteSelf(POutPersist& os) const
+{
+if (dobj == NULL)   return;
+char strg[256];
+
+dobj->UpdateHisto();
+
+// Ecriture entete pour identifier facilement
+sprintf(strg,"HProf: YMin=%f  YMax=%f  Opt=%1d",dobj->YMin,dobj->YMax,dobj->Opt);
+os.PutLine(strg);
+
+// Ecriture des valeurs
+os.Put(dobj->mBins);
+os.Put(dobj->YMin);
+os.Put(dobj->YMax);
+os.Put(dobj->Opt);
+
+// Ecriture des donnees propres a l'histogramme de profil.
+sprintf(strg,"HProf: SumY SumY2 SumW");
+os.PutLine(strg);
+os.Put(dobj->SumY,  dobj->mBins);
+os.Put(dobj->SumY2, dobj->mBins);
+os.Put(dobj->SumW,  dobj->mBins);
+
+// Ecriture de l'histogramme
+// FIO_Histo fio_h((Histo&)*dobj);
+// fio_h.Write(os);
+os << (Histo&)(*dobj);
+
+return;
+}
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template ObjFileIO<HProf>
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class ObjFileIO<HProf>;
+#endif
Index: /tags/V_Dec2002/SophyaLib/HiStats/hisprof.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/HiStats/hisprof.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/HiStats/hisprof.h	(revision 2309)
@@ -0,0 +1,107 @@
+#ifndef HISPROF_SEEN
+#define HISPROF_SEEN
+
+#include <stdio.h>
+#include "peida.h"
+#include "tvector.h"
+#include "ppersist.h"
+#include "histos.h"
+
+namespace SOPHYA {
+
+//! 1 dimension profile histograms
+class HProf : public Histo {
+  friend class ObjFileIO<HProf>;
+public:
+
+  // CREATOR / DESTRUCTOR
+  HProf();
+  HProf(r_8 xMin, r_8 xMax, int_4 nBin=100, r_8 yMin=1., r_8 yMax=-1.);
+  HProf(r_4 xMin, r_4 xMax, int_4 nBin=100, r_4 yMin=1., r_4 yMax=-1.);
+  HProf(const HProf& H);
+  virtual ~HProf();
+
+  // UPDATING or SETTING
+  virtual void UpdateHisto(bool force=false) const;
+
+  void SetErrOpt(bool spread = true);
+  void Zero();
+  void Add(r_8 x, r_8 y, r_8 w = 1.);
+  void AddBin(int_4 numBin, r_8 y, r_8 w = 1.);
+  
+  // Acces a l information
+  //! Retourne l'histogramme de profil.
+  inline Histo GetHisto()
+               {UpdateHisto(); return (Histo) *this;}
+  //! Retourne le contenu de la moyenne dans le vecteur v
+  inline void GetValue(TVector<r_8>& v)
+              {UpdateHisto(); Histo::GetValue(v);}
+  //! Retourne le contenu au carre de la dispersion/erreur dans le vecteur v
+  inline void GetError2(TVector<r_8>& v)
+              {UpdateHisto(); Histo::GetError2(v);}
+  //! Retourne le contenu au carre de la dispersion/erreur dans le vecteur v
+  inline void GetError(TVector<r_8>& v)
+              {UpdateHisto(); Histo::GetError(v);}
+  //! Retourne le contenu du bin i
+  inline r_8 operator()(int_4 i) const
+               {UpdateHisto(); return mData[i];}
+  //! Retourne le carre de la dispersion/erreur du bin i
+  inline r_8 Error2(int_4 i) const
+                {UpdateHisto(); return mErr2[i];}
+  //! Retourne la dispersion/erreur du bin i
+  inline r_8 Error(int_4 i) const
+               {UpdateHisto();
+                return (mErr2[i]>0.) ? sqrt(mErr2[i]) : 0.;}
+
+  // Operators
+  HProf& operator = (const HProf& h);
+  HProf& operator += (const HProf& a);
+
+  // Info, statistique et calculs sur les histogrammes
+  virtual void HRebin(int_4 nbinew);
+
+  virtual void Show(ostream& os) const;
+  //! Print, voir detail dans Histo::Print
+  inline void Print(int_4 dyn=100,r_8 hmin=1.,r_8 hmax=-1.
+                   ,int_4 pflag=0,int_4 il=1,int_4 ih=-1)
+         {UpdateHisto(); Histo::Print(dyn,hmin,hmax,pflag,il,ih);}
+
+protected:
+  void Delete();
+  void updatehisto() const;
+
+  r_8*         SumY;  //!< somme
+  r_8*         SumY2; //!< somme des carres
+  r_8*         SumW;  //!< somme des poids
+  mutable bool Ok;    //!< true if update fait
+  r_8          YMin;  //!< limite minimum Y pour somme
+  r_8          YMax;  //!< limite maximum Y pour somme
+  uint_2       Opt;   //!< options pour les erreurs
+};
+
+
+/*! \ingroup HiStats \fn operator<<(POuttPersist&, HProf)
+  \brief Persistance management */
+inline POutPersist& operator << (POutPersist& os, HProf & obj)
+{ ObjFileIO<HProf> fio(&obj);  fio.Write(os);  return(os); }
+/*! \ingroup HiStats \fn operator>>(PInPersist&, HProf)
+  \brief Persistance management */
+inline PInPersist& operator >> (PInPersist& is, HProf & obj)
+{ ObjFileIO<HProf> fio(&obj);  fio.Read(is);  return(is); }
+// Classe pour la gestion de persistance
+// ObjFileIO<HProf>
+
+/*! \ingroup HiStats \fn operator+(const HProf&, const HProf&)
+  \brief Operateur H = H1 + H2
+  \warning Meme commentaire que pour l'operateur +=
+*/
+inline HProf operator + (const HProf& a, const HProf& b)
+{
+if (b.NBins()!=a.NBins()) THROW(sizeMismatchErr);
+HProf c(a);
+return (c += b);
+}
+
+} // Fin du namespace
+
+#endif // HISPROF_SEEN
Index: /tags/V_Dec2002/SophyaLib/HiStats/histats.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/HiStats/histats.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/HiStats/histats.h	(revision 2309)
@@ -0,0 +1,11 @@
+#ifndef HISTATS_SEEN
+#define HISTATS_SEEN
+
+#include "histinit.h"
+#include "histos.h"
+#include "histos2.h"
+#include "hisprof.h"
+#include "ntuple.h"
+#include "xntuple.h"
+
+#endif // HISTATS_SEEN
Index: /tags/V_Dec2002/SophyaLib/HiStats/histinit.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/HiStats/histinit.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/HiStats/histinit.cc	(revision 2309)
@@ -0,0 +1,56 @@
+// Classe d'initialisation du module HiStats 
+//                        (Histogram and Statistics)
+
+#include "machdefs.h"
+#include "histinit.h"
+
+#include "histos.h"
+#include "histos2.h"
+#include "hisprof.h"
+#include "ntuple.h"
+#include "xntuple.h"
+
+/*!
+   \defgroup HiStats HiStats module
+   This module contains histograms
+*/
+ 
+int HiStatsInitiator::FgInit = 0;
+
+/*!
+  \class SOPHYA::HiStatsInitiator
+  \ingroup HiStats
+  Histograms initiator
+*/
+HiStatsInitiator::HiStatsInitiator()
+  : NToolsInitiator()
+{
+  FgInit++;
+  if (FgInit > 1)  return;
+
+//   Enregistrement des classes PPersist du modules HiStats
+  
+  PPRegister(ObjFileIO<Histo>);
+  DObjRegister(ObjFileIO<Histo>, Histo);
+  PPRegister(ObjFileIO<Histo2D>);
+  DObjRegister(ObjFileIO<Histo2D>, Histo2D);
+  PPRegister(ObjFileIO<HProf>);
+  DObjRegister(ObjFileIO<HProf>, HProf);
+
+  PPRegister(ObjFileIO<NTuple>);
+  DObjRegister(ObjFileIO<NTuple>, NTuple);
+  PPRegister(ObjFileIO<XNTuple>);
+  DObjRegister(ObjFileIO<XNTuple>, XNTuple);
+
+}
+
+HiStatsInitiator::~HiStatsInitiator()
+{
+  FgInit--;
+}
+
+
+// On met un objet initiator en statique, pour les loaders qui savent 
+// appeler le constructeur des objets statiques   Reza 08/98
+static HiStatsInitiator histatsinit;
+
Index: /tags/V_Dec2002/SophyaLib/HiStats/histinit.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/HiStats/histinit.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/HiStats/histinit.h	(revision 2309)
@@ -0,0 +1,28 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe d'initialiseur du module HiStats (Histrogram/Stats)
+
+#ifndef HISTATSINIT_H_SEEN
+#define HISTATSINIT_H_SEEN
+
+
+// Classe d''initialisation pour le module de NTools
+#include "ntoolsinit.h"
+
+namespace SOPHYA {
+
+//! Histograms initiator
+class HiStatsInitiator : public NToolsInitiator {
+private:
+  static int FgInit;
+public:
+  			HiStatsInitiator();
+  virtual		~HiStatsInitiator();
+};
+
+#undef SophyaInit
+#define SophyaInit() HiStatsInitiator histatinitiator
+
+} // Fin du namespace
+
+#endif
+
Index: /tags/V_Dec2002/SophyaLib/HiStats/histos.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/HiStats/histos.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/HiStats/histos.cc	(revision 2309)
@@ -0,0 +1,1536 @@
+//
+// $Id: histos.cc,v 1.15 2001-02-20 18:29:48 ansari Exp $
+//
+
+#include "machdefs.h"
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+#include "histos.h"
+#include "perrors.h"
+#include "poly.h"
+#include "strutil.h"
+
+/*!
+  \class SOPHYA::Histo
+  \ingroup HiStats
+  Classe d'histogrammes 1D
+*/
+
+/********* Methode *********/
+/*! Constructeur par defaut */
+Histo::Histo()
+: mData(NULL), mErr2(NULL),
+  mUnder(0), mOver(0), nHist(0), nEntries(0),
+  mBins(0), mMin(0), mMax(0),
+  binWidth(0)
+{
+ END_CONSTRUCTOR
+}
+
+/********* Methode *********/
+/*! Constructeur d'un histo de nBin bins allant de xMin a xMax */
+Histo::Histo(r_8 xMin, r_8 xMax, int_4 nBin)
+: mData((nBin>0) ? new r_8[nBin] : NULL),
+  mErr2(NULL),
+  mUnder(0), mOver(0), nHist(0), nEntries(0),
+  mBins(nBin), mMin(xMin), mMax(xMax),
+  binWidth((nBin>0) ? (mMax-mMin)/nBin : 0)
+{
+  Zero();
+  END_CONSTRUCTOR
+}
+
+/********* Methode *********/
+/*! Constructeur d'un histo de nBin bins allant de xMin a xMax */
+Histo::Histo(r_4 xMin, r_4 xMax, int_4 nBin)
+: mData((nBin>0) ? new r_8[nBin] : NULL),
+  mErr2(NULL),
+  mUnder(0), mOver(0), nHist(0), nEntries(0),
+  mBins(nBin), mMin((r_8)xMin), mMax((r_8)xMax),
+  binWidth((nBin>0) ? (mMax-mMin)/nBin : 0)
+{
+  Zero();
+  END_CONSTRUCTOR
+}
+
+/********* Methode *********/
+/*! Constructeur par copie */
+Histo::Histo(const Histo& H)
+: mData((H.mBins>0)? new r_8[H.mBins] : NULL),
+  mErr2(NULL),
+  mUnder(H.mUnder), mOver(H.mOver), nHist(H.nHist), nEntries(H.nEntries),
+  mBins(H.mBins), mMin(H.mMin), mMax(H.mMax),
+  binWidth(H.binWidth)
+{
+  if(mBins>0) {
+    memcpy(mData, H.mData, mBins*sizeof(r_8));
+    if( H.mErr2 != NULL ) {
+      mErr2 = new r_8[mBins];
+      memcpy(mErr2, H.mErr2, mBins*sizeof(r_8));
+    }
+  }
+  END_CONSTRUCTOR
+}
+
+/********* Methode *********/
+/*! Gestion de la des-allocation */
+void Histo::Delete()
+{
+  if( mData != NULL ) { delete[] mData; mData = NULL;}
+  if( mErr2 != NULL ) { delete[] mErr2; mErr2 = NULL;}
+  mUnder = mOver = mMin = mMax = binWidth= 0.;
+  nHist = 0.;
+  nEntries = mBins = 0;
+}
+
+/********* Methode *********/
+/*! Destructeur */
+Histo::~Histo()
+{
+Delete();
+}
+
+/********* Methode *********/
+/*!
+  Remise a zero
+*/
+void Histo::Zero()
+{
+  if(mBins<=0) return;
+  memset(mData, 0, mBins*sizeof(r_8));
+  mUnder = mOver = 0;
+  nHist = 0;
+  nEntries = 0;
+  if( mErr2 != NULL ) memset(mErr2, 0, mBins*sizeof(r_8));
+}
+
+/********* Methode *********/
+/*!
+  Pour avoir le calcul des erreurs
+*/
+void Histo::Errors()
+{
+ if(mBins<=0) return;
+ if(mErr2==NULL) mErr2 = new r_8[mBins];
+ memset(mErr2, 0, mBins*sizeof(r_8));
+}
+
+/********* Methode *********/
+/*!
+  Operateur egal Histo = Histo
+*/
+Histo& Histo::operator = (const Histo& h)
+{
+  if(this == &h) return *this;
+  if( h.mBins <= 0 ) {Delete(); return *this;}
+  if( h.mBins > mBins ) Delete();
+  if(!h.mErr2 && mErr2 ) { delete [] mErr2; mErr2=NULL;}
+  if(!mData) mData = new r_8[h.mBins];
+  if(h.mErr2 && !mErr2 ) mErr2 = new r_8[h.mBins];
+
+  mUnder = h.mUnder;
+  mOver = h.mOver;
+  nHist = h.nHist;
+  nEntries = h.nEntries;
+  mBins = h.mBins;
+  mMin = h.mMin;
+  mMax = h.mMax;
+  binWidth = h.binWidth;
+  
+  memcpy(mData, h.mData, mBins*sizeof(r_8));
+  if(mErr2) memcpy(mErr2, h.mErr2, mBins*sizeof(r_8));
+
+  return *this;
+}
+
+/********* Methode *********/
+/*!
+  Operateur de multiplication par une constante
+*/
+Histo& Histo::operator *= (r_8 b)
+{
+r_8 b2 = b*b;
+for(int_4 i=0;i<mBins;i++) {
+  mData[i] *= b;
+  if(mErr2) mErr2[i] *= b2;
+}
+mUnder *= b;
+mOver *= b;
+nHist *= b;
+
+return *this;
+}
+
+/*!
+  Operateur de division par une constante
+*/
+Histo& Histo::operator /= (r_8 b)
+{
+if (b==0.) THROW(inconsistentErr);
+r_8 b2 = b*b;
+for(int_4 i=0;i<mBins;i++) {
+  mData[i] /= b;
+  if(mErr2) mErr2[i] /= b2;
+}
+mUnder /= b;
+mOver /= b;
+nHist /= b;
+
+return *this;
+}
+
+/*!
+  Operateur d'addition d'une constante
+*/
+Histo& Histo::operator += (r_8 b)
+{
+for(int_4 i=0;i<mBins;i++) mData[i] += b;
+mUnder += b;
+mOver += b;
+nHist += mBins*b;
+
+return *this;
+}
+
+/*!
+  Operateur de soustraction d'une constante
+*/
+Histo& Histo::operator -= (r_8 b)
+{
+for(int_4 i=0;i<mBins;i++) mData[i] -= b;
+mUnder -= b;
+mOver -= b;
+nHist -= mBins*b;
+
+return *this;
+}
+
+/********* Methode *********/
+/*!
+  Operateur H += H1
+*/
+Histo& Histo::operator += (const Histo& a)
+{
+if(mBins!=a.mBins) THROW(sizeMismatchErr);
+for(int_4 i=0;i<mBins;i++) {
+  mData[i] += a(i);
+  if(mErr2 && a.mErr2) mErr2[i] += a.Error2(i);
+}
+mUnder += a.mUnder;
+mOver += a.mOver;
+nHist += a.nHist;
+nEntries += a.nEntries;
+
+return *this;
+}
+
+/*!
+  Operateur H -= H1
+*/
+Histo& Histo::operator -= (const Histo& a)
+{
+if(mBins!=a.mBins) THROW(sizeMismatchErr);
+for(int_4 i=0;i<mBins;i++) {
+  mData[i] -= a(i);
+  if(mErr2 && a.mErr2) mErr2[i] += a.Error2(i);
+}
+mUnder -= a.mUnder;
+mOver -= a.mOver;
+nHist -= a.nHist;
+nEntries += a.nEntries;
+
+return *this;
+}
+
+/*!
+  Operateur H *= H1
+*/
+Histo& Histo::operator *= (const Histo& a)
+{
+if(mBins!=a.mBins) THROW(sizeMismatchErr);
+nHist = 0.;
+for(int_4 i=0;i<mBins;i++) {
+  if(mErr2 && a.mErr2)
+      mErr2[i] = a(i)*a(i)*mErr2[i] + mData[i]*mData[i]*a.Error2(i);
+  mData[i] *= a(i);
+  nHist += mData[i];
+}
+mUnder *= a.mUnder;
+mOver *= a.mOver;
+nEntries += a.nEntries;
+
+return *this;
+}
+
+/*!
+  Operateur H /= H1
+*/
+Histo& Histo::operator /= (const Histo& a)
+{
+if(mBins!=a.mBins) THROW(sizeMismatchErr);
+nHist = 0.;
+for(int_4 i=0;i<mBins;i++) {
+  if(a(i)==0.) {
+    mData[i]=0.;
+    if(mErr2) mErr2[i]=0.;
+    continue;
+  }
+  if(mErr2 && a.mErr2)
+      mErr2[i] = (mErr2[i] + mData[i]/a(i)*mData[i]/a(i)*a.Error2(i))
+                /(a(i)*a(i));
+  mData[i] /= a(i);
+  nHist += mData[i];
+}
+if(a.mUnder!=0.) mUnder /= a.mUnder; else mUnder = 0.;
+if(a.mOver!=0.)  mOver  /= a.mOver;  else mOver  = 0.;
+nEntries += a.nEntries;
+
+return *this;
+}
+
+/********* Methode *********/
+/*!
+  Remplissage d'un tableau avec la valeur des abscisses
+*/
+void Histo::GetAbsc(TVector<r_8> &v) const
+{
+v.Realloc(mBins);
+for(int_4 i=0;i<mBins;i++) v(i) = BinLowEdge(i);
+return;
+}
+
+/*!
+  Remplissage d'un tableau avec la valeur du contenu
+*/
+void Histo::GetValue(TVector<r_8> &v) const
+{
+v.Realloc(mBins);
+for(int_4 i=0;i<mBins;i++) v(i) = mData[i];
+return;
+}
+
+/*!
+  Remplissage d'un tableau avec la valeur des erreurs au carre
+*/
+void Histo::GetError2(TVector<r_8> &v) const
+{
+v.Realloc(mBins);
+if(!mErr2) {for(int_4 i=0;i<mBins;i++) v(i) = 0.; return;}
+for(int_4 i=0;i<mBins;i++) v(i) = mErr2[i];
+return;
+}
+
+/*!
+  Remplissage d'un tableau avec la valeur des erreurs
+*/
+void Histo::GetError(TVector<r_8> &v) const
+{
+v.Realloc(mBins);
+if(!mErr2) {for(int_4 i=0;i<mBins;i++) v(i) = 0.; return;}
+for(int_4 i=0;i<mBins;i++) v(i) = Error(i);
+return;
+}
+
+/********* Methode *********/
+/*!
+  Remplissage du contenu de l'histo avec les valeurs d'un vecteur
+*/
+void Histo::PutValue(TVector<r_8> &v, int_4 ierr)
+{
+//if(v.NElts()<(uint_4) mBins) THROW(sizeMismatchErr);
+uint_4 n = (v.NElts()<(uint_4) mBins) ? v.NElts(): (uint_4) mBins;
+if(n>0) for(uint_4 i=0;i<n;i++) {
+  mData[i] = v(i);
+  if(mErr2&&ierr) mErr2[i] = fabs(v(i));
+}
+return;
+}
+
+/*!
+  Addition du contenu de l'histo avec les valeurs d'un vecteur
+*/
+void Histo::PutValueAdd(TVector<r_8> &v, int_4 ierr)
+{
+//if(v.NElts()<(uint_4) mBins) THROW(sizeMismatchErr);
+uint_4 n = (v.NElts()<(uint_4) mBins) ? v.NElts(): (uint_4) mBins;
+if(n>0) for(uint_4 i=0;i<n;i++) {
+  mData[i] += v(i);
+  if(mErr2 && ierr) mErr2[i] += fabs(v(i));
+}
+return;
+}
+
+/*!
+  Remplissage des erreurs au carre de l'histo avec les valeurs d'un vecteur
+*/
+void Histo::PutError2(TVector<r_8> &v)
+{
+//if(v.NElts()<(uint_4) mBins) THROW(sizeMismatchErr);
+uint_4 n = (v.NElts()<(uint_4) mBins) ? v.NElts(): (uint_4) mBins;
+if(n>0) {
+  if(!mErr2) Errors();
+  for(uint_4 i=0;i<n;i++) mErr2[i] = v(i);
+}
+return;
+}
+
+/*!
+  Addition des erreurs au carre de l'histo avec les valeurs d'un vecteur
+*/
+void Histo::PutError2Add(TVector<r_8> &v)
+{
+//if(v.NElts()<(uint_4) mBins) THROW(sizeMismatchErr);
+uint_4 n = (v.NElts()<(uint_4) mBins) ? v.NElts(): (uint_4) mBins;
+if(n>0) {
+  if(!mErr2) Errors();
+  for(uint_4 i=0;i<n;i++) if(v(i)>0.) mErr2[i] += v(i);
+}
+return;
+}
+
+/*!
+  Remplissage des erreurs de l'histo avec les valeurs d'un vecteur
+*/
+void Histo::PutError(TVector<r_8> &v)
+{
+//if(v.NElts()<(uint_4) mBins) THROW(sizeMismatchErr);
+uint_4 n = (v.NElts()<(uint_4) mBins) ? v.NElts(): (uint_4) mBins;
+if(n>0) {
+  if(!mErr2) Errors();
+  for(uint_4 i=0;i<n;i++)
+    if(v(i)>0.) mErr2[i]=v(i)*v(i); else mErr2[i]=-v(i)*v(i);
+}
+return;
+}
+
+/********* Methode *********/
+/*!
+  Addition du contenu de l'histo pour abscisse x poids w
+*/
+void Histo::Add(r_8 x, r_8 w)
+{
+  int_4 numBin = FindBin(x);
+  if (numBin<0) mUnder += w;
+  else if (numBin>=mBins) mOver += w;
+  else {
+    mData[numBin] += w;
+    if(mErr2!=NULL) mErr2[numBin] += w*w;
+    nHist += w;
+    nEntries++;
+  }
+}
+
+/********* Methode *********/
+/*!
+  Addition du contenu de l'histo bin numBin poids w
+*/
+void Histo::AddBin(int_4 numBin, r_8 w)
+{
+  if (numBin<0) mUnder += w;
+  else if (numBin>=mBins) mOver += w;
+  else {
+    mData[numBin] += w;
+    if(mErr2!=NULL) mErr2[numBin] += w*w;
+    nHist += w;
+    nEntries++;
+  }
+}
+
+/********* Methode *********/
+/*!
+  Remplissage du contenu de l'histo pour abscisse x poids w
+*/
+void Histo::SetBin(r_8 x, r_8 w)
+{
+  int_4 numBin = FindBin(x);
+  SetBin(numBin,w);
+}
+
+/********* Methode *********/
+/*!
+  Remplissage du contenu de l'histo pour numBin poids w
+*/
+void Histo::SetBin(int_4 numBin, r_8 w)
+{
+  if (numBin<0) mUnder = w;
+  else if (numBin>=mBins) mOver = w;
+  else {
+    nHist -= mData[numBin];
+    mData[numBin] = w;
+    nHist += w;
+  }
+}
+
+/********* Methode *********/
+/*!
+  Remplissage des erreurs au carre pour abscisse x
+*/
+void Histo::SetErr2(r_8 x, r_8 e2)
+{
+  int_4 numBin = FindBin(x);
+  SetErr2(numBin,e2);
+}
+
+/********* Methode *********/
+/*!
+  Remplissage des erreurs au carre pour numBin poids
+*/
+void Histo::SetErr2(int_4 numBin, r_8 e2)
+{
+  if( mErr2==NULL) return;
+  if ( numBin<0 || numBin>=mBins ) return;
+  mErr2[numBin] = e2;
+}
+
+/********* Methode *********/
+/*!
+  Remplissage des erreurs pour abscisse x
+*/
+void Histo::SetErr(r_8 x, r_8 e)
+{
+SetErr2(x,  e*e);
+}
+
+/********* Methode *********/
+/*!
+  Remplissage des erreurs pour numBin
+*/
+void Histo::SetErr(int_4 numBin, r_8 e)
+{
+SetErr2(numBin,  e*e);
+}
+
+/********* Methode *********/
+/*!
+  Methode virtuelle de mise a jour - Ne fait rien pour Histo - Voir HProf 
+*/
+void Histo::UpdateHisto(bool force) const
+{
+  return;
+}
+
+/********* Methode *********/
+/*!
+  Numero du bin ayant le contenu maximum
+*/
+int_4 Histo::IMax() const
+{
+  int_4 imx=0;
+  if(mBins==1) return imx;
+  r_8 mx=mData[0];
+  for (int_4 i=1; i<mBins; i++)
+    if (mData[i]>mx) {imx = i; mx=mData[i];}
+  return imx;
+}
+
+/********* Methode *********/
+/*!
+  Numero du bin ayant le contenu minimum
+*/
+int_4 Histo::IMin() const
+{
+  int_4 imx=0;
+  if(mBins==1) return imx;
+  r_8 mx=mData[0];
+  for (int_4 i=1; i<mBins; i++)
+    if (mData[i]<mx) {imx = i; mx=mData[i];}
+  return imx;
+}
+
+/********* Methode *********/
+/*!
+  Valeur le contenu maximum
+*/
+r_8 Histo::VMax() const
+{
+  r_8 mx=mData[0];
+  if(mBins==1) return mx;
+  for (int_4 i=1;i<mBins;i++) if(mData[i]>mx) mx=mData[i];
+  return mx;
+}
+
+/********* Methode *********/
+/*!
+  Valeur le contenu minimum
+*/
+r_8 Histo::VMin() const
+{
+  r_8 mx=mData[0];
+  if(mBins==1) return mx;
+  for (int_4 i=1;i<mBins;i++) if(mData[i]<mx) mx=mData[i];
+  return mx;
+}
+
+/********* Methode *********/
+/*!
+  Valeur moyenne
+*/
+r_8 Histo::Mean() const
+{
+  r_8 n = 0;
+  r_8 sx = 0;
+  for (int_4 i=0; i<mBins; i++) {
+    r_8 v = (mData[i]>=0.) ? mData[i] : -mData[i];
+    n += v;
+    sx += BinCenter(i)*v;
+  }
+  if(n>0.) return sx/n; else return mMin;
+}
+
+/********* Methode *********/
+/*!
+  Valeur du sigma
+*/
+r_8 Histo::Sigma() const
+{
+  r_8 n = 0;
+  r_8 sx = 0;
+  r_8 sx2= 0;
+  for (int_4 i=0; i<mBins; i++) {
+    r_8 v = (mData[i]>=0.) ? mData[i] : -mData[i];
+    n += v;
+    sx += BinCenter(i)*v;
+    sx2+= BinCenter(i)*BinCenter(i)*v;
+  }
+  // attention a l'erreur d'arrondi si un seul bin rempli!!
+  if( n == 0 ) return 0.;
+  sx2 = sx2/n - (sx/n)*(sx/n);
+  if( sx2>0. ) return sqrt( sx2 );
+      else return 0.;
+}
+
+/********* Methode *********/
+/*!
+  Valeur de la moyenne calculee entre les bin il et ih
+*/
+r_8 Histo::MeanLH(int_4 il,int_4 ih) const
+{
+  if( ih < il ) { il = 0; ih = mBins-1; }
+  if( il < 0 ) il = 0;
+  if( ih >= mBins ) ih = mBins-1;
+  r_8 n = 0;
+  r_8 sx = 0;
+  for (int_4 i=il; i<=ih; i++) {
+    r_8 v = (mData[i]>=0.) ? mData[i] : -mData[i];
+    n += v;
+    sx += BinCenter(i)*v;
+  }
+  if(n>0.) return sx/n; else return BinLowEdge(il);
+}
+
+/********* Methode *********/
+/*!
+  Valeur de la moyenne calculee entre les bin il et ih
+*/
+r_8 Histo::SigmaLH(int_4 il,int_4 ih) const
+{
+  if( ih < il ) { il = 0; ih = mBins - 1; }
+  if( il < 0 ) il = 0;
+  if( ih >= mBins ) ih = mBins - 1;
+  r_8 n = 0;
+  r_8 sx = 0;
+  r_8 sx2= 0;
+  for (int_4 i=il; i<=ih; i++) {
+    r_8 v = (mData[i]>=0.) ? mData[i] : -mData[i];
+    n += v;
+    sx += BinCenter(i)*v;
+    sx2+= BinCenter(i)*BinCenter(i)*v;
+  }
+  if( n == 0 ) return 0.;
+  sx2 = sx2/n - (sx/n)*(sx/n);
+  if( sx2>0. ) return sqrt( sx2 );
+      else return 0.;
+}
+
+/********* Methode *********/
+/*!
+  Valeur de la moyenne calculee entre x0-dx et x0+dx
+*/
+r_8 Histo::Mean(r_8 x0, r_8 dx) const
+{
+  r_8 sdata = 0;
+  r_8 sx = 0;
+  int_4 iMin = FindBin(x0-dx);
+  if (iMin<0) iMin = 0;
+  int_4 iMax = FindBin(x0+dx);
+  if (iMax>mBins) iMax=mBins;
+  for (int_4 i=iMin; i<iMax; i++) {
+    r_8 v = (mData[i]>=0.) ? mData[i] : -mData[i];
+    sx += BinCenter(i)*v;
+    sdata += v;
+  }
+  if(sdata>0.) return sx/sdata; else return mMin;
+}
+
+/********* Methode *********/
+/*!
+  Valeur du sigma calcule entre x0-dx et x0+dx
+*/
+r_8 Histo::Sigma(r_8 x0, r_8 dx) const
+{
+  r_8 sx = 0;
+  r_8 sx2= 0;
+  r_8 sdata = 0;
+  int_4 iMin = FindBin(x0-dx);
+  if (iMin<0) iMin = 0;
+  int_4 iMax = FindBin(x0+dx);
+  if (iMax>mBins) iMax=mBins;
+  for (int_4 i=iMin; i<iMax; i++) {
+    r_8 v = (mData[i]>=0.) ? mData[i] : -mData[i];
+    sx += BinCenter(i)*v;
+    sx2+= BinCenter(i)*BinCenter(i)*v;
+    sdata += v;
+  }
+  if(sdata>0.) return sqrt( sx2/sdata - (sx/sdata)*(sx/sdata) );
+          else return 0.;
+}
+
+/********* Methode *********/
+/*!
+  Valeur de la moyenne et du sigma nettoyes
+*/
+r_8 Histo::CleanedMean(r_8& sigma) const
+{
+  if (!nHist) return 0;
+  // on fait ca de facon bete, on pourra raffiner apres...
+  r_8 x0 = Mean();
+  r_8 s  = Sigma()+binWidth;
+  
+  for (int_4 i=0; i<3; i++) {
+    r_8 xx0 = Mean(x0,5*s);
+    s  = Sigma(x0,5*s)+binWidth;
+    x0 = xx0;
+  }
+  sigma = s;
+  return x0;
+}
+
+/********* Methode *********/
+/*!
+  Valeur de la moyenne nettoyee
+*/
+r_8 Histo::CleanedMean() const
+{
+  if (!nHist) return 0;
+  r_8 s=0;
+  return CleanedMean(s);
+}
+
+/********* Methode *********/
+/*!
+  Retourne le nombre de bins non-nul
+*/
+int_4 Histo::BinNonNul() const
+{
+int_4 non=0;
+for (int_4 i=0;i<mBins;i++) if( mData[i] != 0. ) non++;
+return non;
+}
+
+/********* Methode *********/
+/*!
+  Retourne le nombre de bins ayant une erreur non-nulle
+*/
+int_4 Histo::ErrNonNul() const
+{
+if(mErr2==NULL) return -1;
+int_4 non=0;
+for (int_4 i=0;i<mBins;i++) if( mErr2[i] != 0. ) non++;
+return non;
+}
+
+/********* Methode *********/
+/*!
+  Renvoie le numero de bin tel que il y ait "per" pourcent entrees
+  entre le bin 0 et ce bin (y compris le contenu de ce bin).
+*/
+int_4 Histo::BinPercent(r_8 per) const
+{
+r_8 n = nHist*per;
+r_8 s = 0.;
+int_4 i;
+for(i=0; i<mBins; i++ ) {
+  s += mData[i];
+  if( s >= n ) break;
+}
+if( i == mBins ) i = mBins-1;
+return i;
+}
+
+/********* Methode *********/
+/*!
+  Renvoie les numeros de bins imin,imax (0=<i<bins) tels que:
+  \verbatim
+       notons I = bin contenant l'abscisse x
+              N1 = nombre d'entrees entre bin 0 et I compris
+              N2 = nombre d'entrees entre bin I et bins-1 compris
+       imin = bin tel que nombre d'entrees entre imin et I = N1 * per
+       imax = bin tel que nombre d'entrees entre I et imax = N2 * per
+     Return: <0 si echec
+             mMin(I-imin,imax-I) si ok
+  \endverbatim
+*/
+int_4 Histo::BinPercent(r_8 x,r_8 per,int_4& imin,int_4& imax) const
+{
+imin = imax = -1;
+if( per <= 0. ) return -1;
+
+int_4 I = FindBin(x);
+if( I<0 || I>=mBins ) return -2;
+
+r_8 N1 = 0.; for(int_4 i=0; i<=I;   i++) N1 += mData[i]; N1 *= per;
+r_8 N2 = 0.; {for(int_4 i=I; i<mBins; i++) N2 += mData[i]; N2 *= per;}
+
+r_8 n = 0.;
+for(imin=I; imin>=0; imin--)   { n += mData[imin]; if(n>=N1) break; }
+if( imin<0 ) imin = 0;
+// cout<<"I="<<I<<" imin="<<imin<<" n="<<n<<" N1="<<N1<<endl;
+
+n = 0.;
+for(imax=I; imax<mBins; imax++) { n += mData[imax]; if(n>=N2) break; }
+if( imax>=mBins ) imax = mBins-1;
+// cout<<"I="<<I<<" imax="<<imax<<" n="<<n<<" N2="<<N2<<endl;
+
+return ( imax-I > I-imin ) ? I-imin : imax-I ;
+}
+
+/********* Methode *********/
+/*!
+  Idem precedent mais renvoie xmin et xmax
+*/
+int_4 Histo::BinPercent(r_8 x,r_8 per,r_8& xmin,r_8& xmax) const
+{
+xmin = xmax = 0.;
+int_4 imin,imax;
+int_4 rc = BinPercent(x,per,imin,imax);
+if( rc >= 0 ) { xmin = BinLowEdge(imin); xmax = BinHighEdge(imax); }
+return rc;
+}
+
+/********* Methode *********/
+/*!
+  Remplace l'histogramme par son integrale normalise a norm:
+  si norm <= 0 : pas de normalisation, integration seule
+*/
+void Histo::HInteg(r_8 norm)
+{
+if( mBins <= 0 ) return; // createur par default
+if(mBins>1)
+  for(int_4 i=1; i<mBins; i++) {
+    mData[i] += mData[i-1];
+    if(mErr2!=NULL) mErr2[i] += mErr2[i-1];
+  }
+if( norm <= 0. ) return;
+norm /= mData[mBins-1];
+for(int_4 i=0; i<mBins; i++) {
+  mData[i] *= norm;
+  if(mErr2!=NULL) mErr2[i] *= norm*norm;
+}
+}
+
+/********* Methode *********/
+/*!
+  Remplace l'histogramme par sa derivee
+*/
+void Histo::HDeriv()
+{
+if( mBins <= 0 ) return; // createur par default
+if( mBins <= 1 ) return;
+r_8 *temp = new r_8[mBins];
+memcpy(temp, mData, mBins*sizeof(r_8));
+if(mBins>=3) for(int_4 i=1; i<mBins-1; i++)
+              temp[i] = (mData[i+1]-mData[i-1])/(2.*binWidth);
+temp[0] = (mData[1]-mData[0])/binWidth;
+temp[mBins-1] = (mData[mBins-1]-mData[mBins-2])/binWidth;
+memcpy(mData, temp, mBins*sizeof(r_8));
+delete [] temp;
+}
+
+/********* Methode *********/
+/*!
+  Pour rebinner l'histogramme sur nbinew bins
+*/
+void Histo::HRebin(int_4 nbinew)
+{
+  if( mBins <= 0 ) return; // createur par default
+  if( nbinew <= 0 ) return;
+
+  // memorisation de l'histogramme original
+  Histo H(*this);
+
+  // Le nombre de bins est il plus grand ??
+  if( nbinew > mBins ) {
+    delete [] mData; mData = NULL;
+    mData = new r_8[nbinew];
+    if( mErr2 != NULL ) {
+      delete [] mErr2; mErr2 = NULL;
+      mErr2 = new r_8[nbinew];
+    }
+  }
+
+  // remise en forme de this
+  mBins = nbinew;
+  this->Zero();
+  binWidth = (mMax-mMin)/mBins;
+  // On recopie les parametres qui n'ont pas changes
+  mUnder = H.mUnder;
+  mOver  = H.mOver;
+
+
+  // Remplissage
+  for(int_4 i=0;i<mBins;i++) {
+    r_8 xmi = BinLowEdge(i);
+    r_8 xma = BinHighEdge(i);
+    int_4 imi =  H.FindBin(xmi);
+    if( imi < 0 ) imi = 0;
+    int_4 ima =  H.FindBin(xma);
+    if( ima >= H.mBins ) ima = H.mBins-1;
+    r_8 w = 0.;
+    if( ima == imi ) {
+      w = H(imi) * binWidth/H.binWidth;
+    } else {
+      w += H(imi) * (H.BinHighEdge(imi)-xmi)/H.binWidth;
+      w += H(ima) * (xma -H.BinLowEdge(ima))/H.binWidth;
+      if( ima > imi+1 )
+          for(int_4 ii=imi+1;ii<ima;ii++) w += H(ii);
+    }
+    AddBin(i, w);
+  }
+
+}
+
+/********* Methode *********/
+/*!
+  Retourne le nombre de maxima locaux, la valeur du maximum (maxi)
+  et sa position (imax), ainsi que la valeur du second maximum
+  local (maxn) et sa position (imaxn).
+  Attention: si un maximum a la meme valeur sur plusieurs bins
+  consecutifs, le bin le plus a droite est pris.
+*/
+int_4 Histo::MaxiLocal(r_8& maxi,int_4& imax,r_8& maxn,int_4& imaxn) const
+{
+int_4 nml = 0;
+imax = imaxn = -1;
+maxi = maxn = -1.;
+
+bool up = true;
+bool down = false;
+for(int_4 i=0;i<mBins;i++) {
+  if( !up ) if( mData[i] > mData[i-1] ) up = true;
+  if( up && !down ) {
+    if( i == mBins-1 ) down=true;
+      else if( mData[i] > mData[i+1] ) down=true;
+  }
+
+  if( up && down ) {
+    nml++;
+    up = down = false;
+    if( imax < 0 ) {
+      imax = i; maxi = mData[i];
+    } else if( mData[i] >= maxi ) {
+      imaxn = imax; maxn = maxi;
+      imax = i; maxi = mData[i];
+    } else {
+      if( imaxn < 0 || mData[i] >= maxn ) { imaxn = i; maxn = mData[i]; }
+    }
+  }
+
+}
+return nml;
+}
+
+/********* Methode *********/
+/*!
+  Fit de la position du maximum de l'histo par un polynome
+  de degre `degree' a `frac' pourcent du maximum.
+  L'histo est suppose etre remplit de valeurs positives
+*/
+r_8 Histo::FitMax(int_4 degree, r_8 frac, int_4 debug) const
+{
+  if (degree < 2 || degree > 3) degree = 3;
+  if (frac <= 0. || frac >= 1.) frac = 0.5;
+
+  if (debug > 1)
+    cout<<"Histo::FitMax : Nb Entrees histo ="<<NEntries()<<endl;
+
+  if (NEntries() < 1) THROW(inconsistentErr);
+
+  int_4 iMax = IMax();
+  r_8 hmax = (*this)(iMax);
+  r_8 xCenter = BinCenter(iMax);
+
+  if(debug>1)
+    cout<<"Max histo i="<<iMax<<" x="<<xCenter<<" v="<<hmax<<endl;
+
+  /* find limits at frac*hmax */
+
+  r_8 limit = frac*hmax;
+
+  volatile int_4 iLow = iMax;
+  while (iLow>0 && (*this)(iLow)>limit) iLow--;
+
+  volatile int_4 iHigh = iMax;
+  while (iHigh<NBins()-1 && (*this)(iHigh)>limit) iHigh++;
+
+  int_4 nLowHigh;
+  for(;;) {
+    nLowHigh = 0;
+    for (int_4 i=iLow; i<=iHigh; i++) if((*this)(i)>0) {
+      if(!mErr2) nLowHigh++;
+        else if(Error2(i)>0.) nLowHigh++;
+    }
+    if (debug > 1) cout <<"Limites histo "<<iLow<<" - "<<iHigh
+                        <<" ("<<nLowHigh<<" non nuls)"<<endl;
+    if( nLowHigh >= degree+1 ) break;
+    iLow--;  iHigh++;
+    if(iLow<0 && iHigh>=NBins()) {
+      if (debug>1)
+        cout<<"Mode histogramme = "<<xCenter
+            <<"   BinCenter("<<iMax<<")"<<endl;
+      return xCenter;
+    }
+    if(iLow  < 0       ) iLow  = 0;
+    if(iHigh >= NBins()) iHigh = NBins()-1;
+  }
+
+  TVector<r_8> xFit(nLowHigh);
+  TVector<r_8> yFit(nLowHigh);
+  TVector<r_8> e2Fit(nLowHigh);
+  TVector<r_8> errcoef(1);
+  int_4 ii = 0;
+  for (int_4 j=iLow; j<=iHigh; j++) {
+    if ((*this)(j)>0) {
+      if(!mErr2) {
+        xFit(ii) = BinCenter(j)-xCenter;
+        yFit(ii) = (*this)(j);
+        e2Fit(ii) = yFit(ii);
+        ii++;
+      } else if(Error2(j)>0.) {
+        xFit(ii) = BinCenter(j)-xCenter;
+        yFit(ii) = (*this)(j);
+        e2Fit(ii) = Error2(j);
+        ii++;
+      }
+    }
+  }
+  if(debug>4) {
+    int_4 k;
+    for(k=0;k<nLowHigh;k++) cout<<" "<<xFit(k);  cout<<endl;
+    for(k=0;k<nLowHigh;k++) cout<<" "<<yFit(k);  cout<<endl;
+    for(k=0;k<nLowHigh;k++) cout<<" "<<e2Fit(k); cout<<endl;
+  }
+  if( ii != nLowHigh ) THROW(inconsistentErr);
+  Poly pol(degree);
+  TRY {
+    pol.Fit(xFit, yFit, e2Fit, degree, errcoef);
+    if (debug>1) cout << "resultat fit = " << pol << endl;
+    pol.Derivate();
+  } CATCHALL {
+    THROW_SAME;
+  } ENDTRY
+
+  int_4 DPolDeg = pol.Degre();
+  r_8 fd = 0.;
+
+  if (DPolDeg == 0) {
+    // on est dans le cas d'un fit de droite
+    if( pol[0] > 0. ) {
+      // on a fitte une droite de pente >0.
+      fd = xFit(nLowHigh-1) + binWidth/2. + xCenter;
+    } else if( pol[0] < 0. ) {
+      // on a fitte une droite de pente <0.
+      fd = xFit(0) - binWidth/2. + xCenter;
+    } else {
+      // on a fitte une droite de pente =0. (creneau)
+      fd = (xFit(0)+xFit(nLowHigh-1))/2. + xCenter;
+    }
+  } else if (DPolDeg == 1) {
+    // on est dans le cas d'un fit de parabole
+    r_8 r=0;
+    if (pol.Root1(r)==0) THROW(inconsistentErr);
+    fd = r + xCenter;
+  } else if (DPolDeg == 2) {
+    // on est dans le cas d'un fit de cubique
+    r_8 r1=0;
+    r_8 r2=0;
+    if (pol.Root2(r1,r2) == 0) THROW(inconsistentErr);
+    pol.Derivate();
+    fd = (pol(r1)<0) ? r1 + xCenter : r2 + xCenter;
+  } else {
+    // on est dans un cas non prevu
+    THROW(inconsistentErr);
+  }
+
+  if(fd>mMax) fd = mMax;
+  if(fd<mMin) fd = mMin;
+
+  if (debug>1)
+    cout << "Mode histogramme = " << fd
+         << "    (DerPol.degre =" << DPolDeg
+         << " pol.coeff[0] =" << pol[0]
+         << ")" << endl;
+
+  return fd;
+}
+
+
+/********* Methode *********/
+/*!
+  Calcul de la largeur a frac pourcent du maximum
+  autour du bin du maximum.
+  L'histo est suppose etre remplit de valeurs positives
+*/
+r_8 Histo::FindWidth(r_8 frac, int_4 debug) const
+{
+  r_8 xmax = BinCenter( IMax() );
+  return FindWidth(xmax,frac,debug);
+}
+
+/********* Methode *********/
+/*!
+  Calcul de la largeur a frac pourcent de la valeur du bin xmax.
+  L'histo est suppose etre remplit de valeurs positives
+*/
+r_8 Histo::FindWidth(r_8 xmax,r_8 frac, int_4 debug) const
+{
+  if (frac <= 0 || frac >= 1.) frac = 0.5;
+
+  if (debug > 1)
+    cout << "Histo::FindWidth a " << frac
+         << " de xmax= " << xmax
+         << " , ndata= " << NData()
+         << " , nent= " << NEntries()
+         << " , nbin= " << NBins() << endl;
+
+  if (NEntries() < 1) THROW(inconsistentErr);
+  if (NBins() < 3) THROW(inconsistentErr);
+
+  int_4 iMax = FindBin(xmax);
+  if (iMax<0 || iMax>=NBins()) THROW(inconsistentErr);
+  r_8 hmax = mData[iMax];
+  r_8 limit = frac*hmax;
+  if (debug > 1)
+    cout << "  Max histo[" << iMax << "] = " << hmax
+         << ", limite " << limit << endl;
+
+  int_4 iLow = iMax;
+  while (iLow>=0 && mData[iLow]>limit) iLow--;
+  if( iLow < 0 ) iLow = 0;
+
+  int_4 iHigh = iMax;
+  while (iHigh<NBins() && mData[iHigh]>limit) iHigh++;
+  if( iHigh >=NBins() ) iHigh = NBins()-1;
+
+  r_8 xlow   = BinCenter(iLow);
+  r_8 ylow   = mData[iLow];
+
+  r_8 xlow1=xlow, ylow1=ylow;
+  if(iLow+1<NBins()) {
+    xlow1  = BinCenter(iLow+1);
+    ylow1  = mData[iLow+1];
+  }
+
+  r_8 xhigh  = BinCenter(iHigh);
+  r_8 yhigh  = mData[iHigh];
+
+  r_8 xhigh1=xhigh, yhigh1=yhigh;
+  if(iHigh-1>=0) {
+    xhigh1 = BinCenter(iHigh-1);
+    yhigh1 = mData[iHigh-1];
+  }
+
+  r_8 xlpred,xhpred,wd;
+
+  if(ylow1>ylow) {
+    xlpred = xlow + (xlow1-xlow)/(ylow1-ylow)*(limit-ylow);
+    if(xlpred < xlow) xlpred = xlow;
+  } else xlpred = xlow;
+
+  if(yhigh1>yhigh) {
+    xhpred = xhigh + (xhigh1-xhigh)/(yhigh1-yhigh)*(limit-yhigh);
+    if(xhpred > xhigh) xhpred = xhigh;
+  } else xhpred = xhigh;
+
+  wd = xhpred - xlpred;
+
+  if (debug > 1) {
+    cout << "Limites histo: " << "  Width " << wd << endl;
+    cout << "  Low: [" << iLow  << "]=" << ylow << " pred-> " << xlpred
+         << " - High: [" << iHigh  << "]=" << yhigh << " pred-> " << xhpred
+         << endl;
+  }
+
+  return wd;
+}
+
+
+/********* Methode *********/
+/*!
+  Cf suivant mais im est le bin du maximum de l'histo
+*/
+int_4 Histo::EstimeMax(r_8& xm,int_4 SzPav) const
+{
+int_4 im = IMax();
+return EstimeMax(im,xm,SzPav);
+}
+
+/********* Methode *********/
+/*!
+  Determine l'abscisses du maximum donne par im
+  en moyennant dans un pave SzPav  autour du maximum
+  \verbatim
+     Return:
+        0 = si fit maximum reussi avec SzPav pixels
+        1 = si fit maximum reussi avec moins que SzPav pixels
+        2 = si fit maximum echoue et renvoit BinCenter()
+       -1 = si echec: SzPav <= 0 ou im hors limites
+  \endverbatim
+*/
+int_4 Histo::EstimeMax(int_4& im,r_8& xm,int_4 SzPav) const
+{
+xm = 0;
+if( SzPav <= 0 ) return -1;
+if( im < 0 || im >= mBins ) return -1;
+
+if( SzPav%2 == 0 ) SzPav++;
+SzPav = (SzPav-1)/2;
+
+int_4 rc = 0;
+r_8 dxm = 0, wx = 0;
+for(int_4 i=im-SzPav;i<=im+SzPav;i++) {
+  if( i<0 || i>= mBins ) {rc=1; continue;}
+  dxm += BinCenter(i) * (*this)(i);
+  wx  += (*this)(i);
+}
+
+if( wx > 0. ) {
+  xm = dxm/wx;
+  return rc;
+} else {
+  xm = BinCenter(im);
+  return 2;
+}
+
+}
+
+/********* Methode *********/
+/*!
+  Determine la largeur a frac% du maximum a gauche (widthG)
+  et a droite (widthD)
+*/
+void Histo::EstimeWidthS(r_8 frac,r_8& widthG,r_8& widthD) const
+{
+int_4 i;
+widthG = widthD = -1.;
+if( mBins<=1 || frac<=0. || frac>=1. ) return;
+
+int_4 imax = 0;
+r_8 maxi = mData[0];
+for(i=1;i<mBins;i++) if(mData[i]>maxi) {imax=i; maxi=mData[i];}
+r_8 xmax = BinCenter(imax);
+r_8 maxf = maxi * frac;
+
+// recherche du sigma a gauche
+widthG = 0.;
+for(i=imax;i>=0;i--) if( mData[i] <= maxf ) break;
+if(i<0) i=0;
+if(i<imax) {
+  if( mData[i+1] != mData[i] ) {
+    widthG = BinCenter(i) + binWidth
+           * (maxf-mData[i])/(mData[i+1]-mData[i]);
+    widthG = xmax - widthG;
+  } else widthG = xmax - BinCenter(i);
+}
+
+// recherche du sigma a droite
+widthD = 0.;
+for(i=imax;i<mBins;i++) if( mData[i] <= maxf ) break;
+if(i>=mBins) i=mBins-1;
+if(i>imax) {
+  if( mData[i] != mData[i-1] ) {
+    widthD = BinCenter(i) - binWidth
+           * (maxf-mData[i])/(mData[i-1]-mData[i]);
+    widthD -= xmax;
+  } else widthD = BinCenter(i) - xmax;
+}
+
+}
+
+/********* Methode *********/
+/*!
+  Impression de l'histogramme
+  \verbatim
+      hdyn = nombre de colonnes pour imprimer les etoiles
+          si =0 alors defaut(100),
+          si <0 pas de print histo seulement infos
+      hmin = minimum de la dynamique
+      hmax = maximum de la dynamique
+          si hmax<=hmin           : hmin=VMin() hmax=VMax()
+          si hmax<=hmin et hmin=0 : hmin=0 hmax=VMax()
+          sinon : hmin hmax
+      pflag < 0 : on imprime les informations (nbin,min,...) sans l'histogramme
+            = 0 : on imprime  "BinCenter(i) mData[i]"  (note "... ...")
+            bit 0 on : (v=1): numero_bin "... ..."
+            bit 1 on : (v=2): "... ..." erreur
+  \endverbatim
+*/
+
+void Histo::Show(ostream & os) const
+{
+ os << " Histo::Show  "
+      << " nHist=" << nHist << "  nEntries=" << nEntries
+      << "  mUnder=" << mUnder << "  mOver=" << mOver << endl;
+ os << "       mBins=" << mBins
+      << "  min=" << mMin << "  mMax=" << mMax
+      << "  binWidth=" << binWidth << endl;
+ os << "       mean=" << Mean() << " r.m.s=" << Sigma() 
+      << "  Errors="<<HasErrors()<< endl;
+}
+
+void Histo::Print(int_4 hdyn,r_8 hmin, r_8 hmax,int_4 pflag,
+	          int_4 il, int_4 ih) const
+{
+ 
+ if( il > ih ) { il = 0; ih = mBins-1; }
+ if( il < 0 ) il = 0;
+ if( ih >= mBins ) ih = mBins-1;
+
+ r_8 dhmin =  hmin;
+ r_8 dhmax =  hmax;
+ r_8 hb,hbmn,hbmx;
+
+ if(hdyn==0) hdyn = 100;
+
+ Show(cout);
+
+ if(hdyn<0 || pflag<0 ) return;
+
+ if(dhmax<=dhmin) { if(hmin != 0.) dhmin =  VMin(); else dhmin=0.;
+                  dhmax =  VMax(); }
+ if(dhmin>dhmax) return;
+ if(dhmin==dhmax) {dhmin -= 1.; dhmax += 1.;}
+ r_8 wb = (dhmax-dhmin) /  hdyn;
+
+ // determination de la position de la valeur zero
+ int_4 i0 = (int_4)(-dhmin/wb);
+
+ // si le zero est dans la dynamique,
+ //  il doit imperativement etre une limite de bin
+ if( 0 <= i0 && i0 < hdyn ) {
+   hbmn = dhmin + i0*wb;
+   hbmx = hbmn + wb;
+   if( hbmn != 0. ) {
+     hbmn *= -1.;
+     if( hbmn < hbmx ) {
+       // le zero est + pres du bord negatif du bin
+       dhmin += hbmn;
+       dhmax += hbmn;
+     } else {
+       // le zero est + pres du bord positif du bin
+       dhmin -= hbmx;
+       dhmax -= hbmx;
+     }
+     wb = (dhmax-dhmin) /  hdyn;
+     i0 = (int_4)(-dhmin/wb);
+   }
+ }
+
+ cout <<"       bin minimum="<<dhmin<<"   bin maximum="<<dhmax
+      <<"   binw="<<wb<< endl;
+
+ char* s = new char[hdyn+1];
+ s[hdyn] = '\0';
+
+ // premiere ligne
+ {for(int_4 i=0;i<hdyn;i++) s[i] = '=';}
+ if( 0 <= i0 && i0 < hdyn ) s[i0] = '0';
+ if(pflag&1) printf("====");
+ printf("======================");
+ if(pflag&2 && mErr2!=NULL) printf("===========");
+ printf("==%s\n",s);
+
+ // histogramme
+ {for(int_4 i=il;i<=ih;i++) {
+   for(int_4 k=0;k<hdyn;k++) s[k] = ' ';
+   hb = (*this)(i);
+
+   //choix du bin (hdyn bin entre [dhmin,dhmax[
+   int_4 ii = (int_4)( (hb-dhmin)/wb );
+   if(ii<0) ii = 0; else if(ii>=hdyn) ii = hdyn-1;
+
+   // limite du bin
+   hbmn = dhmin + ii*wb;
+   hbmx = hbmn + wb;
+
+   // remplissage de s[] en tenant compte des courbes +/-
+   if(i0<0) {
+     // courbe entierement positive
+     for(int_4 k=0;k<=ii;k++) s[k] = 'X';
+   } else if(i0>=hdyn) {
+     // courbe entierement negative
+     for(int_4 k=hdyn-1;k>=ii;k--) s[k] = 'X';
+   } else {
+     // courbe positive et negative
+     s[i0] = '|';
+     if(ii>i0)        for(int_4 k=i0+1;k<=ii;k++) s[k] = 'X';
+       else if(ii<i0) for(int_4 k=ii;k<i0;k++)    s[k] = 'X';
+          else s[ii] = 'X';
+   }
+
+   // valeur a mettre dans le bin le plus haut/bas
+   int_4 ib;
+   if(hb>0.) ib = (int_4)( 10.*(hb-hbmn)/(hbmx-hbmn) );
+     else if(hb<0.) ib = (int_4)( 10.*(hbmx-hb)/(hbmx-hbmn) );
+       else ib = -1;
+   if(ib==-1) s[ii] = '|';
+     else if(ib==0) s[ii] = '.';
+       else if(ib>0 && ib<10) s[ii] = (char)((int_4) '0' + ib);
+
+   // traitement des saturations +/-
+   if( hb < dhmin ) s[0] = '*';
+    else if( hb > dhmax ) s[hdyn-1] = '*';
+
+   if(pflag&1) printf("%3d ",i);
+   printf("%10.4g %10.4g ",BinCenter(i),hb);
+   if(pflag&2 && mErr2!=NULL) printf("%10.4g ",Error(i));
+   printf("= %s\n",s);
+ }}
+
+ // derniere ligne
+ for(int_4 i=0;i<hdyn;i++) s[i] = '=';
+ if( 0 <= i0 && i0 < hdyn ) s[i0] = '0';
+ if(pflag&1) printf("====");
+ printf("======================");
+ if(pflag&2 && mErr2!=NULL) printf("===========");
+ printf("==%s\n",s);
+
+ // valeur basse des bins (sur ["ndig-1" digits + signe] =  ndig char (>=3))
+ const int_4 ndig = 7;
+ char sn[2*ndig+10];
+ hb = ( fabs(dhmin) > fabs(dhmax) ) ? fabs(dhmin) : fabs(dhmax);
+ int_4 n;
+ if( hb > 0. ) n = (int_4)(log10(hb*1.00000001)); else n = 1;
+ r_8 scaledig = pow(10.,(r_8) ndig-2);
+ r_8 expo = scaledig/pow(10.,(r_8) n);
+ // cout <<"n="<<n<<" hb="<<hb<<" scaledig="<<scaledig<<" expo="<<expo<<endl;
+ for(int_4 k=0;k<ndig;k++) {
+   for(int_4 i=0;i<hdyn;i++) s[i] = ' ';
+   {for(int_4 i=0;i<hdyn;i++) {
+     n = (int_4)( (dhmin + i*wb)*expo );
+     for(int_4 j=0;j<2*ndig+10;j++) sn[j] = ' ';
+     sprintf(sn,"%d%c",n,'\0');
+     strip(sn,'B',' ');
+     // cout <<"n="<<n<<" sn=("<<sn<<")  l="<<strlen(sn)<<" k="<<k;
+     if( (int_4) strlen(sn) > k ) s[i] = sn[k];
+     // cout <<"  s=("<<s<<")"<<endl;
+   }}
+   if(pflag&1) printf("    ");
+   printf("                      ");
+   if(pflag&2 && mErr2!=NULL) printf("           ");
+   printf("  %s\n",s);
+ }
+ printf("  (valeurs a multiplier par %.0e)\n",1./expo);
+
+ delete[] s;
+}
+
+
+///////////////////////////////////////////////////////////
+// --------------------------------------------------------
+//   Les objets delegues pour la gestion de persistance 
+// --------------------------------------------------------
+///////////////////////////////////////////////////////////
+
+void ObjFileIO<Histo>::ReadSelf(PInPersist& is)
+{
+char strg[256];
+
+if(dobj==NULL) dobj=new Histo;
+  else         dobj->Delete();
+
+// Lecture entete
+is.GetLine(strg, 255);
+is.GetLine(strg, 255);
+is.GetLine(strg, 255);
+
+// Lecture des valeurs
+is.Get(dobj->mBins);
+is.Get(dobj->nEntries);
+int_4 errok;
+is.Get(errok);
+
+is.Get(dobj->binWidth);
+is.Get(dobj->mMin);
+is.Get(dobj->mMax);
+is.Get(dobj->mUnder);
+is.Get(dobj->mOver);
+
+is.Get(dobj->nHist);
+
+// Lecture des donnees Histo 1D
+dobj->mData = new r_8[dobj->mBins];
+is.GetLine(strg, 255);
+is.Get(dobj->mData, dobj->mBins);
+
+// Lecture des erreurs
+if(errok) {
+  is.GetLine(strg, 255);
+  dobj->mErr2 = new r_8[dobj->mBins];
+  is.Get(dobj->mErr2, dobj->mBins);
+}
+
+return;
+}
+
+void ObjFileIO<Histo>::WriteSelf(POutPersist& os) const
+{
+if (dobj == NULL)   return;
+char strg[256];
+
+// Que faut-il ecrire?
+int_4 errok = (dobj->mErr2) ? 1 : 0;
+
+// Ecriture entete pour identifier facilement
+sprintf(strg,"mBins=%6d  NEnt=%15d  errok=%1d",dobj->mBins,dobj->nEntries,errok);
+os.PutLine(strg);
+sprintf(strg,"binw=%g  mMin=%g mMax=%g",dobj->binWidth,dobj->mMin,dobj->mMax);
+os.PutLine(strg);
+sprintf(strg, "mUnder=%g mOver=%g nHist=%g",dobj->mUnder,dobj->mOver,dobj->nHist);
+os.PutLine(strg);
+
+// Ecriture des valeurs
+os.Put(dobj->mBins);
+os.Put(dobj->nEntries);
+os.Put(errok);
+
+os.Put(dobj->binWidth);
+os.Put(dobj->mMin);
+os.Put(dobj->mMax);
+os.Put(dobj->mUnder);
+os.Put(dobj->mOver);
+
+os.Put(dobj->nHist);
+
+// Ecriture des donnees Histo 1D
+sprintf(strg,"Histo: Tableau des donnees %d",dobj->mBins);
+os.PutLine(strg);
+os.Put(dobj->mData, dobj->mBins);
+
+// Ecriture des erreurs
+if(errok) {
+  sprintf(strg,"Histo: Tableau des erreurs %d",dobj->mBins);
+  os.PutLine(strg);
+  os.Put(dobj->mErr2, dobj->mBins);
+}
+
+return;
+}
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template ObjFileIO<Histo>
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class ObjFileIO<Histo>;
+#endif
Index: /tags/V_Dec2002/SophyaLib/HiStats/histos.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/HiStats/histos.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/HiStats/histos.h	(revision 2309)
@@ -0,0 +1,276 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// $Id: histos.h,v 1.15 2001-02-20 18:29:48 ansari Exp $
+//
+
+#ifndef HISTOS_SEEN
+#define HISTOS_SEEN
+
+#include "objfio.h"
+#include <iostream.h>
+#include <stdio.h>
+#include "peida.h"
+#include "tvector.h"
+#include "ppersist.h"
+#include "anydataobj.h"
+
+namespace SOPHYA {
+
+//! 1 dimension histograms
+class Histo : public AnyDataObj {
+  friend class ObjFileIO<Histo>;
+public:
+
+  // CREATOR / DESTRUCTOR
+  Histo();
+  Histo(r_8 xMin, r_8 xMax, int_4 nBin=100);
+  Histo(r_4 xMin, r_4 xMax, int_4 nBin=100);
+  Histo(const Histo& H);
+  virtual ~Histo();
+
+  // OPTIONS
+  void Errors();
+
+  // UPDATING or SETTING
+  void Zero();
+  void Add(r_8 x, r_8 w = 1.);
+  void AddBin(int_4 numBin, r_8 w = 1.);
+  void SetBin(r_8 x, r_8 w = 1.);
+  void SetBin(int_4 numBin, r_8 w = 1.);
+  void SetErr2(r_8 x, r_8 e2);
+  void SetErr2(int_4 numBin, r_8 e2);
+  void SetErr(r_8 x, r_8 e);
+  void SetErr(int_4 numBin, r_8 e);
+  virtual void UpdateHisto(bool force=false) const;
+
+  // Operators
+  Histo& operator = (const Histo& h);
+  Histo& operator *= (r_8 b);
+  Histo& operator /= (r_8 b);
+  Histo& operator += (r_8 b);
+  Histo& operator -= (r_8 b);
+  Histo& operator += (const Histo& a);
+  Histo& operator -= (const Histo& a);
+  Histo& operator *= (const Histo& a);
+  Histo& operator /= (const Histo& a);
+
+  // get/put dans/depuis un vector
+  void GetAbsc(TVector<r_8>& v) const;
+  void GetValue(TVector<r_8>& v) const;
+  void GetError2(TVector<r_8>& v) const;
+  void GetError(TVector<r_8>& v) const;
+  void PutValue(TVector<r_8>& v, int_4 ierr=0);
+  void PutValueAdd(TVector<r_8> &v, int_4 ierr=0);
+  void PutError2(TVector<r_8>& v);
+  void PutError2Add(TVector<r_8>& v);
+  void PutError(TVector<r_8>& v);
+
+  // INLINES
+  //! Retourne l'abscisse minimum
+  inline r_8 XMin() const {return mMin;}
+  //! Retourne l'abscisse maximum
+  inline r_8 XMax() const {return mMax;}
+  //! Retourne le nombre de bins
+  inline int_4 NBins() const {return mBins;}
+  //! Retourne la largeur du bin
+  inline r_8 BinWidth() const {return binWidth;}
+  //! Retourne le pointeur sur le tableaux des contenus
+  inline r_8* Bins() const {return mData;}
+  //! Retourne le contenu du bin i
+  inline r_8 operator()(int_4 i) const  {return mData[i];}
+  //! Remplit le contenu du bin i
+  inline r_8& operator()(int_4 i) {return mData[i];}
+  //! retourne "true" si il y a des erreurs stoquees
+  inline bool HasErrors() const
+         {if(mErr2) return true; else return false;}
+  //! Retourne l'erreur du bin i
+  inline r_8 Error(int_4 i) const
+         {if(mErr2) {if(mErr2[i]>0.) return sqrt(mErr2[i]); else return 0.;}
+                    else return 0.;}
+  //! Retourne l'erreur au carre du bin i
+  inline r_8 Error2(int_4 i) const
+         {if(mErr2) return mErr2[i]; else return 0.;}
+  //! Remplit l'erreur au carre du bin i
+  inline r_8& Error2(int_4 i) {return mErr2[i];}
+  //! Retourne la somme ponderee
+  inline r_8 NData() const            {return nHist;}
+  //! Retourne le nombre d'entrees
+  inline r_8 NEntries() const         {return nEntries;}
+  //! Retourne le nombre d'overflow
+  inline r_8 NOver() const            {return mOver;}
+  //! Retourne le nombre d'underflow
+  inline r_8 NUnder() const           {return mUnder;}
+
+  //! Retourne l'abscisse du bord inferieur du bin i
+  inline r_8 BinLowEdge(int_4 i)  const {return mMin + i*binWidth;}
+  //! Retourne l'abscisse du centre du bin i
+  inline r_8 BinCenter(int_4 i)   const {return mMin + (i+0.5)*binWidth;}
+  //! Retourne l'abscisse du bord superieur du bin i
+  inline r_8 BinHighEdge(int_4 i) const {return mMin + (i+1)*binWidth;} 
+  //! Retourne le numero du bin contenant l'abscisse x
+  inline int_4 FindBin(r_8 x) const   
+         {return (int_4) floor((x - mMin) / binWidth);}
+
+  // Info, statistique et calculs sur les histogrammes
+  int_4     BinNonNul() const;
+  int_4     ErrNonNul() const;
+  int_4     IMax() const;
+  int_4     IMin() const;
+  r_8       VMax() const;
+  r_8       VMin() const;
+  r_8       Mean() const;
+  r_8       Sigma() const;
+  r_8       MeanLH(int_4 il,int_4 ih) const;
+  r_8       SigmaLH(int_4 il,int_4 ih) const;
+  r_8       Mean(r_8 x0, r_8 dx) const;
+  r_8       Sigma(r_8 x0, r_8 dx) const;
+  r_8       CleanedMean() const;
+  r_8       CleanedMean(r_8& sigma) const;
+  int_4     BinPercent(r_8 per) const;
+  int_4     BinPercent(r_8 x,r_8 per,int_4& imin,int_4& imax) const;
+  int_4     BinPercent(r_8 x,r_8 per,r_8& xmin,r_8& xmax) const;
+  void      HInteg(r_8 norm = 0.);
+  void      HDeriv();
+  virtual void HRebin(int_4 nbinew);
+
+  int_4     MaxiLocal(r_8& maxi,int_4& imax,r_8& maxn,int_4& imaxn) const;
+  r_8       FitMax(int_4 degree=2, r_8 frac=0.5f, int_4 debug=0) const;
+  r_8       FindWidth(r_8 xmax,r_8 frac=0.5f, int_4 debug=0) const;
+  r_8       FindWidth(r_8 frac=0.5f, int_4 debug=0) const;
+  int_4     EstimeMax(r_8& xm,int_4 SzPav = 3) const;
+  int_4     EstimeMax(int_4& im,r_8& xm,int_4 SzPav = 3) const;
+  void      EstimeWidthS(r_8 frac,r_8& widthG,r_8& widthD) const;
+
+  // Print et Display ASCII
+  virtual void Show(ostream& os) const;
+  inline  void Show() const { Show(cout); }
+  void Print(int_4 dyn = 100, r_8 hmin = 1., r_8 hmax = -1.,
+	     int_4 pflag = 0, int_4 il = 1, int_4 ih = -1) const;
+  
+protected:
+  void Delete();
+
+  r_8*   mData;    //!< donnees
+  r_8*   mErr2;	   //!< erreurs carrees
+  r_8    mUnder;   //!< underflow
+  r_8    mOver;    //!< overflow
+  r_8    nHist;    //!< somme ponderee des entrees
+  int_4  nEntries; //!< nombre d'entrees
+  int_4  mBins;    //!< nombre de bins
+  r_8    mMin;     //!< abscisse minimum
+  r_8    mMax;     //!< abscisse maximum
+  r_8    binWidth; //!< largeur du bin
+};
+
+/*! Prints histogram information on stream \b s (h.Show(s)) */
+inline ostream& operator << (ostream& s, Histo const & h)
+  {  h.Show(s);  return(s);  }
+
+/*! \ingroup HiStats \fn operator<<(POuttPersist&,Histo)
+  \brief Persistance management */
+inline POutPersist& operator << (POutPersist& os, Histo & obj)
+{ ObjFileIO<Histo> fio(&obj);  fio.Write(os);  return(os); }
+/*! \ingroup HiStats \fn operator<<(POuttPersist&,Histo)
+  \brief Persistance management */
+inline PInPersist& operator >> (PInPersist& is, Histo & obj)
+{ ObjFileIO<Histo> fio(&obj);  fio.Read(is);  return(is); }
+
+// Classe pour la gestion de persistance
+// ObjFileIO<Histo>
+
+/*! \ingroup HiStats \fn operator*(const Histo&,r_8)
+  \brief Operateur H2 = H1 * b */
+inline Histo operator * (const Histo& a, r_8 b)
+{
+  Histo result(a);
+  return (result *= b);
+}
+
+/*! \ingroup HiStats \fn operator*(r_8,const Histo&)
+  \brief Operateur H2 = b * H1 */
+inline Histo operator * (r_8 b, const Histo& a)
+{
+  Histo result(a);
+  return (result *= b);
+}
+
+/*! \ingroup HiStats \fn operator/(const Histo&,r_8)
+  \brief Operateur H2 = H1 / b */
+inline Histo operator / (const Histo& a, r_8 b)
+{
+  Histo result(a);
+  return (result /= b);
+}
+
+/*! \ingroup HiStats \fn operator+(const Histo&,r_8)
+  \brief Operateur H2 = H1 + b */
+inline Histo operator + (const Histo& a, r_8 b)
+{
+  Histo result(a);
+  return (result += b);
+}
+
+/*! \ingroup HiStats \fn operator+(r_8,const Histo&)
+  \brief Operateur H2 = b + H1 */
+inline Histo operator + (r_8 b, const Histo& a)
+{
+  Histo result(a);
+  return (result += b);
+}
+
+/*! \ingroup HiStats \fn operator-(const Histo&,r_8)
+  \brief Operateur H2 = H1 - b */
+inline Histo operator - (const Histo& a, r_8 b)
+{
+  Histo result(a);
+  return (result -= b);
+}
+
+/*! \ingroup HiStats \fn operator-(r_8,const Histo&)
+  \brief Operateur H2 = b - H1 */
+inline Histo operator - (r_8 b, const Histo& a)
+{
+  Histo result(a);
+  result *= -1.;
+  return (result += b);
+}
+
+/*! \ingroup HiStats \fn operator+(const Histo&,const Histo&)
+  \brief Operateur H = H1 + H2 */
+inline Histo operator + (const Histo& a, const Histo& b)
+{
+if (b.NBins()!=a.NBins()) THROW(sizeMismatchErr);
+Histo c(a);
+return (c += b);
+}
+
+/*! \ingroup HiStats \fn operator-(const Histo&,const Histo&)
+  \brief Operateur H = H1 - H2 */
+inline Histo operator - (const Histo& a, const Histo& b)
+{
+if (b.NBins()!=a.NBins()) THROW(sizeMismatchErr);
+Histo c(a);
+return (c -= b);
+}
+
+/*! \ingroup HiStats \fn operator*(const Histo&,const Histo&)
+  \brief Operateur H = H1 * H2 */
+inline Histo operator * (const Histo& a, const Histo& b)
+{
+if (b.NBins()!=a.NBins()) THROW(sizeMismatchErr);
+Histo c(a);
+return (c *= b);
+}
+
+/*! \ingroup HiStats \fn operator/(const Histo&,const Histo&)
+  \brief Operateur H = H1 / H2 */
+inline Histo operator / (const Histo& a, const Histo& b)
+{
+if (b.NBins()!=a.NBins()) THROW(sizeMismatchErr);
+Histo c(a);
+return (c /= b);
+}
+
+} // Fin du namespace
+
+#endif // HISTOS_SEEN
Index: /tags/V_Dec2002/SophyaLib/HiStats/histos2.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/HiStats/histos2.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/HiStats/histos2.cc	(revision 2309)
@@ -0,0 +1,1698 @@
+//
+//    cmv 05/08/96
+//
+
+#include "machdefs.h"
+
+#include <string.h>
+#include <new.h>
+#include <stdlib.h>
+#include <stdio.h>
+#ifndef NO_VALUES_H
+#include <values.h>
+#endif
+
+#include "histos2.h"
+
+/*!
+  \class SOPHYA::Histo2D
+  \ingroup HiStats
+  Classe d'histogrammes 2D
+  \verbatim
+    Remarque sur les indices:
+     H(i,j)   -> i  = coord x (0<i<nx),     j  = coord y (0<j<ny)
+     v(ii,jj) -> ii = ligne (0<i<NRows()),  jj = colonne (0<i<NCol())
+     On fait une correspondance directe i<->ii et j<->jj
+     ce qui, en representation classique des histos2D et des matrices
+     entraine une inversion x<->y cad une symetrie / diagonale principale
+     H(0,...)  represente ^         mais v(0,...) represente
+                          |x.......               |xxxxxxxx|
+                          |x.......               |........|
+                          |x.......               |........|
+                          |x.......               |........|
+                          |x.......               |........|
+                          --------->
+                          colonne no 1            ligne no 1
+  \endverbatim
+*/
+
+///////////////////////////////////////////////////////////////////
+/*!
+  Createur d'un histogramme 2D ayant nxBin,nyBin bins
+  entre xMin,xMax et yMin,yMax.
+*/
+Histo2D::Histo2D(r_8 xMin,r_8 xMax,int_4 nxBin,r_8 yMin,r_8 yMax,int_4 nyBin)
+      : mData(new r_8[nxBin*nyBin]), mErr2(NULL)
+      , nHist(0), nEntries(0)
+      , mNx(nxBin), mNy(nyBin), mNxy(nxBin*nyBin)
+      , mXmin(xMin), mXmax(xMax), mYmin(yMin), mYmax(yMax)
+      , mWBinx((xMax - xMin)/nxBin), mWBiny((yMax - yMin)/nyBin)
+      , mHprojx(NULL), mHprojy(NULL)
+{
+ASSERT(nxBin>0 && nyBin>0 && xMin<xMax && yMin<yMax);
+for(int_4 i=0;i<3;i++) for(int_4 j=0;j<3;j++) mOver[i][j]=0.;
+Zero();
+mB_s.H = NULL;
+END_CONSTRUCTOR
+}
+
+/*!
+  Createur d'un histogramme 2D ayant nxBin,nyBin bins
+  entre xMin,xMax et yMin,yMax.
+*/
+Histo2D::Histo2D(r_4 xMin,r_4 xMax,int_4 nxBin,r_4 yMin,r_4 yMax,int_4 nyBin)
+      : mData(new r_8[nxBin*nyBin]), mErr2(NULL)
+      , nHist(0), nEntries(0)
+      , mNx(nxBin), mNy(nyBin), mNxy(nxBin*nyBin)
+      , mXmin((r_8)xMin), mXmax((r_8)xMax), mYmin((r_8)yMin), mYmax((r_8)yMax)
+      , mWBinx((xMax - xMin)/nxBin), mWBiny((yMax - yMin)/nyBin)
+      , mHprojx(NULL), mHprojy(NULL)
+{
+ASSERT(nxBin>0 && nyBin>0 && xMin<xMax && yMin<yMax);
+for(int_4 i=0;i<3;i++) for(int_4 j=0;j<3;j++) mOver[i][j]=0.;
+Zero();
+mB_s.H = NULL;
+END_CONSTRUCTOR
+}
+
+/*!
+  Constructeur par copie.
+*/
+Histo2D::Histo2D(const Histo2D& h)
+{
+int_4 i,j;
+mData = new r_8[h.mNxy];
+memcpy(mData, h.mData, h.mNxy*sizeof(r_8));
+
+mErr2 = NULL;
+if(h.mErr2) {
+  mErr2 = new r_8[h.mNxy];
+  memcpy(mErr2, h.mErr2, h.mNxy*sizeof(r_8));
+}
+
+nHist = h.nHist; nEntries = h.nEntries;
+for(i=0;i<3;i++) for(j=0;j<3;j++) mOver[i][j]=h.mOver[i][j];
+mNx = h.mNx;  mNy = h.mNy;  mNxy = h.mNxy;
+mXmin = h.mXmin; mXmax = h.mXmax; mYmin = h.mYmin; mYmax = h.mYmax;
+mWBinx = h.mWBinx; mWBiny = h.mWBiny;
+mB_s.H = NULL;
+
+mHprojx = mHprojy = NULL;
+if(h.mHprojx) {
+  SetProjX();
+  *mHprojx = *(h.mHprojx);
+}
+if(h.mHprojy) {
+  SetProjY();
+  *mHprojy = *(h.mHprojy); 
+}
+
+int_4 nb;
+r_8 min,max;
+nb = h.NSliX();
+if(nb>0) {
+  SetSliX(nb);
+  for(i=0; i<NSliX();i++) *HSliX(i) = *(h.HSliX(i));
+}
+nb = h.NSliY();
+if(nb>0) {
+  SetSliY(nb);
+  for(i=0; i<NSliY();i++) *HSliY(i) = *(h.HSliY(i));
+}
+
+nb = h.NBandX();
+if(nb>0) {
+  for(i=0; i<nb;i++) {
+    h.GetBandX(i,min,max);
+    SetBandX(min,max);
+    *HBandX(i) = *(h.HBandX(i));
+  }
+  for(i=0; i<NBandX();i++) *HBandX(i) = *(h.HBandX(i));
+}
+nb = h.NBandY();
+if(nb>0) {
+  for(i=0; i<nb;i++) {
+    h.GetBandY(i,min,max);
+    SetBandY(min,max);
+    *HBandY(i) = *(h.HBandY(i));
+  }
+  for(i=0; i<NBandY();i++) *HBandY(i) = *(h.HBandY(i));
+}
+
+END_CONSTRUCTOR
+}
+
+/*!
+  Constructeur par defaut.
+*/
+Histo2D::Histo2D()
+      : mData(NULL), mErr2(NULL)
+      , nHist(0), nEntries(0)
+      , mNx(0), mNy(0), mNxy(0)
+      , mXmin(0), mXmax(0), mYmin(0), mYmax(0)
+      , mWBinx(0), mWBiny(0)
+      , mHprojx(NULL), mHprojy(NULL)
+{
+for(int_4 i=0;i<3;i++) for(int_4 j=0;j<3;j++) mOver[i][j]=0.;
+mB_s.H = NULL;
+END_CONSTRUCTOR
+}
+
+///////////////////////////////////////////////////////////////////
+/*!
+  Desallocation de la place de l'histogramme (fct privee).
+*/
+void Histo2D::Delete()
+{
+  if( mData != NULL ) { delete[] mData; mData = NULL;}
+
+  if( mErr2 != NULL ) { delete[] mErr2; mErr2 = NULL;}
+
+  DelProj();
+
+  DelBandX();
+  DelBandY();
+
+  DelSliX();
+  DelSliY();
+
+  nHist = 0;
+  nEntries = 0;
+  mNx = 0; mNy = 0; mNxy = 0;
+  mXmin = 0; mXmax = 0; mYmin = 0; mYmax = 0;
+  mWBinx = 0; mWBiny = 0;
+  for(int_4 i=0;i<3;i++) for(int_4 j=0;j<3;j++) mOver[i][j]=0.;
+  mB_s.H = NULL;
+}
+
+/*!
+  Destructeur.
+*/
+Histo2D::~Histo2D()
+{
+Delete();
+}
+
+///////////////////////////////////////////////////////////////////
+/*!
+  Remise a zero du contenu, des erreurs et des valeurs.
+*/
+void Histo2D::Zero()
+{
+  nHist = nEntries = 0;
+  for(int_4 i=0;i<3;i++) for(int_4 j=0;j<3;j++) mOver[i][j]=0.;
+  memset(mData, 0, mNxy*sizeof(r_8));
+  memset(mOver, 0, 9*sizeof(r_8));
+
+  if( mErr2 != NULL ) memset(mErr2, 0, mNxy*sizeof(r_8));
+
+  ZeroProj();
+
+  ZeroBandX();
+  ZeroBandY();
+
+  ZeroSliX();
+  ZeroSliY();
+}
+
+///////////////////////////////////////////////////////////////////
+/*!
+  Pour avoir le calcul des erreurs.
+*/
+void Histo2D::Errors()
+{
+ if( mNxy > 0 ) {
+   if(mErr2==NULL) mErr2 = new r_8[mNxy];
+   memset(mErr2, 0, mNxy*sizeof(r_8));
+ }
+}
+
+///////////////////////////////////////////////////////////////////
+/*!
+  Operateur H2 = H1
+*/
+Histo2D& Histo2D::operator = (const Histo2D& h)
+{
+  int_4 i,j,nb;
+  r_8 min,max;
+
+  if(this == &h) return *this;
+  if( h.mNxy > mNxy ) Delete();
+  if(!mData) mData = new r_8[h.mNxy];
+  if( !h.mErr2 && mErr2 ) { delete [] mErr2; mErr2=NULL;}
+  if( h.mErr2 && !mErr2 ) mErr2 = new r_8[h.mNxy];
+
+  for(i=0;i<3;i++) for(j=0;j<3;j++) mOver[i][j] = h.mOver[i][j];
+  nHist = h.nHist;
+  nEntries = h.nEntries;
+  mNx = h.mNx;  mNy = h.mNy;  mNxy = h.mNxy;
+  mXmin = h.mXmin; mXmax = h.mXmax; mWBinx = h.mWBinx;
+  mYmin = h.mYmin; mYmax = h.mYmax; mWBiny = h.mWBiny;
+  
+  memcpy(mData, h.mData, mNxy*sizeof(r_8));
+  if(mErr2) memcpy(mErr2, h.mErr2, mNxy*sizeof(r_8));
+
+  DelProjX();
+  if(h.mHprojx) {
+    SetProjX();
+    *mHprojx = *(h.mHprojx);
+  }
+  DelProjY();
+  if(h.mHprojy) {
+    SetProjY();
+    *mHprojy = *(h.mHprojy);
+  }
+
+  DelSliX();
+  nb = h.NSliX();
+  if(nb>0) {
+    SetSliX(nb);
+    for(i=0; i<NSliX();i++) *HSliX(i) = *(h.HSliX(i));
+  }
+  DelSliY();
+  nb = h.NSliY();
+  if(nb>0) {
+    SetSliY(nb);
+    for(i=0; i<NSliY();i++) *HSliY(i) = *(h.HSliY(i));
+  }
+
+  DelBandX();
+  nb = h.NBandX();
+  if(nb>0) {
+    for(i=0; i<nb;i++) {
+      h.GetBandX(i,min,max);
+      SetBandX(min,max);
+      *HBandX(i) = *(h.HBandX(i));
+    }
+    for(i=0; i<NBandX();i++) *HBandX(i) = *(h.HBandX(i));
+  }
+  DelBandY();
+  nb = h.NBandY();
+  if(nb>0) {
+    for(i=0; i<nb;i++) {
+      h.GetBandY(i,min,max);
+      SetBandY(min,max);
+      *HBandY(i) = *(h.HBandY(i));
+    }
+    for(i=0; i<NBandY();i++) *HBandY(i) = *(h.HBandY(i));
+  }
+
+  return *this;
+}
+
+///////////////////////////////////////////////////////////////////
+/*!
+  Operateur H *= b
+*/
+Histo2D& Histo2D::operator *= (r_8 b)
+{
+int_4 i,j;
+r_8 b2 = b*b;
+for(i=0;i<mNxy;i++) {
+  mData[i] *= b;
+  if(mErr2) mErr2[i] *= b2;
+}
+for(i=0;i<3;i++) for(j=0;j<3;j++) mOver[i][j] *= b;
+nHist *= b;
+
+if(mHprojx) *mHprojx *= b;
+if(mHprojy) *mHprojy *= b;
+if(NSliX()>0) for(i=0; i<NSliX();i++) *HSliX(i) *= b;
+if(NSliY()>0) for(i=0; i<NSliY();i++) *HSliY(i) *= b;
+if(NBandX()>0) for(i=0; i<NBandX();i++) *HBandX(i) *= b;
+if(NBandY()>0) for(i=0; i<NBandY();i++) *HBandY(i) *= b;
+
+return *this;
+}
+
+/*!
+  Operateur H /= b
+*/
+Histo2D& Histo2D::operator /= (r_8 b)
+{
+int_4 i,j;
+if (b==0.) THROW(inconsistentErr);
+r_8 b2 = b*b;
+for(i=0;i<mNxy;i++) {
+  mData[i] /= b;
+  if(mErr2) mErr2[i] /= b2;
+}
+for(i=0;i<3;i++) for(j=0;j<3;j++) mOver[i][j] /= b;
+nHist /= b;
+
+if(mHprojx) *mHprojx /= b;
+if(mHprojy) *mHprojy /= b;
+if(NSliX()>0) for(i=0; i<NSliX();i++) *HSliX(i) /= b;
+if(NSliY()>0) for(i=0; i<NSliY();i++) *HSliY(i) /= b;
+if(NBandX()>0) for(i=0; i<NBandX();i++) *HBandX(i) /= b;
+if(NBandY()>0) for(i=0; i<NBandY();i++) *HBandY(i) /= b;
+
+return *this;
+}
+
+/*!
+  Operateur H += b
+*/
+Histo2D& Histo2D::operator += (r_8 b)
+{
+int_4 i,j;
+r_8 min,max;
+for(i=0;i<mNxy;i++) mData[i] += b;
+for(i=0;i<3;i++) for(j=0;j<3;j++) mOver[i][j] += b;
+nHist += mNxy*b;
+
+if(mHprojx) *mHprojx += b*mNy;
+if(mHprojy) *mHprojy += b*mNx;
+if(NSliX()>0) for(i=0; i<NSliX();i++) *HSliX(i) += b*mNy/NSliX();
+if(NSliY()>0) for(i=0; i<NSliY();i++) *HSliY(i) += b*mNx/NSliY();
+if(NBandX()>0) for(i=0; i<NBandX();i++) {
+  GetBandX(i,min,max);
+  *HBandX(i) += b*(max-min)/(mYmax-mYmin)*mNy;
+}
+if(NBandY()>0) for(i=0; i<NBandY();i++) {
+  GetBandY(i,min,max);
+  *HBandY(i) += b*(max-min)/(mXmax-mXmin)*mNx;
+}
+
+return *this;
+}
+
+/*!
+  Operateur H -= b
+*/
+Histo2D& Histo2D::operator -= (r_8 b)
+{
+int_4 i,j;
+r_8 min,max;
+for(i=0;i<mNxy;i++) mData[i] -= b;
+for(i=0;i<3;i++) for(j=0;j<3;j++) mOver[i][j] -= b;
+nHist -= mNxy*b;
+
+if(mHprojx) *mHprojx -= b*mNy;
+if(mHprojy) *mHprojy -= b*mNx;
+if(NSliX()>0) for(i=0; i<NSliX();i++) *HSliX(i) -= b*mNy/NSliX();
+if(NSliY()>0) for(i=0; i<NSliY();i++) *HSliY(i) -= b*mNx/NSliY();
+if(NBandX()>0) for(i=0; i<NBandX();i++) {
+  GetBandX(i,min,max);
+  *HBandX(i) -= b*(max-min)/(mYmax-mYmin)*mNy;
+}
+if(NBandY()>0) for(i=0; i<NBandY();i++) {
+  GetBandY(i,min,max);
+  *HBandY(i) -= b*(max-min)/(mXmax-mXmin)*mNx;
+}
+
+return *this;
+}
+
+///////////////////////////////////////////////////////////////////
+/*!
+  Operateur H += H1
+*/
+Histo2D& Histo2D::operator += (const Histo2D& a)
+{
+int_4 i,j;
+if(mNx!=a.mNx || mNy!=a.mNy) THROW(sizeMismatchErr);
+for(i=0;i<mNxy;i++) {
+  mData[i] += a.mData[i];
+  if(mErr2 && a.mErr2) mErr2[i] += a.mErr2[i];
+}
+for(i=0;i<3;i++) for(j=0;j<3;j++) mOver[i][j] += a.mOver[i][j];
+nHist += a.nHist;
+nEntries += a.nEntries;
+
+if(mHprojx && a.mHprojx) *mHprojx += *(a.mHprojx);
+if(mHprojy && a.mHprojy) *mHprojy += *(a.mHprojy);
+ZeroSliX();  ZeroSliY();
+ZeroBandX(); ZeroBandY();
+
+return *this;
+}
+
+/*!
+  Operateur H -= H1
+*/
+Histo2D& Histo2D::operator -= (const Histo2D& a)
+{
+int_4 i,j;
+if(mNx!=a.mNx || mNy!=a.mNy) THROW(sizeMismatchErr);
+for(i=0;i<mNxy;i++) {
+  mData[i] -= a.mData[i];
+  if(mErr2 && a.mErr2) mErr2[i] += a.mErr2[i];
+}
+for(i=0;i<3;i++) for(j=0;j<3;j++) mOver[i][j] += a.mOver[i][j];
+nHist -= a.nHist;
+nEntries += a.nEntries;
+
+if(mHprojx && a.mHprojx) *mHprojx -= *(a.mHprojx);
+if(mHprojy && a.mHprojy) *mHprojy -= *(a.mHprojy);
+ZeroSliX();  ZeroSliY();
+ZeroBandX(); ZeroBandY();
+
+return *this;
+}
+
+/*!
+  Operateur H *= H1
+*/
+Histo2D& Histo2D::operator *= (const Histo2D& a)
+{
+int_4 i,j;
+if(mNx!=a.mNx || mNy!=a.mNy) THROW(sizeMismatchErr);
+nHist = 0.;
+for(i=0;i<mNxy;i++) {
+  if(mErr2 && a.mErr2)
+      mErr2[i] = a.mData[i]*a.mData[i]*mErr2[i] + mData[i]*mData[i]*a.mErr2[i];
+  mData[i] *= a.mData[i];
+  nHist += mData[i];
+}
+for(i=0;i<3;i++) for(j=0;j<3;j++) mOver[i][j] *= a.mOver[i][j];
+nEntries += a.nEntries;
+
+if(mHprojx && a.mHprojx) *mHprojx *= *(a.mHprojx);
+if(mHprojy && a.mHprojy) *mHprojy *= *(a.mHprojy);
+ZeroSliX();  ZeroSliY();
+ZeroBandX(); ZeroBandY();
+
+return *this;
+}
+
+/*!
+  Operateur H /= H1
+*/
+Histo2D& Histo2D::operator /= (const Histo2D& a)
+{
+int_4 i,j;
+if(mNx!=a.mNx || mNy!=a.mNy) THROW(sizeMismatchErr);
+nHist = 0.;
+for(i=0;i<mNxy;i++) {
+  if(a.mData[i]==0.) {
+    mData[i]=0.;
+    if(mErr2) mErr2[i]=0.;
+    continue;
+  }
+  if(mErr2 && a.mErr2)
+      mErr2[i] = (mErr2[i] + mData[i]/a.mData[i]*mData[i]/a.mData[i]*a.mErr2[i])
+                /(a.mData[i]*a.mData[i]);
+  mData[i] /= a.mData[i];
+  nHist += mData[i];
+}
+for(i=0;i<3;i++) for(j=0;j<3;j++) 
+  if(a.mOver[i][j]!=0.) mOver[i][j] *= a.mOver[i][j]; else mOver[i][j] = 0.;
+nEntries += a.nEntries;
+
+if(mHprojx && a.mHprojx) *mHprojx /= *(a.mHprojx);
+if(mHprojy && a.mHprojy) *mHprojy /= *(a.mHprojy);
+ZeroSliX();  ZeroSliY();
+ZeroBandX(); ZeroBandY();
+
+return *this;
+}
+
+///////////////////////////////////////////////////////////////////
+/*!
+  Remplissage d'un tableau avec les valeurs des abscisses.
+*/
+void Histo2D::GetXCoor(TVector<r_8> &v) const
+{
+r_8 x,y;
+v.Realloc(mNx);
+for(int_4 i=0;i<mNx;i++) {BinLowEdge(i,0,x,y); v(i) = x;}
+return;
+}
+
+/*!
+  Remplissage d'un tableau avec les valeurs des ordonnees.
+*/
+void Histo2D::GetYCoor(TVector<r_8> &v) const
+{
+r_8 x,y;
+v.Realloc(mNy);
+for(int_4 i=0;i<mNy;i++) {BinLowEdge(0,i,x,y); v(i) = y;}
+return;
+}
+
+/*!
+  Remplissage d'un tableau avec les valeurs du contenu.
+*/
+void Histo2D::GetValue(TMatrix<r_8> &v) const
+{
+v.Realloc(mNx,mNy);
+for(int_4 i=0;i<mNx;i++)
+  for(int_4 j=0;j<mNy;j++) v(i,j) = (*this)(i,j);
+return;
+}
+
+/*!
+  Remplissage d'un tableau avec les valeurs du carre des erreurs.
+*/
+void Histo2D::GetError2(TMatrix<r_8> &v) const
+{
+int_4 i,j;
+v.Realloc(mNx,mNy);
+if(!mErr2)
+  {for(i=0;i<mNx;i++) for(j=0;j<mNy;j++) v(i,j) = 0.; return;}
+for(i=0;i<mNx;i++) for(j=0;j<mNy;j++) v(i,j) = Error2(i,j);
+return;
+}
+
+/*!
+  Remplissage d'un tableau avec les valeurs des erreurs.
+*/
+void Histo2D::GetError(TMatrix<r_8> &v) const
+{
+int_4 i,j;
+v.Realloc(mNx,mNy);
+if(!mErr2)
+  {for(i=0;i<mNx;i++) for(j=0;j<mNy;j++) v(i,j) = 0.; return;}
+for(i=0;i<mNx;i++) for(j=0;j<mNy;j++) v(i,j) = Error(i,j);
+return;
+}
+
+///////////////////////////////////////////////////////////////////
+/*!
+  Remplissage du contenu de l'histo avec les valeurs d'un tableau.
+*/
+void Histo2D::PutValue(TMatrix<r_8> &v, int_4 ierr)
+{
+//if(v.NRows()!=(uint_4)mNx || v.NCol()!=(uint_4)mNy) THROW(sizeMismatchErr);
+uint_4 nnx = (v.NRows()<(uint_4)mNx)? v.NRows(): (uint_4)mNx;
+uint_4 nny = (v.NCol() <(uint_4)mNy)? v.NCol() : (uint_4)mNy;
+if(nnx>0 && nny>0) for(uint_4 i=0;i<nnx;i++) for(uint_4 j=0;j<nny;j++) {
+  (*this)(i,j) = v(i,j);
+  if(mErr2 && ierr) Error2(i,j) = fabs(v(i,j));
+}
+return;
+}
+
+/*!
+  Addition du contenu de l'histo avec les valeurs d'un tableau.
+*/
+void Histo2D::PutValueAdd(TMatrix<r_8> &v, int_4 ierr)
+{
+//if(v.NRows()!=(uint_4)mNx || v.NCol()!=(uint_4)mNy) THROW(sizeMismatchErr);
+uint_4 nnx = (v.NRows()<(uint_4)mNx)? v.NRows(): (uint_4)mNx;
+uint_4 nny = (v.NCol() <(uint_4)mNy)? v.NCol() : (uint_4)mNy;
+if(nnx>0 && nny>0) for(uint_4 i=0;i<nnx;i++) for(uint_4 j=0;j<nny;j++) {
+  (*this)(i,j) += v(i,j);
+  if(mErr2 && ierr) Error2(i,j) += fabs(v(i,j));
+}
+return;
+}
+
+/*!
+  Remplissage des erreurs au carre de l'histo
+  avec les valeurs d'un tableau.
+*/
+void Histo2D::PutError2(TMatrix<r_8> &v)
+{
+//if(v.NRows()!=(uint_4)mNx || v.NCol()!=(uint_4)mNy) THROW(sizeMismatchErr);
+uint_4 nnx = (v.NRows()<(uint_4)mNx)? v.NRows(): (uint_4)mNx;
+uint_4 nny = (v.NCol() <(uint_4)mNy)? v.NCol() : (uint_4)mNy;
+if(nnx>0 && nny>0) {
+  if(!mErr2) Errors();
+  for(uint_4 i=0;i<nnx;i++) for(uint_4 j=0;j<nny;j++) Error2(i,j) = v(i,j);
+}
+return;
+}
+
+/*!
+  Addition des erreurs au carre de l'histo
+  avec les valeurs d'un tableau.
+*/
+void Histo2D::PutError2Add(TMatrix<r_8> &v)
+{
+//if(v.NRows()!=(uint_4)mNx || v.NCol()!=(uint_4)mNy) THROW(sizeMismatchErr);
+uint_4 nnx = (v.NRows()<(uint_4)mNx)? v.NRows(): (uint_4)mNx;
+uint_4 nny = (v.NCol() <(uint_4)mNy)? v.NCol() : (uint_4)mNy;
+if(nnx>0 && nny>0) {
+  if(!mErr2) Errors();
+  for(uint_4 i=0;i<nnx;i++) for(uint_4 j=0;j<nny;j++)
+          if(v(i,j)>0.) Error2(i,j) += v(i,j);
+}
+return;
+}
+
+/*!
+  Remplissage des erreurs de l'histo avec les valeurs d'un tableau.
+*/
+void Histo2D::PutError(TMatrix<r_8> &v)
+{
+//if(v.NRows()!=(uint_4)mNx || v.NCol()!=(uint_4)mNy) THROW(sizeMismatchErr);
+uint_4 nnx = (v.NRows()<(uint_4)mNx)? v.NRows(): (uint_4)mNx;
+uint_4 nny = (v.NCol() <(uint_4)mNy)? v.NCol() : (uint_4)mNy;
+if(nnx>0 && nny>0) {
+  if(!mErr2) Errors();
+  for(uint_4 i=0;i<nnx;i++) for(uint_4 j=0;j<nny;j++)
+    if(v(i,j)>0.) Error2(i,j)=v(i,j)*v(i,j); else Error2(i,j)= -v(i,j)*v(i,j);
+}
+return;
+}
+
+///////////////////////////////////////////////////////////////////
+/********* Methode *********/
+/*!
+  Addition du contenu de l'histo pour x,y poids w.
+*/
+void Histo2D::Add(r_8 x, r_8 y, r_8 w)
+{
+list<bande_slice>::iterator it;
+int_4 i,j;
+FindBin(x,y,i,j);
+
+if( mHprojx != NULL ) mHprojx->Add(x,w);
+if( mHprojy != NULL ) mHprojy->Add(y,w);
+
+if(mLBandx.size()>0)
+  for( it = mLBandx.begin(); it != mLBandx.end(); it++)
+    if( (*it).min <= y && y < (*it).max ) (*it).H->Add(x,w);
+
+if(mLBandy.size()>0)
+  for( it = mLBandy.begin(); it != mLBandy.end(); it++)
+    if( (*it).min <= x && x < (*it).max ) (*it).H->Add(y,w);
+
+if(mLSlix.size()>0)
+  for( it = mLSlix.begin(); it != mLSlix.end(); it++)
+    if( (*it).min <= y && y < (*it).max ) (*it).H->Add(x,w);
+
+if(mLSliy.size()>0)
+  for( it = mLSliy.begin(); it != mLSliy.end(); it++)
+    if( (*it).min <= x && x < (*it).max ) (*it).H->Add(y,w);
+
+if( i<0 || i>=mNx || j<0 || j>=mNy ) {
+  if(i<0) i=0; else if(i>=mNx) i=2; else i=1;
+  if(j<0) j=0; else if(j>=mNy) j=2; else j=1;
+  mOver[i][j] += w;
+  mOver[1][1] += w;
+  return;
+}
+
+mData[j*mNx+i] += w;
+if(mErr2!=NULL) mErr2[j*mNx+i] += w*w;
+nHist += w;
+nEntries++;
+}
+
+///////////////////////////////////////////////////////////////////
+/*!
+  Recherche du bin du maximum dans le pave [il,ih][jl,jh].
+*/
+void Histo2D::IJMax(int_4& imax,int_4& jmax,int_4 il,int_4 ih,int_4 jl,int_4 jh) const
+{
+if( il > ih ) { il = 0; ih = mNx-1; }
+if( jl > jh ) { jl = 0; jh = mNy-1; }
+if( il < 0 ) il = 0;
+if( jl < 0 ) jl = 0;
+if( ih >= mNx ) ih = mNx-1;
+if( jh >= mNy ) jh = mNy-1;
+
+imax = jmax = 0;
+if(mNxy==1) return;
+
+r_8 mx=(*this)(il,jl);
+for (int_4 i=il; i<=ih; i++)
+   for (int_4 j=jl; j<=jh; j++)
+      if ((*this)(i,j)>mx) {imax = i; jmax = j; mx=(*this)(i,j);}
+}
+
+/*!
+  Recherche du bin du minimum dans le pave [il,ih][jl,jh].
+*/
+void Histo2D::IJMin(int_4& imax,int_4& jmax,int_4 il,int_4 ih,int_4 jl,int_4 jh) const
+{
+if( il > ih ) { il = 0; ih = mNx-1; }
+if( jl > jh ) { jl = 0; jh = mNy-1; }
+if( il < 0 ) il = 0;
+if( jl < 0 ) jl = 0;
+if( ih >= mNx ) ih = mNx-1;
+if( jh >= mNy ) jh = mNy-1;
+
+imax = jmax = 0;
+if(mNxy==1) return;
+
+r_8 mx=(*this)(il,jl);
+for (int_4 i=il; i<=ih; i++)
+   for (int_4 j=jl; j<=jh; j++)
+      if ((*this)(i,j)<mx) {imax = i; jmax = j; mx=(*this)(i,j);}
+}
+
+
+/*!
+  Recherche du maximum dans le pave [il,ih][jl,jh].
+*/
+r_8 Histo2D::VMax(int_4 il,int_4 ih,int_4 jl,int_4 jh) const
+{
+if( il > ih ) { il = 0; ih = mNx-1; }
+if( jl > jh ) { jl = 0; jh = mNy-1; }
+if( il < 0 ) il = 0;
+if( jl < 0 ) jl = 0;
+if( ih >= mNx ) ih = mNx-1;
+if( jh >= mNy ) jh = mNy-1;
+
+r_8 mx=(*this)(il,jl);
+if(mNxy==1) return mx;
+for (int_4 i=il; i<=ih; i++)
+   for (int_4 j=jl; j<=jh; j++)
+      if ((*this)(i,j)>mx) mx=(*this)(i,j);
+return mx;
+}
+
+/*!
+  Recherche du minimum dans le pave [il,ih][jl,jh].
+*/
+r_8 Histo2D::VMin(int_4 il,int_4 ih,int_4 jl,int_4 jh) const
+{
+if( il > ih ) { il = 0; ih = mNx-1; }
+if( jl > jh ) { jl = 0; jh = mNy-1; }
+if( il < 0 ) il = 0;
+if( jl < 0 ) jl = 0;
+if( ih >= mNx ) ih = mNx-1;
+if( jh >= mNy ) jh = mNy-1;
+
+r_8 mx=(*this)(il,jl);
+if(mNxy==1) return mx;
+for (int_4 i=il; i<=ih; i++)
+   for (int_4 j=jl; j<=jh; j++)
+      if ((*this)(i,j)<mx) mx=(*this)(i,j);
+return mx;
+}
+
+///////////////////////////////////////////////////////////////////
+/*!
+  Renvoie les under.overflow dans les 8 quadrants.
+  \verbatim
+     mOver[3][3]:       20 | 21 | 22
+                           |    |
+                       --------------
+                           |    |
+                        10 | 11 | 12        11 = all overflow+underflow
+                           |    |
+                       --------------
+                           |    |
+                        00 | 01 | 02
+  \endverbatim
+*/
+r_8 Histo2D::NOver(int_4 i,int_4 j) const
+{
+if( i < 0 || i>=3 || j < 0 || j>=3 ) return mOver[1][1];
+return mOver[i][j];
+}
+
+
+///////////////////////////////////////////////////////////////////
+/*!
+  Retourne le nombre de bins non-nuls.
+*/
+int_4 Histo2D::BinNonNul() const
+{
+int_4 non=0;
+for (int_4 i=0;i<mNxy;i++) if( mData[i] != 0. ) non++;
+return non;
+}
+
+/*!
+  Retourne le nombre de bins avec erreurs non-nulles.
+*/
+int_4 Histo2D::ErrNonNul() const
+{
+if(mErr2==NULL) return -1;
+int_4 non=0;
+for (int_4 i=0;i<mNxy;i++) if( mErr2[i] != 0. ) non++;
+return non;
+}
+
+///////////////////////////////////////////////////////////////////
+/*!
+  Idem EstimeMax(int...) mais retourne x,y.
+*/
+int_4 Histo2D::EstimeMax(r_8& xm,r_8& ym,int_4 SzPav
+                      ,int_4 il,int_4 ih,int_4 jl,int_4 jh) const
+{
+int_4 im,jm;
+IJMax(im,jm,il,ih,jl,jh);
+return EstimeMax(im,jm,xm,ym,SzPav);
+}
+
+/*!
+  Determine les abscisses et ordonnees du maximum donne par im,jm
+  en moyennant dans un pave SzPav x SzPav autour du maximum.
+  \verbatim
+     Return:
+       0 = si fit maximum reussi avec SzPav pixels
+       1 = si fit maximum reussi avec moins que SzPav pixels
+                                   dans au moins 1 direction
+       2 = si fit maximum echoue et renvoit BinCenter()
+      -1 = si echec: SzPav <= 0 ou im,jm hors limites
+  \endverbatim
+*/
+int_4 Histo2D::EstimeMax(int_4 im,int_4 jm,r_8& xm,r_8& ym,int_4 SzPav) const
+{
+xm = ym = 0;
+if( SzPav <= 0 ) return -1;
+if( im < 0 || im >= mNx ) return -1;
+if( jm < 0 || jm >= mNy ) return -1;
+
+if( SzPav%2 == 0 ) SzPav++;
+SzPav = (SzPav-1)/2;
+
+int_4 rc = 0;
+r_8 dxm = 0, dym = 0, wx = 0;
+for(int_4 i=im-SzPav;i<=im+SzPav;i++) {
+  if( i<0 || i>= mNx ) {rc=1; continue;}
+  for(int_4 j=jm-SzPav;j<=jm+SzPav;j++) {
+    if( j<0 || j>= mNy ) {rc=1; continue;}
+    r_8 x,y;
+    BinCenter(i,j,x,y);
+    dxm += x * (*this)(i,j);
+    dym += y * (*this)(i,j);
+    wx  += (*this)(i,j);
+  }
+}
+
+if( wx > 0. ) {
+  xm = dxm/wx;
+  ym = dym/wx;
+  return rc;
+} else {
+  BinCenter(im,jm,xm,ym);
+  return 2;
+}
+
+}
+
+/*!
+  Pour trouver le maximum de l'histogramme en tenant compte
+  des fluctuations.
+  \verbatim
+    Methode:
+    1-/ On recherche le bin maximum MAX de l'histogramme
+    2-/ On considere que tous les pixels compris entre [MAX-Dz,MAX]
+        peuvent etre des pixels maxima.
+    3-/ On identifie le bin maximum en choissisant le pixel du 2-/
+        tel que la somme des pixels dans un pave SzPav x SzPav soit maximale.
+    INPUT:
+     SzPav = taille du pave pour departager
+     Dz    = tolerance pour identifier tous les pixels "maximum"
+    OUTPUT:
+     im,jm = pixel maximum trouve
+    RETURN:
+      <0 =  Echec
+      >0 =  nombre de pixels possibles pour le maximum
+  \endverbatim
+*/
+int_4 Histo2D::FindMax(int_4& im,int_4& jm,int_4 SzPav,r_8 Dz
+                    ,int_4 il,int_4 ih,int_4 jl,int_4 jh) const
+{
+if( il > ih ) { il = 0; ih = mNx-1; }
+if( jl > jh ) { jl = 0; jh = mNy-1; }
+if( il < 0 ) il = 0;
+if( jl < 0 ) jl = 0;
+if( ih >= mNx ) ih = mNx-1;
+if( jh >= mNy ) jh = mNy-1;
+if( SzPav < 0 ) SzPav = 0;
+  else { if( SzPav%2 == 0 ) SzPav++; SzPav = (SzPav-1)/2;}
+if( Dz < 0 ) Dz = 0.;
+r_8 max = VMax(il,ih,jl,jh) - Dz;
+int_4 nmax = 0;
+r_8 sumx = -1.e20;
+for(int_4 i=il;i<=ih;i++) for(int_4 j=jl;j<=jh;j++) {
+  if( (*this)(i,j) < max) continue;
+  nmax++;
+  r_8 sum = 0.;
+  for(int_4 ii=i-SzPav;ii<=i+SzPav;ii++) {
+    if( ii<0 || ii >= mNx ) continue;
+    for(int_4 jj=j-SzPav;jj<=j+SzPav;jj++) {
+      if( jj<0 || jj >= mNy ) continue;
+      sum += (*this)(ii,jj);
+    }
+  }
+  if(nmax==1 || sum>sumx) {im=i; jm=j; sumx=sum;}
+}
+if( nmax <= 0 ) { IJMax(im,jm,il,ih,jl,jh); return 1;}
+return nmax;
+}
+
+///////////////////////////////////////////////////////////////////
+/*!
+  Impression des informations sur l'histogramme.
+*/
+void Histo2D::Show(ostream & os) const
+{
+  os << "Histo2D::Show    nHist=" << nHist << " nEntries=" << nEntries;
+  if(HasErrors()) os << "  Errors=Y \n"; else os << "  Errors=N\n";
+  os << "mOver: [ " ;
+  for(int j=2; j>=0; j--) {
+    for(int i=0; i<3; i++) 
+      os << mOver[j][i] << " " ;
+    if (j != 0) os << "// ";
+  }
+  os << "]\n";
+  os << "  nx=" << mNx << " xmin=" << mXmin << " xmax=" << mXmax 
+     << " binx=" << mWBinx ;
+  os << "  ny=" << mNy << " ymin=" << mYmin << " ymax=" << mYmax 
+     << " biny=" << mWBiny << endl;
+   
+  //printf("mOver: [ %g %g %g // %g %g %g  // %g %g %g ]\n"
+  //      ,mOver[2][0],mOver[2][1],mOver[2][2]
+  //      ,mOver[1][0],mOver[1][1],mOver[1][2]
+  //      ,mOver[0][0],mOver[0][1],mOver[0][2]);
+  //printf("  nx=%d xmin=%g xmax=%g binx=%g  ",mNx,mXmin,mXmax,mWBinx);
+  //printf("  ny=%d ymin=%g ymax=%g biny=%g\n",mNy,mYmin,mYmax,mWBiny);
+}
+
+///////////////////////////////////////////////////////////////////
+/*!
+  Impression de l'histogramme sur stdout entre [il,ih] et [jl,jh].
+  \verbatim
+    numero d'index:  00000000001111111111222222222233333
+                     01234567890123456789012345678901234
+    valeur entiere:  00000000001111111111222222222233333
+                     12345678901234567890123456789012345
+  \endverbatim
+*/
+void Histo2D::Print(r_8 min,r_8 max
+                   ,int_4 il,int_4 ih,int_4 jl,int_4 jh) const
+{
+int_4 ns = 35;
+const char *s =    "+23456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+if( il > ih ) { il = 0; ih = mNx-1; }
+if( jl > jh ) { jl = 0; jh = mNy-1; }
+if( il < 0 ) il = 0;
+if( jl < 0 ) jl = 0;
+if( ih >= mNx ) ih = mNx-1;
+if( jh >= mNy ) jh = mNy-1;
+
+PrintStatus();
+
+if( il != 0 || ih != mNx-1 || jl != 0 || jh != mNy-1 ) {
+  r_8 xl,xh,yl,yh;
+  BinLowEdge(il,jl,xl,yl);
+  BinHighEdge(ih,jh,xh,yh);
+  printf("  impression");
+  printf("  en X: %d=[%d,%d] xmin=%g xmax=%g  "
+        ,ih-il+1,il,ih,xl,xh);
+  printf("  en Y: %d=[%d,%d] ymin=%g ymax=%g\n"
+        ,jh-jl+1,jl,jh,yl,yh);
+}
+
+if(min >= max) { if(min != 0.) min = VMin(il,ih,jl,jh); else min=0.;
+                 max = VMax(il,ih,jl,jh); }
+if(min>max) return;
+if(min==max) {min -= 1.; max += 1.;}
+printf("   min=%g max=%g\n",min,max);
+
+// imprime numero de bin en colonne
+printf("\n");
+if( mNx-1 >= 100 ) {
+  printf("     ");
+  for(int_4 i=il;i<=ih;i++) printf("%1d",(int_4) (i%1000)/100);
+  printf("\n");
+}
+if( mNx-1 >= 10 ) {
+  printf("     ");
+  for(int_4 i=il;i<=ih;i++) printf("%1d",(int_4) (i%100)/10);
+  printf("\n");
+}
+printf("     ");
+for(int_4 i=il;i<=ih;i++) printf("%1d",i%10);
+printf("\n");
+printf("     "); {for(int_4 i=il;i<=ih;i++) printf("-"); printf("\n");}
+
+// imprime histogramme
+for(int_4 j=jh;j>=jl;j--) {
+  printf("%3d: ",j);
+  for(int_4 i=il;i<=ih;i++) {
+    int_4 h;
+    if( 1<=max-min && max-min<=35 ) h = (int_4)( (*this)(i,j) - min ) - 1;
+      else h = (int_4)( ((*this)(i,j)-min)/(max-min) * ns ) - 1;
+    char c;
+    if(h<0 && (*this)(i,j)>min) c = '.';
+      else if(h<0) c = ' ';
+        else if(h>=ns) c = '*';
+          else c = s[h];
+    printf("%c",c);
+  }
+  printf("\n");
+}
+
+// imprime numero de bin en colonne
+printf("     "); {for(int_4 i=il;i<=ih;i++) printf("-"); printf("\n");}
+if( mNx-1 >= 100 ) {
+  printf("     ");
+  for(int_4 i=il;i<=ih;i++) printf("%1d",(int_4) (i%1000)/100);
+  printf("\n");
+}
+if( mNx-1 >= 10 ) {
+  printf("     ");
+  for(int_4 i=il;i<=ih;i++) printf("%1d",(int_4) (i%100)/10);
+  printf("\n");
+}
+printf("     ");
+{for(int_4 i=il;i<=ih;i++) printf("%1d",i%10);}
+printf("\n");
+
+}
+
+///////////////////////////////////////////////////////////////////
+// Titre	Methodes pour gerer les projections
+
+/*!
+  Pour creer la projection X.
+*/
+void Histo2D::SetProjX()
+{
+if( mHprojx != NULL ) DelProjX();
+mHprojx = new Histo(mXmin,mXmax,mNx);
+if( mErr2 != NULL && mHprojx != NULL ) mHprojx->Errors();
+}
+
+/*!
+  Pour creer la projection Y.
+*/
+void Histo2D::SetProjY()
+{
+if( mHprojy != NULL ) DelProjY();
+mHprojy = new Histo(mYmin,mYmax,mNy);
+if( mErr2 != NULL && mHprojy != NULL  ) mHprojy->Errors();
+}
+
+/*!
+  Pour creer les projections X et Y.
+*/
+void Histo2D::SetProj()
+{
+SetProjX();
+SetProjY();
+}
+
+/*!
+  Informations sur les projections.
+*/
+void Histo2D::ShowProj() const
+{
+if( mHprojx != NULL ) cout << ">>>> Projection X set : "<< mHprojx <<endl;
+  else cout << ">>>> NO Projection X set"<<endl;
+if( mHprojy != NULL ) cout << ">>>> Projection Y set : "<< mHprojy <<endl;
+  else cout << ">>>> NO Projection Y set"<<endl;
+}
+
+/*!
+  Destruction de l'histogramme de la projection selon X.
+*/
+void Histo2D::DelProjX()
+{
+if( mHprojx == NULL ) return;
+delete mHprojx;
+mHprojx = NULL;
+}
+
+/*!
+  Destruction de l'histogramme de la projection selon X.
+*/
+void Histo2D::DelProjY()
+{
+if( mHprojy == NULL ) return;
+delete mHprojy;
+mHprojy = NULL;
+}
+
+/*!
+  Destruction des histogrammes des projections selon X et Y.
+*/
+void Histo2D::DelProj()
+{
+DelProjX();
+DelProjY();
+}
+
+/*!
+  Remise a zero de la projection selon X.
+*/
+void Histo2D::ZeroProjX()
+{
+if( mHprojx == NULL ) return;
+mHprojx->Zero();
+}
+
+/*!
+  Remise a zero de la projection selon Y.
+*/
+void Histo2D::ZeroProjY()
+{
+if( mHprojy == NULL ) return;
+mHprojy->Zero();
+}
+
+/*!
+  Remise a zero des projections selon X et Y.
+*/
+void Histo2D::ZeroProj()
+{
+ZeroProjX();
+ZeroProjY();
+}
+
+///////////////////////////////////////////////////////////////////
+// Titre	Methodes pour gerer les bandes
+
+/*!
+  Pour creer une bande en X entre ybmin et ybmax.
+*/
+int_4 Histo2D::SetBandX(r_8 ybmin,r_8 ybmax)
+{
+mB_s.num = mLBandx.size();
+mB_s.min = ybmin;
+mB_s.max = ybmax;
+mB_s.H = new Histo(mXmin,mXmax,mNx);
+mLBandx.push_back(mB_s);
+mB_s.H = NULL;
+return mLBandx.size()-1;
+}
+
+/*!
+  Pour creer une bande en Y entre xbmin et xbmax.
+*/
+int_4 Histo2D::SetBandY(r_8 xbmin,r_8 xbmax)
+{
+mB_s.num = mLBandy.size();
+mB_s.min = xbmin;
+mB_s.max = xbmax;
+mB_s.H = new Histo(mYmin,mYmax,mNy);
+mLBandy.push_back(mB_s);
+mB_s.H = NULL;
+return mLBandy.size()-1;
+}
+
+/*!
+  Destruction des histogrammes des bandes selon X.
+*/
+void Histo2D::DelBandX()
+{
+if( mLBandx.size() <= 0 ) return;
+for(list<bande_slice>::iterator i = mLBandx.begin(); i != mLBandx.end(); i++)
+       if( (*i).H != NULL ) {delete (*i).H; (*i).H=NULL;}
+mLBandx.erase(mLBandx.begin(),mLBandx.end());
+}
+
+/*!
+  Destruction des histogrammes des bandes selon Y.
+*/
+void Histo2D::DelBandY()
+{
+if( mLBandy.size() <= 0 ) return;
+for(list<bande_slice>::iterator i = mLBandy.begin(); i != mLBandy.end(); i++)
+       if( (*i).H != NULL ) {delete (*i).H; (*i).H=NULL;}
+mLBandy.erase(mLBandy.begin(),mLBandy.end());
+}
+
+/*!
+  Remise a zero des bandes selon X.
+*/
+void Histo2D::ZeroBandX()
+{
+if( mLBandx.size() <= 0 ) return;
+list<bande_slice>::iterator i;
+for(i = mLBandx.begin(); i != mLBandx.end(); i++)
+              (*i).H->Zero();
+}
+
+/*!
+  Remise a zero des bandes selon Y.
+*/
+void Histo2D::ZeroBandY()
+{
+if( mLBandy.size() <= 0 ) return;
+list<bande_slice>::iterator i;
+for(i = mLBandy.begin(); i != mLBandy.end(); i++)
+              (*i).H->Zero();
+}
+
+/*!
+  Retourne un pointeur sur la bande numero `n' selon X.
+*/
+Histo* Histo2D::HBandX(int_4 n) const
+{
+if( mLBandx.size() <= 0 || n < 0 || n >= (int_4) mLBandx.size() ) return NULL;
+for(list<bande_slice>::const_iterator i = mLBandx.begin(); i != mLBandx.end(); i++)
+              if( (*i).num == n ) return (*i).H;
+return NULL;
+}
+
+/*!
+  Retourne un pointeur sur la bande numero `n' selon Y.
+*/
+Histo* Histo2D::HBandY(int_4 n) const
+{
+if( mLBandy.size() <= 0 || n < 0 || n >= (int_4) mLBandy.size() ) return NULL;
+for(list<bande_slice>::const_iterator i = mLBandy.begin(); i != mLBandy.end(); i++)
+              if( (*i).num == n ) return (*i).H;
+return NULL;
+}
+
+/*!
+  Retourne les limites de la bande numero `n' selon X.
+*/
+void Histo2D::GetBandX(int_4 n,r_8& ybmin,r_8& ybmax) const
+{
+ybmin = 0.; ybmax = 0.;
+if( mLBandx.size() <= 0 || n < 0 || n >= (int_4) mLBandx.size() ) return;
+for(list<bande_slice>::const_iterator i = mLBandx.begin(); i != mLBandx.end(); i++)
+  if( (*i).num == n ) { ybmin = (*i).min; ybmax = (*i).max; return;}
+return;
+}
+
+/*!
+  Retourne les limites de la bande numero `n' selon Y.
+*/
+void Histo2D::GetBandY(int_4 n,r_8& xbmin,r_8& xbmax) const
+{
+xbmin = 0.; xbmax = 0.;
+if( mLBandy.size() <= 0 || n < 0 || n >= (int_4) mLBandy.size() ) return;
+for(list<bande_slice>::const_iterator i = mLBandy.begin(); i != mLBandy.end(); i++)
+  if( (*i).num == n ) { xbmin = (*i).min; xbmax = (*i).max; return;}
+return;
+}
+
+/*!
+  Informations sur les bandes.
+*/
+void Histo2D::ShowBand(int_4 lp) const
+{
+  cout << ">>>> Nombre de bande X : " << mLBandx.size() << endl;
+if( lp>0 && mLBandx.size()>0 ) {
+  list<bande_slice>::const_iterator i;
+  for(i = mLBandx.begin(); i != mLBandx.end(); i++) {
+    cout<<"  "<<(*i).num<<" de ymin="<<(*i).min<<" a ymax="<<(*i).max;
+    if(lp>1) cout << "   H=" << (*i).H;
+    cout << endl;
+  }
+}
+
+cout << ">>>> Nombre de bande Y : " << mLBandy.size() << endl;
+if( lp>0 && mLBandy.size()>0 ) {
+  list<bande_slice>::const_iterator i;
+  for(i = mLBandy.begin(); i != mLBandy.end(); i++) {
+    cout<<"  "<<(*i).num<<" de xmin="<<(*i).min<<" a xmax="<<(*i).max;
+    if(lp>1) cout << "   H=" << (*i).H;
+    cout << endl;
+  }
+}
+}
+
+///////////////////////////////////////////////////////////////////
+// Titre  Methodes pour gerer les bandes equidistantes ou slices
+
+/*!
+  Pour creer `nsli' bandes equidistantes selon X.
+*/
+int_4 Histo2D::SetSliX(int_4 nsli)
+{
+if( nsli <= 0 ) return -1;
+if( nsli >  mNy ) nsli = mNy;
+if( mLSlix.size() > 0 ) DelSliX();
+r_8 w = (mYmax-mYmin)/nsli;
+
+for(int_4 i=0; i<nsli; i++ ) {
+  mB_s.num = i;
+  mB_s.min = mYmin + i*w;
+  mB_s.max = mB_s.min + w;
+  mB_s.H = new Histo(mXmin,mXmax,mNx);
+  mLSlix.push_back(mB_s);
+  mB_s.H = NULL;
+}
+return (int_4) mLSlix.size();
+}
+
+/*!
+  Pour creer `nsli' bandes equidistantes selon Y.
+*/
+int_4 Histo2D::SetSliY(int_4 nsli)
+{
+if( nsli <= 0 ) return -1;
+if( nsli >  mNx ) nsli = mNx;
+if( mLSliy.size() > 0 ) DelSliY();
+r_8 w = (mXmax-mXmin)/nsli;
+
+for(int_4 i=0; i<nsli; i++ ) {
+  mB_s.num = i;
+  mB_s.min = mXmin + i*w;
+  mB_s.max = mB_s.min + w;
+  mB_s.H = new Histo(mYmin,mYmax,mNy);
+  mLSliy.push_back(mB_s);
+  mB_s.H = NULL;
+}
+return (int_4) mLSliy.size();
+}
+
+/*!
+  Destruction des bandes equidistantes selon X.
+*/
+void Histo2D::DelSliX()
+{
+if( mLSlix.size() <= 0 ) return;
+for(list<bande_slice>::iterator i = mLSlix.begin(); i != mLSlix.end(); i++)
+       if( (*i).H != NULL ) {delete (*i).H; (*i).H=NULL;}
+mLSlix.erase(mLSlix.begin(),mLSlix.end());
+}
+
+/*!
+  Destruction des bandes equidistantes selon Y.
+*/
+void Histo2D::DelSliY()
+{
+if( mLSliy.size() <= 0 ) return;
+for(list<bande_slice>::iterator i = mLSliy.begin(); i != mLSliy.end(); i++)
+       if( (*i).H != NULL ) {delete (*i).H; (*i).H=NULL;}
+mLSliy.erase(mLSliy.begin(),mLSliy.end());
+}
+
+/*!
+  Remise a zero des bandes equidistantes selon X.
+*/
+void Histo2D::ZeroSliX()
+{
+if( mLSlix.size() <= 0 ) return;
+list<bande_slice>::iterator i;
+for(i = mLSlix.begin(); i != mLSlix.end(); i++)
+              (*i).H->Zero();
+}
+
+/*!
+  Remise a zero des bandes equidistantes selon Y.
+*/
+void Histo2D::ZeroSliY()
+{
+if( mLSliy.size() <= 0 ) return;
+list<bande_slice>::iterator i;
+for(i = mLSliy.begin(); i != mLSliy.end(); i++)
+              (*i).H->Zero();
+}
+
+/*!
+  Retourne un pointeur sur la bande equidistante numero `n'
+  selon X.
+*/
+Histo* Histo2D::HSliX(int_4 n) const
+{
+if( mLSlix.size() <= 0 || n < 0 || n >= (int_4) mLSlix.size() ) return NULL;
+for(list<bande_slice>::const_iterator i = mLSlix.begin(); i != mLSlix.end(); i++)
+              if( (*i).num == n ) return (*i).H;
+return NULL;
+}
+
+/*!
+  Retourne un pointeur sur la bande equidistante numero `n'
+  selon Y.
+*/
+Histo* Histo2D::HSliY(int_4 n) const
+{
+if( mLSliy.size() <= 0 || n < 0 || n >= (int_4) mLSliy.size() ) return NULL;
+for(list<bande_slice>::const_iterator i = mLSliy.begin(); i != mLSliy.end(); i++)
+              if( (*i).num == n ) return (*i).H;
+return NULL;
+}
+
+/*!
+  Informations sur les bandes equidistantes.
+*/
+void Histo2D::ShowSli(int_4 lp) const
+{
+list<bande_slice>::const_iterator i;
+cout << ">>>> Nombre de slice X : " << mLSlix.size() << endl;
+if( lp>0 && mLSlix.size() > 0 )
+  for(i = mLSlix.begin(); i != mLSlix.end(); i++) {
+    cout<<"  "<<(*i).num<<" de ymin="<<(*i).min<<" a ymax="<<(*i).max;
+    if(lp>1) cout << "   H=" << (*i).H;
+    cout << endl;
+  }
+
+cout << ">>>> Nombre de slice Y : " << mLSliy.size() << endl;
+if( lp>0 && mLSliy.size()>0 )
+  for(i = mLSliy.begin(); i != mLSliy.end(); i++) {
+    cout<<"  "<<(*i).num<<" de xmin="<<(*i).min<<" a xmax="<<(*i).max;
+    if(lp>1) cout << "   H=" << (*i).H;
+    cout << endl;
+  }
+}
+
+///////////////////////////////////////////////////////////
+// --------------------------------------------------------
+//   Les objets delegues pour la gestion de persistance 
+// --------------------------------------------------------
+///////////////////////////////////////////////////////////
+
+
+void  ObjFileIO<Histo2D>::ReadSelf(PInPersist& is)
+{
+char strg[256];
+
+if(dobj==NULL) dobj=new Histo2D;
+  else         dobj->Delete();
+
+r_8 min,max;
+int_4 errok, projx, projy, nslix, nsliy, nbanx, nbany;
+
+// Lecture entete
+is.GetLine(strg, 255);
+is.GetLine(strg, 255);
+is.GetLine(strg, 255);
+is.GetLine(strg, 255);
+is.GetLine(strg, 255);
+is.GetLine(strg, 255);
+
+// Lecture variables de definitions
+is.Get(dobj->mNx);
+is.Get(dobj->mNy);
+is.Get(dobj->mNxy);
+is.Get(errok);
+is.Get(dobj->nEntries);
+is.Get(dobj->nHist);
+
+is.Get(dobj->mXmin);
+is.Get(dobj->mXmax);
+is.Get(dobj->mYmin);
+is.Get(dobj->mYmax);
+is.Get(dobj->mWBinx);
+is.Get(dobj->mWBiny);
+
+is.Get(&(dobj->mOver[0][0]),9);
+
+is.Get(projx);
+is.Get(projy);
+is.Get(nslix);
+is.Get(nsliy);
+is.Get(nbanx);
+is.Get(nbany);
+
+// Lecture histo2D
+dobj->mData = new r_8[dobj->mNxy];
+is.GetLine(strg, 255);
+{for(int_4 j=0;j<dobj->mNy;j++) is.Get(dobj->mData+j*dobj->mNx,dobj->mNx);}
+
+// Lecture erreurs
+if(errok) {
+  is.GetLine(strg, 255);
+  dobj->mErr2 = new r_8[dobj->mNxy];
+  for(int_4 j=0;j<dobj->mNy;j++) is.Get(dobj->mErr2+j*dobj->mNx,dobj->mNx);
+}
+
+// Lecture des projections
+if(projx) {
+  is.GetLine(strg, 255);
+  dobj->SetProjX();
+  ObjFileIO<Histo> fio_h(dobj->mHprojx);
+  fio_h.Read(is);
+}
+if(projy) {
+  is.GetLine(strg, 255);
+  dobj->SetProjY();
+  ObjFileIO<Histo> fio_h(dobj->mHprojy);
+  fio_h.Read(is);
+}
+
+// Lecture des slices
+if(nslix>0) {
+  is.GetLine(strg, 255);
+  dobj->SetSliX(nslix);
+  ASSERT (nslix==dobj->NSliX());
+  for(int_4 j=0;j<dobj->NSliX();j++)
+    {ObjFileIO<Histo> fio_h(dobj->HSliX(j)); fio_h.Read(is);}
+}
+if(nsliy>0) {
+  is.GetLine(strg, 255);
+  dobj->SetSliY(nsliy);
+  ASSERT (nsliy==dobj->NSliY());
+  for(int_4 j=0;j<dobj->NSliY();j++)
+    {ObjFileIO<Histo> fio_h(dobj->HSliY(j)); fio_h.Read(is);}
+}
+
+// Lecture des bandes
+if( nbanx>0 ) {
+  is.GetLine(strg, 255);
+  {for(int_4 j=0; j<nbanx; j++) {
+    is.Get(min); is.Get(max);
+    dobj->SetBandX(min,max);
+  }}
+  ASSERT (nbanx==dobj->NBandX());
+  {for(int_4 j=0; j<dobj->NBandX(); j++) {
+    ObjFileIO<Histo> fio_h(dobj->HBandX(j));
+    fio_h.Read(is);
+  }}
+}
+if( nbany>0 ) {
+  is.GetLine(strg, 255);
+  {for(int_4 j=0; j<nbany; j++) {
+    is.Get(min); is.Get(max);
+    dobj->SetBandY(min,max);
+  }}
+  ASSERT (nbany==dobj->NBandY());
+  {for(int_4 j=0; j<dobj->NBandY(); j++) {
+    ObjFileIO<Histo> fio_h(dobj->HBandY(j));
+    fio_h.Read(is);
+  }}
+}
+
+return;
+}
+
+void ObjFileIO<Histo2D>::WriteSelf(POutPersist& os) const
+{
+if (dobj == NULL)   return;
+char strg[256];
+
+// Que faut-il ecrire?
+int_4 errok = (dobj->mErr2) ? 1 : 0;
+int_4 projx = (dobj->mHprojx) ? 1 : 0;
+int_4 projy = (dobj->mHprojy) ? 1 : 0;
+int_4 nslix = dobj->NSliX();
+int_4 nsliy = dobj->NSliY();
+int_4 nbanx = dobj->NBandX();
+int_4 nbany = dobj->NBandY();
+
+// Ecriture entete pour identifier facilement
+sprintf(strg,"nx=%d  ny=%d  nxy=%d errok=%1d"
+       ,dobj->mNx,dobj->mNy,dobj->mNxy,errok);
+os.PutLine(strg);
+sprintf(strg,"nHist=%g nEntries=%d",dobj->nHist,dobj->nEntries);
+os.PutLine(strg);
+sprintf(strg,"wbinx=%g wbiny=%g",dobj->mWBinx,dobj->mWBiny);
+os.PutLine(strg);
+sprintf(strg,"xmin=%g xmax=%g ymin=%g ymax=%g"
+       ,dobj->mXmin,dobj->mXmax,dobj->mYmin,dobj->mYmax);
+os.PutLine(strg);
+sprintf(strg,"projx/y=%d %d nbandx/y=%d %d nbslix/y=%d %d"
+       ,projx,projy,nbanx,nbany,nslix,nsliy);
+os.PutLine(strg);
+sprintf(strg,"mOver %g %g %g %g %g %g %g %g %g"
+       ,dobj->mOver[0][0],dobj->mOver[0][1],dobj->mOver[0][2]
+       ,dobj->mOver[1][0],dobj->mOver[1][1],dobj->mOver[1][2]
+       ,dobj->mOver[2][0],dobj->mOver[2][1],dobj->mOver[2][2]);
+os.PutLine(strg);
+
+// Ecriture variables de definitions
+os.Put(dobj->mNx);
+os.Put(dobj->mNy);
+os.Put(dobj->mNxy);
+os.Put(errok);
+os.Put(dobj->nEntries);
+os.Put(dobj->nHist);
+
+os.Put(dobj->mXmin);
+os.Put(dobj->mXmax);
+os.Put(dobj->mYmin);
+os.Put(dobj->mYmax);
+os.Put(dobj->mWBinx);
+os.Put(dobj->mWBiny);
+
+os.Put(&(dobj->mOver[0][0]),9);
+
+os.Put(projx);
+os.Put(projy);
+os.Put(nslix);
+os.Put(nsliy);
+os.Put(nbanx);
+os.Put(nbany);
+
+// Ecriture histo2D
+sprintf(strg,"Histo2D: Tableau des donnees %d = %d * %d"
+       ,dobj->mNxy,dobj->mNx,dobj->mNy);
+os.PutLine(strg);
+{for(int_4 j=0;j<dobj->mNy;j++) os.Put(dobj->mData+j*dobj->mNx,dobj->mNx);}
+
+// Ecriture erreurs
+if(errok) {
+  sprintf(strg,"Histo2D: Tableau des erreurs %d = %d * %d"
+         ,dobj->mNxy,dobj->mNx,dobj->mNy);
+  os.PutLine(strg);
+  for(int_4 j=0;j<dobj->mNy;j++) os.Put(dobj->mErr2+j*dobj->mNx,dobj->mNx);
+}
+
+// Ecriture des projections
+if(projx) {
+  sprintf(strg,"Histo2D: Projection X");
+  os.PutLine(strg);
+  ObjFileIO<Histo> fio_h(dobj->mHprojx); fio_h.Write(os);
+}
+if(projy) {
+  sprintf(strg,"Histo2D: Projection Y");
+  os.PutLine(strg);
+  ObjFileIO<Histo> fio_h(dobj->mHprojy); fio_h.Write(os);
+}
+
+// Ecriture des slices
+if(nslix>0) {
+  sprintf(strg,"Histo2D: Slices X %d",nslix);
+  os.PutLine(strg);
+  for(int_4 j=0;j<nslix;j++) {
+    Histo* h = dobj->HSliX(j);
+    ObjFileIO<Histo> fio_h(h); fio_h.Write(os);
+  }
+}
+if(nsliy>0) {
+  sprintf(strg,"Histo2D: Slices Y %d",nsliy);
+  os.PutLine(strg);
+  for(int_4 j=0;j<nsliy;j++) {
+    Histo* h = dobj->HSliY(j);
+    ObjFileIO<Histo> fio_h(h); fio_h.Write(os);
+  }
+}
+
+// Ecriture des bandes
+if( nbanx>0 ) {
+  sprintf(strg,"Histo2D: Bandes X %d",nbanx);
+  os.PutLine(strg);
+  list<Histo2D::bande_slice>::const_iterator it;
+  for(it = dobj->mLBandx.begin(); it != dobj->mLBandx.end(); it++) {
+    r_8 min = (*it).min; r_8 max = (*it).max;
+    os.Put(min); os.Put(max);
+  }
+  for(it = dobj->mLBandx.begin(); it != dobj->mLBandx.end(); it++) {
+    Histo* h = (*it).H;
+    ObjFileIO<Histo> fio_h(h); fio_h.Write(os);
+  }
+}
+if( nbany>0 ) {
+  sprintf(strg,"Histo2D: Bandes Y %d",nbany);
+  os.PutLine(strg);
+  list<Histo2D::bande_slice>::const_iterator it;
+  for(it = dobj->mLBandy.begin(); it != dobj->mLBandy.end(); it++) {
+    r_8 min = (*it).min; r_8 max = (*it).max;
+    os.Put(min); os.Put(max);
+  }
+  for(it = dobj->mLBandy.begin(); it != dobj->mLBandy.end(); it++) {
+    Histo* h = (*it).H;
+    ObjFileIO<Histo> fio_h(h); fio_h.Write(os);
+  }
+}
+
+return;
+}
+
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template ObjFileIO<Histo2D>
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class ObjFileIO<Histo2D>;
+#endif
Index: /tags/V_Dec2002/SophyaLib/HiStats/histos2.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/HiStats/histos2.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/HiStats/histos2.h	(revision 2309)
@@ -0,0 +1,356 @@
+//
+// histogrammes 2D     cmv 2/8/96
+//
+
+#ifndef HISTOS2_SEEN
+#define HISTOS2_SEEN
+
+#include "machdefs.h"
+#include <string>
+
+#include <list>
+#if defined(__KCC__)
+#include <list.h>
+#endif
+
+#include "peida.h"
+#include "utils.h"
+#include "histos.h"
+
+namespace SOPHYA {
+
+//! 2 dimensions histograms
+class Histo2D : public AnyDataObj {
+  friend class ObjFileIO<Histo2D>;
+public:
+
+  // CREATOR / DESTRUCTOR
+  Histo2D(r_8 xMin,r_8 xMax,int_4 nxBin,r_8 yMin,r_8 yMax,int_4 nyBin);
+  Histo2D(r_4 xMin,r_4 xMax,int_4 nxBin,r_4 yMin,r_4 yMax,int_4 nyBin);
+  Histo2D(const Histo2D& h);
+  Histo2D();
+  virtual ~Histo2D();
+
+  // OPTIONS
+  void Errors();  
+  
+  // UPDATING
+  void Zero();
+  void Add(r_8 x, r_8 y, r_8 w = 1.);
+
+  // Operators
+  Histo2D& operator = (const Histo2D& h);
+  Histo2D& operator *= (r_8 b);
+  Histo2D& operator /= (r_8 b);
+  Histo2D& operator += (r_8 b);
+  Histo2D& operator -= (r_8 b);
+  Histo2D& operator += (const Histo2D& a);
+  Histo2D& operator -= (const Histo2D& a);
+  Histo2D& operator *= (const Histo2D& a);
+  Histo2D& operator /= (const Histo2D& a);
+
+  // get/put dans/depuis une matrice / vector
+  void GetXCoor(TVector<r_8>& v) const;
+  void GetValue(TMatrix<r_8> &v) const;
+  void GetYCoor(TVector<r_8>& v) const;
+  void GetError2(TMatrix<r_8>& v) const;
+  void GetError(TMatrix<r_8>& v) const;
+  void PutValue(TMatrix<r_8>& v, int_4 ierr=0);
+  void PutValueAdd(TMatrix<r_8>& v, int_4 ierr=0);
+  void PutError2(TMatrix<r_8>& v);
+  void PutError2Add(TMatrix<r_8>& v);
+  void PutError(TMatrix<r_8>& v);
+
+  // INLINES
+  //! Retourne l'abscisse minimum.
+  inline r_8 XMin() const {return mXmin;}
+  //! Retourne l'abscisse maximum.
+  inline r_8 XMax() const {return mXmax;}
+  //! Retourne l'ordonnee minimum.
+  inline r_8 YMin() const {return mYmin;}
+  //! Retourne l'ordonnee maximum.
+  inline r_8 YMax() const {return mYmax;}
+  //! Retourne le nombre de bins selon X.
+  inline int_4 NBinX() const {return mNx;}
+  //! Retourne le nombre de bins selon Y.
+  inline int_4 NBinY() const {return mNy;}
+  //! Retourne la largeur du bin selon X.
+  inline r_8 WBinX() const {return mWBinx;}
+  //! Retourne la largeur du bin selon Y.
+  inline r_8 WBinY() const {return mWBiny;}
+  //! Retourne le pointeur sur le tableaux des contenus.
+  inline r_8* Bins() const  {return mData;}
+  //! Retourne le contenu du bin i,j.
+  inline r_8 operator()(int_4 i,int_4 j) const {return mData[j*mNx+i];}
+  //! Remplit le contenu du bin i,j.
+  inline r_8& operator()(int_4 i,int_4 j)      {return mData[j*mNx+i];}
+  //! retourne "true" si il y a des erreurs stoquees
+  inline bool HasErrors() const { if(mErr2) return true; else return false;}
+  //! Retourne l'erreur du bin i,j.
+  inline r_8 Error(int_4 i,int_4 j)  const
+    {if(mErr2)
+       {if(mErr2[j*mNx+i]>0.) return sqrt(mErr2[j*mNx+i]); else return 0.;}
+     else return 0.;}
+  //! Remplit l'erreur au carre du bin i,j.
+  inline r_8 Error2(int_4 i,int_4 j) const
+             {if(mErr2) return mErr2[j*mNx+i]; else return 0.;}
+  //! Remplit l'erreur au carre du bin i,j.
+  inline r_8& Error2(int_4 i,int_4 j) {return mErr2[j*mNx+i];}
+  //! Retourne la somme ponderee.
+  inline r_8 NData() const    {return nHist;}
+  //! Retourne le nombre d'entrees.
+  inline int_4 NEntries() const {return nEntries;}
+  //! Retourne l'abscisse et l'ordonnee du coin inferieur du bin i,j.
+  inline void BinLowEdge(int_4 i,int_4 j,r_8& x,r_8& y) const
+              {x = mXmin + i*mWBinx; y = mYmin + j*mWBiny;}
+  //! Retourne l'abscisse et l'ordonnee du coin inferieur du bin i,j.
+  inline void BinLowEdge(int_4 i,int_4 j,r_4& xf,r_4& yf) const
+              {r_8 x,y; BinLowEdge(i,j,x,y); xf=x; yf=y;}
+  //! Retourne l'abscisse et l'ordonnee du centre du bin i,j.
+  inline void BinCenter(int_4 i,int_4 j,r_8& x,r_8& y) const
+              {x = mXmin + (i+0.5)*mWBinx; y = mYmin + (j+0.5)*mWBiny;}
+  //! Retourne l'abscisse et l'ordonnee du centre du bin i,j.
+  inline void BinCenter(int_4 i,int_4 j,r_4& xf,r_4& yf) const
+              {r_8 x,y; BinCenter(i,j,x,y); xf=x; yf=y;}
+  //! Retourne l'abscisse et l'ordonnee du coin superieur du bin i,j.
+  inline void BinHighEdge(int_4 i,int_4 j,r_8& x,r_8& y) const
+              {x = mXmin + (i+1)*mWBinx; y = mYmin + (j+1)*mWBiny;}
+  //! Retourne l'abscisse et l'ordonnee du coin superieur du bin i,j.
+  inline void BinHighEdge(int_4 i,int_4 j,r_4& xf,r_4& yf) const
+              {r_8 x,y; BinHighEdge(i,j,x,y); xf=x; yf=y;}
+  //! Retourne les numeros du bin contenant l'abscisse et l'ordonnee x,y.
+  inline void FindBin(r_8 x,r_8 y,int_4& i,int_4& j) const
+    {i=(int_4) floor((x-mXmin)/mWBinx); j=(int_4) floor((y-mYmin)/mWBiny);}
+
+  // Info, statistique et calculs sur les histogrammes
+  r_8   NOver(int_4 i=-1,int_4 j=-1) const;
+  int_4 BinNonNul() const;
+  int_4 ErrNonNul() const;
+  void IJMax(int_4& imax,int_4& jmax,int_4 il=1,int_4 ih= -1,int_4 jl=1,int_4 jh= -1) const;
+  void IJMin(int_4& imax,int_4& jmax,int_4 il=1,int_4 ih= -1,int_4 jl=1,int_4 jh= -1) const;
+  r_8 VMax(int_4 il=1,int_4 ih= -1,int_4 jl=1,int_4 jh= -1) const;
+  r_8 VMin(int_4 il=1,int_4 ih= -1,int_4 jl=1,int_4 jh= -1) const;
+  int_4 EstimeMax(r_8& xm,r_8& ym,int_4 SzPav = 3
+                 ,int_4 il=1,int_4 ih= -1,int_4 jl=1,int_4 jh= -1) const;
+  int_4 EstimeMax(int_4 im,int_4 jm,r_8& xm,r_8& ym,int_4 SzPav = 3) const;
+  int_4 FindMax(int_4& im,int_4& jm,int_4 SzPav = 3,r_8 Dz = 0.
+               ,int_4 il=1,int_4 ih= -1,int_4 jl=1,int_4 jh= -1) const;
+
+  // Print et Display ASCII
+  virtual void Show(ostream& os) const;
+  inline void  PrintStatus() const { Show(cout); }
+  
+  void Print(r_8 min=1.,r_8 max=-1.
+            ,int_4 il=1,int_4 ih= -1,int_4 jl=1,int_4 jh= -1) const;
+
+  // PROJECTIONS
+  void SetProjX();
+  void SetProjY();
+  void SetProj();
+  void DelProjX();
+  void DelProjY();
+  void DelProj();
+  void ZeroProjX();
+  void ZeroProjY();
+  void ZeroProj();
+  //! Retourne le pointeur sur l'histo 1D de la projection selon X.
+  inline Histo* HProjX() const {return mHprojx;}
+  //! Retourne le pointeur sur l'histo 1D de la projection selon Y.
+  inline Histo* HProjY() const {return mHprojy;}
+  void ShowProj() const;
+
+  // BANDES
+  //! Retourne le nombre de bandes selon X
+  inline int_4 NBandX() const {return mLBandx.size();}
+  //! Retourne le nombre de bandes selon Y
+  inline int_4 NBandY() const {return mLBandy.size();}
+  int_4 SetBandX(r_8 ybmin,r_8 ybmax);
+  int_4 SetBandY(r_8 xbmin,r_8 xbmax);
+  void DelBandX();
+  void DelBandY();
+  void ZeroBandX();
+  void ZeroBandY();
+  Histo* HBandX(int_4 n) const;
+  Histo* HBandY(int_4 n) const;
+  void GetBandX(int_4 n,r_8& ybmin,r_8& ybmax) const;
+  void GetBandY(int_4 n,r_8& xbmin,r_8& xbmax) const;
+  void ShowBand(int_4 lp = 0) const;
+
+  // SLICES
+  //! Retourne le nombre de slices selon X
+  inline int_4 NSliX() const {return mLSlix.size();}
+  //! Retourne le nombre de slices selon Y
+  inline int_4 NSliY() const {return mLSliy.size();}
+  int_4 SetSliX(int_4 nsli);
+  int_4 SetSliY(int_4 nsli);
+  void DelSliX();
+  void DelSliY();
+  void ZeroSliX();
+  void ZeroSliY();
+  Histo* HSliX(int_4 n) const;
+  Histo* HSliY(int_4 n) const;
+  void ShowSli(int_4 lp = 0) const;
+
+#ifndef __DECCXX
+protected:
+#endif
+  //! structure de definition des bandes
+  struct bande_slice {
+    int_4 num;   //!< nombre de bandes
+    r_8 min;     //!< limite minimum pour remplir la bande
+    r_8 max;     //!< limite maximum pour remplir la bande
+    Histo* H;    //!< pointer sur l Histo 1D de la bande
+    STRUCTCOMP(bande_slice)
+  };
+#ifdef __DECCXX
+protected:
+#endif
+
+  void Delete();
+
+  r_8*        mData; //!< donnees
+  r_8*        mErr2; //!< erreurs carrees
+
+  r_8         mOver[3][3]; //!< overflow table
+  r_8         nHist;       //!< somme ponderee des entrees
+  int_4       nEntries;    //!< nombre d'entrees
+
+  int_4       mNx;    //!< nombre de bins en X
+  int_4       mNy;    //!< nombre de bins en Y
+  int_4       mNxy;   //!< nombre de bins total
+  r_8         mXmin;  //!< abscisse minimum
+  r_8         mXmax;  //!< abscisse maximum
+  r_8         mYmin;  //!< ordonnee minimum
+  r_8         mYmax;  //!< ordonnee maximum
+  r_8         mWBinx; //!< largeur du bin en X
+  r_8         mWBiny; //!< largeur du bin en Y
+
+  bande_slice mB_s;
+
+  Histo*      mHprojx; //!< pointer sur Histo des proj X
+  Histo*      mHprojy; //!< pointer sur Histo des proj Y
+
+  list<bande_slice>  mLBandx; //!< liste des bandes selon X
+  list<bande_slice>  mLBandy; //!< liste des bandes selon Y
+  
+  list<bande_slice>  mLSlix; //!< liste des slices selon X
+  list<bande_slice>  mLSliy; //!< liste des slices selon Y
+
+};
+
+/*! Prints histogram information on stream \b s (h.Show(s)) */
+inline ostream& operator << (ostream& s, Histo2D const & h)
+  {  h.Show(s);  return(s);  }
+
+/////////////////////////////////////////////////////////////////////////
+// Classe pour la gestion de persistance
+
+/*! \ingroup HiStats \fn operator<<(POuttPersist&,Histo2D)
+  \brief Persistance management */
+inline POutPersist& operator << (POutPersist& os, Histo2D & obj)
+{ ObjFileIO<Histo2D> fio(&obj);  fio.Write(os);  return(os); }
+/*! \ingroup HiStats \fn operator<<(POuttPersist&,Histo2D)
+  \brief Persistance management */
+inline PInPersist& operator >> (PInPersist& is, Histo2D & obj)
+{ ObjFileIO<Histo2D> fio(&obj);  fio.Read(is);  return(is); }
+
+// Classe pour la gestion de persistance
+// ObjFileIO<Histo2D>
+
+/*! \ingroup HiStats \fn operator*(const Histo2D&,r_8)
+  \brief Operateur H2 = H1 * b */
+inline Histo2D operator * (const Histo2D& a, r_8 b)
+{
+  Histo2D result(a);
+  return (result *= b);
+}
+
+/*! \ingroup HiStats \fn operator*(r_8,const Histo2D&)
+  \brief Operateur H2 = b * H1 */
+inline Histo2D operator * (r_8 b, const Histo2D& a)
+{
+  Histo2D result(a);
+  return (result *= b);
+}
+
+/*! \ingroup HiStats \fn operator/(const Histo2D&,r_8)
+  \brief Operateur H2 = H1 / b */
+inline Histo2D operator / (const Histo2D& a, r_8 b)
+{
+  Histo2D result(a);
+  return (result /= b);
+}
+
+/*! \ingroup HiStats \fn operator+(const Histo2D&,r_8)
+  \brief Operateur H2 = H1 + b */
+inline Histo2D operator + (const Histo2D& a, r_8 b)
+{
+  Histo2D result(a);
+  return (result += b);
+}
+
+/*! \ingroup HiStats \fn operator+(r_8,const Histo2D&)
+  \brief Operateur H2 = b + H1 */
+inline Histo2D operator + (r_8 b, const Histo2D& a)
+{
+  Histo2D result(a);
+  return (result += b);
+}
+
+/*! \ingroup HiStats \fn operator-(const Histo2D&,r_8)
+  \brief Operateur H2 = H1 - b */
+inline Histo2D operator - (const Histo2D& a, r_8 b)
+{
+  Histo2D result(a);
+  return (result -= b);
+}
+
+/*! \ingroup HiStats \fn operator-(r_8,const Histo2D&)
+  \brief Operateur H2 = b - H1 */
+inline Histo2D operator - (r_8 b, const Histo2D& a)
+{
+  Histo2D result(a);
+  result *= -1.;
+  return (result += b);
+}
+
+/*! \ingroup HiStats \fn operator+(const Histo2D&,const Histo2D&)
+  \brief Operateur H = H1 + H2 */
+
+inline Histo2D operator + (const Histo2D& a, const Histo2D& b)
+{
+if (b.NBinX()!=a.NBinX() || b.NBinY()!=a.NBinY()) THROW(sizeMismatchErr);
+Histo2D c(a);
+return (c += b);
+}
+
+/*! \ingroup HiStats \fn operator-(const Histo2D&,const Histo2D&)
+  \brief Operateur H = H1 - H2 */
+inline Histo2D operator - (const Histo2D& a, const Histo2D& b)
+{
+if (b.NBinX()!=a.NBinX() || b.NBinY()!=a.NBinY()) THROW(sizeMismatchErr);
+Histo2D c(a);
+return (c -= b);
+}
+
+/*! \ingroup HiStats \fn operator*(const Histo2D&,const Histo2D&)
+  \brief Operateur H = H1 * H2 */
+inline Histo2D operator * (const Histo2D& a, const Histo2D& b)
+{
+if (b.NBinX()!=a.NBinX() || b.NBinY()!=a.NBinY()) THROW(sizeMismatchErr);
+Histo2D c(a);
+return (c *= b);
+}
+
+/*! \ingroup HiStats \fn operator/(const Histo2D&,const Histo2D&)
+  \brief Operateur H = H1 / H2 */
+inline Histo2D operator / (const Histo2D& a, const Histo2D& b)
+{
+if (b.NBinX()!=a.NBinX() || b.NBinY()!=a.NBinY()) THROW(sizeMismatchErr);
+Histo2D c(a);
+return (c /= b);
+}
+
+} // Fin du namespace
+
+#endif // HISTOS2_SEEN
Index: /tags/V_Dec2002/SophyaLib/HiStats/ntupintf.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/HiStats/ntupintf.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/HiStats/ntupintf.cc	(revision 2309)
@@ -0,0 +1,189 @@
+
+#include "ntupintf.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+/*!
+   \class SOPHYA::NTupleInterface
+   \ingroup HiStats
+   Interface class (pure virtual) defining generic operations on NTuple,
+   a 2-dimensional data set with named columns
+*/
+
+//++
+// Class	NTupleInterface
+// Lib	        HiStats
+// include	ntupintf.h
+//
+//	Interface permettant de construire des vues NTuples (tableau lignes-colonnes) 
+//	pour differents objets. Toutes les methodes ont une implementation par defaut. 
+//--
+
+//++
+// NTupleInterface()
+//	Constructeur.
+// virtual ~NTupleInterface()
+//	Destructeur
+// uint_4  NbLines() const 
+//	Nombre de lignes du tableau
+// uint_4  NbColumns() const 
+//	Nombre de colonnes du tableau
+// r_8 *  GetLineD(int n) const
+//	Renvoie un tableau avec le contenu de la ligne "n"
+// r_8	GetCell(int n, int k) const
+//	Renvoie le contenu de la cellule correspondant a la ligne "n"
+//	et colonne "k"
+// r_8  GetCell(int n, string const & nom) const
+//	Renvoie le contenu de la cellule correspondant a la ligne "n"
+//	pour la colonne identifiee par "nom"
+// string  GetCelltoString(int n, int k) const
+//	Renvoie le contenu de la cellule correspondant a la ligne "n"
+//	et colonne "k", sous forme de chaine de caracteres.
+// string  GetCell(int n, string const & nom) const
+//	Renvoie le contenu de la cellule correspondant a la ligne "n"
+//	pour la colonne identifiee par "nom", sous forme de chaine de caracteres.
+// void GetMinMax(int k, double& min, double& max)  const
+//	Renvoie la valeur mini et maxi de la colonne numero "k"
+// void	GetMinMax(string const & nom, double& min, double& max)
+//	Renvoie la valeur mini et maxi de la colonne identifiee par "nom"
+// int  ColumnIndex(string const & nom)  const
+//	Renvoie le numero de colonne identifiee par "nom". Renvoie -1 (negatif)
+//	si colonne "nom" n'existe pas.
+// string ColumnName(int k) const
+//	Renvoie le nom de la colonne numero "k"
+// string VarList_C(const char* nomx=NULL) const
+//	Renvoie une chaine avec les declarations "C" pour les
+//	variables avec les noms de colonnes
+// string  LineHeaderToString()
+//	Renvoie une chaine avec les noms de colonnes, utilisables pour l'impression
+// string  LineToString(int n)
+//	Renvoie une chaine avec le contenu de la ligne "n", utilisable pour l'impression
+//--
+
+/* --Methode-- */
+NTupleInterface::NTupleInterface()
+{
+}
+/* --Methode-- */
+NTupleInterface::~NTupleInterface()
+{
+}
+
+//! Retuns the number of lines (rows) of the data set
+/* --Methode-- */
+uint_4 NTupleInterface::NbLines() const
+{
+return(0);
+}
+
+//! Retuns the number of columns of the data set 
+/* --Methode-- */
+uint_4 NTupleInterface::NbColumns() const
+{
+return(0);
+}
+
+//! Retuns the content of a given line 
+/*! 
+   An array (double *) containg all cells of a given line, converted to 
+   float values is returned
+*/
+/* --Methode-- */
+r_8 * NTupleInterface::GetLineD(int ) const
+{
+return(NULL);
+}
+
+//! Returns the content of a given cell
+/*!
+    The cell is identified by the line and column number. Its content is
+    converted to a floating value.
+*/
+/* --Methode-- */
+r_8 NTupleInterface::GetCell(int , int ) const
+{
+return(0.);
+}
+
+//! Returns the content of a given cell
+/*!
+    The cell is identified by the line number and column name. Its content is
+    converted to a floating value.
+*/
+/* --Methode-- */
+r_8 NTupleInterface::GetCell(int n, string const & nom) const
+{
+return(GetCell(n, ColumnIndex(nom)));
+}
+
+//! Returns the string representation of a given cell
+/*!
+    The cell is identified by the line and column number. Its content is
+    converted to a string.
+*/
+string NTupleInterface::GetCelltoString(int n, int k) const
+{
+char strg[64];
+//sprintf(strg,"C%d= %g\n", k, GetCell(n, k));
+sprintf(strg,"%g\n", GetCell(n, k));
+return(strg);
+}
+
+//! Returns the string representation of a given cell
+/*!
+    The cell is identified by the line number and column name. Its content is
+    converted to a string.
+*/
+string NTupleInterface::GetCelltoString(int n, string const & nom) const
+{
+return(GetCelltoString(n, ColumnIndex(nom)));
+}
+
+//! Returns the minimum and maximum values for a given column
+/* --Methode-- */
+void NTupleInterface::GetMinMax(int , double& min, double& max)   const
+{
+min = max = 0.;
+}
+
+/* --Methode-- */
+//! Returns the minimum and maximum values for a given named column
+void NTupleInterface::GetMinMax(string const & , double& min, double& max)   const
+{
+min = max = 0.;
+}
+
+/* --Methode-- */
+//! Returns the column index given the column name
+int NTupleInterface::ColumnIndex(string const & nom)  const
+{
+return(-1);
+}
+
+/* --Methode-- */
+//! Returns the column name corresponding to a column index.
+string NTupleInterface::ColumnName(int k) const
+{
+return("");
+}
+
+/* --Methode-- */
+string NTupleInterface::VarList_C(const char*) const
+{
+return("");
+}
+
+/* --Methode-- */
+string NTupleInterface::LineHeaderToString() const
+{
+return("");
+}
+
+/* --Methode-- */
+string NTupleInterface::LineToString(int ) const
+{
+return("");
+}
+
+
+
Index: /tags/V_Dec2002/SophyaLib/HiStats/ntupintf.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/HiStats/ntupintf.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/HiStats/ntupintf.h	(revision 2309)
@@ -0,0 +1,51 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Interface de type NTuple           Reza 05/99
+// LAL-IN2P3/CNRS               CEA-DAPNIA      
+
+#ifndef NTUPLEINTERFACE_H_SEEN
+#define NTUPLEINTERFACE_H_SEEN
+
+#include "machdefs.h"
+#include <string>
+
+namespace SOPHYA {  
+
+class NTupleInterface {
+public:
+  			NTupleInterface(); 
+  virtual		~NTupleInterface();
+// Nombre de lignes du NTuple  (Nb d'entrees)  
+  virtual uint_4        NbLines() const ;
+// Nombre de colonnes (nb de variables)
+  virtual uint_4        NbColumns() const ;
+// La ligne numero n, sous forme d'un tableau de double
+  virtual r_8 *         GetLineD(int n) const ;
+// Cellule de la ligne n, colonne k
+  virtual r_8		GetCell(int n, int k) const ;
+// Cellule de la ligne n, colonne nom
+  virtual r_8		GetCell(int n, string const & nom) const ;
+// Cellule de la ligne n, colonne k, converti en chaine de caracteres
+  virtual string	GetCelltoString(int n, int k) const ;
+// Cellule de la ligne n, colonne nom, converti en chaine de caracteres
+  virtual string	GetCelltoString(int n, string const & nom) const ;
+// Min et Max pour la colonne k
+  virtual void		GetMinMax(int k, double& min, double& max)   const ; 
+// Min et Max pour la colonne nom
+  virtual void		GetMinMax(string const & nom, double& min, double& max)   const ;
+// Numero de colonne pour nom 
+  virtual int           ColumnIndex(string const & nom)  const ;
+// Nom de colonne numero k
+  virtual string        ColumnName(int k) const;
+// Declaration des variables style C
+  virtual string	VarList_C(const char* nomx=NULL) const ;
+// Entete et liste de variable, pouvant servir a l'impression
+  virtual string        LineHeaderToString() const;
+// Contenu de la ligne n, pouvant servir a l'impression
+  virtual string        LineToString(int n) const;  
+};
+
+} // namespace SOPHYA
+
+#endif   /*  NTUPLEINTERFACE_H_SEEN  */
+
+
Index: /tags/V_Dec2002/SophyaLib/HiStats/ntuple.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/HiStats/ntuple.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/HiStats/ntuple.cc	(revision 2309)
@@ -0,0 +1,682 @@
+#include <stdio.h>
+#include <string.h>
+
+#include "strutil.h"
+#include "perrors.h"
+#include "ntuple.h"
+
+
+#define BADVAL -1.e19
+#define LENNAME 8
+#define LENNAME1  (LENNAME+1)
+
+/*!
+   \class SOPHYA::NTuple
+   \ingroup HiStats
+   Simple NTuple class (a Table or 2-D data set) with floating value
+   columns. 
+   \sa SOPHYA::ObjFileIO<NTuple>
+
+   \code
+   #include "ntuple.h"
+   // ...
+   char * names[3] = {"XPos", "YPos", "Val"};
+   // NTuple (Table) creation with 3 columns
+   NTuple  nt(3, names);
+   // Filling the NTuple
+   r_4 x[3];
+   for(int i=0; i<63; i++) {
+     x[0] = (i%9)-4.;  x[1] = (i/9)-3.;  x[2] = x[0]*x[0]+x[1]*x[1];
+     nt.Fill(x);
+   }
+   // Printing table info
+   cout << nt ;
+   // Saving object into a PPF file
+   POutPersist po("nt.ppf");
+   po << nt ;
+   \endcode
+*/
+
+//++
+// Class	NTuple
+// Lib	Outils++ 
+// include	ntuple.h
+//
+//	Classe de ntuples
+//--
+//++
+// Links        Parents
+// PPersist
+// NTupleInterface
+//--
+
+/* --Methode-- */
+//! Default constructor
+//++
+NTuple::NTuple()
+//
+//	Createur par defaut
+//--
+{
+mNVar = mNEnt = mBlk = mNBlk = 0;
+mVar = NULL;
+mVarD = NULL;
+mNames = NULL;
+mInfo = NULL;
+}
+
+
+//! Constructor with specification of number of columns and column name
+/*!
+  \param nvar : Number of columns in the table 
+  \param noms : Array of column names (length(name) < 8 characters) 
+  \param blk : Optional argument specifying number of table lines
+  in a given data block
+ */
+//++
+NTuple::NTuple(int nvar, char** noms, int blk)
+//
+//	Createur d'un ntuple de `nvar' variables dont les
+//	noms sont dans le tableau de cahines de caracteres `noms'
+//	avec `blk' d'evenements par blocks.
+//--
+{
+mNVar = mNEnt = mBlk = mNBlk = 0;
+mVar = NULL;
+mVarD = NULL;
+mNames = NULL;
+mInfo = NULL;
+if (nvar <= 0)  THROW(sizeMismatchErr); 
+mNVar = nvar;
+mVar = new r_4[nvar];
+mVarD = new r_8[nvar];
+if (blk < 10) blk = 10;
+mBlk = blk;
+// On prend des noms de LENNAME char pour le moment
+mNames = new char[nvar*LENNAME1];
+r_4* pt = new r_4[nvar*blk];
+mNBlk = 1;
+mPtr.push_back(pt);
+int i;
+for(i=0; i<nvar; i++)
+  { strncpy(mNames+i*LENNAME1, noms[i], LENNAME);  
+  mNames[i*LENNAME1+LENNAME] = '\0'; }
+return;
+}
+
+//! Copy constructor - Copies the table definition and associated data 
+//                                       cmv 8/10/99
+//++
+NTuple::NTuple(const NTuple& NT)
+//
+//	Createur par copie (clone).
+//--
+: mNVar(0), mNEnt(0), mBlk(0), mNBlk(0)
+, mVar(NULL), mVarD(NULL), mNames(NULL), mInfo(NULL)
+{
+if(NT.mNVar<=0) return; // cas ou NT est cree par defaut
+mNVar = NT.mNVar;
+mBlk = NT.mBlk;
+mVar = new r_4[NT.mNVar];
+mVarD = new r_8[NT.mNVar];
+mNames = new char[NT.mNVar*LENNAME1];
+
+int i;
+r_4* pt = new r_4[mNVar*mBlk];
+mNBlk = 1; mPtr.push_back(pt);
+
+for(i=0;i<mNVar;i++) strcpy(mNames+i*LENNAME1,NT.NomIndex(i)); 
+
+if(NT.mInfo!=NULL) {mInfo = new DVList; *mInfo = *(NT.mInfo);}
+
+if(NT.mNEnt<=0) return;
+for(i=0;i<NT.mNEnt;i++) {r_4* x=NT.GetVec(i,NULL); Fill(x);}
+
+return;
+}
+
+/* --Methode-- */
+//! Constructor with table initialized from a PPF file
+//++
+NTuple::NTuple(char *flnm)
+//
+//	Createur lecture fichier ppersist.
+//--
+{
+mNVar = mNEnt = mBlk = mNBlk = 0;
+mVar = NULL;
+mVarD = NULL;
+mNames = NULL;
+mInfo = NULL;
+PInPersist s(flnm);
+ObjFileIO<NTuple> fiont(this);
+fiont.Read(s);
+}
+
+/* --Methode-- */
+NTuple::~NTuple()
+{
+Clean();
+}
+
+/* --Methode-- */
+//! Clear the data table definition and deletes the associated data
+void NTuple::Clean()
+{
+if (mVar) delete[] mVar;
+if (mVarD) delete[] mVarD;
+if (mNames)  delete[] mNames;
+if (mInfo) delete mInfo;
+int i;
+if(mNBlk>0) for(i=0; i<mNBlk; i++)  delete[] mPtr[i];
+mPtr.erase(mPtr.begin(), mPtr.end());
+mNVar = mNEnt = mBlk = mNBlk = 0;
+mVar = NULL;
+mVarD = NULL;
+mNames = NULL;
+mInfo = NULL;
+return;
+}
+
+/* --Methode--        cmv 08/10/99 */
+//! = operator, copies the data table definition and its contents
+//++
+NTuple& NTuple::operator = (const NTuple& NT)
+//
+//	Operateur egal (clone).
+//--
+{
+if(this == &NT) return *this;
+Clean();
+if(NT.mNVar<=0) return *this; // cas ou NT est cree par defaut
+mNVar = NT.mNVar;
+mBlk = NT.mBlk;
+mVar = new r_4[NT.mNVar];
+mVarD = new r_8[NT.mNVar];
+mNames = new char[NT.mNVar*LENNAME1];
+
+int i;
+r_4* pt = new r_4[mNVar*mBlk];
+mNBlk = 1; mPtr.push_back(pt);
+
+for(i=0;i<mNVar;i++) strcpy(mNames+i*LENNAME1,NT.NomIndex(i)); 
+
+if(NT.mInfo!=NULL) {mInfo = new DVList; *mInfo = *(NT.mInfo);}
+
+if(NT.mNEnt<=0) return *this;
+for(i=0;i<NT.mNEnt;i++) {r_4* x=NT.GetVec(i,NULL); Fill(x);}
+
+// En fait il faudrait un createur par copie qui partage les donnees
+// quand l'objet est temporaire... trop complique A FAIRE !  cmv.
+return *this;
+}
+
+/* --Methode-- */
+//! Adds an entry (a line) to the table
+/*!
+  \param x : content of the line to be appended to the table
+ */
+//++
+void  NTuple::Fill(r_4* x)
+//
+//	Remplit le ntuple avec le tableau cd reels `x'.
+//--
+{
+int numb = mNEnt/mBlk;
+if (numb >= mNBlk) {
+  r_4* pt = new r_4[mNVar*mBlk];
+  mNBlk++;
+  mPtr.push_back(pt);
+}
+int offb = mNEnt-numb*mBlk;
+memcpy((mPtr[numb]+offb*mNVar), x, mNVar*sizeof(r_4));
+mNEnt++;
+return;
+}
+
+
+/* --Methode-- */
+//++
+float NTuple::GetVal(int n, int k)  const
+//
+//	Retourne la valeur de la variable `k' de l'evenement `n'.
+//--
+{
+if (n >= mNEnt)   return(BADVAL);
+if ( (k < 0) || (k >= mNVar) )    return(BADVAL);
+int numb = n/mBlk;
+int offb = n-numb*mBlk;
+return(*(mPtr[numb]+offb*mNVar+k));
+}
+
+
+/* --Methode-- */
+//++
+int NTuple::IndexNom(const char* nom)  const
+//
+//	Retourne le numero de la variable de nom `nom'.
+//--
+{
+int i;
+for(i=0; i<mNVar; i++)  
+  if ( strcmp(nom, mNames+i*LENNAME1) == 0)  return(i);
+return(-1);
+}
+
+
+static char nomretour[2*LENNAME1];
+/* --Methode-- */
+//++
+char* NTuple::NomIndex(int k)  const
+//
+//	Retourne le nom de la variable numero 'k'
+//--
+{
+nomretour[0] = '\0';
+if ((k >= 0) && (k < mNVar))  strcpy(nomretour, mNames+k*LENNAME1);
+return(nomretour);
+}
+
+  
+/* --Methode-- */
+//++
+r_4* NTuple::GetVec(int n, r_4* ret)   const
+//
+//	Retourne l'evenement `n' dans le vecteur `ret'.
+//--
+{
+int i;
+if (ret == NULL)   ret = mVar;
+if (n >= mNEnt) {
+  for(i=0; i<mNVar; i++)   ret[i] = BADVAL;
+  return(ret);
+}
+  
+int numb = n/mBlk;
+int offb = n-numb*mBlk;
+memcpy(ret, (mPtr[numb]+offb*mNVar), mNVar*sizeof(r_4));
+return(ret);
+}
+
+/* --Methode-- */
+//++
+r_8* NTuple::GetVecD(int n, r_8* ret)   const
+//
+//	Retourne l'evenement `n' dans le vecteur `ret'.
+//--
+{
+int i;
+if (ret == NULL)   ret = mVarD;
+float *  fr = GetVec(n);
+for(i=0; i<mNVar; i++)   ret[i] = fr[i];
+return(ret);
+}
+
+
+
+/* --Methode-- */
+//++
+DVList&  NTuple::Info()
+//
+//	Renvoie une référence sur l'objet DVList Associé
+//--
+{
+if (mInfo == NULL)  mInfo = new DVList;
+return(*mInfo);
+}
+
+/* --Methode-- */
+//++
+void  NTuple::Print(int num, int nmax)  const
+//
+//	Imprime `nmax' evenements a partir du numero `num'.
+//--
+{
+int i,j;
+
+printf("Num     ");
+for(i=0; i<mNVar; i++)  printf("%8s ", mNames+i*LENNAME1);
+putchar('\n');
+
+if (nmax <= 0)  nmax = 1;
+if (num < 0)  num = 0;
+nmax += num;
+if (nmax > mNEnt) nmax = mNEnt;
+for(i=num; i<nmax; i++) {
+  GetVec(i, NULL); 
+  printf("%6d  ", i);  
+  for(j=0; j<mNVar; j++)  printf("%8g ", (float)mVar[j]);
+  putchar('\n');
+}
+return;
+}
+
+/* --Methode-- */
+//! Prints table definition and number of entries 
+//++
+void  NTuple::Show(ostream& os)  const
+//
+//	Imprime l'information generale sur le ntuple.
+//--
+{
+os << "NTuple: NVar= " << mNVar << " NEnt=" << mNEnt  
+   << " (Blk Sz,Nb= " << mBlk << " ," << mNBlk << ")\n";
+os << "            Variables       Min      Max       \n";
+int i;
+double min, max;
+char buff[128];
+for(i=0; i<mNVar; i++) {
+  GetMinMax(i, min, max);
+  sprintf(buff, "%3d  %16s  %10g  %10g \n", i, mNames+i*LENNAME1, min, max);
+  os << (string)buff ;
+  }
+os << endl;
+}
+
+
+/* --Methode-- */
+//! Fills the table, reading lines from an ascii file
+/*!
+  \param fn : file name
+  \param defval : default value for empty cells in the ascii file 
+ */
+//++
+int  NTuple::FillFromASCIIFile(string const& fn, float defval)
+//
+//	Remplit le ntuple a partir d'un fichier ASCII.
+//	Renvoie le nombre de lignes ajoutees.
+//--
+{
+if (NbColumns() < 1)  { 
+  cout << "NTuple::FillFromASCIIFile() Ntuple has " << NbColumns() << " columns" << endl;
+  return(-1);
+  }
+FILE * fip = fopen(fn.c_str(), "r");
+if (fip == NULL) {
+  cout << "NTuple::FillFromASCIIFile() Error opening file " << fn << endl;
+  return(-2);
+  }
+
+char lineb[4096];
+char *line;
+char* ccp;
+int j,kk;
+int postab, posb;
+float* xv = new float[NbColumns()];
+
+int nlread = 0;
+int nvar = NbColumns();
+// On boucle sur toutes les lignes
+while (fgets(lineb,4096,fip) != NULL) {
+  lineb[4095] = '\0';
+  j = 0; line = lineb;
+//  On enleve les espaces et tab de debut 
+  while ( (line[j] != '\0') && ((line[j] == ' ') || (line[j] == '\t')) )  j++;
+  line = lineb+j; 
+// Il faut que le premier caractere non-espace soit un digit, ou + ou - ou .
+  if (!( isdigit(line[0]) || (line[0] == '+') || (line[0] == '-') || (line[0] == '.') ))  continue;
+  ccp = line;
+  for(kk=0; kk<nvar; kk++)  xv[kk] = defval;
+  for(kk=0; kk<nvar; kk++) {
+// Les mots sont separes par des espaces ou des tab
+    postab = posc(ccp, '\t' );
+    posb = posc(ccp, ' ' );
+    if (postab >= 0) { 
+       if (posb < 0) posb = postab;
+       else if (postab < posb)  posb = postab; 
+       } 
+    if (posb >= 0)  ccp[posb] = '\0';
+    if ( isdigit(line[0]) || (line[0] == '+') || (line[0] == '-') || (line[0] == '.') ) 
+      xv[kk] = atof(ccp);
+    if (posb < 0)  break;
+    ccp += posb+1;   j = 0;
+    while ( (ccp[j] != '\0') && ((ccp[j] == ' ') || (ccp[j] == '\t')) )  j++;
+    ccp += j;
+    }
+  Fill(xv);
+  nlread++;
+  }
+
+delete[] xv;
+cout << "NTuple::FillFromASCIIFile( " << fn << ") " << nlread << " fill from file " << endl;
+return(nlread);
+}
+
+
+// ------- Implementation de  l interface NTuple  ---------
+
+/* --Methode-- */
+uint_4 NTuple::NbLines() const
+{
+return(NEntry());
+}
+/* --Methode-- */
+uint_4 NTuple::NbColumns() const
+{
+return(NVar());
+}
+
+/* --Methode-- */
+r_8 * NTuple::GetLineD(int n) const
+{
+return(GetVecD(n));
+}
+
+/* --Methode-- */
+r_8 NTuple::GetCell(int n, int k) const
+{
+return(GetVal(n, k));
+}
+
+/* --Methode-- */
+r_8 NTuple::GetCell(int n, string const & nom) const
+{
+return(GetVal(n, nom.c_str()));
+}
+
+/* --Methode-- */
+//++
+void  NTuple::GetMinMax(int k, double& min, double& max)  const
+//
+//	Retourne le minimum et le maximum de la variable `k'.
+//--
+{
+min = 9.e19; max = -9.e19;
+if ( (k < 0) || (k >= mNVar) )    return;
+int jb,ib,i;
+double x;
+i=0;
+for(jb=0; jb< mNBlk; jb++)
+  for(ib=0; ib< mBlk; ib++) {
+    if (i >= mNEnt)  break;
+    i++;
+    x = *(mPtr[jb]+ib*mNVar+k);
+    if(i==1) {min = x; max = x;}
+    if (x < min)  min = x;
+    if (x > max)  max = x;
+  }
+return;
+}
+
+/* --Methode-- */
+void NTuple::GetMinMax(string const & nom, double& min, double& max)   const
+{
+GetMinMax(IndexNom(nom.c_str()), min, max);
+}
+
+/* --Methode-- */
+int NTuple::ColumnIndex(string const & nom)  const
+{
+return(IndexNom(nom.c_str()));
+}
+
+/* --Methode-- */
+string NTuple::ColumnName(int k) const
+{
+return(NomIndex(k));
+}
+
+/* --Methode-- */
+//++
+string NTuple::VarList_C(const char* nomx)  const
+//
+//	Retourne une chaine de caracteres avec la declaration des noms de 
+//	variables. si "nomx!=NULL" , des instructions d'affectation
+//	a partir d'un tableau "nomx[i]" sont ajoutees. 
+//--
+{
+string rets="";
+int i;
+for(i=0; i<mNVar; i++) {
+  if ( (i%5 == 0) && (i > 0) )  rets += ";";  
+  if (i%5 == 0)   rets += "\ndouble "; 
+  else rets += ",";
+  rets += mNames+i*LENNAME1;
+  }
+rets += "; \n";
+if (nomx) { 
+  char buff[256];
+  for(i=0; i<mNVar; i++) {
+    sprintf(buff,"%s=%s[%d]; ",  mNames+i*LENNAME1, nomx, i);
+    rets += buff;
+    if ( (i%3 == 0) && (i > 0) )  rets += "\n"; 
+    }
+  }
+
+return(rets);
+}
+
+
+/* --Methode-- */
+//++
+string NTuple::LineHeaderToString() const 
+//	Retourne une chaine de caracteres avec la liste des noms de  
+//	variables, utilisables pour une impression
+//--
+{
+char buff[32];
+string rets=" Num    ";
+for(int i=0; i<mNVar; i++) {
+  sprintf(buff, "%8s ", mNames+i*LENNAME1);
+  rets += buff;
+  }
+rets += '\n';
+return(rets);
+}
+
+/* --Methode-- */
+//++
+string NTuple::LineToString(int n) const
+//	Retourne une chaine de caracteres avec le contenu de la ligne "n"
+//	utilisable pour une impression
+//--
+{
+char buff[32];
+double* val;
+val = GetLineD(n);
+sprintf(buff,"%6d: ",n);  
+string rets=buff;
+int i;
+for(i=0; i<mNVar; i++) {
+  sprintf(buff, "%8.3g ", val[i]);
+  rets += buff;
+  }
+rets += '\n';
+return(rets);
+}
+
+/*!
+   \class SOPHYA::ObjFileIO<NTuple>
+   \ingroup HiStats
+   Persistence (serialisation) handler for class NTuple
+*/
+
+/* --Methode-- */ 
+//++
+void   ObjFileIO<NTuple>::WriteSelf(POutPersist& s)  const
+//
+//	Ecriture ppersist du ntuple.
+//--
+{
+if (dobj == NULL)   return;
+
+// On ecrit cette chaine pour compatibilite avec l'ancienne version 
+string strg = "NTuple";
+s.Put(strg);
+
+//  On ecrit 3 uint_4 .... 
+//  0: Numero de version,  1 : non nul -> has info,  2 : reserve
+uint_4 itab[3];
+itab[0] = 2;  // Numero de version a 1
+itab[1] = itab[2] = 0;
+if (dobj->mInfo)  itab[1] = 1;
+s.Put(itab, 3);
+
+s.Put(dobj->mNVar);
+s.PutBytes(dobj->mNames, dobj->mNVar*LENNAME1);
+s.Put(dobj->mNEnt);
+s.Put(dobj->mBlk);
+s.Put(dobj->mNBlk);
+if (dobj->mInfo)  s << (*(dobj->mInfo));
+int jb;
+for(jb=0; jb<dobj->mNBlk; jb++)
+  s.Put(dobj->mPtr[jb], dobj->mNVar*dobj->mBlk); 
+return;
+}
+
+/* --Methode-- */
+//++
+void  ObjFileIO<NTuple>::ReadSelf(PInPersist& s)
+//
+//	Lecture ppersist du ntuple.
+//--
+{
+
+if (dobj == NULL) dobj = new NTuple;
+else dobj->Clean();
+
+bool hadinfo = false;
+string strg;
+s.Get(strg);
+if (strg == "NTuple") {
+  uint_4 itab[3];
+  s.Get(itab, 3);
+  if (itab[1] != 0) hadinfo = true;
+}
+else {
+// Ancienne version de PPF NTuple - Pour savoir s'il y avait un DVList Info associe
+  char buff[256];
+  strcpy(buff, strg.c_str());
+  if (strncmp(buff+strlen(buff)-7, "HasInfo", 7) == 0)  hadinfo = true;
+}
+s.Get(dobj->mNVar);
+dobj->mNames = new char[dobj->mNVar*LENNAME1];
+dobj->mVar = new r_4[dobj->mNVar];
+dobj->mVarD = new r_8[dobj->mNVar];
+s.GetBytes(dobj->mNames, dobj->mNVar*LENNAME1);
+s.Get(dobj->mNEnt);
+s.Get(dobj->mBlk);
+s.Get(dobj->mNBlk);
+
+if (hadinfo) {    // Lecture eventuelle du DVList Info
+  if (dobj->mInfo == NULL)  dobj->mInfo = new DVList;
+  s >> (*(dobj->mInfo));
+  }
+
+int jb; 
+for(jb=0; jb<dobj->mNBlk; jb++) {
+  r_4* pt = new r_4[dobj->mNVar*dobj->mBlk];
+  dobj->mPtr.push_back(pt);
+  s.Get(dobj->mPtr[jb], dobj->mNVar*dobj->mBlk); 
+}
+
+}
+
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template ObjFileIO<NTuple>
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class ObjFileIO<NTuple>;
+#endif
Index: /tags/V_Dec2002/SophyaLib/HiStats/ntuple.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/HiStats/ntuple.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/HiStats/ntuple.h	(revision 2309)
@@ -0,0 +1,122 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Class NTuple
+//  CMV+Reza     Juillet 97
+//  CEA-DAPNIA      LAL-IN2P3/CNRS
+
+#ifndef NTUPLE_H_SEEN
+#define NTUPLE_H_SEEN
+
+#include "objfio.h"
+
+#include <iostream.h>
+#include <string>
+#include <vector>
+
+#include "ntupintf.h"
+#include "ppersist.h"
+#include "dvlist.h"
+
+namespace SOPHYA {
+
+//  Forward class declaration for Fits handler
+class FITS_XNTuple;
+
+class NTuple : public AnyDataObj , public NTupleInterface {
+
+public:
+//  enum {classId = ClassId_NTuple };
+
+  		    NTuple(int nvar, char** noms, int blk=512);
+		    NTuple();
+                    NTuple(const NTuple& NT);
+		    NTuple(char* flnm);
+  virtual           ~NTuple();
+
+  NTuple&           operator = (const NTuple& NT);
+ 
+  void              Fill(r_4* x);
+
+  inline int_4      NEntry() const  { return(mNEnt); }  
+  inline int_4      NVar() const { return(mNVar); }  
+  inline int_4      BLock() const { return(mBlk); }  
+// $CHECK$ Reza 21/10/99 Pourquoi faire BLock() ?
+
+  float             GetVal(int n, int k)   const;
+  inline float	    GetVal(int n, const char* nom) const 
+                            { return(GetVal(n, IndexNom(nom)) ); }
+  int               IndexNom(const char* nom)  const ;
+  char*             NomIndex(int k) const;
+
+  r_4*	            GetVec(int n, r_4* ret=NULL)  const ;
+  r_8*	            GetVecD(int n, r_8* ret=NULL)  const ;
+
+// Impression, I/O
+  void              Print(int num, int nmax=1)  const ;
+  void              Show(ostream& os) const;
+  inline void       Show() const { Show(cout); }
+
+  DVList&           Info();
+
+// Remplissage depuis fichier ASCII 
+  int		    FillFromASCIIFile(string const& fn, float defval=0.);
+
+
+// Declaration de l interface NTuple
+  virtual uint_4        NbLines() const ;
+  virtual uint_4        NbColumns() const ;
+  virtual r_8 *         GetLineD(int n) const ;
+  virtual r_8		GetCell(int n, int k) const ;
+  virtual r_8		GetCell(int n, string const & nom) const ;
+  virtual void		GetMinMax(int k, double& min, double& max)   const ; 
+  virtual void		GetMinMax(string const & nom, double& min, double& max)   const ; 
+  virtual int           ColumnIndex(string const & nom)  const ;
+  virtual string        ColumnName(int k) const;
+  virtual string	VarList_C(const char* nomx=NULL) const ;
+  virtual string        LineHeaderToString() const;
+  virtual string        LineToString(int n) const;  
+
+//  Pour la gestion de persistance
+  friend class ObjFileIO<NTuple> ;
+
+  // pour fichiers FITS
+    friend class FITS_NTuple;
+
+
+private:
+  void  Clean();
+
+  int_4 mNVar, mNEnt, mBlk, mNBlk;
+  r_4* mVar;
+  r_8* mVarD;
+  char* mNames;
+
+  vector<r_4*> mPtr;
+
+  DVList* mInfo;        // Infos (variables) attachees au NTuple
+  
+};
+
+/*! Prints table information on stream \b s (nt.Show(s)) */
+inline ostream& operator << (ostream& s, NTuple const & nt)
+  {  nt.Show(s);  return(s);  }
+
+/*! Writes the object in the POutPersist stream \b os */
+inline POutPersist& operator << (POutPersist& os, NTuple & obj)
+{ ObjFileIO<NTuple> fio(&obj);  fio.Write(os);  return(os); }
+/*! Reads the object from the PInPersist stream \b is */
+inline PInPersist& operator >> (PInPersist& is, NTuple & obj)
+{ ObjFileIO<NTuple> fio(&obj);  fio.Read(is);  return(is); }
+
+// Classe pour la gestion de persistance
+// ObjFileIO<NTuple>
+
+
+
+#ifdef __MWERKS__
+__MSL_FIX_ITERATORS__(r_4*);
+#endif
+
+} // namespace SOPHYA
+
+#endif
+  
Index: /tags/V_Dec2002/SophyaLib/HiStats/objlist.list
===================================================================
--- /tags/V_Dec2002/SophyaLib/HiStats/objlist.list	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/HiStats/objlist.list	(revision 2309)
@@ -0,0 +1,8 @@
+hisprof.o
+histinit.o
+histos.o
+histos2.o
+ntupintf.o
+ntuple.o
+proxtuple.o
+xntuple.o
Index: /tags/V_Dec2002/SophyaLib/HiStats/proxtuple.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/HiStats/proxtuple.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/HiStats/proxtuple.cc	(revision 2309)
@@ -0,0 +1,54 @@
+//--------------------------------------------------------------------------
+//
+// Description:
+// 	class ProxTuple : see header file for description.
+//
+//------------------------------------------------------------------------
+//-----------------------
+// This Class's Header --
+//-----------------------
+#include "proxtuple.h"
+//---------------
+// STL
+//-----------------
+using namespace std;
+//-------------------------------
+// Collaborating Class Headers --
+//-------------------------------
+//-----------------------------------------------------------------------
+// Local Macros, Typedefs, Structures, Unions and Forward Declarations --
+//-----------------------------------------------------------------------
+
+
+//-----------------
+// Member functions --
+//-----------------
+void
+ProxTuple::fill(float v,const char* n){
+
+  if (_tuple==0) {
+    _name.push_back(string(n));
+  }
+  _val.push_back(v);
+
+}
+
+void
+ProxTuple::dump(){
+
+  int N=_val.size();
+  if (_tuple==0) {
+    char** names=new char* [N];
+    for (int i=0;i<N;i++) names[i]=const_cast<char*>(_name[i].c_str());
+    _tuple=new NTuple(N,names);
+    delete[] names;
+  }
+  float* xnt=new float[N];
+  for (int i=0;i<N;i++) xnt[i]=_val[i];
+  _tuple->Fill(xnt);
+
+  delete xnt;
+  _val.clear();
+
+
+}
Index: /tags/V_Dec2002/SophyaLib/HiStats/proxtuple.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/HiStats/proxtuple.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/HiStats/proxtuple.h	(revision 2309)
@@ -0,0 +1,68 @@
+//--------------------------------------------------------------------------
+//
+// Description:
+// 	class ProxTuple :
+//
+// un proxy pour ntuple sophya pour une interface + user friendly
+// example d'utilisation:
+/*
+
+  ProxTuple tupleCl;
+  for (i=0;i<N;i++){
+    tupleCl.fill(cl.l(i),"l");
+    tupleCl.fill(i,"i");
+    // etc...
+    
+    tupleCl.dump();
+  }
+   POutPersist pos(string("ct.ppf"));
+  pos.PutObject(tupleCl.tuple(),"tupleCl");
+*/
+//
+// Author List:
+//	S.Plaszczynski 
+//
+// History (add to end):
+//	S.Plaszczynski  sam oct 26 16:22:27 CEST 2002 (creation)
+//
+// Contact: 
+//	plaszczy@lal.in2p3.fr
+//------------------------------------------------------------------------
+#ifndef ProxTuple_hh
+#define ProxTuple_hh
+
+//forward declarations
+
+#include "ntuple.h"
+#include <string>
+
+class ProxTuple
+{
+
+public:
+
+  //constructors
+  ProxTuple():_tuple(0){};
+
+  // destructor
+  ~ProxTuple() {delete _tuple;};
+
+  //member functions
+  void fill(float v,const char*);
+  inline void fill(double v,const char* c) { fill((float)v,c);}
+  inline void fill(int v,const char* c){ fill((float)v,c);}
+  void dump();
+  
+  //acces au ntuple
+  inline NTuple& tuple(){return *_tuple;}
+  
+
+private:
+  NTuple* _tuple;
+  vector<string> _name;
+  vector<float> _val;
+  
+};
+
+#endif
+
Index: /tags/V_Dec2002/SophyaLib/HiStats/xntuple.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/HiStats/xntuple.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/HiStats/xntuple.cc	(revision 2309)
@@ -0,0 +1,1029 @@
+// -*- C++ -*- 
+// 
+// xntuple.cc 
+// N. Regnault   -      98-99 
+// Extended NTuples 
+// 
+#include <string.h>
+#include "ppersist.h"
+#include "perrors.h"
+#include "xntuple.h"
+#ifdef OS_MACOSX
+#include <unistd.h>
+#endif
+
+#define LENNAME 31 
+#define MAXLEN 128
+#define BADVAL -1.e19
+
+/*!
+   \class SOPHYA::XNTuple
+   \ingroup HiStats
+   NTuple class (a Table or 2-D data set) with the possibility of having
+   columns with int, float or string type content. In addition, this class
+   can handle large data sets, using swap space on disk.
+   \sa SOPHYA::ObjFileIO<XNTuple>
+
+   \code
+   #include "xntuple.h"
+   // ...
+   char * names[4] = {"X", "X2", "XInt","XStr"};
+   // XNTuple (Table) creation with 4 columns, of integer, 
+   // double(2) and string type
+   XNTuple  xnt(2,0,1,1, names);
+   // Filling the NTuple
+   r_8 xd[2];
+   int_4 xi[2];
+   char xss[2][32];
+   char * xs[2] = {xss[0], xss[1]} ;
+   for(int i=0; i<50; i++) {
+     xi[0] = i;  xd[0] = i+0.5;  xd[1] = xd[0]*xd[0];
+     sprintf(xs[0],"X=%g", xd[0]);
+     xnt.Fill(xd, NULL, xi, xs);
+   }
+   // Printing table info
+   cout << xnt ;
+   // Saving object into a PPF file
+   POutPersist po("xnt.ppf");
+   po << xnt ;
+   \endcode
+   
+*/
+
+//++
+// Class	XNTuple
+// Lib		Outils++ 
+// include	xntuple.h
+//
+//	Classe de ntuples
+//--
+//++
+// Links	Parents
+// PPersist
+// NTupleInterface
+//--
+//++
+// Links	Voir aussi
+// NTuple
+//--
+
+
+char* XNTuple::glob_swp = NULL ; 
+long int  XNTuple::NbNT = 0 ; 
+
+#ifdef __MWERKS__
+// mktemp() non connu sur Mac (?)  - Dominique Yvon / R. Ansari
+char * mktemp(char * Filename);
+#endif
+
+NTBlk::NTBlk(int ndvar, int nfvar, int nivar, int nsvar, int strsz, int sz) 
+    : sw(0), // pas swappe 
+      swoff(-1), 
+      ddata(NULL), fdata(NULL), 
+      idata(NULL), sdata(NULL)
+{
+    if(ndvar) ddata = new r_8[ndvar*sz] ; 
+    if(nfvar) fdata = new r_4[nfvar*sz] ; 
+    if(nivar) idata = new int_4[nivar*sz] ; 
+    if(nsvar) sdata = new char[nsvar*(strsz+1)*sz] ; 
+}
+
+NTBlk::~NTBlk()
+{
+    free() ; 
+}
+
+void NTBlk::free() 
+{
+    if(ddata) delete[] ddata ; ddata = NULL ; 
+    if(fdata) delete[] fdata ; fdata = NULL ; 
+    if(idata) delete[] idata ; idata = NULL ; 
+    if(sdata) delete[] sdata ; sdata = NULL ; 
+}
+
+// 
+// relit bloc ds fichier swap 
+// (seulement si bloc n'est plus en memoire) 
+// 
+void XNTuple::read_blk(NTBlk* blk) const 
+{
+    // deja en memoire ? 
+    if( !blk->sw ) return ;  
+    
+    blk->free() ; 
+    
+    // On va --> blk 
+    fseek(swf, blk->swoff, SEEK_SET) ; 
+    
+    if(mD) { 
+	blk->ddata = new r_8[mD*mBlkSz] ; 
+	fread(blk->ddata, sizeof(r_8), mD*mBlkSz, swf) ; 
+    }
+    if(mF) { 
+	blk->fdata = new r_4[mF*mBlkSz] ; 
+	fread(blk->fdata, sizeof(r_4), mF*mBlkSz, swf) ; 
+    }
+    if(mI) { 
+	blk->idata = new int_4[mI*mBlkSz] ; 
+	fread(blk->idata, sizeof(int_4), mI*mBlkSz, swf) ; 
+    }
+    if(mS) { 
+	blk->sdata = new char[mS*(mStrSz+1)*mBlkSz] ; 
+	fread(blk->sdata, sizeof(char), mS*mBlkSz*(mStrSz+1), swf) ; 
+    }
+}
+
+// 
+// swappe le bloc present en memoire 
+// depuis le + longtemps 
+// 
+void XNTuple::swap() const 
+{
+    // fichier de swap ouvert ? 
+    if(!swf) { 
+	swf_name = new char[swp.length()+64] ; 
+	strncpy(swf_name, swp.c_str(), swp.length()+1) ; 
+	strcat(swf_name, "NTupleXXXXXX") ; 
+	//	swf_name = strdup("NTupleXXXXXX") ; 
+	mktemp(swf_name) ; 
+	swf = fopen(swf_name, "w+") ; 
+	if(!swf) throw IOExc("XNTuple::swap() - Error opening swap File");
+    }
+    
+    // bloc a swapper 
+    NTBlk* blk = sw.front() ; 
+    
+    // bloc dans fichiers de swap ? 
+    //    if( blk->swoff > 0 ) 
+    write_blk(blk) ; 
+    blk->free() ; 
+    
+    blk->sw = 1 ; // on marque le bloc swappe 
+    sw.pop_front() ; // on le vire de la liste de swap 
+    mNSwBlk++ ; 
+}
+
+
+// 
+// unswap() 
+// 
+void XNTuple::get_blk(int i) const 
+{
+    if(i<0 || i>=mNBlk) return ; 
+    read_blk(ptr[i]) ; 
+    ptr[i]->sw = 0 ; 
+    sw.push_back(ptr[i]) ; 
+    mNSwBlk-- ; 
+}
+
+
+// 
+// ecrit le bloc en bout de fichier 
+// (seulement si swoff < 0 ) 
+// 
+void XNTuple::write_blk(NTBlk* blk) const 
+{
+    // deja swappe ? 
+    if( blk->swoff >= 0 ) return ; 
+    fseek(swf, 0, SEEK_END) ; 
+    // position debut du bloc 
+    blk->swoff = ftell(swf) ; 
+    if(blk->ddata) fwrite(blk->ddata, sizeof(r_8), mD*mBlkSz, swf) ; 
+    if(blk->fdata) fwrite(blk->fdata, sizeof(r_4),  mF*mBlkSz, swf) ; 
+    if(blk->idata) fwrite(blk->idata, sizeof(int_4),  mI*mBlkSz, swf) ; 
+    if(blk->sdata) fwrite(blk->sdata, sizeof(char),   mS*mBlkSz*(mStrSz+1), swf) ; 
+}
+
+
+void  XNTuple::add_blk() 
+{
+    // l'ancien bloc en ecriture peut maintenant 
+    // etre swappe (s'il existe) 
+    if(mBlk>=0) sw.push_back(ptr[mBlk]) ; 
+    
+    // si pas de place, on swappe 
+    if( mNBlk+1 >= mMaxBlk ) swap() ; 
+    
+    // nouveau bloc 
+    NTBlk* tmp = new NTBlk(mD, mF, mI, mS, mStrSz, mBlkSz) ; 
+    ptr.push_back(tmp) ; 
+    
+    //    mNBlk++ ; 
+    //    mOff = 0 ; 
+    //    mBlk++ ; 
+}
+
+
+XNTuple::XNTuple()
+    : mNEnt(0), mNBlk(0), mNSwBlk(0), 
+      mBlkSz(0), mBlk(-1), mOff(0), 
+      mMaxBlk(0), mStrSz(0), 
+      mD(0), mF(0), mI(0), mS(0), 
+      mVarD(NULL), mMin(NULL), mMax(NULL), 
+      mNVars(0), mNames(NULL), 
+  swf(NULL), swf_name(NULL), mInfo(NULL)
+{
+    if(!glob_swp) SetSwapPath() ; 
+    swp = glob_swp ; 
+    NbNT++ ; 
+}
+
+//++
+// Titre	Constructeurs
+//--
+//++
+// XNTuple(int ndvar, int nfvar, int nivar, int nsvar, char** vnames, -
+//	   int blk=512, int maxblk=100, int strsz=30)
+//	Constructeur - Création d'un XNTuple de "ndvar" variables de type "r_8", -
+//                      "nfvar" de type "r_4", "nivar" de type "int" et "nsvar" de type -
+//                      "char*". 
+//|            * "blk"    = taille blocs de données (en nombre d'entrées) 
+//|            * "maxblk" = nombre max de blocs présents en mémoire (non swappés) 
+//|            * "strsz"  = taille des données de type char* 
+// XNTuple(XNTuple const& nt)
+//	Constructeur de copie.
+// XNTuple(string const& flnm)
+//	Constructeur - lecture à partir d'un fichier PPersist.
+//--
+
+//! Constructor with specification colum types and names
+/*!
+  \param ndvar : Number of columns with type double (r_8)
+  \param nfvar : Number of columns with type float (r_4)
+  \param nivar : Number of columns with type integer (int_4)
+  \param nsvar : Number of columns with type string
+  \param vnames : Column names (in the order r_8 r_4 int_4 string)
+  (colum names are limited to 31 characters)
+  \param blk : data block size (in number of table lines)
+  \param maxblk : Maximum number of data block in memory
+  \param strsz : string length (for string type columns)
+ */
+XNTuple::XNTuple(int ndvar, int nfvar, int nivar, int nsvar, 
+		   char** vnames, 
+		   int blk, int maxblk, int strsz)
+    : mNEnt(0), mNBlk(0), mNSwBlk(0), 
+      mBlkSz(blk), mBlk(-1), mOff(0), 
+      mMaxBlk(maxblk), mStrSz(strsz), 
+      mD(ndvar), mF(nfvar), mI(nivar), mS(nsvar), 
+      mVarD(NULL), mMin(NULL), mMax(NULL), 
+      mNVars(ndvar+nfvar+nivar+nsvar), mNames(NULL), 
+      swf(NULL), swf_name(NULL), mInfo(NULL)
+{
+    if(!glob_swp) SetSwapPath() ; 
+    swp = glob_swp ; 
+    
+    mVarD = new r_8[mNVars] ; 
+    mMin  = new r_8[mD+mF+mI] ; 
+    int i;
+    for(i = 0 ; i < (mD+mF+mI) ; i++) mMin[i] =  9E19 ; 
+    mMax  = new r_8[mD+mF+mI] ; 
+    for(i = 0 ; i < (mD+mF+mI) ; i++) mMax[i] = -9E19 ; 
+    
+    if(mNVars) mNames = new char[mNVars*(LENNAME+1)] ; 
+    memset(mNames, 0, mNVars*(LENNAME+1));
+    for(i = 0 ; i < mNVars ; i++)
+      strncpy(mNames+i*(LENNAME+1), vnames[i], LENNAME);
+
+    NbNT++ ; 
+}
+
+
+
+//! Constructor with table initialized from a PPF file
+XNTuple::XNTuple(string const& flnm) 
+    : mNEnt(0), mNBlk(0), mNSwBlk(0), 
+      mBlkSz(0), mBlk(-1), mOff(0), 
+      mMaxBlk(0), mStrSz(0), 
+      mD(0), mF(0), mI(0), mS(0), 
+      mVarD(NULL), mMin(NULL), mMax(NULL), 
+      mNVars(0), mNames(NULL), 
+      swf(NULL), swf_name(NULL), mInfo(NULL)
+{
+    if(!glob_swp) SetSwapPath() ; 
+    swp = glob_swp ; 
+    
+    PInPersist s(flnm);
+    ObjFileIO<XNTuple> fiont(this);
+    fiont.Read(s);
+    NbNT++ ; 
+}
+
+
+//! Copy constructor - Copies the table definition and associated data 
+XNTuple::XNTuple(XNTuple const& nt) 
+    : mNEnt(0), mNBlk(0), mNSwBlk(0), 
+      mBlkSz(0), mBlk(-1), mOff(0), 
+      mMaxBlk(0), mStrSz(0), 
+      mD(0), mF(0), mI(0), mS(0), 
+      mVarD(NULL), mMin(NULL), mMax(NULL), 
+      mNVars(0), mNames(NULL), 
+      swf(NULL), swf_name(NULL), mInfo(NULL) 
+{
+    if(!glob_swp) SetSwapPath() ; 
+    swp = glob_swp ; 
+    Copy(nt) ; 
+    NbNT++ ; 
+}
+
+
+
+XNTuple::~XNTuple()
+{
+    clean() ; 
+    NbNT-- ; 
+    if(NbNT==0) {delete[] glob_swp ; glob_swp = NULL;} 
+}
+
+
+
+//! Clear the data table definition and deletes the associated data
+void XNTuple::clean()
+{
+    // On libere tous les blocs 
+    for(int i = 0 ; i < mNBlk ; i++) 
+	if(!ptr[i]->sw) delete ptr[i] ; 
+    ptr.erase(ptr.begin(), ptr.end()) ; 
+    sw.erase(sw.begin(), sw.end()) ; 
+    
+    // on ferme le fichier de swap 
+    if(swf) { 
+      fclose(swf) ; swf = NULL ; 
+      remove(swf_name) ; 
+      delete swf_name ; swf_name = NULL ; 
+    }
+    // tout le monde remis a 0 
+    mNEnt   = 0 ;     mNBlk   = 0 ; 
+    mNSwBlk = 0 ;     mBlkSz  = 0 ;  
+    mBlk    = -1 ;    mOff    = 0 ; 
+    mMaxBlk = 0 ;     mStrSz  = 0 ; 
+    mD      = 0 ;     mF      = 0 ; 
+    mI      = 0 ;     mS      = 0 ; 
+    mNVars  = 0 ; 
+    
+    
+    if(mVarD) { delete[] mVarD ; mVarD = NULL ; } 
+    if(mMin)  { delete[] mMin  ; mMin  = NULL ; } 
+    if(mMax)  { delete[] mMax  ; mMax  = NULL ; } 
+
+    if(mNames) {delete[] mNames ; mNames = NULL ; }
+    if (mInfo) delete mInfo;
+
+}
+
+
+//++
+// Titre	Méthodes
+//--
+//++
+//  void Fill(r_8* d_data, r_4* f_data, int* i_data, char** s_data) 
+//	Remplissage d'une ligne dans le NTuple
+//  void Show(ostream& os) const 
+//	Impression de la liste des variables avec min-max sur le flot "os"
+//  void Show() const 
+//	Identique à "Show(cout)"
+//  XNTuple&   operator = (XNTuple const& nt) 
+//	Opérateur égal (=) , copie "nt" dans le premier NTuple
+//--
+//! Appends an entry (line) to the table
+/*!
+  \param d_data : double (r_8) line elements
+  \param f_data : float (r_4) line elements
+  \param i_data : integer (int_4) line elements
+  \param s_data : string line elements
+ */
+void XNTuple::Fill(r_8* d_data, r_4* f_data, int_4* i_data, char** s_data) 
+{
+    // place disponible dans bloc courant ? 
+    if( mOff==mBlkSz || mOff==0 ) {
+	add_blk() ; mOff = 0 ; mNBlk++ ; mBlk++ ; 
+    }
+    
+    if( mD && !ptr[mBlk]->ddata || 
+	mF && !ptr[mBlk]->fdata || 
+	mI && !ptr[mBlk]->idata || 
+	mS && !ptr[mBlk]->sdata )
+          throw ParmError("XNTuple::Fill(...) Missing (NULL) argument ");
+    
+    r_8 x ; 
+    // copie variables et update mMin, mMax 
+    if(mD) {
+	memcpy(ptr[mBlk]->ddata+mOff*mD, d_data, mD*sizeof(r_8)) ; 
+	for(int i = 0 ; i < mD ; i++) {
+	    x = d_data[i] ; 
+	    if(x<mMin[i]) mMin[i] = x ; 
+	    if(x>mMax[i]) mMax[i] = x ; 
+	}
+    }
+    
+    if(mF) {
+	memcpy(ptr[mBlk]->fdata+mOff*mF, f_data, mF*sizeof(r_4)) ; 
+	for(int i = 0 ; i < mF ; i++) {
+	    x = f_data[i] ; 
+	    if(x<mMin[i+mD]) mMin[i+mD] = x ; 
+	    if(x>mMax[i+mD]) mMax[i+mD] = x ; 
+	}
+    }
+
+    if(mI) {
+	memcpy(ptr[mBlk]->idata+mOff*mI, i_data, mI*sizeof(int_4)) ; 
+	for(int i = 0 ; i < mI ; i++) {
+	    x = i_data[i] ; 
+	    if(x<mMin[i+mD+mF]) mMin[i+mD+mF] = x ; 
+	    if(x>mMax[i+mD+mF]) mMax[i+mD+mF] = x ; 
+	}
+    }
+    for(int i = 0 ; i < mS ; i++) 
+	memcpy(ptr[mBlk]->sdata+(mOff*mS+i)*(mStrSz+1), 
+	       s_data[i], (strlen(s_data[i])+1)*sizeof(char)) ; 
+    mOff++ ; 
+    mNEnt++ ; 
+}
+
+// 
+// A quel index correspond mon nom ? 
+// 
+int XNTuple::IndexNom(char const* nom) const 
+{
+    int i ; 
+    for(i = 0 ; i < (mD+mF+mI+mS) ; i++)
+	if( !strncmp( mNames+i*(LENNAME+1), nom, LENNAME+1) ) 
+	    return i ; 
+    return -1 ; 
+}
+
+string XNTuple::NomIndex(int k) const 
+{
+    if( k<0 || k>=mNVars ) return "" ; 
+    return mNames + k*(LENNAME+1) ; 
+}
+
+
+// 
+// 
+// 
+r_8 XNTuple::GetDVal(int i, int k) const 
+{
+    if( i<0 || i>=mNEnt || k<0 || k>=mD ) 
+        throw RangeCheckError("XNTuple::GetDVal() Invalid line/column index");
+    
+    // Bloc ? 
+    int blk = (int)(i/mBlkSz) ; 
+    int off = i%mBlkSz ; 
+    
+    // bloc swappe ? 
+    if( ptr[blk]->sw ) { get_blk(blk) ; swap() ; } 
+    return ptr[blk]->ddata[off*mD+k] ; 
+}
+
+// 
+// 
+// 
+r_4 XNTuple::GetFVal(int i, int k) const 
+{
+    if( i<0 || i>=mNEnt || k<mD || k>=(mD+mF) ) 
+        throw RangeCheckError("XNTuple::GetFVal() Invalid line/column index");
+    k -= mD ; 
+    
+    // Bloc ? 
+    int blk = (int)(i/mBlkSz) ; 
+    int off = i%mBlkSz ; 
+    
+    // bloc swappe ? 
+    if( ptr[blk]->sw ) { get_blk(blk) ; swap() ; } 
+    return ptr[blk]->fdata[off*mF+k] ; 
+}
+
+// 
+// 
+// 
+int_4 XNTuple::GetIVal(int i, int k) const 
+{
+    if( i<0 || i>=mNEnt || k<(mD+mF) || k>=(mD+mF+mI) )
+        throw RangeCheckError("XNTuple::GetIVal() Invalid line/column index");
+
+    k -= (mD+mF) ; 
+
+    // Bloc ? 
+    int blk = (int)(i/mBlkSz) ; 
+    int off = i%mBlkSz ; 
+    
+    // bloc swappe ? 
+    if( ptr[blk]->sw ) { get_blk(blk) ; swap() ; } 
+
+    return ptr[blk]->idata[off*mI+k] ; 
+}
+
+// 
+// 
+// 
+string  XNTuple::GetSVal(int i, int k) const 
+{
+    if( i<0 || i>=mNEnt || k<(mD+mF+mI) || k>=(mD+mF+mI+mS) )
+        throw RangeCheckError("XNTuple::GetSVal() Invalid line/column index");
+
+    k -= (mD+mF+mI) ; 
+    
+    // Bloc ? 
+    int blk = (int)(i/mBlkSz) ; 
+    int off = i%mBlkSz ; 
+    
+    // bloc swappe ? 
+    if( ptr[blk]->sw ) { get_blk(blk) ; swap() ; } 
+    
+    // copie de la chaine 
+    // string ret = strdup(ptr[blk]->sdata + (off*mS+k)*(mStrSz+1)) ; // $CHECK$ EA fuite de memoire
+       // attention, strdup fait un malloc et on ne fait jamais de free...
+       // a quoi sert ce strdup ?????????
+    string ret = ptr[blk]->sdata + (off*mS+k)*(mStrSz+1) ; 
+    //    return ptr[blk]->sdata[k] ; 
+    return ret ; 
+}
+
+
+// 
+// Copie bloc a bloc, avec meme parametres 
+//  
+void XNTuple::Copy(XNTuple const& nt) 
+{
+    clean() ; 
+    // Parametres 
+    mNEnt = nt.mNEnt ; 
+    mBlkSz = nt.mBlkSz ; 
+    mOff = nt.mOff ; 
+    mMaxBlk = nt.mMaxBlk ; 
+    mStrSz = nt.mStrSz ; 
+    mD = nt.mD ; 
+    mF = nt.mF ; 
+    mI = nt.mI ; 
+    mS = nt.mS ; 
+    mNVars = nt.mNVars ; 
+    
+    // noms 
+    if(mNVars) {
+	mNames = new char[mNVars*(LENNAME+1)] ; 
+        mVarD = new r_8[mNVars];
+	memcpy(mNames, nt.mNames, mNVars*(LENNAME+1)*sizeof(char)) ; 
+    }
+    // MinMax 
+    if(nt.mMin) { 
+	mMin = new r_8[(mD+mF+mI)] ; 
+	memcpy(mMin, nt.mMin, (mD+mF+mI)*sizeof(r_8)) ; 
+    }
+    if(nt.mMax) { 
+	mMax = new r_8[(mD+mF+mI)] ; 
+	memcpy(mMax, nt.mMax, (mD+mF+mI)*sizeof(r_8)) ; 
+    }
+    
+    //dup blocs 
+    mNBlk = 0 ; 
+    mBlk  = -1 ; 
+    for(int i = 0 ; i < nt.mNBlk ; i++) {
+	add_blk() ; mBlk++ ; mNBlk++ ; 
+	// si nt.ptr[i] swappe, on le relit 
+	if(nt.ptr[i]->sw) nt.read_blk(nt.ptr[i]) ; 
+	if(mD) 
+	    memcpy(ptr[i]->ddata, nt.ptr[i]->ddata, mD*mBlkSz*sizeof(r_8)) ; 
+	if(mF)
+	    memcpy(ptr[i]->fdata, nt.ptr[i]->fdata, mF*mBlkSz*sizeof(r_4)) ; 
+	if(mI)
+	    memcpy(ptr[i]->idata, nt.ptr[i]->idata, mF*mBlkSz*sizeof(int_4)) ; 
+	if(mS)
+	    memcpy(ptr[i]->sdata, nt.ptr[i]->sdata, mS*mBlkSz*sizeof(char)*(mStrSz+1)) ; 
+	if(nt.ptr[i]->sw) nt.ptr[i]->free() ; 
+    }
+
+    // DVList Info block 
+    if(nt.mInfo!=NULL) {mInfo = new DVList; *mInfo = *(nt.mInfo);}
+
+}
+
+//++
+// DVList& Info()
+//	Renvoie une référence sur l'objet DVList Associé
+//--
+
+//! Returns the associated DVList object
+DVList&  XNTuple::Info()
+{
+  if (mInfo == NULL)  mInfo = new DVList;
+  return(*mInfo);
+}
+
+void XNTuple::Print(int num, int nmax) const 
+{
+    printf("XNTuple::Print() : \n") ; 
+    printf("  Entrees = %d, Blocs  = %d, Bloc Size = %d\n", 
+	   mNEnt, mNBlk, mBlkSz) ; 
+    int i,j;
+    printf("  D_Vars  = %d : ", mD) ; 
+    for(i = 0 ; i < mD ; i++) 
+	printf("%s ", NomIndex(i).c_str() ) ; 
+    printf("\n") ; 
+    
+    printf("  F_Vars  = %d : ", mF) ; 
+    for(i = 0 ; i < mF ; i++) 
+	printf("%s ", NomIndex(i+mD).c_str() ) ; 
+    printf("\n") ; 
+    
+    printf("  I_Vars  = %d : ", mI) ; 
+    for(i = 0 ; i < mI ; i++) 
+	printf("%s ", NomIndex(i+mD+mF).c_str() ) ; 
+    printf("\n") ; 
+    
+    printf("  S_Vars  = %d : ", mS) ; 
+    for(i = 0 ; i < mS ; i++) 
+	printf("%s ", NomIndex(i+mD+mF+mI).c_str() ) ; 
+    printf("\n") ; 
+    
+    for(i = num ; i < num+nmax ; i++) {
+	for(j = 0 ; j < mD ; j++) printf("%f ", GetDVal(i,j)) ; 
+	printf(" -- ") ; 
+	for(j = 0 ; j < mF ; j++) printf("%f ", GetFVal(i,j+mD)) ; 
+	printf(" -- ") ; 
+	for(j = 0 ; j < mI ; j++) printf("%d ", GetIVal(i,j+mD+mF)) ; 
+	printf(" -- ") ; 
+	for(j = 0 ; j < mS ; j++) printf("%s ", GetSVal(i,j+mD+mF+mI).c_str()) ; 
+	printf("\n") ; 
+    }
+}
+
+
+//! Prints table definition and number of entries 
+void   XNTuple::Show(ostream& os) const 
+{
+    os << "XNTuple: NVar= " << mNVars << " NEnt= " << mNEnt 
+       << " (BlkSz,NBlk= " << mBlkSz << ", " << mNBlk << ")" 
+       << " (mNSwBlk= " << mNSwBlk << ")" << endl ; 
+    os << "(Sw File= " ; if(swf_name) os << swf_name ; os << ")" << endl ; 
+    
+    char* buff = new char[80] ; 
+    sprintf(buff, "Variables   :  Type         Min         Max  \n") ; 
+    os << buff ; 
+    
+    r_8 min, max ;
+    int i; 
+    for(i = 0 ; i < mD ; i++) {
+	GetMinMax(i, min, max) ; 
+	sprintf(buff, "  %-10s:   D    %12.6g   %12.6g \n", 
+		NomIndex(i).c_str(), min, max) ; 
+	os << buff ; 
+    }
+    for(i = 0 ; i < mF ; i++) {
+	GetMinMax(i+mD, min, max) ; 
+	sprintf(buff, "  %-10s:   F    %12.6g   %12.6g \n", 
+		NomIndex(i+mD).c_str(), min, max) ; 
+	os << buff ; 
+    }
+    for(i = 0 ; i < mI ; i++) {
+	GetMinMax(i+mD+mF, min, max) ; 
+	sprintf(buff, "  %-10s:   I    %12.6g   %12.6g \n", 
+		NomIndex(i+mD+mF).c_str(), min, max) ; 
+	os << buff ; 
+    }
+    for(i = 0 ; i < mS ; i++) {
+	sprintf(buff, "  %-10s:   S      -----        ----- \n", 
+		NomIndex(i+mD+mF+mI).c_str()) ; 
+	os << buff ; 
+    }
+    delete[] buff ; 
+}
+
+//! NOT YET IMPLEMENTED ! - Fills table from an ascii file
+int    XNTuple::FillFromASCIIFile(string const& fn, r_8 ddval,  r_4 dfval,
+                                        int dival, const char * dsval)
+//	Remplit le ntuple a partir d'un fichier ASCII.
+//	Renvoie le nombre de lignes ajoutees.
+{
+// a faire
+return(0);
+}
+
+
+//! Defines swap file path for XNTuple objects (Default=$TMPDIR or /tmp/)
+void  XNTuple::SetSwapPath(char* p) 
+{
+    if (p == NULL) {
+      p = getenv("TMPDIR");
+      if (p == NULL) p = "/tmp/";
+    }
+    if(!glob_swp) glob_swp = new char[MAXLEN+2] ; 
+    strncpy(glob_swp,p,MAXLEN);
+    if(glob_swp[strlen(glob_swp)] != '/') strcat(glob_swp,"/");
+}
+
+// 
+// 
+// Interface NTuple 
+// 
+// 
+uint_4 XNTuple::NbLines() const
+{
+    return(NEntry());
+}
+
+uint_4 XNTuple::NbColumns() const
+{
+    return(NVar());
+}
+
+r_8* XNTuple::GetLineD(int n) const 
+{
+    // memcpy() impossible
+    // il faut faire des GetVal 
+    int i;
+    for(i = 0 ; i < mD ; i++) 
+	mVarD[i] = GetDVal(n, i) ; 
+    for(i = 0 ; i < mF ; i++) 
+	mVarD[i+mD] = (r_8)GetFVal(n, i+mD) ; 
+    for(i = 0 ; i < mI ; i++) 
+	mVarD[i+mD+mF] = (r_8)GetIVal(n, i+mD+mF) ; 
+    for(i = 0 ; i < mS ; i++) 
+	mVarD[i+mD+mF+mI] = atof(GetSVal(n, i+mD+mF+mI).c_str()) ; 
+    return mVarD ; 
+}
+
+
+r_8  XNTuple::GetCell(int n, int k) const 
+{
+    if( k<0 || k>=(mD+mF+mI+mS) ) return BADVAL ; 
+    if(k<mD) return GetDVal(n,k) ; 
+    if(k<(mF+mD)) return GetFVal(n,k) ; 
+    if(k<(mF+mD+mI)) return GetIVal(n,k) ; 
+    if(k<(mD+mF+mI+mS)) return atof(GetSVal(n,k).c_str()) ; 
+    return BADVAL ; 
+}
+
+
+r_8  XNTuple::GetCell(int n, string const& nom) const 
+{
+    int k = IndexNom(nom.c_str()) ; 
+    if(k<0) return BADVAL ; 
+    if(k<mD) return GetDVal(n,k) ; 
+    if(k<(mF+mD)) return GetFVal(n,k) ; 
+    if(k<(mF+mD+mI)) return GetIVal(n,k) ; 
+    if(k<(mD+mF+mI+mS)) return atof(GetSVal(n,k).c_str()) ; 
+    return BADVAL ; 
+}
+
+string   XNTuple::GetCelltoString(int n, int k) const
+{
+    char buff[32];
+    if(k<0) return (""); 
+    else if(k<mD) 
+      { sprintf(buff, "%g", GetDVal(n,k)); return(buff) ; } 
+    else if(k<(mF+mD)) 
+      { sprintf(buff, "%g", (double)GetFVal(n,k)); return(buff) ; } 
+    else if(k<(mF+mD+mI)) 
+      { sprintf(buff, "%d", GetIVal(n,k)); return(buff) ; } 
+    else if(k<(mD+mF+mI+mS)) 
+      return(GetSVal(n,k).c_str()) ; 
+    return("");
+}
+
+void XNTuple::GetMinMax(int k, double& min, double& max)  const
+{
+    min = 9E19 ; max = -9E19 ; 
+    // variables string non traitees 
+    if( k<0 || k>=(mD+mF+mI) ) return ; 
+    
+    min = mMin[k] ; 
+    max = mMax[k] ; 
+    return ; 
+}
+
+
+void XNTuple::GetMinMax(string const & nom, double& min, double& max)   const
+{
+    GetMinMax(IndexNom(nom.c_str()), min, max) ; 
+}
+
+
+int XNTuple::ColumnIndex(string const& nom) const 
+{
+    return IndexNom(nom.c_str()) ; 
+}
+
+
+string XNTuple::ColumnName(int k) const 
+{
+    return NomIndex(k) ; 
+}
+
+
+string XNTuple::VarList_C(const char* nomx) const 
+{
+    string rets = "" ; 
+    rets += "/* r_8 type variables */ \n";
+    // variables r_8 
+    int i;
+    for(i = 0 ; i < mD ; i++) {
+	if( i>0 && (i%5)==0 ) rets += ";" ; 
+	if( (i%5)==0 ) rets+="\ndouble " ; 
+	else rets += ", " ; 
+	rets += NomIndex(i) ; 
+    }
+    if(mD) rets += ";" ; 
+    
+    // variables r_4 
+    rets += "/* r_4 type variables */ \n";
+    for(i = 0 ; i < mF ; i++) {
+	if( i>0 && (i%5)==0 ) rets += ";" ; 
+	if( (i%5)==0 ) rets+="\ndouble " ; 
+	else rets += ", " ; 
+	rets += NomIndex(i+mD) ; 
+    }
+    if(mF) rets += ";" ; 
+    
+    // variables int 
+    rets += "/* int type variables */ \n";
+    for(i = 0 ; i < mI ; i++) {
+	if( i>0 && (i%5)==0 ) rets += ";" ; 
+	if( (i%5)==0 ) rets+="\ndouble " ; 
+	else rets += ", " ; 
+	rets += NomIndex(i+mD+mF) ; 
+    }
+    if(mI) rets += ";" ; 
+    
+    // variables string
+    rets += "/* string type variables */ \n"; 
+    for(i = 0 ; i < mS ; i++) {
+	if( i>0 && (i%5)==0 ) rets += ";" ; 
+	if( (i%5)==0 ) rets+="\ndouble " ; 
+	else rets += ", " ; 
+	rets += NomIndex(i+mD+mF+mI) ; 
+    }
+    if(mS) rets += "; \n" ; 
+
+    if(nomx) {
+	char buff[256] ; 
+	for(i = 0 ; i < mNVars ; i++) {
+	    sprintf(buff, "%s=%s[%d]; ", NomIndex(i).c_str(), nomx, i) ; 
+	    rets+=buff ; 
+	    if( (i%3 == 0) && (i>0) ) rets += "\n" ; 
+	}
+    }
+    return rets ; 
+}
+
+
+string XNTuple::LineHeaderToString() const 
+{
+    char buff[32];
+    string rets=" Num    ";
+    for(int i=0; i<mNVars; i++) {
+	sprintf(buff, "%8s ", NomIndex(i).c_str() );
+	rets += buff;
+    }
+    rets += '\n';
+    return(rets);
+
+}
+
+
+string XNTuple::LineToString(int n) const 
+{
+    char buff[32];
+    r_8* val;
+    val = GetLineD(n);
+    sprintf(buff,"%6d: ",n); 
+    string rets=buff;
+    int i;
+    for(i=0; i<(mD+mF+mI); i++) {
+	sprintf(buff, "%8.3g ", val[i]);
+	rets += buff;
+    }
+    
+    for(i = mD+mF+mI ; i < mNVars ; i++) {
+	sprintf(buff, "%8s ", GetSVal(n,i).c_str() ) ; 
+	rets += buff ; 
+    }
+    
+    rets += '\n';
+    return(rets);
+}
+
+/*!
+   \class SOPHYA::ObjFileIO<XNTuple>
+   \ingroup HiStats
+   Persistence (serialisation) handler for class XNTuple
+*/
+
+void   ObjFileIO<XNTuple>::WriteSelf(POutPersist& ppout) const 
+{
+  if (dobj == NULL)   return;
+//  On ecrit 3 uint_4 .... 
+//  0: Numero de version,  1 : non nul -> has info,  2 : reserve
+  uint_4 itab[3];
+  itab[0] = 1;  // Numero de version a 1
+  itab[1] = itab[2] = 0;
+  if (dobj->mInfo)  itab[1] = 1;
+  ppout.Put(itab,3);
+  if (dobj->mInfo)  if (dobj->mInfo)  ppout << (*(dobj->mInfo));
+
+  // variables internes 
+  ppout.PutI4(dobj->mNEnt) ; 
+  ppout.PutI4(dobj->mNBlk) ; 
+  ppout.PutI4(dobj->mBlkSz) ; 
+  ppout.PutI4(dobj->mBlk) ; 
+  ppout.PutI4(dobj->mOff) ; 
+  ppout.PutI4(dobj->mMaxBlk) ; 
+  ppout.PutI4(dobj->mStrSz) ; 
+  ppout.PutI4(dobj->mD) ; 
+  ppout.PutI4(dobj->mF) ; 
+  ppout.PutI4(dobj->mI) ; 
+  ppout.PutI4(dobj->mS) ; 
+  ppout.PutI4(dobj->mNVars) ; 
+    
+  // Noms 
+  ppout.PutBytes(dobj->mNames, dobj->mNVars*(LENNAME+1)) ; 
+
+  // MinMax 
+  ppout.PutR8s(dobj->mMin, (dobj->mD+dobj->mF+dobj->mI)) ; 
+  ppout.PutR8s(dobj->mMax, (dobj->mD+dobj->mF+dobj->mI)) ; 
+    
+  // Ecriture blocs N'ecrire que si datas existent 
+  for(int i = 0 ; i < dobj->mNBlk ; i++) {
+    // si bloc swappe, on le relit en douce ... 
+    if( dobj->ptr[i]->sw )  dobj->read_blk(dobj->ptr[i]) ; 
+    ppout.PutR8s(dobj->ptr[i]->ddata, dobj->mD*dobj->mBlkSz) ; 
+    ppout.PutR4s(dobj->ptr[i]->fdata, dobj->mF*dobj->mBlkSz) ; 
+    ppout.PutI4s(dobj->ptr[i]->idata, dobj->mI*dobj->mBlkSz) ; 
+    ppout.PutBytes(dobj->ptr[i]->sdata, dobj->mS*dobj->mBlkSz*(dobj->mStrSz+1)) ; 
+    if(dobj->ptr[i]->sw) dobj->ptr[i]->free() ; 
+    }
+}
+
+
+void   ObjFileIO<XNTuple>::ReadSelf(PInPersist& ppin) 
+{
+  if (dobj == NULL) dobj = new XNTuple;
+  else    dobj->clean() ; 
+//  On lit 3 uint_4 .... 
+//  0: Numero de version,  1 : non nul -> has info,  2 : reserve
+  uint_4 itab[3];
+  ppin.Get(itab,3);
+  if (itab[1] != 0) { // Lecture eventuelle du DVList Info
+    if (dobj->mInfo == NULL)  dobj->mInfo = new DVList;
+    ppin >> (*(dobj->mInfo));
+  }
+
+  ppin.GetI4(dobj->mNEnt) ; 
+  ppin.GetI4(dobj->mNBlk) ; 
+  ppin.GetI4(dobj->mBlkSz) ; 
+  ppin.GetI4(dobj->mBlk) ; 
+  ppin.GetI4(dobj->mOff) ; 
+  ppin.GetI4(dobj->mMaxBlk) ; 
+  ppin.GetI4(dobj->mStrSz) ; 
+  ppin.GetI4(dobj->mD) ; 
+  ppin.GetI4(dobj->mF) ; 
+  ppin.GetI4(dobj->mI) ; 
+  ppin.GetI4(dobj->mS) ; 
+  ppin.GetI4(dobj->mNVars) ; 
+    
+  // Noms 
+  dobj->mNames = new char[dobj->mNVars*(LENNAME+1)] ;
+  dobj->mVarD = new r_8[dobj->mNVars]; 
+  ppin.GetBytes(dobj->mNames, dobj->mNVars*(LENNAME+1)) ; 
+
+  // MinMax 
+  dobj->mMin = new r_8[dobj->mD+dobj->mF+dobj->mI] ; 
+  ppin.GetR8s(dobj->mMin, dobj->mD+dobj->mF+dobj->mI) ; 
+  dobj->mMax = new r_8[dobj->mD+dobj->mF+dobj->mI] ; 
+  ppin.GetR8s(dobj->mMax, dobj->mD+dobj->mF+dobj->mI) ; 
+    
+  // lecture Blocs 
+  int nblk = dobj->mNBlk ; 
+  dobj->mBlk = -1 ; dobj->mNBlk = 0 ; 
+  for(int i = 0 ; i < nblk ; i++) {
+    dobj->add_blk() ; dobj->mBlk++ ; dobj->mNBlk++ ; 
+    ppin.GetR8s(dobj->ptr[i]->ddata, dobj->mD*dobj->mBlkSz) ; 
+    ppin.GetR4s(dobj->ptr[i]->fdata, dobj->mF*dobj->mBlkSz) ; 
+    ppin.GetI4s(dobj->ptr[i]->idata, dobj->mI*dobj->mBlkSz) ; 
+    ppin.GetBytes(dobj->ptr[i]->sdata, dobj->mS*dobj->mBlkSz*(dobj->mStrSz+1)) ; 
+  } 
+}
+
+
+
+
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template ObjFileIO<XNTuple>
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class ObjFileIO<XNTuple>;
+#endif
+
+
+#ifdef __MWERKS__
+// Bricolo Dominique Yvon pour faire marcher sur Mac
+#include <stdio.h>
+#include <stdlib.h>
+	static long mktempMemory=0;
+	char * mktemp(char * Filename)
+	{	sprintf(Filename,"TempFile%8i",mktempMemory);
+		mktempMemory++;
+		return Filename;
+	}
+#endif
Index: /tags/V_Dec2002/SophyaLib/HiStats/xntuple.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/HiStats/xntuple.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/HiStats/xntuple.h	(revision 2309)
@@ -0,0 +1,177 @@
+// -*- C++ -*- 
+// 
+// XNTuple 
+// 
+// N. Regnault 03/98 
+//             07/99 (NTupleInterface)
+// 
+// 
+#ifndef XNTUPLE_H_SEEN
+#define XNTUPLE_H_SEEN
+
+#include "machdefs.h"
+
+#include <string.h>
+#include <vector>
+#include <list>
+#include <map>
+
+#include "ntupintf.h"
+#include "ppersist.h"
+#include "dvlist.h"
+#include "objfio.h"
+
+
+namespace SOPHYA {
+// 
+// Bloc de donnees 
+// 
+struct NTBlk
+{
+    NTBlk(int ndvar, int nfvar, int nivar, int nsvar, int strsz, int sz) ; 
+    ~NTBlk() ; 
+    
+    void free() ;     // ne libere que les zones de donnees 
+
+    int      sw ;     // swappe ? 
+    long int swoff ;  // offset dans fichier de swap 
+    r_4*     fdata ;  
+    r_8*     ddata ;  
+    int_4*   idata ;  
+    char*    sdata ;  
+} ; 
+
+//  Forward class declaration for Fits handler
+class FITS_XNTuple;
+
+class XNTuple : public AnyDataObj , public NTupleInterface {
+public:
+  //    enum {classId = ClassId_XNTuple };
+
+    XNTuple() ; 
+    XNTuple(int ndvar, int nfvar, int nivar, int nsvar, 
+	    char** vnames, 
+	    int blk=512, int maxblk=100, int strsz=30) ; 
+    XNTuple(XNTuple const& nt) ; 
+    XNTuple(string const & flnm); 
+    virtual           ~XNTuple();
+    
+    void              Fill(r_8* d_data, r_4* f_data, int_4* i_data, char** sdata);
+    
+    inline int_4      NEntry() const { return mNEnt ; } 
+    inline int_4      NDVar() const  { return mD ; } 
+    inline int_4      NFVar() const  { return mF ; } 
+    inline int_4      NIVar() const  { return mI ; } 
+    inline int_4      NSVar() const  { return mS ; } 
+    inline int_4      NVar() const   { return mNVars ; } 
+    int               IndexNom(char const* nom) const ; 
+    string            NomIndex(int k) const ; 
+    
+    r_8               GetDVal(int i, int k) const ; 
+    r_4               GetFVal(int i, int k) const ; 
+    int_4             GetIVal(int i, int k) const ; 
+    string            GetSVal(int i, int k) const ; 
+    //    MuTyV             GetVal(char const* nom) ; 
+    
+    void              Copy(XNTuple const& nt) ; 
+    inline XNTuple&   operator=(XNTuple const& nt) { Copy(nt) ; return *this ; } 
+    
+    void              Print(int num, int nmax=1) const ;
+    void              Show(ostream& os) const ; 
+    inline void       Show() const { Show(cout) ; } 
+
+    DVList&           Info() ; 
+
+// Remplissage depuis fichier ASCII 
+   int		      FillFromASCIIFile(string const& fn, r_8 ddfval=0., r_4 dfval=0.,
+                                        int dival=0, const char * dsval="");
+        
+    static  void      SetSwapPath(char* p=NULL) ; 
+    string&           SwapPath() { return swp ; } 
+    
+// Declaration de l interface NTuple
+    virtual uint_4    NbLines() const ;
+    virtual uint_4    NbColumns() const ;
+    virtual r_8 *     GetLineD(int n) const ;
+    virtual r_8	      GetCell(int n, int k) const ;
+    virtual r_8	      GetCell(int n, string const & nom) const ;
+    virtual string    GetCelltoString(int n, int k) const ;
+    virtual void      GetMinMax(int k, double& min, double& max)   const ; 
+    virtual void      GetMinMax(string const & nom, double& min, double& max)   const ; 
+    virtual int       ColumnIndex(string const & nom)  const ;
+    virtual string    ColumnName(int k) const;
+    virtual string    VarList_C(const char* nomx=NULL) const ;
+    virtual string    LineHeaderToString() const;
+    virtual string    LineToString(int n) const;  
+
+//  Pour la gestion de persistance
+    friend class ObjFileIO<XNTuple> ;
+
+
+  // pour fichiers FITS
+    friend class FITS_XNTuple;
+
+
+private:
+
+
+
+    void    clean();    // remet tout a zero 
+    void    swap() const ;    // swappe le + ancien blk en memoire 
+    void    read_blk(NTBlk*) const ;  // relit le bloc 
+    void    write_blk(NTBlk*) const ; // ecrit un bloc 
+    void    get_blk(int i) const ;  // == unswap() 
+    void    add_blk() ; // ajout d'un nouveau bloc 
+    
+    int_4   mNEnt ;   // nb total d'entrees 
+    int_4   mNBlk ;   // nb total de blocs 
+    mutable int_4   mNSwBlk ; // nb blocs swappes 
+    int_4   mBlkSz ;  // taille bloc 
+    int_4   mBlk ;    // bloc courant en ecriture 
+    int_4   mOff ;    // offset dans bloc en ecriture ; pointe sur le premiere case vide 
+    int_4   mMaxBlk ; // nb max de blocs autorises en memoire 
+    int_4   mStrSz ;  // taille des variables char** 
+    int_4   mNVars ;  // mD + mF + mI + mS 
+    int_4   mD, mF, mI, mS ; // nb variables de chaque type 
+    
+    r_8* mVarD, *mMin, *mMax ; 
+    
+    // 
+    // Noms + Prefix --> indiquer le type 
+    // 
+    //    char* mDNames, *mFNames, *mINames, *mSNames ; 
+    char* mNames ; 
+    //    typedef less<string> SCmp ; 
+    //    map<string,int,SCmp> mNames ; 
+    
+    // Donnees 
+    mutable vector<NTBlk*> ptr ; 
+    mutable list<NTBlk*> sw ; // liste --> swap() 
+
+    mutable FILE* swf ; // fichier --> swap 
+    mutable char* swf_name ; 
+    string  swp ; // swap_path 
+
+    DVList* mInfo;        // Infos (variables) attachees au NTuple
+
+    static  char*  glob_swp ; // swap_path global 
+    static  long int NbNT ; 
+}; 
+
+/*! Prints table information on stream \b s (nt.Show(os)) */
+inline ostream& operator << (ostream& s, XNTuple const & nt)
+  {  nt.Show(s);  return(s);  }
+
+/*! Writes the object in the POutPersist stream \b os */
+inline POutPersist& operator << (POutPersist& os, XNTuple & obj)
+{ ObjFileIO<XNTuple> fio(&obj);  fio.Write(os);  return(os); }
+/*! Reads the object from the PInPersist stream \b is */
+inline PInPersist& operator >> (PInPersist& is, XNTuple & obj)
+{ ObjFileIO<XNTuple> fio(&obj);  fio.Read(is);  return(is); }
+
+// Classe pour la gestion de persistance
+// ObjFileIO<XNTuple>
+} // namespace SOPHYA
+
+#endif
+
Index: /tags/V_Dec2002/SophyaLib/Mgr/Makefile
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/Makefile	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/Makefile	(revision 2309)
@@ -0,0 +1,196 @@
+# include files defining compiler/linker options 
+MODULECXXREPNAME := PI
+include Mgr/Makefile.h
+include Mgr/Makefile.slb
+
+LIBF =  $(LIB)libBaseTools.a $(LIB)libSysTools.a $(LIB)libSUtils.a $(LIB)libTArray.a $(LIB)libNTools.a $(LIB)libHiStats.a $(LIB)libSkyMap.a $(LIB)libSamba.a $(LIB)libSkyT.a
+LIBS = -L$(LIB) -lBaseTools -lSysTools -lSUtils -lTArray -lNTools -lHiStats -lSkyMap -lSamba -lSkyT
+
+defaut: libs
+
+all: libs extlibs PI
+
+libs: cxxlibs
+
+extlibs: cxxextlibs
+
+cxxlibs:  BaseTools SysTools SUtils TArray NTools HiStats SkyMap Samba SkyT
+
+cxxextlibs:  FitsIOServer IFFTW LinAlg XAstroPack
+
+#--- Create directory and copy includes for install
+depend:
+ifdef DPCDEVREP
+ifdef EROSCXX
+	@echo "Sophya will be installed under:"
+	@echo "  $(DPCDEVREP)/Include" 
+	@echo "  $(DPCDEVREP)/`uname`-$(EROSCXX)" 
+	if [ -d Mgr ] ; then cd Mgr; \
+	./crerep_sophya $(DPCDEVREP) `uname`-$(EROSCXX); \
+	./makefileuser.csh; \
+	./mkmflien -copy ; \
+	fi
+else
+	@echo "Variable EROSCXX must be define with setenv"
+endif
+else
+	@echo "Variable DPCDEVREP must be define with setenv"
+endif
+#--------------------------------------------------------------------
+
+.PHONY:  BaseTools
+BaseTools:
+	if [ -d BaseTools ] ; then cd  BaseTools ; $(MAKE) ; fi
+
+.PHONY:  SysTools
+SysTools:
+	if [ -d SysTools ] ; then cd  SysTools ; $(MAKE) ; fi
+
+.PHONY:  SUtils
+SUtils:
+	if [ -d SUtils ] ; then cd  SUtils ; $(MAKE) ; fi
+ 
+.PHONY:  TArray
+TArray:
+	if [ -d TArray ] ; then cd  TArray ; $(MAKE) ; fi
+ 
+.PHONY:  NTools
+NTools:
+	if [ -d NTools ] ; then cd  NTools ; $(MAKE) ; fi
+ 
+.PHONY:  HiStats
+HiStats:
+	if [ -d HiStats ] ; then cd  HiStats ; $(MAKE) ; fi
+ 
+.PHONY:  SkyMap
+SkyMap:
+	if [ -d SkyMap ] ; then cd  SkyMap ; $(MAKE) ; fi
+ 
+.PHONY:  Samba
+Samba:
+	if [ -d Samba ] ; then cd  Samba ; $(MAKE) ; fi
+ 
+.PHONY:  SkyT
+SkyT:
+	if [ -d SkyT ] ; then cd  SkyT ; $(MAKE) ; fi
+ 
+.PHONY:  FitsIOServer
+FitsIOServer:
+	if [ -d FitsIOServer ] ; then cd  FitsIOServer ; $(MAKE) ; fi
+ 
+.PHONY:  IFFTW
+IFFTW:
+	if [ -d IFFTW ] ; then cd  IFFTW ; $(MAKE) ; fi
+ 
+.PHONY:  LinAlg
+LinAlg:
+	if [ -d LinAlg ] ; then cd  LinAlg ; $(MAKE) ; fi
+ 
+.PHONY:  XAstroPack
+XAstroPack:
+	if [ -d XAstroPack ] ; then cd  XAstroPack ; $(MAKE) ; fi
+ 
+.PHONY: PI
+PI:
+	if [ -d PI ] ; then cd PI ; $(MAKE) ; fi
+	if [ -d PIGcont ] ; then cd PIGcont ; $(MAKE) ; fi
+	if [ -d PIext ] ; then cd PIext ; $(MAKE) ; fi
+#  Shared library creation part of the Makefile
+ 
+#  List of libraries (.a)
+PSLB =  $(LIB)libBaseTools.a $(LIB)libSysTools.a $(LIB)libSUtils.a $(LIB)libTArray.a $(LIB)libNTools.a $(LIB)libHiStats.a $(LIB)libSkyMap.a $(LIB)libSamba.a $(LIB)libSkyT.a
+EXTPSLB =  $(LIB)libFitsIOServer.a $(LIB)libIFFTW.a $(LIB)libLinAlg.a $(LIB)libXAstroPack.a
+PIPSLB =  $(LIB)libPI.a $(LIB)libPIGcont.a $(LIB)libPIext.a
+
+#  List of external library references
+EXTLIBL  = -L$(EXTLIBPATH) -lcfitsio -lfftw -lrfftw -lxastro
+EXTSLBL  = -L$(EXTSLBPATH) -lcfitsio -lfftw -lrfftw -lxastro
+
+# defining the other external libraries needed on different systems
+
+# On Linux   lapack and blas and f2c/g2c ere needed
+ifeq ($(MACHEROS),Linux)
+#EXTLIB = $(EXTLIBL) -llapack -lblas -lf2c
+#EXTSLB = $(EXTSLBL) -llapack -lblas -lf2c
+EXTLIB = $(EXTLIBL) -llapack -lblas -lg2c
+EXTSLB = $(EXTSLBL) -llapack -lblas -lg2c
+endif
+
+# On OSF1 libdxml contains Lapack, but the fortran support library is needed
+ifeq ($(MACHEROS),OSF1)
+EXTLIB = $(EXTLIBL) -ldxml -lfor
+EXTSLB = $(EXTSLBL) -ldxml -lfor
+endif
+
+# On IRIX , complib.sgimath contains Lapack
+ifeq ($(MACHEROS),IRIX64)
+EXTLIB = $(EXTLIBL) -lcomplib.sgimath 
+EXTSLB = $(EXTSLBL) -lcomplib.sgimath 
+endif
+
+
+
+XPILIBS = $(LIBXPIPATH) $(LIBXPILIST)
+
+#  main dependence list
+slball : slb slbext slbpi 
+slb : $(SLB)libsophya.so 
+slbext : $(SLB)libextsophya.so   
+slbpi : $(SLB)libPI.so
+ 
+# List of .o files for each module
+OBJBaseTools = $(shell echo `cat ./BaseTools/objlist.list `)
+OBJSysTools = $(shell echo `cat ./SysTools/objlist.list `)
+OBJSUtils = $(shell echo `cat ./SUtils/objlist.list `)
+OBJTArray = $(shell echo `cat ./TArray/objlist.list `)
+OBJNTools = $(shell echo `cat ./NTools/objlist.list `)
+OBJHiStats = $(shell echo `cat ./HiStats/objlist.list `)
+OBJSkyMap = $(shell echo `cat ./SkyMap/objlist.list `)
+OBJSamba = $(shell echo `cat ./Samba/objlist.list `)
+OBJSkyT = $(shell echo `cat ./SkyT/objlist.list `)
+ALLOBJS = $(OBJBaseTools) $(OBJSysTools) $(OBJSUtils) $(OBJTArray) $(OBJNTools) $(OBJHiStats) $(OBJSkyMap) $(OBJSamba) $(OBJSkyT)
+ 
+# List of .o files modules with reference to external libraries
+OBJFitsIOServer = $(shell echo `cat ./FitsIOServer/objlist.list `)
+OBJIFFTW = $(shell echo `cat ./IFFTW/objlist.list `)
+OBJLinAlg = $(shell echo `cat ./LinAlg/objlist.list `)
+OBJXAstroPack = $(shell echo `cat ./XAstroPack/objlist.list `)
+ALLEXTOBJS = $(OBJFitsIOServer) $(OBJIFFTW) $(OBJLinAlg) $(OBJXAstroPack)
+
+# List of .o files for PI modules 
+OBJPI = $(shell echo `cat ./PI/objlist.list `)
+OBJPIGcont = $(shell echo `cat ./PIGcont/objlist.list `)
+OBJPIext = $(shell echo `cat ./PIext/objlist.list `)
+ALLPIOBJS = $(OBJPI) $(OBJPIGcont) $(OBJPIext) 
+ 
+# Building Sophya shared library
+$(SLB)libsophya.so : $(PSLB)
+	$(CMDTILSHL) 
+	cd  $(OBJ); \
+	$(CMDSHLCXX) -o $(SLB)libsophya.so  \
+	$(FGSHLACXX) $(ALLOBJS)  $(FGSHLNCXX)\
+	-L$(SLB) $(LIBLSHL)
+ 
+# Building ExtSophya shared library
+$(SLB)libextsophya.so : $(EXTPSLB)
+	$(CMDTILSHL) 
+	cd  $(OBJ); \
+	$(CMDSHLCXX) -o $(SLB)libextsophya.so  \
+	$(FGSHLACXX) $(ALLEXTOBJS)  $(FGSHLNCXX)\
+	-L$(SLB) -lsophya $(EXTLIB) $(LIBLSHL)
+ 
+# Building PI shared library
+$(SLB)libPI.so : $(PIPSLB)
+	$(CMDTILSHL) 
+	cd  $(OBJ); \
+	$(CMDSHLCXX) -o $(SLB)libPI.so  \
+	$(FGSHLACXX) $(ALLPIOBJS) $(FGSHLNCXX) \
+	-L$(SLB) -lsophya -lextsophya $(EXTLIB) $(XPILIBS) $(LIBLSHL)
+ 
+
+clean:
+	if [ -d $(LIB) ] ; then cd $(LIB)/. ; rm -f *.a  ; fi
+	if [ -d $(SLB) ] ; then cd $(SLB)/. ; rm -f *.so ; fi
+	if [ -d $(OBJ) ] ; then cd $(OBJ)/. ; rm -f *.o  rm -rf cxxrep* ; fi
+#	if [ -d PI ]     ; then cd PI/.     ; $(MAKE) clean ; fi
+
Index: /tags/V_Dec2002/SophyaLib/Mgr/Makefile.am
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/Makefile.am	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/Makefile.am	(revision 2309)
@@ -0,0 +1,2 @@
+SUBDIRS = include BaseTools SysTools SUtils TArray HiStats NTools SkyMap Samba SkyT
+
Index: /tags/V_Dec2002/SophyaLib/Mgr/Makefile.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/Makefile.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/Makefile.h	(revision 2309)
@@ -0,0 +1,425 @@
+#  -*- makefile -*-
+# #########################  Sophya ############################# 
+# ##### LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA #####
+# ############################################################### 
+# General setup GNU Makefile for Sopyha/Planck. To be included in all makefiles.  
+# Define  makefile variables according to CPU 
+# MACHEROSD = `uname | sed 's/-//'`   i.e. { AIX HPUX OSF1 Linux ... }
+# and compilers {g++, cxx, KCC, xlC, aCC, ...}
+# 
+# Makefile variables set are:
+# - Path to Exec, Include, Libs, Obj directories (from DPCDEVREP env. var.)
+#     i.e. variables LIB, OBJ, EXE, INC 
+#---------------------------------------------------------------------------
+
+# define MACHEROS from uname
+MACHEROS := $(shell echo `uname`)
+# define the -D option
+MACHEROSD := $(shell echo `uname | sed 's/-//'`)
+# Le sous-repertoire des objets specifique machine-compilo
+#   OSF1 : Alpha avec gcc
+#   OSF1-cxx : Alpha avec cxx
+
+#### C++
+ifdef EROSCXX
+  CXX := $(EROSCXX)
+endif
+
+ifeq ($(CXX),gcc)
+  override CXX := g++
+endif
+
+ifeq ($(EROSCXX),egcs++)
+  # en fait de compilo de egcs++ s'appelle g++ !
+  # comme il faut bien differentier ln -s /usr/bin/g++ /usr/bin/egcs++
+  override CXX := egcs++
+endif
+
+ifeq ($(CC),xlC)
+  override CXX := xlC
+endif
+
+#### C
+ifeq ($(CXX), xlC)
+  override CC := xlC
+endif
+
+ifeq ($(CXX), g++)
+  CC := gcc
+endif
+
+ifeq ($(EROSCXX), egcs++)
+  CC := egcs
+endif
+
+#### Fortran (tout ce qui est lie au Fortran est defini ici #############
+FC = f77
+ifeq (${MACHEROS},Linux)
+#  override FC := f77
+  override FC := g77
+endif
+
+ifeq (${MACHEROS},OSF1)
+  LIBFORT = -lfor -lFutil -lots -lUfor
+endif
+ifeq (${MACHEROS},Linux)
+  #LIBFORT = -lf2c
+  LIBFORT = -lg2c
+endif
+#########################################################################
+
+
+MACHDIR := $(MACHEROS)-$(CXX)
+
+
+#-
+#-   Define Makefile paths
+#-  (NE PAS TOUCHER CES LIGNES: generation automatique de MakefileUser.h)
+#-  
+PP  := ${DPCDEVREP}/${MACHDIR}/
+LIB := ${PP}/Libs/
+SLB := ${PP}/ShLibs/
+OBJ := ${PP}/Objs/
+EXE := ${PP}/Exec/
+INC := ${DPCDEVREP}/Include/
+GLB := /usr/local/lib/
+#--
+
+#  Si Makefile.h utilise pour la construction d'autres librairies
+ifdef MYBUILDDEVREP
+  MYPP := ${MYBUILDDEVREP}/${MACHDIR}/
+  MYLIB := ${MYPP}/Libs/
+  MYSLB := ${MYPP}/ShLibs/
+  OBJ := ${MYPP}/Objs/
+  EXE := ${MYPP}/Exec/  
+endif
+
+#-   Flag for optimisation/ debug
+# Pour forcer sans debug, DBGFLAG = -g0
+ifndef OPTFLAG
+  OPTFLAG  := -O
+endif
+
+ifndef DBGFLAG
+  DBGFLAG  := -g
+#  Probleme sur DEC/OSF1 -g avec g++/egcs pose probleme a l'assembleur
+#                    Reza 09/99 - On met -gcoff
+  ifeq (${MACHEROS},OSF1)
+    ifeq ($(CXX), g++)
+      override DBGFLAG := -gcoff
+    endif
+  endif
+endif
+
+# DBGFLAG a -g0 veut dire pas de debug. Tout le monde a ca par defaut...
+ifeq ($(DBGFLAG), -g0)
+  override DBGFLAG :=
+endif
+
+# xlC ne connait pas -O0, par defaut il n'optimise pas.
+ifeq ($(OPTFLAG), -O0)
+  ifeq ($(CC), xlC)
+    override OPTFLAG :=
+  endif
+endif
+
+AR       := ar
+ARFLAGS  := -rcs
+ARARGS   := ?
+
+# le gnu ar ne fonctionne pas bien sur OSF...
+ifeq (${MACHEROS},OSF1)
+AR       := /usr/bin/ar
+endif
+# et sur AIX il nous sort des tas de warnings inutiles
+ifeq ($(MACHEROS),AIX)
+AR := /usr/bin/ar
+endif
+
+ifeq ($(MACHEROS),Darwin)
+AR := libtool
+ARFLAGS := -static -o
+ARARGS := ^
+EROSCXX := g++
+CXX := g++
+CC := cc
+endif
+
+#   Avec certains compilateurs C++ (KCC, aCC) , il faut fabriquer les librairies et 
+# les shared libs avec la meme commande 
+override ARCXX := $(AR) 
+override ARCXXFLAGS := $(ARFLAGS) 
+#RZ0999 ifeq ($(CXX),KCC)
+#RZ0999 override  ARCXX  := KCC
+#RZ0999 override ARCXXFLAGS  := -o
+#RZ0999 endif
+ifeq ($(CXX),aCC)
+override ARCXX  := aCC 
+override ARCXXFLAGS  := -o
+endif
+
+# Les chemins speciaux pour includes systemes et bibliotheques
+ifeq (${MACHEROS},HP-UX)
+  XLDLIBS := -L.
+  XCFLAGS := -I.
+endif
+
+
+#  Pour compiler PI, sous Linux, les includes et libs se trouve souvent ds /usr/X11/include /usr/X11/lib/
+ifeq (${MACHEROS},Linux)
+  XLDLIBS := -L/usr/X11/lib -L/usr/X11R6/lib
+  XCFLAGS := -I/usr/X11/include -I/usr/X11R6/include
+  LDLIBS := -ldl
+endif
+
+ifeq (${MACHEROS},Darwin)
+  XLDLIBS := -L/usr/X11R6/lib -L/sw/lib -ldl
+  XCFLAGS := -I/usr/X11R6/include -I/sw/include -fno-coalesce -fkeep-inline-functions -fno-common
+endif
+
+# Chemin pour les include et fichiers d'autres librairies
+EXTINCPI := 
+EXTLIBPL := 
+EXTSLBPL := 
+EXTINCPATH := 
+EXTLIBPATH := 
+EXTSLBPATH := 
+
+ifdef EXTLIBDIR
+ EXTINCPI := -I$(EXTLIBDIR)/Include/
+ EXTLIBPL := -L$(EXTLIBDIR)/$(MACHDIR)/Libs/
+ EXTSLBPL := -L$(EXTLIBDIR)/$(MACHDIR)/ShLibs/
+ EXTINCPATH := $(EXTLIBDIR)/Include/
+ EXTLIBPATH := $(EXTLIBDIR)/$(MACHDIR)/Libs/
+ EXTSLBPATH := $(EXTLIBDIR)/$(MACHDIR)/ShLibs/
+endif
+
+#  S'il y a des flags particulier pour un module de compilation
+#ifndef MODULECPPFLAGS
+  override MODULECPPFLAGS :=
+#endif
+
+CPPFLAGS     :=  -I${INC} $(EXTINCPI) -D${MACHEROSD} $(MODULECPPFLAGS)
+
+#  Si la variable d'environnement SOPHYA_DEBUG est definie : Activation des 
+#  compilations conditionnelles pour le debug/bound-checking/... ds le code
+ifdef SOPHYA_DEBUG 
+  CPPFLAGS   := $(CPPFLAGS) -DSOPHYA_DEBUG
+endif
+
+# Les options selon les divers compilateurs
+# GNU
+ifeq ($(CC), gcc)
+  CFLAGS       := -Wall -Wpointer-arith \
+                  -Wmissing-prototypes -Wsynth -I$(INC) $(XCFLAGS) \
+                  $(OPTFLAG) $(DBGFLAG) $(MYCFLAGS)
+  LDLIBS       := $(LDLIBS) $(XLDLIBS)
+endif
+ifeq ($(CC), egcs)
+  CFLAGS       := -Wall -Wpointer-arith \
+                  -Wmissing-prototypes -Wsynth -I$(INC) $(XCFLAGS) \
+                  $(OPTFLAG) $(DBGFLAG) $(MYCFLAGS)
+  LDLIBS       := $(LDLIBS) $(XLDLIBS)
+endif
+
+ifeq ($(CXX), g++)
+  CXXFLAGS       := -Wall -Wpointer-arith \
+                    -Wmissing-prototypes -Wsynth -I$(INC) $(XCFLAGS) \
+                    $(OPTFLAG) $(DBGFLAG) $(MYCFLAGS) 
+  LDLIBS      := $(LDLIBS) $(XLDLIBS)
+#  ifdef NOSHLIB 
+#    LDFLAGS := -static
+#  endif
+endif
+ifeq ($(CXX), egcs++)
+  CXXFLAGS       := -Wall -Wpointer-arith \
+                    -Wmissing-prototypes -Wsynth -I$(INC) $(XCFLAGS) \
+                    $(OPTFLAG) $(DBGFLAG) $(MYCFLAGS) 
+  LDLIBS      := $(LDLIBS) $(XLDLIBS)
+  ifdef NOSHLIB 
+    LDFLAGS := -static
+  endif
+endif
+
+# Compilateur natif (GNU-gcc) sous MacOSX (Darwin)
+ifeq (${MACHEROS},Darwin)
+  CFLAGS       := -Wall -Wpointer-arith \
+                  -Wmissing-prototypes -Wsynth -I$(INC) $(XCFLAGS) \
+                  $(OPTFLAG) $(DBGFLAG) $(MYCFLAGS)
+  LDLIBS       := $(LDLIBS) $(XLDLIBS)
+endif
+
+# Compilateur C natif HP-UX
+ifeq (${MACHEROS},HP-UX)
+ifeq ($(CC),cc)                                    
+  CFLAGS       :=  +Z -Aa -Ae $(XCFLAGS) $(OPTFLAG) $(DBGFLAG) $(MYCFLAGS) 
+  FFLAGS       :=  -Aa -I${INC}   -D${MACHEROSD}  
+  CPPFLAGS     :=  -I${INC}  -I$(INC)/tnt -D${MACHEROSD} \
+               -D_HPUX_SOURCE $(MODULECPPFLAGS)
+  LDLIBS      := $(XLDLIBS)
+  override NOSHLIB := Y
+
+endif
+ifeq ($(CXX),aCC)
+  CXXFLAGS := $(XCFLAGS) $(OPTFLAG) $(DBGFLAG) $(MYCFLAGS) +Z -D__aCC__
+#  -DCOMPILER_EXCEPTIONS -D__ANSI_TEMPLATES__  definis ds defs.h
+endif
+endif
+
+# AIX, xlC comme compilateur C et C++
+ifeq ($(CXX), xlC)
+  CFLAGS := $(OPTFLAG) $(DBGFLAG) $(MYCFLAGS) $(XCFLAGS)
+  CPPFLAGS := -I$(INC)/Syst -I${INC}  -I$(INC)/tnt -D${MACHEROSD} $(MODULECPPFLAGS)
+  CXXFLAGS     := $(CFLAGS) -D__xlC 
+# -DCOMPILER_EXCEPTIONS defini ds defs.h
+  LDLIBS      := $(XLDLIBS)
+
+# Pour faire des bibliotheques partagees, il faut faire un truc du
+# style 
+#ld -o shrsub.o subs1.o subs2.o -bE:shrsub.exp -bM:SRE -lc
+
+# Pour le moment on ne se fatigue pas, tant pis
+  override NOSHLIB := Y
+
+# Et puis 1540-293: (W) est un FAUX warning, on supprime les warnings
+  CXXFLAGS := -qflag=e $(CXXFLAGS)
+endif
+
+
+ifeq ($(CXX), cxx)
+  ifeq ($(DBGFLAG), -g)
+    ifdef OPTFLAG
+      override DBGFLAG := -g1
+    endif
+#    ifdef XOPT
+#      override DBGFLAG := -g1
+#    endif
+  endif
+
+# chemin pour repository CXX
+ REP := $(OBJ)/cxxrep/
+ REPPI := $(OBJ)/cxxrep_PI/
+ REPCXX := -ptr $(OBJ)/cxxrep/
+ ifdef MODULECXXREPNAME
+   REPCXX := -ptr $(OBJ)/cxxrep_$(MODULECXXREPNAME)/  -ptr $(OBJ)/cxxrep/
+   REPM := $(OBJ)/cxxrep_$(MODULECXXREPNAME)/
+ endif
+
+  LDLIBS      := $(XLDLIBS) -lrt
+
+  CXXFLAGS := $(OPTFLAG) $(DBGFLAG) $(MYCFLAGS)   \
+              $(REPCXX) -no_implicit_include 
+# $(REPCXX) -no_implicit_include -D__USE_STD_IOSTREAM  passe pas avec cxx 6.0 Reza 23/12/99
+  CFLAGS := $(OPTFLAG) $(DBGFLAG) $(MYCFLAGS)
+#  CXXFLAGS := $(OPTFLAG) $(DBGFLAG) $(MYCFLAGS)  \
+#	      -nopt -define_templates
+  ifeq ($(XOPT), 1)
+    override DBGFLAG :=
+    CXXFLAGS := $(DBGFLAG) $(MYCFLAGS)  \
+	        $(REPCXX) -fp_reorder \
+	        -O5 -inline speed -tune host
+  endif
+  ifeq ($(XOPT), 2)
+    override DBGFLAG :=
+    CXXFLAGS := $(DBGFLAG) $(MYCFLAGS)  \
+	      $(REPCXX) -fp_reorder \
+	      -O5 -inline speed -tune host \
+	      -assume trusted_short_alignment
+  endif
+  ifeq ($(XOPT), 3)
+    override DBGFLAG :=
+    CXXFLAGS := $(DBGFLAG) $(MYCFLAGS)  \
+	      $(REPCXX) -fp_reorder \
+	      -O5 -inline speed -tune host \
+	      -assume trusted_short_alignment \
+	      -non_shared -om
+    override NOSHLIB := Y
+  endif
+
+# le fichier X11/Xlib.h contient des declarations de fonctions sans type
+# Cela genere un grand nombre de warning avec cxx V6
+# La variable MODULEDECCXXFLAGS permet de specifier des options de compilation 
+# pour un module donne  
+  ifdef MODULEDECCXXFLAGS
+    CXXFLAGS := $(CXXFLAGS) $(MODULEDECCXXFLAGS)
+  endif
+endif
+ifeq ($(CC),cc)
+  ifeq ($(MACHEROS),OSF1)
+  ifeq ($(XOPT), 1)
+    CFLAGS :=  $(DBGFLAG) $(MYCFLAGS) -fp_reorder \
+	      -O4 -inline speed -tune host
+  endif
+  ifeq ($(XOPT), 2)
+    CFLAGS :=  $(DBGFLAG) $(MYCFLAGS) -fp_reorder \
+	      -O4 -inline speed -tune host \
+	      -assume trusted_short_alignment -fast
+  endif
+  ifeq ($(XOPT), 3)
+    CFLAGS :=  $(DBGFLAG) $(MYCFLAGS) -fp_reorder \
+	      -O4 -inline speed -tune host \
+	      -assume trusted_short_alignment -fast \
+	      -non_shared -om
+  endif
+  endif
+endif
+
+# --- Compilateur KAI  (OK pour v 3.3)
+ifeq ($(CXX), KCC)
+  CXXFLAGS     :=  --exceptions --rtti  --auto_instantiation --one_instantiation_per_object -D__KCC__
+  CXXFLAGS  := $(CXXFLAGS) $(OPTFLAG) $(DBGFLAG) $(MYCFLAGS)
+  CFLAGS := $(OPTFLAG) $(DBGFLAG) $(MYCFLAGS)
+# Flag --one_instantiation_per_object mis - Reza 02/03/99
+endif
+
+# --- Systeme IRIX64 de Silixon Graphics (SGI) 
+ifeq ($(MACHEROS), IRIX64)
+# --- Compilateur natif CC de SGI 
+  ifeq ($(CXX), CC)
+    CFLAGS  := $(OPTFLAG) $(DBGFLAG) $(MYCFLAGS) 
+    CXXFLAGS := -prelink -D__SGICC__ $(OPTFLAG) $(DBGFLAG) $(MYCFLAGS)
+    LINK.cc := CC $(CPPFLAGS) -D__SGICC__ $(DBGFLAG) $(OPTFLAG)
+#  sur SGI, les libs/executables ont deux formats 32 et 64 bits (trois avec o32)
+#  -n32 Generates a (new) 32-bit object default to -mips3 if -mips4 has not been specified
+#  -64 Generates a 64-bit object - defaults to -mips4 if -mips3 has not been specified
+#  La variable d'environnement SOPHYA_SGI64 controle cette option
+    ifdef SOPHYA_SGI64
+      CFLAGS  := -64 -DSGI_ARCH64 $(OPTFLAG) $(DBGFLAG) $(MYCFLAGS) 
+      CXXFLAGS := -64 -prelink -DSGI_ARCH64 -D__SGICC__ $(OPTFLAG) $(DBGFLAG) $(MYCFLAGS)
+      LINK.cc := CC -64 $(CPPFLAGS) -D__SGICC__ $(DBGFLAG) $(OPTFLAG)
+    endif
+  endif
+  ifeq ($(CXX), g++)
+    ifdef SOPHYA_SGI64
+      CFLAGS  := $(CFLAGS) -DSGI_ARCH64 -mips4 -mlong64 -mfp64 -mgp64 -mabi=64
+      CXXFLAGS := $(CXXFLAGS) -DSGI_ARCH64 -mips4 -mlong64 -mfp64 -mgp64 -mabi=64
+      LINK.cc := $(LINK.cc) -DSGI_ARCH64 -mips4 -mlong64 -mfp64 -mgp64 -mabi=64
+    endif
+  endif
+endif
+
+# Autres compilateurs natifs.
+
+#  CFLAGS       :=  -I$(INC) $(XCFLAGS) $(OPTFLAG) $(DBGFLAG) $(MYCFLAGS)
+#  CXXFLAGS     := $(CFLAGS)
+#  LDLIBS      := $(XLDLIBS)
+
+#- redefine implicit rule. Les .o sont dans $(OBJ).
+$(OBJ)%.o:%.c
+	$(COMPILE.c) -o $@ $<
+
+$(OBJ)%.o:%.cc
+	$(COMPILE.cc) -o $@ $<
+
+$(OBJ)%.o:%.f
+	$(COMPILE.f) -o $@ $< 
+
+#OSF1
+#LDFC est f77
+#LDFCFLAGS est rien
+
+#parfois
+#LDFC est cc
+#LDFCFLAGS est -ltruc
+
+#------------------------------------------------- End of Makefile.h ------- 
Index: /tags/V_Dec2002/SophyaLib/Mgr/Makefile.slb
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/Makefile.slb	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/Makefile.slb	(revision 2309)
@@ -0,0 +1,136 @@
+#  -*- makefile -*-
+# #########################  Sophya ############################# 
+# ##### LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA #####
+# ############################################################### 
+# General setup GNU Makefile for Sopyha/Planck. To be included 
+# for building shared libraries
+#---------------------------------------------------------------------------
+
+#  Chemin des librairies Motifs / X11 (pour chemin non standard)
+LIBXPIPATH :=
+# et liste des librairies pour PI (X11, Motif) 
+LIBXPILIST := -lXm -lXt -lX11
+
+# librairie compilateur GNU (g++)
+LIBGPP := -L$(GLB) -lstdc++
+#ifeq ($(HOSTTYPE), powerpc)
+#  LIBGPP := -L$(GLB)
+#endif
+ifeq ($(MACHEROS), Darwin)
+  LIBGPP := -L/sw/lib -ldl -L/usr/lib/gcc/darwin/default -lstdc++ -lcc_dynamic
+endif
+
+#  External libraries
+EXTLIB := 
+EXTSLB := 
+
+#  Commande de construction de shared-lib 
+CMDSHL := ld -partage
+#  Flag d'inclusion/fin d'inclusion de tous les points  d'entree
+FGSHLA := -tout
+FGSHLN := -rien
+#  Librairies specifiques 
+LIBLSHL := -lpthread -lm -lc
+#  Librairie d'instanciation des templates 
+TILSHL := 
+TILSHLPI := 
+#   Commande de construction de la librairie d'instanciation des templates 
+CMDTILSHL := echo 'No Template instanciation library (.a)'
+CMDTILSHLPI  := echo 'No Template instanciation library (.a)'
+# Utilisation du compilo C++ comme driver pour fabrication des shared-libs
+CMDSHLCXX := $(LINK.cc) 
+FGSHLACXX :=  
+FGSHLNCXX := 
+#  S'il faut utiliser $(CMDSHLCXX) pour fabrication des shared-libs
+USECXX4SO := Y
+# On utilise le compilo g++ pour la fabrication des shared libs
+ifeq ($(EROSCXX), g++)
+  override USECXX4SO := Y
+  override CMDSHLCXX := $(LINK.cc) -shared
+  override LIBLSHL := $(LIBGPP) $(LIBLSHL)
+endif
+
+# On utilise le compilo KCC pour la fabrication des shared libs
+ifeq ($(EROSCXX), KCC)
+  override USECXX4SO := Y
+  override CMDSHLCXX := $(LINK.cc)
+endif
+
+# On utilise le compilo aCC (HP) pour la fabrication des shared libs
+ifeq ($(EROSCXX), aCC)
+  override USECXX4SO := Y
+  override CMDSHLCXX := $(LINK.cc) -b
+endif
+
+# Construction de shared-libs sous OSF1
+ifeq ($(MACHEROS),OSF1)
+  override CMDSHL := ld -shared -update_registry $(SLB)so_locations
+  override FGSHLA := -all
+  override FGSHLN := -none 
+#  override LIBLSHL := -lcxxstd -lcxx -lexc -lm -lc -lrt
+  override LIBLSHL := $(LIBLSHL) -lrt
+  override TILSHL := $(LIB)libertcxx.a
+  override CMDTILSHL := rm -f $(LIB)libsotcxx.a ; cd $(REP); $(AR) $(ARFLAGS) $(LIB)libsotcxx.a *.o
+  override TILSHLPI := $(LIB)libsotcxxpi.a
+  override CMDTILSHLPI := rm -f $(LIB)libsotcxxpi.a ; cd $(REPPI); $(AR) $(ARFLAGS) $(LIB)libsotcxxpi.a *.o
+  ifeq ($(CXX),g++)
+    override TILSHL := 
+    override TILSHLPI := 
+  endif
+#  Attention - Dangereux de mettre -expect_unresolved , enleve  Reza 17/11/99
+  override CMDSHLCXX :=  $(CXX) $(CXXFLAGS) -shared 
+  override FGSHLACXX := 
+  override FGSHLNCXX := 
+  override USECXX4SO := Y
+endif
+
+# Construction de shared-libs sous Linux
+ifeq ($(MACHEROS),Linux)
+  override CMDSHL := ld -shared 
+  override FGSHLA := --whole-archive
+  override FGSHLN := --no-whole-archiv
+  override CMDSHLCXX := $(LINK.cc) -shared 
+  ifeq ($(EROSCXX), KCC)
+    override CMDSHLCXX := $(LINK.cc)
+  endif
+  override FGSHLACXX := 
+  override FGSHLNCXX := 
+  override LIBLSHL := $(LIBLSHL) -ldl
+  override TILSHL := 
+  override LIBXPIPATH := -L/usr/X11/lib -L/usr/X11R6/lib
+  override LIBXPILIST := -lXm -lXt -lXext -lX11
+endif
+
+# Construction de shared-libs sous Sun-OS
+ifeq ($(MACHEROS),SunOS)
+  override CMDSHL := ld -G
+  override FGSHLA := -z allextract
+  override FGSHLN := -z weakextract
+  override TILSHL := 
+  override LIBXPIPATH := -L/usr/X11/lib 
+  override USECXX4SO := Y
+endif
+
+# Construction de shared-libs sous SGI
+ifeq ($(MACHEROS), IRIX64)
+  override CMDSHL := ld -shared
+  override FGSHLA := -all
+  override FGSHLN := -notall
+  override TILSHL := 
+  ifeq ($(EROSCXX), CC)
+    override CMDSHLCXX := CC -shared 
+  endif
+  override LIBXPIPATH := -L/usr/X11/lib 
+  override USECXX4SO := Y
+endif
+
+# Construction de shared-libs sous OSX
+ifeq ($(MACHEROS), Darwin)
+  override CMDSHL := libtool -dynamic
+  override FGSHLA :=
+  override FGSHLN :=
+  override TILSHL :=
+  override CMDSHLCXX := libtool -dynamic
+endif
+
+
Index: /tags/V_Dec2002/SophyaLib/Mgr/Makefile_include.am
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/Makefile_include.am	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/Makefile_include.am	(revision 2309)
@@ -0,0 +1,1 @@
+all:
Index: /tags/V_Dec2002/SophyaLib/Mgr/PIlibdirs
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/PIlibdirs	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/PIlibdirs	(revision 2309)
@@ -0,0 +1,3 @@
+PI
+PIGcont
+PIext
Index: /tags/V_Dec2002/SophyaLib/Mgr/README
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/README	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/README	(revision 2309)
@@ -0,0 +1,215 @@
+========================== Mgr Module =========================
+============= Code Management scripts for SOPHYA ==============
+===============================================================
+
+List of modules:
+==================
+
+* Mgr/           Scripts for code management and makefiles
+* BaseTools/     General architecture support classes
+* SysTools/      Interface to various services provided by the operating system
+* SUtils/        Utility classes and functions
+* TArray/        Template numerical arrays, vectors and matrices
+* SkyMap/        Local and full sky maps
+* SkyT/          Spectral emission and detector frequency response modelling   
+* Samba/         Miscellaneous classes (TOD analysis, Spherical Harmonics, ...)
+* NTools/        Some standard numerical analysis tools 
+* HiStats/       Histogram-ming and data set handling classes
+
+Modules using external library 
+* FitsIOServer/  FITS format file I/O (interface with cfitsio library)
+* LinAlg/        Interface with Lapack linear algebra package
+* IFFTW/         Interface with FFTW package
+* XAstroPack/    Interface with astronomy library (XEphem)
+                 The XEphem library code is in the SOPHYA module XephemAstroLib
+
+* XephemAstroLib/ The code of the external XEphem astronomy library, extracted from XEphem
+
+Modules with main programs
+* Tests/         Simple test programs
+
+* PMixer/        skymixer and utility main programs
+
+* PrgUtil/       Utility main programs
+
+* PrgMap/        Utility main programs for sky map manipulation
+
+PI/piapp GUI and interactive analysis framework
+
+* PI/            GUI class library and application framework
+* PIGcont/       PI contour drawer
+* PIext/         specific GUI objects for SOPHYA classes and piapp framework
+* ProgPI/        interactive analysis tool using SOPHYA, PI PIGCont and PIext
+
+
+Compilation and software installation:
+======================================
+
+The build procedure for the present version of SOPHYA has been 
+tested on :
+
+Operating system            Compiler
+......................................................................
+Compaq/DEC OSF 5.1           cxx 6.3         (shared-library only)
+Compaq/DEC OSF 5.1           g++ 2.95        (shared-library only)
+SGI                          CC  7.30        (shared-library only)
+Linux                        KCC 3.4         (shared-library only)
+Linux                        g++ 2.95        (static and shared library)
+MacOSX/Darwin 10.1           c++/gcc 2.95    (shared-library only)
+
+The environment variables  DPCDEVREP EXTLIBDIR EROSCXX must be defined
+for building and installing the libraries.
+
+$EROSCXX is the name of C++ compiler being used.
+$DPCDEVREP is the path to where the libraries and executables will be put.
+$DPCDEVREP/Include : header files
+The libraries and binaries will be put in subdirectories containing 
+the operating system name and the compiler name: `uname`-$EROSCXX
+For example, on a Linux system, using the GNU compiler:
+
+$DPCDEVREP/Linux-g++/Libs     archive librarires
+$DPCDEVREP/Linux-g++/ShLibs   shared libraries
+$DPCDEVREP/Linux-g++/Exec     binaries
+
+The build procedure expects to find the include files and the libraries 
+for cfitsio in :
+$EXTLIBDIR/Include/FitsIO 
+$EXTLIBDIR/`uname`-$EROSCXX/Libs
+This would translate to Linux-g++ on a Linux system, using g++.
+$EXTLIBDIR/Linux-g++/Libs
+
+Example of c-shell commands to build the libraries:
+The use of GNU make program is mandatory 
+
+# We select our C++ compiler
+csh> setenv EROSCXX g++
+# Setup the build directory
+csh> mkdir /usr/local/Sophya/
+csh> setenv DPCDEVREP  /usr/local/Sophya/
+csh> setenv DPCBASEREP /usr/local/Sophya/
+csh> setenv EXTLIBDIR  /usr/local/ExtLibs/
+
+# --------------- Note for SGI ---------------------
+# SOPHYA can be compiled on SGI IRIX64 OS in 32 bits or 64 bit mode
+# The environment variable SOPHYA_SGI64 has to be set to select 
+# compilation in 64 bits mode
+# ---------------------------------------------------
+
+# Use the top level makefile in Mgr/ 
+csh> cd $SRC
+csh> cp Mgr/Makefile Makefile
+# Step 1: Create the directory tree and copy the include files (.h)
+csh> make depend
+# Step 2: Compile the modules without external library reference
+csh> make libs
+# Step 3: Compile the modules WITH  external library reference (optional) 
+csh> make extlibs
+# Step 4: Build libsophya.so
+csh> make slb
+# Step 5: Build libextsophya.so 
+csh> make slbext
+# Step 6: Compile the PI and PIext modules (optional)
+csh> make PI
+# Step 7: Build the corresponding shared library libPI.so (optional)
+csh> make slbpi
+
+
+To compile all modules and build the shared libraries, it is possible to use:
+
+# Step 2,3,6
+csh> make all
+# Step 4,5,7
+csh> make slball
+
+The building of shared libraries on SGI can be also done using the script 
+mkslbsgi.csh in Mgr/
+
+csh> cp Mgr/mkslbsgi.csh .
+csh> mkslbsgi.csh slball
+
+# To compile test programs
+csh> cd Tests
+csh> make arrt ...
+csh> cd ..
+# To compile other programs, for example from the PMixer module
+csh> cd PMixer
+csh> make
+csh> cd ..
+# To build (s)piapp (libPI.so is needed)
+csh> cd ProgPI
+csh> make 
+csh> cd ..
+
+Notes:
+======
+1) We had to build the shared libraries on our SGI system using the 
+script (mkslbsgi.csh). The corresponding CC command was not performing
+correctly when issued by the GNU make program
+2) The top level Makefile should be modified if one wishes to use 
+static libraries, except for g++. The compiler driver has to be 
+invoked for building archive libraries, in order to include 
+template instanciation into the archive.
+
+
+
+Scripts in Mgr/ module :
+========================
+
+* chk_cvs.csh : Compares/updates modules using CVS
+  Usage: chk_cvs.csh [-a] [-all] [-nos] [-u] [r]
+         chk_cvs.csh  -h  for help
+  Example :
+  Cmd> Mgr/chk_cvs.csh -u  
+  Updates all modules 
+
+* crerep_sophya
+  Creates the directory tree structure :
+                             $DEV/BASEREP/Include
+                                         /OSF1-cxx/
+                                         /OSF1-cxx/Objs
+                                         /OSF1-cxx/Libs
+                                         /OSF1-cxx/ShLibs
+                                         /OSF1-cxx/Exec/
+                                         ....
+  Usage: crerep_sophya <nom des repertoires> [nom_machine-compilateur]
+  Example :
+  Cmd> crerep_sophya $DPCDEVREP OSF1-cxx 
+  Cmd> crerep_sophya ~/Work/ Linux-g++
+
+* install_sophya
+  Install SOPHYA libraries/include files from dev directory ($DPCDEVREP)
+  to the install ($DPCBASEREP) directory
+  Copy files Include/*.h Libs/*.a ShLibs/*.so Exec/*
+
+  Usage: install_sophya <-s repertoire source> <-d repertoire destination>
+                      [-m nom_machine-compilateur]
+  Example 
+  Cmd> install_peida -s  ~/Work  /exp/Planck/DPC
+
+* mkmf
+  Creates a GNUmakefile in each library module and the global 
+  GNUmakefile at top level
+
+  Steps :
+  - mkmflien : Creates symbolic links for all header files in $DPCDEVREP/Include
+
+  - mkmflib : Creation of a GNUmakefile in each library module
+
+  - mkmfPI : Creation of a GNUmakefile for PI and PIext module
+
+  - Top level makefile creation
+
+
+* mkmflib 
+  Creation of the GNUmakefile for a library module
+  The file exclude in the module directory may contain the 
+  list of source files (.cc .c) not to be compiled.
+  Usage: mkmflib ModuleName
+  
+* mkmfprog
+  Creation of the GNUmakefile for a module containing 
+  the main programs 
+  Usage: mkmfprog ProgModuleName
+
+
+
Index: /tags/V_Dec2002/SophyaLib/Mgr/acconfig.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/acconfig.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/acconfig.h	(revision 2309)
@@ -0,0 +1,14 @@
+
+/* Name of C++ compiler */
+#define CXX unknown-cxx-compiler
+
+/* CPU name */
+#define HOST_CPU unknown
+
+/* Vendor name */
+#define HOST_VENDOR unknown
+
+/* OS name */
+#define HOST_OS unknown
+
+
Index: /tags/V_Dec2002/SophyaLib/Mgr/chk_cvs.csh
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/chk_cvs.csh	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/chk_cvs.csh	(revision 2309)
@@ -0,0 +1,61 @@
+#!/bin/csh
+
+unset A
+unset U
+unset NOS
+unset R
+if( "$1" == '-h' ) then
+  echo "usage chk_cvs.csh [-a] [-all] [-nos] [-u] [r]"
+  echo "    -nos : pas de cvs status demande"
+  echo "      -a   : cvs status reduit  pour tous les fichiers"
+  echo "      -all : cvs status complet pour tous les fichiers"
+  echo "    -u   : update demande"
+  echo "    -r   : chmod a+r demande"
+  exit -1
+else
+  while( $#argv>0 )
+    if( "$1" == "-a") set A = 1
+    if( "$1" == "-all") set A = 2
+    if( "$1" == "-nos") set NOS
+    if( "$1" == "-u") set U
+    if( "$1" == "-r") set R
+    shift
+  end
+endif
+if( $?U || $?R ) set NOS
+
+set fall = (`ls -1`)
+set dcvs = ( )
+foreach f ( $fall )
+  if( -e $f/CVS ) set dcvs = ( $dcvs $f )
+end
+
+set CURDIR = `pwd`
+if( $?U ) echo "attention...... UPDATE demande"
+
+foreach d ( $dcvs )
+  if (-e $CURDIR/$d)  then
+    echo " " ; echo " "
+    echo "******************************************"
+    echo "   --- $d ---" ; echo " "
+    cd $CURDIR/$d
+    if( ! $?NOS ) then
+      if( $?A ) then
+        if( $A == 1 ) then
+          cvs status | grep Status
+        else if( $A == 2 ) then
+          cvs status
+        endif
+      else
+        cvs status | grep Status | grep -v "Up-to-date"
+      endif
+    endif
+    if( $?U ) cvs update
+    if( $?R ) then
+      chmod -R a+r *
+    endif
+  endif
+end
+
+cd $CURDIR
+exit 0
Index: /tags/V_Dec2002/SophyaLib/Mgr/cleantstprg.csh
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/cleantstprg.csh	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/cleantstprg.csh	(revision 2309)
@@ -0,0 +1,18 @@
+#!/bin/csh
+set OBJREP = ${DPCDEVREP}/`uname`-$EROSCXX/Objs/
+set EXEREP = ${DPCDEVREP}/`uname`-$EROSCXX/Exec/
+echo ' ---> cleantstprg.csh: Removing Objs/$f.o , Exec/$f '
+foreach f (*.cc)
+  set fo = $OBJREP/$f:r.o
+  if (-e $fo) then 
+    set cmd = "rm -f $fo"
+    echo $cmd ; $cmd
+  endif     
+  set fe = $EXEREP/$f:r
+  if (-e $fe) then 
+    set cmd = "rm -f $fe"
+    echo $cmd ; $cmd
+  endif 
+end
+
+exit 0
Index: /tags/V_Dec2002/SophyaLib/Mgr/configure.in
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/configure.in	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/configure.in	(revision 2309)
@@ -0,0 +1,77 @@
+AC_INIT(SysTools/ctimer.h)
+AM_INIT_AUTOMAKE(Sophya, 0.9.95)
+AM_CONFIG_HEADER(config.h)
+
+dnl check if run from srcdir
+if test -f SysTools/ctimer.h; then
+  AC_MSG_ERROR("do not run configure from the distribution directory")
+fi
+
+AC_CANONICAL_HOST
+
+
+dnl Checks for programs.
+AC_PROG_CXX
+if test `uname` = "OSF1" -a $GXX = "yes" ; then
+  CXXFLAGS="${CXXFLAGS-} -gcoff"
+  export CXXFLAGS
+fi
+
+AC_PROG_CC
+AC_PROG_INSTALL
+AC_PROG_RANLIB
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_C_INLINE
+AC_TYPE_SIZE_T
+AC_C_BIGENDIAN
+AC_C_LONG_DOUBLE
+AC_CHECK_SIZEOF(short)
+AC_CHECK_SIZEOF(int)
+AC_CHECK_SIZEOF(long)
+AC_CHECK_SIZEOF(long long)
+AC_CHECK_SIZEOF(float)
+AC_CHECK_SIZEOF(double)
+
+AC_DEFINE_UNQUOTED(CXX, ${CXX} )
+AC_DEFINE_UNQUOTED(HOST_CPU, $host_cpu)
+AC_DEFINE_UNQUOTED(HOST_VENDOR, $host_vendor)
+AC_DEFINE_UNQUOTED(HOST_OS, $host_os)
+
+
+dnl Check for functions
+AC_CHECK_FUNCS(random)
+AC_CHECK_FUNCS(nice)
+
+cp $srcdir/BaseTools/machdefs_ac.h machdefs.h
+
+
+echo "building include directory..."
+
+mkdir include 2>/dev/null
+cd include
+if test -d $srcdir; then
+  incsrcdir=$srcdir
+elif test -d ../$srcdir; then
+  incsrcdir=../$srcdir
+else
+  AC_MSG_ERROR("cannot find path to source dir")
+fi
+
+
+for xdir in BaseTools SysTools SUtils TArray HiStats NTools SkyMap Samba SkyT; do
+  if test -d $incsrcdir/$xdir ; then
+     for fn in $incsrcdir/$xdir/*.h; do
+       ln -sf $fn .
+     done
+  fi
+done
+echo "done."
+cd ..
+
+AC_OUTPUT(Makefile include/Makefile BaseTools/Makefile SysTools/Makefile 
+                   SUtils/Makefile   TArray/Makefile
+                   HiStats/Makefile NTools/Makefile   SkyMap/Makefile
+                   Samba/Makefile   SkyT/Makefile)
+ 
Index: /tags/V_Dec2002/SophyaLib/Mgr/crecxx.file
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/crecxx.file	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/crecxx.file	(revision 2309)
@@ -0,0 +1,16 @@
+cimage.h
+circrfix.h
+daofind.h
+deflat.h
+dynccd.h
+fitsimage.h
+imageop.h
+killbad.h
+photfitpsf.h
+photfixedap.h
+pixeliter.h
+psf2dfit.h
+qualite.h
+rebinimage.h
+rzimage.h
+sharedimage.h
Index: /tags/V_Dec2002/SophyaLib/Mgr/crerep_sophya
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/crerep_sophya	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/crerep_sophya	(revision 2309)
@@ -0,0 +1,51 @@
+#!/bin/csh
+
+if( $#argv < 1 ) then
+  echo "crerep_sophya <nom des repertoires> [nom_machine-compilateur]"
+  echo " - ex: crerep_sophya "\$"GROUP_DIR/PeidaWork HP-UX"
+  echo " - possibilites nom_machine-compilateur"
+  echo "    [AIX-xlC AIX-g++ HP-UX-aCC HP-UX-g++ OSF1-cxx OSF1-g++ Linux-g++ ...]"
+  if($?EROSCXX) then
+    echo "    defaut: `uname`-$EROSCXX"
+  else
+    echo "    pas de defaut donnez explicitement nom_machine-compilateur"
+  endif
+  exit -1
+endif
+
+set dirl = $1
+if ( ! -e ${dirl} ) then
+  echo ATTENTION REPERTOIRE INEXISTANT:
+  echo ${dirl}
+  exit -1
+endif
+echo "rep. de base: ${dirl}"
+
+shift
+if( $#argv > 0 ) then
+  set diru = $1
+  echo "machine-compilateur: ${diru}"
+else if ($?EROSCXX) then
+  echo uname=`uname` EROSCXX = $EROSCXX
+  set diru = `uname`-$EROSCXX
+  echo "AUTOMATIQUE machine-compilateur: ${diru}"
+else
+  echo "precisez nom_machine-compilateur ou EROSCXX"
+  exit -1
+endif
+
+foreach d ( ${dirl}/${diru} \
+            ${dirl}/Include \
+            ${dirl}/${diru}/Exec \
+            ${dirl}/${diru}/Libs ${dirl}/${diru}/ShLibs \
+            ${dirl}/${diru}/Objs )
+  if ( -e $d ) then
+    echo "rep. existant: $d"
+  else
+    echo "rep. cree: $d"
+    mkdir $d
+  endif
+end
+
+exit 0
+
Index: /tags/V_Dec2002/SophyaLib/Mgr/devinstall
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/devinstall	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/devinstall	(revision 2309)
@@ -0,0 +1,15 @@
+#!/bin/csh
+
+cd ..
+ln Mgr/configure.in
+ln Mgr/Makefile.am
+ln Mgr/acconfig.h
+mkdir include
+cd include
+ln ../Mgr/Makefile_include.am Makefile.am
+cd ..
+
+autoheader
+aclocal
+automake --add-missing --foreign
+autoconf
Index: /tags/V_Dec2002/SophyaLib/Mgr/extlibdirs
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/extlibdirs	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/extlibdirs	(revision 2309)
@@ -0,0 +1,4 @@
+FitsIOServer
+IFFTW
+LinAlg
+XAstroPack
Index: /tags/V_Dec2002/SophyaLib/Mgr/history_eros
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/history_eros	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/history_eros	(revision 2309)
@@ -0,0 +1,38 @@
+Mgr from Mgr
+Mgr from Mgr
+-----------> Makefile.h
+   Nettoyage et MAJ Repository revision:	1.61
+-----------> Makefile.slb
+   Nettoyage et MAJ Repository revision:	1.26
+-----------> chk_cvs.csh
+   Repository revision:	1.2	/projects/Eros/CVSEros/CodeCxx/Mgr/chk_cvs.csh,v
+-----------> crecxx.file
+   Repository revision:	1.1	/projects/Eros/CVSEros/CodeCxx/Mgr/crecxx.file,v
+-----------> crerep_peida
+   Repository revision:	1.5	/projects/Eros/CVSEros/CodeCxx/Mgr/crerep_peida,v
+-----------> install_peida
+   Repository revision:	1.5	/projects/Eros/CVSEros/CodeCxx/Mgr/install_peida,v
+-----------> libdirs
+   Repository revision:	1.7	/projects/Eros/CVSEros/CodeCxx/Mgr/libdirs,v
+-----------> libdirs_ccpn
+   Repository revision:	1.1	/projects/Eros/CVSEros/CodeCxx/Mgr/libdirs_ccpn,v
+-----------> makefileuser.awk
+   Repository revision:	1.1	/projects/Eros/CVSEros/CodeCxx/Mgr/makefileuser.awk,v
+-----------> mkmf
+   Repository revision:	1.36	/projects/Eros/CVSEros/CodeCxx/Mgr/mkmf,v
+   MAJ                  1.39    pour flag powerpc - mais pas pour HP-UX slb (.sl)
+-----------> mkmfPI
+   Repository revision:	1.15	/projects/Eros/CVSEros/CodeCxx/Mgr/mkmfPI,v
+-----------> mkmflib
+   Repository revision:	1.11	/projects/Eros/CVSEros/CodeCxx/Mgr/mkmflib,v
+   MAJ                  1.12    $(AR) et $(ARFLAGS) -> $(ARCXX) et $(ARCXXFLAGS)
+-----------> mkmflien
+   Repository revision:	1.15	/projects/Eros/CVSEros/CodeCxx/Mgr/mkmflien,v
+-----------> mkmfprog
+   Repository revision:	1.20	/projects/Eros/CVSEros/CodeCxx/Mgr/mkmfprog,v
+-----------> mkmfprog.awk
+   Repository revision:	1.4	/projects/Eros/CVSEros/CodeCxx/Mgr/mkmfprog.awk,v
+-----------> progdirs
+   Repository revision:	1.3	/projects/Eros/CVSEros/CodeCxx/Mgr/progdirs,v
+-----------> progdirs_ccpn
+   Repository revision:	1.1	/projects/Eros/CVSEros/CodeCxx/Mgr/progdirs_ccpn,v
Index: /tags/V_Dec2002/SophyaLib/Mgr/install_sophya
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/install_sophya	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/install_sophya	(revision 2309)
@@ -0,0 +1,124 @@
+#!/bin/csh
+#  Script d'installation SOPHYA 
+#  Version preliminaire - Reza 27/11/97 +cmv
+
+if( "$1" == "-h" ) then
+  echo "install_sophya <-s repertoire source> <-d repertoire destination>"
+  echo "              [-m nom_machine-compilateur]"
+  if($?DPCDEVREP) then
+    echo " - defaut repertoire source: $DPCDEVREP"
+  else
+    echo "   pas de defaut donnez explicitement le repertoire source"
+  endif
+  if($?DPCBASEREP) then
+    echo " - defaut repertoire destination: $DPCBASEREP"
+  else
+    echo "   pas de defaut donnez explicitement le repertoire destination"
+  endif
+  echo " - possibilites nom_machine-compilateur"
+  echo "    [AIX-xlC AIX-g++ HP-UX-aCC HP-UX-g++ OSF1-cxx OSF1-g++  Linux-g++ ...]"
+  if($?EROSCXX) then
+    echo "    defaut: `uname`-$EROSCXX"
+  else
+    echo "    pas de defaut donnez explicitement nom_machine-compilateur"
+  endif
+  exit -1
+endif
+
+unset srcdir
+unset dstdir
+unset macomp
+
+while( $#argv > 1 )
+  if( "$1" == "-s" ) then
+    set srcdir = $2
+  endif
+  if( "$1" == "-d" ) then
+    set dstdir = $2
+  endif
+  if( "$1" == "-m" ) then
+    set macomp = $2
+  endif
+  shift
+  shift
+end
+
+if( ! $?srcdir && $?DPCDEVREP ) then
+  echo "defaut srcdir set to DPCDEVREP"
+  set srcdir = $DPCDEVREP
+endif
+if( ! $?dstdir && $?DPCBASEREP ) then
+  echo "defaut dstdir set to DPCBASEREP"
+  set dstdir = $DPCBASEREP
+endif
+if( ! $?macomp && $?EROSCXX ) then
+  echo "defaut macomp set to uname-EROSCXX"
+  set macomp = `uname`-$EROSCXX
+endif
+
+if( ! $?srcdir || ! $?dstdir || ! $?macomp ) then
+  echo "precisez ce que vous voulez:"
+  echo srcdir=$?srcdir dstdir=$?dstdir macomp=$?macomp
+  exit -1
+else
+  set SRC = $srcdir/$macomp
+  set DST = $dstdir/$macomp
+  echo "************** SOPHYA_Install script : ****************** "
+  echo "copie de $srcdir"
+  echo "      vers $dstdir pour $macomp"
+  echo "      pour $macomp"
+  # echo "SRC= $SRC , DST= $DST"
+  echo "********************************************************"
+endif
+
+#set DO = echo
+set DO =
+
+# d'abord les includes
+#foreach d ( Include Include/tnt Include/CInc Include/SystCxx Include/Syst )
+foreach d ( Include  Include/ArchTOI )
+  echo "SOPHYA_Install: Installing $d ... "
+  if( ! -e $srcdir/$d ) then
+    echo "rep. inexistant: $SRC/$d"
+#  else  if( ! -e $dstdir/$d ) then
+#    echo "rep. inexistant: $DST/$d"
+#    endif
+  else
+    if( ! -e $dstdir/$d ) then
+	echo "rep. inexistant: $dstdir/$d -> mkdir"
+	mkdir $dstdir/$d
+    endif
+    cd $srcdir/$d
+    $DO cp * $dstdir/$d/
+    $DO chmod -R a+r $dstdir/$d/
+  endif
+end
+
+# puis le reste
+foreach d ( Libs ShLibs Exec )
+  echo "SOPHYA_Install: Installing $d ... "
+  if( ! -e $SRC/$d ) then
+    echo "rep. inexistant: $SRC/$d"
+  else if( ! -e $DST/$d ) then
+    echo "rep. inexistant: $DST/$d"
+  else
+    if( "$d" == "Exec" ) then
+#      foreach f ( scanppf tobjio tspm tspm2 spiapp tgsky tgrsr skymixer )
+#        if( -e $SRC/$d/$f ) then
+#          $DO cp $SRC/$d/$f $DST/$d/.
+#        endif
+#      end
+      cd $SRC/$d/.
+      $DO cp * $DST/$d/.
+      $DO chmod -R a+x $DST/$d/
+    else
+      cd $SRC/$d/.
+      $DO cp * $DST/$d/.
+    endif
+    $DO chmod -R a+r $DST/$d/
+  endif
+end
+
+echo 'SOPHYA_Install complete'
+
+exit 0
Index: /tags/V_Dec2002/SophyaLib/Mgr/libdirs
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/libdirs	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/libdirs	(revision 2309)
@@ -0,0 +1,10 @@
+BaseTools
+SysTools
+SUtils
+TArray
+NTools
+HiStats
+SkyMap
+Samba
+SkyT
+SysSpec
Index: /tags/V_Dec2002/SophyaLib/Mgr/libdirs_ccpn
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/libdirs_ccpn	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/libdirs_ccpn	(revision 2309)
@@ -0,0 +1,3 @@
+Outils++
+Images++
+StarReco++
Index: /tags/V_Dec2002/SophyaLib/Mgr/lnktofftw.csh
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/lnktofftw.csh	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/lnktofftw.csh	(revision 2309)
@@ -0,0 +1,10 @@
+#! /bin/csh 
+#  Pour creer des liens sur libFFTW et creer le shared-lib correspondant
+#        Reza 04/99
+#
+cd ~/DPC/Linux-g++/Libs/
+ln -s /usr/local/lib/libfftw.a libfftw.a
+ln -s /usr/local/lib/librfftw.a librfftw.a
+ln -s /usr/local/include/fftw.h ../../Include/
+ln -s /usr/local/include/rfftw.h ../../Include/
+ld -shared -o ../ShLibs/libfftw.so -L. --whole-archive -lfftw -lrfftw --no-whole-archive -lm -lc
Index: /tags/V_Dec2002/SophyaLib/Mgr/makefile.darwin
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/makefile.darwin	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/makefile.darwin	(revision 2309)
@@ -0,0 +1,212 @@
+# include files defining compiler/linker options 
+MODULECXXREPNAME := PI
+include Mgr/Makefile.h
+include Mgr/Makefile.slb
+
+LIBF =  $(LIB)libBaseTools.a $(LIB)libSysTools.a $(LIB)libSUtils.a $(LIB)libTArray.a $(LIB)libNTools.a $(LIB)libHiStats.a $(LIB)libSkyMap.a $(LIB)libSamba.a $(LIB)libSkyT.a
+LIBS = -L$(LIB) -lBaseTools -lSysTools -lSUtils -lTArray -lNTools -lHiStats -lSkyMap -lSamba -lSkyT
+
+defaut: libs
+
+all: libs extlibs PI
+
+libs: cxxlibs
+
+extlibs: cxxextlibs
+
+cxxlibs:  BaseTools SysTools SUtils TArray NTools HiStats SkyMap Samba SkyT
+
+cxxextlibs:  FitsIOServer IFFTW LinAlg XAstroPack
+# cxxextlibs:  FitsIOServer 
+
+#--- Create directory and copy includes for install
+depend:
+ifdef DPCDEVREP
+ifdef EROSCXX
+	@echo "Sophya will be installed under:"
+	@echo "  $(DPCDEVREP)/Include" 
+	@echo "  $(DPCDEVREP)/`uname`-$(EROSCXX)" 
+	if [ -d Mgr ] ; then cd Mgr; \
+	./crerep_sophya $(DPCDEVREP) `uname`-$(EROSCXX); \
+	./makefileuser.csh; \
+	./mkmflien -copy ; \
+	fi
+else
+	@echo "Variable EROSCXX must be define with setenv"
+endif
+else
+	@echo "Variable DPCDEVREP must be define with setenv"
+endif
+#--------------------------------------------------------------------
+
+.PHONY:  BaseTools
+BaseTools:
+	if [ -d BaseTools ] ; then cd  BaseTools ; $(MAKE) ; fi
+
+.PHONY:  SysTools
+SysTools:
+	if [ -d SysTools ] ; then cd  SysTools ; $(MAKE) ; fi
+
+.PHONY:  SUtils
+SUtils:
+	if [ -d SUtils ] ; then cd  SUtils ; $(MAKE) ; fi
+ 
+.PHONY:  TArray
+TArray:
+	if [ -d TArray ] ; then cd  TArray ; $(MAKE) ; fi
+ 
+.PHONY:  NTools
+NTools:
+	if [ -d NTools ] ; then cd  NTools ; $(MAKE) ; fi
+ 
+.PHONY:  HiStats
+HiStats:
+	if [ -d HiStats ] ; then cd  HiStats ; $(MAKE) ; fi
+ 
+.PHONY:  SkyMap
+SkyMap:
+	if [ -d SkyMap ] ; then cd  SkyMap ; $(MAKE) ; fi
+ 
+.PHONY:  Samba
+Samba:
+	if [ -d Samba ] ; then cd  Samba ; $(MAKE) ; fi
+ 
+.PHONY:  SkyT
+SkyT:
+	if [ -d SkyT ] ; then cd  SkyT ; $(MAKE) ; fi
+ 
+.PHONY:  FitsIOServer
+FitsIOServer:
+	if [ -d FitsIOServer ] ; then cd  FitsIOServer ; $(MAKE) ; fi
+ 
+.PHONY:  IFFTW
+IFFTW:
+	if [ -d IFFTW ] ; then cd  IFFTW ; $(MAKE) ; fi
+ 
+.PHONY:  LinAlg
+LinAlg:
+	if [ -d LinAlg ] ; then cd  LinAlg ; $(MAKE) ; fi
+ 
+.PHONY:  XAstroPack
+XAstroPack:
+	if [ -d XAstroPack ] ; then cd  XAstroPack ; $(MAKE) ; fi
+ 
+.PHONY: PI
+PI:
+	if [ -d PI ] ; then cd PI ; $(MAKE) ; fi
+	if [ -d PIGcont ] ; then cd PIGcont ; $(MAKE) ; fi
+	if [ -d PIext ] ; then cd PIext ; $(MAKE) ; fi
+#  Shared library creation part of the Makefile
+ 
+#  List of libraries (.a)
+PSLB =  $(LIB)libBaseTools.a $(LIB)libSysTools.a $(LIB)libSUtils.a $(LIB)libTArray.a $(LIB)libNTools.a $(LIB)libHiStats.a $(LIB)libSkyMap.a $(LIB)libSamba.a $(LIB)libSkyT.a $(LIB)libSysSpec.a
+#EXTPSLB =  $(LIB)libFitsIOServer.a $(LIB)libIFFTW.a $(LIB)libLinAlg.a $(LIB)libXAstroPack.a
+EXTPSLB =  $(LIB)libFitsIOServer.a 
+PIPSLB =  $(LIB)libPIext.a $(LIB)libPI.a $(LIB)libPIGcont.a 
+
+#  List of external library references
+EXTLIBL  = -L$(EXTLIBPATH) -lcfitsio -lfftw -lrfftw -lxastro
+EXTSLBL  = -L$(EXTSLBPATH) -lcfitsio -lfftw -lrfftw -lxastro
+#EXTLIBL  = -L$(EXTLIBPATH) -lcfitsio 
+#EXTSLBL  = -L$(EXTSLBPATH) -lcfitsio 
+
+# defining the other external libraries needed on different systems
+
+# On Linux   lapack and blas and f2c/g2c ere needed
+ifeq ($(MACHEROS),Linux)
+#EXTLIB = $(EXTLIBL) -llapack -lblas -lf2c
+#EXTSLB = $(EXTSLBL) -llapack -lblas -lf2c
+EXTLIB = $(EXTLIBL) -llapack -lblas -lg2c
+EXTSLB = $(EXTSLBL) -llapack -lblas -lg2c
+endif
+
+# On Linux   lapack and blas and f2c/g2c ere needed
+# ifeq ($(MACHEROS),Darwin)
+# EXTLIB = $(EXTLIBL) -llapack -lblas -lg2c
+# EXTSLB = $(EXTSLBL) -llapack -lblas -lg2c
+# endif
+
+# On OSF1 libdxml contains Lapack, but the fortran support library is needed
+ifeq ($(MACHEROS),OSF1)
+EXTLIB = $(EXTLIBL) -ldxml -lfor
+EXTSLB = $(EXTSLBL) -ldxml -lfor
+endif
+
+# On IRIX , complib.sgimath contains Lapack
+ifeq ($(MACHEROS),IRIX64)
+EXTLIB = $(EXTLIBL) -lcomplib.sgimath 
+EXTSLB = $(EXTSLBL) -lcomplib.sgimath 
+endif
+
+EXTLIB = $(EXTLIBL) 
+EXTSLB = $(EXTSLBL) 
+
+
+XPILIBS = $(LIBXPIPATH) $(LIBXPILIST)
+
+#  main dependence list
+slball : slb slbext slbpi 
+slb : $(SLB)libsophya.dylib 
+slbext : $(SLB)libextsophya.dylib   
+slbpi : $(SLB)libPI.dylib
+ 
+# List of .o files for each module
+OBJBaseTools = $(shell echo `cat ./BaseTools/objlist.list `)
+OBJSysTools = $(shell echo `cat ./SysTools/objlist.list `)
+OBJSUtils = $(shell echo `cat ./SUtils/objlist.list `)
+OBJTArray = $(shell echo `cat ./TArray/objlist.list `)
+OBJNTools = $(shell echo `cat ./NTools/objlist.list `)
+OBJHiStats = $(shell echo `cat ./HiStats/objlist.list `)
+OBJSkyMap = $(shell echo `cat ./SkyMap/objlist.list `)
+OBJSamba = $(shell echo `cat ./Samba/objlist.list `)
+OBJSkyT = $(shell echo `cat ./SkyT/objlist.list `)
+OBJSysSpec = $(shell echo `cat ./SysSpec/objlist.list `)
+ALLOBJS = $(OBJBaseTools) $(OBJSysTools) $(OBJSUtils) $(OBJTArray) $(OBJNTools) $(OBJHiStats) $(OBJSkyMap) $(OBJSamba) $(OBJSkyT) $(OBJSysSpec) 
+ 
+# List of .o files modules with reference to external libraries
+OBJFitsIOServer = $(shell echo `cat ./FitsIOServer/objlist.list `)
+OBJIFFTW = $(shell echo `cat ./IFFTW/objlist.list `)
+OBJLinAlg = $(shell echo `cat ./LinAlg/objlist.list `)
+OBJXAstroPack = $(shell echo `cat ./XAstroPack/objlist.list `)
+# ALLEXTOBJS = $(OBJFitsIOServer) $(OBJIFFTW) $(OBJLinAlg) $(OBJXAstroPack)
+ALLEXTOBJS = $(OBJFitsIOServer) $(OBJIFFTW) $(OBJXAstroPack)
+# ALLEXTOBJS = $(OBJFitsIOServer) 
+
+# List of .o files for PI modules 
+OBJPI = $(shell echo `cat ./PI/objlist.list `)
+OBJPIGcont = $(shell echo `cat ./PIGcont/objlist.list `)
+OBJPIext = $(shell echo `cat ./PIext/objlist.list `)
+ALLPIOBJS = $(OBJPIext) $(OBJPI)  $(OBJPIGcont) 
+# ALLPIOBJS = $(OBJPI)  $(OBJPIGcont) 
+ 
+# Building Sophya shared library
+$(SLB)libsophya.dylib : $(PSLB)
+	$(CMDTILSHL) 
+	cd  $(OBJ); \
+	$(CMDSHLCXX) -o $(SLB)libsophya.dylib  \
+	$(FGSHLACXX) $(ALLOBJS)  $(FGSHLNCXX)\
+	-L$(SLB) $(LIBLSHL)
+ 
+# Building ExtSophya shared library
+$(SLB)libextsophya.dylib : $(EXTPSLB)
+	$(CMDTILSHL) 
+	cd  $(OBJ); \
+	$(CMDSHLCXX) -o $(SLB)libextsophya.dylib  \
+	$(FGSHLACXX) $(ALLEXTOBJS)  $(FGSHLNCXX)\
+	-L$(SLB) -lsophya $(EXTLIB) $(LIBLSHL)
+ 
+# Building PI shared library
+$(SLB)libPI.dylib : $(PIPSLB)
+	$(CMDTILSHL) 
+	cd  $(OBJ); \
+	$(CMDSHLCXX) -o $(SLB)libPI.dylib  \
+	$(FGSHLACXX) $(ALLPIOBJS) $(FGSHLNCXX) \
+	-L$(SLB) -lextsophya -lsophya -L/sw/lib -L/usr/X11R6/lib -lXm -lXt -lX11  $(LIBLSHL)
+ 
+
+clean:
+	if [ -d $(LIB) ] ; then cd $(LIB)/. ; rm -f *.a  ; fi
+	if [ -d $(SLB) ] ; then cd $(SLB)/. ; rm -f *.so ; fi
+	if [ -d $(OBJ) ] ; then cd $(OBJ)/. ; rm -f *.o  rm -rf cxxrep* ; fi
+#	if [ -d PI ]     ; then cd PI/.     ; $(MAKE) clean ; fi
+
Index: /tags/V_Dec2002/SophyaLib/Mgr/makefileuser.awk
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/makefileuser.awk	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/makefileuser.awk	(revision 2309)
@@ -0,0 +1,25 @@
+BEGIN {change=0;}
+/^PP  := \$\{DPCDEVREP\}\/\$\{MACHDIR\}\// {
+  print "PP  := \$\{DPCBASEREP\}\/\$\{MACHDIR\}\/";
+  print "PPH := \$\{HOME\}\/\$\{MACHDIR\}\/";
+  change=1;
+}
+/^OBJ := \$\{PP\}\/Objs\// {
+  print "OBJ := \$\{PPH\}\/Objs\/";
+  change=1;
+}
+/^EXE := \$\{PP\}\/Exec\// {
+  print "EXE := \$\{PPH\}\/Exec\/";
+  change=1;
+}
+/^INC := \$\{DPCDEVREP\}\/Include\// {
+  print "INC := \$\{DPCBASEREP\}\/Include\/";
+  change=1;
+}
+{
+  if(change==0) print $0
+  change=0;
+}
+END {
+print "# fin gene auto MakefileUser.h"
+}
Index: /tags/V_Dec2002/SophyaLib/Mgr/makefileuser.csh
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/makefileuser.csh	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/makefileuser.csh	(revision 2309)
@@ -0,0 +1,6 @@
+#!/bin/csh 
+# creation de MakefileUser.h a partir de Makefile.h
+
+echo 'makefileuser.csh: Creating MakefileUser.h'
+cat Makefile.h | awk -f makefileuser.awk >! MakefileUser.h
+cat makefileuser.inc >> MakefileUser.h
Index: /tags/V_Dec2002/SophyaLib/Mgr/makefileuser.inc
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/makefileuser.inc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/makefileuser.inc	(revision 2309)
@@ -0,0 +1,145 @@
+
+
+##############################################################################
+##############################################################################
+#################### include des librairies pour le link #####################
+##############################################################################
+##############################################################################
+
+###############################################################################
+# Link :                                                                      #
+# - without Shared Libraries > make NOSHLIB=y                                 #
+# - without Extern Libraries > make NOEXTLIB=y                                #
+# - without Fortan Libraries > make NOLFORT=y                                 #
+# - with PI Libraries        > make USELIBPI=y                                #
+# - with Personal Libraries  > make MYLIBS='-L/home/mylibs -lmylib1 -lmylib2' #
+###############################################################################
+
+LIBF =
+LIBS =
+ELIBF =
+ELIBS =
+SLIBF =
+MLIBS =
+
+#------------------------------------------------------#
+#------------------ Archive Libraries -----------------#
+#------------------------------------------------------#
+ifdef NOSHLIB
+
+#--------- lib sophya ---------
+LIBF := $(LIBF) $(LIB)libBaseTools.a $(LIB)libSysTools.a $(LIB)libSUtils.a $(LIB)libNTools.a $(LIB)libTArray.a $(LIB)libHiStats.a 
+LIBF := $(LIBF) $(LIB)libSamba.a $(LIB)libSkyMap.a $(LIB)libSkyT.a
+LIBS := $(LIBS) -L$(LIB) -lBaseTools -lSysTools -lSUtils -lNTools -lTArray -lHiStats -lSamba -lSkyMap -lSkyT
+
+#--------- lib sophya interface externes ---------
+ifndef NOEXTLIB
+LIBF := $(LIBF) $(LIB)libFitsIOServer.a $(LIB)libIFFTW.a $(LIB)libLinAlg.a $(LIB)libXAstroPack.a
+LIBS := $(LIBS) -lFitsIOServer -lIFFTW -lLinAlg -lXAstroPack
+#LIBF := $(LIBF)libBlitz.a
+#LIBS := $(LIBS) -lBlitz
+endif
+
+#--------- lib piapp ---------
+ifdef USELIBPI
+LIBF := $(LIBF) $(LIB)libPI.a $(LIB)libPIext.a
+LIBS := $(LIBS) -lPI -lPIext
+endif
+
+#--------- Other Extern Libraries ---------
+ifndef NOEXTLIB
+ELIBF := $(ELIBF) $(EXTLIBPATH)libcfitsio.a $(EXTLIBPATH)libfftw.a $(EXTLIBPATH)librfftw.a $(EXTLIBPATH)libxastro.a
+ELIBS := $(ELIBS) -L$(EXTLIBPATH) -lcfitsio -lfftw -lrfftw -lxastro
+ifeq ($(MACHEROS),OSF1)
+ELIBS := $(ELIBS) -ldxml
+endif
+ifeq ($(MACHEROS),Linux)
+ELIBF := $(ELIBF) $(EXTLIBPATH)liblapack.a $(EXTLIBPATH)libblas.a 
+ELIBS := $(ELIBS) -llapack -lblas
+endif
+ifeq ($(MACHEROS),IRIX64)
+ELIBS := $(ELIBS) -lcomplib.sgimath 
+endif
+endif
+
+#--------- lib system ---------
+# librairie des instances de templates cxx Sophya
+ifeq ($(CXX),cxx)
+SLIBS := $(SLIBS) -lertcxx
+endif
+SLIBS := $(SLIBS) -lm
+# Librairies pour le fortran
+ifndef NOLFORT
+ifeq ($(MACHEROS),OSF1)
+SLIBS := $(SLIBS) -lfor
+endif
+ifeq ($(MACHEROS),Linux)
+#SLIBS := $(SLIBS) -lf2c
+SLIBS := $(SLIBS) -lg2c
+endif
+endif
+
+#-----------------------------------------------------#
+#------------------ Shared Libraries -----------------#
+#-----------------------------------------------------#
+else
+
+#--------- lib sophya ---------
+LIBF := $(LIBF) $(SLB)libsophya.so 
+LIBS := $(LIBS) -L$(SLB) -lsophya
+
+#--------- lib sophya interface externes ---------
+ifndef NOEXTLIB
+LIBF := $(LIBF) $(SLB)libextsophya.so 
+LIBS := $(LIBS) -lextsophya
+endif
+
+#--------- lib piapp ---------
+ifdef USELIBPI
+LIBF := $(LIBF) $(SLB)libPI.so 
+LIBS := $(LIBS) -lPI
+endif
+
+#--------- Other Extern Libraries ---------
+# ATTENTION actuellement les blabla.a sont appelees,
+# on pourrait appeller les blabla.so (EXTSLBPATH) si on les avait crees
+ifndef NOEXTLIB
+ELIBF := $(ELIBF) $(EXTLIBPATH)libcfitsio.a $(EXTLIBPATH)libfftw.a $(EXTLIBPATH)librfftw.a $(EXTLIBPATH)libxastro.a
+ELIBS := $(ELIBS) -L$(EXTLIBPATH) -lcfitsio -lfftw -lrfftw  -lxastro
+ifeq ($(MACHEROS),OSF1)
+ELIBS := $(ELIBS) -ldxml
+endif
+ifeq ($(MACHEROS),Linux)
+ELIBF := $(ELIBF) $(EXTLIBPATH)liblapack.a $(EXTLIBPATH)libblas.a 
+ELIBS := $(ELIBS) -llapack -lblas
+endif
+ifeq ($(MACHEROS),IRIX64)
+ELIBS := $(ELIBS) -lcomplib.sgimath 
+endif
+endif
+
+#--------- lib systeme ---------
+SLIBS := $(SLIBS) -lm
+# Librairies pour le fortran
+ifndef NOLFORT
+ifeq ($(MACHEROS),OSF1)
+SLIBS := $(SLIBS) -lfor
+endif
+ifeq ($(MACHEROS),Linux)
+#SLIBS := $(SLIBS) -lf2c
+SLIBS := $(SLIBS) -lg2c
+endif
+endif
+
+endif
+
+#--------- PERSONAL Libraries ---------
+ifdef MYLIBS
+  MLIBS := $(MLIBS) $(MYLIBS)
+endif
+
+#--------- LIBF et LIBS ---------
+LIBF := $(LIBF) $(ELIBF)
+LIBS := $(LIBS) $(ELIBS) $(MLIBS) $(SLIBS)
+
+##############################################################################
Index: /tags/V_Dec2002/SophyaLib/Mgr/mkmf
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/mkmf	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/mkmf	(revision 2309)
@@ -0,0 +1,236 @@
+#!/bin/csh 
+# $Id: mkmf,v 1.17 2001-12-19 18:34:11 ansari Exp $
+
+#  Pour debugger 
+set DODBG = 'echo'
+set DODBG = ''
+
+# Librairies externe
+if( ! $?EXTLIBDIR ) then
+  echo 'mkmf- WARNING (External libraries) EXTLIBDIR variable not set'
+endif
+
+# creation de MakefileUser.h a partir de Makefile.h
+chmod +x ./makefileuser.csh
+$DODBG ./makefileuser.csh
+
+# creation des liens pour les includes
+echo 'mkmf: Creating links for *.h (call mkmflien)'
+chmod +x ./mkmflien
+$DODBG ./mkmflien -clean
+
+# Liste des modules a construire
+# modules : Liste de module SOPHYA, sans dependance exterieure
+# extmodules : Liste de modules avec dependance exterieures
+#        _pres : Liste des modules presents
+
+set modules = `cat libdirs`
+set extmodules = `cat extlibdirs` 
+set modules_pres = ''
+set extmodules_pres = ''
+
+set module_libnames = ''
+set extmodule_libnames = ''
+set extlib_list = ''
+set extslb_list = ''
+#  Constitution de la liste de modules present
+foreach f ($modules)
+  if (-d ../$f ) then
+    set modules_pres = ( $modules_pres $f )
+    set module_libnames = ( $module_libnames '$(LIB)lib'$f.a )
+  endif
+end
+foreach f ($extmodules)
+  if (-d ../$f ) then
+    set extmodules_pres = ( $extmodules_pres $f )
+    set extmodule_libnames = ( $extmodule_libnames '$(LIB)lib'$f.a )
+    set lil = "../$f/extlib_list"
+    if (-f $lil ) set extlib_list = ($extlib_list `sed -e 's/.*/-l&/' $lil`) 
+    set lil = "../$f/extslb_list"
+    if (-f $lil ) set extslb_list = ($extslb_list `sed -e 's/.*/-l&/' $lil`) 
+  endif
+end
+
+echo 'mkmf: List of modules ' 
+echo '  ... modules= ' $modules_pres
+echo $module_libnames 
+echo '  ... extmodules= ' $extmodules_pres
+echo $extmodule_libnames 
+
+echo 'mkmf: Creating makefile global :'
+rm -f GNUmakefile; touch GNUmakefile
+
+echo '# include files defining compiler/linker options '  >> GNUmakefile
+echo 'MODULECXXREPNAME := PI'  >> GNUmakefile
+echo 'include Mgr/Makefile.h' >> GNUmakefile
+echo 'include Mgr/Makefile.slb' >> GNUmakefile
+echo ''   >> GNUmakefile
+
+echo 'LIBF = ' `sed -e 's/.*/$(LIB)lib&.a/' libdirs` >> GNUmakefile
+# echo 'LIBS = -L$(LIB)' `sed -e 's/.*/-l&/' libdirs` '-lm' >> GNUmakefile
+echo 'LIBS = -L$(LIB)' `sed -e 's/.*/-l&/' libdirs`  >> GNUmakefile
+# echo 'LIBG = -L$(GLB) -lstdc++' >> GNUmakefile
+# echo 'ifeq ($(HOSTTYPE), powerpc)' >> GNUmakefile
+# echo '  LIBG = -L$(GLB)' >> GNUmakefile
+# echo 'endif' >> GNUmakefile
+
+cat >> GNUmakefile <<EOF
+
+defaut: libs
+
+all: libs extlibs PI
+
+libs: cxxlibs
+
+extlibs: cxxextlibs
+
+EOF
+
+# Dans cet ordre pour les templates de cxx, a cause des dependances
+# pour instantiation automatique/manuels
+
+echo 'cxxlibs: ' $modules_pres >>    GNUmakefile
+echo ' ' >> GNUmakefile 
+echo 'cxxextlibs: ' $extmodules_pres >> GNUmakefile
+
+
+#  Attention, ne pas changer l'ordre de libnames dependances cxx  ????? 
+set libnames = ($modules_pres $extmodules_pres)
+set i = 1
+set j = $#libnames ; @ j--
+while ($i <= $#libnames)
+  set f = $libnames[$i]
+  set k = $i ; @ k++
+  if ( -d ../$f && ! -f ../$f/no_mkmf ) then 
+    set cmd = "./mkmflib $f "
+    echo "mkmf: Creation makefile lib $f"
+    echo "   execution $cmd"
+    $DODBG $cmd
+  endif
+  echo '.PHONY: ' $f >> GNUmakefile
+  echo $f':' >> GNUmakefile
+  echo '	if [ -d '$f' ] ; then cd ' $f '; $(MAKE) ; fi' >> GNUmakefile
+  echo ' ' >> GNUmakefile
+  @ i++
+end
+
+
+if ( -d ../PI ) then 
+  set cmd = './mkmfPI PI BaseTools'
+  echo "mkmf: Creation makefile lib PI"
+  echo "   execution $cmd"
+  $DODBG  $cmd
+endif
+if ( -d ../PIGcont ) then 
+  set cmd = './mkmfPI PIGcont BaseTools'
+  echo "mkmf: Creation makefile lib PIGcont"
+  echo "   execution $cmd"
+  $DODBG  $cmd
+endif
+if ( -d ../PIext ) then 
+  set cmd = "./mkmfPI PIext $libnames PI"
+  echo "mkmf: Creation makefile lib PIext"
+  echo "   execution $cmd"
+  $DODBG $cmd
+endif
+echo '.PHONY: PI' >> GNUmakefile
+echo 'PI:' >> GNUmakefile
+echo '	if [ -d PI ] ; then cd PI ; $(MAKE) ; fi' >> GNUmakefile
+echo '	if [ -d PIGcont ] ; then cd PIGcont ; $(MAKE) ; fi' >> GNUmakefile
+echo '	if [ -d PIext ] ; then cd PIext ; $(MAKE) ; fi' >> GNUmakefile
+
+
+echo 'mkmf: Writing shared library building part of the makefile :'
+if ( `uname` == "Darwin" ) then
+  set sosfx = "dylib"
+else
+  set sosfx = "so"
+endif
+
+echo '#  Shared library creation part of the Makefile'       >> GNUmakefile
+echo ' '                                 >> GNUmakefile
+echo '#  List of libraries (.a)'         >> GNUmakefile
+echo 'PSLB = ' $module_libnames          >> GNUmakefile
+echo 'EXTPSLB = ' $extmodule_libnames    >> GNUmakefile
+echo 'PIPSLB =  $(LIB)libPI.a  $(LIB)libPIext.a'   >> GNUmakefile
+echo '#  List of external library references'       >> GNUmakefile
+echo 'EXTLIB  = -L$(EXTLIBPATH)' $extlib_list       >> GNUmakefile
+echo 'EXTSLB  = -L$(EXTSLBPATH)' $extslb_list       >> GNUmakefile
+echo 'XPILIBS = $(LIBXPIPATH) $(LIBXPILIST)'        >> GNUmakefile
+echo ''                                   >> GNUmakefile
+echo '#  main dependence list'            >> GNUmakefile
+echo 'slball : slb slbext slbpi '         >> GNUmakefile
+echo 'slb : $(SLB)libsophya.'$sosfx       >> GNUmakefile
+echo 'slbext : $(SLB)libextsophya.'$sosfx >> GNUmakefile
+echo 'slbpi : $(SLB)libPI.'$sosfx         >> GNUmakefile
+echo ' '                                  >> GNUmakefile
+
+echo '# List of .o files for each module'  >> GNUmakefile
+set objalls =  ''
+foreach f ($modules_pres)
+  echo 'OBJ'$f '= $(shell echo' '`cat' "./$f/$f.o.list" '`)'  >> GNUmakefile
+  set objalls = ( $objalls '$(OBJ'$f')' )
+end
+echo 'ALLOBJS =' $objalls                >> GNUmakefile
+echo ' '                                 >> GNUmakefile
+
+echo '# List of .o files modules with reference to external libraries'  >> GNUmakefile
+set objalls =  ''
+foreach f ($extmodules_pres)
+  echo 'OBJ'$f '= $(shell echo' '`cat' "./$f/$f.o.list" '`)'  >> GNUmakefile
+  set objalls = ( $objalls '$(OBJ'$f')' )
+end
+echo 'ALLEXTOBJS =' $objalls             >> GNUmakefile
+echo ' '                                 >> GNUmakefile
+
+echo '# List of .o files for PI modules '  >> GNUmakefile
+set objalls =  ''
+foreach f (PI PIGcont PIext)
+  echo 'OBJ'$f '= $(shell echo' '`cat' "./$f/$f.o.list" '`)'  >> GNUmakefile
+  set objalls = ( $objalls '$(OBJ'$f')' )
+end
+echo 'ALLPIOBJS =' $objalls              >> GNUmakefile
+echo ' '                                 >> GNUmakefile
+
+echo '# Building Sophya shared library'  >> GNUmakefile
+echo '$(SLB)libsophya.'$sosfx' : $(PSLB)'                       >> GNUmakefile
+echo '	$(CMDTILSHL) '                                          >> GNUmakefile
+echo '	cd  $(OBJ); \'                                          >> GNUmakefile
+echo '	$(CMDSHLCXX) -o $(SLB)libsophya.'$sosfx'  \'            >> GNUmakefile
+echo '	$(FGSHLACXX) $(ALLOBJS)  $(FGSHLNCXX)\'                 >> GNUmakefile
+echo '	-L$(SLB) $(LIBLSHL)'                                    >> GNUmakefile
+echo ' '                                                        >> GNUmakefile
+
+echo '# Building ExtSophya shared library'  >> GNUmakefile
+echo '$(SLB)libextsophya.'$sosfx' : $(EXTPSLB)'                 >> GNUmakefile
+echo '	$(CMDTILSHL) '                                          >> GNUmakefile
+echo '	cd  $(OBJ); \'                                          >> GNUmakefile
+echo '	$(CMDSHLCXX) -o $(SLB)libextsophya.'$sosfx'  \'         >> GNUmakefile
+echo '	$(FGSHLACXX) $(ALLEXTOBJS)  $(FGSHLNCXX)\'              >> GNUmakefile
+echo '	-L$(SLB) -lsophya $(EXTLIB) $(LIBLSHL)'                 >> GNUmakefile
+echo ' '                                                        >> GNUmakefile
+
+echo '# Building PI shared library'  >> GNUmakefile
+echo '$(SLB)libPI.'$sosfx' : $(PIPSLB)'                         >> GNUmakefile
+echo '	$(CMDTILSHL) '                                          >> GNUmakefile
+echo '	cd  $(OBJ); \'                                          >> GNUmakefile
+echo '	$(CMDSHLCXX) -o $(SLB)libPI.'$sosfx'  \'                >> GNUmakefile
+echo '	$(FGSHLACXX) $(ALLPIOBJS) $(FGSHLNCXX) \'               >> GNUmakefile
+echo '	-L$(SLB) -lsophya -lextsophya $(EXTLIB) $(XPILIBS) $(LIBLSHL)'      >> GNUmakefile
+echo ' '                                                        >> GNUmakefile
+
+
+cat >> GNUmakefile << __END__
+
+clean:
+	if [ -d \$(LIB) ] ; then cd \$(LIB)/. ; rm -f *.a  ; fi
+	if [ -d \$(SLB) ] ; then cd \$(SLB)/. ; rm -f *.$sosfx ; fi
+	if [ -d \$(OBJ) ] ; then cd \$(OBJ)/. ; rm -f *.o  rm -rf cxxrep* ; fi
+#	if [ -d PI ]     ; then cd PI/.     ; \$(MAKE) clean ; fi
+
+__END__
+
+mv GNUmakefile ../GNUmakefile
+
+echo '*** mkmf done ***'
+
Index: /tags/V_Dec2002/SophyaLib/Mgr/mkmfPI
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/mkmfPI	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/mkmfPI	(revision 2309)
@@ -0,0 +1,89 @@
+#!/bin/csh
+# $Id: mkmfPI,v 1.9 2002-05-14 15:14:47 ansari Exp $
+
+set makefname = 'GNUmakefile'
+
+cd ../$1
+
+if ( ! -f exclude_dpc ) touch exclude_dpc
+if ( ! $?TMPDIR ) set TMPDIR = /tmp
+sort exclude_dpc >! $TMPDIR/exclude.sort
+
+##############################################
+########### fichier de la liste des .o #######
+##############################################
+
+set liblist = $1.o.list
+rm -f $liblist
+touch $liblist
+ls -1 *.{c,cc} | comm -3 -1 $TMPDIR/exclude.sort - | sed -e 's/\.cc/.o/' | sed -e 's/\.c/.o/' >> $liblist
+unset liblist
+
+##############################################
+########### Creation de GNUmakefile ##########
+##############################################
+
+set libf='$(LIB)lib'$1'.a'
+
+rm -f $makefname
+touch $makefname
+
+echo "MODULECXXREPNAME := PI" >>  $makefname
+
+set hfcxxlibs = '-L$(LIB)' 
+set i = 1
+while ($i <= $#argv)
+  set hfcxxlibs = "$hfcxxlibs -l$argv[$i]"
+  @ i++
+end
+
+
+
+# 04/98: le fichier X11/Xlib.h contient des declarations de fonctions sans type  
+# Cela genere un grand nombre de warning avec cxx V6 
+# On specifie donc -msg_quiet pour PI, ProgPI, ...
+echo 'MODULEDECCXXFLAGS := -msg_quiet' >> $makefname
+echo 'include ../Mgr/Makefile.h' >> $makefname
+
+echo " " >> $makefname
+
+set ccfiles  = `ls -1 *.cc *.c | comm -3 -1 $TMPDIR/exclude.sort -`
+set objfiles = `ls -1 *.cc *.c | comm -3 -1 $TMPDIR/exclude.sort - | sed -e 's/\.cc/.o/g' | sed -e 's/\.c/.o/' | sed -e 's/^/$(OBJ)/'`
+
+rm -f $TMPDIR/exclude.sort
+
+echo 'all:' $libf >> $makefname 
+
+echo $libf ':' $objfiles  >> $makefname
+echo '	$(AR) $(ARFLAGS)  $@ $($(ARARGS)) ' >> $makefname
+echo 'ifeq ($(CXX),cxx)' >> $makefname
+# echo '	$(CXX) $? $(CPPFLAGS) $(CXXFLAGS)' $hfcxxlibs '-o $(OBJ)xx.x -Hf' >> $makefname
+echo '	$(CXX) $? $(CPPFLAGS) $(CXXFLAGS) -o $(OBJ)xx.x -Hf' >> $makefname
+echo 'endif ' >> $makefname
+
+echo " " >> $makefname
+
+echo 'clean:' >> $makefname 
+echo '	rm -f '$objfiles >> $makefname
+echo 'ifeq ($(CXX),cxx)' >> $makefname
+echo '	cd $(REPM); rm -f *.o'  >> $makefname
+echo 'endif ' >> $makefname
+
+echo " " >> $makefname
+
+set inc = $DPCDEVREP/Include
+set incext = $EXTLIBDIR/Include
+set nomsys = `uname`
+
+foreach f ( $ccfiles )
+  gcc -MM -D$nomsys -I$inc -I$incext $f  \
+       | sed -e 's/.*\.o/\$(OBJ)&/'  \
+       | sed -e 's?'$inc/'?$(INC)?g'  \
+       | sed -e 's?'$incext/'?$(EXTINCPATH)?g' >> $makefname
+end
+
+
+
+
+
+
Index: /tags/V_Dec2002/SophyaLib/Mgr/mkmflib
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/mkmflib	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/mkmflib	(revision 2309)
@@ -0,0 +1,93 @@
+#!/bin/csh
+# $Id: mkmflib,v 1.11 2002-05-14 15:14:47 ansari Exp $
+
+cd ../$1
+
+if ( ! -f exclude ) touch exclude
+if ( ! -f flags_compil ) touch flags_compil
+if ( ! -f extlib_list ) touch extlib_list
+if ( ! -f extslb_list ) touch extslb_list
+
+if ( ! $?TMPDIR ) set TMPDIR = /tmp
+sort exclude >! $TMPDIR/exclude.sort
+
+##############################################
+########### fichier de la liste des .o #######
+##############################################
+
+set liblist = $1.o.list
+rm -f $liblist
+touch $liblist
+ls -1 *.{c,cc} | comm -3 -1 $TMPDIR/exclude.sort - | sed -e 's/\.cc/.o/' | sed -e 's/\.c/.o/' >> $liblist
+unset liblist
+
+##############################################
+########### Creation de GNUmakefile ##########
+##############################################
+
+set libf='$(LIB)lib'$1'.a'
+
+set hfcxxlibs = '-L$(LIB)' 
+set i = 1
+while ($i <= $#argv)
+  set hfcxxlibs = "$hfcxxlibs -l$argv[$i]"
+  @ i++
+end
+
+set extlib_list = `cat extlib_list`
+set hfcxxlibs = ($hfcxxlibs '-L$(EXTLIBPATH)' $extlib_list)
+
+rm -f GNUmakefile
+touch GNUmakefile
+
+cat flags_compil >> GNUmakefile 
+echo 'include ../Mgr/Makefile.h' >> GNUmakefile 
+
+echo " " >> GNUmakefile
+echo 'all:' $libf  >> GNUmakefile 
+
+echo 'clean:' >> GNUmakefile
+set toto='rm -f'
+foreach f (*.cc *.c) 
+  set toto= ( $toto '$(OBJ)'$f:r.o )
+end
+echo '	'$toto >> GNUmakefile
+echo '	rm -f '$libf >> GNUmakefile
+
+echo $libf ':' \
+ `ls -1 *.{c,cc} | comm -3 -1 $TMPDIR/exclude.sort - | sed -e 's/\.cc/.o/' | sed -e 's/\.c/.o/' | sed -e 's/^/$(OBJ)/'` >> GNUmakefile
+echo '	$(ARCXX) $(ARCXXFLAGS) $@ $($(ARARGS))' >> GNUmakefile
+#  Pour faire compiler les instantiations automatique de cxx (DEC)
+echo 'ifeq ($(CXX),cxx)' >> GNUmakefile
+#echo '	$(CXX) $? $(CPPFLAGS) $(CXXFLAGS)' $hfcxxlibs '-o $(OBJ)xx.x -Hf' >> GNUmakefile
+echo '	$(CXX) $? $(CPPFLAGS) $(CXXFLAGS) -o $(OBJ)xx.x -Hf' >> GNUmakefile
+echo 'endif ' >> GNUmakefile
+
+rm -f $TMPDIR/exclude.sort
+
+echo " " >> GNUmakefile
+
+set inc = $DPCDEVREP/Include
+# set incxx = $inc/CxxInc
+set incext = $EXTLIBDIR/Include
+set nomsys = `uname`
+
+foreach f ( *.cc )
+  grep -q '^'$f'$' exclude && continue
+  gcc -MM -D$nomsys -I$inc -I$incext $f  \
+       | sed -e 's/.*\.o/\$(OBJ)&/'  \
+       | sed -e 's?'$inc/'?$(INC)?g'  \
+       | sed -e 's?'$incext/'?$(EXTINCPATH)?g' >> GNUmakefile
+end
+
+foreach f ( *.c )
+  grep -q '^'$f'$' exclude && continue
+  gcc -MM -D$nomsys -I$inc -I$incext $f  \
+       | sed -e 's/.*\.o/\$(OBJ)&/'  \
+       | sed -e 's?'$inc/'?$(INC)?g' \
+       | sed -e 's?'$incext/'?$(EXTINCPATH)?g' >> GNUmakefile
+end 
+
+
+
+
Index: /tags/V_Dec2002/SophyaLib/Mgr/mkmflib_save
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/mkmflib_save	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/mkmflib_save	(revision 2309)
@@ -0,0 +1,67 @@
+#!/bin/csh
+# $Id: mkmflib_save,v 1.2 1999-10-25 16:24:49 ansari Exp $
+
+cd ../$1
+set libf='$(LIB)lib'$1'.a'
+
+set hfcxxlibs = '-L$(LIB)' 
+set i = 1
+while ($i <= $#argv)
+  set hfcxxlibs = "$hfcxxlibs -l$argv[$i]"
+  @ i++
+end
+
+
+rm -f GNUmakefile
+
+echo 'include ../Mgr/Makefile.h' >> GNUmakefile 
+
+echo " " >> GNUmakefile
+echo 'all:' $libf  >> GNUmakefile 
+
+echo 'clean:' >> GNUmakefile
+set toto='rm -f'
+foreach f (*.cc *.c) 
+  set toto= ( $toto '$(OBJ)'$f:r.o )
+end
+echo '	'$toto >> GNUmakefile
+echo '	rm -f '$libf >> GNUmakefile
+
+if ( ! -f exclude ) touch exclude
+if ( ! $?TMPDIR ) set TMPDIR = /tmp
+sort exclude >! $TMPDIR/exclude.sort
+
+echo $libf ':' \
+ `ls *.{c,cc} | comm -3 -1 $TMPDIR/exclude.sort - | sed -e 's/\.cc/.o/' | sed -e 's/\.c/.o/' | sed -e 's/^/$(OBJ)/'` >> GNUmakefile
+echo '	$(AR) $(ARFLAGS) $@ $?' >> GNUmakefile
+#  Pour faire compiler les instantiations automatique de cxx (DEC)
+echo 'ifeq ($(CXX),cxx)' >> GNUmakefile
+echo '	$(CXX) $? $(CPPFLAGS) $(CXXFLAGS)' $hfcxxlibs '-o $(OBJ)xx.x -Hf' >> GNUmakefile
+echo 'endif ' >> GNUmakefile
+
+rm -f $TMPDIR/exclude.sort
+
+echo " " >> GNUmakefile
+
+set inc = $DPCDEVREP/Include
+set incxx = $inc/CxxInc
+
+foreach f ( *.cc )
+  grep -q '^'$f'$' exclude && continue
+  gcc -MM -I$inc -I$incxx $f  \
+       | sed -e 's/.*\.o/\$(OBJ)&/'  \
+       | sed -e 's?'$incxx/'?$(CXI)?g' \
+       | sed -e 's?'$inc/'?$(INC)?g' >> GNUmakefile
+end
+
+foreach f ( *.c )
+  grep -q '^'$f'$' exclude && continue
+  gcc -MM -I$inc -I$incxx $f  \
+       | sed -e 's/.*\.o/\$(OBJ)&/'  \
+       | sed -e 's?'$incxx/'?$(CXI)?g' \
+       | sed -e 's?'$inc/'?$(INC)?g' >> GNUmakefile
+end 
+
+
+
+
Index: /tags/V_Dec2002/SophyaLib/Mgr/mkmflien
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/mkmflien	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/mkmflien	(revision 2309)
@@ -0,0 +1,127 @@
+#!/bin/csh
+# $Id: mkmflien,v 1.12 2001-12-19 18:34:11 ansari Exp $
+
+# WARNING : mkmflien has to be runned FROM Mgr/
+# usage : mkmflien [-copy] [dir_dest]
+#  -copy : includes are copied (if not they are linked)
+#  -clean : after copy/link file are deleted if not existing (empty link)
+#  dir_dest : link/copy to dir_dest/
+#             default : $DPCDEVREP/Include
+
+#######################
+#### Decodage arguments
+#######################
+unset dst
+set cpln = "ln -sf"
+unset clln
+if( $?DPCDEVREP ) then
+  set dst = $DPCDEVREP/Include
+endif
+
+while( $#argv > 0 )
+  if( "$1" == "-copy" ) then
+    set cpln = "cp"
+  else if( "$1" == "-clean" ) then
+    set clln
+  else
+    set dst = $1
+  endif
+  shift
+end
+
+if( ! $?dst ) then
+  echo "Variable DPCDEVREP must be set"
+  echo "OR you must give a directory for linking/copying"
+  exit -1
+endif
+
+#############################################################
+#### repertoire contenant les liens a creer pour les includes
+#############################################################
+if ( ! -d $dst/ ) then
+  echo repertoire $dst inconnu
+  exit -1
+endif
+
+#########################################################
+#### repertoire contenant les repertoires du code+include
+#########################################################
+pushd ../. > /dev/null
+set src = `pwd | sed 's?/tmp_mnt??'`
+set src = `echo $src | sed 's?/.automount/dapservfic/root??'`
+popd       > /dev/null
+
+#########################################################
+### Les includes a mettre dans Include pour les Makefiles
+#########################################################
+if( -d $src/Mgr ) then
+  cd $src/Mgr/.
+  echo $cpln from Mgr
+  set FILE = ( Makefile.h Makefile.slb MakefileUser.h )
+  pushd $dst/. > /dev/null
+  rm -f $FILE
+  foreach f ( $FILE )
+    if( -e $src/Mgr/$f ) then
+      $cpln $src/Mgr/$f ./
+    endif
+  end
+  popd       > /dev/null
+endif
+
+#############################################
+####  Les includes de Blitz++ lien ds Include
+#############################################
+if( -d $src/Blitz ) then
+  cd $src/Blitz/.
+  foreach d ( blitz blitz/meta blitz/array )
+    if( -d $d ) then
+      echo $cpln from Blitz/$d
+      if( ! -d $dst/$d ) mkdir $dst/$d
+      pushd $d > /dev/null
+      set FILE = ( *.h *.cc )
+      popd     > /dev/null
+      pushd $dst/$d/. > /dev/null
+      rm -f $FILE
+      $cpln $src/Blitz/$d/*.h ./
+      $cpln $src/Blitz/$d/*.cc ./
+      popd       > /dev/null
+    endif
+  end
+endif
+
+####################################################
+####  Les includes du code C++ a mettre dans Include
+####################################################
+foreach d (`cat ../Mgr/libdirs` `cat ../Mgr/extlibdirs` `cat ../Mgr/PIlibdirs`   )
+  if ( -d $src/$d ) then
+    cd $src/$d/.
+    echo $cpln from $d
+    set FILE = ( *.h )
+    pushd $dst/. > /dev/null
+    rm -f $FILE
+    $cpln $src/$d/*.h ./
+    popd         > /dev/null
+  endif
+end
+
+######################################
+####  Le cas particulier de machdefs.h
+######################################
+if ( -e $src/BaseTools/machdefs_mkmf.h ) then
+  echo $cpln from BaseTools/machdefs_mkmf.h
+  $cpln $src/BaseTools/machdefs_mkmf.h $dst/machdefs.h
+endif
+
+###############################
+####  Nettoyage des liens vides
+###############################
+if( $?clln ) then
+  foreach f ( $dst/*.h )
+    if( ! -e $f ) then
+      echo remove empty link : $f
+      rm -f $f
+    endif
+  end
+endif
+
+exit 0
Index: /tags/V_Dec2002/SophyaLib/Mgr/mkmfprog
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/mkmfprog	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/mkmfprog	(revision 2309)
@@ -0,0 +1,94 @@
+#!/bin/csh 
+# $Id: mkmfprog,v 1.4 2000-04-13 15:56:03 ansari Exp $
+
+# $1 : nom du repertoire
+# dans le repertoire, programs : liste des programs
+#                     usedlibs : liste des -L -l utilises
+#                     usedslibs : idem pour shlibs
+
+cd ../$1
+
+rm -f GNUmakefile
+
+
+echo 'MODULECXXREPNAME := ' $1  >> GNUmakefile
+# 04/98 : le fichier X11/Xlib.h contient des declarations de fonctions sans type
+# Cela genere un grand nombre de warning avec cxx V6 
+# On specifie donc -msg_quiet pour ProgPI
+if ($1 == 'ProgPI')  then
+  echo 'MODULEDECCXXFLAGS := -msg_quiet' >> GNUmakefile 
+endif
+echo 'include ../Mgr/Makefile.h' >> GNUmakefile
+
+echo ' ' >> GNUmakefile
+
+echo 'ifdef NOSHLIB'                                        >> GNUmakefile
+echo 'LIBF = ' `sed -e 's/.*/$(LIB)lib&.a/' usedlibs`       >> GNUmakefile
+echo 'LIBS = -L$(LIB)' `sed -e 's/.*/-l&/' usedlibs` ' -lm' >> GNUmakefile
+echo 'ifeq ($(CXX),cxx)'                                    >> GNUmakefile
+echo '# librairie des instances de templates cxx'           >> GNUmakefile
+echo 'LIBS := $(LIBS) -lertcxx'                             >> GNUmakefile
+echo 'endif' >> GNUmakefile 
+echo 'else'                                                 >> GNUmakefile
+echo 'LIBF = ' `sed -e 's/.*/$(SLB)lib&.so/' usedslibs`     >> GNUmakefile
+echo 'LIBS = -L$(SLB)' `sed -e 's/.*/-l&/' usedslibs` ' -lm'>> GNUmakefile
+echo 'endif'                                                >> GNUmakefile
+
+echo 'LIBSORA := $(LIBS)' >> GNUmakefile
+echo 'ifdef ORACLE_HOME' >> GNUmakefile
+echo 'LIBSORA := -L$(LIB) -lDb++ $(LIBS) -lErosDb -L$(ORACLE_HOME)/lib -lclntsh' >> GNUmakefile
+echo 'endif' >> GNUmakefile
+
+echo 'LDLIBS := $(LIBS) $(LDLIBS)' >> GNUmakefile
+
+set progaexe = programs
+if( -e programs_exe ) set progaexe = programs_exe
+echo 'PROGS = '`cut -d \  -f1 $progaexe | awk '{if(length($1)>0) print $1}' | sed -e 's/^/\$(EXE)/'` >> GNUmakefile
+unset progaexe
+
+echo " " >> GNUmakefile
+echo 'all: $(PROGS)' >> GNUmakefile 
+
+set cxxrepname = cxxrep_$1
+
+cat >> GNUmakefile << __END__
+
+clean:
+	rm -f \$(PROGS)
+	if [ -d \$(OBJ)$cxxrepname ] ; then cd \$(OBJ)$cxxrepname ; rm -f *.o ; fi
+
+__END__
+
+awk -f ../Mgr/mkmfprog.awk programs >> GNUmakefile
+
+#foreach f (`cat programs`)
+#  echo $f ': $(EXE)'$f >> GNUmakefile
+#  echo '	' >> GNUmakefile
+#  echo '$(EXE)'$f ':' '$(OBJ)'$f.o '$(LIBF)' >> GNUmakefile
+#  echo '	g++ $(LDFLAGS) -o $@ $< $(LIBS)' >> GNUmakefile
+#  echo " ">> GNUmakefile
+#end
+
+#foreach f (`cat ../Mgr/programs_db`)
+#  echo $f ': $(EXE)'$f >> GNUmakefile
+#  echo '	' >> GNUmakefile
+#  echo '$(EXE)'$f ':' '$(OBJ)'$f.o '$(LIBF)' >> GNUmakefile
+#  echo '	g++ $(LDFLAGS) -o $@ $< $(LIBSORA)' >> GNUmakefile
+#  echo " ">> GNUmakefile
+#end
+
+set inc = $DPCDEVREP/Include
+set incext = $EXTLIBDIR/Include
+set nomsys = `uname`
+
+foreach f ( *.cc )
+  gcc -MM -D$nomsys -I$inc -I$incext $f  \
+       | grep -v $incext \
+       | sed -e 's/.*\.o/\$(OBJ)&/' \
+       | sed -e 's?'$inc/'?$(INC)?g' \
+       | sed -e 's?'$incext/'?$(EXTINCPATH)?g' >> GNUmakefile
+end 
+
+
+
+
Index: /tags/V_Dec2002/SophyaLib/Mgr/mkmfprog.awk
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/mkmfprog.awk	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/mkmfprog.awk	(revision 2309)
@@ -0,0 +1,22 @@
+{ print $1 ": $(EXE)"$1 ;
+  print "	" ;
+  xlib = ""
+  if (NF == 1) 
+     obj = "$(OBJ)"$1".o";
+  else if (NF == 2 && $2 == "DB") {
+     obj = "$(OBJ)"$1".o";
+     xlib = "$(LIBSORA)";
+  }
+  else {
+    obj = "";
+    for (i=2;i<=NF;i++) {
+      if ($i == "DB")
+       xlib = "$(LIBSORA)"
+      else
+       obj = obj " $(OBJ)"$i;
+     }
+  }
+  print "$(EXE)"$1 ":" obj;
+  print "	$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@ " xlib
+  print "  "  
+}
Index: /tags/V_Dec2002/SophyaLib/Mgr/mkslbsgi.csh
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/mkslbsgi.csh	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/mkslbsgi.csh	(revision 2309)
@@ -0,0 +1,93 @@
+#! /bin/csh 
+
+set opt = 'slball'
+
+if ($#argv < 1)   then 
+  echo 'Error Arg/ Usage: mkslb.csh slb/slbext/slbpi/slball'
+  exit 0
+endif
+
+set opt = $1
+
+set cw = `pwd`
+
+echo '---- CWD= ' $cw
+
+set LIBXPIPATH = '-L/usr/X11/lib '
+set LIBXPILIST = '-lXm -lXt -lX11'
+set XPILIBS = "$LIBXPIPATH $LIBXPILIST"
+
+set LIB = $DPCDEVREP/IRIX64-CC/Libs/
+set SLB = $DPCDEVREP/IRIX64-CC/ShLibs/
+set OBJ = $DPCDEVREP/IRIX64-CC/Objs/
+
+set EXTLIBPL = -L${EXTLIBDIR}/IRIX64-CC/Libs/
+set EXTSLBPL = -L${EXTLIBDIR}/IRIX64-CC/ShLibs/
+
+set EXTLIBL  = "${EXTLIBPL} -lcfitsio -lfftw -lrfftw -lxastro -lcomplib.sgimath"
+set EXTSLBL  = "${EXTSLBPL} -lcfitsio -lfftw -lrfftw -lxastro -lcomplib.sgimath"
+
+
+set OBJBaseTools = `cat ./BaseTools/objlist.list `
+set OBJSysTools = `cat ./SysTools/objlist.list `
+set OBJSUtils = `cat ./SUtils/objlist.list `
+set OBJTArray = `cat ./TArray/objlist.list `
+set OBJNTools = `cat ./NTools/objlist.list `
+set OBJHiStats = `cat ./HiStats/objlist.list `
+set OBJSkyMap = `cat ./SkyMap/objlist.list ` 
+set OBJSamba = `cat ./Samba/objlist.list `
+set OBJSkyT = `cat ./SkyT/objlist.list `
+set ALLOBJS = ($OBJBaseTools $OBJSysTools $OBJSUtils $OBJTArray $OBJNTools  $OBJHiStats  $OBJSkyMap $OBJSamba $OBJSkyT)
+	
+set OBJFitsIOServer = `cat ./FitsIOServer/objlist.list `
+set OBJIFFTW = `cat ./IFFTW/objlist.list `
+set OBJLinAlg = `cat ./LinAlg/objlist.list `
+set OBJXAstroPack = `cat ./XAstroPack/objlist.list `
+set ALLEXTOBJS = ( $OBJFitsIOServer $OBJIFFTW $OBJLinAlg $OBJXAstroPack )
+
+set OBJPI = `cat ./PI/objlist.list `
+set OBJPIext = `cat ./PIext/objlist.list `
+set ALLPIOBJS = ( $OBJPI $OBJPIext )
+
+# echo $ALLOBJS 
+
+#   Si nous sommes en 64 bits
+if ( $?SOPHYA_SGI64 ) then 
+  set SHLCC = "CC -64 -shared"
+else
+  set SHLCC = "CC -shared"
+endif
+
+echo 'Going to ' $OBJ
+cd  $OBJ
+
+if ( ($opt == 'slball') || ($opt == 'slb') ) then
+  echo ' ======> Building slb' 
+  set cmd = "$SHLCC -o ${SLB}libsophya.so -all"
+  set cmde = "-notall -lpthread -lm"
+  echo $cmd $ALLOBJS $cmde
+  $cmd $ALLOBJS $cmde
+endif
+
+if ( ($opt == 'slball') || ($opt == 'slbext') ) then
+  echo ' ======> Building slbext' 
+  set cmd = "$SHLCC -o ${SLB}libextsophya.so -all"
+  set cmde = " ${EXTLIBL} -notall -L${SLB} -lsophya -lm"
+  echo $cmd $ALLEXTOBJS $cmde
+  $cmd $ALLEXTOBJS $cmde
+endif
+
+if ( ($opt == 'slball') || ($opt == 'slbpi') ) then
+  echo ' ======> Building slbpi' 
+  set cmd = "$SHLCC -o ${SLB}libPI.so -all"
+  set cmde = " ${EXTLIBL} -notall -L${SLB} -lextsophya -lsophya ${XPILIBS} -lpthread -lm"
+  echo $cmd $ALLPIOBJS $cmde
+  $cmd $ALLPIOBJS $cmde
+endif
+
+
+
+echo 'Back to' $cw
+cd $cw 
+
+exit 
Index: /tags/V_Dec2002/SophyaLib/Mgr/objlist_chk.csh
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/objlist_chk.csh	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/objlist_chk.csh	(revision 2309)
@@ -0,0 +1,18 @@
+#!/bin/csh
+
+set dcvs
+foreach f ( `ls -1` )
+  if( -e $f/CVS ) set dcvs = ( $dcvs $f )
+end
+
+foreach d ( $dcvs )
+  echo ">>>>>>>>>>  ${d}: diff ${d}.o.list objlist.list"
+  if( -e ${d}/${d}.o.list && -e $d/objlist.list ) then
+    diff ${d}/${d}.o.list ${d}/objlist.list
+  ###  if( $status == 0 ) echo "... No differences"
+  ###else
+  ###  echo "fichier(s) ${d}.o.list ou/et objlist.list inexistant(s)"
+  endif
+end
+
+exit 0
Index: /tags/V_Dec2002/SophyaLib/Mgr/progdirs
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/progdirs	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/progdirs	(revision 2309)
@@ -0,0 +1,3 @@
+Prog
+ProgAcq
+ProgPI
Index: /tags/V_Dec2002/SophyaLib/Mgr/progdirs_ccpn
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/progdirs_ccpn	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/progdirs_ccpn	(revision 2309)
@@ -0,0 +1,1 @@
+Prog
Index: /tags/V_Dec2002/SophyaLib/Mgr/sgienv.csh
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/sgienv.csh	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/sgienv.csh	(revision 2309)
@@ -0,0 +1,52 @@
+#!/bin/csh
+#
+#  Script pour la definition d'environnement SOPHYA (version SGI-magique)
+#                             R. Ansari   14/11/2000
+#
+set sgi64 = 'N'
+set sversion = 'pro'
+if ($#argv > 0)  then
+  if ($1 == '-h') then
+    echo 'Usage: source env.csh [pro/new/old] [64] ' 
+    echo '  Defines the environment for using SOPHYA '
+    echo '  First optional argument defines the library version (pro/new/... Default=pro)'
+    echo '  Second optional argument, == 64 -> 64 bit architecture version '
+    exit 0
+  endif
+  set sversion = $1
+  if ($#argv > 1)  then
+    if  ($2 == '64')  then
+	set sgi64 = 'Y'
+    endif
+  endif
+endif
+
+echo ' en.csh : setting environment variables for SOPHYA on SGI'
+
+setenv EROSCXX CC
+if ($sgi64 == 'Y')  then
+  echo ' SGI-64 bits architecture selected ... ' 
+  setenv DPCBASEREP /usr/local/Sophya64/$sversion
+  setenv EXTLIBDIR /usr/local/Sophya64/ExtLibs
+  setenv SOPHYA_SGI64 1
+  setenv LD_LIBRARY64_PATH .:${LD_LIBRARY64_PATH}:${DPCBASEREP}/IRIX64-CC/ShLibs
+else
+  setenv DPCBASEREP /usr/local/Sophya/$sversion
+  setenv EXTLIBDIR /usr/local/Sophya/ExtLibs
+  unsetenv SOPHYA_SGI64
+  setenv LD_LIBRARYN32_PATH .:${LD_LIBRARYN32_PATH}:${DPCBASEREP}/IRIX64-CC/ShLibs
+endif
+
+set path = ($path $DPCBASEREP/IRIX64-CC/Exec)
+
+echo ' EROSCXX= ' $EROSCXX
+echo ' DPCBASEREP= ' $DPCBASEREP
+echo ' EXTLIBDIR= ' $EXTLIBDIR
+echo ' LD_LIBRARYN32_PATH= ' $LD_LIBRARYN32_PATH 
+echo ' LD_LIBRARY64_PATH= ' $LD_LIBRARY64_PATH 
+echo ' PATH= ' $path
+
+exit 0
+
+
+
Index: /tags/V_Dec2002/SophyaLib/Mgr/tar_for_web.csh
===================================================================
--- /tags/V_Dec2002/SophyaLib/Mgr/tar_for_web.csh	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Mgr/tar_for_web.csh	(revision 2309)
@@ -0,0 +1,166 @@
+#!/bin/csh
+# - Avant toute chose, dans ce fichier:
+# 1-/ Mettre le bon numero de version: set VS = "V?.?"
+# 2-/ Mettre le bon TAG: set TAG = "V_???200?"
+# 2-/ Mettre le bon OSCC: set OSCC = "Linux-g++"
+# - Execution et creation du:
+# 1-/ Se placer dans ~/Planck/DPC: cd ~/Planck/DPC/.
+#     (repertoire au dessus des repertoires/modules Sophya)
+# 2-/ ./Mgr/tar_for_web.csh
+#----------------------------------------------
+set VS = "V1.4"
+set TAG = "V_Nov2002"
+set OSCC = "Linux-g++"
+###set OSCC = "OSF1-cxx"
+#----------------------------------------------
+set sophyarep = ( \
+    BaseTools DemoPIApp Examples FitsIOServer HiStats IFFTW \
+    LinAlg Manual Mgr NTools PI PIext PIGcont \
+    PMixer PrgMap PrgUtil ProgPI \
+    Samba SkyMap SysTools SkyT SUtils TArray Tests \
+    XAstroPack XephemAstroLib \
+    modules \
+    )
+#----------------------------------------------
+
+#################################################
+###### Check des variables d'environnement ######
+#################################################
+foreach d ( $sophyarep )
+  if( ! -d $d ) then
+    echo repertoire `pwd`/$d inexistant
+    exit -1
+  endif
+end
+if( ! $?DPCBASEREP ) then
+  echo Precisez DPCBASEREP
+  exit -1
+endif
+if( ! -e $DPCBASEREP/Include ) then
+  echo Pas de repertoire $DPCBASEREP/Include
+  exit -1
+endif
+if( ! -e $DPCBASEREP/${OSCC} ) then
+  echo Pas de repertoire $DPCBASEREP/${OSCC}
+  exit -1
+endif
+foreach d ( Libs ShLibs Exec )
+  if( ! -d $DPCBASEREP/${OSCC}/$d ) then
+    echo repertoire $DPCBASEREP/${OSCC}/$d inexistant
+    exit -1
+  endif
+end
+if( ! $?EXTLIBDIR ) then
+  echo Precisez EXTLIBDIR
+  exit -1
+endif
+if( ! -e $EXTLIBDIR/Include ) then
+  echo Pas de repertoire $EXTLIBDIR/Include
+  exit -1
+endif
+if( ! -e $EXTLIBDIR/${OSCC} ) then
+  echo Pas de repertoire $EXTLIBDIR/${OSCC}
+  exit -1
+endif
+foreach d ( Libs ShLibs )
+  if( ! -d $EXTLIBDIR/${OSCC}/$d ) then
+    echo repertoire $EXTLIBDIR/${OSCC}/$d inexistant
+    exit -1
+  endif
+end
+set SYS = `echo $OSCC | awk -F"-" '{print $1}'`
+echo "SOURCE        = " `pwd`
+echo "DPCBASEREP    = " $DPCBASEREP
+echo "EXTLIBDIR     = " $EXTLIBDIR
+echo "Version       = " $VS
+echo "Tag           = " $TAG
+echo "System-compil = " $OSCC
+echo "System        = " $SYS
+
+###############################
+###### Repertoire tampon ######
+###############################
+if( $?TMPDIR ) then
+  set tmp = $TMPDIR/tar_for_web
+else
+  set tmp = /tmp/tar_for_web
+endif
+echo "tmp        = " $tmp
+rm -rf $tmp
+mkdir $tmp
+if( $status != 0 ) then
+  echo impossible de creer le repertoire temporaire $tmp
+  exit -1
+endif
+mkdir $tmp/${VS}
+mkdir $tmp/ExtLibs
+
+############################
+###### Le Code Sophya ######
+############################
+echo '>>>>>>>>' Code de Sophya
+mkdir $tmp/${VS}/Src
+cat >! $tmp/${VS}/Src/COPYRIGHT <<EOF
+  ---------------------------------
+      SOPHYA ::
+      Version: ${VS} - ${TAG}
+       Copyright (C) 1998-2002
+   LAL / IN2P3-CNRS DAPNIA/SPP CEA
+  ---------------------------------
+EOF
+foreach d ( $sophyarep )
+  echo repertoire $d
+  tar -chf - $d |(cd $tmp/${VS}/Src/.; tar -xf -)
+  rm -rf $tmp/${VS}/Src/$d/CVS
+end
+pushd $tmp > /dev/null
+tar -cf sophya_src.tar ${VS}/Src
+rm -rf ${VS}/Src
+gzip -f sophya_src.tar
+popd > /dev/null
+
+##################################################
+###### Les librairies et executables Sophya ######
+##################################################
+echo '>>>>>>>>' Librairies et executables de Sophya
+pushd $DPCBASEREP > /dev/null
+tar -chf - Include |(cd $tmp/${VS}/.; tar -xf -)
+popd > /dev/null
+pushd $DPCBASEREP/${OSCC} > /dev/null
+tar -chf - Libs   |(cd $tmp/${VS}/.; tar -xf -)
+tar -chf - ShLibs |(cd $tmp/${VS}/.; tar -xf -)
+tar -chf - Exec   |(cd $tmp/${VS}/.; tar -xf -)
+popd > /dev/null
+pushd $tmp > /dev/null
+tar -cf sophya_${SYS}.tar ${VS}
+rm -rf ${VS}
+gzip -f sophya_${SYS}.tar
+popd > /dev/null
+
+########################################
+###### Les librairies exterieures ######
+########################################
+echo '>>>>>>>>' Librairies exterieures de Sophya
+pushd $EXTLIBDIR > /dev/null
+tar -chf - Include |(cd $tmp/ExtLibs/.; tar -xf -)
+popd > /dev/null
+pushd $EXTLIBDIR/${OSCC} > /dev/null
+tar -chf - Libs   |(cd $tmp/ExtLibs/.; tar -xf -)
+tar -chf - ShLibs |(cd $tmp/ExtLibs/.; tar -xf -)
+popd > /dev/null
+pushd $tmp > /dev/null
+tar -cf sophya_extlibs_${SYS}.tar ExtLibs
+rm -rf ExtLibs
+gzip -f sophya_extlibs_${SYS}.tar
+popd > /dev/null
+
+####################
+###### Resume ######
+####################
+echo "---------------------------------------"
+du -sk $tmp/sophya*.tar.gz
+echo "---------------------------------------"
+ls -ltr $tmp/sophya*.tar.gz
+echo "---------------------------------------"
+
+exit 0
Index: /tags/V_Dec2002/SophyaLib/NTools/FSAppIrrSmpl.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/FSAppIrrSmpl.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/FSAppIrrSmpl.cc	(revision 2309)
@@ -0,0 +1,347 @@
+#include "FSAppIrrSmpl.h"
+
+
+FSApproximationIrregularSampling::FSApproximationIrregularSampling()  : fftIntfPtr_(NULL) {;}
+
+FSApproximationIrregularSampling::FSApproximationIrregularSampling(TVector<double>& sampling, double offset, double range) 
+  {
+    initFFT();
+    makeSamplingVector(sampling, offset, range);
+    M_ = 0;
+  }
+
+
+FSApproximationIrregularSampling::~FSApproximationIrregularSampling()
+{if (fftIntfPtr_!=NULL) delete fftIntfPtr_;}
+
+void FSApproximationIrregularSampling::makeRHS(TVector<complex<double> >& coefSolution)
+{
+  int k;
+  if (exponFourier_.Size() == 0) calculeExponentiellesFourier();
+  coefSolution.ReSize(2*M_+1);
+  coefSolution = complex<double>(0.,0.);
+  int nbEchantillons = samplingValues_.Size();
+
+  // initialisation d'un tableau de travail pour calcul des termes
+  // du second membre par recurrence
+  TVector<complex<double> > travail(nbEchantillons);
+  for (k=0; k < nbEchantillons; k++)
+    {
+      travail(k) = poids_(k)*signal_(k);
+      coefSolution(M_) +=  travail(k);
+    }
+
+  // recurrence
+  for (k=1; k<=M_; k++)
+    {
+      int j;
+      for (j=0; j < nbEchantillons; j++)
+	{
+	  travail(j) *= exponFourier_(j);
+	  coefSolution(M_+k) += travail(j);
+	}
+      coefSolution(M_-k) = conj(coefSolution(M_+k));
+    }
+}
+
+void FSApproximationIrregularSampling::makeToeplitzMatrix(int M)
+{
+  int j,k;
+  M_ = M;
+  int nbEchantillons = samplingValues_.Size();
+  // matrice de Toeplitz
+   if (exponFourier_.Size() == 0) calculeExponentiellesFourier();
+
+  TVector<complex<double> > gamma(2*M_+1);
+  gamma = complex<double>(0.,0.);
+  // initialisation d'un tableau de travail pour calcul des termes
+  // de la matrice par recurrence
+  TVector<complex<double> > travail(nbEchantillons);
+  travail = poids_;
+
+  for (j=0; j<nbEchantillons; j++) gamma(0) += travail(j);
+
+  // recurrence
+  for (k=1; k<=2*M_; k++)
+    {
+
+      for (j=0; j<nbEchantillons; j++)
+	{
+	  travail(j) *= exponFourier_(j);
+	  gamma(k) += travail(j);
+	}
+
+    }
+  
+  tptz_.setMatrix(gamma);
+}
+void FSApproximationIrregularSampling::approximateSignal(int M, const TVector<double>& signal)
+{
+  int k;
+    if (delta_ <= 1./(2.*M) )
+      {
+	cout << " FSApproximationIrregularSampling : BON ECHANTILLONNAGE " << endl;
+      }
+    else
+      {
+	cout << " FSApproximationIrregularSampling : ATTENTION : SIGNAL SOUS-ECHANTILLONNE " << endl;
+	cout << " deltaMax (normalise) = " << delta_ << " devrait etre inferieur a " << 1./(2.*M) << endl;
+	cout << " ecart max intervient entre echantillon no " << nokdelta_ << " et le suivant, abscisse= " <<  samplingValues_(nokdelta_)*samplingRange_+samplingOffset_ << endl;
+
+      }
+    //  PrtTim(" avant toeplitz " );
+
+    if ( M != M_ ) makeToeplitzMatrix(M);
+
+    // PrtTim(" fin toeplitz " );
+
+ 
+   makeSignalVector(signal);
+   //  PrtTim(" fin fabrication signal " );
+
+    // second membre
+    
+    TVector<complex<double> > coefSolution;
+    makeRHS(coefSolution);
+    int j;
+    // PrtTim(" fin fabrication second membre " );
+
+    int niter =  tptz_.gradientToeplitz(coefSolution);
+    // int niter =  tptz_.gradientToeplitzPreconTChang(coefSolution);
+    cout << " FSApproximationIrregularSampling::approximateSignal : converged in " << niter << " iterations " << endl;
+    coefFourier_.ReSize(M_+1);
+    coefFourier_ = coefSolution(Range(M_, 2*M_));
+}
+
+// la periode normalisee 1 est divisee en nbInterv intervalles
+// les valeurs de la solution sont donnes en 0, 1/n, ..... (n-1)/n 
+// le calcul est beaucoup plus rapide si nbInterv est pair (FFT)
+void FSApproximationIrregularSampling::restaureRegularlySampledSignal(int nbInterv, TVector<double>& solution) const
+{
+  cout << " c'est celui que je corrige " << endl;
+  int k; 
+  if (nbInterv < 2*M_+1) 
+      {
+	solution.ReSize(nbInterv); 
+	double delta = 1./nbInterv;
+	for (k=0; k<nbInterv; k++)
+	  {
+	    double u = k*delta;
+	    solution(k) = valeursSerie(u);
+	  }
+      }
+    else
+      {
+	TVector<complex<double> > TFf(nbInterv);
+	TVector<complex<double> > bidon(nbInterv);
+	TFf = complex<double>(0.,0.);
+	TFf(Range(0,M_)) = coefFourier_;
+	for ( k=1; k<= M_; k++)
+	  { 
+	    TFf(nbInterv-k) = conj(coefFourier_(k));
+	  }
+	fftIntfPtr_-> FFTBackward(TFf, bidon);
+	cout << " taille de bidon "<< bidon.Size() << endl;
+	solution.ReSize(nbInterv);
+	for (k=0; k< nbInterv; k++) solution(k) = bidon(k).real();
+      }
+  reshapeSignalInUsersFrame(solution);
+}
+
+void FSApproximationIrregularSampling::computeSignalOnASampling(const TVector<double>& abscisses, TVector<double>& solution ) const
+{
+  int k;
+  int n= abscisses.Size();
+  if (n<=0) 
+    {
+      cout << " restaurationEnPoints: vecteurs de points vide " << endl;
+      return;
+    }
+  TVector<double> abscissesLocales;
+  abscissesLocales = abscisses;
+  matchToSamplingReference(abscissesLocales);
+  solution.ReSize(n);
+  for (k=0; k<n; k++)
+    {
+      double u = abscissesLocales(k);
+      solution(k) =  valeursSerie(u);
+    }
+  reshapeSignalInUsersFrame(abscisses, solution);
+
+}
+
+double FSApproximationIrregularSampling::estimationConditionnement() const
+{
+  double deuxDeltaM = 2.*delta_*M_; 
+  double cond = (1.+deuxDeltaM)/(1.-deuxDeltaM);
+  cond *= cond;
+  return cond;
+}
+
+void  FSApproximationIrregularSampling::samplingValues(TVector<double>& sv) const 
+{
+  int k; 
+  int n = samplingValues_.Size();
+  sv.ReSize(n);
+  for (k=0; k<n;k++)
+    {
+      sv(k) = samplingOffset_+samplingRange_*samplingValues_(k);
+    }
+
+}
+
+// terme constant, puis cos, sin, cos, sin......
+void FSApproximationIrregularSampling::coeffCosSin(TVector<double>& coef) const
+{
+  int j;
+  coef.ReSize(2*M_+1);
+  coef(0) = coefFourier_(0).real();
+  for (j=1; j<M_; j++)
+    {
+      double aj =  2.*coefFourier_(j).real();
+      double bj =  -2.*coefFourier_(j).imag();
+      coef(2*(j-1)+1) = aj;
+      coef(2*(j-1)+2) = bj;
+    }
+  coef *= normeSignal_;
+}  
+
+// exprime les valeurs d'abscisses, selon la reference locale
+void FSApproximationIrregularSampling::matchToSamplingReference(TVector<double>& sampling) const
+
+{
+  int k;
+  int compteur = sampling.Size();
+  double fac = 1./samplingRange_;
+  for (k=0; k<compteur; k++)
+    {
+      sampling(k) = (sampling(k)-samplingOffset_)*fac;
+ 
+    }
+  if ( sampling(0) <0. || sampling(compteur-1) >1. )
+    {
+      cout << " matchToSamplingReference: points hors [0.,1.] " << endl;
+      cout << " " << sampling(0) << " " << sampling(compteur-1) << endl;
+    }
+}
+
+// exprime les valeurs d'echantillonnage entre 0 et 1
+void FSApproximationIrregularSampling::resizeSamplingIn_0_1(double offset, double range) 
+{
+  int k;
+  int compteur = samplingValues_.Size();
+  samplingOffset_ = offset;
+  samplingRange_ = range;
+  double fac = 1./samplingRange_;
+  for (k=0; k<compteur ;k++)
+    {
+      samplingValues_(k) = (samplingValues_(k)-samplingOffset_)*fac;
+    }
+}
+
+void FSApproximationIrregularSampling::computeWeights()
+{
+  int k;
+  int nbEchantillons = samplingValues_.Size();
+  nokdelta_ = 0;
+
+  // calcul de l'ecart maximum entre deux temps d'echantillonnage consecutifs
+  delta_ = samplingValues_(0)-samplingValues_(nbEchantillons-1)+1;
+  for (k=0; k< nbEchantillons-1; k++)
+    {
+      double diff = samplingValues_(k+1)-samplingValues_(k);
+      if ( diff > delta_ )
+	{
+	  delta_ = diff;
+	  nokdelta_ = k;
+	}
+    }
+  // calcul des poids (pour tenir compte de l'irregularite de 
+  // l'echantillonnage)
+  poids_.ReSize(nbEchantillons);
+  poids_(0) = 0.5*(samplingValues_(1)-samplingValues_(nbEchantillons-1) + 1.);
+  for (k=1; k< nbEchantillons-1; k++)
+    {
+      poids_(k) = 0.5*(samplingValues_(k+1)-samplingValues_(k-1));
+    }
+  poids_(nbEchantillons-1) = 0.5*(samplingValues_(0) +1 - samplingValues_(nbEchantillons-2));
+  
+}
+void FSApproximationIrregularSampling::NormSignal()
+{
+  int k;
+  int nbEchantillons = samplingValues_.Size();
+  normeSignal_=0;
+  for (k=0; k< nbEchantillons; k++)
+    {
+      double s = signal_(k); 
+      normeSignal_ += s*s*poids_(k);
+    }
+  normeSignal_=sqrt(normeSignal_);
+  double fac = 1./normeSignal_;
+  signal_ *= fac;
+}
+
+
+
+void FSApproximationIrregularSampling::reshapeSignalInUsersFrame(const TVector<double>& abscisses, TVector<double>& resultat) const
+{
+  if (resultat.Size() <= 0) 
+    {
+      cout << " reshapeSignalInUsersFrame: vecteur solution VIDE" << endl;
+    }
+  resultat *= normeSignal_;
+}
+
+void FSApproximationIrregularSampling::reshapeSignalInUsersFrame(TVector<double>& resultat) const
+{
+  if (resultat.Size() <= 0) 
+    {
+      cout << " reshapeSignalInUsersFrame: vecteur solution VIDE" << endl;
+    }
+  resultat *= normeSignal_;
+}
+
+
+void FSApproximationIrregularSampling::makeSamplingVector(const TVector<double>& sampling, double offset, double range)
+{
+  samplingValues_.ReSize(sampling.Size());
+  samplingValues_ = sampling;
+  resizeSamplingIn_0_1(offset, range);
+  computeWeights();
+}
+
+void FSApproximationIrregularSampling::makeSignalVector(const TVector<double>& signal)
+{
+  int n = samplingValues_.Size();
+    if (n != signal.Size() )
+      {
+	cout << " echantillonnage et signal n'ont pas les memes dimensions " << endl;
+      }
+    signal_ = signal;
+    NormSignal();
+}
+
+
+
+
+
+void FSApproximationIrregularSampling::restaureSignal(TVector<double>& solution) const
+{
+  int k;
+  int n= samplingValues_.Size();
+  if (n<=0) 
+    {
+      cout << " restaurationEnPoints: vecteurs de points vide " << endl;
+      return;
+    }
+  solution.ReSize(n);
+  for (k=0; k<n; k++)
+    {
+      double u = samplingValues_(k);
+      solution(k) = valeursSerie(u);
+    }
+  reshapeSignalInUsersFrame(solution);
+}
+
+
Index: /tags/V_Dec2002/SophyaLib/NTools/FSAppIrrSmpl.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/FSAppIrrSmpl.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/FSAppIrrSmpl.h	(revision 2309)
@@ -0,0 +1,166 @@
+#ifndef FSAPPIRRSMPL_SEEN
+#define FSAPPIRRSMPL_SEEN
+
+
+// approximation par serie de Fourier avec echantillonnage irregulier
+//------------------------------------------------------------------
+//   *****   Guy Le Meur -- LAL-Orsay mars 2002 ****************
+//-------------------------------------------------------------------
+
+
+
+#include <math.h>
+#include <iostream.h>
+
+
+#include "machdefs.h"    // Definitions specifiques SOPHYA
+#include "nbmath.h"
+#include "timing.h"
+#include "array.h"
+#include "fftservintf.h"
+#include "fftpserver.h"
+
+#include "toeplitzMatrix.h"
+
+
+////////////////////////////////////////////////////////////////////
+// Un signal donne , suppose a bande de frequences limitee, de longueur 
+// finie est periodise. Ce signal periodise est suppose developpe 
+// en serie de Fourier finie: l'approximation consiste a rechercher 
+// les coefficients de cette serie de Fourier. Cela est fait en utilisant 
+// le fait que la matrice du systeme a ecrire est Toeplitz. On utilise
+// une classe ToeplitzMatrix, qui utilise les FFT pour la resolution
+// L'utilisation standard comporte les etapes suivantes : 
+//
+//   constructeur --> definit l'echantillonnage et l'amplitude
+//                    des abscisses (pour periodisation)
+//
+//   methode approximateSignal(nbFreq, signal) : definit la bande
+//                    de frequences et les valeurs du signal
+//
+//   recuperation de valeurs approximees ou interpolees : 
+//   methodes:  . restaureSignal() (signal "debruite" aux valeurs 
+//                                              d'echantionnage) 
+//              . restaureRegularlySampledSignal() (signal recalcule
+//                          sur un echantillonnage regulier quelconque)
+//              . computeSignalOnASampling()  (signal recalcule
+//                          sur un echantillonnage irregulier quelconque)
+//
+//  on peut aussi recuperer les valeurs des coefficients du developpement
+//  en serie de Fourier (methodes complexFourierCoef() et coeffCosSin()
+/////////////////////////////////////////////////////////////////////
+
+
+class FSApproximationIrregularSampling
+{
+
+private:
+  // verouiller le clonage
+FSApproximationIrregularSampling(const FSApproximationIrregularSampling&) {}
+FSApproximationIrregularSampling &operator = (const FSApproximationIrregularSampling&) {return *this;}
+
+
+public:
+FSApproximationIrregularSampling();
+
+FSApproximationIrregularSampling(TVector<double>& sampling, double offset, double range);
+
+~FSApproximationIrregularSampling(); 
+
+void approximateSignal(int M, const TVector<double>& signal);
+
+void restaureRegularlySampledSignal(int n, TVector<double>& solution) const;
+
+
+// le vecteur d'abscissses est suppose ordonne et appartenir a l'intervalle 
+// de definition du signal
+ void computeSignalOnASampling(const TVector<double>& abscisses, TVector<double>& solution ) const;
+
+double estimationConditionnement() const;
+
+void  samplingValues(TVector<double>& sv) const; 
+
+void restaureSignal(TVector<double>& sol) const; 
+
+
+inline void sampledSignal(TVector<double>& signal) const 
+{
+  signal = signal_;  
+  reshapeSignalInUsersFrame(samplingValues_, signal);
+}
+inline const TVector<double>& weights() const { return poids_;}
+
+// coefficients complexes ck, pour k=0,M
+inline void complexFourierCoef(TVector<complex<double> >& coef) const
+{
+  int n= coefFourier_.Size();
+  coef.ReSize(n);
+  coef = coefFourier_;
+  coef *=  normeSignal_;
+}
+// terme constant, puis cos, sin, cos, sin......
+void coeffCosSin(TVector<double>& coef) const;
+
+private:
+
+inline void initFFT()
+{
+  fftIntfPtr_ =new FFTPackServer;
+  fftIntfPtr_->setNormalize(false);
+    
+}
+inline double valeursSerie(double u) const
+{
+  complex<double> somme =complex<double>(0.,0.);
+  for (int j=1; j<=M_; j++)
+    {
+      double angle = 2.*M_PI*j*u;
+      complex<double> expon = complex<double>(cos(angle), sin(angle));
+      somme += coefFourier_(j)*expon;
+    }
+  return coefFourier_(0).real()+ 2*somme.real();
+}
+
+inline void calculeExponentiellesFourier()
+{
+  int j;
+  int n = samplingValues_.Size();
+  exponFourier_.ReSize(n);
+  for (j=0; j<n; j++)
+    {
+      double angle=-2.*M_PI*samplingValues_(j);
+      exponFourier_(j) = complex<double>(cos(angle),sin(angle));
+    }
+}
+
+void matchToSamplingReference(TVector<double>& sampling) const;
+void resizeSamplingIn_0_1(double offset, double range); 
+
+void reshapeSignalInUsersFrame(const TVector<double>& abscisses, TVector<double>& resultat) const;
+void reshapeSignalInUsersFrame(TVector<double>& resultat) const;
+ 
+void makeToeplitzMatrix(int M);
+void makeRHS(TVector<complex<double> >& coefSolution);
+void makeSamplingVector(const TVector<double>& sampling, double offset, double range);
+void makeSignalVector(const TVector<double>& signal);
+void computeWeights();
+void NormSignal();
+
+
+FFTServerInterface* fftIntfPtr_;
+Toeplitz tptz_;
+TVector<double> samplingValues_;
+TVector<double> poids_;
+TVector<double> signal_;
+TVector<complex<double> > exponFourier_;
+TVector<complex<double> > coefFourier_;
+double samplingOffset_;
+double samplingRange_;
+double normeSignal_;
+double delta_;
+int nokdelta_;
+int M_;
+};
+
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/Makefile
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/Makefile	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/Makefile	(revision 2309)
@@ -0,0 +1,351 @@
+include ../Mgr/Makefile.h
+ 
+all: $(LIB)libNTools.a
+clean:
+	rm -f $(OBJ)FSAppIrrSmpl.o $(OBJ)cimage.o $(OBJ)cspline.o $(OBJ)datatypes.o $(OBJ)dates.o $(OBJ)difeq.o $(OBJ)dynccd.o $(OBJ)fct1dfit.o $(OBJ)fct2dfit.o $(OBJ)fftmserver.o $(OBJ)fftpserver.o $(OBJ)fftservintf.o $(OBJ)generaldata.o $(OBJ)generalfit.o $(OBJ)imageop.o $(OBJ)integ.o $(OBJ)median.o $(OBJ)ntoolsinit.o $(OBJ)objfitter.o $(OBJ)perandom.o $(OBJ)poly.o $(OBJ)rk4cdifeq.o $(OBJ)simplesort.o $(OBJ)tabmath.o $(OBJ)datime.o $(OBJ)fftmayer_r4.o $(OBJ)fftmayer_r8.o $(OBJ)fftpackc.o $(OBJ)matxop.o $(OBJ)nbmath.o $(OBJ)nbtri.o
+	rm -f $(LIB)libNTools.a
+$(LIB)libNTools.a : $(OBJ)FSAppIrrSmpl.o $(OBJ)cimage.o $(OBJ)cspline.o $(OBJ)datatypes.o $(OBJ)dates.o $(OBJ)datime.o $(OBJ)difeq.o $(OBJ)dynccd.o $(OBJ)fct1dfit.o $(OBJ)fct2dfit.o $(OBJ)fftmayer_r4.o $(OBJ)fftmayer_r8.o $(OBJ)fftmserver.o $(OBJ)fftpackc.o $(OBJ)fftpserver.o $(OBJ)fftservintf.o $(OBJ)generaldata.o $(OBJ)generalfit.o $(OBJ)integ.o $(OBJ)matxop.o $(OBJ)median.o $(OBJ)nbmath.o $(OBJ)nbtri.o $(OBJ)ntoolsinit.o $(OBJ)objfitter.o $(OBJ)perandom.o $(OBJ)poly.o $(OBJ)rk4cdifeq.o $(OBJ)simplesort.o $(OBJ)tabmath.o
+	$(ARCXX) $(ARCXXFLAGS) $@ $($(ARARGS))
+ifeq ($(CXX),cxx)
+	$(CXX) $? $(CPPFLAGS) $(CXXFLAGS) -o $(OBJ)xx.x -Hf
+endif 
+ 
+$(OBJ)FSAppIrrSmpl.o: FSAppIrrSmpl.cc FSAppIrrSmpl.h \
+ $(INC)machdefs.h nbmath.h \
+ $(INC)smathconst.h \
+ $(INC)timing.h \
+ $(INC)array.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)tmatrix.h \
+ $(INC)tvector.h \
+ $(INC)matharr.h \
+ $(INC)fioarr.h \
+ $(INC)sopemtx.h fftservintf.h fftpserver.h \
+ $(INC)toeplitzMatrix.h \
+ $(INC)nbmath.h \
+ $(INC)fftservintf.h \
+ $(INC)fftpserver.h
+$(OBJ)cimage.o: cimage.cc $(INC)machdefs.h \
+ $(INC)pexceptions.h cimage.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)fioarr.h \
+ $(INC)tvector.h
+$(OBJ)cspline.o: cspline.cc $(INC)machdefs.h \
+ nbtri.h cspline.h $(INC)pexceptions.h
+$(OBJ)datatypes.o: datatypes.cc datatypes.h \
+ $(INC)machdefs.h
+$(OBJ)dates.o: dates.cc $(INC)machdefs.h \
+ $(INC)perrors.h \
+ $(INC)pexceptions.h dates.h
+$(OBJ)difeq.o: difeq.cc difeq.h $(INC)machdefs.h \
+ $(INC)pexceptions.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)ctimer.h
+$(OBJ)dynccd.o: dynccd.cc $(INC)machdefs.h fmath.h \
+ perandom.h $(INC)histos.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)fmath.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h nbrandom.h \
+ $(INC)srandgen.h cimage.h \
+ $(INC)fioarr.h dynccd.h
+$(OBJ)fct1dfit.o: fct1dfit.cc $(INC)machdefs.h \
+ fct1dfit.h generalfit.h $(INC)pexceptions.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h generaldata.h \
+ $(INC)ntupintf.h poly.h peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h fmath.h nbconst.h tabmath.h
+$(OBJ)fct2dfit.o: fct2dfit.cc $(INC)machdefs.h \
+ fct2dfit.h generalfit.h $(INC)pexceptions.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h generaldata.h \
+ $(INC)ntupintf.h poly.h peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h fmath.h nbconst.h tabmath.h \
+ simps2d.h
+$(OBJ)fftmserver.o: fftmserver.cc fftmserver.h fftservintf.h \
+ $(INC)machdefs.h \
+ $(INC)pexceptions.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)tvector.h fftmayer.h
+$(OBJ)fftpserver.o: fftpserver.cc fftpserver.h fftservintf.h \
+ $(INC)machdefs.h \
+ $(INC)pexceptions.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)tvector.h fftpackc.h
+$(OBJ)fftservintf.o: fftservintf.cc fftservintf.h \
+ $(INC)machdefs.h \
+ $(INC)pexceptions.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)tvector.h
+$(OBJ)generaldata.o: generaldata.cc \
+ $(INC)machdefs.h \
+ $(INC)strutil.h nbtri.h generalfit.h \
+ $(INC)pexceptions.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h generaldata.h \
+ $(INC)ntupintf.h poly.h peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h fmath.h
+$(OBJ)generalfit.o: generalfit.cc $(INC)machdefs.h \
+ $(INC)pexceptions.h generalfit.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h generaldata.h \
+ $(INC)ntupintf.h poly.h peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h fmath.h \
+ $(INC)sopemtx.h
+$(OBJ)integ.o: integ.cc integ.h classfunc.h $(INC)machdefs.h \
+ $(INC)pexceptions.h generalfit.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h generaldata.h \
+ $(INC)ntupintf.h poly.h peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h fmath.h
+$(OBJ)median.o: median.cc
+$(OBJ)ntoolsinit.o: ntoolsinit.cc $(INC)machdefs.h \
+ ntoolsinit.h $(INC)tarrinit.h \
+ $(INC)sophyainit.h poly.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h fmath.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h generaldata.h \
+ $(INC)ntupintf.h cimage.h \
+ $(INC)fioarr.h tabmath.h nbconst.h dates.h \
+ datime.h
+$(OBJ)objfitter.o: objfitter.cc objfitter.h \
+ $(INC)machdefs.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h cimage.h \
+ $(INC)fioarr.h \
+ $(INC)tvector.h \
+ $(INC)histos.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)fmath.h \
+ $(INC)histos2.h \
+ $(INC)hisprof.h generalfit.h generaldata.h \
+ $(INC)ntupintf.h poly.h peida.h
+$(OBJ)perandom.o: perandom.cc $(INC)machdefs.h \
+ $(INC)pexceptions.h perandom.h \
+ $(INC)histos.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)fmath.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h nbrandom.h \
+ $(INC)srandgen.h pemath.h
+$(OBJ)poly.o: poly.cc $(INC)machdefs.h poly.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h fmath.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h linfit.h \
+ $(INC)sopemtx.h \
+ $(INC)fioarr.h
+$(OBJ)rk4cdifeq.o: rk4cdifeq.cc $(INC)machdefs.h \
+ rk4cdifeq.h difeq.h $(INC)pexceptions.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)ctimer.h
+$(OBJ)simplesort.o: simplesort.cc $(INC)machdefs.h \
+ simplesort.h peida.h $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)pexceptions.h fmath.h
+$(OBJ)tabmath.o: tabmath.cc $(INC)machdefs.h \
+ tabmath.h peida.h $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)pexceptions.h fmath.h nbconst.h
+$(OBJ)datime.o: datime.c $(INC)machdefs.h \
+ $(INC)strutil.h nbconst.h datime.h
+$(OBJ)fftmayer_r4.o: fftmayer_r4.c fftmayer.h \
+ $(INC)machdefs.h trigtbl.h
+$(OBJ)fftmayer_r8.o: fftmayer_r8.c fftmayer.h \
+ $(INC)machdefs.h trigtbl.h
+$(OBJ)fftpackc.o: fftpackc.c fftpackc.h \
+ $(INC)machdefs.h
+$(OBJ)matxop.o: matxop.c matxop.h nbmath.h \
+ $(INC)machdefs.h \
+ $(INC)smathconst.h
+$(OBJ)nbmath.o: nbmath.c nbmath.h $(INC)machdefs.h \
+ $(INC)smathconst.h matxop.h nbinteg.h \
+ nbtri.h
+$(OBJ)nbtri.o: nbtri.c nbtri.h $(INC)machdefs.h
Index: /tags/V_Dec2002/SophyaLib/NTools/Makefile.am
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/Makefile.am	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/Makefile.am	(revision 2309)
@@ -0,0 +1,13 @@
+lib_LIBRARIES = libNTools.a
+
+libNTools_a_SOURCES = \
+cimage.cc     dynccd.cc      fftpackc.c      ntoolsinit.cc  simplesort.cc\
+cspline.cc    fct1dfit.cc    fftpserver.cc   integ.cc    ntupintf.cc    tabmath.cc   \
+datatypes.cc  fct2dfit.cc    fftserver.cc    matxop.c    objfitter.cc  \
+dates.cc      fftmayer_r4.c  fftservintf.cc  median.cc   perandom.cc   \
+datime.c      fftmayer_r8.c  generaldata.cc  nbmath.c    poly.cc       \
+difeq.cc      fftmserver.cc  generalfit.cc   nbtri.c     rk4cdifeq.cc
+
+# imageop.cc excluded
+
+DEFS = -I.. -I../include
Index: /tags/V_Dec2002/SophyaLib/NTools/cimage.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/cimage.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/cimage.cc	(revision 2309)
@@ -0,0 +1,207 @@
+//  Classes image heritant de TMatrix<T>
+//                       R.Ansari, C.Magneville 07/2000    
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "pexceptions.h"
+#include "cimage.h"
+#include "datatype.h"
+#include <typeinfo>
+
+/*!
+   \class SOPHYA::Image
+   \ingroup NTools
+   This class specializes the Matrix class, for representing intensity 
+   (or grey-level) images. It adds the possibility of defining pixel
+   size and offset. The convention for the acces operator is also
+   changed, compared to the matrix class.
+*/
+
+//! Default constructor - Pixel array not allocated
+template <class T>
+Image<T>::Image()
+// Constructeur par defaut.
+  : TMatrix<T>()
+{
+  SetOrg();
+  SetPixelSize();
+}
+
+//! Constructor, with specification of the image size, pixel size and offsets
+template <class T>
+Image<T>::Image(sa_size_t sizx, sa_size_t sizy, r_8 szpx, r_8 szpy, r_8 orgx, r_8 orgy)
+// Constructeur par defaut.
+  : TMatrix<T>(sizy, sizx) 
+{
+  SetOrg(orgx, orgy);
+  SetPixelSize(szpx, szpy);
+}
+
+//! Copy constructor
+template <class T>
+Image<T>::Image(const Image<T>& a)
+  : TMatrix<T>(a)
+{
+  SetOrg(a.XOrg(), a.YOrg() );
+  SetPixelSize(a.XPixSize(), a.YPixSize());
+}
+
+
+//! Copy constructor with possibility of duplicating the pixel array
+/*!
+  \param share : if true, the data is shared, duplicated if false.
+*/
+template <class T>
+Image<T>::Image(const Image<T>& a, bool share)
+  : TMatrix<T>(a, share)
+{
+  SetOrg(a.XOrg(), a.YOrg() );
+  SetPixelSize(a.XPixSize(), a.YPixSize());
+}
+
+//! Destructor 
+template <class T>
+Image<T>::~Image()
+{
+}
+
+
+// --------------------------------------------------------
+//   Les objets delegues pour la gestion de persistance 
+// --------------------------------------------------------
+/*!
+  \class SOPHYA::FIO_Image
+  \ingroup Image
+  Class for persistent management of Image
+
+ */
+///////////////////////////////////////////////////////////
+
+//! Default constructor
+template <class T>
+FIO_Image<T>::FIO_Image()
+  : FIO_TArray<T>()
+{
+}
+
+
+//! Constructor from the file \b filename
+template <class T>
+FIO_Image<T>::FIO_Image(string const & filename) 
+  : FIO_TArray<T>(filename) 
+{
+}
+
+//! Constructor from the Image \b obj
+template <class T>
+FIO_Image<T>::FIO_Image(const Image<T> & obj) 
+  : FIO_TArray<T>()
+{ 
+  dobj = new Image<T>(obj, true);
+  ownobj=true; 
+}
+
+//! Connect with a Image \b obj
+template <class T>
+FIO_Image<T>::FIO_Image(Image<T> * obj) 
+  : FIO_TArray<T>(obj)
+{ 
+}
+
+
+//! Connect Image \b o
+template <class T>
+void FIO_Image<T>::SetDataObj(AnyDataObj & o)
+{
+  Image<T> * po = dynamic_cast< Image<T> * >(&o);
+  if (po == NULL) {
+    char buff[160];
+    sprintf(buff,"FIO_Image<%s>::SetDataObj(%s) - Object type  error ! ",
+	    DataTypeInfo<T>::getTypeName().c_str(), typeid(o).name());
+    throw TypeMismatchExc(PExcLongMessage(buff));        
+  }
+  if (ownobj && dobj) delete dobj;
+  dobj = po; ownobj = false;
+} 
+
+template <class T>
+void FIO_Image<T>::ReadSelf(PInPersist& is)
+{
+  if (dobj == NULL) dobj = new Image<T>;
+  Image<T> * img = dynamic_cast<Image<T> * > (dobj);
+// On lit les 3 premiers uint_4
+//  0: Numero de version,  1 : reserve
+  uint_4 itab[3];
+  is.Get(itab,3);
+
+// Image<T> part data
+  r_8 orgx, orgy;
+  is.Get(orgx);
+  is.Get(orgy);
+  img->SetOrg(orgx, orgy);
+  r_8 szx, szy;
+  is.Get(szx);
+  is.Get(szy);
+  img->SetPixelSize(szx, szy);
+
+// Reading the TArray part 
+  FIO_TArray<T>::ReadSelf(is);
+}
+
+template <class T>
+void FIO_Image<T>::WriteSelf(POutPersist& os) const
+{
+  if (dobj == NULL)   return;
+  Image<T> * img = dynamic_cast<Image<T> * > (dobj);
+//  On ecrit 3 uint_4 .... 
+  uint_4 itab[3];
+  itab[0] = 1;  // Numero de version a 1
+  itab[1] = 0; 
+  itab[2] = 0; 
+  os.Put(itab,3);
+
+// Image<T> part data
+  os.Put(img->XOrg());
+  os.Put(img->XOrg());
+  os.Put(img->XPixSize());
+  os.Put(img->YPixSize());
+
+// Writing the TArray part 
+  FIO_TArray<T>::WriteSelf(os);
+}
+
+///////////////////////////////////////////////////////////////
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template Image<uint_2>
+#pragma define_template Image<int_4>
+#pragma define_template Image<int_8>
+#pragma define_template Image<r_4>
+#pragma define_template Image<r_8> 
+//#pragma define_template Image< complex<r_4> > 
+//#pragma define_template Image< complex<r_8> > 
+
+#pragma define_template FIO_Image<uint_2>
+#pragma define_template FIO_Image<int_4>
+#pragma define_template FIO_Image<int_8>
+#pragma define_template FIO_Image<r_4>
+#pragma define_template FIO_Image<r_8>
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class Image<uint_2>;
+template class Image<int_4>;
+template class Image<int_8>;
+template class Image<r_4>;
+template class Image<r_8>;
+//template class Image< complex<r_4> >;
+//template class Image< complex<r_8> >;
+
+template class FIO_Image<uint_2>;
+template class FIO_Image<int_4>;
+template class FIO_Image<int_8>;
+template class FIO_Image<r_4>;
+template class FIO_Image<r_8>;
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/cimage.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/cimage.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/cimage.h	(revision 2309)
@@ -0,0 +1,141 @@
+// This may look like C code, but it is really -*- C++ -*-
+//  Classes image heritant de TMatrix<T>
+//                       R.Ansari, C.Magneville 07/2000    
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef CIMAGE_SEEN
+#define CIMAGE_SEEN
+
+#include "tmatrix.h"
+#include "fioarr.h"
+
+
+// **********************************************************
+// Classe Image
+
+namespace SOPHYA {
+
+//! Class for handling images
+template <class T>
+class Image : public TMatrix<T> {
+
+public:
+  Image();
+  Image(sa_size_t sizx, sa_size_t sizy, r_8 szpx=1., r_8 szpy=1., r_8 orgx=0., r_8 orgy=0.);
+  Image(const Image<T>& a);
+  Image(const Image<T>& a, bool share);
+
+  virtual ~Image();
+
+  // Inline element acces methods 
+  inline T const& operator()(sa_size_t ix, sa_size_t jy) const;
+  inline T&       operator()(sa_size_t ix, sa_size_t jy);
+
+  //! Returns the image size along X (corresponding to the number of columns)  
+  inline sa_size_t  XSize() const {return NCols();}
+  //! Returns the image size along Y (corresponding to the number of lines)  
+  inline sa_size_t  YSize() const {return NRows();}
+
+  //! Returns the X position, for pixel(0,0)
+  inline r_8     XOrg() const {return org_x;}
+  //! Returns the Y position, for pixel(0,0)
+  inline r_8     YOrg() const {return org_y;}
+
+  //! Returns pixel size along X 
+  inline r_8     XPixSize() const {return pxsz_x;}
+  //! Returns pixel size along Y
+  inline r_8     YPixSize() const {return pxsz_y;}
+
+  //! Returns the pixel position along X, for pixels with X index \b i
+  inline r_8     XPos(sa_size_t i) const {return org_x + i*pxsz_x;}
+  //! Returns the pixel position along Y, for pixels with Y index \b j
+  inline r_8     YPos(sa_size_t j) const {return org_y + j*pxsz_y;}
+
+  //! Set the position for pixel(0,0)
+  inline void    SetOrg(r_8 orgx=0., r_8 orgy=0.)
+                       { org_x = orgx;  org_y = orgy; }  
+  //! Set the pixel size
+  inline void    SetPixelSize(r_8 szx=1., r_8 szy=1.)
+                       { pxsz_x = szx;   pxsz_y = szy; }
+
+protected:
+  r_8   org_x,org_y;        //  Coordonnees pixel(0,0)
+  r_8   pxsz_x, pxsz_y;     //  Taille des pixels
+};
+
+//! () : Return the pixel value (element) for pixel \b ix (column index) and \b jy (line index)
+template <class T>
+inline T const& Image<T>::operator()(sa_size_t ix, sa_size_t jy) const
+{
+  return (TMatrix<T>::operator() (jy, ix));
+}
+
+//! () : Return the pixel value (element) for pixel \b ix (column index) and \b jy (line index)
+template <class T>
+inline T & Image<T>::operator()(sa_size_t ix, sa_size_t jy) 
+{
+  return (TMatrix<T>::operator() (jy, ix));
+}
+
+/////////////////////////////////////////////////////////////////////////
+//! Class for persistent management of Image
+template <class T>
+class FIO_Image : public FIO_TArray<T>   {
+public:
+  FIO_Image();
+  FIO_Image(string const & filename); 
+  FIO_Image(const Image<T> & obj);
+  FIO_Image(Image<T> * obj);
+  //  virtual ~FIO_Image();  
+  virtual void        SetDataObj(AnyDataObj & o);
+  inline operator Image<T>() { return(*(dynamic_cast<Image<T> * >(dobj))); }
+protected :
+  virtual void ReadSelf(PInPersist&);           
+  virtual void WriteSelf(POutPersist&) const;  
+};
+
+/*! \ingroup NTools \fn operator<<(POutPersist&,Image<T>&)
+  \brief Write Image \b obj into POutPersist stream \b os */
+template <class T>
+inline POutPersist& operator << (POutPersist& os, Image<T> & obj)
+{ FIO_Image<T> fio(&obj);  fio.Write(os);  return(os); }
+
+/*! \ingroup NTools \fn operator>>(PInPersist&,Image<T>&)
+  \brief Read Image \b obj from PInPersist stream \b os */
+template <class T>
+inline PInPersist& operator >> (PInPersist& is, Image<T> & obj)
+{ FIO_Image<T> fio(&obj);  fio.Read(is);  return(is); }
+
+
+
+typedef Image<uint_2> ImageU2;
+typedef Image<int_4>  ImageI4;
+typedef Image<r_4>    ImageR4;
+typedef Image<r_8>    ImageR8;
+
+class GeneralFit;
+//! OBSOLETE - Should not be used - for compatibility with peida in (s)piapp
+class RzImage {
+public:
+  RzImage() { }
+  ~RzImage() { }
+  inline uint_4  XSize() const {return 0;}
+  inline uint_4  YSize() const {return 0;}
+
+  inline r_8     XOrg() const {return 0;}
+  inline r_8     YOrg() const {return 0;}
+
+  inline r_8     XPixSize() const {return 1.;}
+  inline r_8     YPixSize() const {return 1.;}
+  inline r_8     DValue(int i, int j) const { return 0.; }
+  // Resultats d'un GeneralFit
+  inline RzImage*      FitResidus(GeneralFit& gfit) { return NULL; }
+  inline RzImage*      FitFunction(GeneralFit& gfit) { return NULL; }
+
+};
+
+}  // End of namespace SOPHYA
+
+#endif
+
+
Index: /tags/V_Dec2002/SophyaLib/NTools/classfunc.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/classfunc.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/classfunc.h	(revision 2309)
@@ -0,0 +1,29 @@
+////////////////////////////////////////////////////////////////
+//this class provides an alernative to functions which can be viewed as classes
+//                          S.Plaszczynski 29/11/02
+//////////////////////////////////////////////////////////////////////
+
+
+#ifndef CLASSFUNC_H
+#define CLASSFUNC_H
+
+namespace SOPHYA {
+
+//abstract class-function
+class ClassFunc {
+public:
+  virtual double operator()(double x)=0;
+};
+
+//ClassFunc constructed from a a function:simple forward to function
+class Function : public ClassFunc {
+ private:
+  double (*f)(double);
+ public:
+  Function(double (*g)(double)):f(g){}
+  inline  double operator()(double x){ return f(x);}
+};
+
+}
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/cspline.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/cspline.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/cspline.cc	(revision 2309)
@@ -0,0 +1,483 @@
+#include "machdefs.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <iostream.h>
+
+#ifdef __MWERKS__
+   #include <iostream>
+#endif
+
+#include "nbtri.h"
+#include "cspline.h"
+
+//++
+// Class	CSpline
+// Lib	Outils++ 
+// include	cspline.h
+//
+//	Classe de spline 1D
+//--
+
+//++
+// Titre	Constructeurs
+//--
+
+//////////////////////////////////////////////////////////////////////////////
+//++
+CSpline::CSpline(int n,double* x,double* y,double yp1,double ypn
+                ,int natural,bool order)
+//
+//	Createur pour spline 3 sur "x[0->n],y[0->n]" avec "yp1,ypn" derivees
+//	au premier et dernier points et "natural" indiquant les types de
+//	contraintes sur les derivees 2sd au premier et dernier point.
+//	"order" doit etre mis a "true" si le tableau de "x[]" n'est pas ordonne
+//	dans l'ordre des "x" croissants ("x[i]<x[i+1]"): cette option
+//	realloue la place pour les tableaux "x,y" autrement seule une
+//	connection aux tableaux "x,y" externes est realisee.
+//--
+  : Nel(0), corrupt_Y2(true), XY_Created(false), Natural(natural)
+  , YP1(yp1), YPn(ypn), X(NULL), Y(NULL), Y2(NULL), tmp(NULL)
+{
+SetNewTab(n,x,y,order,true);
+if( x != NULL && y != NULL) ComputeCSpline();
+
+END_CONSTRUCTOR
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//++
+CSpline::CSpline(double yp1,double ypn,int natural)
+//
+//	Createur par defaut.
+//--
+  : Nel(0), corrupt_Y2(true), XY_Created(false), Natural(natural)
+  , YP1(yp1), YPn(ypn), X(NULL), Y(NULL), Y2(NULL), tmp(NULL)
+{
+END_CONSTRUCTOR
+}
+
+//////////////////////////////////////////////////////////////////////////////
+CSpline::~CSpline()
+// destructeur
+{
+DelTab();
+}
+
+//++
+// Titre	Methodes
+//--
+
+//////////////////////////////////////////////////////////////////////////////
+//++
+void CSpline::SetNewTab(int n,double* x,double* y,bool order,bool force)
+//
+//	Pour changer les tableaux sans recreer la classe,
+//	memes arguments que dans le createur.
+//	Pour connecter les tableaux "x[n],y[n]" aux pointeurs internes "X,Y"
+//	Si "order=true", on considere que x n'est pas range par ordre
+//	des "x" croissants. La methode alloue de la place pour des tableaux
+//	internes "X,Y" qu'elle re-ordonne par "x" croissant.
+//	"force=true" impose la reallocation des divers buffers, sinon
+//	la reallocation n'a lieu que si le nombre de points augmente.
+//--
+{
+ASSERT( n>3 );
+
+// allocation des buffers Y2 et tmp
+if( n>Nel || force ) {
+  if( Y2  != NULL ) delete [] Y2;
+  if( tmp != NULL ) delete [] tmp;
+  Y2   = new double[n];
+  tmp  = new double[n];
+}
+// des-allocation eventuelle de X,Y
+if( XY_Created ) {
+  if( !order || n>Nel || force ) {
+    if( X != NULL ) delete [] X;  X = NULL;
+    if( Y != NULL ) delete [] Y;  Y = NULL;
+    XY_Created = false;
+  }
+}
+// allocation eventuelle de X,Y
+if( order ) {
+  if( !XY_Created || n>Nel || force ) {
+    X = new double[n];
+    Y = new double[n];
+    XY_Created = true;
+  }
+}
+Nel = n;
+corrupt_Y2 = true;
+
+if( x==NULL || y==NULL ) return;
+
+// Classement eventuel par ordre des x croissants
+if( order ) {
+  if( tmp == NULL ) tmp = new double[n];
+  ind = (int_4 *) tmp;
+  tri_double(x,ind,(int_4) Nel);
+  for(int i=0;i<Nel;i++) {
+    X[i] = x[ind[i]];
+    Y[i] = y[ind[i]];
+    if( i>0 ) if( X[i-1]>= X[i] ) {
+      printf("CSpline::SetNewTab_Erreur: X[%d]>=X[%d] (%g>=%g)\n"
+            ,i-1,i,X[i-1],X[i]);
+      THROW(inconsistentErr);
+    }
+  }
+} else { X = x; Y = y; }
+
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CSpline::DelTab()
+// destruction des divers tableaux en tenant compte des allocations/connections
+{
+if( X   != NULL && XY_Created ) delete [] X;    X   = NULL;
+if( Y   != NULL && XY_Created ) delete [] Y;    Y   = NULL;
+if( Y2  != NULL ) delete [] Y2;   Y2  = NULL;
+if( tmp != NULL ) delete [] tmp;  tmp = NULL;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//++
+void CSpline::SetBound1er(double yp1,double ypn)
+//
+//	Pour changer les valeurs des derivees 1ere au 1er et dernier points
+//	Valeurs imposees des derivees 1ere au points "X[0]" et "X[Nel-1]".
+//--
+{
+if( yp1 == YP1 && ypn == YPn ) return;
+
+YP1 = yp1;
+YPn = ypn;
+
+corrupt_Y2 = true;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//++
+void CSpline::ComputeCSpline()
+//
+//	Pour calculer les tableaux de coeff permettant le calcul
+//	des interpolations spline.
+//--
+{
+// on ne fait rien si les tableaux ne sont pas connectes
+if( X == NULL || Y == NULL ) {
+  printf("CSpline::ComputeCSpline()_Erreur: tableaux non connectes X=%p Y=%p\n"
+        ,X,Y);
+  return;
+}
+// On ne fait rien si rien n'a change!
+if( ! corrupt_Y2 ) return;
+// protection si tmp a ete desalloue pour gain de place (ex: CSpline2)
+if( tmp == NULL ) tmp = new double[Nel];
+
+double p,qn,sig,un;
+
+if (Natural & Natural1)
+  Y2[0] = tmp[0] = 0.0;
+else {
+  Y2[0] = -0.5;
+  tmp[0] = (3.0/(X[1]-X[0]))*((Y[1]-Y[0])/(X[1]-X[0])-YP1);
+}
+
+for (int i=1;i<Nel-1;i++) {
+  sig = (X[i]-X[i-1])/(X[i+1]-X[i-1]);
+  p = sig * Y2[i-1] + 2.0;
+  Y2[i] = (sig-1.0)/p;
+  tmp[i]= (Y[i+1]-Y[i])/(X[i+1]-X[i]) - (Y[i]-Y[i-1])/(X[i]-X[i-1]);
+  tmp[i]= (6.0*tmp[i]/(X[i+1]-X[i-1])-sig*tmp[i-1])/p;
+}
+
+if (Natural & NaturalN)
+   qn = un = 0.0;
+else {
+   qn = 0.5;
+   un = (3.0/(X[Nel-1]-X[Nel-2]))
+       *(YPn-(Y[Nel-1]-Y[Nel-2])/(X[Nel-1]-X[Nel-2]));
+}
+Y2[Nel-1] = (un-qn*tmp[Nel-2])/(qn*Y2[Nel-2]+1.0);
+for (int k=Nel-2;k>=0;k--) Y2[k] = Y2[k]*Y2[k+1] + tmp[k];
+
+corrupt_Y2 = false;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//++
+double CSpline::CSplineInt(double x)
+//
+//	Interpolation spline en "x"
+//--
+{
+int klo,khi,k;
+double h,b,a,y = 0.;
+
+if( corrupt_Y2 ) {
+  cout<<"CSpline::CSplineInt: calcul des coef du spline corrupted"<<endl;
+  THROW(inconsistentErr);
+}
+
+klo = 0;
+khi = Nel-1;
+while (khi-klo > 1) {
+  k = (khi+klo) >> 1;
+  if (X[k] > x) khi=k;
+    else klo=k;
+}
+h=X[khi]-X[klo];
+
+if (h == 0.0) {
+  cout<<"CSpline::CSplineInt: pout khi="<<khi<<" klo="<<klo
+      <<" memes valeurs de X[]: "<<X[khi]<<endl;
+  THROW(inconsistentErr);
+}
+
+a = (X[khi]-x)/h;
+b = (x-X[klo])/h;
+y = a*Y[klo]+b*Y[khi]+((a*a*a-a)*Y2[klo]+(b*b*b-b)*Y2[khi])*(h*h)/6.0;
+
+return y;
+}
+
+///////////////////////////////////////////////////////////////
+///////// rappel des inlines pour commentaires ////////////////
+///////////////////////////////////////////////////////////////
+
+//++
+// inline void SetNaturalCSpline(int type = NaturalAll)
+//	Pour changer le type de contraintes sur les derivees 2sd
+//--
+//++
+// inline void Free_Tmp()
+//	Pour liberer la place tampon qui ne sert que
+//	dans ComputeCSpline() et pas dans CSplineInt
+//--
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+//++
+// Class	CSpline2
+// Lib	Outils++ 
+// include	cspline.h
+//
+//	Classe de spline 2D
+//--
+
+//++
+// Titre	Constructeurs
+//--
+
+//////////////////////////////////////////////////////////////////////////////
+//++
+CSpline2::CSpline2(int n1,double* x1,int n2,double* x2,double* y
+                  ,int natural,bool order)
+//
+//	Meme commentaire que pour CSpline avec:
+//| x1[n1]: liste des coordonnees selon l axe 1
+//| x2[n2]: liste des coordonnees selon l axe 2
+//| y[n1*n2]: liste des valeurs avec le rangement suivant
+//| x1[0]......x1[n1-1]  x1[0]......x1[n1-1]  ... x1[0]......x1[n1-1]
+//| |    0<=i<n1      |  |    0<=i<n1      |  ... |    0<=i<n1      |
+//|      j=0 X2[0]            j=1 X2[1]              j=n2-1 X2[n2-1]
+//--
+  : Nel1(0), Nel2(0), corrupt_Y2(true), XY_Created(false), Natural(natural)
+  , X1(NULL), X2(NULL), Y(NULL), Y2(NULL)
+  , Nel_S(0), S(NULL), Sint(NULL), tmp(NULL)
+{
+SetNewTab(n1,x1,n2,x2,y,order,true);
+if( x1 != NULL && x2 != NULL && y != NULL) ComputeCSpline();
+
+END_CONSTRUCTOR
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//++
+CSpline2::CSpline2(int natural)
+//
+//	Createur par defaut.
+//--
+  : Nel1(0), Nel2(0), corrupt_Y2(true), XY_Created(false), Natural(natural)
+  , X1(NULL), X2(NULL), Y(NULL), Y2(NULL)
+  , Nel_S(0), S(NULL), Sint(NULL), tmp(NULL)
+{
+END_CONSTRUCTOR
+}
+
+//////////////////////////////////////////////////////////////////////////////
+CSpline2::~CSpline2()
+{
+DelTab();
+}
+
+//++
+// Titre	Methodes
+//--
+
+//////////////////////////////////////////////////////////////////////////////
+//++
+void CSpline2::SetNewTab(int n1,double* x1,int n2,double* x2,double* y
+                        ,bool order,bool force)
+//
+//	Voir commentaire meme methode de CSpline
+//--
+{
+ASSERT( n1>3 && n2>3 );
+
+int n = ( n1 < n2 ) ? n2 : n1;
+
+// allocation des buffers Y2 et tmp et des CSpline 1D
+if( n1>Nel1 || n2>Nel2 || force ) {
+  if( Y2  != NULL ) delete [] Y2;
+  if( tmp != NULL ) delete [] tmp;
+  Y2   = new double[n1*n2];
+  tmp  = new double[n];
+
+  // et les CSpline[n1] pour memoriser les interpolations sur x1(0->n1)
+  if( S != NULL ) {
+    for(int i=0;i<Nel_S;i++) if(S[i] != NULL) { delete S[i]; S[i]=NULL;}
+    delete S; S = NULL;
+  }
+  S = new CSpline * [n2];
+  for(int j=0;j<n2;j++) {
+    S[j] = new CSpline(n1,NULL,NULL,0.,0.,Natural);
+    S[j]->Free_Tmp();
+  }
+  Nel_S = n2;
+
+  if( S != NULL ) { delete Sint; Sint = NULL;}
+  Sint = new CSpline(n2,NULL,NULL,0.,0.,Natural);
+
+}
+// des-allocation eventuelle de X1,X2,Y
+if( XY_Created ) {
+  if( !order || n1>Nel1 || n2>Nel2 || force ) {
+    if( X1 != NULL ) delete [] X1; X1 = NULL;
+    if( X2 != NULL ) delete [] X2; X2 = NULL;
+    if( Y != NULL )  delete [] Y;  Y  = NULL;
+    XY_Created = false;
+  }
+}
+// allocation eventuelle de X1,X2,Y
+if( order ) {
+  if( !XY_Created || n1>Nel1 || n2>Nel1 || force ) {
+    X1 = new double[n1];
+    X2 = new double[n2];
+    Y  = new double[n1*n2];
+    XY_Created = true;
+  }
+}
+Nel1 = n1;  Nel2 = n2;
+corrupt_Y2 = true;
+
+if( x1==NULL || x2==NULL || y==NULL ) return;
+
+// Classement eventuel par ordre des x1 et x2 croissants
+if( order ) {
+
+  if( tmp == NULL ) tmp = new double[n];
+  ind = (int_4 *) tmp;
+  double* Ytmp = new double[n1*n2];
+
+  // tri par valeur croissantes de x1
+  tri_double(x1,ind,(int_4) Nel1);
+  for(int i=0;i<Nel1;i++) {
+    X1[i] = x1[ind[i]];
+    if( i>0 ) if( X1[i-1] >= X1[i] )
+      { printf("CSpline::SetNewTab_Erreur: X1[%d]>=X1[%d] (%g>=%g)\n"
+              ,i-1,i,X1[i-1],X1[i]);
+        THROW(inconsistentErr); }
+    for(int j=0;j<Nel2;j++) Ytmp[j*Nel1+i]  = y[j*Nel1+ind[i]];
+  }
+
+  // tri par valeur croissantes de x2
+  tri_double(x2,ind,(int_4) Nel2);
+  for(int j=0;j<Nel2;j++) {
+    X2[j] = x2[ind[j]];
+    if( j>0 ) if( X2[j-1] >= X2[j] )
+      { printf("CSpline::SetNewTab_Erreur: X2[%d]>=X2[%d] (%g>=%g)\n"
+              ,j-1,j,X2[j-1],X2[j]);
+        THROW(inconsistentErr); }
+    for(int i=0;i<Nel1;i++) Y[j*Nel1+i] = Ytmp[j*Nel1+ind[i]];
+  }
+  delete [] Ytmp;
+
+} else {
+
+  X1 = x1;
+  X2 = x2;
+  Y  = y;
+
+}
+
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CSpline2::DelTab()
+{
+if( X1  != NULL && XY_Created ) delete [] X1;  X1   = NULL;
+if( X2  != NULL && XY_Created ) delete [] X2;  X2   = NULL;
+if( Y   != NULL && XY_Created ) delete [] Y;   Y   = NULL;
+if( Y2  != NULL ) delete [] Y2;   Y2  = NULL;
+if( tmp != NULL ) delete [] tmp;  tmp = NULL;
+if( S != NULL ) {
+  for(int i=0;i<Nel_S;i++) if(S[i] != NULL) { delete S[i]; S[i]=NULL;}
+  delete S; S = NULL;
+}
+if( Sint != NULL ) { delete Sint; Sint=NULL;}
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//++
+void CSpline2::ComputeCSpline()
+//
+//	Voir commentaire meme methode de CSpline
+//--
+{
+// on ne fait rien si X1 ou X2 ou Y non connectes
+if( X1 == NULL || X2 == NULL || Y == NULL ) return;
+// On ne fait rien si rien n'a change
+if( ! corrupt_Y2 ) return;
+
+for(int j=0; j<Nel2; j++) {
+  // on n'alloue pas de place nouvelle, on utilise CSpline2::tmp
+  S[j]->tmp = tmp;
+  // connection de X1,Y au spline 1D sans ordre demande
+  S[j]->SetNewTab(Nel1,X1,&Y[j*Nel1],false,false);
+  // calcul des coeff splien pour l'interpolation future
+  S[j]->ComputeCSpline();
+}
+
+corrupt_Y2 = false;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//++
+double CSpline2::CSplineInt(double x1,double x2)
+//
+//	Voir commentaire meme methode de CSpline
+//--
+{
+// calcul de la valeur Y pour x=x1 et remplissage du tampon tmp
+for(int j=0;j<Nel2;j++) tmp[j] = S[j]->CSplineInt(x1);
+
+// connection X2,tmp pour interpolation selon x=x2
+Sint->SetNewTab(Nel2,X2,tmp,false,false);
+// calcul des coeff pour interpolation selon X2
+Sint->ComputeCSpline();
+// Interpolation finale
+return Sint->CSplineInt(x2);
+}
+
+///////////////////////////////////////////////////////////////
+///////// rappel des inlines pour commenatires ////////////////
+///////////////////////////////////////////////////////////////
+
+//++
+// inline void SetNaturalCSpline(int type = NaturalAll)
+//	Voir commentaire meme methode de CSpline
+//--
Index: /tags/V_Dec2002/SophyaLib/NTools/cspline.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/cspline.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/cspline.h	(revision 2309)
@@ -0,0 +1,124 @@
+#ifndef CSPLINE_H_SEEN
+#define CSPLINE_H_SEEN
+
+#include "machdefs.h"
+#include "pexceptions.h"
+
+///////////////////////////////////////////////////////////////////
+// Class CSpline et CSpline2 selon Numerical Receipes (cmv 17/02/97)
+///////////////////////////////////////////////////////////////////
+namespace SOPHYA {
+
+//! Spline fit to a set of points Y=f(X) (as in Numerical Receipes).
+class CSpline {
+
+public:
+
+  friend class CSpline2;
+
+  enum { NaturalAll = 3, NoNatural = 0, Natural1 = 1, NaturalN = 2 };
+
+  CSpline(int n,double* x,double* y,double yp1=0.,double ypn=0.
+         ,int natural=NaturalAll,bool order=true);
+
+  CSpline(double yp1=0.,double ypn=0.,int natural=NaturalAll);
+
+  virtual ~CSpline();
+
+  void SetNewTab(int n,double* x,double* y
+                ,bool order=true,bool force=false);
+
+  void SetBound1er(double yp1 = 0.,double yp2 = 0.);
+
+  inline void SetNaturalCSpline(int type = NaturalAll)
+                 { Natural = type;}
+
+  inline void Free_Tmp()
+                { if(tmp != NULL) delete [] tmp; tmp=NULL;}
+
+  void ComputeCSpline();
+
+  double CSplineInt(double x);
+
+protected:
+
+  void DelTab();
+
+  // nombre d elements dans les tableaux X et Y
+  int Nel;
+  // true si les tableaux ont ete changes
+  // et qu il faut recalculer ComputeCSpline()
+  bool corrupt_Y2;
+  // true si les tableaux X,Y ont ete alloues
+  bool XY_Created;
+  // type de contraintes sur la derivee 2sd
+  int Natural;
+  // valeurs imposees de la derivee 1ere aux limites
+  double YP1, YPn;
+
+  // tableaux rellement alloues si "order=true" ou seulement
+  // connectes aux tableaux externes si "order=false"
+  double* X;
+  double* Y;
+
+  // tableau des coeff permettant l interpolation,
+  // remplis par ComputeCSpline()
+  double* Y2;
+
+  // tableau tampon utilise dans ComputeCSpline()
+  double* tmp;
+  int_4*  ind;
+
+};
+
+
+///////////////////////////////////////////////////////////////////
+//! 2D Spline fit to a set of points Y=f(X1,X2) (as in Numerical Receipes).
+class CSpline2  {
+
+public:
+  CSpline2(int n1,double* x1,int n2,double* x2,double* y
+          ,int natural=CSpline::NaturalAll,bool order=true);
+
+  CSpline2(int natural=CSpline::NaturalAll);
+
+  virtual ~CSpline2();
+
+  void SetNewTab(int n1,double* x1,int n2,double* x2,double* y
+                ,bool order=true,bool force=false);
+
+  inline void SetNaturalCSpline(int type = CSpline::NaturalAll)
+                 { Natural = type;}
+
+  void ComputeCSpline();
+
+  double CSplineInt(double x1,double x2);
+
+protected:
+  void DelTab();
+
+  int Nel1, Nel2;
+  bool corrupt_Y2;
+  bool XY_Created;
+  int Natural;
+
+  double* X1;
+  double* X2;
+  double* Y;
+  double* Y2;
+
+  // nombre d elements alloues dans S
+  int Nel_S;
+  // tableau de CSpline pour interpolation selon X1
+  CSpline** S;       // S[0->n2]
+  CSpline*  Sint;
+
+  // tableau tampon utilise dans CSplineInt()
+  double* tmp;  // tmp[max(n1,n2)]
+  int_4*  ind;
+
+};
+
+} // Fin du namespace
+
+#endif /* CSPLINE_H_SEEN */
Index: /tags/V_Dec2002/SophyaLib/NTools/datatypes.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/datatypes.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/datatypes.cc	(revision 2309)
@@ -0,0 +1,82 @@
+// Type de donnees de base 
+//                E. Lesquoy , E. Aubourg 
+//                             R. Ansari 04/95
+
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "datatypes.h"
+
+/* Nouvelle-Fonction */
+char * DataName(PBaseDataTypes typ)
+{
+switch (typ)
+  {
+  case kuint_1 :
+    return ("uint_1");
+  case kint_1 :
+    return ("int_1");
+  case kuint_2 :
+    return ("uint_2");
+  case kint_2 :
+    return ("int_2");
+  case kint_4:
+    return ("int_4");
+  case kr_4 :
+    return ("r_4");
+  case kr_8 :
+    return ("r_8");
+  default :
+    return ("unknown");
+  }
+}
+
+/* Nouvelle-Fonction */
+char * DataLongName(PBaseDataTypes typ)
+{
+switch (typ)
+  {
+  case kuint_1 :
+    return ("unsigned char (*1)");
+  case kint_1 :
+    return ("signed char (*1)");
+  case kuint_2 :
+    return ("unsigned short int (*2)");
+  case kint_2 :
+    return ("short int (*2)");
+  case kint_4:
+    return ("int (*4)");
+  case kr_4 :
+    return ("float (*4)");
+  case kr_8 :
+    return ("double (*8)");
+  default :
+    return ("unknown");
+  }
+}
+
+/* Nouvelle-Fonction */
+int DataSize(PBaseDataTypes typ)
+{
+switch (typ)
+  {
+  case kuint_1 :
+    return (sizeof(uint_1));
+  case kint_1 :
+    return (sizeof(int_1));
+  case kuint_2 :
+    return (sizeof(uint_2));
+  case kint_2 :
+    return (sizeof(int_2));
+  case kint_4:
+    return (sizeof(int_4));
+  case kr_4 :
+    return (sizeof(r_4));
+  case kr_8 :
+    return (sizeof(r_8));
+  default :
+    return (0);
+  }
+}
+
+
+
Index: /tags/V_Dec2002/SophyaLib/NTools/datatypes.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/datatypes.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/datatypes.h	(revision 2309)
@@ -0,0 +1,140 @@
+/*   Manipulation et conversion des types de bases     */
+/*          E. Aubourg, E. Lesquoy                     */
+
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef DATATYPES_H_SEEN
+#define DATATYPES_H_SEEN
+
+#include "machdefs.h"
+
+
+enum PBaseDataTypes {kpbdt_unknown=-1, kuint_1=1, kint_1=2, 
+                     kuint_2=3, kint_2=4, kuint_4=5, kint_4=6, 
+                     kr_4=7, kr_8=8};
+
+inline PBaseDataTypes DataType(uint_1) {return kuint_1;}
+inline PBaseDataTypes DataType(int_1)  {return kint_1;}
+inline PBaseDataTypes DataType(uint_2) {return kuint_2;}
+inline PBaseDataTypes DataType(int_2)  {return kint_2;}
+inline PBaseDataTypes DataType(uint_4) {return kuint_4;}
+inline PBaseDataTypes DataType(int_4)  {return kint_4;}
+inline PBaseDataTypes DataType(r_4)    {return kr_4;}
+inline PBaseDataTypes DataType(r_8)    {return kr_8;}
+
+char * DataName(PBaseDataTypes);
+char * DataLongName(PBaseDataTypes);
+int    DataSize(PBaseDataTypes);
+
+// Limites des types
+
+inline double   MinRange(uint_1) {return  0.0;}
+inline double   MaxRange(uint_1) {return  255.0;}
+inline double   MinRange(uint_2) {return  0.0;}
+inline double   MaxRange(uint_2) {return  65535.0;}
+inline double   MinRange(int_2)  {return -32768.0;}
+inline double   MaxRange(int_2)  {return  32767.0;}
+inline double   MinRange(int_4)  {return -2147483648.0;}
+inline double   MaxRange(int_4)  {return  2147483647.0;}
+inline double   MinRange(r_4)    {return -3.40282347e+38f;}
+inline double   MaxRange(r_4)    {return  3.40282347e+38f;}
+
+// reduction range donnee si on va du type 1 au type 2 (y/n)
+// ReducRange(type 1 , type 2 )
+// retour:
+
+enum {t_same,t_up,t_spe,t_down}; 
+//         t_same: meme type
+//         t_up  : ascendant   (I,U2)->(I4,R4), I4->R4 
+//         t_spe:  speciaux    I2->U2 , U2->I2 
+//         t_down: descendants R4->I4, (R4,I4)->(U2,I2) 
+
+inline int ConvType(uint_1 , uint_1 ) {return  t_same;}
+inline int ConvType(uint_1 , uint_2 ) {return  t_up;}
+inline int ConvType(uint_1 , int_2 )  {return  t_up;}
+inline int ConvType(uint_1 , int_4 )  {return  t_up;}
+inline int ConvType(uint_1 , r_4 )    {return  t_up;}
+inline int ConvType(uint_2 , uint_1 ) {return  t_down;}
+inline int ConvType(uint_2 , uint_2 ) {return  t_same;}
+inline int ConvType(uint_2 , int_2 )  {return  t_spe;}
+inline int ConvType(uint_2 , int_4 )  {return  t_up;}
+inline int ConvType(uint_2 , r_4 )    {return  t_up;}
+inline int ConvType(int_2 , uint_1 )  {return  t_down;}
+inline int ConvType(int_2 , uint_2 )  {return  t_spe;}
+inline int ConvType(int_2 , int_2 )   {return  t_same;}
+inline int ConvType(int_2 , int_4 )   {return  t_up;}
+inline int ConvType(int_2 , r_4 )     {return  t_up;}
+inline int ConvType(int_4 , uint_1 )  {return  t_down;}
+inline int ConvType(int_4 , uint_2 )  {return  t_down;}
+inline int ConvType(int_4 , int_2 )   {return  t_down;}
+inline int ConvType(int_4 , int_4 )   {return  t_same;}
+inline int ConvType(int_4 , r_4 )     {return  t_up;}
+inline int ConvType(r_4 , uint_1 )    {return  t_down;}
+inline int ConvType(r_4 , uint_2 )    {return  t_down;}
+inline int ConvType(r_4 , int_2 )     {return  t_down;}
+inline int ConvType(r_4 , int_4 )     {return  t_down;}
+inline int ConvType(r_4 , r_4 )       {return  t_same;}
+
+/*
+template <class T> 
+inline T PutInRange(double x,T t) {
+           return (T)( x < MinRange(t) ? MinRange(t) : \
+		      (x > MaxRange(t) ? MaxRange(t) : x));
+	 }
+// BUG GCC 2.6.1. Unresolved: xxx..ng
+*/
+
+inline uint_1 PutInRange(double x, uint_1 t) {
+  return (uint_1)( x < MinRange(t) ? MinRange(t) : \
+	     (x > MaxRange(t) ? MaxRange(t) : x));
+	 }
+inline uint_2 PutInRange(double x, uint_2 t) {
+  return (uint_2)( x < MinRange(t) ? MinRange(t) : \
+	     (x > MaxRange(t) ? MaxRange(t) : x));
+	 }
+inline int_2 PutInRange(double x, int_2 t) {
+  return (int_2)( x < MinRange(t) ? MinRange(t) : \
+	     (x > MaxRange(t) ? MaxRange(t) : x));
+	 }
+inline int_4 PutInRange(double x, int_4 t) {
+  return (int_4)( x < MinRange(t) ? MinRange(t) : \
+	     (x > MaxRange(t) ? MaxRange(t) : x));
+	 }
+inline r_4 PutInRange(double x  , r_4)  {return x;} 
+
+/*
+template <class T> 
+inline T SharePix(double x, T t, double cutmin, double cutmax)
+         { double tmp = (((x - cutmin)/(cutmax-cutmin))* \
+          ( MaxRange(t)-MinRange(t)))+MinRange(t);
+	   return PutInRange(tmp, t);
+	 }
+// BUG GCC 2.6.1. Unresolved: xxx..ng
+*/
+inline double SharePix(double x, uint_1 t, double cutmin, double cutmax)
+         { double tmp = (((x - cutmin)/(cutmax-cutmin))* \
+          ( MaxRange(t)-MinRange(t)))+MinRange(t);
+	   return PutInRange(tmp, t);
+	 }
+inline double SharePix(double x, uint_2 t, double cutmin, double cutmax)
+         { double tmp = (((x - cutmin)/(cutmax-cutmin))* \
+          ( MaxRange(t)-MinRange(t)))+MinRange(t);
+	   return PutInRange(tmp, t);
+	 }
+inline double SharePix(double x, int_2 t, double cutmin, double cutmax)
+         { double tmp = (((x - cutmin)/(cutmax-cutmin))* \
+          ( MaxRange(t)-MinRange(t)))+MinRange(t);
+	   return PutInRange(tmp, t);
+	 }
+inline double SharePix(double x, int_4 t, double cutmin, double cutmax)
+         { double tmp = (((x - cutmin)/(cutmax-cutmin))* \
+          ( MaxRange(t)-MinRange(t)))+MinRange(t);
+	   return PutInRange(tmp, t);
+	 }
+inline double SharePix(double x, r_4 t, double cutmin, double cutmax)
+         { double tmp = (((x - cutmin)/(cutmax-cutmin))* \
+          ( MaxRange(t)-MinRange(t)))+ MinRange(t);
+	   return PutInRange(tmp, t);
+	 }
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/dates.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/dates.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/dates.cc	(revision 2309)
@@ -0,0 +1,882 @@
+#include "machdefs.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <iostream.h>
+#include <time.h>
+#include <ctype.h>
+#include <math.h>
+#include "perrors.h"
+#include "dates.h"
+
+//++
+// Class	TimeZone
+// Lib		Outils++ 
+// include	dates.h
+//
+//	Classe de fuseau horaire. Permet les conversion
+//	GMT <-> temps local, en gérant les changements
+//	d'heure hiver-été.
+//	Deux fuseaux horaires sont prédéfinis, "France"
+//	et "Chili".
+//--
+
+TimeZone* gTimeZone = NULL;
+
+//++
+// Titre	Constructeurs
+//--
+
+//++
+TimeZone::TimeZone()
+//
+//	Constructeur par défaut. Il lit la variable
+//	d'environnement ACQ_TZ pour choisir le fuseau
+//	horaire. Si la variable n'est pas définie, nous
+//	sommes en France...
+//--
+{
+  char* p = getenv("ACQ_TZ");
+#if defined(__DECCXX) || defined(__KCC__) || defined(__aCC__)
+  if (!p) p = const_cast<char *>("France");
+#else
+  if (!p) p = "France";
+#endif
+  SetZone(p);
+  END_CONSTRUCTOR;
+}
+
+//++
+TimeZone::TimeZone(const char* nom)
+//
+//	Constructeur à partir du nom d'un fuseau horaire.
+//--
+{
+  SetZone(nom);
+  END_CONSTRUCTOR
+}
+
+//++
+void TimeZone::SetZone(const char* nom)
+//	
+//	Choisit un fuseau horaire. Contient la définition
+//	du fuseau "France" (GMT+1, DST : dernier dimanche
+//	de mars - dernier dimanche de septembre, c'est-à-dire
+//	pré-gouvernement Juppé), et Chili (GMT-4, DST :
+//	deuxième dimanche d'octobre - deuxième dimanche de mars).
+//--
+{
+  if (!strcmp(nom,"France")) {
+     strcpy(code,"MET");
+     strcpy(name,nom);
+     gmtOffset      = 1;
+     hasDST         = 1;
+     dstByWeekDay   = 1;
+     dstStartDay    = Date::jour_Dimanche; // dernier dimanche de mars
+     dstStartNum    = -1;
+     dstStartMonth  = Date::mois_Mars;
+     dstStopDay     = Date::jour_Dimanche; // dernier dimanche de septembre
+     dstStopNum     = -1;
+     dstStopMonth   = Date::mois_Septembre;
+     dstOffset      = 1;
+  } else if (!strcmp(nom,"Chili") || !strcmp(nom,"Chile")) {
+// # Chile has 2nd Sunday in October to 2nd Sunday in March DST
+    strcpy(code,"CST");
+    strcpy(name,"Chili");
+    gmtOffset      = -4;
+    hasDST         = 1;
+    dstByWeekDay   = 1;
+    dstStartDay    = Date::jour_Dimanche; // 2e dimanche d'octobre
+    dstStartNum    = 2;
+    dstStartMonth  = Date::mois_Octobre;
+    dstStopDay     = Date::jour_Dimanche; // 2e dimanche de mars
+    dstStopNum     = 2;
+    dstStopMonth   = Date::mois_Mars;
+    dstOffset      = 1;
+  } else THROW(parmErr);
+}
+
+//++
+int TimeZone::IsDst(const Date& date)
+//
+//	Teste si une date est en heure d'été (DST).
+//--
+{
+  Date dt = date;
+  if (dt.MM < 0 || dt.JJ < 0) THROW(inconsistentErr)
+  if (dt.hh >= 0) dt += gmtOffset/24.0; // date "fictive" en local d'hiver
+  else dt.ss = dt.hh = dt.mm = 0;       // minuit local si heure indeterminee
+  // On est en-dehors des mois frontiere ?
+  if (dstStartMonth < dstStopMonth) {
+     if (dt.MM < dstStartMonth) return 0;
+     if (dt.MM > dstStopMonth)  return 0;
+     if (dt.MM > dstStartMonth && dt.MM < dstStopMonth) return 1;
+  } else {
+     if (dt.MM < dstStopMonth)  return 1;
+     if (dt.MM > dstStartMonth) return 1;
+     if (dt.MM > dstStopMonth && dt.MM < dstStartMonth) return 0;
+  }
+  
+  // Nous sommes dans un mois-frontiere
+  DBASSERT(dt.MM == dstStopMonth || dt.MM == dstStartMonth);
+  
+  if (dt.MM == dstStartMonth) {
+    int jour;
+    if (dstByWeekDay) jour = Date::NthMonthDay(dstStartNum,dstStartDay, dt.MM, dt.AA);
+    else jour = (dstStartNum>0) ? dstStartNum : Date::MonthDays(dt.MM, dt.AA)+1-dstStartNum;
+    if (dt.JJ < jour) return 0;
+    if (dt.JJ > jour) return 1;
+    if (dt.hh > 1) return 1;
+    return 0;
+  } else {
+    int jour;
+    if (dstByWeekDay) jour = Date::NthMonthDay(dstStopNum,dstStopDay, dt.MM, dt.AA);
+    else jour = (dstStopNum>0) ? dstStopNum : Date::MonthDays(dt.MM, dt.AA)+1-dstStopNum;
+    if (dt.JJ < jour) return 1;
+    if (dt.JJ > jour) return 0;
+    if (dt.hh < 2) return 0;
+    return 1;
+  }
+}
+
+//++
+int TimeZone::GetOffset(const Date& date)
+//
+//	Retourne la difference TL-GMT pour une date donnée,
+//	en tenant compte de l'heure d'été éventuelle.
+//--
+{
+  return IsDst(date) ? gmtOffset+dstOffset : gmtOffset;
+}
+
+//++
+// Class	Date
+// Lib		Outils++ 
+// include	dates.h
+//
+//	Une classe date comme une autre, avec gestion
+//	temps local / GMT / changement d'heure, et un 
+//	jour temps sidéral.
+//
+//	Une partie de la date (heure, jour...) peut être
+//	indéterminée. Les comparaisons sont alors faites
+//	de façon astucieuse...
+//
+//	La date peut être déterminée de minuit à minuit
+//	ou de midi à midi (nuit d'observation). Logique
+//	complexe et peut-être foireuse pour passer de
+//	l'un à l'autre, mais pas encore d'ennuis pour le
+//	moment... Une date-nuit doit avoir une heure
+//	indéterminée.
+//
+//	Il faut que Date::gTimeZone soit initialisé pour
+//	éviter des gros pépins, mais PeidaInit() le fait.
+//
+//	An 2000 : Lorsqu'on gère des dates sous forme de chaine :
+//	* En sortie, 2 caractères pour l'année entre 1950 et 1999
+//	  et 4 caractères sinon
+//	* En entrée, si AA<100 on ajoute 1900.
+//--
+
+//++
+short Date::MonthDays(short mois, short annee)
+//
+//	Retourne le nombre de jours dans le mois
+//--
+{
+  if (mois<1 || mois>12) THROW(inconsistentErr);
+  
+  switch(mois) {
+    case mois_Janvier:
+    case mois_Mars:
+    case mois_Mai:
+    case mois_Juillet:
+    case mois_Aout:
+    case mois_Octobre:
+    case mois_Decembre:
+      return 31;
+    case mois_Avril:
+    case mois_Juin:
+    case mois_Septembre:
+    case mois_Novembre:
+      return 30;
+    case mois_Fevrier:
+     return (((annee%4 == 0) && (annee%100 != 0)) || (annee%400 == 0)) ? 29 : 28;
+  }
+  return -1;
+}
+    
+//++
+short Date::YearDays(short annee)
+//
+//	Retourne le nombre de jours dans l'année
+//--
+{
+  return (((annee%4 == 0) && (annee%100 != 0)) || (annee%400 == 0)) ? 366 : 365;
+}
+
+//++
+bool Date::UndetDate() const
+//
+//	Retourne true si une partie de la date (jour
+//	ou mois ou année) est indéterminée.
+//--
+{
+  return ((AA == -1) || (MM == -1) || (JJ == -1));
+}
+
+//++
+bool Date::AllUndetDate() const
+//
+//	Retourne true si toute la date (jour
+//	et mois et année) est indéterminée.
+//--
+{
+  return ((AA == -1) && (MM == -1) && (JJ == -1));
+}
+
+//++
+bool Date::UndetTime() const
+//
+//	Retourne true si une partie de l'heure (heure
+//	ou minutes ou secondes) est indéterminée.
+//--
+{
+  return ((hh == -1) || (mm == -1) || (ss == -1));
+}
+
+//++
+bool Date::AllUndetTime() const
+//
+//	Retourne true si toute l'heure (heure
+//	et minutes et secondes) est indéterminée.
+//--
+{
+  return ((hh == -1) && (mm == -1) && (ss == -1));
+}
+
+//Date::operator double() const
+
+//++
+double
+Date::GetDays() const
+//
+//	Jours écoulés depuis le 0 janvier 1901 0h TU
+//--
+{
+   if (UndetTime() && !AllUndetTime()) THROW(inconsistentErr);
+   if (UndetDate() && !AllUndetDate()) THROW(inconsistentErr);
+   double t=0;
+   if (!UndetDate()) {
+     int nban = AA-1901;
+     if (nban >= 0)  
+       t = nban*365 + (nban/4) - (nban/100) + ((nban+300)/400);
+     else 
+       t = nban*365 + (nban/4) - (nban/100) + ((nban-100)/400);
+     for (int i=1; i<MM; i++)  t += Date::MonthDays(i,AA);
+     t += JJ;
+   }
+   if (!UndetTime()) t += hh/24.0 + mm/1440.0 + ss/86400.0;
+   else if (nuit) t += 0.5;
+   return t;
+}
+
+//++
+void Date::Set(double t)
+//
+//	Jours écoulés depuis le 0 janvier 1901 0h TU
+//--
+{
+   t += 1/8640000.0;
+   int nban = int(floor((t/*-1*/) / 365.2425));
+   if (nban >= 0)  
+     t -= nban*365 + ((nban)/4) - ((nban)/100) + ((nban+300)/400);
+   else 
+     t -= nban*365 + ((nban)/4) - ((nban)/100) + ((nban-100)/400);
+     
+   AA = 1901 + nban;
+   if (t > Date::YearDays(AA)+1) {
+     t -= Date::YearDays(AA);
+     AA++;
+   } else if (t<1) {
+     AA--;
+     t += Date::YearDays(AA);
+   }
+   
+   MM = 1;
+   while (t > Date::MonthDays(MM,AA)+1) {
+     t -= Date::MonthDays(MM,AA);
+     MM++;
+   }
+   
+   JJ = int(t);
+   t -= JJ;
+   
+   t *= 24;
+   hh = int(t);
+   
+   t = (t-hh)*60;
+   mm = int(t);
+   
+   t = (t-mm)*60;
+   ss = t;
+   
+   nuit = 0;
+}
+//++
+Date::Date()
+//
+//	Constructeur. Prend l'heure courante...
+//--
+: timeZone(gTimeZone)
+{
+  time_t t = time(NULL);
+  struct tm* TM = gmtime(&t);
+  
+  AA = TM->tm_year + 1900;
+  MM = TM->tm_mon+1;
+  JJ = TM->tm_mday;
+  hh = TM->tm_hour;
+  mm = TM->tm_min;
+  ss = TM->tm_sec;
+  nuit = 0;
+  END_CONSTRUCTOR
+}
+
+//++
+Date::Date(int J, int M, int A, int h, int m, double s)
+//
+//	Constructeur simple.
+//--
+: JJ(J), MM(M), AA(A), hh(h), mm(m), ss(s), timeZone(gTimeZone), nuit(0)
+{
+  END_CONSTRUCTOR
+}
+
+//++
+Date::Date(double t)
+//
+//	Constructeur à partir des 
+//	jours écoulés depuis le 0 janvier 1901 0h TU
+//
+//--
+: timeZone(gTimeZone)
+{
+  Set(t);
+  END_CONSTRUCTOR
+}
+
+//++
+void Date::SetTimeZone(TimeZone* tz)
+// 
+//	On change de fuseau horaire.
+//--
+{
+  timeZone = tz;
+}
+
+//++
+Date::Date(const char* date, const char* heure, int tOpt)
+//
+//	Constructeur à partir de la date sous la forme
+//	'DD/MM/YYYY'  'HH/MM/SS', et tOpt est Date::kGMTTime
+//	(par défaut) ou Date::kLocalTime.
+//
+//	Tout ou partie de la date peut être indéterminée ('??').
+//--
+: timeZone(gTimeZone)
+{
+  Set(date,heure,tOpt);
+  END_CONSTRUCTOR
+}
+
+//++
+Date::Date(string const& date, string const& heure, int tOpt)
+//
+//	Constructeur à partir de la date sous la forme
+//	'DD/MM/YYYY'  'HH/MM/SS', et tOpt est Date::kGMTTime
+//	(par défaut) ou Date::kLocalTime.
+//
+//	Tout ou partie de la date peut être indéterminée ('??').
+//--
+: timeZone(gTimeZone)
+{
+  Set(date,heure,tOpt);
+  END_CONSTRUCTOR
+}
+
+//++
+void Date::Set(string const& date, string const& heure, int tOpt)
+//
+//	Positionne la date sous la forme
+//	'DD/MM/YYYY'  'HH/MM/SS', et tOpt est Date::kGMTTime
+//	(par défaut) ou Date::kLocalTime.
+//
+//	Tout ou partie de la date peut être indéterminée ('??').
+//--
+{
+  Set(date.c_str(), heure == "" ? (char*)NULL : heure.c_str(), tOpt);
+}
+
+//++
+void Date::Set(const char* date, const char* heure, int tOpt)
+//
+//	Positionne la date sous la forme
+//	'DD/MM/YYYY'  'HH/MM/SS', et tOpt est Date::kGMTTime
+//	(par défaut) ou Date::kLocalTime.
+//
+//	Tout ou partie de la date peut être indéterminée ('??').
+//--
+{
+  nuit = 0;
+  if (date) {
+   if (strlen(date) >= 5) {         //  J(J)/M(M)/AA(AA), ?/?/?, combinaison
+    const char* p = date;
+    if (p[0] == '?' && (p[1] == '?' || p[1] == '/'))   JJ = -1;
+    else {
+      if (!isdigit(p[0])) THROW(inconsistentErr);
+      if (!isdigit(p[1]) && p[1] != '/') THROW(inconsistentErr);
+      JJ = atoi(p);
+      if (JJ <= 0) THROW(inconsistentErr);
+    }
+    
+    if (p[1] == '/') p += 2;
+    else if (p[2] == '/') p+= 3;
+    else THROW(inconsistentErr);
+
+    if (p[0] == '?' && (p[1] == '?' || p[1] == '/'))   MM = -1;
+    else {
+      if (!isdigit(p[0])) THROW(inconsistentErr);
+      if (!isdigit(p[1]) && p[1] != '/') THROW(inconsistentErr);
+      MM = atoi(p);
+      if (MM <= 0 || MM >12) THROW(inconsistentErr);
+    }
+
+    if (p[1] == '/') p += 2;
+    else if (p[2] == '/') p+= 3;
+    else THROW(inconsistentErr);
+
+    if (p[0] == '?')  AA = -1;
+    else {
+      if (!isdigit(p[0])) THROW(inconsistentErr);
+      if (!isdigit(p[1])) THROW(inconsistentErr);
+      AA = atoi(p);
+      if (AA < 100 && AA >= 0 && date[6] != '0') AA += 1900;
+    }
+    
+    if (AA > 0 && MM > 0 && JJ > 0 && JJ > MonthDays(MM,AA)) THROW(inconsistentErr);
+    
+   } else if (strlen(date)==4) {      // Code EROS de date
+     if (date[0] == '?') AA = -1;
+     else {
+       if (!isdigit(date[0])) THROW(inconsistentErr);
+       AA = 1990 + date[0] - '0';
+     }
+     
+     if (date[1] == '?') MM = -1;
+     else {
+       if (!isalpha(date[1])) THROW(inconsistentErr);
+       if (islower(date[1]))
+         MM = date[1] - 'a' + 1;
+       else
+         MM = date[1] - 'A' + 1;
+       if (MM<1 || MM>12) THROW(inconsistentErr);
+     }
+     
+     if (date[2] == '?' && date[3] == '?') JJ = -1;
+     else {
+       if (!isdigit(date[2])) THROW(inconsistentErr);
+       if (!isdigit(date[3])) THROW(inconsistentErr);
+       JJ = atoi(date+2);
+     }
+     
+     if (AA > 0 && MM > 0 && JJ > 0 && JJ > MonthDays(MM,AA)) THROW(inconsistentErr);
+     nuit = 1;
+   } else THROW(inconsistentErr);   // Mauvaise longueur
+  } else {                          // Pas de date
+    JJ = MM = AA = -1;
+  }
+  
+  if (heure) {
+    const char* p = heure;
+    if (p[0] == '?' && (p[1] == '?' || p[1] == ':'))   hh = -1;
+    else {
+      if (!isdigit(p[0])) THROW(inconsistentErr);
+      if (!isdigit(p[1]) && p[1] != ':') THROW(inconsistentErr);
+      hh = atoi(p);
+    }
+
+    if (p[1] == ':') p += 2;
+    else if (p[2] == ':') p+= 3;
+    else THROW(inconsistentErr);
+
+    if (p[0] == '?' && (p[1] == '?' || p[1] == ':'))   mm = -1;
+    else {
+      if (!isdigit(p[0])) THROW(inconsistentErr);
+      if (!isdigit(p[1]) && p[1] != '/') THROW(inconsistentErr);
+      mm = atoi(p);
+    }
+
+    if (p[1] == ':') p += 2;
+    else if (p[2] == ':') p+= 3;
+    else THROW(inconsistentErr);
+
+    if (p[0] == '?')   ss = -1;
+    else {
+      if (!isdigit(p[0])) THROW(inconsistentErr);
+      ss = atoi(p);
+    }
+  } else {
+    ss = hh = mm = -1;
+  }
+  
+  if (tOpt == kLocalTime) {
+    DBASSERT(timeZone != NULL);
+    operator -= (timeZone->gmtOffset/24.0);
+    if (timeZone->IsDst(*this))
+      operator -= (timeZone->dstOffset/24.0);   // A VERIFIER SANS DOUTE INEXACT
+  } 
+  
+  if (nuit && !UndetTime() && hh < 12)
+    *this += 1;
+}
+
+//++
+void Date::GetDateStr(char* s, int tOpt) const
+//
+//	Récupère la date sous la forme d'une chaîne 'DD/MM/YYYY'
+//	en tOpt = Date::kGMTTime ou Date::kLocalTime.
+//--
+{
+  Date dt(*this);
+  if (tOpt == kLocalTime && !UndetTime()) {
+    DBASSERT(timeZone != NULL);
+    dt += timeZone->GetOffset(*this)/24.0;
+  }
+  
+  if (dt.AA < 1950 || dt.AA > 1999) 
+    sprintf(s, "%02d/%02d/%04d", dt.JJ, dt.MM, dt.AA);
+  else
+    sprintf(s, "%02d/%02d/%02d", dt.JJ, dt.MM, dt.AA-1900);
+    
+  if (dt.JJ == -1)
+    s[0] = s[1] = '?';
+  if (dt.MM == -1)
+    s[3] = s[4] = '?';
+  if (dt.AA == -1) {
+    s[6] = s[7] = '?';
+    s[8] = '\0';
+  }
+}
+
+//++
+void Date::GetDateCode(char* s, int tOpt) const
+//
+//	Code EROS de la date.
+//--
+{
+  Date dt(*this);
+  if (tOpt == kLocalTime && !UndetTime()) {
+    DBASSERT(timeZone != NULL);
+    dt += timeZone->GetOffset(*this)/24.0;
+  }
+
+  if (!dt.UndetTime() && dt.hh<12) dt -= 1;
+
+  if (dt.AA != -1) {
+    if (dt.AA < 1990 || dt.AA > 2016) THROW(inconsistentErr);
+    int i = dt.AA - 1990;
+    if (i<10)
+      s[0] = '0' + i;
+    else
+      s[0] = 'a' + i - 10;
+  } else
+    s[0] = '?';
+    
+  if (dt.MM != -1)
+    s[1] = 'a' + dt.MM - 1;
+  else
+    s[1] = '?';
+    
+  if (dt.JJ != -1)
+    sprintf(s+2, "%02d", dt.JJ);
+  else
+    s[2] = s[3] = '?';
+  
+  s[4] = 0;
+}
+
+//++
+void Date::GetTimeStr(char* s, int tOpt) const
+//
+//	Récupère l'heure sous la forme 'HH:MM:SS'
+//--
+{
+  Date dt(*this);
+  if (tOpt == kLocalTime) {
+    DBASSERT(timeZone != NULL);
+    dt += timeZone->GetOffset(*this)/24.0;
+  }
+
+  sprintf(s, "%02d:%02d:%02d", dt.hh, dt.mm, int(dt.ss));
+  if (dt.hh == -1)
+    s[0] = s[1] = '?';
+  if (dt.mm == -1)
+    s[3] = s[4] = '?';
+  if (dt.ss == -1)
+    s[6] = s[7] = '?';
+}
+
+//++
+void Date::GetSidTStr(char* s) const
+//
+//	Récupèrera un jour le temps sidéral.
+//--
+{
+  strcpy(s,"TOBEDONE!!");
+}
+
+//++
+string Date::DateStr(int tOpt) const
+//
+//	Récupère la date sous la forme d'une chaîne 'DD/MM/YYYY'
+//	en tOpt = Date::kGMTTime ou Date::kLocalTime.
+//--
+{
+   char s[20];
+   GetDateStr(s,tOpt);
+   return s;
+}
+
+//++
+string Date::DateCode(int tOpt) const
+//
+//	Code EROS de la date.
+//--
+{
+   char s[20];
+   GetDateCode(s,tOpt);
+   return s;
+}
+
+//++
+string Date::TimeStr(int tOpt) const
+//
+//	Récupère l'heure sous la forme 'HH:MM:SS'
+//--
+{
+   char s[20];
+   GetTimeStr(s,tOpt);
+   return s;
+}
+
+//++
+string Date::SidTStr() const
+//
+//	Récupèrera un jour le temps sidéral.
+//--
+{
+   char s[20];
+   GetSidTStr(s);
+   return s;
+}
+
+//++
+int Date::DayOfWeek(int tOpt) const
+//
+//	Retourne le jour dans la semaine, 0-6
+//	avec 0 = Date::jour_Lundi.
+//--
+{
+  double t = GetDays();
+  if (tOpt == kLocalTime && hh >=0) {
+    DBASSERT(timeZone != NULL);
+    t += timeZone->GetOffset(*this)/24.0;
+  }
+  int ndays = int(t);  // nb de jours depuis 0 janvier 1901
+  ndays = (ndays + 1) % 7;
+  if (ndays<0) ndays += 7;
+  return ndays;
+}
+
+//++
+short Date::NthMonthDay(short i, short joursem, short mois, short annee)
+//
+//	Retourne la date correspondant au ieme joursem dans le mois 
+//	correspondant (exemple, 2e dimanche de mars 1960).
+//--
+{
+   if (i>0) {
+     int jprem = Date(1, mois, annee, 0, 0, 0).DayOfWeek();
+     int d = (joursem - jprem);
+     if (d<0) d+=7;
+     return d + 1 + (i-1)*7;
+   } else {
+     int ider = MonthDays(mois, annee);
+     int jder = Date(ider, mois, annee, 0, 0, 0).DayOfWeek();
+     int d = (joursem - jder);
+     if (d>0) d-=7;
+     return d + ider + (i+1)*7;
+   }
+}
+
+//++
+Date& Date::operator += (double dt)     
+//
+//	dt en jours
+//--
+{
+  int u = UndetTime();
+  Set(GetDays()+dt);
+  if (u) ss = hh = mm = -1;
+  return *this;
+}
+
+//++
+Date& Date::operator -= (double dt)    
+//
+//	dt en jours
+//--
+{
+  int u = UndetTime();
+  Set(GetDays()-dt);
+  if (u) ss = hh = mm = -1;
+  return *this;
+}
+
+//++
+Date operator + (Date const& d, double dt)
+//
+//--
+{
+  Date a(d);
+  a += dt;
+  return a;
+}
+
+//++
+Date operator - (Date const& d, double dt)
+//
+//--
+{
+  Date a(d);
+  a -= dt;
+  return a;
+}
+
+//++
+double operator - (Date const& a, Date const& b)
+//
+//	Résultat en jours
+//--
+{
+  if (a.UndetTime() != b.UndetTime()) THROW(inconsistentErr);
+  if (a.UndetDate() != b.UndetDate()) THROW(inconsistentErr);
+  return a.GetDays() - b.GetDays();
+}
+
+//++
+bool operator == (Date const& a, Date const& b)
+//
+//	On n'a pas égalite dès que des éléments déterminés sont différents
+//--
+{
+  if (a.nuit && a.UndetTime() && !b.nuit && !b.UndetTime() && b.hh<12)
+    {Date d = a+1; d.nuit = 0; return d == b;}
+  else if (b.nuit && b.UndetTime() && !a.nuit && !a.UndetTime() && a.hh<12)
+    {Date d = b+1; d.nuit = 0; return a == d;}
+
+  if (a.AA != -1 && b.AA != -1 && a.AA != b.AA) return false;
+  if (a.MM != -1 && b.MM != -1 && a.MM != b.MM) return false;
+  if (a.JJ != -1 && b.JJ != -1 && a.JJ != b.JJ) return false;
+  if (a.hh != -1 && b.hh != -1 && a.hh != b.hh) return false;
+  if (a.mm != -1 && b.mm != -1 && a.mm != b.mm) return false;
+  if (a.ss != -1 && b.ss != -1 && a.ss != b.ss) return false;
+  return true;
+}
+
+//++
+bool operator != (Date const& a, Date const& b)
+//
+//--
+{
+  return !(a == b);
+}
+
+//++
+bool operator <= (Date const& a, Date const& b)
+//
+//	Inégalité large. Pas de subtilités
+//--
+{
+  if (a.nuit && a.UndetTime() && !b.nuit && !b.UndetTime() && b.hh<12)
+    {Date d = a+1; d.nuit = 0; return d <= b;}
+  else if (b.nuit && b.UndetTime() && !a.nuit && !a.UndetTime() && a.hh<12)
+    {Date d = b+1; d.nuit = 0; return a <= d;}
+
+  if (a.AA != -1 && b.AA != -1) {
+    if (a.AA < b.AA) return true;
+    if (a.AA > b.AA) return false;
+  }
+  if (a.MM != -1 && b.MM != -1) {
+    if (a.MM < b.MM) return true;
+    if (a.MM > b.MM) return false;
+  }
+  if (a.JJ != -1 && b.JJ != -1) {
+    if (a.JJ < b.JJ) return true;
+    if (a.JJ > b.JJ) return false;
+  }
+  if (a.hh != -1 && b.hh != -1) {
+    if (a.hh < b.hh) return true;
+    if (a.hh > b.hh) return false;
+  }
+  if (a.mm != -1 && b.mm != -1) {
+    if (a.mm < b.mm) return true;
+    if (a.mm > b.mm) return false;
+  }
+  if (a.ss != -1 && b.ss != -1) {
+    if (a.ss < b.ss) return true;
+    if (a.ss > b.ss) return false;
+  }
+  return true;
+}
+
+//++
+bool operator < (Date const& a, Date const& b)
+//
+//	Inégalité stricte, codée à partir de la large pour résoudre
+//	sans cas particuliers les subtilités 
+//	01/02/95 < ??/03/95 mais pas 01/02/95 < ??/02/95
+//--
+{
+  return (a <= b) && !(a == b);
+}
+
+//++
+bool operator >= (Date const& a, Date const& b)
+//
+//--
+{
+  return (b <= a);
+}
+
+//++
+bool operator > (Date const& a, Date const& b)
+//
+//--
+{
+  return (b < a);
+}
+
+//++
+ostream& operator << (ostream& s, Date const& d)
+//
+//--
+{
+  char x[20];
+  d.GetDateStr(x);
+  s << x << " ";
+  d.GetTimeStr(x);
+  s << x;
+  return s;
+}
Index: /tags/V_Dec2002/SophyaLib/NTools/dates.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/dates.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/dates.h	(revision 2309)
@@ -0,0 +1,154 @@
+//   Gestion de dates 
+//        E. Aubourg       1995-2000
+// DAPNIA/SPP (Saclay) / CEA    LAL - IN2P3/CNRS  (Orsay)
+
+#ifndef DATES_SEEN
+#define DATES_SEEN
+
+#include <string.h>
+#include <string>
+#include <iostream.h>
+#include "pexceptions.h"
+
+// namespace SOPHYA {  
+
+class TimeZone;
+// <summary> Dates, conversions, operations </summary>
+// Classe generale de date et heure, operation, TU/TL ...
+class Date  {
+public:
+  // Enumerations jours et mois
+  // <group>
+  enum Jour {jour_Lundi=0, jour_Mardi, jour_Mercredi, jour_Jeudi, jour_Vendredi, jour_Samedi, jour_Dimanche};
+  enum Mois {mois_Janvier=1, mois_Fevrier, mois_Mars, mois_Avril, mois_Mai, mois_Juin, mois_Juillet,
+             mois_Aout, mois_Septembre, mois_Octobre, mois_Novembre, mois_Decembre};
+  enum {kGMTTime=0, kLocalTime=1};
+  // </group>  
+
+  // Constructeur : maintenant 
+  Date();
+  // Constructeur : jours ecoules depuis 0/1/1901 0h TU
+  Date(double);
+  // Constructeur : "jj/mm/aa" ou "amjj", "hh:mm:ss"
+  // topt : kGMTTime (par defaut) ou kLocalTime
+  // <group>
+  Date(const char*, const char* = 0, int topt=0); 
+  Date(string const&, string const& = "", int topt=0); 
+  // </group>
+  // Constructeur : Jour Mois An, Heure Minutes Secondes
+  Date(int J, int M, int A, int h, int m, double s);
+
+  /*operator double() const;*/
+  // Jours depuis le 0 janvier 1901 0h TU
+  double GetDays() const;
+  // Jours depuis le 0 janvier 1901 0h TU
+  void Set(double);
+  //  "jj/mm/aa" ou "amjj", "hh:mm:ss"
+  // <group>
+  void Set(const char*, const char* = 0, int topt=0);
+  void Set(string const&, string const& = "", int topt=0);
+  // </group>
+  
+  // Change de zone horaire.
+  void SetTimeZone(TimeZone* tz);
+
+  // Verifie si des parties de la date sont indeterminees
+  // <group>
+  // Date partiellement indeterminee
+  bool UndetDate() const;
+  // Date totalement indeterminee
+  bool AllUndetDate() const;
+  // Heure partiellement indeterminee
+  bool UndetTime() const;
+  // Heure totalement indeterminee
+  bool AllUndetTime() const;
+  // </group>
+
+  // Conversion vers des chaines de caractere,
+  // date en clair ou code Eros, heure, et temps sideral
+  // en heure local ou GMT.
+  // <group>
+  void GetDateStr(char*, int tOpt=0) const;
+  void GetDateCode(char*, int tOpt=0) const;
+  void GetTimeStr(char*, int tOpt=0) const;
+  void GetSidTStr(char*) const;
+  
+  string DateStr(int tOpt=0) const;
+  string DateCode(int tOpt=0) const;
+  string TimeStr(int tOpt=0) const;
+  string SidTStr() const;
+  // </group>
+
+  // Jour de la semaine, jour_Lundi == 0
+  int  DayOfWeek(int tOpt=0) const;
+  
+  // Ajoute ou soustrait un intervalle en jour et fraction de jour
+  // <group>
+  Date& operator += (double);
+  Date& operator -= (double);
+
+  friend Date operator + (Date const&, double);
+  friend Date operator - (Date const&, double);
+  // </group>
+  
+  // Nombre de jour (et fraction) entre deux dates
+  friend double operator - (Date const&, Date const&);
+  
+  // Comparaisons entre dates
+  // <group>
+  friend bool operator == (Date const&, Date const&);
+  friend bool operator <  (Date const&, Date const&);
+  friend bool operator <= (Date const&, Date const&);
+  friend bool operator >  (Date const&, Date const&);
+  friend bool operator >= (Date const&, Date const&);
+  friend bool operator != (Date const&, Date const&);
+  // </group>
+  
+  // Impression
+  friend ostream& operator << (ostream&, Date const&);
+
+  // Nombre de jours dans le mois
+  static short MonthDays(short mois, short annee);
+  
+  // Nombre de jours dans l'annee
+  static short YearDays(short annee);
+  
+  // Ieme jourssem dans le mois
+  // (2, jour_Dimanche, 5, 1996) : deuxieme dimanche de mai 96
+  static short NthMonthDay(short i, short joursem, short mois, short annee);
+
+  short JJ,MM,AA,hh,mm;
+  double ss; 
+  TimeZone* timeZone;
+  int nuit;  // est-ce une date midi-midi ?
+
+/* void GetSysTimeZone(); */
+};
+
+// <summary> Gestion des fuseaux horaires </summary>
+// Classe de gestion des fuseaux horaires. Tient compte des heures d'ete.
+class TimeZone  {
+public:
+  char code[4];
+  char name[20];
+
+  short  gmtOffset;
+
+  short  hasDST;
+  short  dstByWeekDay;
+  short  dstStartDay, dstStartNum, dstStartMonth;   // -1 : le dernier, dstStartDay : apres cette date
+  short  dstStopDay, dstStopNum, dstStopMonth;
+  short  dstOffset;
+
+  TimeZone();                 // Tente de deviner le timezone systeme
+  TimeZone(const char*);      // Par nom
+  void SetZone(const char*);
+  int IsDst(Date const& date);
+  int GetOffset(Date const& date);
+};
+
+extern TimeZone* gTimeZone;
+
+// }  namespace SOPHYA
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/datime.c
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/datime.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/datime.c	(revision 2309)
@@ -0,0 +1,1266 @@
+#include "machdefs.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+#ifdef __MWERKS__
+#include "unixmac.h"
+#endif
+
+#define DATIMEPRIVEE
+#include "strutil.h"
+#include "nbconst.h"
+#include "datime.h"
+
+
+/*       Fonctions de calcule de date et temps (Heure)       */
+/* 
+++ 
+  Module 	Dates (C)
+  Lib	LibsUtil
+  include	datime.h
+
+	Ce groupe de fonctions permettent de manipuler des dates et heures.
+	En particulier, il est possible de calculer l'ecart (en nombre de jours
+	ou de secondes separant deux dates, ou le temps sideral correspondant 
+	a une date et heure legale. Deux structures simples sont definies
+	afin de faciliter le passage des arguments entre differentes fonctions:
+	- *JMA* : Jour, Mois, Annee
+ 	- *HMS* : Heure, Minutes, Secondes
+
+--
+*/
+/*
+++
+  Links	Voir aussi:
+ Temps Sideral, Universel (C)
+--
+*/
+/*
+++
+Titre	Quelques Macros 
+--
+*/
+
+/*
+++
+  StrgtoJMA(strg, jma)
+	Decodage d'une chaine de caracteres "strg" sous forme de "12/3/97" en structure 
+	JMA "jma".
+  JMAtoStrg(jma, strg)
+	Ecrit le contenu de la structure JMA "jma" sous forme de "jj/mm/aaaa" dans la chaine
+	de caracteres "strg"
+  JMAtoStrgLong(jma, strg)
+	Ecriture de date en format long , par ex : "Jeudi , 19 Juin 1997"
+  StrgtoHMS(strg, hms)
+	Decodage d'une chaine de caracteres "strg" sous forme de "hh:mm:ss 10:43:60.5"
+	en structure HMS "hms".
+  HMStoStrg(hms, strg)
+	Ecrit le contenu de la structure HMS "hms" sous forme de "hh:mm:ss" dans la chaine
+	de caracteres "strg"
+  StrtoHMS(strg, hms)
+	Decodage d'une chaine de caracteres "strg" sous forme de "hh:mm:ss 10:43:60.5"
+	en structure HMS "hms" avec gestion des signes (decodage correcte de -44:30:05.23)
+  HMStoStr(hms, strg)
+	Ecrit le contenu de la structure HMS "hms" sous forme de "hh:mm:ss" dans la chaine
+	de caracteres "strg" avec gestion des signes
+--
+*/
+
+void StrtoHMS(char *s,HMS* h)
+/* On ne peut pas ecrire 1:-05:-45 pas gere et debile! (mn et sec >=0.)  cmv 12/8/97 */
+{
+int imoins, i2pt;
+h->Heures = h->Minutes = 0; h->Secondes = 0.;
+/* decodage de la chaine de characteres */
+sscanf(s,"%d:%d:%lf", &(h->Heures),&(h->Minutes),&(h->Secondes));
+/* cas du type 5:34:45.5 */
+if( h->Heures > 0 ) return;
+/* cas du type -5:34:45.5 */
+if( h->Heures < 0 ) {
+  h->Minutes *= -1; h->Secondes *= -1.;
+  return;
+}
+/* Ici les Heures sont donc nulles "0:..." ou "-0:..." */
+/* on n'a donne que l'heure nulle cas "0" ou "-0" sans ":" (idiot mais bon!) */
+i2pt = posc(s,':');
+if( i2pt < 0 ) return;
+/* Ici on a au moins un ou 2 ":" */
+/* cas du type 0:34:45.5 ou 0:0:45.5 sans signe - */
+imoins = posc(s,'-');
+if( imoins < 0 ) return;
+/* cas du type -0:34:45.5 ou -0:0:45.5, le signe - n'est pas decode par sscanf */
+if( imoins < i2pt ) {   /* on a donne -0:34 ou -0:34:45.5 */
+  h->Minutes *= -1; h->Secondes *= -1.;
+  return;
+}
+/* Ici il reste les cas mal codes ou le signe "-" est n'importe ou! */
+/* On laisse le decodage par sscanf */
+return;
+}
+
+
+void HMStoStr(HMS h,char *s)
+/* L'ecriture est forcee a h:mn:sec avec mn et sec >=0  cmv 12/8/97 */
+{
+double v;
+v = HMStoH(h);
+h =  DoubletoHMS(v);
+if( v < 0. ) {
+  h.Heures *= -1; h.Minutes *= -1; h.Secondes *= -1.;
+  sprintf(s,"-%02d:%02d:%04.1f", h.Heures,h.Minutes,h.Secondes);
+} else {
+  sprintf(s,"%02d:%02d:%04.1f", h.Heures,h.Minutes,h.Secondes);
+}
+}
+
+/* Nouvelle-Fonction */
+int NbJourMois(int a, int m)
+/* Retourne le nombre de jours dans le mois m, annee a */
+{
+if(a<100) a+=1900;
+if( m<1 || m>12 ) return(-1);
+m--;
+if(m!=1) return(NbJoMois[m]);
+/* traitement du mois de fevrier bissextile ou non */
+if(  ((a%4==0) && (a%100!=0))
+  ||       (a%400==0)         ) return(NbJoMois[m]+1);
+else return(NbJoMois[m]);
+}
+
+/* Nouvelle-Fonction */
+long JMAtoJ(JMA jma)
+/*           Calcule le Nb. de jours ecoules depuis 0 Jan 1901         */
+/*   Si annee < 100  On considere annee = annee+1900  (1900-1999)      */
+
+{
+long rc,nban;
+int i;
+
+/* Protection */
+if ( (jma.Mois < 1) || (jma.Mois > 12) )  jma.Mois = 1;
+if ( (jma.Jour < 1) || (jma.Jour > 31) )  jma.Jour = 1;
+
+if (jma.Annee < 100)  jma.Annee+=1900;
+nban = jma.Annee - 1901;
+
+/*  Annee Normale = 365 Jours - Bissextile = 366 Jours    */
+/*  366 Jours  :  Divisible par 4 et non divisible par 100  (1972,1976)   */
+/*             :  Divisible par 400 (1900 Non-Biss. et 2000 Biss.)        */
+
+if (nban >= 0)  
+  rc = nban*365 + (nban/4) - (nban/100) + ((nban+300)/400);
+else 
+  rc = nban*365 + (nban/4) - (nban/100) + ((nban-300)/400);
+
+/*    Comptabilisation du nb. des jours des mois ecoule   */
+for (i=1; i<jma.Mois; i++)  rc += NbJourMois(jma.Annee, i);
+rc += jma.Jour;
+
+return(rc);
+}
+
+/* Nouvelle-Fonction */
+JMA JtoJMA(long j)
+/* retourne la date correspondant a j jours ecoules depuis le 0/1/1901 */
+{
+long i;
+int inc,m;
+JMA buf;
+
+inc = (j>=0) ? 1 : -1;
+buf.Jour = buf.Mois = 1; buf.Annee = 1901;
+
+/* recherche de l'annee */
+for(;;) {
+  i = j-JMAtoJ(buf);
+  if( i==0 ) return(buf);
+  if( inc*i<0 ) {
+    /* printf("...annee j=%ld scan=%ld test=%ld\n"
+          ,j,JMAtoJ(buf),inc*i); */
+    break;
+  }
+  buf.Annee += inc;
+}
+if(inc>0) buf.Annee--;
+/* printf("Annee trouvee: %d\n",buf.Annee); */
+
+/* recherche du mois */
+for(m=1;m<=12;m++) {
+  buf.Mois=m;
+  i = j-JMAtoJ(buf);
+  if( i==0 ) return(buf);
+  if(i<0) {
+    /* printf("...mois j=%ld scan=%ld test=%ld\n"
+          ,j,JMAtoJ(buf),i); */
+    buf.Mois--;
+    break;
+  }
+}
+/* printf("Mois trouve: %d\n",buf.Mois); */
+
+/* recherche du jour */
+for(m=1;m<=31;m++) {
+  buf.Jour=m;
+  i = j-JMAtoJ(buf);
+  if( i==0 ) return(buf);
+}
+/* printf("Jour trouve: %d\n",buf.Jour); */
+
+/* on a pas trouve !!! normallement impossible! */
+printf("**** JtoJMA_Erreur: date non trouvee j=%ld ****\n",j);
+buf.Jour = buf.Mois = 1; buf.Annee = 0;
+return(buf);
+}
+
+/* Nouvelle-Fonction */
+int NumJour(JMA jma)
+/*        Cette fonction calcule le numero de jour de la semaine    */
+/*        (Lundi=1 .. Dimanche=7)                                   */
+
+{
+int l;
+
+/*  On appelle JMAtoJ() pour avoir le nb de jours ecoule depuis 1/01/1901  */
+/*  Le premier janvier 1901 etait un Mardi (JMAtoJ = 1 , NumJour = 2)      */
+l = JMAtoJ(jma)%7 ;
+if (l >= 0)  return(l+1);
+else return(l+8);
+}
+
+/* Nouvelle-Fonction */
+JMA JsmmaatoJMA(int nj, int mm, int aa)
+
+/*   Pour "nj=kj*10+jj", calcule la date correspondant au "kj" eme 
+     jour "jj" (1 .. 7 - Lundi .. Dimanche) du mois mm , annee aa
+     Si "nj" est negatif ->  Dernier jour "jj". Si "kj=0", premier jour "jj".
+     Si "kj" ne peut etre atteint -> Dernier jour "jj".
+     Si annee "aa" <= 99   ->  annee de 1901 - 1999       */
+
+{
+JMA  jma;
+int i,k;
+int jj, kj;
+
+kj = nj/10;
+jj = nj%10;
+if (kj < 0)  kj = 0;
+
+if (mm > 12)  mm = 12;
+if (mm < 1 ) mm = 1;
+if (aa < 100)  aa += 1900;
+jma.Mois = mm;
+jma.Annee = aa;
+
+if (kj == 0) {
+  if (jj >= 0)  {      /*   Premier jour du mois   */    
+    if (jj > 7)  jj = 7;
+    if (jj < 1)  jj = 1;
+    jma.Jour = 1;
+    i = NumJour(jma);
+    if (i > jj)  jma.Jour = (7-i)+jj+1;
+    else jma.Jour = 1+(jj-i);
+    }
+  else   {             /*   Dernier jour du mois   */
+    jj = -jj;
+    if (jj > 7)  jj = 7;
+    if (jj < 1)  jj = 1;
+    jma.Jour = NbJourMois(aa,mm);  
+    i = NumJour(jma);
+    if (i >= jj)   jma.Jour -= (i-jj);
+    else  jma.Jour -= (7+i-jj);
+  }
+}
+else {  /*  On demande le kj eme jour jj du mois  */
+  if (jj > 7)  jj = 7;
+  if (jj < 1)  jj = 1;
+  k = 0;
+  for(i=1; i<=NbJourMois(aa,mm); i++) {
+    jma.Jour = i;
+    if (NumJour(jma) == jj)  k++;
+    if (k == kj)  break;
+  }
+/*  On n'a pas kj jour jj ds ce mois, on renvoie le dernier jj */
+  if (k<kj) return(JsmmaatoJMA(-jj, mm, aa));  
+}
+
+return(jma);
+}
+
+JMA JApmmaatoJMA(int nj, int mm, int aa)
+/*    Pour "nj=dd*10+jj", calcule la date correspondant au jour
+      "jj" (1 .. 7 - Lundi .. Dimanche) du mois "mm" , annee "aa"
+      se trouvant apres (ou egal a) la date "dd/mm/aa" .
+      Si annee "aa" <= 99   ->  annee de 1901 - 1999       */
+{
+int i, dd, jj;
+JMA jma;
+
+if (nj < 0) nj = -nj;
+if (nj < 1) nj = 1;
+dd = nj/10;
+jj = nj%10;
+for(i=1; i<=6; i++) {
+  jma = JsmmaatoJMA(jj+10*i, mm, aa);
+  if(jma.Jour >= dd) return(jma);
+}
+printf("JApmmaatoJMA(%d...) Erreur / Pas de jour %d >= %d/%d/%d\n", nj, jj,dd, mm, aa);
+jma.Jour = jma.Mois = jma.Annee = 0;
+return(jma);
+}
+
+/* Nouvelle-Fonction */
+double HMStoH(HMS hms)
+
+/* Cette fonction calcule le nb d'heures en decimales pour hms */
+/* Heures/Minutes/Secondes peuvent etre +/- avec toutes les combi possibles */
+{
+return ((double)hms.Heures + ((double)hms.Minutes)/60. + hms.Secondes/3600.);
+}
+
+
+
+/* Nouvelle-Fonction */
+double HMStoSec(HMS hms)
+/*    Calcul du nb de secondes pour hms    */
+/* Heures/Minutes/Secondes peuvent etre +/- avec toutes les combi possibles */
+{
+return ((double)hms.Heures*3600. + (double)hms.Minutes*60. + hms.Secondes);
+}
+
+/* Nouvelle-Fonction */
+long DatetoSec(char const* date, char const* heure)
+/*   Calcul du nombre de secondes correspondant a date/heure    */
+/*  a partir de l'origine 1er Janv 1990  0H00                   */
+/*  Date entre 1930 - 2050                                      */
+{
+JMA jma,jma0;
+HMS hms;
+long dj;
+
+StrgtoJMA(date,jma);   StrgtoHMS(heure,hms);
+StrgtoJMA("01/01/1990",jma0);
+dj = JMAtoJ(jma) - JMAtoJ(jma0);
+if (dj < -24000)  return(-0x7FFFFFFF);
+if (dj > 24000)  return(0x7FFFFFFF);
+return( dj*3600*24 + (int)(HMStoSec(hms)) );    
+}
+
+/* Nouvelle-Fonction */
+long DatetoSecOff(char const* date, char const* heure)
+{
+JMA jma,jma0;
+HMS hms, hms0;
+long dj,tdec;
+
+StrgtoJMA(date,jma);   StrgtoHMS(heure,hms);
+StrgtoJMA("01/01/1990",jma0);   StrgtoHMS("00:00:00",hms0);
+dj = JMAtoJ(jma) - JMAtoJ(jma0);
+if (dj < -24000)  return(-0x7FFFFFFF);
+if (dj > 24000)  return(0x7FFFFFFF);
+
+/* H_vrai+TOff=H_leg : H_vrai-H_vrai0 = (H_leg-TOff)-(H_leg0-TOff0) */
+tdec  = 3600*(TLegOffset(jma, hms)-TLegOffset(jma0, hms0));
+
+dj = dj*3600*24 + (int)(HMStoSec(hms)) - tdec;
+return(dj);    
+}
+
+/* Nouvelle-Fonction */
+HMS HtoHMS(double h)
+/* Heures decimales en H , M , Sec  Il y a un modulo 24  */
+/* la sortie est telle que 0 <= heures < 24 */
+{
+HMS hms; 
+
+while (h < 0.) h += 24.;
+  
+hms.Heures = (int) h;
+h = (h-hms.Heures)*60.;
+hms.Minutes = (int) h;
+hms.Secondes = (h-hms.Minutes)*60.;
+hms.Heures = hms.Heures % 24;
+
+return(hms);
+}
+
+/* Nouvelle-Fonction */
+HMS DtoDMS(double h)
+/* Degres decimaux en D , M , Sec  Il y a un modulo 360  */
+/* la sortie est telle que -180 < deg <= 180. */
+{
+HMS hms;
+int sgn = 1;
+
+while (h > 180.) h -= 360.;
+while (h <= -180.) h += 360.;
+if( h < 0. ) {h *= -1.; sgn = -1;}
+  
+hms.Heures = (int) h;
+h = (h-hms.Heures)*60.;
+hms.Minutes = (int) h;
+hms.Secondes = (h-hms.Minutes)*60.;
+hms.Heures = hms.Heures % 360;
+
+if( sgn<0 ) {hms.Heures *= -1; hms.Minutes *= -1; hms.Secondes *= -1.;}
+return(hms);
+}
+
+/* Nouvelle-Fonction */
+HMS DoubletoHMS(double h)
+/*    Degres/Heures decimaux en D/H , M , Sec  SANS modulo 360/24  */
+{
+HMS hms;
+
+int sgn = 1;
+if( h < 0. ) {h *= -1.; sgn = -1;}
+
+hms.Heures = (int) h;
+h = (h-hms.Heures)*60.;
+hms.Minutes = (int) h;
+hms.Secondes = (h-hms.Minutes)*60.;
+hms.Heures = hms.Heures;
+
+if( sgn<0 ) {hms.Heures *= -1; hms.Minutes *= -1; hms.Secondes *= -1.;}
+return(hms);
+}
+
+/*
+++
+ Titre	Calcule sur dates et heures
+--
+*/
+
+/*
+++
+int NbJourMois(int a, int m)
+	Retourne le nombre de jours dans le mois "m", annee "a".
+long JMAtoJ(JMA jma)
+	Calcule le Nb. de jours ecoules depuis 0 Jan 1901, 
+	Si annee < 100  On considere annee = annee+1900  (1900-1999)
+JMA JtoJMA(long j)
+	Retourne la date correspondant a un nombre de jours "j"
+	ecoules depuis le 0 Jan 1901.
+int NumJour(JMA jma)
+	Calcule le numero du jour de la semaine correspondant a la date indiquee
+	par la structure JMA "jma". (Lundi=1 .. Dimanche=7)
+JMA JsmmaatoJMA(int nj, int mm, int aa)
+	Pour "nj=kj*10+jj", calcule la date correspondant au "kj" eme 
+	jour "jj" (1 .. 7 - Lundi .. Dimanche) du mois mm , annee aa
+  	Si "nj" est negatif ->  Dernier jour "jj". Si "kj=0", premier jour "jj".
+	Si "kj" ne peut etre atteint -> Dernier jour "jj".
+	Si annee "aa" <= 99   ->  annee de 1901 - 1999       
+JMA JApmmaatoJMA(int nj, int mm, int aa)
+	Pour "nj=dd*10+jj", calcule la date correspondant au jour
+	"jj" (1 .. 7 - Lundi .. Dimanche) du mois "mm" , annee "aa"
+	se trouvant apres (ou egal a) la date "dd/mm/aa" .
+	Si annee "aa" <= 99   ->  annee de 1901 - 1999       
+double HMStoH(HMS hms)
+	Conversion en heures decimales de la structure  "hms"
+double HMStoSec(HMS hms)
+	Conversion en secondes de la structure HMS  "hms"
+HMS HtoHMS(double h)
+	Conversion heures en decimales en structure HMS
+HMS DtoDMS(double h)
+	Conversion degres decimaux en structure HMS (deg,min,sec)
+HMS DoubletoHMS(double h)
+	Conversion degres/heures decimaux en structure HMS (deg/heure,min,sec)
+                   SANS modulo 360/24
+long DatetoSec(char const* date, char const* heure)
+	Calcule le nombre de secondes correspondant a "date,heure" 
+	a partir de l'origine 1er Janv 1990  0H00 ( Date entre 1930 - 2050 )		
+long DatetoSecOff(char const* date, char const* heure)
+	Calcule le nombre de secondes correspondant a "date,heure" 
+	a partir de l'origine 1er Janv 1990  0H00 ( Date entre 1930 - 2050 )
+        en tenant compte des decalages des heures legales.
+--
+*/
+
+
+
+/*   Variables contenant les informations pour conversion  */
+/*  Temps Legal <> TU <> Temps solaire moyen               */
+
+static double  TSolMOff = 0.;     /*  TSol.Moyen - TU  (en heures) */
+static char SiteName[128];           /*  Nom de site  */
+
+static struct
+  {
+  char fg;         /*  Flag (=A ou B) Type de specification  */
+  int jj[2];       /*  Numero ou date du jour                */
+  int mm[2];       /*  Mois    */
+  int Off[3];      /*  Decalage = TLegal - TU    */
+  }  TLegInfo = {'\0',{0,0},{0,0},{0,0,0}} ;
+
+static HMS HChgH = {0,0,0.} ; /*  Heure de changement d'heure */
+
+/* 
+++ 
+  Module 	Temps Sideral, Universel (C)
+  Lib	LibsUtil
+  include	datime.h
+
+	Ce groupe de fonctions permet convertir differentes heures:
+	les temps local, le temps universel (TU), le temps legal (TLeg). Il est 
+	aussi possible de calculer le temps sideral (TS). 
+--
+*/
+/*
+++
+  Links	Voir aussi:
+  Dates (C)
+--
+*/
+/*
+++
+ Titre	T-Legal, TU
+	Conversion entre l'heure legale, le temps universel (TU) et le temps solaire
+	moyen
+--
+*/
+
+/*
+++
+SetTSolMOff(double tsmoff, char *name)
+	Definit pour un site donne, le decalage T Sol. Moyen - TU (en heures) "tmsoff"
+	et le nom du site 
+PrtTSolMOff()
+	Imprime les infos definis par "SetTSolMOff()"
+--
+*/
+
+/* Nouvelle-Fonction */
+void SetTSolMOff(double tsmoff, char *name)
+
+/*     Offset  T Sol. Moyen - TU (en hh:mm:ss) ,  Nom de site name   */
+{
+TSolMOff = tsmoff;
+strcpy(SiteName,name);
+return;
+}
+
+
+/* Nouvelle-Fonction */
+void PrtTSolMOff(void)
+{
+printf("  **Site : %s , T Sol.Moy.-TU  %g  (heures) \n",SiteName,TSolMOff);
+return;
+}
+
+/*
+++
+int SetTLegOff(char* dtz, char* dhz)
+	Initialise la structure TLegInfo. L'argument *dtz peut etre 
+	sous 2 forme differentes et permet de  definir 3 plages 
+	de temps avec 3 decalages horaires (nb entier). 
+	Les dates pivots sont les jours de changement d'heure a 
+	l'heure indiquee par dhz ("hh:mm:ss"), si "dhz==NULL ou 
+	chaine vide, alors changement a 0 heure.  
+|   1) dtz = "A Off1 j1/m1 Off2 j2/m2 Off3"
+|      jx/mx Jour/Mois - Offx : Decalage TLeg - TU                  
+|      pour 01/01 <= jj/mm <  j1/m1   ->  Off1 
+|           j1/m1 <= jj/mm <  j2/m2   ->  Off2 
+|           j2/m2 <= jj/mm <= 31/12   ->  off3 
+|   2) dtz = "B off1 Js1/m1 Off2 Js2/m2 Off3"
+|      Jsx/mx  Numero du jour de la semaine (Js) et numero du mois
+|      Js =  1 ..  7  (Lundi .. Dimanche)  :  1er Jour Js du mois    
+|         = -1 .. -7   Dernier jour Js du mois                  
+|         = k1 .. k7   k eme jour Js du mois                  
+|   3) dtz = "C off1 Js1/m1 Off2 Js2/m2 Off3"
+|      Jsx/mx  Numero du jour de la semaine (Js) et numero du mois avec une 
+|      precision d'une date butee inferieurs    
+|      Js =  ddj ..  (j=1..7  Lundi .. Dimanche)  :  1er Jour j du mois
+|      apres (ou egal a) la date dd/mm    
+	Retour : 0 si Ok -1 Sinon                                          
+void PrtTLegInfo(int aa)	
+	Imprime les informations de decalage TLeg ,  TU - Annee "aa"
+int  TLegOffset(JMA date, HMS heure)
+	Indique le decalage (en nombre d'heures) TLeg-TU	
+--
+*/
+
+/* Nouvelle-Fonction */
+int SetTLegOff(char* dtz, char* dhz)
+
+                        
+{
+int is;
+
+HChgH.Heures = HChgH.Minutes = 0;
+HChgH.Secondes = 0.;
+
+if (dhz) StrgtoHMS(dhz, HChgH);
+if ( (HChgH.Heures < 0) || (HChgH.Heures > 23) )
+  { HChgH.Heures = HChgH.Minutes = 0;  HChgH.Secondes = 0.; }
+
+is = sscanf(dtz,"%c %d %d/%d %d %d/%d %d", &(TLegInfo.fg), &(TLegInfo.Off[0]), &(TLegInfo.jj[0]),  &(TLegInfo.mm[0]), &(TLegInfo.Off[1]), &(TLegInfo.jj[1]),  &(TLegInfo.mm[1]), &(TLegInfo.Off[2]) );
+
+if ( (TLegInfo.fg != 'A') && (TLegInfo.fg != 'B')
+     && (TLegInfo.fg != 'C') )  TLegInfo.fg = '\0';
+if (is != 8) TLegInfo.fg = '\0';
+if (TLegInfo.fg != '\0') return(0);
+else { printf("SetTLegOff()/Erreur %s \n", dtz); return(-1); }
+}
+
+/* Nouvelle-Fonction */
+void PrtTLegInfo(int aa)
+
+/*    Cette fonction  print les infos de TLegInfo     */
+{
+int i,k,j;
+char ForL[2][128];
+JMA jma;
+
+if (TLegInfo.fg == '\0')    printf ("  !!! TlegInfo not set or Error \n");
+
+
+HMStoStrg(HChgH, ForL[0]);
+printf("  ==== TLegInfo : Changement d'heure a %s \n", ForL[0]);
+ForL[0][0] = '\0';
+if (TLegInfo.fg == 'A')  
+  {
+  printf("  ---- TLegInfo : Selection par date (Flag = A)  ---- \n");
+  printf("   -> 01 Janvier - %d %s   :  %d heures \n",TLegInfo.jj[0], NomMo[TLegInfo.mm[0]-1], TLegInfo.Off[0]);
+  printf("   -> %d %s - %d %s  :  %d heures \n",TLegInfo.jj[0], NomMo[TLegInfo.mm[0]-1],TLegInfo.jj[1], NomMo[TLegInfo.mm[1]-1],TLegInfo.Off[1]);
+  printf("   -> %d %s - 31 Decembre  :  %d heures \n",TLegInfo.jj[1], NomMo[TLegInfo.mm[1]-1], TLegInfo.Off[2]);
+  }
+
+if (TLegInfo.fg == 'B')  
+  {
+  printf("  --- TLegInfo : Selection par Jour de semaine et mois (Flag = B)  --- \n");
+  for (i=0;i<2;i++) {
+    k = TLegInfo.jj[i]/10;
+    if (k < 1)  k = 1;
+    j = TLegInfo.jj[i]%10;
+    if (j < 0)  j = -j;
+    if (j < 1) j = 1;
+    if (j > 7) j = 7;
+    if (TLegInfo.jj[i] < 0)  sprintf(ForL[i]," Dernier  %s  de  %s  (KJ=%d)", NomJo[j-1], 
+                                     NomMo[TLegInfo.mm[i]-1], TLegInfo.jj[i]);
+    else  sprintf(ForL[i]," %d eme  %s  de  %s (KJ=%d)", k, NomJo[j-1], 
+                  NomMo[TLegInfo.mm[i]-1], TLegInfo.jj[i]);
+    }
+  printf(" Butees: %s  -  %s \n", ForL[0], ForL[1]);
+  for (i=0;i<2;i++) {
+    jma = JsmmaatoJMA(TLegInfo.jj[i], TLegInfo.mm[i], aa);
+    JMAtoStrg(jma, ForL[i]);
+  }
+  printf("   -> 01 Janvier %d - %s  :  %d heures \n",aa, ForL[0], TLegInfo.Off[0]);
+  printf("   -> %s - %s  :  %d heures \n",ForL[0], ForL[1], TLegInfo.Off[1]);
+  printf("   -> %s - 31 Decembre %d :  %d heures \n",ForL[1], aa, TLegInfo.Off[2]);
+ }
+
+if (TLegInfo.fg == 'C')  
+  {
+  printf("  --- TLegInfo : Selection par Jour de semaine >= dd et mois (Flag = C)  --- \n");
+  for (i=0;i<2;i++) {
+    k = TLegInfo.jj[i]/10;
+    j = TLegInfo.jj[i]%10;
+    if (j < 0)  j = -j;
+    if (j < 1) j = 1;
+    if (j > 7) j = 7;
+    sprintf(ForL[i],"1er %s  apres le %d %s ", NomJo[j-1], k, NomMo[TLegInfo.mm[i]-1]);
+    }
+  printf(" Butees: %s - %s \n", ForL[0], ForL[1]);
+  for (i=0;i<2;i++) {
+    jma = JApmmaatoJMA(TLegInfo.jj[i], TLegInfo.mm[i], aa);
+    JMAtoStrg(jma, ForL[i]);
+  }
+  printf("   -> 01 Janvier %d - %s  :  %d heures \n",aa, ForL[0], TLegInfo.Off[0]);
+  printf("   -> %s - %s  :  %d heures \n",ForL[0], ForL[1], TLegInfo.Off[1]);
+  printf("   -> %s - 31 Decembre %d :  %d heures \n",ForL[1], aa, TLegInfo.Off[2]);
+ }
+
+return;
+}
+
+
+/* Nouvelle-Fonction */
+int  TLegOffset(JMA date, HMS heure)
+
+/*     Cette fonction calcule l'offset   TLeg - TU  pour la date donnee date  */
+{
+JMA jma1,jma2;
+long nbj1,nbj2,nbj;
+double decj1, decj2, decj;
+int Off;
+
+/*   On recherche l'offset correspondant a la date   */
+jma1.Annee = jma2.Annee = date.Annee;
+if (TLegInfo.fg == 'A')
+/*    Periode defini par des dates ds les mois   */ 
+  {
+  jma1.Mois = TLegInfo.mm[0];
+  jma1.Jour = TLegInfo.jj[0];
+  jma2.Mois = TLegInfo.mm[1];
+  jma2.Jour = TLegInfo.jj[1];
+  }
+if (TLegInfo.fg == 'B')
+/*    Periodes definies par jour de semaine et mois   */
+  {
+  jma1 = JsmmaatoJMA(TLegInfo.jj[0],TLegInfo.mm[0],date.Annee);
+  jma2 = JsmmaatoJMA(TLegInfo.jj[1],TLegInfo.mm[1],date.Annee);
+  }
+
+if (TLegInfo.fg == 'C')
+/*    Periodes definies par jour de semaine et mois  avec date inferieure */
+  {
+  jma1 = JApmmaatoJMA(TLegInfo.jj[0],TLegInfo.mm[0],date.Annee);
+  jma2 = JApmmaatoJMA(TLegInfo.jj[1],TLegInfo.mm[1],date.Annee);
+  }
+
+nbj = JMAtoJ(date);
+nbj1 = JMAtoJ(jma1);
+nbj2 = JMAtoJ(jma2);
+
+/*  Les dates pivots sont les jours de changement d'heure a Heure= HChgH */
+decj = (double)nbj + HMStoH(heure)/24.;
+decj1 = (double)nbj1 + HMStoH(HChgH)/24.;
+decj2 = (double)nbj2 + HMStoH(HChgH)/24.;
+
+if ( decj < decj1 )  Off = TLegInfo.Off[0];
+else if (decj < decj2)  Off = TLegInfo.Off[1];
+     else Off = TLegInfo.Off[2];
+
+/*     Impression de debugging   */
+/*Debug--  printf ("   @@@ Debug_TLegOffset (date= %d/%d/%d)  :  %d H. \n",date.Jour,date.Mois,date.Annee,Off);
+printf("  @-1 %s , %d %s %d \n", NomJo[NumJour(jma1)-1], jma1.Jour, NomMo[jma1.Mois-1], jma1.Annee) ;
+printf("  @-2 %s , %d %s %d \n", NomJo[NumJour(jma2)-1], jma2.Jour, NomMo[jma2.Mois-1], jma2.Annee) ;  --*/
+
+
+return (Off);
+}
+
+/*
+++
+HMS TLegtoTU(JMA date, HMS TLeg)
+	Conversion TLegal en TU pour une date donnée
+HMS TUtoTLeg(JMA date, HMS TLeg)
+	Conversion TU en TLegal pour une date donnée. L'heure légale calculée
+	peut être erronnée autour des dates de changement d'heure.
+HMS TUtoTSolM(HMS TU)
+	Conversion TU en temps solaire moyen
+--
+*/
+
+/* Nouvelle-Fonction */
+HMS TLegtoTU(JMA date, HMS hmsz)
+
+/*   Cette fonction transforme le temps legal en temps universel   */
+{
+HMS  TU;
+int Off;
+
+Off = TLegOffset(date, hmsz);
+TU = hmsz;
+TU.Heures -= Off;
+if (TU.Heures >= 24)  TU.Heures -= 24;
+if (TU.Heures < 0)  TU.Heures += 24;
+return(TU);
+}
+
+
+
+/* Nouvelle-Fonction */
+HMS TUtoTLeg(JMA date, HMS hms)
+
+/*   Cette fonction transforme le temps universel en temps legal */
+{
+HMS  TLeg;
+int Off;
+
+Off = TLegOffset(date, hms);    /*  $CHECK$  */
+TLeg = hms;
+TLeg.Heures += Off;
+TLeg.Heures = TLeg.Heures%24;
+if (TLeg.Heures < 0)  TLeg.Heures += 24;
+return(TLeg);
+}
+
+
+/* Nouvelle-Fonction  */
+HMS TUtoTSolM(HMS TU)
+
+/*   Passage  TU  ->  Temps local    */
+{
+double t;
+t = HMStoH(TU) + TSolMOff;
+return(HtoHMS(t));
+}
+
+/*
+++
+ Titre	Temps Sideral
+|      Jour Sideral = 86400 Sec. Sid.  ( = 24 H Sid. )    
+|      Annee Solaire = 365 J 5H 48' 46"  =~  365.2422 J                       
+|      Annee Solaire = 365.2422 Jours Solaire Moyen = 366.2422 Jours Sideraux 
+|      Jour Sol. Moyem = 24 H Sol. = 24 H Sid. * (366.2422 / 365.2422)        
+|      Jour Solaire Moyen = 86636.555359 Sec. Sid. = 24 H 3' 56.555359"       
+|      Heure Solaire Moyen = 3609.85647 Sec. Sid.                             
+|      Sec. Sol. = 1.0027379 Sec. Sid.                                        
+|      Le 1er Janvier 1989 0H TU Il etait 6H 42' 30" GMT_Sideral 
+--
+*/
+
+/*
+++
+HMS TLegtoTSid(JMA date, HMS TZ)
+	Cette fonction calcule le temps sideral a partir du temps
+	legal et de la date
+GMST_at_0h_UT(JMA date)
+	Cette fonction calcule le temps sideral moyen a greenwich a 0h UT
+--
+*/
+
+/* Nouvelle-Fonction  */
+HMS TLegtoTSid(JMA date, HMS TZ)
+
+/*  Cette fonction  donne le temps sideral a partir du temps legal  */
+/*  et la date                                                      */
+{
+HMS  Orgh,TU,TSid;
+JMA  Orgd;
+int off;
+long lj;
+double ts,ratio;
+
+/* Le 1er Janvier 1989 0H TU Il etait 6H 42' 30" GMT_Sideral */
+StrgtoJMA("1/1/1989",Orgd);
+StrgtoHMS("6:42:30",Orgh);
+
+
+
+/*    Nb de jours / Date Origine   */
+lj = JMAtoJ(date) - JMAtoJ(Orgd);
+
+/*  On calcule l'heure TU et on tient compte du decalage eventuel de + ou - 1 jour  */
+off = TLegOffset(date, TZ);
+TU = TZ;
+TU.Heures -= off;
+if (TU.Heures < 0)  
+  {
+  lj -= 1;
+  TU.Heures += 24;
+  }
+if (TU.Heures >= 24)  
+  {
+  lj += 1;
+  TU.Heures -= 24;
+  }
+
+
+
+ratio = ((365.*24.) + 5. + (48. / 60.) + (46. / 3600.)) / 24.;
+ratio = (ratio+1) / ratio ;
+
+/*   Calcul du decalage en heures du temps Sideral par rapport a          */
+/*   l'origine choisie :  ts                                              */
+
+ts = lj * (24. * (ratio - 1) );
+ts += ( TU.Heures * ratio );
+ts += ( ( TU.Minutes / 60. ) * ratio );
+ts += ( (TU.Secondes / 3600. ) * ratio );
+
+ts += HMStoH(Orgh);
+
+/*   On tient compte de l'offset du temps solaire moyen  */
+ts += TSolMOff;
+
+TSid = HtoHMS(ts);
+TSid.Heures = TSid.Heures % 24;
+if (TSid.Heures < 0)  TSid.Heures += 24;
+
+return(TSid);
+}
+
+
+/* Nouvelle-Fonction  */
+HMS GMST_at_0h_UT (JMA date)
+
+/*  Cette fonction  donne le temps sideral moyen a greenwich a 0h UT */
+/*                                                       CMV 5/11/93 */
+{
+HMS Orgh, TSid;
+JMA  Orgd;
+long lj, ejs;
+double js, hs, hs0;
+
+/*  J H ' " sont les vraies valeurs indiscutables (cf metre etalon etc..)  */
+/*  Annee Solaire  = 365 J 5H 48' 45.2" =~  365.2421898148 J               */
+/*  Annee Siderale = 365 J 6H  9'  9.8" =~  365.2563634259 J               */
+/*  Le 1er Janvier 1994 0H TU Il sera 6h 41' 40.4305" GMT_Sideral          */
+StrgtoJMA("1/1/1994",Orgd);
+StrgtoHMS("6:41:40.4305",Orgh);
+hs0 = HMStoH(Orgh);
+
+/*   Nb de jours ecoules depuis la Date Origine */
+lj = JMAtoJ(date) - JMAtoJ(Orgd);
+/* printf("nombre de jours ecoules depuis 1/1/94 %d\n",lj); */
+
+/*   Nb de jours sideraux depuis la Date Origine */
+js = (double) lj * 366.2421898148 / 365.2421898148;
+/*   Nb d'heures siderales depuis Date Origine (modulo un jour) */
+ejs = (int) js;
+hs = js - (double) ejs;
+hs *= 24.;
+hs += hs0;
+
+TSid = HtoHMS(hs);
+/* printf("nombre d'heures siderales depuis la reference (modulo un jour) %d %d %f\n"
+         ,TSid.Heures,TSid.Minutes,TSid.Secondes); */
+
+return(TSid);
+}
+
+/*
+++
+HMS TUtoTSid(JMA date, HMS TU)
+	Cette fonction calcule le temps sideral GMT a partir du temps
+	universel et de la date GMT.
+int TSidtoTU(JMA date, HMS TS, HMS *TU1, HMS *TU2)
+	Cette fonction calcule les temps universels a partir du temps
+	sideral GMT et de la date GMT. Selon la valeur du TS, il peut y avoir
+	une ou deux possibilites pour le TU (return code).
+--
+*/
+
+/* Nouvelle-Fonction  */
+HMS TUtoTSid(JMA date, HMS TU)
+
+/*  Cette fonction  donne le temps sideral GMT a partir du temps universel  */
+/*  et la date  GMT                                                         */
+{
+HMS  Orgh,TSid;
+JMA  Orgd;
+long lj;
+double ts,ratio;
+
+/*   Le 1er Janvier 1989 0H TU Il etait 6H 42' 30" GMT_Sideral */
+StrgtoJMA("1/1/1989",Orgd);
+StrgtoHMS("6:42:30",Orgh);
+
+/*    Nb de jours / Date Origine   */
+lj = JMAtoJ(date) - JMAtoJ(Orgd);
+
+ratio = ((365.*24.) + 5. + (48. / 60.) + (46. / 3600.)) / 24.;
+ratio = (ratio+1) / ratio ;
+
+/*   Calcul du decalage en heures du temps Sideral par rapport a          */
+/*   l'origine choisie :  ts                                              */
+
+ts = lj * (24. * (ratio - 1) );
+ts += ( TU.Heures * ratio );
+ts += ( ( TU.Minutes / 60. ) * ratio );
+ts += ( (TU.Secondes / 3600. ) * ratio );
+
+ts += HMStoH(Orgh);
+
+TSid = HtoHMS(ts);
+TSid.Heures = TSid.Heures % 24;
+if (TSid.Heures < 0)  TSid.Heures += 24;
+
+return(TSid);
+}
+
+/* Nouvelle-Fonction  */
+int TSidtoTU(JMA date, HMS TS, HMS *TU1, HMS *TU2)
+
+/*  Cette fonction  donne les temps universels a partir du temps sideral GMT */
+/*  et la date GMT                                                           */
+{
+int rc = 0;
+HMS  Orgh,T0;
+double ratio,delt,deltt,jsecsid;
+char strd[16],strh[16];
+/* char strh1[16]; */
+
+TU1->Heures = TU2->Heures = -1;
+TU1->Minutes = TU2->Minutes = 0;
+TU1->Secondes = TU2->Secondes = 0.;
+
+ratio = ((365.*24.) + 5. + (48. / 60.) + (46. / 3600.)) / 24.;
+ratio = (ratio / (ratio+1));
+jsecsid = 86400./ratio;
+
+/* temps sideral pour la date a 0h TU */
+StrgtoHMS("00:00:00",T0);
+Orgh =  TUtoTSid(date,T0);
+/* JMAtoStrg(date,strd); HMStoStrg(T0,strh); HMStoStrg(Orgh,strh1);
+printf("... date=%s tu=%s -> org_ts=%s\n",strd,strh,strh1); */
+
+/* difference de temps sideral / a 0h TU */
+delt = HMStoSec(TS) - HMStoSec(Orgh);
+/* printf("... ts=%f org_ts=%f en sec -> delt=%f (jsecsid=%g)\n"
+      ,HMStoSec(TS),HMStoSec(Orgh),delt,jsecsid); */
+
+if(fabs(delt)<1.e-10) delt=0.;
+if(delt<0.) delt += 86400.;
+if( fabs(delt-86400.)<1.e-10 ) delt = 86400. - 1.e-10;
+if(delt<0. || delt>=86400.+1.e-10) {
+  HMStoStrg(TS,strh);
+  JMAtoStrg(date,strd);
+  printf("*** BUG *** TSidtoTU_erreur: delt=%g<0. (d=%s,ts=%s) *******\n"
+        ,delt,strd,strh);
+  return(0);
+}
+
+/* difference de temps / a 0h TU 1ere solution */
+/* printf("... delt=%f en sec sid",delt); */
+deltt = delt*ratio;
+*TU1 = SectoHMS(deltt);
+*TU2 = *TU1;
+rc++;
+/* HMStoStrg((*TU1),strh1);
+printf("... deltt=%f en sec -> TU1=%s\n",deltt,strh1); */
+
+/* Y a t-il une seconde solution ? */
+if(delt>=jsecsid-86400.-1.e-10) return(rc);
+delt += 86400.;
+deltt = delt*ratio;
+*TU2 = SectoHMS(deltt);
+/* HMStoStrg((*TU2),strh1);
+printf("... deltt=%f en sec -> TU2=%s\n",deltt,strh1); */
+rc++;
+
+return (rc);
+}
+
+/*
+++
+void TSidSetupLaSilla()
+	Fonction d'initialisation de conversion  de temps sideral et legal 
+	pour la ESO-Silla "SetTSolMOff() , SetTLegOff()".
+|       Longitude = 70 deg 43.8 min ouest
+|       Latitude  = 29 deg 15.4 min Sud    
+|       T Sol. Moyen - TU = -4.715333 Heures
+|       TLegal-TU : -4 Heures de Mars a Octobre, -3 Heures sinon
+|       Changement le 1er dimanche >= 8/03  8/10 a midi (12:00:00)
+--
+*/
+
+/* Fonction d'initialisation de calcul de temps sideral pour la Silla */
+void TSidSetupLaSilla()
+{
+SetTSolMOff((double)(-4.715333),"La Silla (Chili)");
+if (SetTLegOff("C -3 87/3 -4 87/10 -3","12:00:00") != 0)
+  printf("  TSidSetupLaSilla / Erreur SetTLegOff \n"); 
+/*  Position de l'observatoire */
+/* SetObsPos("La Silla (Chili)","O 70:43:48","S 29:15:24",2347);  */
+return;
+}
+
+
+
+/*
+++
+double ToJulianDay(JMA dateTU, HMS hmsTU);
+	Calcul du jour Julien pour une date TU.
+	Uniquement valable a partir du 15/10/1582 00:00:00.
+--
+*/
+
+double ToJulianDay(JMA dateTU, HMS hmsTU)
+/* Cf Fundamental astronomie, Springer Verlag 2sd ed.  cmv 4/12/98 */
+{
+double j_dat_0_ut;
+long int f,g,a;
+f = (dateTU.Mois>=3) ? dateTU.Annee: dateTU.Annee-1;
+g = (dateTU.Mois>=3) ? dateTU.Mois: dateTU.Mois+12;
+a = 2 - (int)((double)f/100.) + (int)((double)f/400.);
+/* Julian date at 0h UT */
+j_dat_0_ut = (int)(365.25*(double)f)+(int)(30.6001*(double)(g+1))+dateTU.Jour+a+1720994.5;
+return j_dat_0_ut + HMStoH(hmsTU)/24.;
+}
+
+/*
+++
+int FromJulianDay(double JD,JMA* dateTU, HMS* hmsTU);
+	Calcul de la date date et l'heure TU a partir d'un jour Julien.
+	Retourne 0 si succes.
+--
+*/
+
+int FromJulianDay(double JD,JMA* dateTU, HMS* hmsTU)
+/* Cf Fundamental astronomie, Springer Verlag 2sd ed.  cmv 4/12/98 */
+{
+double jd,i,f,a,x,b,c,d,e,h;
+if(JD<0.) return 1;
+
+i = JD - (int)(JD);
+if(i<0.5) jd = (int)(JD)-0.5; else jd = (int)(JD)+0.5;
+
+i = (int)(jd+0.5);
+f = jd+0.5 - i;
+if(i<2299161.0) a = i;
+else {x = (int)((i-1867216.25)/36524.25); a = i+1.+x-(int)(x/4.);}
+b = a+1524.;
+c = (int)((b-122.1)/365.25);
+d = (int)(365.25*c);
+e = (int)((b-d)/30.6001);
+
+x = b-d-(int)(30.6001*e)+f;
+dateTU->Jour = (int)(x);
+
+if(e<13.5) dateTU->Mois = (int)(e-1.); else dateTU->Mois = (int)(e-13.);
+
+if(dateTU->Mois>2.5) dateTU->Annee = (int)(c-4716.); else dateTU->Annee = (int)(c-4715.);
+
+hmsTU->Heures = hmsTU->Minutes = 0; hmsTU->Secondes = 0.;
+h = (JD-ToJulianDay(*dateTU,*hmsTU)) * 24.;
+*hmsTU = HtoHMS(h);
+
+return 0;
+}
+
+
+/*
+++
+double StrgtoDegDec(char *strg)
+	Cette fonction renvoie la valeur decimale en heures
+	d'un angle specifie sous forme de [-][+]dd:mm:ss.
+--
+*/
+
+double StrgtoDegDec(char *strg)
+/*         cmv 4/12/98 */
+{
+int dd,mm;
+float ss;
+char sgn;
+double deg;
+
+dd = mm = 0;
+ss = 0.;
+sgn = *strg;
+if (isdigit(sgn))
+  sscanf(strg,"%d:%d:%f",&dd,&mm,&ss);
+else
+  sscanf(strg+1,"%d:%d:%f",&dd,&mm,&ss);
+deg = (double)(dd) + (double)(mm)/60. + (double)(ss)/3600.;
+if (sgn == '-')  deg = (-deg);
+return(deg);
+}
+
+/*
+++
+char * DegDectoStrg(double deg, char *strg)
+	Cette fonction ecrit une valeur en degre decimal sous 
+	forme de [-]dd:mm:ss.
+--
+*/
+
+char * DegDectoStrg(double deg, char *strg)
+/*         cmv 4/12/98 */
+{
+int dd,mm;
+float ss;
+char sgn;
+
+if (deg < (double)(0.))
+  { deg = (-deg) ; sgn = '-' ; }
+else sgn = '+';
+dd = (int)deg;
+deg = (deg-(double)(dd)) * (double)60.;
+mm = (int)deg;
+ss = (deg-(double)(mm)) * (double)60.;
+if (sgn == '-')
+  sprintf(strg,"-%d:%d:%f",dd,mm,ss);
+else
+  sprintf(strg,"%d:%d:%f",dd,mm,ss);
+return(strg);
+}
+
+/*
+++
+double EccEarth(JMA dateTU)
+	Valeur de l'eccentricite de l'orbite terrestre
+	a la date TU ``dateTU''.
+--
+*/
+double EccEarth(JMA dateTU)
+/* Cf Fundamental astronomie, Springer Verlag 2sd ed p477 table E10.  cmv 9/12/98 */
+{
+double JD,T;
+HMS hmsTU;
+hmsTU.Heures = 12; hmsTU.Minutes = 0; hmsTU.Secondes = 0.;
+JD = ToJulianDay(dateTU,hmsTU);
+/* T en siecles juliens depuis 31/12/1899 a 12h TU --> JD=2415020. */
+T = (JD-2415020.)/36525;
+return(0.0167498 - 0.00004258*T - 0.000000137*T*T);
+}
+
+/*
+++
+double ObliqEarth(JMA dateTU)
+	Valeur de l'obliquite de l'orbite terrestre
+	a la date TU ``dateTU'' (en degres decimaux).
+--
+*/
+double ObliqEarth(JMA dateTU)
+/* Cf Fundamental astronomie, Springer Verlag 2sd ed.  cmv 9/12/98 */
+/* le 1/1/1900 a 0h00 TU --> jd = 2415020.5 */
+{
+double jd;
+HMS hmsTU;
+hmsTU.Heures = hmsTU.Minutes = 0; hmsTU.Secondes = 0.;
+jd = ToJulianDay(dateTU,hmsTU) - 2415020.5;
+return(23.452294 - 0.00013 *jd/365.25);
+}
+
+/*
+++
+double LongEcPerihelie(JMA dateTU)
+	Retourne la Longitude Ecliptique du perihelie de
+	l'orbite terrestre a la date TU ``dateTU'' (en degres decimaux).
+--
+*/
+double LongEcPerihelie(JMA dateTU)
+/* Cf Fundamental astronomie, Springer Verlag 2sd ed p477 table E10.  cmv 9/12/98 */
+{
+double JD,T;
+HMS hmsTU;
+hmsTU.Heures = 12; hmsTU.Minutes = 0; hmsTU.Secondes = 0.;
+JD = ToJulianDay(dateTU,hmsTU);
+/* T en siecles juliens depuis 31/12/1899 a 12h TU --> JD=2415020. */
+T = (JD-2415020.)/36525;
+/* l = 101d 13' 07.15" + 6171.77" *T + 1.823" *T^2 */
+return(101.218652778 + 1.71438055556*T + 0.000506388889*T*T);
+}
+
+/*
+++
+void EquatToEclip(double a,double d,double* l,double *b,JMA dateTU);
+	Renvoie les coordonnees ecliptiques ``l,b'' a partir de
+	coordonnees equatoriales ``a,d'' a la date TU ``dateTU''.
+	La date permet de corriger la variation annuelle
+	de l'obliquite terrestre.
+--
+*/
+void EquatToEclip(double a,double d,double* l,double *b,JMA dateTU)
+/* Cf Fundamental astronomie, Springer Verlag 2sd ed p477 table E10.  cmv 9/12/98 */
+/* l=[0,360[, b=[-90,90] */
+{
+double e,sinb,cosb,sinl,cosl;
+
+e = ObliqEarth(dateTU)*DegenRad;
+a *= DegenRad; d *= DegenRad;
+
+sinb = sin(d)*cos(e)-cos(d)*sin(e)*sin(a);
+if(sinb>1.) sinb=1.; if(sinb<-1.) sinb=-1.;
+*b = asin(sinb);
+cosb = cos(*b);
+
+*l = 0.;
+if(cosb!=0.) {
+  sinl = (sin(d)*sin(e)+cos(d)*cos(e)*sin(a))/cosb;
+  cosl = cos(d)*cos(a)/cosb;
+  if(cosl>1.) cosl=1.; if(cosl<-1.) cosl=-1.;
+  *l = acos(cosl);
+  if(sinl<0.) *l += M_PI;
+  if(*l>2.*M_PI) *l -= 2.*M_PI;
+}
+
+*b /= DegenRad;
+*l /= DegenRad;
+}
Index: /tags/V_Dec2002/SophyaLib/NTools/datime.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/datime.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/datime.h	(revision 2309)
@@ -0,0 +1,125 @@
+/*    ------ 1)  Declaration de structure temps et date  ----- */
+/*                            Reza 92/93                       */
+
+#ifndef DATIME_H_SEEN
+#define DATIME_H_SEEN
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef struct 
+  {
+  int Jour;
+  int Mois;
+  int Annee;
+  }  JMA ;
+
+
+typedef struct 
+  {
+  int  Heures;
+  int Minutes;
+  double Secondes;
+  } HMS ;
+
+/*   ----------    2) Donnees constantes  ---------- */
+#ifdef  DATIMEPRIVEE
+/*   Noms des jours de la semaine - des mois  */
+char *NomJo[7] =  {"Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi","Dimanche"};
+char *NomMo[12] = 
+  {"Janvier","Fevrier","Mars","Avril","Mai","Juin","Juillet",
+  "Aout","Septembre","Octobre","Novembre","Decembre"};
+
+/*   Nombre de jours des mois   */
+static int NbJoMois[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
+
+#else
+
+extern char *NomJo[7];
+extern char *NomMo[12];
+
+#endif
+
+/*    ------ 3) Macro de manipulation de date et heure  -------  */
+
+#define  NomJour(d)      (NomJo[NumJour(d)-1])
+#define  NomMois(d)      (NomMo[d.Mois-1])
+
+/*   Chaine de forme  hh:mm:sec  <->  structure HMS   */
+#define  StrgtoHMS(s,h)  ( sscanf(s,"%d:%d:%lf", &(h.Heures),&(h.Minutes),&(h.Secondes)) )
+#define  HMStoStrg(h,s)  ( sprintf(s,"%02d:%02d:%02.0f", h.Heures,h.Minutes,h.Secondes) )
+
+/*    Chaine de forme jj/mm/aa  <-> structure JMA     */
+/* EA 140998, machin infame pour que ca marche pour 1998/09/14... Pourquoi avoir fait */
+/* des macros ??????????????????????????????????????????????????????????????????????? */
+#define  StrgtoJMA(strg,j)  ( sscanf(strg,"%d/%d/%d", &(j.Jour),&(j.Mois),&(j.Annee)),\
+    (j.Jour>1900 ? sscanf(strg,"%d/%d/%d", &(j.Annee),&(j.Mois),&(j.Jour)) : 1) ) 
+
+#define  JMAtoStrg(j,strg)  ( sprintf(strg,"%02d/%02d/%4d", j.Jour,j.Mois,j.Annee) )
+#define  JMAtoStrgLong(j,strg)   ( sprintf(strg,"%s , %d %s %d", NomJo[NumJour(j)-1], j.Jour, NomMo[j.Mois-1], j.Annee) )
+
+#define  HtoSec(h)        (h*3600.) 
+#define  SectoHMS(s)      ( HtoHMS(s/3600.) )
+
+
+#define  TLegtoTSolM(d,h)    ( TUtoTSolM(TLegtoTU(d,h)) )
+
+/*  -------  4)  Declaration des fonctions    ----------  */
+
+void StrtoHMS(char *s,HMS* hms);
+void HMStoStr(HMS hms,char *s);
+
+int NbJourMois(int a, int m);
+long JMAtoJ(JMA jma);
+JMA JtoJMA(long j);
+int NumJour(JMA jma);
+JMA JsmmaatoJMA(int jj, int mm, int aa);
+JMA JApmmaatoJMA(int nj, int mm, int aa);
+
+double HMStoH(HMS hms);
+double HMStoSec(HMS hms);
+
+long DatetoSec(char const* date, char const* heure);
+long DatetoSecOff(char const* date, char const* heure);
+
+HMS HtoHMS(double h);
+HMS DtoDMS(double h);
+HMS DoubletoHMS(double h);
+
+void SetTSolMOff(double tsmoff, char *name);
+void PrtTSolMOff(void);
+int  SetTLegOff(char *dtz, char* dhz);
+void PrtTLegInfo(int aa);
+int  TLegOffset(JMA date, HMS heure);
+
+HMS TLegtoTU(JMA date, HMS TLeg);
+HMS TUtoTLeg(JMA date, HMS TLeg);
+HMS TUtoTSolM(HMS TU);
+HMS TLegtoTSid(JMA date, HMS TLeg);
+HMS GMST_at_0h_UT(JMA date);
+HMS TUtoTSid(JMA date, HMS TU);
+int TSidtoTU(JMA date, HMS TS, HMS *TU1, HMS *TU2);
+void TSidSetupLaSilla(void);
+
+double ToJulianDay(JMA dateTU, HMS hmsTU);
+int FromJulianDay(double JD,JMA* dateTU, HMS* hmsTU);
+
+double StrgtoDegDec(char *strg);   
+char * DegDectoStrg(double deg, char *strg);
+
+double EccEarth(JMA dateTU);
+double ObliqEarth(JMA dateTU);
+double LongEcPerihelie(JMA dateTU);
+void EquatToEclip(double alpha,double delta,double* l,double *b,JMA dateTU);
+
+/*   -------------------------------------------------------  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
Index: /tags/V_Dec2002/SophyaLib/NTools/difeq.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/difeq.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/difeq.cc	(revision 2309)
@@ -0,0 +1,625 @@
+#include "difeq.h"
+#include "ctimer.h"
+
+//++
+// Class	DiffEqSolver
+// Lib  	Outils++ 
+// include	difeq.h
+//
+//	Classe abstraite de résolveur d'équation différentielles.
+//	Beaucoup de méthodes renvoient l'objet afin de pouvoir
+//	utiliser une notation chaînée du type
+//|	s.Step(...).Start(...).Solve(...)
+//--
+//++ 
+// Links	Implementations
+// RK4DiffEq
+// RK4CDiffEq
+//--
+
+//++
+// Titre	Constructeurs
+//--
+
+//++
+DiffEqSolver::DiffEqSolver()
+//
+//	Constructeur vide. 
+//--
+: mFunc(NULL), mOwnFunc(false),
+  mYStart(1), mXStart(0), mStep(0.01)
+{}
+
+//++
+DiffEqSolver::DiffEqSolver(DiffEqFunction* f)
+//
+//	Constructeur général. L'équation est donnée sous forme
+//	de DiffEqFunction
+//--
+: mFunc(f), mOwnFunc(false),
+  mYStart(mFunc->NFuncReal()), mXStart(0), mStep(0.01)
+{}
+
+//++
+DiffEqSolver::DiffEqSolver(DIFEQFCN1 f)
+//
+//	Constructeur pour le cas particulier d'une équation du premier
+//	ordre. Voir DiffEqFcn1. La fonction f correspond à l'équation
+//	y' = f(y).
+//--
+: mFunc(new DiffEqFcn1(f)), mOwnFunc(true),
+  mYStart(mFunc->NFuncReal()), mXStart(0), mStep(0.01)
+{}
+
+DiffEqSolver::~DiffEqSolver()
+{
+  if (mOwnFunc) delete mFunc;
+}
+
+//++
+// Titre	Méthodes
+//--
+
+//++
+DiffEqSolver&
+DiffEqSolver::Func(DiffEqFunction* f)
+//
+//	Permet de spécifier l'équation différentielle, sous la forme
+//	d'une DiffEqFunction. Retourne l'objet DiffEqSolver : notation
+//	chaînée possible
+//--
+{
+  if (mFunc && mOwnFunc) delete mFunc;
+  mFunc    = f;
+  mOwnFunc = false;
+  return *this;
+}
+
+//++
+DiffEqSolver&
+DiffEqSolver::Func(DIFEQFCN1 f)
+//
+//	Permet de spécifier l'équation différentielle, sous la forme
+//	d'une fonction f telle que y' = f(y). Retourne l'objet DiffEqSolver : 
+//	notation chaînée possible.
+//--
+{
+  if (mFunc && mOwnFunc) delete mFunc;
+  mFunc    = new DiffEqFcn1(f);
+  mOwnFunc = true;
+  return *this;
+}
+
+//++
+DiffEqSolver&
+DiffEqSolver::Step(double step)
+//
+//	Spécifie le pas d'intégration de l'équation différentielle (pour
+//	les méthodes où ce pas a un sens). La valeur par défaut est 0.01.
+//	Retourne l'objet DiffEqSolver : notation chaînée possible.
+//--
+{
+  mStep = step;
+  return *this;
+}
+
+//++
+DiffEqSolver&
+DiffEqSolver::StartV(Vector const& yi, double t)
+//
+//	Spécifie le point de départ de l'intégration de l'équadif.
+//	Le vecteur y contient les valeurs intiales. Voir la description
+//	de chaque fonction-objet-équation différentielle pour connaître
+//	le rôle de chaque élément du vecteur. t est la valeur initiale 
+//	du temps.
+//	La dimension de y doit correspondre au nombre apparent de fonctions.
+//	Retourne l'objet DiffEqSolver : notation chaînée possible.
+//--
+{
+  ASSERT(mFunc != NULL);
+  ASSERT(yi.NElts() == mFunc->NFunc());   // Nombre apparent
+  mYStart = yi;
+  mXStart = t;
+  mFunc->AdjustStart(mYStart,t);
+  ASSERT(mYStart.NElts() == mFunc->NFuncReal());
+  return *this;
+}
+
+//++
+DiffEqSolver&
+DiffEqSolver::Start1(double y, double t)
+//
+//	Spécifie le point de départ de l'intégration de l'équadif,
+//	pour une équation y' = f(y). On donne le temps et la valeur de y.
+//	Retourne l'objet DiffEqSolver : notation chaînée possible.
+//--
+{
+  ASSERT(mFunc != NULL);
+  ASSERT(mFunc->NFunc() == 1);   // Nombre apparent
+  mYStart.Realloc(1);
+  mYStart(0) = y;
+  mXStart = t;
+  mFunc->AdjustStart(mYStart,t);
+  ASSERT(mYStart.NElts() == mFunc->NFuncReal());
+  return *this;
+}
+
+//++
+DiffEqSolver&
+DiffEqSolver::Start(double const* yi, double t)
+//
+//	Spécifie le point de départ de l'intégration de l'équadif.
+//	Le tableau yi contient les valeurs intiales. Voir la description
+//	de chaque fonction-objet-équation différentielle pour connaître
+//	le rôle de chaque élément du tableau. t est la valeur initiale 
+//	du temps.
+//	Le nombre d'éléments de yi doit correspondre au nombre apparent
+//	de fonctions.
+//	Retourne l'objet DiffEqSolver : notation chaînée possible.
+//--
+{
+  mYStart.Realloc(mFunc->NFunc());
+  for (int i=0; i<mFunc->NFunc(); i++)
+    mYStart(i) = yi[i];
+  mXStart = t;
+  mFunc->AdjustStart(mYStart,t);
+  ASSERT(mYStart.NElts() == mFunc->NFuncReal());
+  return *this;
+}
+
+//++
+// virtual void DiffEqSolver::SolveArr(Matrix&  y, double* t, double tf, int n)=0
+//	Lance la résolution de l'équadif, jusqu'à la valeur
+//	tf du temps. N valeurs intermédiaires sont retournées dans 
+//	les tableaux y et t :
+//	t[i] est le temps au pas i, pour 0<=i<n
+//	y[i] sont les valeurs des fonctions au pas i.
+//	Voir la description
+//	de chaque fonction-objet-équation différentielle pour connaître
+//	le rôle de chaque élément de y[i].
+//	t[n-1] vaut tf.
+//	Le nombre d'éléments de y[i] doit correspondre au nombre apparent
+//	de fonctions.
+//	Cette fonction doit être redéfinie pour chaque méthode de résolution
+//	d'équations. Elle est appelée par toutes les autres fonctions de
+//	résolution (autres SolveArr, et Solve).
+//--
+
+
+//++
+void
+DiffEqSolver::SolveV(Vector& yf, double tf)
+//
+//	Lance la résolution de l'équadif, jusqu'à la valeur
+//	tf du temps. Les valeurs finales sont retournées dans yf.
+//	Voir la description
+//	de chaque fonction-objet-équation différentielle pour connaître
+//	le rôle de chaque élément de yf.
+//	Le nombre d'éléments de yf doit correspondre au nombre apparent
+//	de fonctions.
+//--
+{
+  double t;
+  Matrix m(1, mFunc->NFuncReal());
+  SolveArr(m, &t, tf, 1);
+  yf.Realloc(mFunc->NFunc());
+  for (int i=0; i<mFunc->NFunc(); i++)
+    yf(i) = m(0,i);
+}
+
+//++
+void
+DiffEqSolver::Solve1(double& yf, double tf)
+//
+//	Lance la résolution de l'équadif, jusqu'à la valeur
+//	tf du temps, pour une équation du premier ordre y' = f(y).
+//	La valeur finale de y est retournée dans yf.
+//--
+{
+  ASSERT(mFunc->NFunc() == 1);
+  double t;
+  Matrix m(1,mFunc->NFuncReal());
+  SolveArr(m, &t, tf, 1);
+  yf = m(0,0);
+}
+
+//++
+void
+DiffEqSolver::Solve(double* yf, double tf)
+//
+//	Lance la résolution de l'équadif, jusqu'à la valeur
+//	tf du temps. Les valeurs finales sont retournées dans yf.
+//	Voir la description
+//	de chaque fonction-objet-équation différentielle pour connaître
+//	le rôle de chaque élément de yf.
+//	Le nombre d'éléments de yf doit correspondre au nombre apparent
+//	de fonctions.
+//--
+{
+  double t;
+  Matrix m(1, mFunc->NFuncReal());
+  SolveArr(m, &t, tf, 1);
+  for (int i=0; i<mFunc->NFunc(); i++)
+    yf[i] = m(0,i);
+}
+
+//++
+void
+DiffEqSolver::SolveArr1(double*  y, double* t, double tf, int n)
+//
+//	Lance la résolution de l'équadif (du premier ordre), jusqu'à la valeur
+//	tf du temps. N valeurs intermediaires sont retournées dans 
+//	les tableaux y et t :
+//	t[i] est le temps au pas i, pour 0<=i<n
+//	y[i] est la valeur de la fonction au pas i.
+//	t[n-1] vaut tf.
+//--
+
+{
+  ASSERT(mFunc->NFunc() == 1);
+  Matrix m(n, mFunc->NFuncReal());
+  SolveArr(m, t, tf, n);
+  for (int i=0; i<n; i++)
+    y[i] = m(i,0);
+}
+
+//++
+void
+DiffEqSolver::SolveArr2(double** y, double* t, double tf, int n)
+//
+//	Lance la résolution de l'équadif, jusqu'à la valeur
+//	tf du temps. N valeurs intermédiaires sont retournées dans 
+//	les tableaux y et t :
+//	t[i] est le temps au pas i, pour 0<=i<n
+//	y[i] sont les valeurs des fonctions au pas i.
+//	Voir la description
+//	de chaque fonction-objet-équation différentielle pour connaître
+//	le rôle de chaque élément de y[i].
+//	t[n-1] vaut tf.
+//	Le nombre d'éléments de y[i] doit correspondre au nombre apparent
+//	de fonctions.
+//--
+{
+   Matrix m(n, mFunc->NFuncReal());
+   SolveArr(m, t, tf, n);
+   for (int i=0; i<n; i++)
+     for (int j=0; j<mFunc->NFunc(); j++)
+       y[i][j] = m(i,j);
+}
+
+
+//++
+// Class	DiffEqFunction
+// Lib	Outils++ 
+// include	difeq.h
+//
+//	Classe de fonctions pour la résolution d'équations différentielles.
+//	On résoud de facon générale un système de n équations différentielles
+//	du premier ordre, donnant les dérivées fpi de n fonctions fi. 
+//	Cette méthode permet de résoudre toutes les sortes d'équations :
+//	pour une équation du second ordre on crée une fonction intermédiaire
+//	qui est la dérivée de la fonction cherchée.
+//--
+
+//++
+// DiffEqFunction::DiffEqFunction(int n)
+//	Constructeur. N est le nombre de fonctions dans le
+//	système.
+//--
+
+//++
+// DiffEqFunction::DiffEqFunction(int n, int napp)
+//	Constructeur. N est le nombre réel de fonctions dans le
+//	système, et napp le nombre apparent (pour l'utilisateur).
+//	En effet, dans certains cas, on peut avoir besoin de fonctions
+//	supplémentaires masquées à l'utilisateur, par exemple la fonction
+//	constante valant 1, si l'équadif fait intervenir le temps (t).
+//--
+
+//++
+//  virtual void ComputeV(Vector& fpi, Vector const& fi)
+//	Calcule les valeurs des dérivées fpi à partir des valeurs 
+//	des fonctions fi. A redéfinir.
+//--
+
+//++
+//  virtual void Compute(double& fp, double f)
+//	Dans le cas où il y a une seule fonction, calcule la dérivée
+//      fp à partir de la valeur de la fonction f. A redéfinir.
+//--
+
+//++
+// int NFunc()
+// 	Nombre apparent de fonctions dans le système
+//--
+  
+//++
+// int NFuncReal() {return mNFunc;}
+// 	Nombre réel de fonctions dans le système
+//--
+
+//++
+// virtual void AdjustStart(Vector& start, double tstart)
+//	Pour ajuster le vecteur de départ quand il y a des 
+//	fonctions à usage interne...
+//--
+
+
+
+//++
+// Class	DiffEqFcn1
+// Lib	Outils++ 
+// include	difeq.h
+//
+//	Objet-fonction générique pour la résolution d'équations
+//	différentielles de la forme y' = f(y).
+//	On fournit une fonction de type
+//|	typedef double(*DIFEQFCN1)(double);
+//	qui retourne y' en fonction de y.
+//--
+//++
+// Links	Parents
+// DiffEqFunction
+//--
+
+//++
+DiffEqFcn1::DiffEqFcn1(DIFEQFCN1 fcn)
+//
+//	Constructeur. On fournit la fonction f tq y'=f(y)
+//--
+: DiffEqFunction(1), mFcn(fcn)
+{}
+
+void
+DiffEqFcn1::Compute(double& fp, double f)
+{
+   fp = (*mFcn)(f);
+}
+
+//++
+// Class	DiffEqFcnT1
+// Lib	Outils++ 
+// include	difeq.h
+//
+//	Objet-fonction générique pour la résolution d'équations
+//	différentielles de la forme y' = f(y,t).
+//	On fournit une fonction de type
+//|	typedef double(*DIFEQFCNT1)(double, double);
+//	qui retourne y' en fonction de y et t.
+//	Note : le système résolu est alors en fait
+//|	y'[0] = fcn(y[0], y[1])
+//|	y'[1] = 1
+//--
+//++
+// Links	Parents
+// DiffEqFunction
+//--
+
+//++
+DiffEqFcnT1::DiffEqFcnT1(DIFEQFCNT1 fcn)
+//
+//	Constructeur. On fournit la fonction f tq y' = f(y,t)
+//--
+: DiffEqFunction(2, 1), mFcn(fcn)
+{}
+
+void
+DiffEqFcnT1::ComputeV(Vector& fpi, Vector const& fi)
+{
+  fpi(0) = (*mFcn)(fi(0), fi(1));
+  fpi(1) = 1;
+}
+
+void
+DiffEqFcnT1::AdjustStart(Vector& start, double tstart)
+{
+  start.Realloc(2);
+  start(1) = tstart;
+}
+
+//++
+// Class	DiffEqFcn2
+// Lib	Outils++ 
+// include	difeq.h
+//
+//	Objet-fonction générique pour la résolution d'équations
+//	différentielles de la forme y'' = f(y',y).
+//	On fournit une fonction de type
+//|	typedef double(*DIFEQFCN2)(double, double);
+//	qui retourne y'' en fonction de y' et y.
+//	Note : le système résolu est en fait
+//|	y'[0] = y[1]
+//|	y'[1] = f(y[1], y[0])
+//--
+//++
+// Links	Parents
+// DiffEqFunction
+//--
+
+//++
+DiffEqFcn2::DiffEqFcn2(DIFEQFCN2 fcn)
+//
+//	Constructeur. On fournit la fonction f tq y''=f(y',y)
+//--
+: DiffEqFunction(2), mFcn(fcn)
+{}
+
+void
+DiffEqFcn2::ComputeV(Vector& fpi, Vector const& fi)
+{
+  fpi(0) = fi(1);
+  fpi(1) = (*mFcn)(fi(1), fi(0));
+}
+
+//++
+// Class	DiffEqFcnT2
+// Lib	Outils++ 
+// include	difeq.h
+//
+//	Objet-fonction générique pour la résolution d'équations
+//	différentielles de la forme y'' = f(y',y,t).
+//	On fournit une fonction de type
+//|	typedef double(*DIFEQFCNT2)(double, double, double);
+//	qui retourne y'' en fonction de y', y et t.
+//	Note : le système résolu est alors en fait
+//|	y'[0] = y[1]
+//|	y'[1] = f(y[1], y[0], y[2])
+//|	y'[2] = 1
+//--
+//++
+// Links	Parents
+// DiffEqFunction
+//--
+
+//++
+DiffEqFcnT2::DiffEqFcnT2(DIFEQFCNT2 fcn)
+//
+//	Constructeur. On fournit la fonction f tq y'' = f(y',y,t)
+//--
+: DiffEqFunction(3,2), mFcn(fcn)
+{}
+
+void
+DiffEqFcnT2::ComputeV(Vector& fpi, Vector const& fi)
+{
+  fpi(0) = fi(1);
+  fpi(1) = (*mFcn)(fi(1), fi(0), fi(2));
+  fpi(2) = 1;
+}
+
+void
+DiffEqFcnT2::AdjustStart(Vector& start, double tstart)
+{
+  start.Realloc(3);
+  start(2) = tstart;
+}
+
+
+//++
+// Class	DiffEqFcnV
+// Lib	Outils++ 
+// include	difeq.h
+//
+//	Objet-fonction générique pour la résolution d'équations
+//	différentielles 3D de la forme y'' = f(y',y), ou y est
+//	un vecteur de dimension 3.
+//	On fournit une fonction de type
+//|	typedef void(*DIFEQFCNV)(Vector& y2, Vector const& y1, 
+//|	                         Vector const& y);
+//	qui retourne y'' en fonction de y' et y.
+//	Note : le système résolu est alors en fait
+//|	v(0-2) = y, v(3-5) = y'
+//|
+//|	v'[0] = v[3]
+//|	v'[1] = v[4]
+//|	v'[2] = v[5]
+//|	v'[3-5] = f(v[3-5], v[0-2])
+//--
+//++
+// Links	Parents
+// DiffEqFunction
+//--
+
+DiffEqFcnV::DiffEqFcnV(DIFEQFCNV fcn)
+: DiffEqFunction(6), mFcn(fcn),
+  tmp1(3), tmp2(3), tmp3(3)
+{}
+
+void
+DiffEqFcnV::ComputeV(Vector& fpi, Vector const& fi)
+{
+  fpi(0) = fi(3);
+  fpi(1) = fi(4);
+  fpi(2) = fi(5);
+  
+  tmp2(0) = fi(3); tmp2(1) = fi(4); tmp2(2) = fi(5);
+  tmp3(0) = fi(0); tmp3(1) = fi(1); tmp3(2) = fi(2);
+  
+  (*mFcn)(tmp1, tmp2, tmp3);
+  
+  fpi(3) = tmp1(0); fpi(4) = tmp1(1); fpi(5) = tmp1(2);
+}
+
+
+//++
+// Class	RK4DiffEq
+// Lib  	Outils++ 
+// include	difeq.h
+//
+//	Classe de résolution d'équadif par la méthode de
+//	Runge-Kutta d'ordre 4.
+//	Voir DiffEqSolver pour les méthodes.
+//--
+//++
+// Links	Parents
+// DiffEqSolver
+//--
+
+//++
+// Titre	Constructeurs
+//--
+
+RK4DiffEq::RK4DiffEq()
+: DiffEqSolver(), k1(10), k2(10), k3(10), k4(10)
+{}
+
+//++
+RK4DiffEq::RK4DiffEq(DiffEqFunction* f)
+//
+//	Constructeur général
+//--
+: DiffEqSolver(f), k1(f->NFuncReal()), 
+  k2(f->NFuncReal()), k3(f->NFuncReal()), k4(f->NFuncReal())
+{}
+
+//++
+RK4DiffEq::RK4DiffEq(DIFEQFCN1 f)
+//
+//	Constructeur pour y' = f(y)
+//--
+: DiffEqSolver(f), k1(1), k2(1), k3(1), k4(1)
+{}
+
+void
+RK4DiffEq::SolveArr(Matrix& y, double* t, double tf, int n)
+{
+  //TIMEF;
+  // On calcule le nombre de sous-pas par pas
+   
+   int nStep = (mStep > 0) ? int((tf - mXStart)/n/mStep) : 1;
+   if (nStep <= 1) nStep = 1;
+   
+   double dx = (tf - mXStart)/(n*nStep);
+   
+   Vector yt(mYStart,false);
+
+   k1.Realloc(mFunc->NFuncReal());
+   k2.Realloc(mFunc->NFuncReal());
+   k3.Realloc(mFunc->NFuncReal());
+   k4.Realloc(mFunc->NFuncReal());
+   
+      
+   for (int i=0; i<n; i++) {
+     for (int j=0; j<nStep; j++)
+       RKStep(yt, yt, dx);
+     for (int k=0; k<mFunc->NFunc(); k++)
+       y(i,k) = yt(k);
+     t[i] = (i+1)*dx*nStep + mXStart;  
+   }
+}
+
+void
+RK4DiffEq::RKStep(Vector& newY, Vector const& y0, double dt)
+{
+    mFunc->ComputeV(k1, y0);
+    k1 *= dt;
+    mFunc->ComputeV(k2, y0 + k1/2.);
+    k2 *= dt;
+    mFunc->ComputeV(k3, y0 + k2/2.);
+    k3 *= dt;
+    mFunc->ComputeV(k4, y0 + k3);
+    k4 *= dt;
+    
+    newY = y0 + (k1 + k2*2. + k3*2. + k4)/6.;
+}
+
Index: /tags/V_Dec2002/SophyaLib/NTools/difeq.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/difeq.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/difeq.h	(revision 2309)
@@ -0,0 +1,235 @@
+// This may look like C code, but it is really -*- C++ -*-
+//  Simple differential equation solver 
+//        E. Aubourg 1996-
+// DAPNIA/SPP (Saclay) / CEA    LAL - IN2P3/CNRS  (Orsay)
+
+#ifndef DIFEQ_H_SEEN
+#define DIFEQ_H_SEEN
+
+#include "machdefs.h"
+#include "pexceptions.h"
+#include "tvector.h"
+
+namespace SOPHYA {
+
+class GeneralFunction;
+
+// <summary> fonction pour equadifs </summary>
+// Une fonction utilisee pour les equations differentielles.
+// On resoud de facon generale un systeme de n equations differentielles,
+// donnant les derivees fpi de n fonctions fi.
+class DiffEqFunction  {
+public:
+  // Constructeur. n = nombre de fonctions dans le systeme
+  DiffEqFunction(int n)          : mNFunc(n), mNFuncApp(n) {}
+  
+  // Constructeur. n = nombre reel de fonctions dans le systeme,
+  // m = nombre apparent (il y a dans certaines cas des fonctions a 
+  // usage interne,  par exemple la fonction constante valant 1...)
+  
+  DiffEqFunction(int n, int m)   : mNFunc(n), mNFuncApp(m) {}
+  
+  // Destructeur
+  virtual ~DiffEqFunction()      {}
+  
+  // Calcule les valeurs des derivees fpi a partir des valeurs des fonctions fi
+  virtual void ComputeV(Vector& fpi, Vector const& fi)
+       { Compute(fpi(0), fi(0)); }
+
+  // Dans le cas ou on a une seule fonction, calcule la valeur de la derivee fp
+  // a partir de la valeur de la fonction
+  virtual void Compute(double& /*fp*/, double /*f*/)
+       { ASSERT(mNFunc == 1); }
+  
+  // Nombre apparent de fonctions dans le systeme
+  int NFunc()     {return mNFuncApp;}
+  
+  // Nombre reel de fonctions dans le systeme
+  int NFuncReal() {return mNFunc;}
+  
+  // Pour ajuster vecteur de depart quand il y a des fonctions a usage
+  // interne...
+  virtual void AdjustStart(Vector& /*start*/, double /*tstart*/) 
+    {}   
+protected:
+  // Nombre de fonctions dans le systeme
+  int mNFunc;                   
+  // Nombre apparent de fonctions                 
+  int mNFuncApp;                               
+};
+
+
+// Cas y' = f(y)
+typedef double(*DIFEQFCN1)(double);
+
+// <summary> Cas y' = f(y) </summary>
+// Cas y' = f(y), on fournit la fonction f, sous la forme
+// double f(double), et ca construit la bonne DiffEqFunction
+class DiffEqFcn1 : public DiffEqFunction {
+public:
+  // Constructeur, on fournit une fonction double->double
+  // qui donne y' en fonction de y.
+  DiffEqFcn1(DIFEQFCN1);
+
+  // Implementation de Compute qui va utiliser la fonction fournie
+  // au constructeur.
+  virtual void Compute(double& fp, double f);
+protected:
+  DIFEQFCN1 mFcn;
+};
+
+// Cas y' = f(y,t)
+typedef double(*DIFEQFCNT1)(double, double);
+
+// <summary> y' = f(y,t) </summary>
+// Cas y' = f(y,t), on fournit la fonction f, sous la forme
+// double f(double, double), et ca construit la bonne DiffEqFunction
+class DiffEqFcnT1 : public DiffEqFunction {
+public:
+  // Constructeur, on fournit une fonction (double, double)->double
+  // qui donne y' en fonction de y et t.
+  DiffEqFcnT1(DIFEQFCNT1);
+
+  // Implementation de Compute qui va utiliser la fonction fournie
+  // au constructeur.
+  virtual void ComputeV(Vector& fpi, Vector const& fi);
+
+  // Implementation de AdjustStart qui gere la fonction a usage interne.
+  virtual void AdjustStart(Vector& start, double tstart);
+protected:
+  DIFEQFCNT1 mFcn;
+};
+
+// Cas y'' = f(y',y)
+typedef double(*DIFEQFCN2)(double, double);
+
+class DiffEqFcn2 : public DiffEqFunction {
+public:
+  DiffEqFcn2(DIFEQFCN2);
+
+  virtual void ComputeV(Vector& fpi, Vector const& fi);
+protected:
+  DIFEQFCN2 mFcn;
+};
+
+// Cas y'' = f(y',y,t)
+typedef double(*DIFEQFCNT2)(double, double, double);
+
+// <summary> y'' = f(y',y,t) </summary>
+// Cas y'' = f(y',y,t), on fournit la fonction f, sous la forme
+// double f(double, double, double), et ca construit la bonne DiffEqFunction
+class DiffEqFcnT2 : public DiffEqFunction {
+public:
+  // Constructeur, on fournit une fonction (double, double, double)->double
+  // qui donne y'' en fonction de y', y et t.
+  DiffEqFcnT2(DIFEQFCNT2);
+
+  // Implementation de Compute qui va utiliser la fonction fournie
+  // au constructeur.
+  virtual void ComputeV(Vector& fpi, Vector const& fi);
+
+  // Implementation de AdjustStart qui gere la fonction a usage interne.
+  virtual void AdjustStart(Vector& start, double tstart);
+protected:
+  DIFEQFCNT2 mFcn;
+};
+
+// Cas y'' = f(y',y) avec des 3-vecteurs
+typedef void(*DIFEQFCNV)(Vector&, Vector const&, Vector const&);
+
+// <summary> y'' = f(y',y,t) </summary>
+// Cas y'' = f(y',y,t), on fournit la fonction f, sous la forme
+// double f(Vector), et ca construit la bonne DiffEqFunction
+class DiffEqFcnV : public DiffEqFunction {
+public:
+  // Constructeur, on fournit une fonction (Vector)->double
+  // qui donne y'' en fonction du vecteur (t, y, y')
+  DiffEqFcnV(DIFEQFCNV);
+
+  // Implementation de Compute qui va utiliser la fonction fournie
+  // au constructeur.
+  virtual void ComputeV(Vector& fpi, Vector const& fi);
+protected:
+  DIFEQFCNV mFcn;
+  Vector tmp1, tmp2, tmp3;
+};
+
+// <summary> Classe abstraite de resolveur d'equadif </summary>
+// Classe abstraite de resolveur d'equadif
+// Beaucoup de fonctions renvoient l'objet pour pouvoir faire une
+// notation chainee s.Step(...).Start(...).Solve(...)
+class DiffEqSolver  {
+public:
+  // Constructeurs. L'equadif est donnee sous forme de DiffEqFunction.
+  // On a prevu le cas particulier du premier degre directement
+  // <group>
+  DiffEqSolver();
+  DiffEqSolver(DiffEqFunction*);
+  DiffEqSolver(DIFEQFCN1);
+  // </group>
+  
+  // Destructeur
+  virtual ~DiffEqSolver();
+
+  // Change la fonction. Notation chainee possible
+  // <group>
+  DiffEqSolver& Func(DiffEqFunction*);
+  DiffEqSolver& Func(DIFEQFCN1);
+  // </group>
+  // Change le pas d'integration. Notation chainee possible
+  DiffEqSolver& Step(double);
+  
+  // Change les conditions initiales. Notation chainee possible.
+  // <group>
+  DiffEqSolver& StartV(Vector const& yi, double t);
+  // si NFunc == 1
+  DiffEqSolver& Start1(double        yi, double t);
+  DiffEqSolver& Start(double const* yi, double t);
+  // </group>
+  
+  // Lance la resolution, avec ou sans conservation de n valeurs intermediaires
+  // <group>
+  virtual void SolveV(Vector& yf, double tf);
+  // si NFunc == 1
+  virtual void Solve1(double& yf, double tf);  
+  virtual void Solve(double* yf, double tf);
+  virtual void SolveArr(Matrix&  y, double* t, double tf, int n)=0;
+  // si NFunc == 1
+  virtual void SolveArr1(double*  y, double* t, double tf, int n);   
+  virtual void SolveArr2(double** y, double* t, double tf, int n);
+  // </group>
+  
+protected:
+  DiffEqFunction* mFunc;
+  bool mOwnFunc;
+
+  Vector  mYStart;
+  double  mXStart;
+  double  mStep;
+};
+
+// <summary> Runge-Kutta ordre 4 </summary>
+// Runge-Kutta ordre 4
+class RK4DiffEq : public DiffEqSolver {
+public:
+  // Constructeurs. Voir <linkto class=DiffEqSolver>DiffEqSolver</linkto>
+  // <group>
+  RK4DiffEq();
+  RK4DiffEq(DiffEqFunction*);
+  RK4DiffEq(DIFEQFCN1);
+  // </group>
+
+  // Implementation de RK4
+  virtual void SolveArr(Matrix& y, double* t, double tf, int n);
+
+protected:
+  // Un pas RK4
+  void RKStep(Vector& newY, Vector const& y0, double dt);
+  // Vecteurs utilises en interne, pour ne pas les reallouer.
+  Vector k1, k2, k3, k4;
+};
+
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/dynccd.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/dynccd.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/dynccd.cc	(revision 2309)
@@ -0,0 +1,222 @@
+#include "machdefs.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "fmath.h"
+#include "perandom.h"
+
+#include "cimage.h"
+
+#include "dynccd.h"
+
+//++
+// Class	DynCCD
+// Lib		Images++ 
+// include	dynccd.h
+// 
+//	Cette classe permet la specification des parametres 
+//	definissant la dynamique du CCD, et doit etre utilise
+//      pour le calcul des images de bruit.
+//	- TypNoise = 1 :
+//	Bruit = Sqrt( (RONoise/Gain)**2 + ValPix/Gain )      
+//	- TypNoise = 2 :                                     
+//	Bruit = Sqrt( RefSFond**2 + (ValPix-RefFond)/Gain )  
+//	- TypNoise = 0 
+//	Bruit = 1  (Constant pour tous les pixels) 
+//	- TypNoise = 3         
+//	Bruit = Sqrt(Abs(ValPix)) 
+//
+//	Les pixels hors dynamique sont marques (Bruit = 0)
+//	( < MinADU ou > MaxADU) pour toutes valeurs de TypNoise.
+//	Gain est exprime en electron par ADU, RONoise en electron,
+//	Bruit, ValPix et RefFond en ADU.
+//--
+
+//++
+// Links	Parents
+// PPersist
+//--
+//++
+// Links	Autres
+// RzImage
+// Image<T> 
+//--
+//++
+// Titre	Methodes
+//--
+//++
+// DynCCD(int_4TypNoise=0, r_8 MinADU=-9.e19, r_8 MaxADU=9.e19, r_8 Gain=1., r_8 RONoise=0., r_8 RefFond=0., r_8 RefSFond=0.);
+//	Creation d'un objet DynCCD ("typ" determine la methode de calcul du bruit)
+//	|Test verbatim 
+//
+// void Set(int_4TypNoise=0, r_8 MinADU=-9.e19, r_8 MaxADU=9.e19, r_8 Gain=1., r_8 RONoise=0., r_8 RefFond=0., r_8 RefSFond=0.);
+//	Modification des parametres de la dynamique
+// void Print()
+// r_8 Noise(r_8 pixel) const
+//	Renvoie la valeur du bruit pour "pixel" en ADU.
+//--
+
+/* ............................................................ */
+/* :::::::::::::  methode de la classe  DynCCD :::::::::::::::: */
+/* ............................................................ */
+
+/* --Methode-- */
+DynCCD::DynCCD(int_4 typ, r_8 min, r_8 max, r_8 g,
+               r_8 ron, r_8 rf, r_8 rfs)
+{
+if ( (typ >= kConstantNoise) && (typ <= kSqrtADUNoise) )  TypNoise = typ;
+else  TypNoise = kConstantNoise;
+MinADU = min;  MaxADU = max;
+Gain = g;  RONoise = ron;
+RefFond = rf;  RefSFond = rfs;
+}
+
+/* --Methode-- */
+void DynCCD::Set(int_4 typ, r_8 min, r_8 max, r_8 g,
+               r_8 ron, r_8 rf, r_8 rfs)
+{
+if ( (typ >= kConstantNoise) && (typ <= kSqrtADUNoise) )  TypNoise = typ;
+MinADU = min;  MaxADU = max;
+Gain = g;  RONoise = ron;
+RefFond = rf;  RefSFond = rfs;
+}
+
+/* --Methode-- */
+void DynCCD::Print()
+{
+printf("DynCCD: Type= %d Min/MaxADU= %g %g Gain/RoN= %g %g\n",
+       TypNoise, MinADU, MaxADU, Gain, RONoise);
+if (TypNoise == 2)
+  printf("... RefFond= %g  RefSFond= %g \n", RefFond, RefSFond);
+return;
+}
+
+/* --Methode-- */
+r_8 DynCCD::Noise(r_8 pixel) const
+
+/* Cette fonction calcule la valeur du bruit pour pixel     */
+/*  Si TypNoise = 1 :                                       */
+/*     Bruit = Sqrt( (RONoise/Gain)**2 + ValPix/Gain )      */
+/*  Si TypNoise = 2 :                                       */
+/*     Bruit = Sqrt( RefSFond**2 + (ValPix-RefFond)/Gain )  */
+/*  Si TypNoise = 0                                         */
+/*     Bruit = 1  (Constant pour tous les pixels)           */
+/*  Si TypNoise = 3                                         */
+/*     Bruit = Sqrt(Abs(PixelADU))                          */
+/*  Les pixels hors dynamique sont marques (Bruit = 0)      */
+/*  ( < MinADU ou > MaxADU) pour tout valeur de TypNoise    */
+
+{
+r_8 h,s,ronsq;
+r_8 fond;
+
+if ( (pixel > MaxADU) || (pixel < MinADU) )   return(0.);
+if ( TypNoise == kConstantNoise)  return(1.);
+if ( TypNoise == kSqrtADUNoise )  return(sqrt(fabs(pixel)));
+
+if ( TypNoise == kSigFondNoise)
+  { fond = RefFond;
+  ronsq = RefSFond * RefSFond; }
+else
+  { fond = 0;
+  ronsq = RONoise/Gain;  ronsq *= ronsq; }
+
+h = (pixel>fond) ? (r_8)(pixel-fond) : 0.;
+s = ronsq+h/Gain;
+s = sqrt(s);
+return(s);
+}
+
+/* --------------------------------------------------------------  */
+/*      Quelques fonctions pour manipuler des images de bruit      */
+/* --------------------------------------------------------------  */
+
+//++
+// Module	Images de bruit 
+// Lib		Images++ 
+// include	dynccd.h
+//
+//	Ces fonctions permettent le calcul d'image de bruit a partir d'une 
+//	image (RzImage ou Image<T>) et d'un objet DynCCD 
+//--
+//++
+// Links 	Voir classes
+// DynCCD
+// RzImage
+// Image<T>
+//--
+//++
+// Titre	Les fonctions 
+//--
+
+//++
+// Function	RzImage * NoiseImage(RzImage const *pim, DynCCD const * dynccd)
+//	Construit et renvoie l'image du bruit pour l'image "*pim" (RzImage)
+// Function	Image<T> * NoiseImage(Image<T> const * pim, DynCCD const * dynccd)
+//      Meme fonctionalite pour une image typee (ImageU2, ImageR4, ...)
+// Function	ImgAddNoise(Image<T>&, DynCCD const&)
+//	Calcule l'image du bruit et le rajoute a l'image originale
+//--
+
+/* Nouvelle-Fonction */
+template <class T>
+Image<T> NoiseImage(Image<T> const & pim, DynCCD const & dynccd)
+
+/* Creation et Calcul d'une image de bruit a partir de l'image */
+/* pim et de dynccd. Voir la methode DynCCD::Noise() pour la   */
+/* description du calcul                                       */
+
+{
+r_8 h,s,ronsq;
+r_8 fond, min,max;
+int_4 k, npix;
+r_8 minois, offnois;
+
+npix = pim.XSize()*pim.YSize();
+Image<T> nois(pim.XSize(), pim.YSize());
+nois.SetOrg(pim.XOrg(), pim.YOrg());
+
+min = dynccd.MinADU;   max = dynccd.MaxADU;
+for(k=0; k<npix; k++)      {
+  if ( (pim[k] <= max) && (pim[k] >= min) )  nois[k] = (T)1;
+  else nois[k] = 0;
+}
+
+
+return(nois);
+}
+
+
+/* Nouvelle-Fonction */
+template <class T>
+void ImgAddNoise(Image<T>& img, DynCCD const& dyn)
+{
+  int_4 nPix = img.XSize() * img.YSize();
+	
+  for (int_4 i=0; i<nPix; i++)
+    img[i] += (T) (dyn.Noise(img[i])*NorRand());
+}
+
+
+
+
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template NoiseImage<uint_2>
+#pragma define_template NoiseImage<int_4>
+#pragma define_template NoiseImage<r_4>
+
+#pragma define_template ImgAddNoise<uint_2>
+#pragma define_template ImgAddNoise<int_4>
+#pragma define_template ImgAddNoise<r_4>
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(__GNU_TEMPLATES__)
+template Image<uint_2> NoiseImage<uint_2>(Image<uint_2> const& , DynCCD const&);
+template Image< int_4> NoiseImage< int_4>(Image< int_4> const& , DynCCD const&);
+template Image<   r_4> NoiseImage<   r_4>(Image<   r_4> const& , DynCCD const&);
+
+template void ImgAddNoise<uint_2>(Image<uint_2>&, DynCCD const&);
+template void ImgAddNoise< int_4>(Image< int_4>&, DynCCD const&);
+template void ImgAddNoise<   r_4>(Image<   r_4>&, DynCCD const&);
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/dynccd.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/dynccd.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/dynccd.h	(revision 2309)
@@ -0,0 +1,62 @@
+/*  Caracteristique du CCD      Reza  03/95  -*- C++ -*- */
+
+#ifndef DYNCCD_H_SEEN
+#define DYNCCD_H_SEEN
+
+#include "machdefs.h"
+#include "pexceptions.h"
+#include "cimage.h"
+#include "ppersist.h"
+
+namespace SOPHYA {
+
+enum {kConstantNoise = 0, kPhotonNoise, kSigFondNoise, kSqrtADUNoise};
+
+class DynCCD 
+{
+  public :
+
+  int_4 TypNoise;      // Type de calcul du bruit 
+  r_8 MinADU,MaxADU;   // Valeur min et max des pixels 
+  r_8 Gain;            // Gain en electron/ADU 
+  r_8 RONoise;         // Bruit de lecture en electron  
+  r_8 RefFond;         // Fond de ciel de ref (TypNoise=2) 
+  r_8 RefSFond;        // Sigma du fond  (TypNoise=2) */
+
+/*    ===>  Les methodes   */
+  DynCCD(int_4 typ=0, r_8 min=-9.e19, r_8 max=9.e19,
+         r_8 g=1., r_8 ron=0., r_8 rf=0., r_8 rfs=0.);
+
+  void Set(int_4 typ=0, r_8 min=-9.e19, r_8 max=9.e19,
+         r_8 g=1., r_8 ron=0., r_8 rf=0., r_8 rfs=0.);
+  void Print();
+  r_8 Noise(r_8 pixel) const;
+};
+
+} // Fin du namespace
+
+
+template <class T>
+Image<T> NoiseImage(Image<T> const & pim, DynCCD const & dynccd);
+
+template <class T>
+void ImgAddNoise(Image<T>&, DynCCD const&);
+
+// Les entrees-sortie
+
+inline POutPersist& operator << (POutPersist& c, DynCCD const& data)
+{
+  c.PutI4(data.TypNoise);
+  c.PutR8s(&data.MinADU, 6);
+  return c;
+}
+
+inline 
+PInPersist& operator >> (PInPersist& c, DynCCD& data)
+{
+  c.GetI4(data.TypNoise);
+  c.GetR8s(&data.MinADU, 6);
+  return c;
+}
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/exclude
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/exclude	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/exclude	(revision 2309)
@@ -0,0 +1,1 @@
+imageop.cc
Index: /tags/V_Dec2002/SophyaLib/NTools/fct1dfit.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/fct1dfit.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/fct1dfit.cc	(revision 2309)
@@ -0,0 +1,476 @@
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream.h>
+#include <math.h>
+#include "fct1dfit.h"
+#include "perrors.h"
+#include "nbconst.h"
+#include "tabmath.h"
+
+//define EXPO exp
+#define EXPO tabFExp
+#define MINEXPM (100.)
+
+//================================================================
+// CLASSES DE FONCTIONS 1D AVEC PARAMETRES POUR LE FIT
+//================================================================
+
+/////////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::Gauss1DPol
+  \ingroup NTools
+  \anchor Gauss1DPol
+  \verbatim
+     Gaussienne+polynome:
+     Si polcenter=true: xc=(x-par[1]), sinon xc=x
+     f(x) = par[0]*exp[-0.5*( (x-par[1]) / par[2] )**2 ]
+           +par[3] + par[4]*xc + .... + par[3+NDegPol]*xc**NDegPol
+     NDegPol = degre du polynome, si <0 pas de polynome
+  \endverbatim
+*/
+Gauss1DPol::Gauss1DPol(unsigned int ndegpol,bool polcenter)
+: GeneralFunction(1,ndegpol+4), NDegPol(ndegpol), PolCenter(polcenter)
+{
+}
+
+Gauss1DPol::Gauss1DPol(bool polcenter)
+: GeneralFunction(1,3), NDegPol(-1), PolCenter(polcenter)
+{
+}
+
+Gauss1DPol::~Gauss1DPol()
+{
+}
+
+double Gauss1DPol::Value(double const xp[], double const* Par)
+{
+double xc = (xp[0]-Par[1])/Par[2];
+double e = 0.5*xc*xc;
+if( e<MINEXPM ) e = EXPO(-e); else e = 0.;
+double f = Par[0]*e;
+
+if(NDegPol>=0) {
+  double xcp = (PolCenter) ? Par[1] : 0.;
+  double xpow = 1.;
+  for(int i=0;i<=NDegPol;i++) {
+    f += Par[3+i]*xpow;
+    xpow *= xp[0]-xcp;
+  }
+}
+return (f);
+}
+
+double Gauss1DPol::Val_Der(double const xp[],double const* Par
+                          ,double *DgDpar)
+{
+
+ double xc = (xp[0]-Par[1])/Par[2];
+ double xc2 = xc*xc;
+ double e = 0.5*xc2;
+ if( e<MINEXPM ) e = EXPO(-e); else e = 0.;
+ double f = Par[0]*e;
+
+ DgDpar[0] = e;
+ DgDpar[1] = xc / Par[2] *f;
+ DgDpar[2] = xc2/ Par[2] *f;
+
+ if(NDegPol>=0) {
+   double xcp = (PolCenter) ? Par[1] : 0.;
+   double xpow = 1.;
+   for(int i=0;i<=NDegPol;i++) {
+     DgDpar[3+i] = xpow;
+     f += Par[3+i]*xpow;
+     if(PolCenter && i<NDegPol) DgDpar[2] += -(i+1)*xpow*Par[4+i];
+     xpow *= xp[0]-xcp;
+   }
+ }
+return f;
+}
+
+
+/////////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::GaussN1DPol
+  \ingroup NTools
+  \anchor GaussN1DPol
+  \verbatim
+    Gaussienne_Normalisee+polynome (par[0]=Volume:
+     Si polcenter=true: xc=(x-par[1]), sinon xc=x
+     f(x) = par[0]/(sqrt(2*Pi)*par[2])*exp[-0.5*((x-par[1])/par[2])**2 ]
+           +par[3] + par[4]*xc + .... + par[3+NDegPol]*xc**NDegPol
+     NDegPol = degre du polynome, si <0 pas de polynome
+  \endverbatim
+*/
+GaussN1DPol::GaussN1DPol(unsigned int ndegpol,bool polcenter)
+: GeneralFunction(1,ndegpol+4), NDegPol(ndegpol), PolCenter(polcenter)
+{
+}
+
+GaussN1DPol::GaussN1DPol(bool polcenter)
+: GeneralFunction(1,3), NDegPol(-1), PolCenter(polcenter)
+{
+}
+
+GaussN1DPol::~GaussN1DPol()
+{
+}
+
+double GaussN1DPol::Value(double const xp[], double const* Par)
+{
+ double xc = (xp[0]-Par[1])/Par[2];
+ double xc2 = xc*xc;
+ double e = 0.5*xc2;
+ if( e<MINEXPM ) e = EXPO(-e)/(S2Pi*Par[2]); else e = 0.;
+ double f = Par[0]*e;
+
+ if(NDegPol>=0) {
+   double xcp = (PolCenter) ? Par[1] : 0.;
+   double xpow = 1.;
+   for(int i=0;i<=NDegPol;i++) {
+     f += Par[3+i]*xpow;
+     xpow *= xp[0]-xcp;
+   }
+ }
+
+return (f);
+}
+
+double GaussN1DPol::Val_Der(double const xp[], double const* Par
+                           , double *DgDpar)
+{
+ double xc = (xp[0]-Par[1])/Par[2];
+ double xc2 = xc*xc;
+ double e = 0.5*xc2;
+ if( e<MINEXPM ) e = EXPO(-e)/(S2Pi*Par[2]); else e = 0.;
+ double f = Par[0]*e;
+
+ DgDpar[0] = e;
+ DgDpar[1] = xc / Par[2] *f;
+ DgDpar[2] = (xc2-1.)/ Par[2] *f;
+
+ if(NDegPol>=0) {
+   double xcp = (PolCenter) ? Par[1] : 0.;
+   double xpow = 1.;
+   for(int i=0;i<=NDegPol;i++) {
+     DgDpar[3+i] = xpow;
+     f += Par[3+i]*xpow;
+     if(PolCenter && i<NDegPol) DgDpar[2] += -(i+1)*xpow*Par[4+i];
+     xpow *= xp[0]-xcp;
+   }
+ }
+
+ return f;
+}
+
+/////////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::Exp1DPol
+  \ingroup NTools
+  \anchor Exp1DPol
+  \verbatim
+     Exponentielle+polynome:
+     xx = x - X_Center
+     f(x) = exp[par[0]+par[1]*xx]
+           +par[2] + par[3]*xx + .... + par[2+NDegPol]*xx**NDegPol
+     NDegPol = degre du polynome, si <0 pas de polynome
+  \endverbatim
+*/
+Exp1DPol::Exp1DPol(unsigned int ndegpol,double x0)
+: GeneralFunction(1,ndegpol+3), NDegPol(ndegpol), X_Center(x0)
+{
+}
+
+Exp1DPol::Exp1DPol(double x0)
+: GeneralFunction(1,2), NDegPol(-1), X_Center(x0)
+{
+}
+
+Exp1DPol::~Exp1DPol()
+{
+}
+
+double Exp1DPol::Value(double const xp[], double const* Par)
+{
+double xc = Par[0]+Par[1]*(xp[0]-X_Center);
+double f = ( xc>-MINEXPM ) ? EXPO(xc): 0.;
+
+if(NDegPol>=0) {
+  double xpow = 1.;
+  for(int i=0;i<=NDegPol;i++) {
+    f += Par[2+i]*xpow;
+    xpow *= xp[0]-X_Center;
+  }
+}
+return (f);
+}
+
+double Exp1DPol::Val_Der(double const xp[],double const* Par
+                          ,double *DgDpar)
+{
+double xc = Par[0]+Par[1]*(xp[0]-X_Center);
+double f = ( xc>-MINEXPM ) ? EXPO(xc): 0.;
+
+DgDpar[0] = f;
+DgDpar[1] = (xp[0]-X_Center) * f;
+
+if(NDegPol>=0) {
+  double xpow = 1.;
+  for(int i=0;i<=NDegPol;i++) {
+    DgDpar[2+i] = xpow;
+    f += Par[2+i]*xpow;
+    xpow *= xp[0]-X_Center;
+  }
+}
+return f;
+}
+
+/////////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::Polyn1D
+  \ingroup NTools
+  \anchor Polyn1D
+  \verbatim
+    polynome 1D:
+     xx = x - X_Center
+     f(x) = par[0] + par[1]*xx + .... + par[NDegPol+1]*xx**NDegPol
+     NDegPol = degre du polynome
+  \endverbatim
+*/
+Polyn1D::Polyn1D(unsigned int ndegpol,double x0)
+: GeneralFunction(1,ndegpol+1), NDegPol(ndegpol), X_Center(x0)
+{
+}
+
+Polyn1D::~Polyn1D()
+{
+}
+
+double Polyn1D::Value(double const xp[], double const* Par)
+{
+ double xpow = 1.;
+ double f = 0.;
+ for(int i=0;i<=NDegPol;i++) {
+   f += Par[i]*xpow;
+   xpow *= xp[0]-X_Center;
+ }
+ return (f);
+}
+
+double Polyn1D::Val_Der(double const xp[], double const* Par
+                       , double *DgDpar)
+{
+ double xpow = 1.;
+ double f = 0.;
+ for(int i=0;i<=NDegPol;i++) {
+   DgDpar[i] = xpow;
+   f += Par[i]*xpow;
+   xpow *= xp[0]-X_Center;
+ }
+ return f;
+}
+
+
+/////////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::HarmonieNu
+  \ingroup NTools
+  \anchor HarmonieNu
+  \verbatim
+    Analyse harmonique:
+     f(t) = par(1) + Sum[par(2k)  *cos(2*pi*k*par(0)*(t-t0)]
+                   + Sum[par(2k+1)*sin(2*pi*k*par(0)*(t-t0)]
+     la somme Sum porte sur l'indice k qui varie de [1,NHarm()+1]
+     avec la convention   k=1  pour le fondamental
+                          k>1  pour le (k-1)ieme harmonique
+     par(0) = inverse de la periode (frequence)
+     par(1) = terme constant
+     par(2), par(3) = termes devant le cosinus et le sinus
+                      du fondamental
+     par(2(m+1)), par(2(m+1)+1) = termes devant le cosinus
+                      et le sinus de l'harmonique m (m>=1).
+     NHarm() = nombre d'harmoniques a fitter.
+     T0() = centrage des temps, ce n'est pas un parametre du fit.
+   	`Conseil:' Avant de faire un fit avec les `NHarm()'
+   	harmoniques, il est preferable de faire un pre-fit
+   	ou seuls les parametres 1,2 et 3 sont libres et d'injecter
+   	le resultat du fit sur ces 3 parametres comme valeurs
+   	de depart pour le fit global avec les `NHarm()' harmoniques.
+   	De toute facon, le fit ne marchera que si la periode
+   	est initialisee de facon tres precise.
+  \endverbatim
+*/
+HarmonieNu::HarmonieNu(unsigned int nharm,double t0)
+: GeneralFunction(1,4+2*nharm), NHarm(nharm), T0(t0)
+{
+}
+
+HarmonieNu::~HarmonieNu()
+{
+}
+
+double HarmonieNu::Value(double const xp[], double const* Par)
+{
+ double a = 2.*Pi*(xp[0]-T0)*Par[0];
+ double f = Par[1];
+ for(int k=1;k<=NHarm+1;k++) {
+   // k=1 fondamental, k=2 a NHarm+1 harmoniques numero 1 a NHarm
+   f += Par[2*k]*cos(k*a) + Par[2*k+1]*sin(k*a);
+ }
+ return f;
+}
+
+double HarmonieNu::Val_Der(double const xp[], double const* Par
+                        , double *DgDpar)
+{
+ double cs,sn;
+ double dadp0 = 2.*Pi*(xp[0]-T0);
+ double a = dadp0*Par[0];
+ double f = Par[1];
+ DgDpar[0] = 0.;
+ DgDpar[1] = 1.;
+ for(int k=1;k<=NHarm+1;k++) {
+   cs = cos(k*a); sn = sin(k*a);
+   f += Par[2*k]*cs + Par[2*k+1]*sn;
+   DgDpar[0] += k*dadp0*(-Par[2*k]*sn+Par[2*k+1]*cs);
+   DgDpar[2*k]   = cs;
+   DgDpar[2*k+1] = sn;
+ }
+ return f;
+}
+
+
+/////////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::HarmonieT
+  \ingroup NTools
+  \anchor HarmonieT
+  \verbatim
+    Analyse harmonique:
+     f(t) = par(1) + Sum[par(2k)  *cos(2*pi*k*(t-t0)/par(0)]
+                   + Sum[par(2k+1)*sin(2*pi*k*(t-t0)/par(0)]
+     la somme Sum porte sur l'indice k qui varie de [1,NHarm()+1]
+     avec la convention   k=1  pour le fondamental
+                          k>1  pour le (k-1)ieme harmonique
+     par(0) = periode
+     par(1) = terme constant
+     par(2), par(3) = termes devant le cosinus et le sinus
+                      du fondamental
+     par(2(m+1)), par(2(m+1)+1) = termes devant le cosinus
+                      et le sinus de l'harmonique m (m>=1).
+     NHarm() = nombre d'harmoniques a fitter.
+     T0() = centrage des temps, ce n'est pas un parametre du fit.
+  \endverbatim
+*/
+HarmonieT::HarmonieT(unsigned int nharm,double t0)
+: GeneralFunction(1,4+2*nharm), NHarm(nharm), T0(t0)
+{
+}
+
+HarmonieT::~HarmonieT()
+{
+}
+
+double HarmonieT::Value(double const xp[], double const* Par)
+{
+ double a = 2.*Pi*(xp[0]-T0)/Par[0];
+ double f = Par[1];
+ for(int k=1;k<=NHarm+1;k++) {
+   // k=1 fondamental, k=2 a NHarm+1 harmoniques numero 1 a NHarm
+   f += Par[2*k]*cos(k*a) + Par[2*k+1]*sin(k*a);
+ }
+ return f;
+}
+
+double HarmonieT::Val_Der(double const xp[], double const* Par
+                        , double *DgDpar)
+{
+ double cs,sn;
+ double dadp0 = 2.*Pi*(xp[0]-T0);
+ double a = dadp0/Par[0];
+ double f = Par[1];
+ DgDpar[0] = 0.;
+ DgDpar[1] = 1.;
+ for(int k=1;k<=NHarm+1;k++) {
+   cs = cos(k*a); sn = sin(k*a);
+   f += Par[2*k]*cs + Par[2*k+1]*sn;
+   DgDpar[0] += k*dadp0*(-Par[2*k]*sn+Par[2*k+1]*cs)/(-Par[0]*Par[0]);
+   DgDpar[2*k]   = cs;
+   DgDpar[2*k+1] = sn;
+ }
+ return f;
+}
+
+//================================================================
+// CLASSES DE FONCTIONS 2D AVEC PARAMETRES POUR LE FIT
+//================================================================
+
+/////////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::Polyn2D
+  \ingroup NTools
+  \anchor Polyn2D
+  \verbatim
+    polynome 2D de degre total degre:
+     NDegPol = degre du polynome (note N dans la suite)
+     x = x - X_Center,  y = y - Y_Center
+     f(x,y) = p[0] +sum(k=1,n){ sum(i=0,k){ p[ki]*x^i*y^(k-i) }}
+     Il y a k+1 termes de degre k  (ex: x^i*y^(k-i))
+     terme de degre k avec x^i: p[ki] avec  ki = k*(k+1)/2 + i
+    C'est a dire:
+    deg0:   p0
+    deg1: + p1*y + p2*x
+    deg2: + p3*y^2 + p4*x*y + p5*x^2
+    deg3: + p6*y^3 + p7*x*y^2 + p8*x^2*y + p9*x^3
+    deg4: + p10*y^4 + p11*x*y^3 + p12*x^2*y^2 + p13*x^3*y + p14*x^4
+    deg5: + p15*y^5 + ...                       ... + ... + p20*x^5
+    ...
+    degk: + p[k*(k+1)/2]*y^k + ...           ... + p[k*(k+3)/2]*x^k
+    ...
+    degn: + p[n*(n+1)/2]*y^n + ...           ... + p[n*(n+3)/2]*x^n
+  \endverbatim
+*/
+Polyn2D::Polyn2D(unsigned int ndegpol,double x0,double y0)
+: GeneralFunction(2,ndegpol*(ndegpol+3)/2+1), NDegPol(ndegpol), X_Center(x0), Y_Center(y0)
+{
+}
+
+Polyn2D::~Polyn2D()
+{
+}
+
+double Polyn2D::Value(double const xp[], double const* Par)
+{
+ double f = 0.;
+ double xpow = 1.;
+ for(int i=0;i<=NDegPol;i++) { // On gere la puissance x^i i<ndeg
+   int ip;
+   double ypow = 1.;
+   for(int j=0;j<=NDegPol-i;j++) { // On gere la puissance x^j tq degre=i+j<=ndeg
+     ip = (i+j)*(i+j+1)/2+i;
+     f += Par[ip]*xpow*ypow;
+     ypow *= xp[1]-Y_Center;
+   }
+   xpow *= xp[0]-X_Center;
+ }
+ return f;
+}
+
+double Polyn2D::Val_Der(double const xp[], double const* Par
+                       , double *DgDpar)
+{
+ double f = 0.;
+ double xpow = 1.;
+ for(int i=0;i<=NDegPol;i++) { // On gere la puissance x^i i<ndeg
+   int ip;
+   double ypow = 1.;
+   for(int j=0;j<=NDegPol-i;j++) { // On gere la puissance x^j tq degre=i+j<=ndeg
+     ip = (i+j)*(i+j+1)/2+i;
+     DgDpar[ip] = xpow*ypow;
+     f += Par[ip]*DgDpar[ip];
+     ypow *= xp[1]-Y_Center;
+   }
+   xpow *= xp[0]-X_Center;
+ }
+ return f;
+}
Index: /tags/V_Dec2002/SophyaLib/NTools/fct1dfit.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/fct1dfit.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/fct1dfit.h	(revision 2309)
@@ -0,0 +1,147 @@
+#ifndef FCT1DFIT_SEEN
+#define FCT1DFIT_SEEN
+
+#include "generalfit.h"
+
+namespace SOPHYA {
+
+//================================================================
+// CLASSES DE FONCTIONS 1D AVEC PARAMETRES POUR LE FIT
+//================================================================
+
+//////////////////////////////////////////////////////////////////
+//! Gaussienne + polynome
+class Gauss1DPol : public GeneralFunction {
+public:
+  Gauss1DPol(unsigned int ndegpol,bool polcenter=false);
+  Gauss1DPol(bool polcenter=false);
+  virtual ~Gauss1DPol();
+
+  virtual double Value(double const xp[], double const* Par);
+  virtual double Val_Der(double const xp[],double const* Par,double* DgDpar);
+
+  inline int NDegP() const {return NDegPol;}
+
+protected:
+  int NDegPol;    // degre du polynome
+  bool PolCenter; // centrage du polynome
+};
+
+//////////////////////////////////////////////////////////////////
+//! Gaussienne_Normalisee+polynome
+class GaussN1DPol : public GeneralFunction {
+public:
+  GaussN1DPol(unsigned int ndegpol,bool polcenter=false);
+  GaussN1DPol(bool polcenter=false);
+  virtual ~GaussN1DPol();
+
+  virtual double Value(double const xp[], double const* Par);
+  virtual double Val_Der(double const xp[],double const* Par,double* DgDpar);
+
+  inline int NDegP() const {return NDegPol;}
+
+protected:
+  int NDegPol;    // degre du polynome
+  bool PolCenter; // centrage du polynome
+};
+
+//////////////////////////////////////////////////////////////////
+//! Exponentielle + polynome
+class Exp1DPol : public GeneralFunction {
+public:
+  Exp1DPol(unsigned int ndegpol,double x0=0.);
+  Exp1DPol(double x0=0.);
+  virtual ~Exp1DPol();
+
+  virtual double Value(double const xp[], double const* Par);
+  virtual double Val_Der(double const xp[],double const* Par,double* DgDpar);
+
+  inline int NDegP() const {return NDegPol;}
+  inline double XCenter() {return X_Center;}
+
+protected:
+  int NDegPol;     // degre du polynome
+  double X_Center; // Centrage en X pour stabilitee
+};
+
+//////////////////////////////////////////////////////////////////
+//! polynome 1D
+class Polyn1D : public GeneralFunction {
+public:
+  Polyn1D(unsigned int ndegpol,double x0=0.);
+  virtual ~Polyn1D();
+
+  virtual double Value(double const xp[], double const* Par);
+  virtual double Val_Der(double const xp[],double const* Par,double* DgDpar);
+
+  inline int NDegP() const {return NDegPol;}
+  inline double XCenter() {return X_Center;}
+
+protected:
+  int NDegPol;     // degre du polynome
+  double X_Center; // Centrage en X pour stabilitee
+};
+
+//////////////////////////////////////////////////////////////////
+//! Analyse harmonique
+class HarmonieNu : public GeneralFunction {
+public:
+  HarmonieNu(unsigned int nharm=0, double t0=0.);
+  virtual ~HarmonieNu();
+
+  virtual double Value(double const xp[], double const* Par);
+  virtual double Val_Der(double const xp[],double const* Par,double* DgDpar);
+
+  inline int NHarmonic()  {return NHarm;}
+  inline double  T0Center() const {return T0;}
+  inline double& T0Center()       {return T0;}
+
+protected:
+  int NHarm;
+  double T0;
+};
+
+//////////////////////////////////////////////////////////////////
+//! Analyse harmonique
+class HarmonieT : public GeneralFunction {
+public:
+  HarmonieT(unsigned int nharm=0, double t0=0.);
+  virtual ~HarmonieT();
+
+  virtual double Value(double const xp[], double const* Par);
+  virtual double Val_Der(double const xp[],double const* Par,double* DgDpar);
+
+  inline int NHarmonic()  {return NHarm;}
+  inline double  T0Center() const {return T0;}
+  inline double& T0Center()       {return T0;}
+
+protected:
+  int NHarm;
+  double T0;
+};
+
+//================================================================
+// CLASSES DE FONCTIONS 2D AVEC PARAMETRES POUR LE FIT
+//================================================================
+
+//////////////////////////////////////////////////////////////////
+//! polynome 2D
+class Polyn2D : public GeneralFunction {
+public:
+  Polyn2D(unsigned int ndegpol,double x0=0.,double y0=0.);
+  virtual ~Polyn2D();
+
+  virtual double Value(double const xp[], double const* Par);
+  virtual double Val_Der(double const xp[],double const* Par,double* DgDpar);
+
+  inline int NDegP() const {return NDegPol;}
+
+protected:
+  int NDegPol;     // degre du polynome
+  double X_Center; // Centrage en X pour stabilitee
+  double Y_Center; // Centrage en Y pour stabilitee
+};
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/fct2dfit.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/fct2dfit.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/fct2dfit.cc	(revision 2309)
@@ -0,0 +1,1515 @@
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream.h>
+#include <math.h>
+#include "fct2dfit.h"
+#include "perrors.h"
+#include "nbconst.h"
+#include "tabmath.h"
+
+// define SIMPSON4  c'etait la prod 91-95 rcecile
+#define SIMPSON9
+#include "simps2d.h"
+
+// define EXPO exp
+#define EXPO tabFExp
+#define MINEXPM (100.)
+
+//================================================================
+// GeneralFunction 2D pour PSF pixel taille 1x1
+//================================================================
+
+/////////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::GeneralPSF2D
+  \ingroup NTools
+  \anchor GeneralPSF2D
+   Classe de definition d'une PSF 2D a nPar parametres
+   Pour definir une PSF, il faut creer une classe qui herite
+   de ``GeneralPSF2D'' (cf par exemple GauRho2D...).
+   La disposition des parametres definissant la PSF est indifferente,
+   toutefois il est conseille de suivre l'ordre:
+  \verbatim
+   - PSF 2D a NPar parametres:
+   p[0] = Volume (ou hauteur)
+   p[1] = centre X0, p[2] = centre Y0
+   p[3] = SigmaX   , p[4] = SigmaY,    p[5] = Rho
+   p[6],p[7],... = autres parametres (eventuels) definissant la PSF.
+                   (ex: pour la Moffat p[6] = exposant Beta et NPar=8).
+   p[NPar-1] = Fond
+  \endverbatim
+   L'emploi de certaines classes comme par exemple ``GenMultiPSF2D''
+   necessite de suivre rigoureusement l'ordre indique ci-dessus
+   pour les parametres.
+*/
+
+GeneralPSF2D::GeneralPSF2D(unsigned int nPar)
+: GeneralFunction(2,nPar), VolEps(1.e-4)
+{
+ASSERT( nPar>0 );
+}
+
+GeneralPSF2D::~GeneralPSF2D()
+{
+}
+
+/*!
+  \verbatim
+    ValueH = hauteur*forme(x,y)+fond tq forme(0,0)=1.
+        alors que Value = volume*forme(x,y)+fond tq volume(forme)=1.
+    Dans notre convention le dernier parametre est le fond,
+    le premier le volume et les 2 suivants le centrage x0,y0
+    ---> Ici parm[0] = hauteur
+  \endverbatim
+ */
+double GeneralPSF2D::ValueH(double const xp[], double const* parm)
+{
+double x0[2];
+int mm1 = mNPar - 1;
+
+// point central en [x0,y0]
+x0[0] = parm[1];  x0[1] = parm[2];
+
+// retour avec hauteur = 1
+return   (Value(xp,parm) - parm[mm1]) / (Value(x0,parm) - parm[mm1])
+         * parm[0] + parm[mm1];
+}
+
+/*!
+  \verbatim
+    Cette fonction calcule le volume d'une PSF de hauteur=1
+    avec une precision de "VolEps"
+    dans le but de connaitre le coefficient permettant
+    de convertir le volume d'une PSF en son amplitude
+    ou vice-versa: " volume = VolPSF * hauteur "
+     L'integration se fait 1/4 de pixel par 1/4 de pixel
+     ATTENTION: Il s'agit de PSF donc x,y,x0,y0,Sigma.. sont en pixels
+  \endverbatim
+ */
+double GeneralPSF2D::VolPSF(double const* parm)
+{
+ double x[2],step;
+ double vol,volprec;
+ int ecart,i,j,k;
+ int mm1 = mNPar-1;
+
+ step = 1. / 4.;
+ vol = volprec = 0.;
+ ecart = 1;
+
+ /* pixel central */
+ for(k=0;k<nd2d;k++) {
+   x[0] = parm[1] + dx2d[k]*step;
+   x[1] = parm[2] + dy2d[k]*step;
+   vol += (ValueH(x,parm)-parm[mm1]) * w2d[k];
+ }
+
+/* increment en couronnes carrees de 2*ecart+1 de cote */
+ while ( ecart < 2 || fabs((vol-volprec)/vol) > VolEps ) {
+   volprec = vol;
+   for (i= -ecart;i<=ecart;i++) for(k=0;k<nd2d;k++) {
+     x[0] = parm[1] + (i+dx2d[k])*step;
+     x[1] = parm[2] + (-ecart+dy2d[k])*step;
+     vol += (ValueH(x,parm)-parm[mm1]) * w2d[k];
+     x[1] = parm[2] + ( ecart+dy2d[k])*step;
+     vol += (ValueH(x,parm)-parm[mm1]) * w2d[k];
+   }
+   for (j= -ecart+1;j<=ecart-1;j++) for(k=0;k<nd2d;k++) {
+     x[1] = parm[2] + (j+dy2d[k])*step;
+     x[0] = parm[1] + (-ecart+dx2d[k])*step;
+     vol += (ValueH(x,parm)-parm[mm1]) * w2d[k];
+     x[0] = parm[1] + ( ecart+dx2d[k])*step;
+     vol += (ValueH(x,parm)-parm[mm1]) * w2d[k];
+   }
+   ecart++;
+   // printf("ec=%d v=%f prec=%f %f\n",ecart,vol,fabs((vol-volprec)/vol),VolEps);
+ }
+
+ vol *= step * step / parm[0];
+ return vol;
+}
+
+//! Definition des defauts des parametres
+void GeneralPSF2D::DefaultParam(double *parm)
+{
+  for (int i=0; i<mNPar; i++) parm[i] = 0.;
+  parm[3] = parm[4] = 1.;  // Sigx Sigy
+}
+
+//! Definition de la precision sur le calcul du volume
+void GeneralPSF2D::SetVolEps(double const prec)
+{
+  VolEps = prec;
+}
+
+//================================================================
+// GeneralFunction 2D pour MULTI-PSF pixel taille 1x1
+//================================================================
+
+/////////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::GenMultiPSF2D
+  \ingroup NTools
+  \anchor GenMultiPSF2D
+   Classe de definition d'un ensemble de PSF2D
+   pour fiter simultanement plusieurs etoiles et un fond constant.
+   Les parametres de forme de la PSF (Sx, Sy, Rho etc... et Fond)
+   sont les memes pour toutes les etoiles, seuls le centre
+   (X0,Y0) et le volume (ou la hauteur) V varient pour chaque etoile.
+   La disposition des parametres definissant la PSF generique
+   est obligatoirement la suivante:
+  \verbatim
+     - PSF 2D a NPar parametres:
+     p[0] = Volume (ou hauteur)
+     p[1] = centre X0, p[2] = centre Y0
+     p[3] = SigmaX   , p[4] = SigmaY,    p[5] = Rho
+     p[6],p[7],... = autres parametres (eventuels) definissant la PSF.
+                     (ex: pour la Moffat p[6] = exposant Beta et NPar=8).
+     p[NPar-1] = Fond
+   
+     - La Multi-PSF a ses parametres arranges dans l'ordre suivant:
+       Soit NStar le nombre d'etoiles a fiter simultanement
+            NP = le nombre de parametres de la PSF 2D generique
+       On a NF = NP-7 parametres de forme supplementaires
+            (ex: nf=0 pour GauRho2D, nf=1 pour MofRho2D)
+     p[0],p[1],p[2] = V0,X0,Y0 pour la premiere etoile
+     p[3],p[4],p[5] = V1,X1,Y1 pour la deuxieme etoile
+     ...
+     p[3*i],p[3*i+1],p[3*i+2] = Vi,Xi,Yi pour la (i+1) ieme etoile
+     ...
+     p[m*i],p[m*i+1],p[m*i+2] = Vm,Xm,Ym   ;   m = NStar-1
+                          pour la NStar ieme et derniere etoile
+     p[3*NStar],p[3*NStar+1],p[3*NStar+2] = SigmaX, SigmaY et Rho
+     p[3*NStar+3],...,p[3*NStar+2+NF] = parametres de forme
+                           supplementaires pour definir la PSF 2D
+     p[3*NStar+2+NF+1] = Fond
+  \endverbatim
+*/
+
+/*!
+  Createur. ``psf2d'' est le nom de la PSF generique a utiliser,
+  et ``nstar'' est le nombre d'etoiles a fiter simultanement.
+  */
+GenMultiPSF2D::GenMultiPSF2D(GeneralPSF2D* psf2d,unsigned int nstar)
+  : GeneralPSF2D((psf2d!=NULL) ? 3*nstar+4+psf2d->NPar()-7: 0)
+  , mPsf2D(psf2d), mNStar(nstar)
+{
+ASSERT( nstar>0 && psf2d!=NULL );
+mNForme = mPsf2D->NPar() - 7;
+ASSERT( mNForme>=0 );
+mNParm = mPsf2D->NPar();
+mParm = new double[mNParm];
+mDer = new double[mNParm];
+mNParmTot = GeneralPSF2D::NPar();
+cout<<"mNStar="<<mNStar<<" mNParmTot="<<mNParmTot
+    <<" mNParm="<<mNParm<<" mNForme="<<mNForme<<endl;
+}
+
+GenMultiPSF2D::~GenMultiPSF2D()
+{
+delete [] mParm; mParm = NULL;
+delete [] mDer;  mDer = NULL;
+}
+
+double GenMultiPSF2D::Value(double const xp[], double const* Par)
+{
+// Fond commun
+double val = Par[mNParmTot-1];
+
+// Remplissage le tableau des parametres pour la PSF generique
+// ... Communs a toutes les PSF individuelles: Sx,Sy,Rho,[Forme],Fond
+const double *pt = &Par[3*mNStar];
+double *p = &mParm[3];
+{for(int i=0;i<3+mNForme;i++) *(p++) = *(pt++);}  // Sx,Sy,Rho,[Forme...]
+*(p++) = 0.;   // Fond
+
+// ... Propres a chaque etoiles: Vi,Xi,Yi
+pt = Par;
+{for(int i=0;i<mNStar;i++) {
+  mParm[0] = *(pt++);  // Vi (ou Hi)
+  mParm[1] = *(pt++);  // Xi
+  mParm[2] = *(pt++);  // Yi
+  val += mPsf2D->Value(xp,mParm);
+}}
+
+return val;
+}
+
+double GenMultiPSF2D::Val_Der(double const xp[], double const* Par
+                             ,double *DgDpar)
+{
+{for(int i=3*mNStar;i<mNParmTot-1;i++) DgDpar[i] = 0.;}
+
+// Fond commun
+double val = Par[mNParmTot-1];
+DgDpar[mNParmTot-1] = 1.;  // D./DFond
+
+// Remplissage le tableau des parametres pour la PSF generique
+// ... Communs a toutes les PSF individuelles: Sx,Sy,Rho,[Forme],Fond
+const double *pt = &Par[3*mNStar];
+double *p = &mParm[3];
+{for(int i=0;i<3+mNForme;i++) *(p++) = *(pt++);}  // Sx,Sy,Rho,[Forme...]
+*(p++) = 0.;   // Fond
+
+// ... Propres a chaque etoiles: Vi,Xi,Yi
+double *dpt = DgDpar, *dpt2 = &DgDpar[3*mNStar];
+pt = Par;
+{for(int i=0;i<mNStar;i++) {
+  mParm[0] = *(pt++);  // Vi (ou Hi)
+  mParm[1] = *(pt++);  // Xi
+  mParm[2] = *(pt++);  // Yi
+  val += mPsf2D->Val_Der(xp,mParm,mDer);
+  {for(int j=0;j<3;j++) *(dpt++) = mDer[j];}  // D./DVi,D./DXi,D./DYi
+  {for(int j=0;j<3+mNForme;j++) *(dpt2+j) += mDer[3+j];} // D./DSx,D./DSy,D./DRho,[D./DForme]
+}}
+
+return val;
+}
+
+//==============================================================================
+// CLASSES DE FONCTIONS 2D type PSF AVEC PARAMETRES POUR LE FIT pixel taille 1x1
+// la taille du pixel est importante quand on utilise les PSF integrees
+//    (x,y x0,y0 sigmaX.... sont en unites de pixels !!!)
+//==============================================================================
+
+#define _x0_   Par[1]
+#define _y0_   Par[2]
+#define _sigx_ Par[3]
+#define _sigy_ Par[4]
+#define _rho_  Par[5]
+#define _Gm_   Par[6]
+#define _B4_   Par[6]
+#define _B6_   Par[7]
+#define _B2_   Par[8]
+
+/////////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::GauRho2D
+  \ingroup NTools
+  \anchor GauRho2D
+  \verbatim
+    gaussienne+fond 2D
+    Par [0]=vol [1]=x0 [2]=y0 [3]=sigx [4]=sigy [5]=rho [6]=fond
+      sigx,sigy,rho = sigma et rho de la gaussienne
+      x0,y0 = centre de la gaussienne
+     PSF(x,y) = N * exp[ - 1/2 (X**2 + Y**2 -2*rho*X*Y) ]
+              avec X = (x-x0)/sigx et Y = (y-y0)/sigy
+                   N = sqrt(1-rho**2)/(2*Pi*sigx*sigy)
+     le volume de cette gaussienne est V=1.
+     F(x,y) = Par[0]*PSF(x,y)+Par[6] (volume=Par[0],fond=Par[6])
+    -*- Remarque: De la facon dont est ecrite la PSF gaussienne
+    sigx,sigy representent les sigmas des gaussiennes 1D
+    qui sont les coupes de la gaussienne 2D pour y=0 et x=0.
+    Les moments centres d'ordre 2 sont
+      sx = sigx/sqrt(1-ro^2) et sy = sigy/sqrt(1-ro^2)
+  \endverbatim
+*/
+/////////////////////////////////////////////////////////////////
+
+GauRho2D::GauRho2D()
+: GeneralPSF2D(7)
+{
+}
+
+GauRho2D::~GauRho2D()
+{
+}
+
+double GauRho2D::Value(double const xp[], double const* Par)
+{
+ double N = sqrt(1.-_rho_*_rho_)/(DeuxPi*_sigx_*_sigy_);
+ double X = (xp[0]-_x0_)/_sigx_;
+ double Y = (xp[1]-_y0_)/_sigy_;
+ double z2 = (X*X + Y*Y - 2.*_rho_*X*Y)/2.;
+ if( z2<MINEXPM ) return Par[0] * N*EXPO(-z2) + Par[6];
+   else return Par[6];
+}
+
+double GauRho2D::ValueH(double const xp[], double const* Par)
+{
+ double X = (xp[0]-_x0_)/_sigx_;
+ double Y = (xp[1]-_y0_)/_sigy_;
+ //double z2 = (X*X + Y*Y - 2.*_rho_*X*Y)/2.;
+ double z2 = 0.5*(X-Y)*(X-Y) - (_rho_ - 1)*X*Y;
+ if( z2<MINEXPM ) return Par[0] * EXPO(-z2) + Par[6];
+   else return Par[6];
+}
+
+double GauRho2D::VolPSF(double const* Par)
+{
+ return DeuxPi * _sigx_ * _sigy_ / sqrt(1.-_rho_*_rho_);
+}
+
+double GauRho2D::Val_Der(double const xp[], double const* Par
+                        , double *DgDpar)
+{
+ double unmr2 = 1.-_rho_*_rho_;
+ double N = sqrt(unmr2)/(DeuxPi*_sigx_*_sigy_);
+ double X = (xp[0]-_x0_)/_sigx_;
+ double Y = (xp[1]-_y0_)/_sigy_;
+
+ double XmrY = X-_rho_*Y;
+ double YmrX = Y-_rho_*X;
+ double z2 = (X*(XmrY-_rho_*Y)+Y*Y)/2.;
+
+ /* g(x,y) */
+ double PSF = 0.;
+ if( z2<MINEXPM ) PSF = N * EXPO(-z2);
+ /* dg(x,y)/d(x0) */
+ DgDpar[1] =  Par[0]* PSF* XmrY/_sigx_;
+ /* dg(x,y)/d(y0) */
+ DgDpar[2] =  Par[0]* PSF* YmrX/_sigy_;
+ /* dg(x,y)/d(sx)*/
+ DgDpar[3] =  Par[0]* PSF* (X*XmrY-1.)/_sigx_;
+ /* dg(x,y)/d(sy) */
+ DgDpar[4] =  Par[0]* PSF* (Y*YmrX-1.)/_sigy_;
+ /* dg(x,y)/d(rho) */
+ DgDpar[5] =  Par[0]* PSF* (X*Y-2.*_rho_/unmr2);
+ /* dg(x,y)/d(Vol) */
+ DgDpar[0] = PSF;
+ /* dg(x,y)/d(Fond) */
+ DgDpar[6] = 1.;
+
+ return Par[0] * PSF + Par[6];
+}
+
+void GauRho2D::DefaultParam(double *parm)
+{
+  for (int i=0; i<mNPar; i++) parm[i] = 0.;
+  parm[3] = parm[4] = 1.;  // Sigx Sigy
+}
+
+
+/////////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::GauRhInt2D
+  \ingroup NTools
+  \anchor GauRhInt2D
+  \verbatim
+    Cette fonction calcule une approximation a l'integrale d'une
+    gaussienne 2D sur un carre de longueur unite (x,y-05 -> x,y+0.5)
+  \endverbatim
+  \sa GauRho2D
+*/
+/////////////////////////////////////////////////////////////////
+
+GauRhInt2D::GauRhInt2D()
+: GeneralPSF2D(7)
+{
+}
+
+GauRhInt2D::~GauRhInt2D()
+{
+}
+
+double GauRhInt2D::Value(double const xp[], double const* Par)
+{
+ double N = sqrt(1.-_rho_*_rho_)/(DeuxPi*_sigx_*_sigy_);
+ double x = xp[0] - _x0_;
+ double y = xp[1] - _y0_;
+ double SPSF = 0.;
+ double X,Y,z2;
+ for(int i=0; i<nd2d; i++) {
+   X = (x+dx2d[i])/_sigx_;
+   Y = (y+dy2d[i])/_sigy_;
+   z2 = (X*X + Y*Y - 2.*_rho_*X*Y)/2.;
+   if( z2<MINEXPM ) SPSF += EXPO(-z2) * w2d[i];
+ }
+ return Par[0]* N*SPSF + Par[6];
+}
+
+double GauRhInt2D::ValueH(double const xp[], double const* Par)
+{
+ double x = xp[0] - _x0_;
+ double y = xp[1] - _y0_;
+ double SPSF = 0.;
+ double X,Y,z2;
+ for(int i=0; i<nd2d; i++) {
+   X = (x+dx2d[i])/_sigx_;
+   Y = (y+dy2d[i])/_sigy_;
+   z2 = (X*X + Y*Y - 2.*_rho_*X*Y)/2.;
+   if( z2<MINEXPM ) SPSF += EXPO(-z2) * w2d[i];
+ }
+ return Par[0] *SPSF + Par[6];
+}
+
+double GauRhInt2D::VolPSF(double const* Par)
+{
+ return DeuxPi * _sigx_ * _sigy_ / sqrt(1.-_rho_*_rho_);
+}
+
+double GauRhInt2D::Val_Der(double const xp[], double const* Par
+                          ,double *DgDpar)
+{
+ for(int i=0; i<=6; i++) DgDpar[i] = 0.;
+ double unmr2 = 1.-_rho_*_rho_;
+ double N = sqrt(unmr2)/(DeuxPi*_sigx_*_sigy_);
+ double x = xp[0] - _x0_;
+ double y = xp[1] - _y0_;
+
+ double z2,PSF,X,Y,XmrY,YmrX;
+ double SPSF = 0.;
+ {
+ for(int i=0; i<nd2d; i++) {
+   X = (x+dx2d[i])/_sigx_;
+   Y = (y+dy2d[i])/_sigy_;
+   XmrY = X-_rho_*Y;
+   YmrX = Y-_rho_*X;
+   z2 = (X*(XmrY-_rho_*Y)+Y*Y)/2.;
+   /* g(x,y) */
+   if(z2<MINEXPM) PSF = N * EXPO(-z2) * w2d[i]; else PSF = 0.;
+   SPSF += PSF;
+   /* dg(x,y)/d(x0) */
+   DgDpar[1] += Par[0] * PSF* XmrY/_sigx_;
+   /* dg(x,y)/d(y0) */
+   DgDpar[2] += Par[0] * PSF* YmrX/_sigy_;
+   /* dg(x,y)/d(sx)*/
+   DgDpar[3] += Par[0] * PSF* (X*XmrY-1.)/_sigx_;
+   /* dg(x,y)/d(sy) */
+   DgDpar[4] += Par[0] * PSF* (Y*YmrX-1.)/_sigy_;
+   /* dg(x,y)/d(rho) */
+   DgDpar[5] += Par[0] * PSF* (X*Y-2.*_rho_/unmr2);
+ }
+ }
+ /* dg(x,y)/d(Vol) */
+ DgDpar[0] = SPSF;
+ /* dg(x,y)/d(Fond) */
+ DgDpar[6] = 1.;
+
+ return Par[0] *SPSF + Par[6];
+}
+
+void GauRhInt2D::DefaultParam(double *parm)
+{
+  for (int i=0; i<mNPar; i++) parm[i] = 0.;
+  parm[3] = parm[4] = 1.;  // Sigx Sigy
+}
+
+#define B4 1.
+#define B6 1.
+#define KB4B6 0.136887
+
+/////////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::GdlRho2D
+  \ingroup NTools
+  \anchor GdlRho2D
+  \verbatim
+    Cette fonction calcule une gaussienne 2D de volume 1 approchee
+     par son developpement limite au 3ieme ordre (see dophot)
+     Meme commentaire que GauRho2D, cf plus haut sauf que:
+     Par [0]=vol [1]=x0 [2]=y0 [3]=sigx [4]=sigy [5]=rho [6]=fond
+       z**2 = 1/2 (X**2 + Y**2 -2*rho*X*Y)
+       PSF(x,y) = N / [ 1 + z**2 + B4/2 *z**4 + B6/6 *z**6 ]
+                  N = KB4B6
+       le coefficient KB4B6 etant trop dur a calculer analytiquement
+       Il doit etre calcule numeriquement et entre dans ce programme
+     ATTENTION: dans cette routine B4 et B6 sont imposes et pas fites!
+     - DL de la gaussienne:  B4=1., B6=1., KB4B6=0.13688679
+     le volume de cette gaussienne est V=1.
+     F(x,y) = Par[0]*PSF(x,y)+Par[6] (volume=Par[0],fond=Par[6])
+  \endverbatim
+*/
+/////////////////////////////////////////////////////////////////
+
+GdlRho2D::GdlRho2D()
+: GeneralPSF2D(7)
+{
+}
+
+GdlRho2D::~GdlRho2D()
+{
+}
+
+double GdlRho2D::Value(double const xp[], double const* Par)
+{
+ double N = KB4B6*sqrt(1.-_rho_*_rho_)/(_sigx_*_sigy_);
+ double X = (xp[0]-_x0_)/_sigx_;
+ double Y = (xp[1]-_y0_)/_sigy_;
+ double z2 = (X*X + Y*Y - 2.*_rho_*X*Y)/2.;
+ double D = 1.+z2*(1.+z2*(B4/2.+B6/6.*z2));
+ return Par[0] *N/D + Par[6];
+}
+
+double GdlRho2D::ValueH(double const xp[], double const* Par)
+{
+ double X = (xp[0]-_x0_)/_sigx_;
+ double Y = (xp[1]-_y0_)/_sigy_;
+ double z2 = (X*X + Y*Y - 2.*_rho_*X*Y)/2.;
+ double D = 1.+z2*(1.+z2*(B4/2.+B6/6.*z2));
+ return Par[0] /D + Par[6];
+}
+
+double GdlRho2D::VolPSF(double const* Par)
+{
+ return _sigx_*_sigy_/(KB4B6*sqrt(1.-_rho_*_rho_));
+}
+
+double GdlRho2D::Val_Der(double const xp[], double const* Par
+                        , double *DgDpar)
+{
+ double unmr2 = 1.-_rho_*_rho_;
+ double N = KB4B6*sqrt(unmr2)/(_sigx_*_sigy_);
+ double X = (xp[0]-_x0_)/_sigx_;
+ double Y = (xp[1]-_y0_)/_sigy_;
+ double XmrY = X-_rho_*Y;
+ double YmrX = Y-_rho_*X;
+ double z2 = (X*(XmrY-_rho_*Y)+Y*Y)/2.;
+ double D = 1.+z2*(1.+z2*(B4/2.+B6/6.*z2));
+ double dDsD = (1.+z2*(B4+B6/2.*z2))/D;
+
+ /* g(x,y) */
+ double PSF = N / D;
+ /* dg(x,y)/d(x0) */
+ DgDpar[1] = Par[0]* PSF* dDsD*XmrY/_sigx_;
+ /* dg(x,y)/d(y0) */
+ DgDpar[2] = Par[0]* PSF* dDsD*YmrX/_sigy_;
+ /* dg(x,y)/d(sx)*/
+ DgDpar[3] = Par[0]* PSF* (dDsD*X*XmrY-1.)/_sigx_;
+ /* dg(x,y)/d(sy) */
+ DgDpar[4] = Par[0]* PSF* (dDsD*Y*YmrX-1.)/_sigy_;
+ /* dg(x,y)/d(rho) */
+ DgDpar[5] = Par[0]* PSF* (dDsD*X*Y-2.*_rho_/unmr2);
+ /* dg(x,y)/d(Vol) */
+ DgDpar[0] = PSF;
+ /* dg(x,y)/d(Fond) */
+ DgDpar[6] = 1.;
+
+ return Par[0] *PSF + Par[6];
+}
+
+void GdlRho2D::DefaultParam(double *parm)
+{
+  for (int i=0; i<mNPar; i++) parm[i] = 0.;
+  parm[3] = parm[4] = 1.;  // Sigx Sigy
+}
+
+
+/////////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::GdlRhInt2D
+  \ingroup NTools
+  \anchor GdlRhInt2D
+  Fonction integree de GdlRho2d
+  \sa GdlRho2D
+*/
+/////////////////////////////////////////////////////////////////
+
+GdlRhInt2D::GdlRhInt2D()
+: GeneralPSF2D(7)
+{
+}
+
+GdlRhInt2D::~GdlRhInt2D()
+{
+}
+
+double GdlRhInt2D::Value(double const xp[], double const* Par)
+{
+ double N = KB4B6*sqrt(1.-_rho_*_rho_)/(_sigx_*_sigy_);
+ double x = xp[0] - _x0_;
+ double y = xp[1] - _y0_;
+
+ double z2,X,Y,D;
+ double SPSF = 0.;
+ for(int i=0; i<nd2d; i++) {
+   X = (x+dx2d[i])/_sigx_;
+   Y = (y+dy2d[i])/_sigy_;
+   z2 = (X*X + Y*Y - 2.*_rho_*X*Y)/2.;
+   D = 1.+z2*(1.+z2*(B4/2.+B6/6.*z2));
+   SPSF += w2d[i] / D;
+  }
+ return Par[0] *N*SPSF + Par[6];
+}
+
+double GdlRhInt2D::ValueH(double const xp[], double const* Par)
+{
+ double x = xp[0] - _x0_;
+ double y = xp[1] - _y0_;
+
+ double z2,X,Y,D;
+ double SPSF = 0.;
+ for(int i=0; i<nd2d; i++) {
+   X = (x+dx2d[i])/_sigx_;
+   Y = (y+dy2d[i])/_sigy_;
+   z2 = (X*X + Y*Y - 2.*_rho_*X*Y)/2.;
+   D = 1.+z2*(1.+z2*(B4/2.+B6/6.*z2));
+   SPSF += w2d[i] / D;
+  }
+ return Par[0] *SPSF + Par[6];
+}
+
+double GdlRhInt2D::VolPSF(double const* Par)
+{
+ return _sigx_*_sigy_/(KB4B6*sqrt(1.-_rho_*_rho_));
+}
+
+double GdlRhInt2D::Val_Der(double const xp[], double const* Par
+                          , double *DgDpar)
+{
+ for(int i=0; i<=6; i++) DgDpar[i] = 0.;
+ double unmr2 = 1.-_rho_*_rho_;
+ double N = KB4B6*sqrt(unmr2)/(_sigx_*_sigy_);
+ double x = xp[0] - _x0_;
+ double y = xp[1] - _y0_;
+
+ double z2,PSF,X,Y,XmrY,YmrX,D,dDsD;
+ double SPSF = 0.;
+ {
+ for(int i=0; i<nd2d; i++) {
+   X = (x+dx2d[i])/_sigx_;
+   Y = (y+dy2d[i])/_sigy_;
+   XmrY = X-_rho_*Y;
+   YmrX = Y-_rho_*X;
+   z2 = (X*(XmrY-_rho_*Y)+Y*Y)/2.;
+   D = 1.+z2*(1.+z2*(B4/2.+B6/6.*z2));
+   dDsD = (1.+z2*(B4+B6/2.*z2))/D;
+   /* g(x,y) */
+   PSF = N / D  * w2d[i];
+   SPSF += PSF;
+   /* dg(x,y)/d(x0) */
+   DgDpar[1] += Par[0]* PSF* dDsD*XmrY/_sigx_;
+   /* dg(x,y)/d(y0) */
+   DgDpar[2] += Par[0]* PSF* dDsD*YmrX/_sigy_;
+   /* dg(x,y)/d(sx)*/
+   DgDpar[3] += Par[0]* PSF* (dDsD*X*XmrY-1.)/_sigx_;
+   /* dg(x,y)/d(sy) */
+   DgDpar[4] += Par[0]* PSF* (dDsD*Y*YmrX-1.)/_sigy_;
+   /* dg(x,y)/d(rho) */
+   DgDpar[5] += Par[0]* PSF* (dDsD*X*Y-2.*_rho_/unmr2);
+ }
+ }
+ /* dg(x,y)/d(Vol) */
+ DgDpar[0] = SPSF;
+ /* dg(x,y)/d(Fond) */
+ DgDpar[6] = 1.;
+
+ return Par[0] *SPSF + Par[6];
+}
+
+void GdlRhInt2D::DefaultParam(double *parm)
+{
+  for (int i=0; i<mNPar; i++) parm[i] = 0.;
+  parm[3] = parm[4] = 1.;  // Sigx Sigy
+}
+
+#undef B4
+#undef B6
+#undef KB4B6
+
+/////////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::Gdl1Rho2D
+  \ingroup NTools
+  \anchor Gdl1Rho2D
+  \verbatim
+    Cette fonction calcule une gaussienne 2D approchee
+    par son developpement limite au 2sd ordre (see dophot)
+    Meme commentaire que GauRho2D, cf plus haut sauf que:
+      z**2 = 1/2 (X**2 + Y**2 -2*rho*X*Y)
+      PSF(x,y) = N / [ 1 + z**2 + B4/2 *z**4 ]
+      Le coefficient B4 est fitte (6ieme parametres)
+    ATTENTION: les normalisations N dependent de B4
+     1-/ B4 est suppose etre toujours positif pour que la PSF tendent
+         vers 0+ quand z2 tend vers l'infini
+     2-/ Il y a 3 cas de calcul de K(B4) = int(PSF(x,y)) de 0 a l'infini
+                0<B4<1/2, 1/2<B4, et B4=1/2
+         mais pour des raisons d'analyse
+         numerique j'ai pris 3 intervalles:
+                0.<B4<0.499, 0.501<B4, 0.499<=B4<=0.501
+         dans le 3ieme intervalle, comme K est continue est derivable
+         en B4=1/2, j'ai represente K par la droite tangeante
+         ce qui, apres verification dans paw est une tres bonne approx.
+         (je tiens les calculs a disposition.. me demander)
+     Par [0]=vol [1]=x0 [2]=y0 [3]=sigx [4]=sigy [5]=rho [6]=B4 [7]=fond
+     F(x,y) = Par[0]*PSF(x,y)+Par[7]
+  \endverbatim
+*/
+/////////////////////////////////////////////////////////////////
+
+Gdl1Rho2D::Gdl1Rho2D()
+: GeneralPSF2D(8)
+{
+}
+
+Gdl1Rho2D::~Gdl1Rho2D()
+{
+}
+
+double Gdl1Rho2D::Value(double const xp[], double const* Par)
+{
+ double K,W,V,dKdB4;
+ if ( 0. < _B4_ && _B4_ < 0.499 ) {
+   V = 1.-2.*_B4_;
+   W = sqrt(V);
+   K = -log( (1.-W)/(1.+W) )/W;
+   dKdB4 = ( K-2./(1.-V) )/V;
+ } else if ( 0.501 < _B4_ ) {
+   V = 1./(2.*_B4_-1.);
+   W = sqrt(V);
+   K = 2.*W*( Pi/2.-atan(W) );
+   dKdB4 = V*( 2.*V/(1.+V) - K );
+ } else if ( 0.499 <= _B4_ && _B4_ <= 0.501 ) {
+   dKdB4 = -4./3.;
+   K = dKdB4 * ( _B4_ - 0.5 ) + 2.;
+ } else {
+   return(0.);
+ }
+ double N = sqrt(1.-_rho_*_rho_)/(_sigx_*_sigy_*DeuxPi*K);
+
+ double X = (xp[0] - _x0_)/_sigx_;
+ double Y = (xp[1] - _y0_)/_sigy_;
+ double z2 = (X*X + Y*Y - 2.*_rho_*X*Y)/2.;
+ double D = 1.+z2*(1.+z2*_B4_/2.);
+ return Par[0] *N/D + Par[7];
+}
+
+double Gdl1Rho2D::ValueH(double const xp[], double const* Par)
+{
+ double X = (xp[0] - _x0_)/_sigx_;
+ double Y = (xp[1] - _y0_)/_sigy_;
+ double z2 = (X*X + Y*Y - 2.*_rho_*X*Y)/2.;
+ double D = 1.+z2*(1.+z2*_B4_/2.);
+ return Par[0] /D + Par[7];
+}
+
+double Gdl1Rho2D::VolPSF(double const* Par)
+{
+ double K,W,V,dKdB4;
+ if ( 0. < _B4_ && _B4_ < 0.499 ) {
+   V = 1.-2.*_B4_;
+   W = sqrt(V);
+   K = -log( (1.-W)/(1.+W) )/W;
+   dKdB4 = ( K-2./(1.-V) )/V;
+ } else if ( 0.501 < _B4_ ) {
+   V = 1./(2.*_B4_-1.);
+   W = sqrt(V);
+   K = 2.*W*( Pi/2.-atan(W) );
+   dKdB4 = V*( 2.*V/(1.+V) - K );
+ } else if ( 0.499 <= _B4_ && _B4_ <= 0.501 ) {
+   dKdB4 = -4./3.;
+   K = dKdB4 * ( _B4_ - 0.5 ) + 2.;
+ } else {
+   return(0.);
+ }
+ double N = sqrt(1.-_rho_*_rho_)/(_sigx_*_sigy_*DeuxPi*K);
+ return 1./N;
+}
+
+double Gdl1Rho2D::Val_Der(double const xp[], double const* Par
+                         , double *DgDpar)
+{
+ double K,W,V,dKdB4;
+ if ( 0. < _B4_ && _B4_ < 0.499 ) {
+   V = 1.-2.*_B4_;
+   W = sqrt(V);
+   K = -log( (1.-W)/(1.+W) )/W;
+   dKdB4 = ( K-2./(1.-V) )/V;
+ } else if ( 0.501 < _B4_ ) {
+   V = 1./(2.*_B4_-1.);
+   W = sqrt(V);
+   K = 2.*W*( Pi/2.-atan(W) );
+   dKdB4 = V*( 2.*V/(1.+V) - K );
+ } else if ( 0.499 <= _B4_ && _B4_ <= 0.501 ) {
+   dKdB4 = -4./3.;
+   K = dKdB4 * ( _B4_ - 0.5 ) + 2.;
+ } else {
+   for(int i=0;i<=7;i++) DgDpar[i] = 0.;
+   return(0.);
+ }
+ double unmr2 = 1.-_rho_*_rho_;
+ double N = sqrt(unmr2)/(_sigx_*_sigy_*DeuxPi*K);
+
+ double X = (xp[0] - _x0_)/_sigx_;
+ double Y = (xp[1] - _y0_)/_sigy_;
+ double XmrY = X-_rho_*Y;
+ double YmrX = Y-_rho_*X;
+ double z2 = (X*(XmrY-_rho_*Y)+Y*Y)/2.;
+ double D = 1.+z2*(1.+z2*_B4_/2.);
+ double dDsD = (1.+z2*_B4_)/D;
+
+ /* g(x,y) */
+ double PSF = N / D;
+ /* dg(x,y)/d(x0) */
+ DgDpar[1] =  Par[0]* PSF* dDsD*XmrY/_sigx_;
+ /* dg(x,y)/d(y0) */
+ DgDpar[2] =  Par[0]* PSF* dDsD*YmrX/_sigy_;
+ /* dg(x,y)/d(sx)*/
+ DgDpar[3] =  Par[0]* PSF* (dDsD*X*XmrY-1.)/_sigx_;
+ /* dg(x,y)/d(sy) */
+ DgDpar[4] =  Par[0]* PSF* (dDsD*Y*YmrX-1.)/_sigy_;
+ /* dg(x,y)/d(rho) */
+ DgDpar[5] =  Par[0]* PSF* (dDsD*X*Y-2.*_rho_/unmr2);
+ /* dg(x,y)/d(B4) */
+ DgDpar[6] =  Par[0]* PSF* (-dKdB4/K-z2*z2/2./D);
+ /* dg(x,y)/d(Vol) */
+ DgDpar[0] = PSF;
+ /* dg(x,y)/d(Fond) */
+ DgDpar[7] = 1.;
+
+ return Par[0] *PSF + Par[7];
+}
+
+void Gdl1Rho2D::DefaultParam(double *parm)
+{
+  for (int i=0; i<mNPar; i++) parm[i] = 0.;
+  parm[3] = parm[4] = 1.;  // Sigx Sigy
+  parm[6] = 1.;
+}
+
+/////////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::Gdl1RhInt2D
+  \ingroup NTools
+  \anchor Gdl1RhInt2D
+  Fonction integree de Gdl1Rho2D
+  \sa Gdl1Rho2D
+*/
+/////////////////////////////////////////////////////////////////
+
+Gdl1RhInt2D::Gdl1RhInt2D()
+: GeneralPSF2D(8)
+{
+}
+
+Gdl1RhInt2D::~Gdl1RhInt2D()
+{
+}
+
+double Gdl1RhInt2D::Value(double const xp[], double const* Par)
+{
+ double K,W,V,dKdB4;
+ if ( 0. < _B4_ && _B4_ < 0.499 ) {
+   V = 1.-2.*_B4_;
+   W = sqrt(V);
+   K = -log( (1.-W)/(1.+W) )/W;
+   dKdB4 = ( K-2./(1.-V) )/V;
+ } else if ( 0.501 < _B4_ ) {
+   V = 1./(2.*_B4_-1.);
+   W = sqrt(V);
+   K = 2.*W*( Pi/2.-atan(W) );
+   dKdB4 = V*( 2.*V/(1.+V) - K );
+ } else if ( 0.499 <= _B4_ && _B4_ <= 0.501 ) {
+   dKdB4 = -4./3.;
+   K = dKdB4 * ( _B4_ - 0.5 ) + 2.;
+ } else {
+   return(0.);
+ }
+ double N = sqrt(1.-_rho_*_rho_)/(_sigx_*_sigy_*DeuxPi*K);
+
+ double x = xp[0] - _x0_;
+ double y = xp[1] - _y0_;
+ double SPSF=0.;
+ double z2,X,Y,D;
+ for(int i=0; i<nd2d; i++) {
+   X = (x+dx2d[i])/_sigx_;
+   Y = (y+dy2d[i])/_sigy_;
+   z2 = (X*X + Y*Y -2.*_rho_*X*Y)/2.;
+   D = 1.+z2*(1.+z2*_B4_/2.);
+   SPSF += w2d[i] / D;
+ }
+ return Par[0] *N*SPSF + Par[7];
+}
+
+double Gdl1RhInt2D::ValueH(double const xp[], double const* Par)
+{
+ double x = xp[0] - _x0_;
+ double y = xp[1] - _y0_;
+ double SPSF=0.;
+ double z2,X,Y,D;
+ for(int i=0; i<nd2d; i++) {
+   X = (x+dx2d[i])/_sigx_;
+   Y = (y+dy2d[i])/_sigy_;
+   z2 = (X*X + Y*Y -2.*_rho_*X*Y)/2.;
+   D = 1.+z2*(1.+z2*_B4_/2.);
+   SPSF += w2d[i] / D;
+ }
+ return Par[0] *SPSF + Par[7];
+}
+
+double Gdl1RhInt2D::VolPSF(double const* Par)
+{
+ double K,W,V,dKdB4;
+ if ( 0. < _B4_ && _B4_ < 0.499 ) {
+   V = 1.-2.*_B4_;
+   W = sqrt(V);
+   K = -log( (1.-W)/(1.+W) )/W;
+   dKdB4 = ( K-2./(1.-V) )/V;
+ } else if ( 0.501 < _B4_ ) {
+   V = 1./(2.*_B4_-1.);
+   W = sqrt(V);
+   K = 2.*W*( Pi/2.-atan(W) );
+   dKdB4 = V*( 2.*V/(1.+V) - K );
+ } else if ( 0.499 <= _B4_ && _B4_ <= 0.501 ) {
+   dKdB4 = -4./3.;
+   K = dKdB4 * ( _B4_ - 0.5 ) + 2.;
+ } else {
+   return(0.);
+ }
+ double N = sqrt(1.-_rho_*_rho_)/(_sigx_*_sigy_*DeuxPi*K);
+ return 1./N;
+}
+
+double Gdl1RhInt2D::Val_Der(double const xp[], double const* Par
+                           , double *DgDpar)
+{
+ for(int i=0; i<7; i++) DgDpar[i] = 0.;
+
+ double K,W,V,dKdB4;
+ if ( 0. < _B4_ && _B4_ < 0.499 ) {
+   V = 1.-2.*_B4_;
+   W = sqrt(V);
+   K = -log( (1.-W)/(1.+W) )/W;
+   dKdB4 = ( K-2./(1.-V) )/V;
+ } else if ( 0.501 < _B4_ ) {
+   V = 1./(2.*_B4_-1.);
+   W = sqrt(V);
+   K = 2.*W*( Pi/2.-atan(W) );
+   dKdB4 = V*( 2.*V/(1.+V) - K );
+ } else if ( 0.499 <= _B4_ && _B4_ <= 0.501 ) {
+   dKdB4 = -4./3.;
+   K = dKdB4 * ( _B4_ - 0.5 ) + 2.;
+ } else {
+   return(0.);
+ }
+ double unmr2 = 1.-_rho_*_rho_;
+ double N = sqrt(unmr2)/(_sigx_*_sigy_*DeuxPi*K);
+
+ double x = xp[0] - _x0_;
+ double y = xp[1] - _y0_;
+ double z2,PSF,X,Y,XmrY,YmrX,D,dDsD;
+ double SPSF=0.;
+ {for(int i=0; i<nd2d; i++) {
+   X = (x+dx2d[i])/_sigx_;
+   Y = (y+dy2d[i])/_sigy_;
+   XmrY = X-_rho_*Y;
+   YmrX = Y-_rho_*X;
+   z2 = (X*(XmrY-_rho_*Y)+Y*Y)/2.;
+   D = 1.+z2*(1.+z2*_B4_/2.);
+   dDsD = (1.+z2*_B4_)/D;
+   /* dg(x,y) */
+   PSF = N / D  * w2d[i];
+   SPSF += PSF;
+   /* dg(x,y)/d(x0) */
+   DgDpar[1] += Par[0]* PSF* dDsD*XmrY/_sigx_;
+   /* dg(x,y)/d(y0) */
+   DgDpar[2] += Par[0]* PSF* dDsD*YmrX/_sigy_;
+   /* dg(x,y)/d(sx)*/
+   DgDpar[3] += Par[0]* PSF* (dDsD*X*XmrY-1.)/_sigx_;
+   /* dg(x,y)/d(sy) */
+   DgDpar[4] += Par[0]* PSF* (dDsD*Y*YmrX-1.)/_sigy_;
+   /* dg(x,y)/d(rho) */
+   DgDpar[5] += Par[0]* PSF* (dDsD*X*Y-2.*_rho_/unmr2);
+   /* dg(x,y)/d(B4) */
+   DgDpar[6] += Par[0]* PSF* (-dKdB4/K-z2*z2/2./D);
+ }}
+ /* dg(x,y)/d(Vol) */
+ DgDpar[0] = SPSF;
+ /* dg(x,y)/d(Fond) */
+ DgDpar[7] = 1.;
+
+ return Par[0] *SPSF + Par[7];
+}
+
+void Gdl1RhInt2D::DefaultParam(double *parm)
+{
+  for (int i=0; i<mNPar; i++) parm[i] = 0.;
+  parm[3] = parm[4] = 1.;  // Sigx Sigy
+  parm[6] = 1.;
+}
+
+/////////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::Gdl2Rho2D
+  \ingroup NTools
+  \anchor Gdl2Rho2D
+  \verbatim
+    Cette fonction calcule une gaussienne 2D de hauteur 1 approchee
+    par son developpement limite ordre 3 (see dophot)
+    Meme commentaire que GauRho2D, cf plus haut sauf que:
+      z**2 = 1/2 (X**2 + Y**2 -2*rho*X*Y)
+      Z**2 = B2*z2
+      PSF(x,y) = h / [ 1 + Z**2 + B4**2/2 *Z**4 + B6**2/6 *Z**6 ]
+      B2,B4,B6 peuvent etre fittes
+    - DL de la gaussienne:  B2=B4=B6=1.
+     Par [0]=hauteur [1]=x0 [2]=y0 [3]=sigx [4]=sigy [5]=rho
+         [6]=B4 [7]=B6 [8]=B2 [9]= fond
+     F(x,y) = Par[0]*PSF(x,y)+Par[9]
+  \endverbatim
+*/
+/////////////////////////////////////////////////////////////////
+
+Gdl2Rho2D::Gdl2Rho2D()
+: GeneralPSF2D(10)
+{
+}
+
+Gdl2Rho2D::~Gdl2Rho2D()
+{
+}
+
+double Gdl2Rho2D::Value(double const xp[], double const* Par)
+{
+ double X = (xp[0]-_x0_)/_sigx_;
+ double Y = (xp[1]-_y0_)/_sigy_;
+ double z2 = (X*X + Y*Y - 2*_rho_*X*Y)/2.;
+ double Z2 = _B2_ * _B2_ * z2;
+ double Z4 = Z2*Z2;
+ double Z6 = Z4*Z2;
+ double D = 1. + Z2 + _B4_*_B4_/2.*Z4 + _B6_*_B6_/6.*Z6;
+ return Par[0] /D + Par[9];
+}
+
+double Gdl2Rho2D::ValueH(double const xp[], double const* Par)
+{
+ double X = (xp[0]-_x0_)/_sigx_;
+ double Y = (xp[1]-_y0_)/_sigy_;
+ double z2 = (X*X + Y*Y - 2*_rho_*X*Y)/2.;
+ double Z2 = _B2_ * _B2_ * z2;
+ double Z4 = Z2*Z2;
+ double Z6 = Z4*Z2;
+ double D = 1. + Z2 + _B4_*_B4_/2.*Z4 + _B6_*_B6_/6.*Z6;
+ return Par[0] /D + Par[9];
+}
+
+double Gdl2Rho2D::Val_Der(double const xp[], double const* Par
+                         , double *DgDpar)
+{
+ double unmr2 = 1.-_rho_*_rho_;
+ double X = (xp[0]-_x0_)/_sigx_;
+ double Y = (xp[1]-_y0_)/_sigy_;
+ double XmrY = X-_rho_*Y;
+ double YmrX = Y-_rho_*X;
+ double z2 = (X*(XmrY-_rho_*Y)+Y*Y)/2.;
+ double Z2 = _B2_ * _B2_ * z2;
+ double Z4 = Z2*Z2;
+ double Z6 = Z4*Z2;
+ double D = 1. + Z2 + _B4_*_B4_/2.*Z4 + _B6_*_B6_/6.*Z6;
+ double dDsDB2 = (1. + _B4_*_B4_*Z2    + _B6_*_B6_/2.*Z4 )/D;
+ double dDsD = _B2_*_B2_ * dDsDB2;
+ /* g(x,y) */
+ double PSF = 1. / D;
+ /* dg(x,y)/d(x0) */
+ DgDpar[1] = Par[0]* PSF* dDsD*XmrY/_sigx_;
+ /* dg(x,y)/d(y0) */
+ DgDpar[2] = Par[0]* PSF* dDsD*YmrX/_sigy_;
+ /* dg(x,y)/d(sx)*/
+ DgDpar[3] = Par[0]* PSF* (dDsD*X*XmrY-1.)/_sigx_;
+ /* dg(x,y)/d(sy) */
+ DgDpar[4] = Par[0]* PSF* (dDsD*Y*YmrX-1.)/_sigy_;
+ /* dg(x,y)/d(rho) */
+ DgDpar[5] = Par[0]* PSF* (dDsD*X*Y-2.*_rho_/unmr2);
+ /* dg(x,y)/d(B4) */
+ DgDpar[6] = Par[0]* PSF* (-_B4_*Z4/D);
+ /* dg(x,y)/d(B6) */
+ DgDpar[7] = Par[0]* PSF* (-_B6_*Z6/3./D);
+ /* dg(x,y)/d(B2)  */
+ DgDpar[8] = Par[0]* PSF* (-2.*_B2_*z2*dDsDB2);
+ /* dg(x,y)/d(hauteur) */
+ DgDpar[0] = PSF;
+ /* dg(x,y)/d(Fond) */
+ DgDpar[9] = 1.;
+
+ return Par[0] *PSF + Par[9];
+}
+
+void Gdl2Rho2D::DefaultParam(double *parm)
+{
+  for (int i=0; i<mNPar; i++) parm[i] = 0.;
+  parm[3] = parm[4] = 1.;  // Sigx Sigy
+  parm[6] = parm[7] = parm[8] = 1.;
+}
+
+/////////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::Gdl2RhInt2D
+  \ingroup NTools
+  \anchor Gdl2RhInt2D
+  Fonction integree de Gdl2Rho2d
+  \sa Gdl2Rho2D
+*/
+/////////////////////////////////////////////////////////////////
+
+Gdl2RhInt2D::Gdl2RhInt2D()
+: GeneralPSF2D(10)
+{
+}
+
+Gdl2RhInt2D::~Gdl2RhInt2D()
+{
+}
+
+double Gdl2RhInt2D::Value(double const xp[], double const* Par)
+{
+ double x = xp[0] - _x0_;
+ double y = xp[1] - _y0_;
+ double SPSF=0.;
+ double X,Y,z2,Z2,Z4,Z6,D;
+ for(int i=0; i<nd2d; i++) {
+   X = (x+dx2d[i])/_sigx_;
+   Y = (y+dy2d[i])/_sigy_;
+   z2 = (X*X + Y*Y - 2.*_rho_*X*Y)/2.;
+   Z2 = _B2_ * _B2_ * z2;
+   Z4 = Z2*Z2;
+   Z6 = Z4*Z2;
+   D = 1. + Z2 + _B4_*_B4_/2.*Z4 + _B6_*_B6_/6.*Z6;
+   /* g(x,y) */
+   SPSF += w2d[i] / D;
+ }
+ return Par[0] *SPSF + Par[9];
+}
+
+double Gdl2RhInt2D::ValueH(double const xp[], double const* Par)
+{
+ double x = xp[0] - _x0_;
+ double y = xp[1] - _y0_;
+ double SPSF=0.;
+ double X,Y,z2,Z2,Z4,Z6,D;
+ for(int i=0; i<nd2d; i++) {
+   X = (x+dx2d[i])/_sigx_;
+   Y = (y+dy2d[i])/_sigy_;
+   z2 = (X*X + Y*Y - 2.*_rho_*X*Y)/2.;
+   Z2 = _B2_ * _B2_ * z2;
+   Z4 = Z2*Z2;
+   Z6 = Z4*Z2;
+   D = 1. + Z2 + _B4_*_B4_/2.*Z4 + _B6_*_B6_/6.*Z6;
+   /* g(x,y) */
+   SPSF += w2d[i] / D;
+ }
+ return Par[0] *SPSF + Par[9];
+}
+
+double Gdl2RhInt2D::Val_Der(double const xp[], double const* Par
+                           , double *DgDpar)
+{
+ for(int i=0; i<=9; i++) DgDpar[i] = 0.;
+
+ double unmr2 = 1.-_rho_*_rho_;
+ double x = xp[0] - _x0_;
+ double y = xp[1] - _y0_;
+ double SPSF=0.;
+ double X,Y,XmrY,YmrX,z2,Z2,Z4,Z6,D,dDsD,dDsDB2,PSF;
+ {for(int i=0; i<nd2d; i++) {
+   X = (x+dx2d[i])/_sigx_;
+   Y = (y+dy2d[i])/_sigy_;
+   XmrY = X-_rho_*Y;
+   YmrX = Y-_rho_*X;
+   z2 = (X*(XmrY-_rho_*Y)+Y*Y)/2.;
+   Z2 = _B2_ * _B2_ * z2;
+   Z4 = Z2*Z2;
+   Z6 = Z4*Z2;
+   D = 1. + Z2 + _B4_*_B4_/2.*Z4 + _B6_*_B6_/6.*Z6;
+   dDsDB2 = (1. + _B4_*_B4_*Z2    + _B6_*_B6_/2.*Z4 )/D;
+   dDsD = _B2_*_B2_ * dDsDB2;
+   /* dg(x,y) */
+   PSF = w2d[i] / D;
+   SPSF += PSF;
+   /* dg(x,y)/d(x0) */
+   DgDpar[1] += Par[0]* PSF* dDsD*XmrY/_sigx_;
+   /* dg(x,y)/d(y0) */
+   DgDpar[2] += Par[0]* PSF* dDsD*YmrX/_sigy_;
+   /* dg(x,y)/d(sx)*/
+   DgDpar[3] += Par[0]* PSF* (dDsD*X*XmrY-1.)/_sigx_;
+   /* dg(x,y)/d(sy) */
+   DgDpar[4] += Par[0]* PSF* (dDsD*Y*YmrX-1.)/_sigy_;
+   /* dg(x,y)/d(rho) */
+   DgDpar[5] += Par[0]* PSF* (dDsD*X*Y-2.*_rho_/unmr2);
+   /* dg(x,y)/d(B4) */
+   DgDpar[6] += Par[0]* PSF* (-_B4_*Z4/D);
+   /* dg(x,y)/d(B6) */
+   DgDpar[7] += Par[0]* PSF* (-_B6_*Z6/3./D);
+   /* dg(x,y)/d(B2)  */
+   DgDpar[8] += Par[0]* PSF* (-2.*_B2_*z2*dDsDB2);
+ }}
+ /* dg(x,y)/d(hauteur) */
+ DgDpar[0] = SPSF;
+ /* dg(x,y)/d(Fond) */
+ DgDpar[9] = 1.;
+
+ return Par[0] *SPSF + Par[9];
+}
+
+void Gdl2RhInt2D::DefaultParam(double *parm)
+{
+  for (int i=0; i<mNPar; i++) parm[i] = 0.;
+  parm[3] = parm[4] = 1.;  // Sigx Sigy
+  parm[6] = parm[7] = parm[8] = 1.;
+}
+
+/////////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::MofRho2D
+  \ingroup NTools
+  \anchor MofRho2D
+  \verbatim
+    Cette fonction calcule une Moffat 2D
+      Par [0]=hauteur [1]=x0 [2]=y0 [3]=sigx [4]=sigy [5]=rho
+          [6]=Gm [7]= fond
+     PSF(x,y)  = valeur de la Moffat normalisee a un volume = 1
+     PSF(x,y) = N / [ 1. +  0.5*(X**2 + Y**2 -2*rho*X*Y) ]**Gm
+              avec X = (x-x0)/sigx et Y = (y-y0)/sigy et Gm>1
+                   N = (1-Gm)*sqrt(1-rho**2)/(2*Pi*sigx*sigy)
+     le volume de cette Moffat est V=1.
+     F(x,y) = Par[0]*PSF(x,y)+Par[7]
+  \endverbatim
+*/
+/////////////////////////////////////////////////////////////////
+
+MofRho2D::MofRho2D()
+: GeneralPSF2D(8)
+{
+}
+
+MofRho2D::~MofRho2D()
+{
+}
+
+double MofRho2D::Value(double const xp[], double const* Par)
+{
+ double N = (_Gm_-1.)*sqrt(1.-_rho_*_rho_)/(DeuxPi*_sigx_*_sigy_);
+ double X = (xp[0] - _x0_)/_sigx_;
+ double Y = (xp[1] - _y0_)/_sigy_;
+ double z2 = (X*X + Y*Y -2.*_rho_*X*Y)/2.;
+ z2 = _Gm_*log(1. + z2);
+ if( z2<MINEXPM ) return Par[0] *N*EXPO(-z2) + Par[7];
+    else return Par[7];
+}
+
+double MofRho2D::ValueH(double const xp[], double const* Par)
+{
+ double X = (xp[0] - _x0_)/_sigx_;
+ double Y = (xp[1] - _y0_)/_sigy_;
+ double z2 = (X*X + Y*Y -2.*_rho_*X*Y)/2.;
+ z2 = _Gm_*log(1. + z2);
+ if( z2<MINEXPM ) return Par[0] *EXPO(-z2) + Par[7];
+    else return Par[7];
+}
+
+double MofRho2D::VolPSF(double const* Par)
+{
+ double N = (_Gm_-1.)*sqrt(1.-_rho_*_rho_)/(DeuxPi*_sigx_*_sigy_);
+ return 1./N;
+}
+
+double MofRho2D::Val_Der(double const xp[], double const* Par
+                        , double *DgDpar)
+{
+ double unmr2 = 1.-_rho_*_rho_;
+ double N = (_Gm_-1.)*sqrt(unmr2)/DeuxPi/_sigx_/_sigy_;
+ double X = (xp[0] - _x0_)/_sigx_;
+ double Y = (xp[1] - _y0_)/_sigy_;
+ double XmrY = X-_rho_*Y;
+ double YmrX = Y-_rho_*X;
+ double z2 = (X*(XmrY-_rho_*Y)+Y*Y)/2.;
+ double D = 1. + z2;
+ double lD = log(D);
+ /* g(x,y) */
+ double PSF = _Gm_*lD;
+ if( PSF<MINEXPM ) PSF = N * EXPO(-PSF); else PSF = 0.;
+ /* dg(x,y)/d(x0) */
+ DgDpar[1] = Par[0]* PSF* XmrY/_sigx_ * _Gm_/D;
+ /* dg(x,y)/d(y0) */
+ DgDpar[2] = Par[0]* PSF* YmrX/_sigy_ * _Gm_/D;
+ /* dg(x,y)/d(sx)*/
+ DgDpar[3] = Par[0]* PSF* (X*XmrY*_Gm_/D - 1.)/_sigx_;
+ /* dg(x,y)/d(sy) */
+ DgDpar[4] = Par[0]* PSF* (Y*YmrX*_Gm_/D - 1.)/_sigy_;
+ /* dg(x,y)/d(rho) */
+ DgDpar[5] = Par[0]* PSF* (X*Y*_Gm_/D - 2.*_rho_/unmr2);
+ /* dg(x,y)/d(Gm) */
+ DgDpar[6] = Par[0]* PSF* (1./(_Gm_-1.) - lD);
+ /* dg(x,y)/d(Vol) */
+ DgDpar[0] = PSF;
+ /* dg(x,y)/d(Fond) */
+ DgDpar[7] = 1.;
+
+ return Par[0] *PSF + Par[7];
+}
+
+void MofRho2D::DefaultParam(double *parm)
+{
+  for (int i=0; i<mNPar; i++) parm[i] = 0.;
+  parm[3] = parm[4] = 1.;  // Sigx Sigy
+  parm[6] = 3.;
+}
+
+/////////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::MofRhInt2D
+  \ingroup NTools
+  \anchor MofRhInt2D
+  Fonction integree de MofRho2d
+  \sa MofRho2D
+*/
+/////////////////////////////////////////////////////////////////
+
+MofRhInt2D::MofRhInt2D()
+: GeneralPSF2D(8)
+{
+}
+
+MofRhInt2D::~MofRhInt2D()
+{
+}
+
+double MofRhInt2D::Value(double const xp[], double const* Par)
+{
+ double N = (_Gm_-1.)*sqrt(1.-_rho_*_rho_)/(DeuxPi*_sigx_*_sigy_);
+ double x = xp[0] - _x0_;
+ double y = xp[1] - _y0_;
+ double SPSF = 0.;
+ double z2,X,Y;
+ for(int i=0; i<nd2d; i++) {
+   X = (x+dx2d[i])/_sigx_;
+   Y = (y+dy2d[i])/_sigy_;
+   z2 = (X*X + Y*Y - 2.*_rho_*X*Y)/2.;
+   /* g(x,y) */
+   z2  = _Gm_*log(1. + z2);
+   if( z2<MINEXPM ) SPSF += EXPO(-z2) * w2d[i];
+ }
+ return Par[0] * N*SPSF + Par[7];
+}
+
+double MofRhInt2D::ValueH(double const xp[], double const* Par)
+{
+ double x = xp[0] - _x0_;
+ double y = xp[1] - _y0_;
+ double SPSF = 0.;
+ double z2,X,Y;
+ for(int i=0; i<nd2d; i++) {
+   X = (x+dx2d[i])/_sigx_;
+   Y = (y+dy2d[i])/_sigy_;
+   z2 = (X*X + Y*Y - 2.*_rho_*X*Y)/2.;
+   /* g(x,y) */
+   z2  = _Gm_*log(1. + z2);
+   if( z2<MINEXPM ) SPSF += EXPO(-z2) * w2d[i];
+ }
+ return Par[0] *SPSF + Par[7];
+}
+
+double MofRhInt2D::VolPSF(double const* Par)
+{
+ double N = (_Gm_-1.)*sqrt(1.-_rho_*_rho_)/(DeuxPi*_sigx_*_sigy_);
+ return 1./N;
+}
+
+double MofRhInt2D::Val_Der(double const xp[], double const* Par
+                          , double *DgDpar)
+{
+ for(int i=0; i<=7; i++) DgDpar[i] = 0.;
+
+ double unmr2 = 1.-_rho_*_rho_;
+ double N = (_Gm_-1.)*sqrt(unmr2)/(DeuxPi*_sigx_*_sigy_);
+ double x = xp[0] - _x0_;
+ double y = xp[1] - _y0_;
+ double SPSF = 0.;
+ double X,Y,XmrY,YmrX,z2,D,lD,PSF;
+ {for(int i=0; i<nd2d; i++) {
+   X = (x+dx2d[i])/_sigx_;
+   Y = (y+dy2d[i])/_sigy_;
+   XmrY = X-_rho_*Y;
+   YmrX = Y-_rho_*X;
+   z2 = (X*(XmrY-_rho_*Y)+Y*Y)/2.;
+   D = 1. + z2;
+   lD = log(D);
+   /* g(x,y) */
+   PSF = _Gm_*lD;
+   if( PSF<MINEXPM ) PSF = N * EXPO(-PSF) * w2d[i]; else PSF = 0.;
+   SPSF += PSF;
+   /* dg(x,y)/d(x0) */
+   DgDpar[1] += Par[0]* PSF* XmrY/_sigx_ * _Gm_/D;
+   /* dg(x,y)/d(y0) */
+   DgDpar[2] += Par[0]* PSF* YmrX/_sigy_ * _Gm_/D;
+   /* dg(x,y)/d(sx)*/
+   DgDpar[3] += Par[0]* PSF* (X*XmrY*_Gm_/D - 1.)/_sigx_;
+   /* dg(x,y)/d(sy) */
+   DgDpar[4] += Par[0]* PSF* (Y*YmrX*_Gm_/D - 1.)/_sigy_;
+   /* dg(x,y)/d(rho) */
+   DgDpar[5] += Par[0]* PSF* (X*Y*_Gm_/D - 2.*_rho_/unmr2);
+   /* dg(x,y)/d(Gm) */
+   DgDpar[6] += Par[0]* PSF* (1./(_Gm_-1.) - lD);
+ }}
+ /* dg(x,y)/d(Vol) */
+ DgDpar[0] = SPSF;
+ /* dg(x,y)/d(Fond) */
+ DgDpar[7] = 1.;
+
+ return Par[0] *SPSF + Par[7];
+}
+
+void MofRhInt2D::DefaultParam(double *parm)
+{
+  for (int i=0; i<mNPar; i++) parm[i] = 0.;
+  parm[3] = parm[4] = 1.;  // Sigx Sigy
+  parm[6] = 3.;
+}
+
+
+#undef _sigx_
+#undef _sigy_
+#undef _rho_
+#undef _x0_
+#undef _y0_
+#undef _Gm_
+#undef _B4_
+#undef _B6_
+#undef _B2_
+
+//==============================================================================
+// CLASSES DE FONCTIONS 2D type Xi2 AVEC PARAMETRES POUR LE FIT pixel taille 1x1
+// la taille du pixel est importante quand on utilise les PSF integrees
+//    (x,y x0,y0 sigmaX.... sont en unites de pixels !!!)
+//==============================================================================
+
+/////////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::X2_GauRho2D
+  \ingroup NTools
+  \anchor X2_GauRho2D
+   Chi2 pour une Gaussienne+fond 2D (voir detail dans GauRho2D).
+*/
+/////////////////////////////////////////////////////////////////
+
+X2_GauRho2D::X2_GauRho2D()
+: GeneralXi2(7)
+{
+  gaurho2d = new GauRho2D;
+}
+
+X2_GauRho2D::~X2_GauRho2D()
+{
+  delete gaurho2d;
+}
+
+double X2_GauRho2D::Value(GeneralFitData& data, double* parm, int& ndataused)
+{
+ ASSERT( data.NVar()==2 );
+ double x[2],z;
+
+ double c2 = 0.;
+ ndataused = 0;
+ for(int k=0;k<data.NData();k++) {
+   if( ! data.IsValid(k) ) continue;
+   x[0] = data.X(k); x[1] = data.Y(k);
+   z = (data.Val(k)-gaurho2d->Value(x,parm))/data.EVal(k);
+   c2 += z*z;
+   ndataused++;
+ }
+ return c2;
+}
+
+double X2_GauRho2D::Derivee2(GeneralFitData& data, int i,int j, double* parm)
+{
+ ASSERT( data.NVar()==2 && i<7 && j<7);
+ double x[2],dparm[7];
+
+ double d2c2 = 0.;
+ for(int k=0;k<data.NData();k++) {
+   if( ! data.IsValid(k) ) continue;
+   x[0] = data.X(k); x[1] = data.Y(k);
+   gaurho2d->Val_Der(x,parm,dparm);
+   d2c2 += 2.*dparm[i]*dparm[j]/(data.EVal(k)*data.EVal(k));
+ }
+ return d2c2;
+}
Index: /tags/V_Dec2002/SophyaLib/NTools/fct2dfit.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/fct2dfit.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/fct2dfit.h	(revision 2309)
@@ -0,0 +1,212 @@
+#ifndef FCT2DFIT_SEEN
+#define FCT2DFIT_SEEN
+
+#include "generalfit.h"
+
+namespace SOPHYA {
+
+//================================================================
+// GeneralFunction 2D pour PSF pixel taille 1x1
+//================================================================
+
+//! Classe de definition d'une PSF 2D a nPar parametres
+class GeneralPSF2D : public GeneralFunction {
+public:
+  GeneralPSF2D(unsigned int nPar);
+  virtual ~GeneralPSF2D();
+
+  virtual double ValueH(double const xp[], double const* parm);
+  virtual double VolPSF(double const* parm);
+  virtual void   DefaultParam(double *parm);
+
+  void SetVolEps(double const prec) ;
+protected:
+  double VolEps;
+};
+
+//================================================================
+// GeneralFunction 2D pour MULTI-PSF pixel taille 1x1
+//================================================================
+
+//! Classe de definition d'un ensemble de PSF2D
+class GenMultiPSF2D : public GeneralPSF2D {
+public:
+  GenMultiPSF2D(GeneralPSF2D* psf2d,unsigned int nstar);
+  virtual ~GenMultiPSF2D();
+
+  virtual double Value(double const xp[], double const* Par);
+  virtual double Val_Der(double const xp[],double const* Par,double* DgDpar);
+
+protected:
+  GeneralPSF2D* mPsf2D; // Type de PSF generique a fiter.
+  int mNStar;           // Nombre d etoiles a fiter.
+  int mNParmTot;        // Nombre total de parametres pour le fit.
+  int mNParm;           // Nombre de parametre pour la PSF generique.
+  int mNForme;          // Nombre de parametres de forme autres que Sx,Sy,Rho
+  double* mParm;        // pour la PSF generique. Buffer pour PSF generique
+  double* mDer;         // et pour le stoquage temporaire des derivees.
+};
+
+//==============================================================================
+// CLASSES DE FONCTIONS 2D type PSF AVEC PARAMETRES POUR LE FIT pixel taille 1x1
+//==============================================================================
+
+//////////////////////////////////////////////////////////////////
+//! gaussienne + fond 2D
+class GauRho2D : public GeneralPSF2D {
+public:
+  GauRho2D();
+  virtual ~GauRho2D();
+
+  virtual double Value(double const xp[], double const* Par);
+  virtual double Val_Der(double const xp[],double const* Par,double* DgDpar);
+  virtual double ValueH(double const xp[], double const* Par);
+  virtual double VolPSF(double const* Par);
+  virtual void   DefaultParam(double *Par);
+};
+
+//////////////////////////////////////////////////////////////////
+//! gaussienne integree + fond 2D
+class GauRhInt2D : public GeneralPSF2D {
+public:
+  GauRhInt2D();
+  virtual ~GauRhInt2D();
+
+  virtual double Value(double const xp[], double const* Par);
+  virtual double Val_Der(double const xp[],double const* Par,double* DgDpar);
+  virtual double ValueH(double const xp[], double const* Par);
+  virtual double VolPSF(double const* Par);
+  virtual void   DefaultParam(double *Par);
+};
+
+//////////////////////////////////////////////////////////////////
+//! gaussienne 2D de volume 1 approchee par dl au 3ieme ordre
+class GdlRho2D : public GeneralPSF2D {
+public:
+  GdlRho2D();
+  virtual ~GdlRho2D();
+
+  virtual double Value(double const xp[], double const* Par);
+  virtual double Val_Der(double const xp[],double const* Par,double* DgDpar);
+  virtual double ValueH(double const xp[], double const* Par);
+  virtual double VolPSF(double const* Par);
+  virtual void   DefaultParam(double *Par);
+};
+
+//////////////////////////////////////////////////////////////////
+//! gaussienne integree 2D de volume 1 approchee par dl au 3ieme ordre
+class GdlRhInt2D : public GeneralPSF2D {
+public:
+  GdlRhInt2D();
+  virtual ~GdlRhInt2D();
+
+  virtual double Value(double const xp[], double const* Par);
+  virtual double Val_Der(double const xp[],double const* Par,double* DgDpar);
+  virtual double ValueH(double const xp[], double const* Par);
+  virtual double VolPSF(double const* Par);
+  virtual void   DefaultParam(double *Par);
+};
+
+//////////////////////////////////////////////////////////////////
+//! gaussienne 2D de volume 1 approchee par dl au 2sd ordre
+class Gdl1Rho2D : public GeneralPSF2D {
+public:
+  Gdl1Rho2D();
+  virtual ~Gdl1Rho2D();
+
+  virtual double Value(double const xp[], double const* Par);
+  virtual double Val_Der(double const xp[],double const* Par,double* DgDpar);
+  virtual double ValueH(double const xp[], double const* Par);
+  virtual double VolPSF(double const* Par);
+  virtual void   DefaultParam(double *Par);
+};
+
+//////////////////////////////////////////////////////////////////
+//! gaussienne ontegree 2D de volume 1 approchee par dl au 2sd ordre
+class Gdl1RhInt2D : public GeneralPSF2D {
+public:
+  Gdl1RhInt2D();
+  virtual ~Gdl1RhInt2D();
+
+  virtual double Value(double const xp[], double const* Par);
+  virtual double Val_Der(double const xp[],double const* Par,double* DgDpar);
+  virtual double ValueH(double const xp[], double const* Par);
+  virtual double VolPSF(double const* Par);
+  virtual void   DefaultParam(double *Par);
+};
+
+//////////////////////////////////////////////////////////////////
+//! gaussienne 2D de hauteur 1 approchee dl 3ieme
+class Gdl2Rho2D : public GeneralPSF2D {
+public:
+  Gdl2Rho2D();
+  virtual ~Gdl2Rho2D();
+
+  virtual double Value(double const xp[], double const* Par);
+  virtual double Val_Der(double const xp[],double const* Par,double* DgDpar);
+  virtual double ValueH(double const xp[], double const* Par);
+  virtual void   DefaultParam(double *Par);
+};
+
+//////////////////////////////////////////////////////////////////
+//! gaussienne integree 2D de hauteur 1 approchee dl 3ieme
+class Gdl2RhInt2D : public GeneralPSF2D {
+public:
+  Gdl2RhInt2D();
+  virtual ~Gdl2RhInt2D();
+
+  virtual double Value(double const xp[], double const* Par);
+  virtual double Val_Der(double const xp[],double const* Par,double* DgDpar);
+  virtual double ValueH(double const xp[], double const* Par);
+  virtual void   DefaultParam(double *Par);
+};
+
+//////////////////////////////////////////////////////////////////
+//! Moffat 2D
+class MofRho2D : public GeneralPSF2D {
+public:
+  MofRho2D();
+  virtual ~MofRho2D();
+
+  virtual double Value(double const xp[], double const* Par);
+  virtual double Val_Der(double const xp[],double const* Par,double* DgDpar);
+  virtual double ValueH(double const xp[], double const* Par);
+  virtual double VolPSF(double const* Par);
+  virtual void   DefaultParam(double *Par);
+};
+
+//////////////////////////////////////////////////////////////////
+//! Moffat integree 2D
+class MofRhInt2D : public GeneralPSF2D {
+public:
+  MofRhInt2D();
+  virtual ~MofRhInt2D();
+
+  virtual double Value(double const xp[], double const* Par);
+  virtual double Val_Der(double const xp[],double const* Par,double* DgDpar);
+  virtual double ValueH(double const xp[], double const* Par);
+  virtual double VolPSF(double const* Par);
+  virtual void   DefaultParam(double *Par);
+};
+
+//==============================================================================
+// CLASSES DE FONCTIONS 2D type Xi2 AVEC PARAMETRES POUR LE FIT pixel taille 1x1
+//==============================================================================
+
+//////////////////////////////////////////////////////////////////
+//! Chi2 pour une Gaussienne+fond 2D
+class X2_GauRho2D : public GeneralXi2 {
+public:
+  X2_GauRho2D();
+  virtual ~X2_GauRho2D();
+
+  virtual double Value(GeneralFitData& data, double* parm, int& ndataused);
+  virtual double Derivee2(GeneralFitData& data, int i,int j, double* parm);
+
+protected:
+  GauRho2D* gaurho2d;
+};
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/fftmayer.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/fftmayer.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/fftmayer.h	(revision 2309)
@@ -0,0 +1,71 @@
+#ifndef  FFTMAYER_H_SEEN
+#define  FFTMAYER_H_SEEN
+/*
+** FFT and FHT routines
+**  Copyright 1988, 1993; Ron Mayer
+**  
+**  fht(fz,n);
+**      Does a hartley transform of "n" points in the array "fz".
+**  fft(n,real,imag)
+**      Does a fourier transform of "n" points of the "real" and
+**      "imag" arrays.
+**  ifft(n,real,imag)
+**      Does an inverse fourier transform of "n" points of the "real"
+**      and "imag" arrays.
+**  realfft(n,real)
+**      Does a real-valued fourier transform of "n" points of the
+**      "real" arrays.  The real part of the transform ends
+**      up in the first half of the array and the imaginary part of the
+**      transform ends up in the second half of the array.
+**  realifft(n,real)
+**      The inverse of the realfft() routine above.
+**      
+**      
+** NOTE: This routine uses at least 2 patented algorithms, and may be
+**       under the restrictions of a bunch of different organizations.
+**       Although I wrote it completely myself; it is kind of a derivative
+**       of a routine I once authored and released under the GPL, so it
+**       may fall under the free software foundation's restrictions;
+**       it was worked on as a Stanford Univ project, so they claim
+**       some rights to it; it was further optimized at work here, so
+**       I think this company claims parts of it.  The patents are
+**       held by R. Bracewell (the FHT algorithm) and O. Buneman (the
+**       trig generator), both at Stanford Univ.
+**       If it were up to me, I'd say go do whatever you want with it;
+**       but it would be polite to give credit to the following people
+**       if you use this anywhere:
+**           Euler     - probable inventor of the fourier transform.
+**           Gauss     - probable inventor of the FFT.
+**           Hartley   - probable inventor of the hartley transform.
+**           Buneman   - for a really cool trig generator
+**           Mayer(me) - for authoring this particular version and
+**                       including all the optimizations in one package.
+**       Thanks,
+**       Ron Mayer; mayer@acuson.com
+**
+*/
+
+/*   Reza 4/02/99 : Introduced double AND float version   */
+#include "machdefs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void fht_r4( r_4 *fz,int n);
+void ifft_r4(int n, r_4 *real, r_4 *imag);
+void realfft_r4(int n, r_4 *real);
+void fft_r4(int n, r_4 *real,r_4 *imag);
+void realifft_r4(int n,r_4 *real);
+
+void fht_r8( r_8 *fz,int n);
+void ifft_r8(int n, r_8 *real, r_8 *imag);
+void realfft_r8(int n, r_8 *real);
+void fft_r8(int n, r_8 *real,r_8 *imag);
+void realifft_r8(int n,r_8 *real);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/fftmayer_r4.c
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/fftmayer_r4.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/fftmayer_r4.c	(revision 2309)
@@ -0,0 +1,259 @@
+/*
+** FFT and FHT routines
+**  Copyright 1988, 1993; Ron Mayer
+**  
+**  fht(fz,n);
+**      Does a hartley transform of "n" points in the array "fz".
+**  fft(n,real,imag)
+**      Does a fourier transform of "n" points of the "real" and
+**      "imag" arrays.
+**  ifft(n,real,imag)
+**      Does an inverse fourier transform of "n" points of the "real"
+**      and "imag" arrays.
+**  realfft(n,real)
+**      Does a real-valued fourier transform of "n" points of the
+**      "real" array. The real part of the transform ends
+**      up in the first half of the array and the imaginary part of the
+**      transform ends up in the second half of the array.
+**  realifft(n,real)
+**      The inverse of the realfft() routine above.
+**      
+**      
+** NOTE: This routine uses at least 2 patented algorithms, and may be
+**       under the restrictions of a bunch of different organizations.
+**       Although I wrote it completely myself; it is kind of a derivative
+**       of a routine I once authored and released under the GPL, so it
+**       may fall under the free software foundation's restrictions;
+**       it was worked on as a Stanford Univ project, so they claim
+**       some rights to it; it was further optimized at work here, so
+**       I think this company claims parts of it.  The patents are
+**       held by R. Bracewell (the FHT algorithm) and O. Buneman (the
+**       trig generator), both at Stanford Univ.
+**       If it were up to me, I'd say go do whatever you want with it;
+**       but it would be polite to give credit to the following people
+**       if you use this anywhere:
+**           Euler     - probable inventor of the fourier transform.
+**           Gauss     - probable inventor of the FFT.
+**           Hartley   - probable inventor of the hartley transform.
+**           Buneman   - for a really cool trig generator
+**           Mayer(me) - for authoring this particular version and
+**                       including all the optimizations in one package.
+**       Thanks,
+**       Ron Mayer; mayer@acuson.com
+**
+*/
+
+#include "fftmayer.h"
+
+#define GOOD_TRIG
+#define REAL r_4
+#include "trigtbl.h"
+
+char fht_r4_version[] = "Brcwl-Hrtly-Ron-dbld";
+
+#define SQRT2_2   0.70710678118654752440084436210484
+#define SQRT2   2*0.70710678118654752440084436210484
+
+void fht_r4(r_4 *fz,int n)
+{
+ r_4 a,b;
+ r_4 c1,s1,s2,c2,s3,c3,s4,c4;
+ r_4 f0,g0,f1,g1,f2,g2,f3,g3;
+ int i,k,k1,k2,k3,k4,kx;
+ r_4 *fi,*fn,*gi;
+ TRIG_VARS;
+
+ for (k1=1,k2=0;k1<n;k1++)
+    {
+     r_4 a;
+     for (k=n>>1; (!((k2^=k)&k)); k>>=1);
+     if (k1>k2)
+	{
+	     a=fz[k1];fz[k1]=fz[k2];fz[k2]=a;
+	}
+    }
+ for ( k=0 ; (1<<k)<n ; k++ );
+ k  &= 1;
+ if (k==0)
+    {
+	 for (fi=fz,fn=fz+n;fi<fn;fi+=4)
+	    {
+	     r_4 f0,f1,f2,f3;
+	     f1     = fi[0 ]-fi[1 ];
+	     f0     = fi[0 ]+fi[1 ];
+	     f3     = fi[2 ]-fi[3 ];
+	     f2     = fi[2 ]+fi[3 ];
+	     fi[2 ] = (f0-f2);	
+	     fi[0 ] = (f0+f2);
+	     fi[3 ] = (f1-f3);	
+	     fi[1 ] = (f1+f3);
+	    }
+    }
+ else
+    {
+	 for (fi=fz,fn=fz+n,gi=fi+1;fi<fn;fi+=8,gi+=8)
+	    {
+	     r_4 s1,c1,s2,c2,s3,c3,s4,c4,g0,f0,f1,g1,f2,g2,f3,g3;
+	     c1     = fi[0 ] - gi[0 ];
+	     s1     = fi[0 ] + gi[0 ];
+	     c2     = fi[2 ] - gi[2 ];
+	     s2     = fi[2 ] + gi[2 ];
+	     c3     = fi[4 ] - gi[4 ];
+	     s3     = fi[4 ] + gi[4 ];
+	     c4     = fi[6 ] - gi[6 ];
+	     s4     = fi[6 ] + gi[6 ];
+	     f1     = (s1 - s2);	
+	     f0     = (s1 + s2);
+	     g1     = (c1 - c2);	
+	     g0     = (c1 + c2);
+	     f3     = (s3 - s4);	
+	     f2     = (s3 + s4);
+	     g3     = SQRT2*c4;		
+	     g2     = SQRT2*c3;
+	     fi[4 ] = f0 - f2;
+	     fi[0 ] = f0 + f2;
+	     fi[6 ] = f1 - f3;
+	     fi[2 ] = f1 + f3;
+	     gi[4 ] = g0 - g2;
+	     gi[0 ] = g0 + g2;
+	     gi[6 ] = g1 - g3;
+	     gi[2 ] = g1 + g3;
+	    }
+    }
+ if (n<16) return;
+
+ do
+    {
+     r_4 s1,c1;
+     k  += 2;
+     k1  = 1  << k;
+     k2  = k1 << 1;
+     k4  = k2 << 1;
+     k3  = k2 + k1;
+     kx  = k1 >> 1;
+	 fi  = fz;
+	 gi  = fi + kx;
+	 fn  = fz + n;
+	 do
+	    {
+	     r_4 g0,f0,f1,g1,f2,g2,f3,g3;
+	     f1      = fi[0 ] - fi[k1];
+	     f0      = fi[0 ] + fi[k1];
+	     f3      = fi[k2] - fi[k3];
+	     f2      = fi[k2] + fi[k3];
+	     fi[k2]  = f0	  - f2;
+	     fi[0 ]  = f0	  + f2;
+	     fi[k3]  = f1	  - f3;
+	     fi[k1]  = f1	  + f3;
+	     g1      = gi[0 ] - gi[k1];
+	     g0      = gi[0 ] + gi[k1];
+	     g3      = SQRT2  * gi[k3];
+	     g2      = SQRT2  * gi[k2];
+	     gi[k2]  = g0	  - g2;
+	     gi[0 ]  = g0	  + g2;
+	     gi[k3]  = g1	  - g3;
+	     gi[k1]  = g1	  + g3;
+	     gi     += k4;
+	     fi     += k4;
+	    } while (fi<fn);
+     TRIG_INIT(k,c1,s1);
+     for (i=1;i<kx;i++)
+        {
+	 r_4 c2,s2;
+         TRIG_NEXT(k,c1,s1);
+         c2 = c1*c1 - s1*s1;
+         s2 = 2*(c1*s1);
+	     fn = fz + n;
+	     fi = fz +i;
+	     gi = fz +k1-i;
+	     do
+		{
+		 r_4 a,b,g0,f0,f1,g1,f2,g2,f3,g3;
+		 b       = s2*fi[k1] - c2*gi[k1];
+		 a       = c2*fi[k1] + s2*gi[k1];
+		 f1      = fi[0 ]    - a;
+		 f0      = fi[0 ]    + a;
+		 g1      = gi[0 ]    - b;
+		 g0      = gi[0 ]    + b;
+		 b       = s2*fi[k3] - c2*gi[k3];
+		 a       = c2*fi[k3] + s2*gi[k3];
+		 f3      = fi[k2]    - a;
+		 f2      = fi[k2]    + a;
+		 g3      = gi[k2]    - b;
+		 g2      = gi[k2]    + b;
+		 b       = s1*f2     - c1*g3;
+		 a       = c1*f2     + s1*g3;
+		 fi[k2]  = f0        - a;
+		 fi[0 ]  = f0        + a;
+		 gi[k3]  = g1        - b;
+		 gi[k1]  = g1        + b;
+		 b       = c1*g2     - s1*f3;
+		 a       = s1*g2     + c1*f3;
+		 gi[k2]  = g0        - a;
+		 gi[0 ]  = g0        + a;
+		 fi[k3]  = f1        - b;
+		 fi[k1]  = f1        + b;
+		 gi     += k4;
+		 fi     += k4;
+		} while (fi<fn);
+        }
+     TRIG_RESET(k,c1,s1);
+    } while (k4<n);
+}
+
+
+void ifft_r4(int n, r_4 *real, r_4 *imag)
+{
+ r_4 a,b,c,d;
+ r_4 q,r,s,t;
+ int i,j,k;
+ fht_r4(real,n);
+ fht_r4(imag,n);
+ for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
+  a = real[i]; b = real[j];  q=a+b; r=a-b;
+  c = imag[i]; d = imag[j];  s=c+d; t=c-d;
+  imag[i] = (s+r)*0.5;  imag[j] = (s-r)*0.5;
+  real[i] = (q-t)*0.5;  real[j] = (q+t)*0.5;
+ }
+}
+
+void realfft_r4(int n, r_4 *real)
+{
+ r_4 a,b,c,d;
+ int i,j,k;
+ fht_r4(real,n);
+ for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
+  a = real[i];
+  b = real[j];
+  real[j] = (a-b)*0.5;
+  real[i] = (a+b)*0.5;
+ }
+}
+
+void fft_r4(int n, r_4 *real,r_4 *imag)
+{
+ r_4 a,b,c,d;
+ r_4 q,r,s,t;
+ int i,j,k;
+ for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
+  a = real[i]; b = real[j];  q=a+b; r=a-b;
+  c = imag[i]; d = imag[j];  s=c+d; t=c-d;
+  real[i] = (q+t)*.5; real[j] = (q-t)*.5;
+  imag[i] = (s-r)*.5; imag[j] = (s+r)*.5;
+ }
+ fht_r4(real,n);
+ fht_r4(imag,n);
+}
+
+void realifft_r4(int n,r_4 *real)
+{
+ r_4 a,b,c,d;
+ int i,j,k;
+ for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
+  a = real[i];
+  b = real[j];
+  real[j] = (a-b);
+  real[i] = (a+b);
+ }
+ fht_r4(real,n);
+}
Index: /tags/V_Dec2002/SophyaLib/NTools/fftmayer_r8.c
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/fftmayer_r8.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/fftmayer_r8.c	(revision 2309)
@@ -0,0 +1,259 @@
+/*
+** FFT and FHT routines
+**  Copyright 1988, 1993; Ron Mayer
+**  
+**  fht(fz,n);
+**      Does a hartley transform of "n" points in the array "fz".
+**  fft(n,real,imag)
+**      Does a fourier transform of "n" points of the "real" and
+**      "imag" arrays.
+**  ifft(n,real,imag)
+**      Does an inverse fourier transform of "n" points of the "real"
+**      and "imag" arrays.
+**  realfft(n,real)
+**      Does a real-valued fourier transform of "n" points of the
+**      "real" array. The real part of the transform ends
+**      up in the first half of the array and the imaginary part of the
+**      transform ends up in the second half of the array.
+**  realifft(n,real)
+**      The inverse of the realfft() routine above.
+**      
+**      
+** NOTE: This routine uses at least 2 patented algorithms, and may be
+**       under the restrictions of a bunch of different organizations.
+**       Although I wrote it completely myself; it is kind of a derivative
+**       of a routine I once authored and released under the GPL, so it
+**       may fall under the free software foundation's restrictions;
+**       it was worked on as a Stanford Univ project, so they claim
+**       some rights to it; it was further optimized at work here, so
+**       I think this company claims parts of it.  The patents are
+**       held by R. Bracewell (the FHT algorithm) and O. Buneman (the
+**       trig generator), both at Stanford Univ.
+**       If it were up to me, I'd say go do whatever you want with it;
+**       but it would be polite to give credit to the following people
+**       if you use this anywhere:
+**           Euler     - probable inventor of the fourier transform.
+**           Gauss     - probable inventor of the FFT.
+**           Hartley   - probable inventor of the hartley transform.
+**           Buneman   - for a really cool trig generator
+**           Mayer(me) - for authoring this particular version and
+**                       including all the optimizations in one package.
+**       Thanks,
+**       Ron Mayer; mayer@acuson.com
+**
+*/
+
+#include "fftmayer.h"
+
+#define GOOD_TRIG
+#define REAL r_8
+#include "trigtbl.h"
+
+char fht_r8_version[] = "Brcwl-Hrtly-Ron-dbld";
+
+#define SQRT2_2   0.70710678118654752440084436210484
+#define SQRT2   2*0.70710678118654752440084436210484
+
+void fht_r8(r_8 *fz,int n)
+{
+ r_8 a,b;
+ r_8 c1,s1,s2,c2,s3,c3,s4,c4;
+ r_8 f0,g0,f1,g1,f2,g2,f3,g3;
+ int i,k,k1,k2,k3,k4,kx;
+ r_8 *fi,*fn,*gi;
+ TRIG_VARS;
+
+ for (k1=1,k2=0;k1<n;k1++)
+    {
+     r_8 a;
+     for (k=n>>1; (!((k2^=k)&k)); k>>=1);
+     if (k1>k2)
+	{
+	     a=fz[k1];fz[k1]=fz[k2];fz[k2]=a;
+	}
+    }
+ for ( k=0 ; (1<<k)<n ; k++ );
+ k  &= 1;
+ if (k==0)
+    {
+	 for (fi=fz,fn=fz+n;fi<fn;fi+=4)
+	    {
+	     r_8 f0,f1,f2,f3;
+	     f1     = fi[0 ]-fi[1 ];
+	     f0     = fi[0 ]+fi[1 ];
+	     f3     = fi[2 ]-fi[3 ];
+	     f2     = fi[2 ]+fi[3 ];
+	     fi[2 ] = (f0-f2);	
+	     fi[0 ] = (f0+f2);
+	     fi[3 ] = (f1-f3);	
+	     fi[1 ] = (f1+f3);
+	    }
+    }
+ else
+    {
+	 for (fi=fz,fn=fz+n,gi=fi+1;fi<fn;fi+=8,gi+=8)
+	    {
+	     r_8 s1,c1,s2,c2,s3,c3,s4,c4,g0,f0,f1,g1,f2,g2,f3,g3;
+	     c1     = fi[0 ] - gi[0 ];
+	     s1     = fi[0 ] + gi[0 ];
+	     c2     = fi[2 ] - gi[2 ];
+	     s2     = fi[2 ] + gi[2 ];
+	     c3     = fi[4 ] - gi[4 ];
+	     s3     = fi[4 ] + gi[4 ];
+	     c4     = fi[6 ] - gi[6 ];
+	     s4     = fi[6 ] + gi[6 ];
+	     f1     = (s1 - s2);	
+	     f0     = (s1 + s2);
+	     g1     = (c1 - c2);	
+	     g0     = (c1 + c2);
+	     f3     = (s3 - s4);	
+	     f2     = (s3 + s4);
+	     g3     = SQRT2*c4;		
+	     g2     = SQRT2*c3;
+	     fi[4 ] = f0 - f2;
+	     fi[0 ] = f0 + f2;
+	     fi[6 ] = f1 - f3;
+	     fi[2 ] = f1 + f3;
+	     gi[4 ] = g0 - g2;
+	     gi[0 ] = g0 + g2;
+	     gi[6 ] = g1 - g3;
+	     gi[2 ] = g1 + g3;
+	    }
+    }
+ if (n<16) return;
+
+ do
+    {
+     r_8 s1,c1;
+     k  += 2;
+     k1  = 1  << k;
+     k2  = k1 << 1;
+     k4  = k2 << 1;
+     k3  = k2 + k1;
+     kx  = k1 >> 1;
+	 fi  = fz;
+	 gi  = fi + kx;
+	 fn  = fz + n;
+	 do
+	    {
+	     r_8 g0,f0,f1,g1,f2,g2,f3,g3;
+	     f1      = fi[0 ] - fi[k1];
+	     f0      = fi[0 ] + fi[k1];
+	     f3      = fi[k2] - fi[k3];
+	     f2      = fi[k2] + fi[k3];
+	     fi[k2]  = f0	  - f2;
+	     fi[0 ]  = f0	  + f2;
+	     fi[k3]  = f1	  - f3;
+	     fi[k1]  = f1	  + f3;
+	     g1      = gi[0 ] - gi[k1];
+	     g0      = gi[0 ] + gi[k1];
+	     g3      = SQRT2  * gi[k3];
+	     g2      = SQRT2  * gi[k2];
+	     gi[k2]  = g0	  - g2;
+	     gi[0 ]  = g0	  + g2;
+	     gi[k3]  = g1	  - g3;
+	     gi[k1]  = g1	  + g3;
+	     gi     += k4;
+	     fi     += k4;
+	    } while (fi<fn);
+     TRIG_INIT(k,c1,s1);
+     for (i=1;i<kx;i++)
+        {
+	 r_8 c2,s2;
+         TRIG_NEXT(k,c1,s1);
+         c2 = c1*c1 - s1*s1;
+         s2 = 2*(c1*s1);
+	     fn = fz + n;
+	     fi = fz +i;
+	     gi = fz +k1-i;
+	     do
+		{
+		 r_8 a,b,g0,f0,f1,g1,f2,g2,f3,g3;
+		 b       = s2*fi[k1] - c2*gi[k1];
+		 a       = c2*fi[k1] + s2*gi[k1];
+		 f1      = fi[0 ]    - a;
+		 f0      = fi[0 ]    + a;
+		 g1      = gi[0 ]    - b;
+		 g0      = gi[0 ]    + b;
+		 b       = s2*fi[k3] - c2*gi[k3];
+		 a       = c2*fi[k3] + s2*gi[k3];
+		 f3      = fi[k2]    - a;
+		 f2      = fi[k2]    + a;
+		 g3      = gi[k2]    - b;
+		 g2      = gi[k2]    + b;
+		 b       = s1*f2     - c1*g3;
+		 a       = c1*f2     + s1*g3;
+		 fi[k2]  = f0        - a;
+		 fi[0 ]  = f0        + a;
+		 gi[k3]  = g1        - b;
+		 gi[k1]  = g1        + b;
+		 b       = c1*g2     - s1*f3;
+		 a       = s1*g2     + c1*f3;
+		 gi[k2]  = g0        - a;
+		 gi[0 ]  = g0        + a;
+		 fi[k3]  = f1        - b;
+		 fi[k1]  = f1        + b;
+		 gi     += k4;
+		 fi     += k4;
+		} while (fi<fn);
+        }
+     TRIG_RESET(k,c1,s1);
+    } while (k4<n);
+}
+
+
+void ifft_r8(int n, r_8 *real, r_8 *imag)
+{
+ r_8 a,b,c,d;
+ r_8 q,r,s,t;
+ int i,j,k;
+ fht_r8(real,n);
+ fht_r8(imag,n);
+ for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
+  a = real[i]; b = real[j];  q=a+b; r=a-b;
+  c = imag[i]; d = imag[j];  s=c+d; t=c-d;
+  imag[i] = (s+r)*0.5;  imag[j] = (s-r)*0.5;
+  real[i] = (q-t)*0.5;  real[j] = (q+t)*0.5;
+ }
+}
+
+void realfft_r8(int n, r_8 *real)
+{
+ r_8 a,b,c,d;
+ int i,j,k;
+ fht_r8(real,n);
+ for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
+  a = real[i];
+  b = real[j];
+  real[j] = (a-b)*0.5;
+  real[i] = (a+b)*0.5;
+ }
+}
+
+void fft_r8(int n, r_8 *real,r_8 *imag)
+{
+ r_8 a,b,c,d;
+ r_8 q,r,s,t;
+ int i,j,k;
+ for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
+  a = real[i]; b = real[j];  q=a+b; r=a-b;
+  c = imag[i]; d = imag[j];  s=c+d; t=c-d;
+  real[i] = (q+t)*.5; real[j] = (q-t)*.5;
+  imag[i] = (s-r)*.5; imag[j] = (s+r)*.5;
+ }
+ fht_r8(real,n);
+ fht_r8(imag,n);
+}
+
+void realifft_r8(int n,r_8 *real)
+{
+ r_8 a,b,c,d;
+ int i,j,k;
+ for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
+  a = real[i];
+  b = real[j];
+  real[j] = (a-b);
+  real[i] = (a+b);
+ }
+ fht_r8(real,n);
+}
Index: /tags/V_Dec2002/SophyaLib/NTools/fftmserver.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/fftmserver.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/fftmserver.cc	(revision 2309)
@@ -0,0 +1,398 @@
+#include "fftmserver.h"
+#include <iostream.h>
+#include "fftmayer.h"
+
+
+/* --Methode-- */
+FFTMayerServer::FFTMayerServer()
+   : FFTServerInterface("FFTMayerServer using extended FFTMayer package")
+  , ckR4("FFTMayerServer: ", true, true) , ckR8("FFTMayerServer: ", true, true)
+
+{
+}
+
+/* --Methode-- */
+FFTMayerServer::~FFTMayerServer()
+{
+}
+
+/* --Methode-- */
+FFTServerInterface * FFTMayerServer::Clone()
+{
+  return (new FFTMayerServer);
+}
+
+
+/* --Methode-- */
+void FFTMayerServer::FFTForward(TArray< complex<r_8> > const & ina, TArray< complex<r_8> > & outa)
+{
+ ckR8.CheckResize(ina, outa);
+ TVector< complex<r_8> > in(ina);
+ TVector< complex<r_8> > out(outa);
+
+ r_8 a,b,c,d;
+ r_8 q,r,s,t;
+ int i,j,k;
+ int n = in.NElts();
+ if (checkLength(n))  {
+   char buff[256];
+   sprintf(buff, "FFTMayerServer::FFTForward/Error Size(%d) != 2^n ! (File=%s Line=%d)",
+	   n, __FILE__,__LINE__);
+   throw ParmError(string(buff));
+ }
+ TVector< r_8 > inoutre(n);
+ TVector< r_8 > inoutim(n);
+ inoutre(0) = in(0).real();
+ inoutim(0) = in(0).imag();
+ inoutre(n/2) = in(n/2).real();
+ inoutim(n/2) = in(n/2).imag();
+ if (n > 2) {
+   inoutre(n/2+1) = in(n/2).real();
+   inoutim(n/2+1) = in(n/2).imag();
+ }
+ for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
+  a = in(i).real(); b = in(j).real();  q=a+b; r=a-b;
+  c = in(i).imag(); d = in(j).imag();  s=c+d; t=c-d;
+  inoutre(i) = (q+t)*.5; inoutre(j) = (q-t)*.5;
+  inoutim(i) = (s-r)*.5; inoutim(j) = (s+r)*.5;
+ }
+ fht_r8(inoutre.Data(),inoutre.NElts());
+ fht_r8(inoutim.Data(),inoutim.NElts());
+
+ // out.ReSize(in.NElts());
+ r_8 fn = 1./n;
+ if (getNormalize()) 
+   for(k=0; k<out.NElts(); k++)
+     out(k) = complex<r_8>(inoutre(k)*fn, inoutim(k)*fn);
+ else 
+   for(k=0; k<out.NElts(); k++)
+     out(k) = complex<r_8>(inoutre(k), inoutim(k));
+}
+
+/* --Methode-- */
+void FFTMayerServer::FFTBackward(TArray< complex<r_8> > const & ina, TArray< complex<r_8> > & outa)
+{
+ ckR8.CheckResize(ina, outa);
+ TVector< complex<r_8> > in(ina);
+ TVector< complex<r_8> > out(outa);
+
+ r_8 a,b,c,d;
+ r_8 q,r,s,t;
+ int i,j,k;
+ int n = in.NElts();
+ if (checkLength(n))  {
+   char buff[256];
+   sprintf(buff, "FFTMayerServer::FFTBackward/Error Size(%d) != 2^n ! (File=%s Line=%d)",
+	   n, __FILE__,__LINE__);
+   throw ParmError(string(buff));
+ }
+ TVector< r_8 > inoutre(n);
+ TVector< r_8 > inoutim(n);
+ for(k=0; k<out.NElts(); k++) {
+   inoutre(k) = in(k).real();
+   inoutim(k) = in(k).imag();
+ }
+ fht_r8(inoutre.Data(),inoutre.NElts());
+ fht_r8(inoutim.Data(),inoutim.NElts());
+
+ // out.ReSize(in.NElts());
+ out(0) = complex<r_8>(inoutre(0), inoutim(0));
+ out(n/2) = complex<r_8>(inoutre(n/2), inoutim(n/2));
+ if (n > 2) out(n/2+1) = complex<r_8>(inoutre(n/2+1), inoutim(n/2+1));
+
+ for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
+  a = inoutre(i); b = inoutre(j);  q=a+b; r=a-b;
+  c = inoutim(i); d = inoutim(j);  s=c+d; t=c-d;
+  out(i) = complex<r_8>( (q-t)*0.5 , (s+r)*0.5 );
+  out(j) = complex<r_8>( (q+t)*0.5 , (s-r)*0.5 );
+ }
+
+}
+
+/* --Methode-- */
+void FFTMayerServer::FFTForward(TArray< complex<r_4> > const & ina, TArray< complex<r_4> > & outa)
+{
+ ckR4.CheckResize(ina, outa);
+ TVector< complex<r_4> > in(ina);
+ TVector< complex<r_4> > out(outa);
+
+ r_4 a,b,c,d;
+ r_4 q,r,s,t;
+ int i,j,k;
+ int n = in.NElts();
+ if (checkLength(n))  {
+   char buff[256];
+   sprintf(buff, "FFTMayerServer::FFTForward/Error Size(%d) != 2^n ! (File=%s Line=%d)",
+	   n, __FILE__,__LINE__);
+   throw ParmError(string(buff));
+ }
+ TVector< r_4 > inoutre(n);
+ TVector< r_4 > inoutim(n);
+ inoutre(0) = in(0).real();
+ inoutim(0) = in(0).imag();
+ inoutre(n/2) = in(n/2).real();
+ inoutim(n/2) = in(n/2).imag();
+ if (n > 2) {
+   inoutre(n/2+1) = in(n/2).real();
+   inoutim(n/2+1) = in(n/2).imag();
+ }
+ for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
+  a = in(i).real(); b = in(j).real();  q=a+b; r=a-b;
+  c = in(i).imag(); d = in(j).imag();  s=c+d; t=c-d;
+  inoutre(i) = (q+t)*.5; inoutre(j) = (q-t)*.5;
+  inoutim(i) = (s-r)*.5; inoutim(j) = (s+r)*.5;
+ }
+ fht_r4(inoutre.Data(),inoutre.NElts());
+ fht_r4(inoutim.Data(),inoutim.NElts());
+
+ // out.ReSize(in.NElts());
+ r_4 fn = 1./n;
+ if (getNormalize()) 
+   for(k=0; k<out.NElts(); k++)
+     out(k) = complex<r_4>(inoutre(k)*fn, inoutim(k)*fn);
+ else 
+   for(k=0; k<out.NElts(); k++)
+     out(k) = complex<r_4>(inoutre(k), inoutim(k));
+
+}
+
+/* --Methode-- */
+void FFTMayerServer::FFTBackward(TArray< complex<r_4> > const & ina, TArray< complex<r_4> > & outa)
+{
+ ckR4.CheckResize(ina, outa);
+ TVector< complex<r_4> > in(ina);
+ TVector< complex<r_4> > out(outa);
+
+ r_4 a,b,c,d;
+ r_4 q,r,s,t;
+ int i,j,k;
+ int n = in.NElts();
+ if (checkLength(n))  {
+   char buff[256];
+   sprintf(buff, "FFTMayerServer::FFTBackward/Error Size(%d) != 2^n ! (File=%s Line=%d)",
+	   n, __FILE__,__LINE__);
+   throw ParmError(string(buff));
+ }
+
+ TVector< r_4 > inoutre(n);
+ TVector< r_4 > inoutim(n);
+ for(k=0; k<out.NElts(); k++) {
+   inoutre(k) = in(k).real();
+   inoutim(k) = in(k).imag();
+ }
+ fht_r4(inoutre.Data(),inoutre.NElts());
+ fht_r4(inoutim.Data(),inoutim.NElts());
+
+ // out.ReSize(in.NElts());
+ out(0) = complex<r_4>(inoutre(0), inoutim(0));
+ out(n/2) = complex<r_4>(inoutre(n/2), inoutim(n/2));
+ if (n > 2) out(n/2+1) = complex<r_4>(inoutre(n/2+1), inoutim(n/2+1));
+
+ for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
+  a = inoutre(i); b = inoutre(j);  q=a+b; r=a-b;
+  c = inoutim(i); d = inoutim(j);  s=c+d; t=c-d;
+  out(i) = complex<r_4>( (q-t)*0.5 , (s+r)*0.5 );
+  out(j) = complex<r_4>( (q+t)*0.5 , (s-r)*0.5 );
+ }
+
+}
+
+/* --Methode-- */
+void FFTMayerServer::FFTForward(TArray< r_4 > const & ina, TArray< complex<r_4> > & outa)
+{
+ ckR4.CheckResize(ina, outa);
+ TVector< r_4 > in(ina);
+ TVector< complex<r_4> > out(outa);
+
+ r_4 a,b;
+ int i,j,k;
+ int n = in.NElts();
+ if (checkLength(n))  {
+   char buff[256];
+   sprintf(buff, "FFTMayerServer::FFTForward/Error Size(%d) != 2^n ! (File=%s Line=%d)",
+	   n, __FILE__,__LINE__);
+   throw ParmError(string(buff));
+ }
+
+ TVector< r_4 > inout(in);
+ fht_r4(inout.Data(),inout.NElts());
+ for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
+  a = inout(i);  
+  b = inout(j);
+  inout(j) = (a-b)*0.5;
+  inout(i) = (a+b)*0.5;
+  out(i) = complex<r_4>( (a+b)*0.5 , (a-b)*0.5 );
+ }
+
+  
+ // out.ReSize(n/2+1);
+ out(0) = complex<r_4>(inout(0), 0.);
+
+ if (n%2 == 0) { // n pair
+   for (i=1,j=n/2+1; i<n/2; i++,j++) 
+     out(i) = complex<r_4>(inout(i), inout(j));
+
+   out(n/2) = complex<r_4>(inout(n/2), 0.);
+ }
+ else { // n impair
+   for (i=1,j=n/2+2; i<n/2; i++,j++) 
+     out(i) = complex<r_4>(inout(i), inout(j));
+
+   out(n/2) = complex<r_4>(inout(n/2), inout(n/2+1));
+ }
+
+ if (getNormalize()) out *= (1./(r_4)(in.NElts()));
+}
+
+/* --Methode-- */
+void FFTMayerServer::FFTBackward(TArray< complex<r_4> > const & ina, TArray< r_4 > & outa,
+				 bool usoutsz)
+{
+ ckR4.CheckResize(ina, outa);
+ TVector< complex<r_4> > in(ina);
+ TVector< r_4 > out(outa);
+
+ r_4 a,b;
+ int i,j,k;
+ int n = in.NElts();
+ int nc = (fabs(in(n-1).imag()) < 1.e-9) ? nc = n*2-2 : nc = n*2-1;
+ if (checkLength(nc))  {
+   char buff[256];
+   sprintf(buff, "FFTMayerServer::FFTBackward/Error Size(%d) != 2^n ! (File=%s Line=%d)",
+	   nc, __FILE__,__LINE__);
+   throw ParmError(string(buff));
+ }
+
+ // out.ReSize(nc);
+ out(0) = in(0).real();
+ if (nc%2 == 0) { // nc pair
+   for (i=1,j=nc/2+1; i<nc/2; i++,j++) {
+     out(i) = in(i).real();
+     out(j) = in(i).imag();
+   }
+   out(nc/2) = in(nc/2).real();
+ }
+ else { // nc impair
+   for (i=1,j=nc/2+2; i<nc/2; i++,j++) {
+     out(i) = in(i).real();
+     out(j) = in(i).imag();
+   }
+   out(nc/2) = in(nc/2).real();
+   out(nc/2+1) = in(nc/2).imag();
+ }
+
+ for (i=1,j=nc-1,k=nc/2;i<k;i++,j--) {
+  a = out(i);
+  b = out(j);
+  out(j) = (a-b);
+  out(i) = (a+b);
+ }
+ fht_r4(out.Data(),out.NElts());
+}
+
+
+/* --Methode-- */
+void FFTMayerServer::FFTForward(TArray< r_8 > const & ina, TArray< complex<r_8> > & outa)
+{
+ ckR8.CheckResize(ina, outa);
+ TVector< r_8 > in(ina);
+ TVector< complex<r_8> > out(outa);
+
+ r_8 a,b;
+ int i,j,k;
+ int n = in.NElts();
+ if (checkLength(n))  {
+   char buff[256];
+   sprintf(buff, "FFTMayerServer::FFTForward/Error Size(%d) != 2^n ! (File=%s Line=%d)",
+	   n, __FILE__,__LINE__);
+   throw ParmError(string(buff));
+ }
+
+ TVector< r_8 > inout(in);
+ fht_r8(inout.Data(),inout.NElts());
+ for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
+  a = inout(i);  
+  b = inout(j);
+  inout(j) = (a-b)*0.5;
+  inout(i) = (a+b)*0.5;
+  out(i) = complex<r_8>( (a+b)*0.5 , (a-b)*0.5 );
+ }
+
+  
+ // out.ReSize(n/2+1);
+ out(0) = complex<r_8>(inout(0), 0.);
+
+ if (n%2 == 0) { // n pair
+   for (i=1,j=n/2+1; i<n/2; i++,j++) 
+     out(i) = complex<r_8>(inout(i), inout(j));
+
+   out(n/2) = complex<r_8>(inout(n/2), 0.);
+ }
+ else { // n impair
+   for (i=1,j=n/2+2; i<n/2; i++,j++) 
+     out(i) = complex<r_8>(inout(i), inout(j));
+
+   out(n/2) = complex<r_8>(inout(n/2), inout(n/2+1));
+ }
+ if (getNormalize()) out *= (1./(r_4)(in.NElts()));
+}
+
+/* --Methode-- */
+void FFTMayerServer::FFTBackward(TArray< complex<r_8> > const & ina, TArray< r_8 > & outa,
+				 bool usoutsz)
+{
+ ckR8.CheckResize(ina, outa);
+ TVector< r_8 > out(outa);
+ TVector< complex<r_8> > in(ina);
+
+ r_8 a,b;
+ int i,j,k;
+ int n = in.NElts();
+ int nc = (fabs(in(n-1).imag()) < 1.e-18) ? nc = n*2-2 : nc = n*2-1;
+ if (checkLength(nc))  {
+   char buff[256];
+   sprintf(buff, "FFTMayerServer::FFTBackward/Error Size(%d) != 2^n ! (File=%s Line=%d)",
+	   nc, __FILE__,__LINE__);
+   throw ParmError(string(buff));
+ }
+
+ // out.ReSize(nc);
+ out(0) = in(0).real();
+ if (nc%2 == 0) { // nc pair
+   for (i=1,j=nc/2+1; i<nc/2; i++,j++) {
+     out(i) = in(i).real();
+     out(j) = in(i).imag();
+   }
+   out(nc/2) = in(nc/2).real();
+ }
+ else { // nc impair
+   for (i=1,j=nc/2+2; i<nc/2; i++,j++) {
+     out(i) = in(i).real();
+     out(j) = in(i).imag();
+   }
+   out(nc/2) = in(nc/2).real();
+   out(nc/2+1) = in(nc/2).imag();
+ }
+
+ for (i=1,j=nc-1,k=nc/2;i<k;i++,j--) {
+  a = out(i);
+  b = out(j);
+  out(j) = (a-b);
+  out(i) = (a+b);
+ }
+ fht_r8(out.Data(),out.NElts());
+}
+
+
+
+/* --Methode-- */
+bool FFTMayerServer::checkLength(int n)
+{
+  if (n < 2) return(true);
+  int nc = n;
+  while (nc > 1) {
+    if (nc%2 != 0)  return(true);
+    nc /= 2;
+  }
+  return(false);
+}
Index: /tags/V_Dec2002/SophyaLib/NTools/fftmserver.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/fftmserver.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/fftmserver.h	(revision 2309)
@@ -0,0 +1,47 @@
+#ifndef  FFTMServer_H_SEEN
+#define  FFTMServer_H_SEEN
+
+#include "fftservintf.h"
+
+// implementation de FFTServerInterface en utilisant FFTPack 
+
+namespace SOPHYA {
+
+class FFTMayerServer : public FFTServerInterface {
+ public:
+  FFTMayerServer();
+  virtual ~FFTMayerServer();
+
+  // Implementation de l'interface FFTServerInterface
+
+  virtual FFTServerInterface * Clone();
+
+  // Transforme unidimensionnel sur des doubles
+  virtual void FFTForward(TArray< complex<r_8> > const & in, TArray< complex<r_8> > & out);
+  virtual void FFTBackward(TArray< complex<r_8> > const & in, TArray< complex<r_8> > & out);
+  virtual void FFTForward(TArray< r_8 > const & in, TArray< complex<r_8> > & out);
+  virtual void FFTBackward(TArray< complex<r_8> > const & in, TArray< r_8 > & out,
+			   bool usoutsz=false);
+
+
+  // Transforme unidimensionnel sur des float
+  virtual void FFTForward(TArray< complex<r_4> > const & in, TArray< complex<r_4> > & out);
+  virtual void FFTBackward(TArray< complex<r_4> > const & in, TArray< complex<r_4> > & out);
+  virtual void FFTForward(TArray< r_4 > const & in, TArray< complex<r_4> > & out);
+  virtual void FFTBackward(TArray< complex<r_4> > const & in, TArray< r_4 > & out,
+			   bool usoutsz=false);
+
+
+protected:
+  virtual bool checkLength(int n);
+
+  FFTArrayChecker<r_4> ckR4;
+  FFTArrayChecker<r_8> ckR8;
+};
+
+} // Fin du namespace
+
+
+
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/fftpackc.c
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/fftpackc.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/fftpackc.c	(revision 2309)
@@ -0,0 +1,8890 @@
+/* fftpackc.c is the fortran FFTPACK package retrieved from netlib */
+
+/* allf.f -- translated by f2c (version 19970805).
+   You must link the resulting object file with the libraries:
+	-lf2c -lm   (in that order)
+*/
+
+/* #include "f2c.h" -- Remplace par ce qui suit */
+#include "fftpackc.h"
+#include <math.h>
+
+/*  ------ File cfftb.f ------ */
+/* Subroutine */ int cfftb_(int_4 *n, r_4 *c__, r_4 *wsave)
+{
+    extern /* Subroutine */ int cfftb1_(int_4 *, r_4 *, r_4 *, r_4 *, 
+	    int_4 *);
+    static int_4 iw1, iw2;
+
+    /* Parameter adjustments */
+    --wsave;
+    --c__;
+
+    /* Function Body */
+    if (*n == 1) {
+	return 0;
+    }
+    iw1 = *n + *n + 1;
+    iw2 = iw1 + *n + *n;
+    cfftb1_(n, &c__[1], &wsave[1], &wsave[iw1], (int_4 *)&wsave[iw2]);  /* (int *) ajoute - Reza 29/11/99 */
+    return 0;
+} /* cfftb_ */
+
+/*  ------ File cfftb1.f ------ */
+/* Subroutine */ int cfftb1_(int_4 *n, r_4 *c__, r_4 *ch, r_4 *wa, 
+	int_4 *ifac)
+{
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Local variables */
+    static int_4 idot, i__;
+    extern /* Subroutine */ int passb_(int_4 *, int_4 *, int_4 *, 
+	    int_4 *, int_4 *, r_4 *, r_4 *, r_4 *, r_4 *, r_4 *, 
+	    r_4 *);
+    static int_4 k1, l1, l2, n2;
+    extern /* Subroutine */ int passb2_(int_4 *, int_4 *, r_4 *, r_4 *, 
+	    r_4 *), passb3_(int_4 *, int_4 *, r_4 *, r_4 *, r_4 *, 
+	    r_4 *), passb4_(int_4 *, int_4 *, r_4 *, r_4 *, r_4 *, 
+	    r_4 *, r_4 *), passb5_(int_4 *, int_4 *, r_4 *, r_4 *, 
+	    r_4 *, r_4 *, r_4 *, r_4 *);
+    static int_4 na, nf, ip, iw, ix2, ix3, ix4, nac, ido, idl1;
+
+    /* Parameter adjustments */
+    --ifac;
+    --wa;
+    --ch;
+    --c__;
+
+    /* Function Body */
+    nf = ifac[2];
+    na = 0;
+    l1 = 1;
+    iw = 1;
+    i__1 = nf;
+    for (k1 = 1; k1 <= i__1; ++k1) {
+	ip = ifac[k1 + 2];
+	l2 = ip * l1;
+	ido = *n / l2;
+	idot = ido + ido;
+	idl1 = idot * l1;
+	if (ip != 4) {
+	    goto L103;
+	}
+	ix2 = iw + idot;
+	ix3 = ix2 + idot;
+	if (na != 0) {
+	    goto L101;
+	}
+	passb4_(&idot, &l1, &c__[1], &ch[1], &wa[iw], &wa[ix2], &wa[ix3]);
+	goto L102;
+L101:
+	passb4_(&idot, &l1, &ch[1], &c__[1], &wa[iw], &wa[ix2], &wa[ix3]);
+L102:
+	na = 1 - na;
+	goto L115;
+L103:
+	if (ip != 2) {
+	    goto L106;
+	}
+	if (na != 0) {
+	    goto L104;
+	}
+	passb2_(&idot, &l1, &c__[1], &ch[1], &wa[iw]);
+	goto L105;
+L104:
+	passb2_(&idot, &l1, &ch[1], &c__[1], &wa[iw]);
+L105:
+	na = 1 - na;
+	goto L115;
+L106:
+	if (ip != 3) {
+	    goto L109;
+	}
+	ix2 = iw + idot;
+	if (na != 0) {
+	    goto L107;
+	}
+	passb3_(&idot, &l1, &c__[1], &ch[1], &wa[iw], &wa[ix2]);
+	goto L108;
+L107:
+	passb3_(&idot, &l1, &ch[1], &c__[1], &wa[iw], &wa[ix2]);
+L108:
+	na = 1 - na;
+	goto L115;
+L109:
+	if (ip != 5) {
+	    goto L112;
+	}
+	ix2 = iw + idot;
+	ix3 = ix2 + idot;
+	ix4 = ix3 + idot;
+	if (na != 0) {
+	    goto L110;
+	}
+	passb5_(&idot, &l1, &c__[1], &ch[1], &wa[iw], &wa[ix2], &wa[ix3], &wa[
+		ix4]);
+	goto L111;
+L110:
+	passb5_(&idot, &l1, &ch[1], &c__[1], &wa[iw], &wa[ix2], &wa[ix3], &wa[
+		ix4]);
+L111:
+	na = 1 - na;
+	goto L115;
+L112:
+	if (na != 0) {
+	    goto L113;
+	}
+	passb_(&nac, &idot, &ip, &l1, &idl1, &c__[1], &c__[1], &c__[1], &ch[1]
+		, &ch[1], &wa[iw]);
+	goto L114;
+L113:
+	passb_(&nac, &idot, &ip, &l1, &idl1, &ch[1], &ch[1], &ch[1], &c__[1], 
+		&c__[1], &wa[iw]);
+L114:
+	if (nac != 0) {
+	    na = 1 - na;
+	}
+L115:
+	l1 = l2;
+	iw += (ip - 1) * idot;
+/* L116: */
+    }
+    if (na == 0) {
+	return 0;
+    }
+    n2 = *n + *n;
+    i__1 = n2;
+    for (i__ = 1; i__ <= i__1; ++i__) {
+	c__[i__] = ch[i__];
+/* L117: */
+    }
+    return 0;
+} /* cfftb1_ */
+
+/*  ------ File cfftf.f ------ */
+/* Subroutine */ int cfftf_(int_4 *n, r_4 *c__, r_4 *wsave)
+{
+    extern /* Subroutine */ int cfftf1_(int_4 *, r_4 *, r_4 *, r_4 *, 
+	    int_4 *);
+    static int_4 iw1, iw2;
+
+    /* Parameter adjustments */
+    --wsave;
+    --c__;
+
+    /* Function Body */
+    if (*n == 1) {
+	return 0;
+    }
+    iw1 = *n + *n + 1;
+    iw2 = iw1 + *n + *n;
+    cfftf1_(n, &c__[1], &wsave[1], &wsave[iw1], (int_4 *)&wsave[iw2]);   /* (int *) ajoute - Reza 29/11/99 */
+    return 0;
+} /* cfftf_ */
+
+/*  ------ File cfftf1.f ------ */
+/* Subroutine */ int cfftf1_(int_4 *n, r_4 *c__, r_4 *ch, r_4 *wa, 
+	int_4 *ifac)
+{
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Local variables */
+    static int_4 idot, i__;
+    extern /* Subroutine */ int passf_(int_4 *, int_4 *, int_4 *, 
+	    int_4 *, int_4 *, r_4 *, r_4 *, r_4 *, r_4 *, r_4 *, 
+	    r_4 *);
+    static int_4 k1, l1, l2, n2;
+    extern /* Subroutine */ int passf2_(int_4 *, int_4 *, r_4 *, r_4 *, 
+	    r_4 *), passf3_(int_4 *, int_4 *, r_4 *, r_4 *, r_4 *, 
+	    r_4 *), passf4_(int_4 *, int_4 *, r_4 *, r_4 *, r_4 *, 
+	    r_4 *, r_4 *), passf5_(int_4 *, int_4 *, r_4 *, r_4 *, 
+	    r_4 *, r_4 *, r_4 *, r_4 *);
+    static int_4 na, nf, ip, iw, ix2, ix3, ix4, nac, ido, idl1;
+
+    /* Parameter adjustments */
+    --ifac;
+    --wa;
+    --ch;
+    --c__;
+
+    /* Function Body */
+    nf = ifac[2];
+    na = 0;
+    l1 = 1;
+    iw = 1;
+    i__1 = nf;
+    for (k1 = 1; k1 <= i__1; ++k1) {
+	ip = ifac[k1 + 2];
+	l2 = ip * l1;
+	ido = *n / l2;
+	idot = ido + ido;
+	idl1 = idot * l1;
+	if (ip != 4) {
+	    goto L103;
+	}
+	ix2 = iw + idot;
+	ix3 = ix2 + idot;
+	if (na != 0) {
+	    goto L101;
+	}
+	passf4_(&idot, &l1, &c__[1], &ch[1], &wa[iw], &wa[ix2], &wa[ix3]);
+	goto L102;
+L101:
+	passf4_(&idot, &l1, &ch[1], &c__[1], &wa[iw], &wa[ix2], &wa[ix3]);
+L102:
+	na = 1 - na;
+	goto L115;
+L103:
+	if (ip != 2) {
+	    goto L106;
+	}
+	if (na != 0) {
+	    goto L104;
+	}
+	passf2_(&idot, &l1, &c__[1], &ch[1], &wa[iw]);
+	goto L105;
+L104:
+	passf2_(&idot, &l1, &ch[1], &c__[1], &wa[iw]);
+L105:
+	na = 1 - na;
+	goto L115;
+L106:
+	if (ip != 3) {
+	    goto L109;
+	}
+	ix2 = iw + idot;
+	if (na != 0) {
+	    goto L107;
+	}
+	passf3_(&idot, &l1, &c__[1], &ch[1], &wa[iw], &wa[ix2]);
+	goto L108;
+L107:
+	passf3_(&idot, &l1, &ch[1], &c__[1], &wa[iw], &wa[ix2]);
+L108:
+	na = 1 - na;
+	goto L115;
+L109:
+	if (ip != 5) {
+	    goto L112;
+	}
+	ix2 = iw + idot;
+	ix3 = ix2 + idot;
+	ix4 = ix3 + idot;
+	if (na != 0) {
+	    goto L110;
+	}
+	passf5_(&idot, &l1, &c__[1], &ch[1], &wa[iw], &wa[ix2], &wa[ix3], &wa[
+		ix4]);
+	goto L111;
+L110:
+	passf5_(&idot, &l1, &ch[1], &c__[1], &wa[iw], &wa[ix2], &wa[ix3], &wa[
+		ix4]);
+L111:
+	na = 1 - na;
+	goto L115;
+L112:
+	if (na != 0) {
+	    goto L113;
+	}
+	passf_(&nac, &idot, &ip, &l1, &idl1, &c__[1], &c__[1], &c__[1], &ch[1]
+		, &ch[1], &wa[iw]);
+	goto L114;
+L113:
+	passf_(&nac, &idot, &ip, &l1, &idl1, &ch[1], &ch[1], &ch[1], &c__[1], 
+		&c__[1], &wa[iw]);
+L114:
+	if (nac != 0) {
+	    na = 1 - na;
+	}
+L115:
+	l1 = l2;
+	iw += (ip - 1) * idot;
+/* L116: */
+    }
+    if (na == 0) {
+	return 0;
+    }
+    n2 = *n + *n;
+    i__1 = n2;
+    for (i__ = 1; i__ <= i__1; ++i__) {
+	c__[i__] = ch[i__];
+/* L117: */
+    }
+    return 0;
+} /* cfftf1_ */
+
+/*  ------ File cffti.f ------ */
+/* Subroutine */ int cffti_(int_4 *n, r_4 *wsave)
+{
+    extern /* Subroutine */ int cffti1_(int_4 *, r_4 *, int_4 *);
+    static int_4 iw1, iw2;
+
+    /* Parameter adjustments */
+    --wsave;
+
+    /* Function Body */
+    if (*n == 1) {
+	return 0;
+    }
+    iw1 = *n + *n + 1;
+    iw2 = iw1 + *n + *n;
+    cffti1_(n, &wsave[iw1], (int_4 *)&wsave[iw2]);  /*  (int *) ajoute Reza 29/11/99 */
+    return 0;
+} /* cffti_ */
+
+/*  ------ File cffti1.f ------ */
+/* Subroutine */ int cffti1_(int_4 *n, r_4 *wa, int_4 *ifac)
+{
+    /* Initialized data */
+
+    static int_4 ntryh[4] = { 3,4,2,5 };
+
+    /* System generated locals */
+    int_4 i__1, i__2, i__3;
+
+    /* Builtin functions */ 
+/*    r_8 cos(r_8truc), sin(r_8truc);   commente, remplace par math.h - Reza  29/11/99 */
+
+    /* Local variables */
+    static r_4 argh;
+    static int_4 idot, ntry, i__, j;
+    static r_4 argld;
+    static int_4 i1, k1, l1, l2, ib;
+    static r_4 fi;
+    static int_4 ld, ii, nf, ip, nl, nq, nr;
+    static r_4 arg;
+    static int_4 ido, ipm;
+    static r_4 tpi;
+
+    /* Parameter adjustments */
+    --ifac;
+    --wa;
+
+    /* Function Body */
+    nl = *n;
+    nf = 0;
+    j = 0;
+L101:
+    ++j;
+    if (j - 4 <= 0) {
+	goto L102;
+    } else {
+	goto L103;
+    }
+L102:
+    ntry = ntryh[j - 1];
+    goto L104;
+L103:
+    ntry += 2;
+L104:
+    nq = nl / ntry;
+    nr = nl - ntry * nq;
+    if (nr != 0) {
+	goto L101;
+    } else {
+	goto L105;
+    }
+L105:
+    ++nf;
+    ifac[nf + 2] = ntry;
+    nl = nq;
+    if (ntry != 2) {
+	goto L107;
+    }
+    if (nf == 1) {
+	goto L107;
+    }
+    i__1 = nf;
+    for (i__ = 2; i__ <= i__1; ++i__) {
+	ib = nf - i__ + 2;
+	ifac[ib + 2] = ifac[ib + 1];
+/* L106: */
+    }
+    ifac[3] = 2;
+L107:
+    if (nl != 1) {
+	goto L104;
+    }
+    ifac[1] = *n;
+    ifac[2] = nf;
+    tpi = 6.28318530717959f;
+    argh = tpi / (r_4) (*n);
+    i__ = 2;
+    l1 = 1;
+    i__1 = nf;
+    for (k1 = 1; k1 <= i__1; ++k1) {
+	ip = ifac[k1 + 2];
+	ld = 0;
+	l2 = l1 * ip;
+	ido = *n / l2;
+	idot = ido + ido + 2;
+	ipm = ip - 1;
+	i__2 = ipm;
+	for (j = 1; j <= i__2; ++j) {
+	    i1 = i__;
+	    wa[i__ - 1] = 1.f;
+	    wa[i__] = 0.f;
+	    ld += l1;
+	    fi = 0.f;
+	    argld = (r_4) ld * argh;
+	    i__3 = idot;
+	    for (ii = 4; ii <= i__3; ii += 2) {
+		i__ += 2;
+		fi += 1.f;
+		arg = fi * argld;
+		wa[i__ - 1] = cos(arg);
+		wa[i__] = sin(arg);
+/* L108: */
+	    }
+	    if (ip <= 5) {
+		goto L109;
+	    }
+	    wa[i1 - 1] = wa[i__ - 1];
+	    wa[i1] = wa[i__];
+L109:
+	    ;
+	}
+	l1 = l2;
+/* L110: */
+    }
+    return 0;
+} /* cffti1_ */
+
+/*  ------ File cosqb.f ------ */
+/* Subroutine */ int cosqb_(int_4 *n, r_4 *x, r_4 *wsave)
+{
+    /* Initialized data */
+
+    static r_4 tsqrt2 = 2.82842712474619f;
+
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Local variables */
+    static r_4 x1;
+    extern /* Subroutine */ int cosqb1_(int_4 *, r_4 *, r_4 *, r_4 *);
+
+    /* Parameter adjustments */
+    --wsave;
+    --x;
+
+    /* Function Body */
+    if ((i__1 = *n - 2) < 0) {
+	goto L101;
+    } else if (i__1 == 0) {
+	goto L102;
+    } else {
+	goto L103;
+    }
+L101:
+    x[1] *= 4.f;
+    return 0;
+L102:
+    x1 = (x[1] + x[2]) * 4.f;
+    x[2] = tsqrt2 * (x[1] - x[2]);
+    x[1] = x1;
+    return 0;
+L103:
+    cosqb1_(n, &x[1], &wsave[1], &wsave[*n + 1]);
+    return 0;
+} /* cosqb_ */
+
+/*  ------ File cosqb1.f ------ */
+/* Subroutine */ int cosqb1_(int_4 *n, r_4 *x, r_4 *w, r_4 *xh)
+{
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Local variables */
+    static int_4 modn, i__, k;
+    extern /* Subroutine */ int rfftb_(int_4 *, r_4 *, r_4 *);
+    static int_4 kc, np2, ns2;
+    static r_4 xim1;
+
+    /* Parameter adjustments */
+    --xh;
+    --w;
+    --x;
+
+    /* Function Body */
+    ns2 = (*n + 1) / 2;
+    np2 = *n + 2;
+    i__1 = *n;
+    for (i__ = 3; i__ <= i__1; i__ += 2) {
+	xim1 = x[i__ - 1] + x[i__];
+	x[i__] -= x[i__ - 1];
+	x[i__ - 1] = xim1;
+/* L101: */
+    }
+    x[1] += x[1];
+    modn = *n % 2;
+    if (modn == 0) {
+	x[*n] += x[*n];
+    }
+    rfftb_(n, &x[1], &xh[1]);
+    i__1 = ns2;
+    for (k = 2; k <= i__1; ++k) {
+	kc = np2 - k;
+	xh[k] = w[k - 1] * x[kc] + w[kc - 1] * x[k];
+	xh[kc] = w[k - 1] * x[k] - w[kc - 1] * x[kc];
+/* L102: */
+    }
+    if (modn == 0) {
+	x[ns2 + 1] = w[ns2] * (x[ns2 + 1] + x[ns2 + 1]);
+    }
+    i__1 = ns2;
+    for (k = 2; k <= i__1; ++k) {
+	kc = np2 - k;
+	x[k] = xh[k] + xh[kc];
+	x[kc] = xh[k] - xh[kc];
+/* L103: */
+    }
+    x[1] += x[1];
+    return 0;
+} /* cosqb1_ */
+
+/*  ------ File cosqf.f ------ */
+/* Subroutine */ int cosqf_(int_4 *n, r_4 *x, r_4 *wsave)
+{
+    /* Initialized data */
+
+    static r_4 sqrt2 = 1.4142135623731f;
+
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Local variables */
+    static r_4 tsqx;
+    extern /* Subroutine */ int cosqf1_(int_4 *, r_4 *, r_4 *, r_4 *);
+
+    /* Parameter adjustments */
+    --wsave;
+    --x;
+
+    /* Function Body */
+    if ((i__1 = *n - 2) < 0) {
+	goto L102;
+    } else if (i__1 == 0) {
+	goto L101;
+    } else {
+	goto L103;
+    }
+L101:
+    tsqx = sqrt2 * x[2];
+    x[2] = x[1] - tsqx;
+    x[1] += tsqx;
+L102:
+    return 0;
+L103:
+    cosqf1_(n, &x[1], &wsave[1], &wsave[*n + 1]);
+    return 0;
+} /* cosqf_ */
+
+/*  ------ File cosqf1.f ------ */
+/* Subroutine */ int cosqf1_(int_4 *n, r_4 *x, r_4 *w, r_4 *xh)
+{
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Local variables */
+    static int_4 modn, i__, k;
+    extern /* Subroutine */ int rfftf_(int_4 *, r_4 *, r_4 *);
+    static int_4 kc, np2, ns2;
+    static r_4 xim1;
+
+    /* Parameter adjustments */
+    --xh;
+    --w;
+    --x;
+
+    /* Function Body */
+    ns2 = (*n + 1) / 2;
+    np2 = *n + 2;
+    i__1 = ns2;
+    for (k = 2; k <= i__1; ++k) {
+	kc = np2 - k;
+	xh[k] = x[k] + x[kc];
+	xh[kc] = x[k] - x[kc];
+/* L101: */
+    }
+    modn = *n % 2;
+    if (modn == 0) {
+	xh[ns2 + 1] = x[ns2 + 1] + x[ns2 + 1];
+    }
+    i__1 = ns2;
+    for (k = 2; k <= i__1; ++k) {
+	kc = np2 - k;
+	x[k] = w[k - 1] * xh[kc] + w[kc - 1] * xh[k];
+	x[kc] = w[k - 1] * xh[k] - w[kc - 1] * xh[kc];
+/* L102: */
+    }
+    if (modn == 0) {
+	x[ns2 + 1] = w[ns2] * xh[ns2 + 1];
+    }
+    rfftf_(n, &x[1], &xh[1]);
+    i__1 = *n;
+    for (i__ = 3; i__ <= i__1; i__ += 2) {
+	xim1 = x[i__ - 1] - x[i__];
+	x[i__] = x[i__ - 1] + x[i__];
+	x[i__ - 1] = xim1;
+/* L103: */
+    }
+    return 0;
+} /* cosqf1_ */
+
+/*  ------ File cosqi.f ------ */
+/* Subroutine */ int cosqi_(int_4 *n, r_4 *wsave)
+{
+    /* Initialized data */
+
+    static r_4 pih = 1.57079632679491f;
+
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Builtin functions */
+/*    r_8 cos(r_8truc);    commente - Remplace par math.h  Reza 29/11/99 */
+
+    /* Local variables */
+    static int_4 k;
+    extern /* Subroutine */ int rffti_(int_4 *, r_4 *);
+    static r_4 fk, dt;
+
+    /* Parameter adjustments */
+    --wsave;
+
+    /* Function Body */
+    dt = pih / (r_4) (*n);
+    fk = 0.f;
+    i__1 = *n;
+    for (k = 1; k <= i__1; ++k) {
+	fk += 1.f;
+	wsave[k] = cos(fk * dt);
+/* L101: */
+    }
+    rffti_(n, &wsave[*n + 1]);
+    return 0;
+} /* cosqi_ */
+
+/*  ------ File cost.f ------ */
+/* Subroutine */ int cost_(int_4 *n, r_4 *x, r_4 *wsave)
+{
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Local variables */
+    static int_4 modn, i__, k;
+    extern /* Subroutine */ int rfftf_(int_4 *, r_4 *, r_4 *);
+    static r_4 c1, t1, t2;
+    static int_4 kc;
+    static r_4 xi;
+    static int_4 nm1, np1;
+    static r_4 x1h;
+    static int_4 ns2;
+    static r_4 tx2, x1p3, xim2;
+
+    /* Parameter adjustments */
+    --wsave;
+    --x;
+
+    /* Function Body */
+    nm1 = *n - 1;
+    np1 = *n + 1;
+    ns2 = *n / 2;
+    if ((i__1 = *n - 2) < 0) {
+	goto L106;
+    } else if (i__1 == 0) {
+	goto L101;
+    } else {
+	goto L102;
+    }
+L101:
+    x1h = x[1] + x[2];
+    x[2] = x[1] - x[2];
+    x[1] = x1h;
+    return 0;
+L102:
+    if (*n > 3) {
+	goto L103;
+    }
+    x1p3 = x[1] + x[3];
+    tx2 = x[2] + x[2];
+    x[2] = x[1] - x[3];
+    x[1] = x1p3 + tx2;
+    x[3] = x1p3 - tx2;
+    return 0;
+L103:
+    c1 = x[1] - x[*n];
+    x[1] += x[*n];
+    i__1 = ns2;
+    for (k = 2; k <= i__1; ++k) {
+	kc = np1 - k;
+	t1 = x[k] + x[kc];
+	t2 = x[k] - x[kc];
+	c1 += wsave[kc] * t2;
+	t2 = wsave[k] * t2;
+	x[k] = t1 - t2;
+	x[kc] = t1 + t2;
+/* L104: */
+    }
+    modn = *n % 2;
+    if (modn != 0) {
+	x[ns2 + 1] += x[ns2 + 1];
+    }
+    rfftf_(&nm1, &x[1], &wsave[*n + 1]);
+    xim2 = x[2];
+    x[2] = c1;
+    i__1 = *n;
+    for (i__ = 4; i__ <= i__1; i__ += 2) {
+	xi = x[i__];
+	x[i__] = x[i__ - 2] - x[i__ - 1];
+	x[i__ - 1] = xim2;
+	xim2 = xi;
+/* L105: */
+    }
+    if (modn != 0) {
+	x[*n] = xim2;
+    }
+L106:
+    return 0;
+} /* cost_ */
+
+/*  ------ File costi.f ------ */
+/* Subroutine */ int costi_(int_4 *n, r_4 *wsave)
+{
+    /* Initialized data */
+
+    static r_4 pi = 3.14159265358979f;
+
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Builtin functions */
+/*    r_8 sin(r_8truc), cos(r_8truc);  commente - Remplace par math.h  Reza 29/11/99 */
+
+    /* Local variables */
+    static int_4 k;
+    extern /* Subroutine */ int rffti_(int_4 *, r_4 *);
+    static int_4 kc;
+    static r_4 fk, dt;
+    static int_4 nm1, np1, ns2;
+
+    /* Parameter adjustments */
+    --wsave;
+
+    /* Function Body */
+    if (*n <= 3) {
+	return 0;
+    }
+    nm1 = *n - 1;
+    np1 = *n + 1;
+    ns2 = *n / 2;
+    dt = pi / (r_4) nm1;
+    fk = 0.f;
+    i__1 = ns2;
+    for (k = 2; k <= i__1; ++k) {
+	kc = np1 - k;
+	fk += 1.f;
+	wsave[k] = sin(fk * dt) * 2.f;
+	wsave[kc] = cos(fk * dt) * 2.f;
+/* L101: */
+    }
+    rffti_(&nm1, &wsave[*n + 1]);
+    return 0;
+} /* costi_ */
+
+/*  ------ File ezfft1.f ------ */
+/* Subroutine */ int ezfft1_(int_4 *n, r_4 *wa, int_4 *ifac)
+{
+    /* Initialized data */
+
+    static int_4 ntryh[4] = { 4,2,3,5 };
+    static r_4 tpi = 6.28318530717959f;
+
+    /* System generated locals */
+    int_4 i__1, i__2, i__3;
+
+    /* Builtin functions */
+/*    r_8 cos(r_8truc), sin(r_8truc);  commente - Remplace par math.h  Reza 29/11/99 */
+
+    /* Local variables */
+    static r_4 argh;
+    static int_4 ntry, i__, j, k1, l1, l2, ib, ii, nf, ip, nl, is, nq, nr;
+    static r_4 ch1, sh1;
+    static int_4 ido, ipm;
+    static r_4 dch1, ch1h, arg1, dsh1;
+    static int_4 nfm1;
+
+    /* Parameter adjustments */
+    --ifac;
+    --wa;
+
+    /* Function Body */
+    nl = *n;
+    nf = 0;
+    j = 0;
+L101:
+    ++j;
+    if (j - 4 <= 0) {
+	goto L102;
+    } else {
+	goto L103;
+    }
+L102:
+    ntry = ntryh[j - 1];
+    goto L104;
+L103:
+    ntry += 2;
+L104:
+    nq = nl / ntry;
+    nr = nl - ntry * nq;
+    if (nr != 0) {
+	goto L101;
+    } else {
+	goto L105;
+    }
+L105:
+    ++nf;
+    ifac[nf + 2] = ntry;
+    nl = nq;
+    if (ntry != 2) {
+	goto L107;
+    }
+    if (nf == 1) {
+	goto L107;
+    }
+    i__1 = nf;
+    for (i__ = 2; i__ <= i__1; ++i__) {
+	ib = nf - i__ + 2;
+	ifac[ib + 2] = ifac[ib + 1];
+/* L106: */
+    }
+    ifac[3] = 2;
+L107:
+    if (nl != 1) {
+	goto L104;
+    }
+    ifac[1] = *n;
+    ifac[2] = nf;
+    argh = tpi / (r_4) (*n);
+    is = 0;
+    nfm1 = nf - 1;
+    l1 = 1;
+    if (nfm1 == 0) {
+	return 0;
+    }
+    i__1 = nfm1;
+    for (k1 = 1; k1 <= i__1; ++k1) {
+	ip = ifac[k1 + 2];
+	l2 = l1 * ip;
+	ido = *n / l2;
+	ipm = ip - 1;
+	arg1 = (r_4) l1 * argh;
+	ch1 = 1.f;
+	sh1 = 0.f;
+	dch1 = cos(arg1);
+	dsh1 = sin(arg1);
+	i__2 = ipm;
+	for (j = 1; j <= i__2; ++j) {
+	    ch1h = dch1 * ch1 - dsh1 * sh1;
+	    sh1 = dch1 * sh1 + dsh1 * ch1;
+	    ch1 = ch1h;
+	    i__ = is + 2;
+	    wa[i__ - 1] = ch1;
+	    wa[i__] = sh1;
+	    if (ido < 5) {
+		goto L109;
+	    }
+	    i__3 = ido;
+	    for (ii = 5; ii <= i__3; ii += 2) {
+		i__ += 2;
+		wa[i__ - 1] = ch1 * wa[i__ - 3] - sh1 * wa[i__ - 2];
+		wa[i__] = ch1 * wa[i__ - 2] + sh1 * wa[i__ - 3];
+/* L108: */
+	    }
+L109:
+	    is += ido;
+/* L110: */
+	}
+	l1 = l2;
+/* L111: */
+    }
+    return 0;
+} /* ezfft1_ */
+
+/*  ------ File ezfftb.f ------ */
+/* Subroutine */ int ezfftb_(int_4 *n, r_4 *r__, r_4 *azero, r_4 *a, 
+	r_4 *b, r_4 *wsave)
+{
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Local variables */
+    static int_4 i__;
+    extern /* Subroutine */ int rfftb_(int_4 *, r_4 *, r_4 *);
+    static int_4 ns2;
+
+    /* Parameter adjustments */
+    --wsave;
+    --b;
+    --a;
+    --r__;
+
+    /* Function Body */
+    if ((i__1 = *n - 2) < 0) {
+	goto L101;
+    } else if (i__1 == 0) {
+	goto L102;
+    } else {
+	goto L103;
+    }
+L101:
+    r__[1] = *azero;
+    return 0;
+L102:
+    r__[1] = *azero + a[1];
+    r__[2] = *azero - a[1];
+    return 0;
+L103:
+    ns2 = (*n - 1) / 2;
+    i__1 = ns2;
+    for (i__ = 1; i__ <= i__1; ++i__) {
+	r__[i__ * 2] = a[i__] * .5f;
+	r__[(i__ << 1) + 1] = b[i__] * -.5f;
+/* L104: */
+    }
+    r__[1] = *azero;
+    if (*n % 2 == 0) {
+	r__[*n] = a[ns2 + 1];
+    }
+    rfftb_(n, &r__[1], &wsave[*n + 1]);
+    return 0;
+} /* ezfftb_ */
+
+/*  ------ File ezfftf.f ------ */
+/* Subroutine */ int ezfftf_(int_4 *n, r_4 *r__, r_4 *azero, r_4 *a, 
+	r_4 *b, r_4 *wsave)
+{
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Local variables */
+    static int_4 i__;
+    extern /* Subroutine */ int rfftf_(int_4 *, r_4 *, r_4 *);
+    static r_4 cf;
+    static int_4 ns2;
+    static r_4 cfm;
+    static int_4 ns2m;
+
+
+/*                       VERSION 3  JUNE 1979 */
+
+    /* Parameter adjustments */
+    --wsave;
+    --b;
+    --a;
+    --r__;
+
+    /* Function Body */
+    if ((i__1 = *n - 2) < 0) {
+	goto L101;
+    } else if (i__1 == 0) {
+	goto L102;
+    } else {
+	goto L103;
+    }
+L101:
+    *azero = r__[1];
+    return 0;
+L102:
+    *azero = (r__[1] + r__[2]) * .5f;
+    a[1] = (r__[1] - r__[2]) * .5f;
+    return 0;
+L103:
+    i__1 = *n;
+    for (i__ = 1; i__ <= i__1; ++i__) {
+	wsave[i__] = r__[i__];
+/* L104: */
+    }
+    rfftf_(n, &wsave[1], &wsave[*n + 1]);
+    cf = 2.f / (r_4) (*n);
+    cfm = -cf;
+    *azero = cf * .5f * wsave[1];
+    ns2 = (*n + 1) / 2;
+    ns2m = ns2 - 1;
+    i__1 = ns2m;
+    for (i__ = 1; i__ <= i__1; ++i__) {
+	a[i__] = cf * wsave[i__ * 2];
+	b[i__] = cfm * wsave[(i__ << 1) + 1];
+/* L105: */
+    }
+    if (*n % 2 == 1) {
+	return 0;
+    }
+    a[ns2] = cf * .5f * wsave[*n];
+    b[ns2] = 0.f;
+    return 0;
+} /* ezfftf_ */
+
+/*  ------ File ezffti.f ------ */
+/* Subroutine */ int ezffti_(int_4 *n, r_4 *wsave)
+{
+    extern /* Subroutine */ int ezfft1_(int_4 *, r_4 *, int_4 *);
+
+    /* Parameter adjustments */
+    --wsave;
+
+    /* Function Body */
+    if (*n == 1) {
+	return 0;
+    }
+    ezfft1_(n, &wsave[(*n << 1) + 1], (int_4*)&wsave[*n * 3 + 1]);
+    return 0;
+} /* ezffti_ */
+
+/*  ------ File passb.f ------ */
+/* Subroutine */ int passb_(int_4 *nac, int_4 *ido, int_4 *ip, int_4 *
+	l1, int_4 *idl1, r_4 *cc, r_4 *c1, r_4 *c2, r_4 *ch, r_4 *ch2, 
+	r_4 *wa)
+{
+    /* System generated locals */
+    int_4 ch_dim1, ch_dim2, ch_offset, cc_dim1, cc_dim2, cc_offset, c1_dim1,
+	     c1_dim2, c1_offset, c2_dim1, c2_offset, ch2_dim1, ch2_offset, 
+	    i__1, i__2, i__3;
+
+    /* Local variables */
+    static int_4 idij, idlj, idot, ipph, i__, j, k, l, jc, lc, ik, nt, idj, 
+	    idl, inc, idp;
+    static r_4 wai, war;
+    static int_4 ipp2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    c1_dim1 = *ido;
+    c1_dim2 = *l1;
+    c1_offset = c1_dim1 * (c1_dim2 + 1) + 1;
+    c1 -= c1_offset;
+    cc_dim1 = *ido;
+    cc_dim2 = *ip;
+    cc_offset = cc_dim1 * (cc_dim2 + 1) + 1;
+    cc -= cc_offset;
+    ch2_dim1 = *idl1;
+    ch2_offset = ch2_dim1 + 1;
+    ch2 -= ch2_offset;
+    c2_dim1 = *idl1;
+    c2_offset = c2_dim1 + 1;
+    c2 -= c2_offset;
+    --wa;
+
+    /* Function Body */
+    idot = *ido / 2;
+    nt = *ip * *idl1;
+    ipp2 = *ip + 2;
+    ipph = (*ip + 1) / 2;
+    idp = *ip * *ido;
+
+    if (*ido < *l1) {
+	goto L106;
+    }
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    i__3 = *ido;
+	    for (i__ = 1; i__ <= i__3; ++i__) {
+		ch[i__ + (k + j * ch_dim2) * ch_dim1] = cc[i__ + (j + k * 
+			cc_dim2) * cc_dim1] + cc[i__ + (jc + k * cc_dim2) * 
+			cc_dim1];
+		ch[i__ + (k + jc * ch_dim2) * ch_dim1] = cc[i__ + (j + k * 
+			cc_dim2) * cc_dim1] - cc[i__ + (jc + k * cc_dim2) * 
+			cc_dim1];
+/* L101: */
+	    }
+/* L102: */
+	}
+/* L103: */
+    }
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 1; i__ <= i__2; ++i__) {
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = cc[i__ + (k * cc_dim2 + 1) * 
+		    cc_dim1];
+/* L104: */
+	}
+/* L105: */
+    }
+    goto L112;
+L106:
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	i__2 = *ido;
+	for (i__ = 1; i__ <= i__2; ++i__) {
+	    i__3 = *l1;
+	    for (k = 1; k <= i__3; ++k) {
+		ch[i__ + (k + j * ch_dim2) * ch_dim1] = cc[i__ + (j + k * 
+			cc_dim2) * cc_dim1] + cc[i__ + (jc + k * cc_dim2) * 
+			cc_dim1];
+		ch[i__ + (k + jc * ch_dim2) * ch_dim1] = cc[i__ + (j + k * 
+			cc_dim2) * cc_dim1] - cc[i__ + (jc + k * cc_dim2) * 
+			cc_dim1];
+/* L107: */
+	    }
+/* L108: */
+	}
+/* L109: */
+    }
+    i__1 = *ido;
+    for (i__ = 1; i__ <= i__1; ++i__) {
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = cc[i__ + (k * cc_dim2 + 1) * 
+		    cc_dim1];
+/* L110: */
+	}
+/* L111: */
+    }
+L112:
+    idl = 2 - *ido;
+    inc = 0;
+    i__1 = ipph;
+    for (l = 2; l <= i__1; ++l) {
+	lc = ipp2 - l;
+	idl += *ido;
+	i__2 = *idl1;
+	for (ik = 1; ik <= i__2; ++ik) {
+	    c2[ik + l * c2_dim1] = ch2[ik + ch2_dim1] + wa[idl - 1] * ch2[ik 
+		    + (ch2_dim1 << 1)];
+	    c2[ik + lc * c2_dim1] = wa[idl] * ch2[ik + *ip * ch2_dim1];
+/* L113: */
+	}
+	idlj = idl;
+	inc += *ido;
+	i__2 = ipph;
+	for (j = 3; j <= i__2; ++j) {
+	    jc = ipp2 - j;
+	    idlj += inc;
+	    if (idlj > idp) {
+		idlj -= idp;
+	    }
+	    war = wa[idlj - 1];
+	    wai = wa[idlj];
+	    i__3 = *idl1;
+	    for (ik = 1; ik <= i__3; ++ik) {
+		c2[ik + l * c2_dim1] += war * ch2[ik + j * ch2_dim1];
+		c2[ik + lc * c2_dim1] += wai * ch2[ik + jc * ch2_dim1];
+/* L114: */
+	    }
+/* L115: */
+	}
+/* L116: */
+    }
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	i__2 = *idl1;
+	for (ik = 1; ik <= i__2; ++ik) {
+	    ch2[ik + ch2_dim1] += ch2[ik + j * ch2_dim1];
+/* L117: */
+	}
+/* L118: */
+    }
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	i__2 = *idl1;
+	for (ik = 2; ik <= i__2; ik += 2) {
+	    ch2[ik - 1 + j * ch2_dim1] = c2[ik - 1 + j * c2_dim1] - c2[ik + 
+		    jc * c2_dim1];
+	    ch2[ik - 1 + jc * ch2_dim1] = c2[ik - 1 + j * c2_dim1] + c2[ik + 
+		    jc * c2_dim1];
+	    ch2[ik + j * ch2_dim1] = c2[ik + j * c2_dim1] + c2[ik - 1 + jc * 
+		    c2_dim1];
+	    ch2[ik + jc * ch2_dim1] = c2[ik + j * c2_dim1] - c2[ik - 1 + jc * 
+		    c2_dim1];
+/* L119: */
+	}
+/* L120: */
+    }
+    *nac = 1;
+    if (*ido == 2) {
+	return 0;
+    }
+    *nac = 0;
+    i__1 = *idl1;
+    for (ik = 1; ik <= i__1; ++ik) {
+	c2[ik + c2_dim1] = ch2[ik + ch2_dim1];
+/* L121: */
+    }
+    i__1 = *ip;
+    for (j = 2; j <= i__1; ++j) {
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    c1[(k + j * c1_dim2) * c1_dim1 + 1] = ch[(k + j * ch_dim2) * 
+		    ch_dim1 + 1];
+	    c1[(k + j * c1_dim2) * c1_dim1 + 2] = ch[(k + j * ch_dim2) * 
+		    ch_dim1 + 2];
+/* L122: */
+	}
+/* L123: */
+    }
+    if (idot > *l1) {
+	goto L127;
+    }
+    idij = 0;
+    i__1 = *ip;
+    for (j = 2; j <= i__1; ++j) {
+	idij += 2;
+	i__2 = *ido;
+	for (i__ = 4; i__ <= i__2; i__ += 2) {
+	    idij += 2;
+	    i__3 = *l1;
+	    for (k = 1; k <= i__3; ++k) {
+		c1[i__ - 1 + (k + j * c1_dim2) * c1_dim1] = wa[idij - 1] * ch[
+			i__ - 1 + (k + j * ch_dim2) * ch_dim1] - wa[idij] * 
+			ch[i__ + (k + j * ch_dim2) * ch_dim1];
+		c1[i__ + (k + j * c1_dim2) * c1_dim1] = wa[idij - 1] * ch[i__ 
+			+ (k + j * ch_dim2) * ch_dim1] + wa[idij] * ch[i__ - 
+			1 + (k + j * ch_dim2) * ch_dim1];
+/* L124: */
+	    }
+/* L125: */
+	}
+/* L126: */
+    }
+    return 0;
+L127:
+    idj = 2 - *ido;
+    i__1 = *ip;
+    for (j = 2; j <= i__1; ++j) {
+	idj += *ido;
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    idij = idj;
+	    i__3 = *ido;
+	    for (i__ = 4; i__ <= i__3; i__ += 2) {
+		idij += 2;
+		c1[i__ - 1 + (k + j * c1_dim2) * c1_dim1] = wa[idij - 1] * ch[
+			i__ - 1 + (k + j * ch_dim2) * ch_dim1] - wa[idij] * 
+			ch[i__ + (k + j * ch_dim2) * ch_dim1];
+		c1[i__ + (k + j * c1_dim2) * c1_dim1] = wa[idij - 1] * ch[i__ 
+			+ (k + j * ch_dim2) * ch_dim1] + wa[idij] * ch[i__ - 
+			1 + (k + j * ch_dim2) * ch_dim1];
+/* L128: */
+	    }
+/* L129: */
+	}
+/* L130: */
+    }
+    return 0;
+} /* passb_ */
+
+/*  ------ File passb2.f ------ */
+/* Subroutine */ int passb2_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, 
+	r_4 *wa1)
+{
+    /* System generated locals */
+    int_4 cc_dim1, cc_offset, ch_dim1, ch_dim2, ch_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k;
+    static r_4 ti2, tr2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_offset = cc_dim1 * 3 + 1;
+    cc -= cc_offset;
+    --wa1;
+
+    /* Function Body */
+    if (*ido > 2) {
+	goto L102;
+    }
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	ch[(k + ch_dim2) * ch_dim1 + 1] = cc[((k << 1) + 1) * cc_dim1 + 1] + 
+		cc[((k << 1) + 2) * cc_dim1 + 1];
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 1] = cc[((k << 1) + 1) * cc_dim1 
+		+ 1] - cc[((k << 1) + 2) * cc_dim1 + 1];
+	ch[(k + ch_dim2) * ch_dim1 + 2] = cc[((k << 1) + 1) * cc_dim1 + 2] + 
+		cc[((k << 1) + 2) * cc_dim1 + 2];
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 2] = cc[((k << 1) + 1) * cc_dim1 
+		+ 2] - cc[((k << 1) + 2) * cc_dim1 + 2];
+/* L101: */
+    }
+    return 0;
+L102:
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 2; i__ <= i__2; i__ += 2) {
+	    ch[i__ - 1 + (k + ch_dim2) * ch_dim1] = cc[i__ - 1 + ((k << 1) + 
+		    1) * cc_dim1] + cc[i__ - 1 + ((k << 1) + 2) * cc_dim1];
+	    tr2 = cc[i__ - 1 + ((k << 1) + 1) * cc_dim1] - cc[i__ - 1 + ((k <<
+		     1) + 2) * cc_dim1];
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = cc[i__ + ((k << 1) + 1) * 
+		    cc_dim1] + cc[i__ + ((k << 1) + 2) * cc_dim1];
+	    ti2 = cc[i__ + ((k << 1) + 1) * cc_dim1] - cc[i__ + ((k << 1) + 2)
+		     * cc_dim1];
+	    ch[i__ + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * ti2 + 
+		    wa1[i__] * tr2;
+	    ch[i__ - 1 + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * tr2 
+		    - wa1[i__] * ti2;
+/* L103: */
+	}
+/* L104: */
+    }
+    return 0;
+} /* passb2_ */
+
+/*  ------ File passb3.f ------ */
+/* Subroutine */ int passb3_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, 
+	r_4 *wa1, r_4 *wa2)
+{
+    /* Initialized data */
+
+    static r_4 taur = -.5f;
+    static r_4 taui = .866025403784439f;
+
+    /* System generated locals */
+    int_4 cc_dim1, cc_offset, ch_dim1, ch_dim2, ch_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k;
+    static r_4 ci2, ci3, di2, di3, cr2, cr3, dr2, dr3, ti2, tr2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_offset = (cc_dim1 << 2) + 1;
+    cc -= cc_offset;
+    --wa1;
+    --wa2;
+
+    /* Function Body */
+    if (*ido != 2) {
+	goto L102;
+    }
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	tr2 = cc[(k * 3 + 2) * cc_dim1 + 1] + cc[(k * 3 + 3) * cc_dim1 + 1];
+	cr2 = cc[(k * 3 + 1) * cc_dim1 + 1] + taur * tr2;
+	ch[(k + ch_dim2) * ch_dim1 + 1] = cc[(k * 3 + 1) * cc_dim1 + 1] + tr2;
+	ti2 = cc[(k * 3 + 2) * cc_dim1 + 2] + cc[(k * 3 + 3) * cc_dim1 + 2];
+	ci2 = cc[(k * 3 + 1) * cc_dim1 + 2] + taur * ti2;
+	ch[(k + ch_dim2) * ch_dim1 + 2] = cc[(k * 3 + 1) * cc_dim1 + 2] + ti2;
+	cr3 = taui * (cc[(k * 3 + 2) * cc_dim1 + 1] - cc[(k * 3 + 3) * 
+		cc_dim1 + 1]);
+	ci3 = taui * (cc[(k * 3 + 2) * cc_dim1 + 2] - cc[(k * 3 + 3) * 
+		cc_dim1 + 2]);
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 1] = cr2 - ci3;
+	ch[(k + ch_dim2 * 3) * ch_dim1 + 1] = cr2 + ci3;
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 2] = ci2 + cr3;
+	ch[(k + ch_dim2 * 3) * ch_dim1 + 2] = ci2 - cr3;
+/* L101: */
+    }
+    return 0;
+L102:
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 2; i__ <= i__2; i__ += 2) {
+	    tr2 = cc[i__ - 1 + (k * 3 + 2) * cc_dim1] + cc[i__ - 1 + (k * 3 + 
+		    3) * cc_dim1];
+	    cr2 = cc[i__ - 1 + (k * 3 + 1) * cc_dim1] + taur * tr2;
+	    ch[i__ - 1 + (k + ch_dim2) * ch_dim1] = cc[i__ - 1 + (k * 3 + 1) *
+		     cc_dim1] + tr2;
+	    ti2 = cc[i__ + (k * 3 + 2) * cc_dim1] + cc[i__ + (k * 3 + 3) * 
+		    cc_dim1];
+	    ci2 = cc[i__ + (k * 3 + 1) * cc_dim1] + taur * ti2;
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = cc[i__ + (k * 3 + 1) * 
+		    cc_dim1] + ti2;
+	    cr3 = taui * (cc[i__ - 1 + (k * 3 + 2) * cc_dim1] - cc[i__ - 1 + (
+		    k * 3 + 3) * cc_dim1]);
+	    ci3 = taui * (cc[i__ + (k * 3 + 2) * cc_dim1] - cc[i__ + (k * 3 + 
+		    3) * cc_dim1]);
+	    dr2 = cr2 - ci3;
+	    dr3 = cr2 + ci3;
+	    di2 = ci2 + cr3;
+	    di3 = ci2 - cr3;
+	    ch[i__ + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * di2 + 
+		    wa1[i__] * dr2;
+	    ch[i__ - 1 + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * dr2 
+		    - wa1[i__] * di2;
+	    ch[i__ + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 1] * di3 + wa2[
+		    i__] * dr3;
+	    ch[i__ - 1 + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 1] * dr3 - 
+		    wa2[i__] * di3;
+/* L103: */
+	}
+/* L104: */
+    }
+    return 0;
+} /* passb3_ */
+
+/*  ------ File passb4.f ------ */
+/* Subroutine */ int passb4_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, 
+	r_4 *wa1, r_4 *wa2, r_4 *wa3)
+{
+    /* System generated locals */
+    int_4 cc_dim1, cc_offset, ch_dim1, ch_dim2, ch_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k;
+    static r_4 ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, 
+	    tr3, tr4;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_offset = cc_dim1 * 5 + 1;
+    cc -= cc_offset;
+    --wa1;
+    --wa2;
+    --wa3;
+
+    /* Function Body */
+    if (*ido != 2) {
+	goto L102;
+    }
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	ti1 = cc[((k << 2) + 1) * cc_dim1 + 2] - cc[((k << 2) + 3) * cc_dim1 
+		+ 2];
+	ti2 = cc[((k << 2) + 1) * cc_dim1 + 2] + cc[((k << 2) + 3) * cc_dim1 
+		+ 2];
+	tr4 = cc[((k << 2) + 4) * cc_dim1 + 2] - cc[((k << 2) + 2) * cc_dim1 
+		+ 2];
+	ti3 = cc[((k << 2) + 2) * cc_dim1 + 2] + cc[((k << 2) + 4) * cc_dim1 
+		+ 2];
+	tr1 = cc[((k << 2) + 1) * cc_dim1 + 1] - cc[((k << 2) + 3) * cc_dim1 
+		+ 1];
+	tr2 = cc[((k << 2) + 1) * cc_dim1 + 1] + cc[((k << 2) + 3) * cc_dim1 
+		+ 1];
+	ti4 = cc[((k << 2) + 2) * cc_dim1 + 1] - cc[((k << 2) + 4) * cc_dim1 
+		+ 1];
+	tr3 = cc[((k << 2) + 2) * cc_dim1 + 1] + cc[((k << 2) + 4) * cc_dim1 
+		+ 1];
+	ch[(k + ch_dim2) * ch_dim1 + 1] = tr2 + tr3;
+	ch[(k + ch_dim2 * 3) * ch_dim1 + 1] = tr2 - tr3;
+	ch[(k + ch_dim2) * ch_dim1 + 2] = ti2 + ti3;
+	ch[(k + ch_dim2 * 3) * ch_dim1 + 2] = ti2 - ti3;
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 1] = tr1 + tr4;
+	ch[(k + (ch_dim2 << 2)) * ch_dim1 + 1] = tr1 - tr4;
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 2] = ti1 + ti4;
+	ch[(k + (ch_dim2 << 2)) * ch_dim1 + 2] = ti1 - ti4;
+/* L101: */
+    }
+    return 0;
+L102:
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 2; i__ <= i__2; i__ += 2) {
+	    ti1 = cc[i__ + ((k << 2) + 1) * cc_dim1] - cc[i__ + ((k << 2) + 3)
+		     * cc_dim1];
+	    ti2 = cc[i__ + ((k << 2) + 1) * cc_dim1] + cc[i__ + ((k << 2) + 3)
+		     * cc_dim1];
+	    ti3 = cc[i__ + ((k << 2) + 2) * cc_dim1] + cc[i__ + ((k << 2) + 4)
+		     * cc_dim1];
+	    tr4 = cc[i__ + ((k << 2) + 4) * cc_dim1] - cc[i__ + ((k << 2) + 2)
+		     * cc_dim1];
+	    tr1 = cc[i__ - 1 + ((k << 2) + 1) * cc_dim1] - cc[i__ - 1 + ((k <<
+		     2) + 3) * cc_dim1];
+	    tr2 = cc[i__ - 1 + ((k << 2) + 1) * cc_dim1] + cc[i__ - 1 + ((k <<
+		     2) + 3) * cc_dim1];
+	    ti4 = cc[i__ - 1 + ((k << 2) + 2) * cc_dim1] - cc[i__ - 1 + ((k <<
+		     2) + 4) * cc_dim1];
+	    tr3 = cc[i__ - 1 + ((k << 2) + 2) * cc_dim1] + cc[i__ - 1 + ((k <<
+		     2) + 4) * cc_dim1];
+	    ch[i__ - 1 + (k + ch_dim2) * ch_dim1] = tr2 + tr3;
+	    cr3 = tr2 - tr3;
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = ti2 + ti3;
+	    ci3 = ti2 - ti3;
+	    cr2 = tr1 + tr4;
+	    cr4 = tr1 - tr4;
+	    ci2 = ti1 + ti4;
+	    ci4 = ti1 - ti4;
+	    ch[i__ - 1 + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * cr2 
+		    - wa1[i__] * ci2;
+	    ch[i__ + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * ci2 + 
+		    wa1[i__] * cr2;
+	    ch[i__ - 1 + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 1] * cr3 - 
+		    wa2[i__] * ci3;
+	    ch[i__ + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 1] * ci3 + wa2[
+		    i__] * cr3;
+	    ch[i__ - 1 + (k + (ch_dim2 << 2)) * ch_dim1] = wa3[i__ - 1] * cr4 
+		    - wa3[i__] * ci4;
+	    ch[i__ + (k + (ch_dim2 << 2)) * ch_dim1] = wa3[i__ - 1] * ci4 + 
+		    wa3[i__] * cr4;
+/* L103: */
+	}
+/* L104: */
+    }
+    return 0;
+} /* passb4_ */
+
+/*  ------ File passb5.f ------ */
+/* Subroutine */ int passb5_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, 
+	r_4 *wa1, r_4 *wa2, r_4 *wa3, r_4 *wa4)
+{
+    /* Initialized data */
+
+    static r_4 tr11 = .309016994374947f;
+    static r_4 ti11 = .951056516295154f;
+    static r_4 tr12 = -.809016994374947f;
+    static r_4 ti12 = .587785252292473f;
+
+    /* System generated locals */
+    int_4 cc_dim1, cc_offset, ch_dim1, ch_dim2, ch_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k;
+    static r_4 ci2, ci3, ci4, ci5, di3, di4, di5, di2, cr2, cr3, cr5, cr4, 
+	    ti2, ti3, ti4, ti5, dr3, dr4, dr5, dr2, tr2, tr3, tr4, tr5;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_offset = cc_dim1 * 6 + 1;
+    cc -= cc_offset;
+    --wa1;
+    --wa2;
+    --wa3;
+    --wa4;
+
+    /* Function Body */
+    if (*ido != 2) {
+	goto L102;
+    }
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	ti5 = cc[(k * 5 + 2) * cc_dim1 + 2] - cc[(k * 5 + 5) * cc_dim1 + 2];
+	ti2 = cc[(k * 5 + 2) * cc_dim1 + 2] + cc[(k * 5 + 5) * cc_dim1 + 2];
+	ti4 = cc[(k * 5 + 3) * cc_dim1 + 2] - cc[(k * 5 + 4) * cc_dim1 + 2];
+	ti3 = cc[(k * 5 + 3) * cc_dim1 + 2] + cc[(k * 5 + 4) * cc_dim1 + 2];
+	tr5 = cc[(k * 5 + 2) * cc_dim1 + 1] - cc[(k * 5 + 5) * cc_dim1 + 1];
+	tr2 = cc[(k * 5 + 2) * cc_dim1 + 1] + cc[(k * 5 + 5) * cc_dim1 + 1];
+	tr4 = cc[(k * 5 + 3) * cc_dim1 + 1] - cc[(k * 5 + 4) * cc_dim1 + 1];
+	tr3 = cc[(k * 5 + 3) * cc_dim1 + 1] + cc[(k * 5 + 4) * cc_dim1 + 1];
+	ch[(k + ch_dim2) * ch_dim1 + 1] = cc[(k * 5 + 1) * cc_dim1 + 1] + tr2 
+		+ tr3;
+	ch[(k + ch_dim2) * ch_dim1 + 2] = cc[(k * 5 + 1) * cc_dim1 + 2] + ti2 
+		+ ti3;
+	cr2 = cc[(k * 5 + 1) * cc_dim1 + 1] + tr11 * tr2 + tr12 * tr3;
+	ci2 = cc[(k * 5 + 1) * cc_dim1 + 2] + tr11 * ti2 + tr12 * ti3;
+	cr3 = cc[(k * 5 + 1) * cc_dim1 + 1] + tr12 * tr2 + tr11 * tr3;
+	ci3 = cc[(k * 5 + 1) * cc_dim1 + 2] + tr12 * ti2 + tr11 * ti3;
+	cr5 = ti11 * tr5 + ti12 * tr4;
+	ci5 = ti11 * ti5 + ti12 * ti4;
+	cr4 = ti12 * tr5 - ti11 * tr4;
+	ci4 = ti12 * ti5 - ti11 * ti4;
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 1] = cr2 - ci5;
+	ch[(k + ch_dim2 * 5) * ch_dim1 + 1] = cr2 + ci5;
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 2] = ci2 + cr5;
+	ch[(k + ch_dim2 * 3) * ch_dim1 + 2] = ci3 + cr4;
+	ch[(k + ch_dim2 * 3) * ch_dim1 + 1] = cr3 - ci4;
+	ch[(k + (ch_dim2 << 2)) * ch_dim1 + 1] = cr3 + ci4;
+	ch[(k + (ch_dim2 << 2)) * ch_dim1 + 2] = ci3 - cr4;
+	ch[(k + ch_dim2 * 5) * ch_dim1 + 2] = ci2 - cr5;
+/* L101: */
+    }
+    return 0;
+L102:
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 2; i__ <= i__2; i__ += 2) {
+	    ti5 = cc[i__ + (k * 5 + 2) * cc_dim1] - cc[i__ + (k * 5 + 5) * 
+		    cc_dim1];
+	    ti2 = cc[i__ + (k * 5 + 2) * cc_dim1] + cc[i__ + (k * 5 + 5) * 
+		    cc_dim1];
+	    ti4 = cc[i__ + (k * 5 + 3) * cc_dim1] - cc[i__ + (k * 5 + 4) * 
+		    cc_dim1];
+	    ti3 = cc[i__ + (k * 5 + 3) * cc_dim1] + cc[i__ + (k * 5 + 4) * 
+		    cc_dim1];
+	    tr5 = cc[i__ - 1 + (k * 5 + 2) * cc_dim1] - cc[i__ - 1 + (k * 5 + 
+		    5) * cc_dim1];
+	    tr2 = cc[i__ - 1 + (k * 5 + 2) * cc_dim1] + cc[i__ - 1 + (k * 5 + 
+		    5) * cc_dim1];
+	    tr4 = cc[i__ - 1 + (k * 5 + 3) * cc_dim1] - cc[i__ - 1 + (k * 5 + 
+		    4) * cc_dim1];
+	    tr3 = cc[i__ - 1 + (k * 5 + 3) * cc_dim1] + cc[i__ - 1 + (k * 5 + 
+		    4) * cc_dim1];
+	    ch[i__ - 1 + (k + ch_dim2) * ch_dim1] = cc[i__ - 1 + (k * 5 + 1) *
+		     cc_dim1] + tr2 + tr3;
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = cc[i__ + (k * 5 + 1) * 
+		    cc_dim1] + ti2 + ti3;
+	    cr2 = cc[i__ - 1 + (k * 5 + 1) * cc_dim1] + tr11 * tr2 + tr12 * 
+		    tr3;
+	    ci2 = cc[i__ + (k * 5 + 1) * cc_dim1] + tr11 * ti2 + tr12 * ti3;
+	    cr3 = cc[i__ - 1 + (k * 5 + 1) * cc_dim1] + tr12 * tr2 + tr11 * 
+		    tr3;
+	    ci3 = cc[i__ + (k * 5 + 1) * cc_dim1] + tr12 * ti2 + tr11 * ti3;
+	    cr5 = ti11 * tr5 + ti12 * tr4;
+	    ci5 = ti11 * ti5 + ti12 * ti4;
+	    cr4 = ti12 * tr5 - ti11 * tr4;
+	    ci4 = ti12 * ti5 - ti11 * ti4;
+	    dr3 = cr3 - ci4;
+	    dr4 = cr3 + ci4;
+	    di3 = ci3 + cr4;
+	    di4 = ci3 - cr4;
+	    dr5 = cr2 + ci5;
+	    dr2 = cr2 - ci5;
+	    di5 = ci2 - cr5;
+	    di2 = ci2 + cr5;
+	    ch[i__ - 1 + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * dr2 
+		    - wa1[i__] * di2;
+	    ch[i__ + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * di2 + 
+		    wa1[i__] * dr2;
+	    ch[i__ - 1 + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 1] * dr3 - 
+		    wa2[i__] * di3;
+	    ch[i__ + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 1] * di3 + wa2[
+		    i__] * dr3;
+	    ch[i__ - 1 + (k + (ch_dim2 << 2)) * ch_dim1] = wa3[i__ - 1] * dr4 
+		    - wa3[i__] * di4;
+	    ch[i__ + (k + (ch_dim2 << 2)) * ch_dim1] = wa3[i__ - 1] * di4 + 
+		    wa3[i__] * dr4;
+	    ch[i__ - 1 + (k + ch_dim2 * 5) * ch_dim1] = wa4[i__ - 1] * dr5 - 
+		    wa4[i__] * di5;
+	    ch[i__ + (k + ch_dim2 * 5) * ch_dim1] = wa4[i__ - 1] * di5 + wa4[
+		    i__] * dr5;
+/* L103: */
+	}
+/* L104: */
+    }
+    return 0;
+} /* passb5_ */
+
+/*  ------ File passf.f ------ */
+/* Subroutine */ int passf_(int_4 *nac, int_4 *ido, int_4 *ip, int_4 *
+	l1, int_4 *idl1, r_4 *cc, r_4 *c1, r_4 *c2, r_4 *ch, r_4 *ch2, 
+	r_4 *wa)
+{
+    /* System generated locals */
+    int_4 ch_dim1, ch_dim2, ch_offset, cc_dim1, cc_dim2, cc_offset, c1_dim1,
+	     c1_dim2, c1_offset, c2_dim1, c2_offset, ch2_dim1, ch2_offset, 
+	    i__1, i__2, i__3;
+
+    /* Local variables */
+    static int_4 idij, idlj, idot, ipph, i__, j, k, l, jc, lc, ik, nt, idj, 
+	    idl, inc, idp;
+    static r_4 wai, war;
+    static int_4 ipp2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    c1_dim1 = *ido;
+    c1_dim2 = *l1;
+    c1_offset = c1_dim1 * (c1_dim2 + 1) + 1;
+    c1 -= c1_offset;
+    cc_dim1 = *ido;
+    cc_dim2 = *ip;
+    cc_offset = cc_dim1 * (cc_dim2 + 1) + 1;
+    cc -= cc_offset;
+    ch2_dim1 = *idl1;
+    ch2_offset = ch2_dim1 + 1;
+    ch2 -= ch2_offset;
+    c2_dim1 = *idl1;
+    c2_offset = c2_dim1 + 1;
+    c2 -= c2_offset;
+    --wa;
+
+    /* Function Body */
+    idot = *ido / 2;
+    nt = *ip * *idl1;
+    ipp2 = *ip + 2;
+    ipph = (*ip + 1) / 2;
+    idp = *ip * *ido;
+
+    if (*ido < *l1) {
+	goto L106;
+    }
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    i__3 = *ido;
+	    for (i__ = 1; i__ <= i__3; ++i__) {
+		ch[i__ + (k + j * ch_dim2) * ch_dim1] = cc[i__ + (j + k * 
+			cc_dim2) * cc_dim1] + cc[i__ + (jc + k * cc_dim2) * 
+			cc_dim1];
+		ch[i__ + (k + jc * ch_dim2) * ch_dim1] = cc[i__ + (j + k * 
+			cc_dim2) * cc_dim1] - cc[i__ + (jc + k * cc_dim2) * 
+			cc_dim1];
+/* L101: */
+	    }
+/* L102: */
+	}
+/* L103: */
+    }
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 1; i__ <= i__2; ++i__) {
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = cc[i__ + (k * cc_dim2 + 1) * 
+		    cc_dim1];
+/* L104: */
+	}
+/* L105: */
+    }
+    goto L112;
+L106:
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	i__2 = *ido;
+	for (i__ = 1; i__ <= i__2; ++i__) {
+	    i__3 = *l1;
+	    for (k = 1; k <= i__3; ++k) {
+		ch[i__ + (k + j * ch_dim2) * ch_dim1] = cc[i__ + (j + k * 
+			cc_dim2) * cc_dim1] + cc[i__ + (jc + k * cc_dim2) * 
+			cc_dim1];
+		ch[i__ + (k + jc * ch_dim2) * ch_dim1] = cc[i__ + (j + k * 
+			cc_dim2) * cc_dim1] - cc[i__ + (jc + k * cc_dim2) * 
+			cc_dim1];
+/* L107: */
+	    }
+/* L108: */
+	}
+/* L109: */
+    }
+    i__1 = *ido;
+    for (i__ = 1; i__ <= i__1; ++i__) {
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = cc[i__ + (k * cc_dim2 + 1) * 
+		    cc_dim1];
+/* L110: */
+	}
+/* L111: */
+    }
+L112:
+    idl = 2 - *ido;
+    inc = 0;
+    i__1 = ipph;
+    for (l = 2; l <= i__1; ++l) {
+	lc = ipp2 - l;
+	idl += *ido;
+	i__2 = *idl1;
+	for (ik = 1; ik <= i__2; ++ik) {
+	    c2[ik + l * c2_dim1] = ch2[ik + ch2_dim1] + wa[idl - 1] * ch2[ik 
+		    + (ch2_dim1 << 1)];
+	    c2[ik + lc * c2_dim1] = -wa[idl] * ch2[ik + *ip * ch2_dim1];
+/* L113: */
+	}
+	idlj = idl;
+	inc += *ido;
+	i__2 = ipph;
+	for (j = 3; j <= i__2; ++j) {
+	    jc = ipp2 - j;
+	    idlj += inc;
+	    if (idlj > idp) {
+		idlj -= idp;
+	    }
+	    war = wa[idlj - 1];
+	    wai = wa[idlj];
+	    i__3 = *idl1;
+	    for (ik = 1; ik <= i__3; ++ik) {
+		c2[ik + l * c2_dim1] += war * ch2[ik + j * ch2_dim1];
+		c2[ik + lc * c2_dim1] -= wai * ch2[ik + jc * ch2_dim1];
+/* L114: */
+	    }
+/* L115: */
+	}
+/* L116: */
+    }
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	i__2 = *idl1;
+	for (ik = 1; ik <= i__2; ++ik) {
+	    ch2[ik + ch2_dim1] += ch2[ik + j * ch2_dim1];
+/* L117: */
+	}
+/* L118: */
+    }
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	i__2 = *idl1;
+	for (ik = 2; ik <= i__2; ik += 2) {
+	    ch2[ik - 1 + j * ch2_dim1] = c2[ik - 1 + j * c2_dim1] - c2[ik + 
+		    jc * c2_dim1];
+	    ch2[ik - 1 + jc * ch2_dim1] = c2[ik - 1 + j * c2_dim1] + c2[ik + 
+		    jc * c2_dim1];
+	    ch2[ik + j * ch2_dim1] = c2[ik + j * c2_dim1] + c2[ik - 1 + jc * 
+		    c2_dim1];
+	    ch2[ik + jc * ch2_dim1] = c2[ik + j * c2_dim1] - c2[ik - 1 + jc * 
+		    c2_dim1];
+/* L119: */
+	}
+/* L120: */
+    }
+    *nac = 1;
+    if (*ido == 2) {
+	return 0;
+    }
+    *nac = 0;
+    i__1 = *idl1;
+    for (ik = 1; ik <= i__1; ++ik) {
+	c2[ik + c2_dim1] = ch2[ik + ch2_dim1];
+/* L121: */
+    }
+    i__1 = *ip;
+    for (j = 2; j <= i__1; ++j) {
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    c1[(k + j * c1_dim2) * c1_dim1 + 1] = ch[(k + j * ch_dim2) * 
+		    ch_dim1 + 1];
+	    c1[(k + j * c1_dim2) * c1_dim1 + 2] = ch[(k + j * ch_dim2) * 
+		    ch_dim1 + 2];
+/* L122: */
+	}
+/* L123: */
+    }
+    if (idot > *l1) {
+	goto L127;
+    }
+    idij = 0;
+    i__1 = *ip;
+    for (j = 2; j <= i__1; ++j) {
+	idij += 2;
+	i__2 = *ido;
+	for (i__ = 4; i__ <= i__2; i__ += 2) {
+	    idij += 2;
+	    i__3 = *l1;
+	    for (k = 1; k <= i__3; ++k) {
+		c1[i__ - 1 + (k + j * c1_dim2) * c1_dim1] = wa[idij - 1] * ch[
+			i__ - 1 + (k + j * ch_dim2) * ch_dim1] + wa[idij] * 
+			ch[i__ + (k + j * ch_dim2) * ch_dim1];
+		c1[i__ + (k + j * c1_dim2) * c1_dim1] = wa[idij - 1] * ch[i__ 
+			+ (k + j * ch_dim2) * ch_dim1] - wa[idij] * ch[i__ - 
+			1 + (k + j * ch_dim2) * ch_dim1];
+/* L124: */
+	    }
+/* L125: */
+	}
+/* L126: */
+    }
+    return 0;
+L127:
+    idj = 2 - *ido;
+    i__1 = *ip;
+    for (j = 2; j <= i__1; ++j) {
+	idj += *ido;
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    idij = idj;
+	    i__3 = *ido;
+	    for (i__ = 4; i__ <= i__3; i__ += 2) {
+		idij += 2;
+		c1[i__ - 1 + (k + j * c1_dim2) * c1_dim1] = wa[idij - 1] * ch[
+			i__ - 1 + (k + j * ch_dim2) * ch_dim1] + wa[idij] * 
+			ch[i__ + (k + j * ch_dim2) * ch_dim1];
+		c1[i__ + (k + j * c1_dim2) * c1_dim1] = wa[idij - 1] * ch[i__ 
+			+ (k + j * ch_dim2) * ch_dim1] - wa[idij] * ch[i__ - 
+			1 + (k + j * ch_dim2) * ch_dim1];
+/* L128: */
+	    }
+/* L129: */
+	}
+/* L130: */
+    }
+    return 0;
+} /* passf_ */
+
+/*  ------ File passf2.f ------ */
+/* Subroutine */ int passf2_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, 
+	r_4 *wa1)
+{
+    /* System generated locals */
+    int_4 cc_dim1, cc_offset, ch_dim1, ch_dim2, ch_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k;
+    static r_4 ti2, tr2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_offset = cc_dim1 * 3 + 1;
+    cc -= cc_offset;
+    --wa1;
+
+    /* Function Body */
+    if (*ido > 2) {
+	goto L102;
+    }
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	ch[(k + ch_dim2) * ch_dim1 + 1] = cc[((k << 1) + 1) * cc_dim1 + 1] + 
+		cc[((k << 1) + 2) * cc_dim1 + 1];
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 1] = cc[((k << 1) + 1) * cc_dim1 
+		+ 1] - cc[((k << 1) + 2) * cc_dim1 + 1];
+	ch[(k + ch_dim2) * ch_dim1 + 2] = cc[((k << 1) + 1) * cc_dim1 + 2] + 
+		cc[((k << 1) + 2) * cc_dim1 + 2];
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 2] = cc[((k << 1) + 1) * cc_dim1 
+		+ 2] - cc[((k << 1) + 2) * cc_dim1 + 2];
+/* L101: */
+    }
+    return 0;
+L102:
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 2; i__ <= i__2; i__ += 2) {
+	    ch[i__ - 1 + (k + ch_dim2) * ch_dim1] = cc[i__ - 1 + ((k << 1) + 
+		    1) * cc_dim1] + cc[i__ - 1 + ((k << 1) + 2) * cc_dim1];
+	    tr2 = cc[i__ - 1 + ((k << 1) + 1) * cc_dim1] - cc[i__ - 1 + ((k <<
+		     1) + 2) * cc_dim1];
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = cc[i__ + ((k << 1) + 1) * 
+		    cc_dim1] + cc[i__ + ((k << 1) + 2) * cc_dim1];
+	    ti2 = cc[i__ + ((k << 1) + 1) * cc_dim1] - cc[i__ + ((k << 1) + 2)
+		     * cc_dim1];
+	    ch[i__ + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * ti2 - 
+		    wa1[i__] * tr2;
+	    ch[i__ - 1 + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * tr2 
+		    + wa1[i__] * ti2;
+/* L103: */
+	}
+/* L104: */
+    }
+    return 0;
+} /* passf2_ */
+
+/*  ------ File passf3.f ------ */
+/* Subroutine */ int passf3_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, 
+	r_4 *wa1, r_4 *wa2)
+{
+    /* Initialized data */
+
+    static r_4 taur = -.5f;
+    static r_4 taui = -.866025403784439f;
+
+    /* System generated locals */
+    int_4 cc_dim1, cc_offset, ch_dim1, ch_dim2, ch_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k;
+    static r_4 ci2, ci3, di2, di3, cr2, cr3, dr2, dr3, ti2, tr2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_offset = (cc_dim1 << 2) + 1;
+    cc -= cc_offset;
+    --wa1;
+    --wa2;
+
+    /* Function Body */
+    if (*ido != 2) {
+	goto L102;
+    }
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	tr2 = cc[(k * 3 + 2) * cc_dim1 + 1] + cc[(k * 3 + 3) * cc_dim1 + 1];
+	cr2 = cc[(k * 3 + 1) * cc_dim1 + 1] + taur * tr2;
+	ch[(k + ch_dim2) * ch_dim1 + 1] = cc[(k * 3 + 1) * cc_dim1 + 1] + tr2;
+	ti2 = cc[(k * 3 + 2) * cc_dim1 + 2] + cc[(k * 3 + 3) * cc_dim1 + 2];
+	ci2 = cc[(k * 3 + 1) * cc_dim1 + 2] + taur * ti2;
+	ch[(k + ch_dim2) * ch_dim1 + 2] = cc[(k * 3 + 1) * cc_dim1 + 2] + ti2;
+	cr3 = taui * (cc[(k * 3 + 2) * cc_dim1 + 1] - cc[(k * 3 + 3) * 
+		cc_dim1 + 1]);
+	ci3 = taui * (cc[(k * 3 + 2) * cc_dim1 + 2] - cc[(k * 3 + 3) * 
+		cc_dim1 + 2]);
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 1] = cr2 - ci3;
+	ch[(k + ch_dim2 * 3) * ch_dim1 + 1] = cr2 + ci3;
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 2] = ci2 + cr3;
+	ch[(k + ch_dim2 * 3) * ch_dim1 + 2] = ci2 - cr3;
+/* L101: */
+    }
+    return 0;
+L102:
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 2; i__ <= i__2; i__ += 2) {
+	    tr2 = cc[i__ - 1 + (k * 3 + 2) * cc_dim1] + cc[i__ - 1 + (k * 3 + 
+		    3) * cc_dim1];
+	    cr2 = cc[i__ - 1 + (k * 3 + 1) * cc_dim1] + taur * tr2;
+	    ch[i__ - 1 + (k + ch_dim2) * ch_dim1] = cc[i__ - 1 + (k * 3 + 1) *
+		     cc_dim1] + tr2;
+	    ti2 = cc[i__ + (k * 3 + 2) * cc_dim1] + cc[i__ + (k * 3 + 3) * 
+		    cc_dim1];
+	    ci2 = cc[i__ + (k * 3 + 1) * cc_dim1] + taur * ti2;
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = cc[i__ + (k * 3 + 1) * 
+		    cc_dim1] + ti2;
+	    cr3 = taui * (cc[i__ - 1 + (k * 3 + 2) * cc_dim1] - cc[i__ - 1 + (
+		    k * 3 + 3) * cc_dim1]);
+	    ci3 = taui * (cc[i__ + (k * 3 + 2) * cc_dim1] - cc[i__ + (k * 3 + 
+		    3) * cc_dim1]);
+	    dr2 = cr2 - ci3;
+	    dr3 = cr2 + ci3;
+	    di2 = ci2 + cr3;
+	    di3 = ci2 - cr3;
+	    ch[i__ + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * di2 - 
+		    wa1[i__] * dr2;
+	    ch[i__ - 1 + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * dr2 
+		    + wa1[i__] * di2;
+	    ch[i__ + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 1] * di3 - wa2[
+		    i__] * dr3;
+	    ch[i__ - 1 + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 1] * dr3 + 
+		    wa2[i__] * di3;
+/* L103: */
+	}
+/* L104: */
+    }
+    return 0;
+} /* passf3_ */
+
+/*  ------ File passf4.f ------ */
+/* Subroutine */ int passf4_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, 
+	r_4 *wa1, r_4 *wa2, r_4 *wa3)
+{
+    /* System generated locals */
+    int_4 cc_dim1, cc_offset, ch_dim1, ch_dim2, ch_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k;
+    static r_4 ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, 
+	    tr3, tr4;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_offset = cc_dim1 * 5 + 1;
+    cc -= cc_offset;
+    --wa1;
+    --wa2;
+    --wa3;
+
+    /* Function Body */
+    if (*ido != 2) {
+	goto L102;
+    }
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	ti1 = cc[((k << 2) + 1) * cc_dim1 + 2] - cc[((k << 2) + 3) * cc_dim1 
+		+ 2];
+	ti2 = cc[((k << 2) + 1) * cc_dim1 + 2] + cc[((k << 2) + 3) * cc_dim1 
+		+ 2];
+	tr4 = cc[((k << 2) + 2) * cc_dim1 + 2] - cc[((k << 2) + 4) * cc_dim1 
+		+ 2];
+	ti3 = cc[((k << 2) + 2) * cc_dim1 + 2] + cc[((k << 2) + 4) * cc_dim1 
+		+ 2];
+	tr1 = cc[((k << 2) + 1) * cc_dim1 + 1] - cc[((k << 2) + 3) * cc_dim1 
+		+ 1];
+	tr2 = cc[((k << 2) + 1) * cc_dim1 + 1] + cc[((k << 2) + 3) * cc_dim1 
+		+ 1];
+	ti4 = cc[((k << 2) + 4) * cc_dim1 + 1] - cc[((k << 2) + 2) * cc_dim1 
+		+ 1];
+	tr3 = cc[((k << 2) + 2) * cc_dim1 + 1] + cc[((k << 2) + 4) * cc_dim1 
+		+ 1];
+	ch[(k + ch_dim2) * ch_dim1 + 1] = tr2 + tr3;
+	ch[(k + ch_dim2 * 3) * ch_dim1 + 1] = tr2 - tr3;
+	ch[(k + ch_dim2) * ch_dim1 + 2] = ti2 + ti3;
+	ch[(k + ch_dim2 * 3) * ch_dim1 + 2] = ti2 - ti3;
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 1] = tr1 + tr4;
+	ch[(k + (ch_dim2 << 2)) * ch_dim1 + 1] = tr1 - tr4;
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 2] = ti1 + ti4;
+	ch[(k + (ch_dim2 << 2)) * ch_dim1 + 2] = ti1 - ti4;
+/* L101: */
+    }
+    return 0;
+L102:
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 2; i__ <= i__2; i__ += 2) {
+	    ti1 = cc[i__ + ((k << 2) + 1) * cc_dim1] - cc[i__ + ((k << 2) + 3)
+		     * cc_dim1];
+	    ti2 = cc[i__ + ((k << 2) + 1) * cc_dim1] + cc[i__ + ((k << 2) + 3)
+		     * cc_dim1];
+	    ti3 = cc[i__ + ((k << 2) + 2) * cc_dim1] + cc[i__ + ((k << 2) + 4)
+		     * cc_dim1];
+	    tr4 = cc[i__ + ((k << 2) + 2) * cc_dim1] - cc[i__ + ((k << 2) + 4)
+		     * cc_dim1];
+	    tr1 = cc[i__ - 1 + ((k << 2) + 1) * cc_dim1] - cc[i__ - 1 + ((k <<
+		     2) + 3) * cc_dim1];
+	    tr2 = cc[i__ - 1 + ((k << 2) + 1) * cc_dim1] + cc[i__ - 1 + ((k <<
+		     2) + 3) * cc_dim1];
+	    ti4 = cc[i__ - 1 + ((k << 2) + 4) * cc_dim1] - cc[i__ - 1 + ((k <<
+		     2) + 2) * cc_dim1];
+	    tr3 = cc[i__ - 1 + ((k << 2) + 2) * cc_dim1] + cc[i__ - 1 + ((k <<
+		     2) + 4) * cc_dim1];
+	    ch[i__ - 1 + (k + ch_dim2) * ch_dim1] = tr2 + tr3;
+	    cr3 = tr2 - tr3;
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = ti2 + ti3;
+	    ci3 = ti2 - ti3;
+	    cr2 = tr1 + tr4;
+	    cr4 = tr1 - tr4;
+	    ci2 = ti1 + ti4;
+	    ci4 = ti1 - ti4;
+	    ch[i__ - 1 + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * cr2 
+		    + wa1[i__] * ci2;
+	    ch[i__ + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * ci2 - 
+		    wa1[i__] * cr2;
+	    ch[i__ - 1 + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 1] * cr3 + 
+		    wa2[i__] * ci3;
+	    ch[i__ + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 1] * ci3 - wa2[
+		    i__] * cr3;
+	    ch[i__ - 1 + (k + (ch_dim2 << 2)) * ch_dim1] = wa3[i__ - 1] * cr4 
+		    + wa3[i__] * ci4;
+	    ch[i__ + (k + (ch_dim2 << 2)) * ch_dim1] = wa3[i__ - 1] * ci4 - 
+		    wa3[i__] * cr4;
+/* L103: */
+	}
+/* L104: */
+    }
+    return 0;
+} /* passf4_ */
+
+/*  ------ File passf5.f ------ */
+/* Subroutine */ int passf5_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, 
+	r_4 *wa1, r_4 *wa2, r_4 *wa3, r_4 *wa4)
+{
+    /* Initialized data */
+
+    static r_4 tr11 = .309016994374947f;
+    static r_4 ti11 = -.951056516295154f;
+    static r_4 tr12 = -.809016994374947f;
+    static r_4 ti12 = -.587785252292473f;
+
+    /* System generated locals */
+    int_4 cc_dim1, cc_offset, ch_dim1, ch_dim2, ch_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k;
+    static r_4 ci2, ci3, ci4, ci5, di3, di4, di5, di2, cr2, cr3, cr5, cr4, 
+	    ti2, ti3, ti4, ti5, dr3, dr4, dr5, dr2, tr2, tr3, tr4, tr5;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_offset = cc_dim1 * 6 + 1;
+    cc -= cc_offset;
+    --wa1;
+    --wa2;
+    --wa3;
+    --wa4;
+
+    /* Function Body */
+    if (*ido != 2) {
+	goto L102;
+    }
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	ti5 = cc[(k * 5 + 2) * cc_dim1 + 2] - cc[(k * 5 + 5) * cc_dim1 + 2];
+	ti2 = cc[(k * 5 + 2) * cc_dim1 + 2] + cc[(k * 5 + 5) * cc_dim1 + 2];
+	ti4 = cc[(k * 5 + 3) * cc_dim1 + 2] - cc[(k * 5 + 4) * cc_dim1 + 2];
+	ti3 = cc[(k * 5 + 3) * cc_dim1 + 2] + cc[(k * 5 + 4) * cc_dim1 + 2];
+	tr5 = cc[(k * 5 + 2) * cc_dim1 + 1] - cc[(k * 5 + 5) * cc_dim1 + 1];
+	tr2 = cc[(k * 5 + 2) * cc_dim1 + 1] + cc[(k * 5 + 5) * cc_dim1 + 1];
+	tr4 = cc[(k * 5 + 3) * cc_dim1 + 1] - cc[(k * 5 + 4) * cc_dim1 + 1];
+	tr3 = cc[(k * 5 + 3) * cc_dim1 + 1] + cc[(k * 5 + 4) * cc_dim1 + 1];
+	ch[(k + ch_dim2) * ch_dim1 + 1] = cc[(k * 5 + 1) * cc_dim1 + 1] + tr2 
+		+ tr3;
+	ch[(k + ch_dim2) * ch_dim1 + 2] = cc[(k * 5 + 1) * cc_dim1 + 2] + ti2 
+		+ ti3;
+	cr2 = cc[(k * 5 + 1) * cc_dim1 + 1] + tr11 * tr2 + tr12 * tr3;
+	ci2 = cc[(k * 5 + 1) * cc_dim1 + 2] + tr11 * ti2 + tr12 * ti3;
+	cr3 = cc[(k * 5 + 1) * cc_dim1 + 1] + tr12 * tr2 + tr11 * tr3;
+	ci3 = cc[(k * 5 + 1) * cc_dim1 + 2] + tr12 * ti2 + tr11 * ti3;
+	cr5 = ti11 * tr5 + ti12 * tr4;
+	ci5 = ti11 * ti5 + ti12 * ti4;
+	cr4 = ti12 * tr5 - ti11 * tr4;
+	ci4 = ti12 * ti5 - ti11 * ti4;
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 1] = cr2 - ci5;
+	ch[(k + ch_dim2 * 5) * ch_dim1 + 1] = cr2 + ci5;
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 2] = ci2 + cr5;
+	ch[(k + ch_dim2 * 3) * ch_dim1 + 2] = ci3 + cr4;
+	ch[(k + ch_dim2 * 3) * ch_dim1 + 1] = cr3 - ci4;
+	ch[(k + (ch_dim2 << 2)) * ch_dim1 + 1] = cr3 + ci4;
+	ch[(k + (ch_dim2 << 2)) * ch_dim1 + 2] = ci3 - cr4;
+	ch[(k + ch_dim2 * 5) * ch_dim1 + 2] = ci2 - cr5;
+/* L101: */
+    }
+    return 0;
+L102:
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 2; i__ <= i__2; i__ += 2) {
+	    ti5 = cc[i__ + (k * 5 + 2) * cc_dim1] - cc[i__ + (k * 5 + 5) * 
+		    cc_dim1];
+	    ti2 = cc[i__ + (k * 5 + 2) * cc_dim1] + cc[i__ + (k * 5 + 5) * 
+		    cc_dim1];
+	    ti4 = cc[i__ + (k * 5 + 3) * cc_dim1] - cc[i__ + (k * 5 + 4) * 
+		    cc_dim1];
+	    ti3 = cc[i__ + (k * 5 + 3) * cc_dim1] + cc[i__ + (k * 5 + 4) * 
+		    cc_dim1];
+	    tr5 = cc[i__ - 1 + (k * 5 + 2) * cc_dim1] - cc[i__ - 1 + (k * 5 + 
+		    5) * cc_dim1];
+	    tr2 = cc[i__ - 1 + (k * 5 + 2) * cc_dim1] + cc[i__ - 1 + (k * 5 + 
+		    5) * cc_dim1];
+	    tr4 = cc[i__ - 1 + (k * 5 + 3) * cc_dim1] - cc[i__ - 1 + (k * 5 + 
+		    4) * cc_dim1];
+	    tr3 = cc[i__ - 1 + (k * 5 + 3) * cc_dim1] + cc[i__ - 1 + (k * 5 + 
+		    4) * cc_dim1];
+	    ch[i__ - 1 + (k + ch_dim2) * ch_dim1] = cc[i__ - 1 + (k * 5 + 1) *
+		     cc_dim1] + tr2 + tr3;
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = cc[i__ + (k * 5 + 1) * 
+		    cc_dim1] + ti2 + ti3;
+	    cr2 = cc[i__ - 1 + (k * 5 + 1) * cc_dim1] + tr11 * tr2 + tr12 * 
+		    tr3;
+	    ci2 = cc[i__ + (k * 5 + 1) * cc_dim1] + tr11 * ti2 + tr12 * ti3;
+	    cr3 = cc[i__ - 1 + (k * 5 + 1) * cc_dim1] + tr12 * tr2 + tr11 * 
+		    tr3;
+	    ci3 = cc[i__ + (k * 5 + 1) * cc_dim1] + tr12 * ti2 + tr11 * ti3;
+	    cr5 = ti11 * tr5 + ti12 * tr4;
+	    ci5 = ti11 * ti5 + ti12 * ti4;
+	    cr4 = ti12 * tr5 - ti11 * tr4;
+	    ci4 = ti12 * ti5 - ti11 * ti4;
+	    dr3 = cr3 - ci4;
+	    dr4 = cr3 + ci4;
+	    di3 = ci3 + cr4;
+	    di4 = ci3 - cr4;
+	    dr5 = cr2 + ci5;
+	    dr2 = cr2 - ci5;
+	    di5 = ci2 - cr5;
+	    di2 = ci2 + cr5;
+	    ch[i__ - 1 + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * dr2 
+		    + wa1[i__] * di2;
+	    ch[i__ + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * di2 - 
+		    wa1[i__] * dr2;
+	    ch[i__ - 1 + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 1] * dr3 + 
+		    wa2[i__] * di3;
+	    ch[i__ + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 1] * di3 - wa2[
+		    i__] * dr3;
+	    ch[i__ - 1 + (k + (ch_dim2 << 2)) * ch_dim1] = wa3[i__ - 1] * dr4 
+		    + wa3[i__] * di4;
+	    ch[i__ + (k + (ch_dim2 << 2)) * ch_dim1] = wa3[i__ - 1] * di4 - 
+		    wa3[i__] * dr4;
+	    ch[i__ - 1 + (k + ch_dim2 * 5) * ch_dim1] = wa4[i__ - 1] * dr5 + 
+		    wa4[i__] * di5;
+	    ch[i__ + (k + ch_dim2 * 5) * ch_dim1] = wa4[i__ - 1] * di5 - wa4[
+		    i__] * dr5;
+/* L103: */
+	}
+/* L104: */
+    }
+    return 0;
+} /* passf5_ */
+
+/*  ------ File radb2.f ------ */
+/* Subroutine */ int radb2_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, 
+	r_4 *wa1)
+{
+    /* System generated locals */
+    int_4 cc_dim1, cc_offset, ch_dim1, ch_dim2, ch_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k, ic;
+    static r_4 ti2, tr2;
+    static int_4 idp2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_offset = cc_dim1 * 3 + 1;
+    cc -= cc_offset;
+    --wa1;
+
+    /* Function Body */
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	ch[(k + ch_dim2) * ch_dim1 + 1] = cc[((k << 1) + 1) * cc_dim1 + 1] + 
+		cc[*ido + ((k << 1) + 2) * cc_dim1];
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 1] = cc[((k << 1) + 1) * cc_dim1 
+		+ 1] - cc[*ido + ((k << 1) + 2) * cc_dim1];
+/* L101: */
+    }
+    if ((i__1 = *ido - 2) < 0) {
+	goto L107;
+    } else if (i__1 == 0) {
+	goto L105;
+    } else {
+	goto L102;
+    }
+L102:
+    idp2 = *ido + 2;
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 3; i__ <= i__2; i__ += 2) {
+	    ic = idp2 - i__;
+	    ch[i__ - 1 + (k + ch_dim2) * ch_dim1] = cc[i__ - 1 + ((k << 1) + 
+		    1) * cc_dim1] + cc[ic - 1 + ((k << 1) + 2) * cc_dim1];
+	    tr2 = cc[i__ - 1 + ((k << 1) + 1) * cc_dim1] - cc[ic - 1 + ((k << 
+		    1) + 2) * cc_dim1];
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = cc[i__ + ((k << 1) + 1) * 
+		    cc_dim1] - cc[ic + ((k << 1) + 2) * cc_dim1];
+	    ti2 = cc[i__ + ((k << 1) + 1) * cc_dim1] + cc[ic + ((k << 1) + 2) 
+		    * cc_dim1];
+	    ch[i__ - 1 + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 2] * tr2 
+		    - wa1[i__ - 1] * ti2;
+	    ch[i__ + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 2] * ti2 + 
+		    wa1[i__ - 1] * tr2;
+/* L103: */
+	}
+/* L104: */
+    }
+    if (*ido % 2 == 1) {
+	return 0;
+    }
+L105:
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	ch[*ido + (k + ch_dim2) * ch_dim1] = cc[*ido + ((k << 1) + 1) * 
+		cc_dim1] + cc[*ido + ((k << 1) + 1) * cc_dim1];
+	ch[*ido + (k + (ch_dim2 << 1)) * ch_dim1] = -(cc[((k << 1) + 2) * 
+		cc_dim1 + 1] + cc[((k << 1) + 2) * cc_dim1 + 1]);
+/* L106: */
+    }
+L107:
+    return 0;
+} /* radb2_ */
+
+/*  ------ File radb3.f ------ */
+/* Subroutine */ int radb3_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, 
+	r_4 *wa1, r_4 *wa2)
+{
+    /* Initialized data */
+
+    static r_4 taur = -.5f;
+    static r_4 taui = .866025403784439f;
+
+    /* System generated locals */
+    int_4 cc_dim1, cc_offset, ch_dim1, ch_dim2, ch_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k, ic;
+    static r_4 ci2, ci3, di2, di3, cr2, cr3, dr2, dr3, ti2, tr2;
+    static int_4 idp2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_offset = (cc_dim1 << 2) + 1;
+    cc -= cc_offset;
+    --wa1;
+    --wa2;
+
+    /* Function Body */
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	tr2 = cc[*ido + (k * 3 + 2) * cc_dim1] + cc[*ido + (k * 3 + 2) * 
+		cc_dim1];
+	cr2 = cc[(k * 3 + 1) * cc_dim1 + 1] + taur * tr2;
+	ch[(k + ch_dim2) * ch_dim1 + 1] = cc[(k * 3 + 1) * cc_dim1 + 1] + tr2;
+	ci3 = taui * (cc[(k * 3 + 3) * cc_dim1 + 1] + cc[(k * 3 + 3) * 
+		cc_dim1 + 1]);
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 1] = cr2 - ci3;
+	ch[(k + ch_dim2 * 3) * ch_dim1 + 1] = cr2 + ci3;
+/* L101: */
+    }
+    if (*ido == 1) {
+	return 0;
+    }
+    idp2 = *ido + 2;
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 3; i__ <= i__2; i__ += 2) {
+	    ic = idp2 - i__;
+	    tr2 = cc[i__ - 1 + (k * 3 + 3) * cc_dim1] + cc[ic - 1 + (k * 3 + 
+		    2) * cc_dim1];
+	    cr2 = cc[i__ - 1 + (k * 3 + 1) * cc_dim1] + taur * tr2;
+	    ch[i__ - 1 + (k + ch_dim2) * ch_dim1] = cc[i__ - 1 + (k * 3 + 1) *
+		     cc_dim1] + tr2;
+	    ti2 = cc[i__ + (k * 3 + 3) * cc_dim1] - cc[ic + (k * 3 + 2) * 
+		    cc_dim1];
+	    ci2 = cc[i__ + (k * 3 + 1) * cc_dim1] + taur * ti2;
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = cc[i__ + (k * 3 + 1) * 
+		    cc_dim1] + ti2;
+	    cr3 = taui * (cc[i__ - 1 + (k * 3 + 3) * cc_dim1] - cc[ic - 1 + (
+		    k * 3 + 2) * cc_dim1]);
+	    ci3 = taui * (cc[i__ + (k * 3 + 3) * cc_dim1] + cc[ic + (k * 3 + 
+		    2) * cc_dim1]);
+	    dr2 = cr2 - ci3;
+	    dr3 = cr2 + ci3;
+	    di2 = ci2 + cr3;
+	    di3 = ci2 - cr3;
+	    ch[i__ - 1 + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 2] * dr2 
+		    - wa1[i__ - 1] * di2;
+	    ch[i__ + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 2] * di2 + 
+		    wa1[i__ - 1] * dr2;
+	    ch[i__ - 1 + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 2] * dr3 - 
+		    wa2[i__ - 1] * di3;
+	    ch[i__ + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 2] * di3 + wa2[
+		    i__ - 1] * dr3;
+/* L102: */
+	}
+/* L103: */
+    }
+    return 0;
+} /* radb3_ */
+
+/*  ------ File radb4.f ------ */
+/* Subroutine */ int radb4_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, 
+	r_4 *wa1, r_4 *wa2, r_4 *wa3)
+{
+    /* Initialized data */
+
+    static r_4 sqrt2 = 1.414213562373095f;
+
+    /* System generated locals */
+    int_4 cc_dim1, cc_offset, ch_dim1, ch_dim2, ch_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k, ic;
+    static r_4 ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, 
+	    tr3, tr4;
+    static int_4 idp2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_offset = cc_dim1 * 5 + 1;
+    cc -= cc_offset;
+    --wa1;
+    --wa2;
+    --wa3;
+
+    /* Function Body */
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	tr1 = cc[((k << 2) + 1) * cc_dim1 + 1] - cc[*ido + ((k << 2) + 4) * 
+		cc_dim1];
+	tr2 = cc[((k << 2) + 1) * cc_dim1 + 1] + cc[*ido + ((k << 2) + 4) * 
+		cc_dim1];
+	tr3 = cc[*ido + ((k << 2) + 2) * cc_dim1] + cc[*ido + ((k << 2) + 2) *
+		 cc_dim1];
+	tr4 = cc[((k << 2) + 3) * cc_dim1 + 1] + cc[((k << 2) + 3) * cc_dim1 
+		+ 1];
+	ch[(k + ch_dim2) * ch_dim1 + 1] = tr2 + tr3;
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 1] = tr1 - tr4;
+	ch[(k + ch_dim2 * 3) * ch_dim1 + 1] = tr2 - tr3;
+	ch[(k + (ch_dim2 << 2)) * ch_dim1 + 1] = tr1 + tr4;
+/* L101: */
+    }
+    if ((i__1 = *ido - 2) < 0) {
+	goto L107;
+    } else if (i__1 == 0) {
+	goto L105;
+    } else {
+	goto L102;
+    }
+L102:
+    idp2 = *ido + 2;
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 3; i__ <= i__2; i__ += 2) {
+	    ic = idp2 - i__;
+	    ti1 = cc[i__ + ((k << 2) + 1) * cc_dim1] + cc[ic + ((k << 2) + 4) 
+		    * cc_dim1];
+	    ti2 = cc[i__ + ((k << 2) + 1) * cc_dim1] - cc[ic + ((k << 2) + 4) 
+		    * cc_dim1];
+	    ti3 = cc[i__ + ((k << 2) + 3) * cc_dim1] - cc[ic + ((k << 2) + 2) 
+		    * cc_dim1];
+	    tr4 = cc[i__ + ((k << 2) + 3) * cc_dim1] + cc[ic + ((k << 2) + 2) 
+		    * cc_dim1];
+	    tr1 = cc[i__ - 1 + ((k << 2) + 1) * cc_dim1] - cc[ic - 1 + ((k << 
+		    2) + 4) * cc_dim1];
+	    tr2 = cc[i__ - 1 + ((k << 2) + 1) * cc_dim1] + cc[ic - 1 + ((k << 
+		    2) + 4) * cc_dim1];
+	    ti4 = cc[i__ - 1 + ((k << 2) + 3) * cc_dim1] - cc[ic - 1 + ((k << 
+		    2) + 2) * cc_dim1];
+	    tr3 = cc[i__ - 1 + ((k << 2) + 3) * cc_dim1] + cc[ic - 1 + ((k << 
+		    2) + 2) * cc_dim1];
+	    ch[i__ - 1 + (k + ch_dim2) * ch_dim1] = tr2 + tr3;
+	    cr3 = tr2 - tr3;
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = ti2 + ti3;
+	    ci3 = ti2 - ti3;
+	    cr2 = tr1 - tr4;
+	    cr4 = tr1 + tr4;
+	    ci2 = ti1 + ti4;
+	    ci4 = ti1 - ti4;
+	    ch[i__ - 1 + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 2] * cr2 
+		    - wa1[i__ - 1] * ci2;
+	    ch[i__ + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 2] * ci2 + 
+		    wa1[i__ - 1] * cr2;
+	    ch[i__ - 1 + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 2] * cr3 - 
+		    wa2[i__ - 1] * ci3;
+	    ch[i__ + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 2] * ci3 + wa2[
+		    i__ - 1] * cr3;
+	    ch[i__ - 1 + (k + (ch_dim2 << 2)) * ch_dim1] = wa3[i__ - 2] * cr4 
+		    - wa3[i__ - 1] * ci4;
+	    ch[i__ + (k + (ch_dim2 << 2)) * ch_dim1] = wa3[i__ - 2] * ci4 + 
+		    wa3[i__ - 1] * cr4;
+/* L103: */
+	}
+/* L104: */
+    }
+    if (*ido % 2 == 1) {
+	return 0;
+    }
+L105:
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	ti1 = cc[((k << 2) + 2) * cc_dim1 + 1] + cc[((k << 2) + 4) * cc_dim1 
+		+ 1];
+	ti2 = cc[((k << 2) + 4) * cc_dim1 + 1] - cc[((k << 2) + 2) * cc_dim1 
+		+ 1];
+	tr1 = cc[*ido + ((k << 2) + 1) * cc_dim1] - cc[*ido + ((k << 2) + 3) *
+		 cc_dim1];
+	tr2 = cc[*ido + ((k << 2) + 1) * cc_dim1] + cc[*ido + ((k << 2) + 3) *
+		 cc_dim1];
+	ch[*ido + (k + ch_dim2) * ch_dim1] = tr2 + tr2;
+	ch[*ido + (k + (ch_dim2 << 1)) * ch_dim1] = sqrt2 * (tr1 - ti1);
+	ch[*ido + (k + ch_dim2 * 3) * ch_dim1] = ti2 + ti2;
+	ch[*ido + (k + (ch_dim2 << 2)) * ch_dim1] = -sqrt2 * (tr1 + ti1);
+/* L106: */
+    }
+L107:
+    return 0;
+} /* radb4_ */
+
+/*  ------ File radb5.f ------ */
+/* Subroutine */ int radb5_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, 
+	r_4 *wa1, r_4 *wa2, r_4 *wa3, r_4 *wa4)
+{
+    /* Initialized data */
+
+    static r_4 tr11 = .309016994374947f;
+    static r_4 ti11 = .951056516295154f;
+    static r_4 tr12 = -.809016994374947f;
+    static r_4 ti12 = .587785252292473f;
+
+    /* System generated locals */
+    int_4 cc_dim1, cc_offset, ch_dim1, ch_dim2, ch_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k, ic;
+    static r_4 ci2, ci3, ci4, ci5, di3, di4, di5, di2, cr2, cr3, cr5, cr4, 
+	    ti2, ti3, ti4, ti5, dr3, dr4, dr5, dr2, tr2, tr3, tr4, tr5;
+    static int_4 idp2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_offset = cc_dim1 * 6 + 1;
+    cc -= cc_offset;
+    --wa1;
+    --wa2;
+    --wa3;
+    --wa4;
+
+    /* Function Body */
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	ti5 = cc[(k * 5 + 3) * cc_dim1 + 1] + cc[(k * 5 + 3) * cc_dim1 + 1];
+	ti4 = cc[(k * 5 + 5) * cc_dim1 + 1] + cc[(k * 5 + 5) * cc_dim1 + 1];
+	tr2 = cc[*ido + (k * 5 + 2) * cc_dim1] + cc[*ido + (k * 5 + 2) * 
+		cc_dim1];
+	tr3 = cc[*ido + (k * 5 + 4) * cc_dim1] + cc[*ido + (k * 5 + 4) * 
+		cc_dim1];
+	ch[(k + ch_dim2) * ch_dim1 + 1] = cc[(k * 5 + 1) * cc_dim1 + 1] + tr2 
+		+ tr3;
+	cr2 = cc[(k * 5 + 1) * cc_dim1 + 1] + tr11 * tr2 + tr12 * tr3;
+	cr3 = cc[(k * 5 + 1) * cc_dim1 + 1] + tr12 * tr2 + tr11 * tr3;
+	ci5 = ti11 * ti5 + ti12 * ti4;
+	ci4 = ti12 * ti5 - ti11 * ti4;
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 1] = cr2 - ci5;
+	ch[(k + ch_dim2 * 3) * ch_dim1 + 1] = cr3 - ci4;
+	ch[(k + (ch_dim2 << 2)) * ch_dim1 + 1] = cr3 + ci4;
+	ch[(k + ch_dim2 * 5) * ch_dim1 + 1] = cr2 + ci5;
+/* L101: */
+    }
+    if (*ido == 1) {
+	return 0;
+    }
+    idp2 = *ido + 2;
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 3; i__ <= i__2; i__ += 2) {
+	    ic = idp2 - i__;
+	    ti5 = cc[i__ + (k * 5 + 3) * cc_dim1] + cc[ic + (k * 5 + 2) * 
+		    cc_dim1];
+	    ti2 = cc[i__ + (k * 5 + 3) * cc_dim1] - cc[ic + (k * 5 + 2) * 
+		    cc_dim1];
+	    ti4 = cc[i__ + (k * 5 + 5) * cc_dim1] + cc[ic + (k * 5 + 4) * 
+		    cc_dim1];
+	    ti3 = cc[i__ + (k * 5 + 5) * cc_dim1] - cc[ic + (k * 5 + 4) * 
+		    cc_dim1];
+	    tr5 = cc[i__ - 1 + (k * 5 + 3) * cc_dim1] - cc[ic - 1 + (k * 5 + 
+		    2) * cc_dim1];
+	    tr2 = cc[i__ - 1 + (k * 5 + 3) * cc_dim1] + cc[ic - 1 + (k * 5 + 
+		    2) * cc_dim1];
+	    tr4 = cc[i__ - 1 + (k * 5 + 5) * cc_dim1] - cc[ic - 1 + (k * 5 + 
+		    4) * cc_dim1];
+	    tr3 = cc[i__ - 1 + (k * 5 + 5) * cc_dim1] + cc[ic - 1 + (k * 5 + 
+		    4) * cc_dim1];
+	    ch[i__ - 1 + (k + ch_dim2) * ch_dim1] = cc[i__ - 1 + (k * 5 + 1) *
+		     cc_dim1] + tr2 + tr3;
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = cc[i__ + (k * 5 + 1) * 
+		    cc_dim1] + ti2 + ti3;
+	    cr2 = cc[i__ - 1 + (k * 5 + 1) * cc_dim1] + tr11 * tr2 + tr12 * 
+		    tr3;
+	    ci2 = cc[i__ + (k * 5 + 1) * cc_dim1] + tr11 * ti2 + tr12 * ti3;
+	    cr3 = cc[i__ - 1 + (k * 5 + 1) * cc_dim1] + tr12 * tr2 + tr11 * 
+		    tr3;
+	    ci3 = cc[i__ + (k * 5 + 1) * cc_dim1] + tr12 * ti2 + tr11 * ti3;
+	    cr5 = ti11 * tr5 + ti12 * tr4;
+	    ci5 = ti11 * ti5 + ti12 * ti4;
+	    cr4 = ti12 * tr5 - ti11 * tr4;
+	    ci4 = ti12 * ti5 - ti11 * ti4;
+	    dr3 = cr3 - ci4;
+	    dr4 = cr3 + ci4;
+	    di3 = ci3 + cr4;
+	    di4 = ci3 - cr4;
+	    dr5 = cr2 + ci5;
+	    dr2 = cr2 - ci5;
+	    di5 = ci2 - cr5;
+	    di2 = ci2 + cr5;
+	    ch[i__ - 1 + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 2] * dr2 
+		    - wa1[i__ - 1] * di2;
+	    ch[i__ + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 2] * di2 + 
+		    wa1[i__ - 1] * dr2;
+	    ch[i__ - 1 + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 2] * dr3 - 
+		    wa2[i__ - 1] * di3;
+	    ch[i__ + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 2] * di3 + wa2[
+		    i__ - 1] * dr3;
+	    ch[i__ - 1 + (k + (ch_dim2 << 2)) * ch_dim1] = wa3[i__ - 2] * dr4 
+		    - wa3[i__ - 1] * di4;
+	    ch[i__ + (k + (ch_dim2 << 2)) * ch_dim1] = wa3[i__ - 2] * di4 + 
+		    wa3[i__ - 1] * dr4;
+	    ch[i__ - 1 + (k + ch_dim2 * 5) * ch_dim1] = wa4[i__ - 2] * dr5 - 
+		    wa4[i__ - 1] * di5;
+	    ch[i__ + (k + ch_dim2 * 5) * ch_dim1] = wa4[i__ - 2] * di5 + wa4[
+		    i__ - 1] * dr5;
+/* L102: */
+	}
+/* L103: */
+    }
+    return 0;
+} /* radb5_ */
+
+/*  ------ File radbg.f ------ */
+/* Subroutine */ int radbg_(int_4 *ido, int_4 *ip, int_4 *l1, int_4 *
+	idl1, r_4 *cc, r_4 *c1, r_4 *c2, r_4 *ch, r_4 *ch2, r_4 *wa)
+{
+    /* Initialized data */
+
+    static r_4 tpi = 6.28318530717959f;
+
+    /* System generated locals */
+    int_4 ch_dim1, ch_dim2, ch_offset, cc_dim1, cc_dim2, cc_offset, c1_dim1,
+	     c1_dim2, c1_offset, c2_dim1, c2_offset, ch2_dim1, ch2_offset, 
+	    i__1, i__2, i__3;
+
+    /* Builtin functions */
+/*    r_8 cos(r_8truc), sin(r_8truc);  commente - Remplace par math.h  Reza 29/11/99 */
+
+    /* Local variables */
+    static int_4 idij, ipph, i__, j, k, l, j2, ic, jc, lc, ik, is;
+    static r_4 dc2, ai1, ai2, ar1, ar2, ds2;
+    static int_4 nbd;
+    static r_4 dcp, arg, dsp, ar1h, ar2h;
+    static int_4 idp2, ipp2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    c1_dim1 = *ido;
+    c1_dim2 = *l1;
+    c1_offset = c1_dim1 * (c1_dim2 + 1) + 1;
+    c1 -= c1_offset;
+    cc_dim1 = *ido;
+    cc_dim2 = *ip;
+    cc_offset = cc_dim1 * (cc_dim2 + 1) + 1;
+    cc -= cc_offset;
+    ch2_dim1 = *idl1;
+    ch2_offset = ch2_dim1 + 1;
+    ch2 -= ch2_offset;
+    c2_dim1 = *idl1;
+    c2_offset = c2_dim1 + 1;
+    c2 -= c2_offset;
+    --wa;
+
+    /* Function Body */
+    arg = tpi / (r_4) (*ip);
+    dcp = cos(arg);
+    dsp = sin(arg);
+    idp2 = *ido + 2;
+    nbd = (*ido - 1) / 2;
+    ipp2 = *ip + 2;
+    ipph = (*ip + 1) / 2;
+    if (*ido < *l1) {
+	goto L103;
+    }
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 1; i__ <= i__2; ++i__) {
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = cc[i__ + (k * cc_dim2 + 1) * 
+		    cc_dim1];
+/* L101: */
+	}
+/* L102: */
+    }
+    goto L106;
+L103:
+    i__1 = *ido;
+    for (i__ = 1; i__ <= i__1; ++i__) {
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = cc[i__ + (k * cc_dim2 + 1) * 
+		    cc_dim1];
+/* L104: */
+	}
+/* L105: */
+    }
+L106:
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	j2 = j + j;
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    ch[(k + j * ch_dim2) * ch_dim1 + 1] = cc[*ido + (j2 - 2 + k * 
+		    cc_dim2) * cc_dim1] + cc[*ido + (j2 - 2 + k * cc_dim2) * 
+		    cc_dim1];
+	    ch[(k + jc * ch_dim2) * ch_dim1 + 1] = cc[(j2 - 1 + k * cc_dim2) *
+		     cc_dim1 + 1] + cc[(j2 - 1 + k * cc_dim2) * cc_dim1 + 1];
+/* L107: */
+	}
+/* L108: */
+    }
+    if (*ido == 1) {
+	goto L116;
+    }
+    if (nbd < *l1) {
+	goto L112;
+    }
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    i__3 = *ido;
+	    for (i__ = 3; i__ <= i__3; i__ += 2) {
+		ic = idp2 - i__;
+		ch[i__ - 1 + (k + j * ch_dim2) * ch_dim1] = cc[i__ - 1 + ((j 
+			<< 1) - 1 + k * cc_dim2) * cc_dim1] + cc[ic - 1 + ((j 
+			<< 1) - 2 + k * cc_dim2) * cc_dim1];
+		ch[i__ - 1 + (k + jc * ch_dim2) * ch_dim1] = cc[i__ - 1 + ((j 
+			<< 1) - 1 + k * cc_dim2) * cc_dim1] - cc[ic - 1 + ((j 
+			<< 1) - 2 + k * cc_dim2) * cc_dim1];
+		ch[i__ + (k + j * ch_dim2) * ch_dim1] = cc[i__ + ((j << 1) - 
+			1 + k * cc_dim2) * cc_dim1] - cc[ic + ((j << 1) - 2 + 
+			k * cc_dim2) * cc_dim1];
+		ch[i__ + (k + jc * ch_dim2) * ch_dim1] = cc[i__ + ((j << 1) - 
+			1 + k * cc_dim2) * cc_dim1] + cc[ic + ((j << 1) - 2 + 
+			k * cc_dim2) * cc_dim1];
+/* L109: */
+	    }
+/* L110: */
+	}
+/* L111: */
+    }
+    goto L116;
+L112:
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	i__2 = *ido;
+	for (i__ = 3; i__ <= i__2; i__ += 2) {
+	    ic = idp2 - i__;
+	    i__3 = *l1;
+	    for (k = 1; k <= i__3; ++k) {
+		ch[i__ - 1 + (k + j * ch_dim2) * ch_dim1] = cc[i__ - 1 + ((j 
+			<< 1) - 1 + k * cc_dim2) * cc_dim1] + cc[ic - 1 + ((j 
+			<< 1) - 2 + k * cc_dim2) * cc_dim1];
+		ch[i__ - 1 + (k + jc * ch_dim2) * ch_dim1] = cc[i__ - 1 + ((j 
+			<< 1) - 1 + k * cc_dim2) * cc_dim1] - cc[ic - 1 + ((j 
+			<< 1) - 2 + k * cc_dim2) * cc_dim1];
+		ch[i__ + (k + j * ch_dim2) * ch_dim1] = cc[i__ + ((j << 1) - 
+			1 + k * cc_dim2) * cc_dim1] - cc[ic + ((j << 1) - 2 + 
+			k * cc_dim2) * cc_dim1];
+		ch[i__ + (k + jc * ch_dim2) * ch_dim1] = cc[i__ + ((j << 1) - 
+			1 + k * cc_dim2) * cc_dim1] + cc[ic + ((j << 1) - 2 + 
+			k * cc_dim2) * cc_dim1];
+/* L113: */
+	    }
+/* L114: */
+	}
+/* L115: */
+    }
+L116:
+    ar1 = 1.f;
+    ai1 = 0.f;
+    i__1 = ipph;
+    for (l = 2; l <= i__1; ++l) {
+	lc = ipp2 - l;
+	ar1h = dcp * ar1 - dsp * ai1;
+	ai1 = dcp * ai1 + dsp * ar1;
+	ar1 = ar1h;
+	i__2 = *idl1;
+	for (ik = 1; ik <= i__2; ++ik) {
+	    c2[ik + l * c2_dim1] = ch2[ik + ch2_dim1] + ar1 * ch2[ik + (
+		    ch2_dim1 << 1)];
+	    c2[ik + lc * c2_dim1] = ai1 * ch2[ik + *ip * ch2_dim1];
+/* L117: */
+	}
+	dc2 = ar1;
+	ds2 = ai1;
+	ar2 = ar1;
+	ai2 = ai1;
+	i__2 = ipph;
+	for (j = 3; j <= i__2; ++j) {
+	    jc = ipp2 - j;
+	    ar2h = dc2 * ar2 - ds2 * ai2;
+	    ai2 = dc2 * ai2 + ds2 * ar2;
+	    ar2 = ar2h;
+	    i__3 = *idl1;
+	    for (ik = 1; ik <= i__3; ++ik) {
+		c2[ik + l * c2_dim1] += ar2 * ch2[ik + j * ch2_dim1];
+		c2[ik + lc * c2_dim1] += ai2 * ch2[ik + jc * ch2_dim1];
+/* L118: */
+	    }
+/* L119: */
+	}
+/* L120: */
+    }
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	i__2 = *idl1;
+	for (ik = 1; ik <= i__2; ++ik) {
+	    ch2[ik + ch2_dim1] += ch2[ik + j * ch2_dim1];
+/* L121: */
+	}
+/* L122: */
+    }
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    ch[(k + j * ch_dim2) * ch_dim1 + 1] = c1[(k + j * c1_dim2) * 
+		    c1_dim1 + 1] - c1[(k + jc * c1_dim2) * c1_dim1 + 1];
+	    ch[(k + jc * ch_dim2) * ch_dim1 + 1] = c1[(k + j * c1_dim2) * 
+		    c1_dim1 + 1] + c1[(k + jc * c1_dim2) * c1_dim1 + 1];
+/* L123: */
+	}
+/* L124: */
+    }
+    if (*ido == 1) {
+	goto L132;
+    }
+    if (nbd < *l1) {
+	goto L128;
+    }
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    i__3 = *ido;
+	    for (i__ = 3; i__ <= i__3; i__ += 2) {
+		ch[i__ - 1 + (k + j * ch_dim2) * ch_dim1] = c1[i__ - 1 + (k + 
+			j * c1_dim2) * c1_dim1] - c1[i__ + (k + jc * c1_dim2) 
+			* c1_dim1];
+		ch[i__ - 1 + (k + jc * ch_dim2) * ch_dim1] = c1[i__ - 1 + (k 
+			+ j * c1_dim2) * c1_dim1] + c1[i__ + (k + jc * 
+			c1_dim2) * c1_dim1];
+		ch[i__ + (k + j * ch_dim2) * ch_dim1] = c1[i__ + (k + j * 
+			c1_dim2) * c1_dim1] + c1[i__ - 1 + (k + jc * c1_dim2) 
+			* c1_dim1];
+		ch[i__ + (k + jc * ch_dim2) * ch_dim1] = c1[i__ + (k + j * 
+			c1_dim2) * c1_dim1] - c1[i__ - 1 + (k + jc * c1_dim2) 
+			* c1_dim1];
+/* L125: */
+	    }
+/* L126: */
+	}
+/* L127: */
+    }
+    goto L132;
+L128:
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	i__2 = *ido;
+	for (i__ = 3; i__ <= i__2; i__ += 2) {
+	    i__3 = *l1;
+	    for (k = 1; k <= i__3; ++k) {
+		ch[i__ - 1 + (k + j * ch_dim2) * ch_dim1] = c1[i__ - 1 + (k + 
+			j * c1_dim2) * c1_dim1] - c1[i__ + (k + jc * c1_dim2) 
+			* c1_dim1];
+		ch[i__ - 1 + (k + jc * ch_dim2) * ch_dim1] = c1[i__ - 1 + (k 
+			+ j * c1_dim2) * c1_dim1] + c1[i__ + (k + jc * 
+			c1_dim2) * c1_dim1];
+		ch[i__ + (k + j * ch_dim2) * ch_dim1] = c1[i__ + (k + j * 
+			c1_dim2) * c1_dim1] + c1[i__ - 1 + (k + jc * c1_dim2) 
+			* c1_dim1];
+		ch[i__ + (k + jc * ch_dim2) * ch_dim1] = c1[i__ + (k + j * 
+			c1_dim2) * c1_dim1] - c1[i__ - 1 + (k + jc * c1_dim2) 
+			* c1_dim1];
+/* L129: */
+	    }
+/* L130: */
+	}
+/* L131: */
+    }
+L132:
+    if (*ido == 1) {
+	return 0;
+    }
+    i__1 = *idl1;
+    for (ik = 1; ik <= i__1; ++ik) {
+	c2[ik + c2_dim1] = ch2[ik + ch2_dim1];
+/* L133: */
+    }
+    i__1 = *ip;
+    for (j = 2; j <= i__1; ++j) {
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    c1[(k + j * c1_dim2) * c1_dim1 + 1] = ch[(k + j * ch_dim2) * 
+		    ch_dim1 + 1];
+/* L134: */
+	}
+/* L135: */
+    }
+    if (nbd > *l1) {
+	goto L139;
+    }
+    is = -(*ido);
+    i__1 = *ip;
+    for (j = 2; j <= i__1; ++j) {
+	is += *ido;
+	idij = is;
+	i__2 = *ido;
+	for (i__ = 3; i__ <= i__2; i__ += 2) {
+	    idij += 2;
+	    i__3 = *l1;
+	    for (k = 1; k <= i__3; ++k) {
+		c1[i__ - 1 + (k + j * c1_dim2) * c1_dim1] = wa[idij - 1] * ch[
+			i__ - 1 + (k + j * ch_dim2) * ch_dim1] - wa[idij] * 
+			ch[i__ + (k + j * ch_dim2) * ch_dim1];
+		c1[i__ + (k + j * c1_dim2) * c1_dim1] = wa[idij - 1] * ch[i__ 
+			+ (k + j * ch_dim2) * ch_dim1] + wa[idij] * ch[i__ - 
+			1 + (k + j * ch_dim2) * ch_dim1];
+/* L136: */
+	    }
+/* L137: */
+	}
+/* L138: */
+    }
+    goto L143;
+L139:
+    is = -(*ido);
+    i__1 = *ip;
+    for (j = 2; j <= i__1; ++j) {
+	is += *ido;
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    idij = is;
+	    i__3 = *ido;
+	    for (i__ = 3; i__ <= i__3; i__ += 2) {
+		idij += 2;
+		c1[i__ - 1 + (k + j * c1_dim2) * c1_dim1] = wa[idij - 1] * ch[
+			i__ - 1 + (k + j * ch_dim2) * ch_dim1] - wa[idij] * 
+			ch[i__ + (k + j * ch_dim2) * ch_dim1];
+		c1[i__ + (k + j * c1_dim2) * c1_dim1] = wa[idij - 1] * ch[i__ 
+			+ (k + j * ch_dim2) * ch_dim1] + wa[idij] * ch[i__ - 
+			1 + (k + j * ch_dim2) * ch_dim1];
+/* L140: */
+	    }
+/* L141: */
+	}
+/* L142: */
+    }
+L143:
+    return 0;
+} /* radbg_ */
+
+/*  ------ File radf2.f ------ */
+/* Subroutine */ int radf2_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, 
+	r_4 *wa1)
+{
+    /* System generated locals */
+    int_4 ch_dim1, ch_offset, cc_dim1, cc_dim2, cc_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k, ic;
+    static r_4 ti2, tr2;
+    static int_4 idp2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_offset = ch_dim1 * 3 + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_dim2 = *l1;
+    cc_offset = cc_dim1 * (cc_dim2 + 1) + 1;
+    cc -= cc_offset;
+    --wa1;
+
+    /* Function Body */
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	ch[((k << 1) + 1) * ch_dim1 + 1] = cc[(k + cc_dim2) * cc_dim1 + 1] + 
+		cc[(k + (cc_dim2 << 1)) * cc_dim1 + 1];
+	ch[*ido + ((k << 1) + 2) * ch_dim1] = cc[(k + cc_dim2) * cc_dim1 + 1] 
+		- cc[(k + (cc_dim2 << 1)) * cc_dim1 + 1];
+/* L101: */
+    }
+    if ((i__1 = *ido - 2) < 0) {
+	goto L107;
+    } else if (i__1 == 0) {
+	goto L105;
+    } else {
+	goto L102;
+    }
+L102:
+    idp2 = *ido + 2;
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 3; i__ <= i__2; i__ += 2) {
+	    ic = idp2 - i__;
+	    tr2 = wa1[i__ - 2] * cc[i__ - 1 + (k + (cc_dim2 << 1)) * cc_dim1] 
+		    + wa1[i__ - 1] * cc[i__ + (k + (cc_dim2 << 1)) * cc_dim1];
+	    ti2 = wa1[i__ - 2] * cc[i__ + (k + (cc_dim2 << 1)) * cc_dim1] - 
+		    wa1[i__ - 1] * cc[i__ - 1 + (k + (cc_dim2 << 1)) * 
+		    cc_dim1];
+	    ch[i__ + ((k << 1) + 1) * ch_dim1] = cc[i__ + (k + cc_dim2) * 
+		    cc_dim1] + ti2;
+	    ch[ic + ((k << 1) + 2) * ch_dim1] = ti2 - cc[i__ + (k + cc_dim2) *
+		     cc_dim1];
+	    ch[i__ - 1 + ((k << 1) + 1) * ch_dim1] = cc[i__ - 1 + (k + 
+		    cc_dim2) * cc_dim1] + tr2;
+	    ch[ic - 1 + ((k << 1) + 2) * ch_dim1] = cc[i__ - 1 + (k + cc_dim2)
+		     * cc_dim1] - tr2;
+/* L103: */
+	}
+/* L104: */
+    }
+    if (*ido % 2 == 1) {
+	return 0;
+    }
+L105:
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	ch[((k << 1) + 2) * ch_dim1 + 1] = -cc[*ido + (k + (cc_dim2 << 1)) * 
+		cc_dim1];
+	ch[*ido + ((k << 1) + 1) * ch_dim1] = cc[*ido + (k + cc_dim2) * 
+		cc_dim1];
+/* L106: */
+    }
+L107:
+    return 0;
+} /* radf2_ */
+
+/*  ------ File radf3.f ------ */
+/* Subroutine */ int radf3_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, 
+	r_4 *wa1, r_4 *wa2)
+{
+    /* Initialized data */
+
+    static r_4 taur = -.5f;
+    static r_4 taui = .866025403784439f;
+
+    /* System generated locals */
+    int_4 ch_dim1, ch_offset, cc_dim1, cc_dim2, cc_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k, ic;
+    static r_4 ci2, di2, di3, cr2, dr2, dr3, ti2, ti3, tr2, tr3;
+    static int_4 idp2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_offset = (ch_dim1 << 2) + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_dim2 = *l1;
+    cc_offset = cc_dim1 * (cc_dim2 + 1) + 1;
+    cc -= cc_offset;
+    --wa1;
+    --wa2;
+
+    /* Function Body */
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	cr2 = cc[(k + (cc_dim2 << 1)) * cc_dim1 + 1] + cc[(k + cc_dim2 * 3) * 
+		cc_dim1 + 1];
+	ch[(k * 3 + 1) * ch_dim1 + 1] = cc[(k + cc_dim2) * cc_dim1 + 1] + cr2;
+	ch[(k * 3 + 3) * ch_dim1 + 1] = taui * (cc[(k + cc_dim2 * 3) * 
+		cc_dim1 + 1] - cc[(k + (cc_dim2 << 1)) * cc_dim1 + 1]);
+	ch[*ido + (k * 3 + 2) * ch_dim1] = cc[(k + cc_dim2) * cc_dim1 + 1] + 
+		taur * cr2;
+/* L101: */
+    }
+    if (*ido == 1) {
+	return 0;
+    }
+    idp2 = *ido + 2;
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 3; i__ <= i__2; i__ += 2) {
+	    ic = idp2 - i__;
+	    dr2 = wa1[i__ - 2] * cc[i__ - 1 + (k + (cc_dim2 << 1)) * cc_dim1] 
+		    + wa1[i__ - 1] * cc[i__ + (k + (cc_dim2 << 1)) * cc_dim1];
+	    di2 = wa1[i__ - 2] * cc[i__ + (k + (cc_dim2 << 1)) * cc_dim1] - 
+		    wa1[i__ - 1] * cc[i__ - 1 + (k + (cc_dim2 << 1)) * 
+		    cc_dim1];
+	    dr3 = wa2[i__ - 2] * cc[i__ - 1 + (k + cc_dim2 * 3) * cc_dim1] + 
+		    wa2[i__ - 1] * cc[i__ + (k + cc_dim2 * 3) * cc_dim1];
+	    di3 = wa2[i__ - 2] * cc[i__ + (k + cc_dim2 * 3) * cc_dim1] - wa2[
+		    i__ - 1] * cc[i__ - 1 + (k + cc_dim2 * 3) * cc_dim1];
+	    cr2 = dr2 + dr3;
+	    ci2 = di2 + di3;
+	    ch[i__ - 1 + (k * 3 + 1) * ch_dim1] = cc[i__ - 1 + (k + cc_dim2) *
+		     cc_dim1] + cr2;
+	    ch[i__ + (k * 3 + 1) * ch_dim1] = cc[i__ + (k + cc_dim2) * 
+		    cc_dim1] + ci2;
+	    tr2 = cc[i__ - 1 + (k + cc_dim2) * cc_dim1] + taur * cr2;
+	    ti2 = cc[i__ + (k + cc_dim2) * cc_dim1] + taur * ci2;
+	    tr3 = taui * (di2 - di3);
+	    ti3 = taui * (dr3 - dr2);
+	    ch[i__ - 1 + (k * 3 + 3) * ch_dim1] = tr2 + tr3;
+	    ch[ic - 1 + (k * 3 + 2) * ch_dim1] = tr2 - tr3;
+	    ch[i__ + (k * 3 + 3) * ch_dim1] = ti2 + ti3;
+	    ch[ic + (k * 3 + 2) * ch_dim1] = ti3 - ti2;
+/* L102: */
+	}
+/* L103: */
+    }
+    return 0;
+} /* radf3_ */
+
+/*  ------ File radf4.f ------ */
+/* Subroutine */ int radf4_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, 
+	r_4 *wa1, r_4 *wa2, r_4 *wa3)
+{
+    /* Initialized data */
+
+    static r_4 hsqt2 = .7071067811865475f;
+
+    /* System generated locals */
+    int_4 cc_dim1, cc_dim2, cc_offset, ch_dim1, ch_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k, ic;
+    static r_4 ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, 
+	    tr3, tr4;
+    static int_4 idp2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_offset = ch_dim1 * 5 + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_dim2 = *l1;
+    cc_offset = cc_dim1 * (cc_dim2 + 1) + 1;
+    cc -= cc_offset;
+    --wa1;
+    --wa2;
+    --wa3;
+
+    /* Function Body */
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	tr1 = cc[(k + (cc_dim2 << 1)) * cc_dim1 + 1] + cc[(k + (cc_dim2 << 2))
+		 * cc_dim1 + 1];
+	tr2 = cc[(k + cc_dim2) * cc_dim1 + 1] + cc[(k + cc_dim2 * 3) * 
+		cc_dim1 + 1];
+	ch[((k << 2) + 1) * ch_dim1 + 1] = tr1 + tr2;
+	ch[*ido + ((k << 2) + 4) * ch_dim1] = tr2 - tr1;
+	ch[*ido + ((k << 2) + 2) * ch_dim1] = cc[(k + cc_dim2) * cc_dim1 + 1] 
+		- cc[(k + cc_dim2 * 3) * cc_dim1 + 1];
+	ch[((k << 2) + 3) * ch_dim1 + 1] = cc[(k + (cc_dim2 << 2)) * cc_dim1 
+		+ 1] - cc[(k + (cc_dim2 << 1)) * cc_dim1 + 1];
+/* L101: */
+    }
+    if ((i__1 = *ido - 2) < 0) {
+	goto L107;
+    } else if (i__1 == 0) {
+	goto L105;
+    } else {
+	goto L102;
+    }
+L102:
+    idp2 = *ido + 2;
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 3; i__ <= i__2; i__ += 2) {
+	    ic = idp2 - i__;
+	    cr2 = wa1[i__ - 2] * cc[i__ - 1 + (k + (cc_dim2 << 1)) * cc_dim1] 
+		    + wa1[i__ - 1] * cc[i__ + (k + (cc_dim2 << 1)) * cc_dim1];
+	    ci2 = wa1[i__ - 2] * cc[i__ + (k + (cc_dim2 << 1)) * cc_dim1] - 
+		    wa1[i__ - 1] * cc[i__ - 1 + (k + (cc_dim2 << 1)) * 
+		    cc_dim1];
+	    cr3 = wa2[i__ - 2] * cc[i__ - 1 + (k + cc_dim2 * 3) * cc_dim1] + 
+		    wa2[i__ - 1] * cc[i__ + (k + cc_dim2 * 3) * cc_dim1];
+	    ci3 = wa2[i__ - 2] * cc[i__ + (k + cc_dim2 * 3) * cc_dim1] - wa2[
+		    i__ - 1] * cc[i__ - 1 + (k + cc_dim2 * 3) * cc_dim1];
+	    cr4 = wa3[i__ - 2] * cc[i__ - 1 + (k + (cc_dim2 << 2)) * cc_dim1] 
+		    + wa3[i__ - 1] * cc[i__ + (k + (cc_dim2 << 2)) * cc_dim1];
+	    ci4 = wa3[i__ - 2] * cc[i__ + (k + (cc_dim2 << 2)) * cc_dim1] - 
+		    wa3[i__ - 1] * cc[i__ - 1 + (k + (cc_dim2 << 2)) * 
+		    cc_dim1];
+	    tr1 = cr2 + cr4;
+	    tr4 = cr4 - cr2;
+	    ti1 = ci2 + ci4;
+	    ti4 = ci2 - ci4;
+	    ti2 = cc[i__ + (k + cc_dim2) * cc_dim1] + ci3;
+	    ti3 = cc[i__ + (k + cc_dim2) * cc_dim1] - ci3;
+	    tr2 = cc[i__ - 1 + (k + cc_dim2) * cc_dim1] + cr3;
+	    tr3 = cc[i__ - 1 + (k + cc_dim2) * cc_dim1] - cr3;
+	    ch[i__ - 1 + ((k << 2) + 1) * ch_dim1] = tr1 + tr2;
+	    ch[ic - 1 + ((k << 2) + 4) * ch_dim1] = tr2 - tr1;
+	    ch[i__ + ((k << 2) + 1) * ch_dim1] = ti1 + ti2;
+	    ch[ic + ((k << 2) + 4) * ch_dim1] = ti1 - ti2;
+	    ch[i__ - 1 + ((k << 2) + 3) * ch_dim1] = ti4 + tr3;
+	    ch[ic - 1 + ((k << 2) + 2) * ch_dim1] = tr3 - ti4;
+	    ch[i__ + ((k << 2) + 3) * ch_dim1] = tr4 + ti3;
+	    ch[ic + ((k << 2) + 2) * ch_dim1] = tr4 - ti3;
+/* L103: */
+	}
+/* L104: */
+    }
+    if (*ido % 2 == 1) {
+	return 0;
+    }
+L105:
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	ti1 = -hsqt2 * (cc[*ido + (k + (cc_dim2 << 1)) * cc_dim1] + cc[*ido + 
+		(k + (cc_dim2 << 2)) * cc_dim1]);
+	tr1 = hsqt2 * (cc[*ido + (k + (cc_dim2 << 1)) * cc_dim1] - cc[*ido + (
+		k + (cc_dim2 << 2)) * cc_dim1]);
+	ch[*ido + ((k << 2) + 1) * ch_dim1] = tr1 + cc[*ido + (k + cc_dim2) * 
+		cc_dim1];
+	ch[*ido + ((k << 2) + 3) * ch_dim1] = cc[*ido + (k + cc_dim2) * 
+		cc_dim1] - tr1;
+	ch[((k << 2) + 2) * ch_dim1 + 1] = ti1 - cc[*ido + (k + cc_dim2 * 3) *
+		 cc_dim1];
+	ch[((k << 2) + 4) * ch_dim1 + 1] = ti1 + cc[*ido + (k + cc_dim2 * 3) *
+		 cc_dim1];
+/* L106: */
+    }
+L107:
+    return 0;
+} /* radf4_ */
+
+/*  ------ File radf5.f ------ */
+/* Subroutine */ int radf5_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, 
+	r_4 *wa1, r_4 *wa2, r_4 *wa3, r_4 *wa4)
+{
+    /* Initialized data */
+
+    static r_4 tr11 = .309016994374947f;
+    static r_4 ti11 = .951056516295154f;
+    static r_4 tr12 = -.809016994374947f;
+    static r_4 ti12 = .587785252292473f;
+
+    /* System generated locals */
+    int_4 cc_dim1, cc_dim2, cc_offset, ch_dim1, ch_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k, ic;
+    static r_4 ci2, di2, ci4, ci5, di3, di4, di5, ci3, cr2, cr3, dr2, dr3, 
+	    dr4, dr5, cr5, cr4, ti2, ti3, ti5, ti4, tr2, tr3, tr4, tr5;
+    static int_4 idp2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_offset = ch_dim1 * 6 + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_dim2 = *l1;
+    cc_offset = cc_dim1 * (cc_dim2 + 1) + 1;
+    cc -= cc_offset;
+    --wa1;
+    --wa2;
+    --wa3;
+    --wa4;
+
+    /* Function Body */
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	cr2 = cc[(k + cc_dim2 * 5) * cc_dim1 + 1] + cc[(k + (cc_dim2 << 1)) * 
+		cc_dim1 + 1];
+	ci5 = cc[(k + cc_dim2 * 5) * cc_dim1 + 1] - cc[(k + (cc_dim2 << 1)) * 
+		cc_dim1 + 1];
+	cr3 = cc[(k + (cc_dim2 << 2)) * cc_dim1 + 1] + cc[(k + cc_dim2 * 3) * 
+		cc_dim1 + 1];
+	ci4 = cc[(k + (cc_dim2 << 2)) * cc_dim1 + 1] - cc[(k + cc_dim2 * 3) * 
+		cc_dim1 + 1];
+	ch[(k * 5 + 1) * ch_dim1 + 1] = cc[(k + cc_dim2) * cc_dim1 + 1] + cr2 
+		+ cr3;
+	ch[*ido + (k * 5 + 2) * ch_dim1] = cc[(k + cc_dim2) * cc_dim1 + 1] + 
+		tr11 * cr2 + tr12 * cr3;
+	ch[(k * 5 + 3) * ch_dim1 + 1] = ti11 * ci5 + ti12 * ci4;
+	ch[*ido + (k * 5 + 4) * ch_dim1] = cc[(k + cc_dim2) * cc_dim1 + 1] + 
+		tr12 * cr2 + tr11 * cr3;
+	ch[(k * 5 + 5) * ch_dim1 + 1] = ti12 * ci5 - ti11 * ci4;
+/* L101: */
+    }
+    if (*ido == 1) {
+	return 0;
+    }
+    idp2 = *ido + 2;
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 3; i__ <= i__2; i__ += 2) {
+	    ic = idp2 - i__;
+	    dr2 = wa1[i__ - 2] * cc[i__ - 1 + (k + (cc_dim2 << 1)) * cc_dim1] 
+		    + wa1[i__ - 1] * cc[i__ + (k + (cc_dim2 << 1)) * cc_dim1];
+	    di2 = wa1[i__ - 2] * cc[i__ + (k + (cc_dim2 << 1)) * cc_dim1] - 
+		    wa1[i__ - 1] * cc[i__ - 1 + (k + (cc_dim2 << 1)) * 
+		    cc_dim1];
+	    dr3 = wa2[i__ - 2] * cc[i__ - 1 + (k + cc_dim2 * 3) * cc_dim1] + 
+		    wa2[i__ - 1] * cc[i__ + (k + cc_dim2 * 3) * cc_dim1];
+	    di3 = wa2[i__ - 2] * cc[i__ + (k + cc_dim2 * 3) * cc_dim1] - wa2[
+		    i__ - 1] * cc[i__ - 1 + (k + cc_dim2 * 3) * cc_dim1];
+	    dr4 = wa3[i__ - 2] * cc[i__ - 1 + (k + (cc_dim2 << 2)) * cc_dim1] 
+		    + wa3[i__ - 1] * cc[i__ + (k + (cc_dim2 << 2)) * cc_dim1];
+	    di4 = wa3[i__ - 2] * cc[i__ + (k + (cc_dim2 << 2)) * cc_dim1] - 
+		    wa3[i__ - 1] * cc[i__ - 1 + (k + (cc_dim2 << 2)) * 
+		    cc_dim1];
+	    dr5 = wa4[i__ - 2] * cc[i__ - 1 + (k + cc_dim2 * 5) * cc_dim1] + 
+		    wa4[i__ - 1] * cc[i__ + (k + cc_dim2 * 5) * cc_dim1];
+	    di5 = wa4[i__ - 2] * cc[i__ + (k + cc_dim2 * 5) * cc_dim1] - wa4[
+		    i__ - 1] * cc[i__ - 1 + (k + cc_dim2 * 5) * cc_dim1];
+	    cr2 = dr2 + dr5;
+	    ci5 = dr5 - dr2;
+	    cr5 = di2 - di5;
+	    ci2 = di2 + di5;
+	    cr3 = dr3 + dr4;
+	    ci4 = dr4 - dr3;
+	    cr4 = di3 - di4;
+	    ci3 = di3 + di4;
+	    ch[i__ - 1 + (k * 5 + 1) * ch_dim1] = cc[i__ - 1 + (k + cc_dim2) *
+		     cc_dim1] + cr2 + cr3;
+	    ch[i__ + (k * 5 + 1) * ch_dim1] = cc[i__ + (k + cc_dim2) * 
+		    cc_dim1] + ci2 + ci3;
+	    tr2 = cc[i__ - 1 + (k + cc_dim2) * cc_dim1] + tr11 * cr2 + tr12 * 
+		    cr3;
+	    ti2 = cc[i__ + (k + cc_dim2) * cc_dim1] + tr11 * ci2 + tr12 * ci3;
+	    tr3 = cc[i__ - 1 + (k + cc_dim2) * cc_dim1] + tr12 * cr2 + tr11 * 
+		    cr3;
+	    ti3 = cc[i__ + (k + cc_dim2) * cc_dim1] + tr12 * ci2 + tr11 * ci3;
+	    tr5 = ti11 * cr5 + ti12 * cr4;
+	    ti5 = ti11 * ci5 + ti12 * ci4;
+	    tr4 = ti12 * cr5 - ti11 * cr4;
+	    ti4 = ti12 * ci5 - ti11 * ci4;
+	    ch[i__ - 1 + (k * 5 + 3) * ch_dim1] = tr2 + tr5;
+	    ch[ic - 1 + (k * 5 + 2) * ch_dim1] = tr2 - tr5;
+	    ch[i__ + (k * 5 + 3) * ch_dim1] = ti2 + ti5;
+	    ch[ic + (k * 5 + 2) * ch_dim1] = ti5 - ti2;
+	    ch[i__ - 1 + (k * 5 + 5) * ch_dim1] = tr3 + tr4;
+	    ch[ic - 1 + (k * 5 + 4) * ch_dim1] = tr3 - tr4;
+	    ch[i__ + (k * 5 + 5) * ch_dim1] = ti3 + ti4;
+	    ch[ic + (k * 5 + 4) * ch_dim1] = ti4 - ti3;
+/* L102: */
+	}
+/* L103: */
+    }
+    return 0;
+} /* radf5_ */
+
+/*  ------ File radfg.f ------ */
+/* Subroutine */ int radfg_(int_4 *ido, int_4 *ip, int_4 *l1, int_4 *
+	idl1, r_4 *cc, r_4 *c1, r_4 *c2, r_4 *ch, r_4 *ch2, r_4 *wa)
+{
+    /* Initialized data */
+
+    static r_4 tpi = 6.28318530717959f;
+
+    /* System generated locals */
+    int_4 ch_dim1, ch_dim2, ch_offset, cc_dim1, cc_dim2, cc_offset, c1_dim1,
+	     c1_dim2, c1_offset, c2_dim1, c2_offset, ch2_dim1, ch2_offset, 
+	    i__1, i__2, i__3;
+
+    /* Builtin functions */
+/*    r_8 cos(r_8truc), sin(r_8truc);    */
+
+    /* Local variables */
+    static int_4 idij, ipph, i__, j, k, l, j2, ic, jc, lc, ik, is;
+    static r_4 dc2, ai1, ai2, ar1, ar2, ds2;
+    static int_4 nbd;
+    static r_4 dcp, arg, dsp, ar1h, ar2h;
+    static int_4 idp2, ipp2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    c1_dim1 = *ido;
+    c1_dim2 = *l1;
+    c1_offset = c1_dim1 * (c1_dim2 + 1) + 1;
+    c1 -= c1_offset;
+    cc_dim1 = *ido;
+    cc_dim2 = *ip;
+    cc_offset = cc_dim1 * (cc_dim2 + 1) + 1;
+    cc -= cc_offset;
+    ch2_dim1 = *idl1;
+    ch2_offset = ch2_dim1 + 1;
+    ch2 -= ch2_offset;
+    c2_dim1 = *idl1;
+    c2_offset = c2_dim1 + 1;
+    c2 -= c2_offset;
+    --wa;
+
+    /* Function Body */
+    arg = tpi / (r_4) (*ip);
+    dcp = cos(arg);
+    dsp = sin(arg);
+    ipph = (*ip + 1) / 2;
+    ipp2 = *ip + 2;
+    idp2 = *ido + 2;
+    nbd = (*ido - 1) / 2;
+    if (*ido == 1) {
+	goto L119;
+    }
+    i__1 = *idl1;
+    for (ik = 1; ik <= i__1; ++ik) {
+	ch2[ik + ch2_dim1] = c2[ik + c2_dim1];
+/* L101: */
+    }
+    i__1 = *ip;
+    for (j = 2; j <= i__1; ++j) {
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    ch[(k + j * ch_dim2) * ch_dim1 + 1] = c1[(k + j * c1_dim2) * 
+		    c1_dim1 + 1];
+/* L102: */
+	}
+/* L103: */
+    }
+    if (nbd > *l1) {
+	goto L107;
+    }
+    is = -(*ido);
+    i__1 = *ip;
+    for (j = 2; j <= i__1; ++j) {
+	is += *ido;
+	idij = is;
+	i__2 = *ido;
+	for (i__ = 3; i__ <= i__2; i__ += 2) {
+	    idij += 2;
+	    i__3 = *l1;
+	    for (k = 1; k <= i__3; ++k) {
+		ch[i__ - 1 + (k + j * ch_dim2) * ch_dim1] = wa[idij - 1] * c1[
+			i__ - 1 + (k + j * c1_dim2) * c1_dim1] + wa[idij] * 
+			c1[i__ + (k + j * c1_dim2) * c1_dim1];
+		ch[i__ + (k + j * ch_dim2) * ch_dim1] = wa[idij - 1] * c1[i__ 
+			+ (k + j * c1_dim2) * c1_dim1] - wa[idij] * c1[i__ - 
+			1 + (k + j * c1_dim2) * c1_dim1];
+/* L104: */
+	    }
+/* L105: */
+	}
+/* L106: */
+    }
+    goto L111;
+L107:
+    is = -(*ido);
+    i__1 = *ip;
+    for (j = 2; j <= i__1; ++j) {
+	is += *ido;
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    idij = is;
+	    i__3 = *ido;
+	    for (i__ = 3; i__ <= i__3; i__ += 2) {
+		idij += 2;
+		ch[i__ - 1 + (k + j * ch_dim2) * ch_dim1] = wa[idij - 1] * c1[
+			i__ - 1 + (k + j * c1_dim2) * c1_dim1] + wa[idij] * 
+			c1[i__ + (k + j * c1_dim2) * c1_dim1];
+		ch[i__ + (k + j * ch_dim2) * ch_dim1] = wa[idij - 1] * c1[i__ 
+			+ (k + j * c1_dim2) * c1_dim1] - wa[idij] * c1[i__ - 
+			1 + (k + j * c1_dim2) * c1_dim1];
+/* L108: */
+	    }
+/* L109: */
+	}
+/* L110: */
+    }
+L111:
+    if (nbd < *l1) {
+	goto L115;
+    }
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    i__3 = *ido;
+	    for (i__ = 3; i__ <= i__3; i__ += 2) {
+		c1[i__ - 1 + (k + j * c1_dim2) * c1_dim1] = ch[i__ - 1 + (k + 
+			j * ch_dim2) * ch_dim1] + ch[i__ - 1 + (k + jc * 
+			ch_dim2) * ch_dim1];
+		c1[i__ - 1 + (k + jc * c1_dim2) * c1_dim1] = ch[i__ + (k + j *
+			 ch_dim2) * ch_dim1] - ch[i__ + (k + jc * ch_dim2) * 
+			ch_dim1];
+		c1[i__ + (k + j * c1_dim2) * c1_dim1] = ch[i__ + (k + j * 
+			ch_dim2) * ch_dim1] + ch[i__ + (k + jc * ch_dim2) * 
+			ch_dim1];
+		c1[i__ + (k + jc * c1_dim2) * c1_dim1] = ch[i__ - 1 + (k + jc 
+			* ch_dim2) * ch_dim1] - ch[i__ - 1 + (k + j * ch_dim2)
+			 * ch_dim1];
+/* L112: */
+	    }
+/* L113: */
+	}
+/* L114: */
+    }
+    goto L121;
+L115:
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	i__2 = *ido;
+	for (i__ = 3; i__ <= i__2; i__ += 2) {
+	    i__3 = *l1;
+	    for (k = 1; k <= i__3; ++k) {
+		c1[i__ - 1 + (k + j * c1_dim2) * c1_dim1] = ch[i__ - 1 + (k + 
+			j * ch_dim2) * ch_dim1] + ch[i__ - 1 + (k + jc * 
+			ch_dim2) * ch_dim1];
+		c1[i__ - 1 + (k + jc * c1_dim2) * c1_dim1] = ch[i__ + (k + j *
+			 ch_dim2) * ch_dim1] - ch[i__ + (k + jc * ch_dim2) * 
+			ch_dim1];
+		c1[i__ + (k + j * c1_dim2) * c1_dim1] = ch[i__ + (k + j * 
+			ch_dim2) * ch_dim1] + ch[i__ + (k + jc * ch_dim2) * 
+			ch_dim1];
+		c1[i__ + (k + jc * c1_dim2) * c1_dim1] = ch[i__ - 1 + (k + jc 
+			* ch_dim2) * ch_dim1] - ch[i__ - 1 + (k + j * ch_dim2)
+			 * ch_dim1];
+/* L116: */
+	    }
+/* L117: */
+	}
+/* L118: */
+    }
+    goto L121;
+L119:
+    i__1 = *idl1;
+    for (ik = 1; ik <= i__1; ++ik) {
+	c2[ik + c2_dim1] = ch2[ik + ch2_dim1];
+/* L120: */
+    }
+L121:
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    c1[(k + j * c1_dim2) * c1_dim1 + 1] = ch[(k + j * ch_dim2) * 
+		    ch_dim1 + 1] + ch[(k + jc * ch_dim2) * ch_dim1 + 1];
+	    c1[(k + jc * c1_dim2) * c1_dim1 + 1] = ch[(k + jc * ch_dim2) * 
+		    ch_dim1 + 1] - ch[(k + j * ch_dim2) * ch_dim1 + 1];
+/* L122: */
+	}
+/* L123: */
+    }
+
+    ar1 = 1.f;
+    ai1 = 0.f;
+    i__1 = ipph;
+    for (l = 2; l <= i__1; ++l) {
+	lc = ipp2 - l;
+	ar1h = dcp * ar1 - dsp * ai1;
+	ai1 = dcp * ai1 + dsp * ar1;
+	ar1 = ar1h;
+	i__2 = *idl1;
+	for (ik = 1; ik <= i__2; ++ik) {
+	    ch2[ik + l * ch2_dim1] = c2[ik + c2_dim1] + ar1 * c2[ik + (
+		    c2_dim1 << 1)];
+	    ch2[ik + lc * ch2_dim1] = ai1 * c2[ik + *ip * c2_dim1];
+/* L124: */
+	}
+	dc2 = ar1;
+	ds2 = ai1;
+	ar2 = ar1;
+	ai2 = ai1;
+	i__2 = ipph;
+	for (j = 3; j <= i__2; ++j) {
+	    jc = ipp2 - j;
+	    ar2h = dc2 * ar2 - ds2 * ai2;
+	    ai2 = dc2 * ai2 + ds2 * ar2;
+	    ar2 = ar2h;
+	    i__3 = *idl1;
+	    for (ik = 1; ik <= i__3; ++ik) {
+		ch2[ik + l * ch2_dim1] += ar2 * c2[ik + j * c2_dim1];
+		ch2[ik + lc * ch2_dim1] += ai2 * c2[ik + jc * c2_dim1];
+/* L125: */
+	    }
+/* L126: */
+	}
+/* L127: */
+    }
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	i__2 = *idl1;
+	for (ik = 1; ik <= i__2; ++ik) {
+	    ch2[ik + ch2_dim1] += c2[ik + j * c2_dim1];
+/* L128: */
+	}
+/* L129: */
+    }
+
+    if (*ido < *l1) {
+	goto L132;
+    }
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 1; i__ <= i__2; ++i__) {
+	    cc[i__ + (k * cc_dim2 + 1) * cc_dim1] = ch[i__ + (k + ch_dim2) * 
+		    ch_dim1];
+/* L130: */
+	}
+/* L131: */
+    }
+    goto L135;
+L132:
+    i__1 = *ido;
+    for (i__ = 1; i__ <= i__1; ++i__) {
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    cc[i__ + (k * cc_dim2 + 1) * cc_dim1] = ch[i__ + (k + ch_dim2) * 
+		    ch_dim1];
+/* L133: */
+	}
+/* L134: */
+    }
+L135:
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	j2 = j + j;
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    cc[*ido + (j2 - 2 + k * cc_dim2) * cc_dim1] = ch[(k + j * ch_dim2)
+		     * ch_dim1 + 1];
+	    cc[(j2 - 1 + k * cc_dim2) * cc_dim1 + 1] = ch[(k + jc * ch_dim2) *
+		     ch_dim1 + 1];
+/* L136: */
+	}
+/* L137: */
+    }
+    if (*ido == 1) {
+	return 0;
+    }
+    if (nbd < *l1) {
+	goto L141;
+    }
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	j2 = j + j;
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    i__3 = *ido;
+	    for (i__ = 3; i__ <= i__3; i__ += 2) {
+		ic = idp2 - i__;
+		cc[i__ - 1 + (j2 - 1 + k * cc_dim2) * cc_dim1] = ch[i__ - 1 + 
+			(k + j * ch_dim2) * ch_dim1] + ch[i__ - 1 + (k + jc * 
+			ch_dim2) * ch_dim1];
+		cc[ic - 1 + (j2 - 2 + k * cc_dim2) * cc_dim1] = ch[i__ - 1 + (
+			k + j * ch_dim2) * ch_dim1] - ch[i__ - 1 + (k + jc * 
+			ch_dim2) * ch_dim1];
+		cc[i__ + (j2 - 1 + k * cc_dim2) * cc_dim1] = ch[i__ + (k + j *
+			 ch_dim2) * ch_dim1] + ch[i__ + (k + jc * ch_dim2) * 
+			ch_dim1];
+		cc[ic + (j2 - 2 + k * cc_dim2) * cc_dim1] = ch[i__ + (k + jc *
+			 ch_dim2) * ch_dim1] - ch[i__ + (k + j * ch_dim2) * 
+			ch_dim1];
+/* L138: */
+	    }
+/* L139: */
+	}
+/* L140: */
+    }
+    return 0;
+L141:
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	j2 = j + j;
+	i__2 = *ido;
+	for (i__ = 3; i__ <= i__2; i__ += 2) {
+	    ic = idp2 - i__;
+	    i__3 = *l1;
+	    for (k = 1; k <= i__3; ++k) {
+		cc[i__ - 1 + (j2 - 1 + k * cc_dim2) * cc_dim1] = ch[i__ - 1 + 
+			(k + j * ch_dim2) * ch_dim1] + ch[i__ - 1 + (k + jc * 
+			ch_dim2) * ch_dim1];
+		cc[ic - 1 + (j2 - 2 + k * cc_dim2) * cc_dim1] = ch[i__ - 1 + (
+			k + j * ch_dim2) * ch_dim1] - ch[i__ - 1 + (k + jc * 
+			ch_dim2) * ch_dim1];
+		cc[i__ + (j2 - 1 + k * cc_dim2) * cc_dim1] = ch[i__ + (k + j *
+			 ch_dim2) * ch_dim1] + ch[i__ + (k + jc * ch_dim2) * 
+			ch_dim1];
+		cc[ic + (j2 - 2 + k * cc_dim2) * cc_dim1] = ch[i__ + (k + jc *
+			 ch_dim2) * ch_dim1] - ch[i__ + (k + j * ch_dim2) * 
+			ch_dim1];
+/* L142: */
+	    }
+/* L143: */
+	}
+/* L144: */
+    }
+    return 0;
+} /* radfg_ */
+
+/*  ------ File rfftb.f ------ */
+/* Subroutine */ int rfftb_(int_4 *n, r_4 *r__, r_4 *wsave)
+{
+    extern /* Subroutine */ int rfftb1_(int_4 *, r_4 *, r_4 *, r_4 *, 
+	    int_4 *);
+
+    /* Parameter adjustments */
+    --wsave;
+    --r__;
+
+    /* Function Body */
+    if (*n == 1) {
+	return 0;
+    }
+    rfftb1_(n, &r__[1], &wsave[1], &wsave[*n + 1], (int_4 *)&wsave[(*n << 1) + 1]);   /* (int *) rajoute Reza 29/11/99 */
+    return 0;
+} /* rfftb_ */
+
+/*  ------ File rfftb1.f ------ */
+/* Subroutine */ int rfftb1_(int_4 *n, r_4 *c__, r_4 *ch, r_4 *wa, 
+	int_4 *ifac)
+{
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Local variables */
+    extern /* Subroutine */ int radb2_(int_4 *, int_4 *, r_4 *, r_4 *, 
+	    r_4 *), radb3_(int_4 *, int_4 *, r_4 *, r_4 *, r_4 *, 
+	    r_4 *), radb4_(int_4 *, int_4 *, r_4 *, r_4 *, r_4 *, 
+	    r_4 *, r_4 *), radb5_(int_4 *, int_4 *, r_4 *, r_4 *, 
+	    r_4 *, r_4 *, r_4 *, r_4 *);
+    static int_4 i__;
+    extern /* Subroutine */ int radbg_(int_4 *, int_4 *, int_4 *, 
+	    int_4 *, r_4 *, r_4 *, r_4 *, r_4 *, r_4 *, r_4 *);
+    static int_4 k1, l1, l2, na, nf, ip, iw, ix2, ix3, ix4, ido, idl1;
+
+    /* Parameter adjustments */
+    --ifac;
+    --wa;
+    --ch;
+    --c__;
+
+    /* Function Body */
+    nf = ifac[2];
+    na = 0;
+    l1 = 1;
+    iw = 1;
+    i__1 = nf;
+    for (k1 = 1; k1 <= i__1; ++k1) {
+	ip = ifac[k1 + 2];
+	l2 = ip * l1;
+	ido = *n / l2;
+	idl1 = ido * l1;
+	if (ip != 4) {
+	    goto L103;
+	}
+	ix2 = iw + ido;
+	ix3 = ix2 + ido;
+	if (na != 0) {
+	    goto L101;
+	}
+	radb4_(&ido, &l1, &c__[1], &ch[1], &wa[iw], &wa[ix2], &wa[ix3]);
+	goto L102;
+L101:
+	radb4_(&ido, &l1, &ch[1], &c__[1], &wa[iw], &wa[ix2], &wa[ix3]);
+L102:
+	na = 1 - na;
+	goto L115;
+L103:
+	if (ip != 2) {
+	    goto L106;
+	}
+	if (na != 0) {
+	    goto L104;
+	}
+	radb2_(&ido, &l1, &c__[1], &ch[1], &wa[iw]);
+	goto L105;
+L104:
+	radb2_(&ido, &l1, &ch[1], &c__[1], &wa[iw]);
+L105:
+	na = 1 - na;
+	goto L115;
+L106:
+	if (ip != 3) {
+	    goto L109;
+	}
+	ix2 = iw + ido;
+	if (na != 0) {
+	    goto L107;
+	}
+	radb3_(&ido, &l1, &c__[1], &ch[1], &wa[iw], &wa[ix2]);
+	goto L108;
+L107:
+	radb3_(&ido, &l1, &ch[1], &c__[1], &wa[iw], &wa[ix2]);
+L108:
+	na = 1 - na;
+	goto L115;
+L109:
+	if (ip != 5) {
+	    goto L112;
+	}
+	ix2 = iw + ido;
+	ix3 = ix2 + ido;
+	ix4 = ix3 + ido;
+	if (na != 0) {
+	    goto L110;
+	}
+	radb5_(&ido, &l1, &c__[1], &ch[1], &wa[iw], &wa[ix2], &wa[ix3], &wa[
+		ix4]);
+	goto L111;
+L110:
+	radb5_(&ido, &l1, &ch[1], &c__[1], &wa[iw], &wa[ix2], &wa[ix3], &wa[
+		ix4]);
+L111:
+	na = 1 - na;
+	goto L115;
+L112:
+	if (na != 0) {
+	    goto L113;
+	}
+	radbg_(&ido, &ip, &l1, &idl1, &c__[1], &c__[1], &c__[1], &ch[1], &ch[
+		1], &wa[iw]);
+	goto L114;
+L113:
+	radbg_(&ido, &ip, &l1, &idl1, &ch[1], &ch[1], &ch[1], &c__[1], &c__[1]
+		, &wa[iw]);
+L114:
+	if (ido == 1) {
+	    na = 1 - na;
+	}
+L115:
+	l1 = l2;
+	iw += (ip - 1) * ido;
+/* L116: */
+    }
+    if (na == 0) {
+	return 0;
+    }
+    i__1 = *n;
+    for (i__ = 1; i__ <= i__1; ++i__) {
+	c__[i__] = ch[i__];
+/* L117: */
+    }
+    return 0;
+} /* rfftb1_ */
+
+/*  ------ File rfftf.f ------ */
+/* Subroutine */ int rfftf_(int_4 *n, r_4 *r__, r_4 *wsave)
+{
+    extern /* Subroutine */ int rfftf1_(int_4 *, r_4 *, r_4 *, r_4 *, 
+	    int_4 *);
+
+    /* Parameter adjustments */
+    --wsave;
+    --r__;
+
+    /* Function Body */
+    if (*n == 1) {
+	return 0;
+    }
+    rfftf1_(n, &r__[1], &wsave[1], &wsave[*n + 1], (int_4 *)&wsave[(*n << 1) + 1]); /* (int *) rajoute Reza 29/11/99 */
+    return 0;
+} /* rfftf_ */
+
+/*  ------ File rfftf1.f ------ */
+/* Subroutine */ int rfftf1_(int_4 *n, r_4 *c__, r_4 *ch, r_4 *wa, 
+	int_4 *ifac)
+{
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Local variables */
+    extern /* Subroutine */ int radf2_(int_4 *, int_4 *, r_4 *, r_4 *, 
+	    r_4 *), radf3_(int_4 *, int_4 *, r_4 *, r_4 *, r_4 *, 
+	    r_4 *), radf4_(int_4 *, int_4 *, r_4 *, r_4 *, r_4 *, 
+	    r_4 *, r_4 *), radf5_(int_4 *, int_4 *, r_4 *, r_4 *, 
+	    r_4 *, r_4 *, r_4 *, r_4 *);
+    static int_4 i__;
+    extern /* Subroutine */ int radfg_(int_4 *, int_4 *, int_4 *, 
+	    int_4 *, r_4 *, r_4 *, r_4 *, r_4 *, r_4 *, r_4 *);
+    static int_4 k1, l1, l2, na, kh, nf, ip, iw, ix2, ix3, ix4, ido, idl1;
+
+    /* Parameter adjustments */
+    --ifac;
+    --wa;
+    --ch;
+    --c__;
+
+    /* Function Body */
+    nf = ifac[2];
+    na = 1;
+    l2 = *n;
+    iw = *n;
+    i__1 = nf;
+    for (k1 = 1; k1 <= i__1; ++k1) {
+	kh = nf - k1;
+	ip = ifac[kh + 3];
+	l1 = l2 / ip;
+	ido = *n / l2;
+	idl1 = ido * l1;
+	iw -= (ip - 1) * ido;
+	na = 1 - na;
+	if (ip != 4) {
+	    goto L102;
+	}
+	ix2 = iw + ido;
+	ix3 = ix2 + ido;
+	if (na != 0) {
+	    goto L101;
+	}
+	radf4_(&ido, &l1, &c__[1], &ch[1], &wa[iw], &wa[ix2], &wa[ix3]);
+	goto L110;
+L101:
+	radf4_(&ido, &l1, &ch[1], &c__[1], &wa[iw], &wa[ix2], &wa[ix3]);
+	goto L110;
+L102:
+	if (ip != 2) {
+	    goto L104;
+	}
+	if (na != 0) {
+	    goto L103;
+	}
+	radf2_(&ido, &l1, &c__[1], &ch[1], &wa[iw]);
+	goto L110;
+L103:
+	radf2_(&ido, &l1, &ch[1], &c__[1], &wa[iw]);
+	goto L110;
+L104:
+	if (ip != 3) {
+	    goto L106;
+	}
+	ix2 = iw + ido;
+	if (na != 0) {
+	    goto L105;
+	}
+	radf3_(&ido, &l1, &c__[1], &ch[1], &wa[iw], &wa[ix2]);
+	goto L110;
+L105:
+	radf3_(&ido, &l1, &ch[1], &c__[1], &wa[iw], &wa[ix2]);
+	goto L110;
+L106:
+	if (ip != 5) {
+	    goto L108;
+	}
+	ix2 = iw + ido;
+	ix3 = ix2 + ido;
+	ix4 = ix3 + ido;
+	if (na != 0) {
+	    goto L107;
+	}
+	radf5_(&ido, &l1, &c__[1], &ch[1], &wa[iw], &wa[ix2], &wa[ix3], &wa[
+		ix4]);
+	goto L110;
+L107:
+	radf5_(&ido, &l1, &ch[1], &c__[1], &wa[iw], &wa[ix2], &wa[ix3], &wa[
+		ix4]);
+	goto L110;
+L108:
+	if (ido == 1) {
+	    na = 1 - na;
+	}
+	if (na != 0) {
+	    goto L109;
+	}
+	radfg_(&ido, &ip, &l1, &idl1, &c__[1], &c__[1], &c__[1], &ch[1], &ch[
+		1], &wa[iw]);
+	na = 1;
+	goto L110;
+L109:
+	radfg_(&ido, &ip, &l1, &idl1, &ch[1], &ch[1], &ch[1], &c__[1], &c__[1]
+		, &wa[iw]);
+	na = 0;
+L110:
+	l2 = l1;
+/* L111: */
+    }
+    if (na == 1) {
+	return 0;
+    }
+    i__1 = *n;
+    for (i__ = 1; i__ <= i__1; ++i__) {
+	c__[i__] = ch[i__];
+/* L112: */
+    }
+    return 0;
+} /* rfftf1_ */
+
+/*  ------ File rffti.f ------ */
+/* Subroutine */ int rffti_(int_4 *n, r_4 *wsave)
+{
+    extern /* Subroutine */ int rffti1_(int_4 *, r_4 *, int_4 *);
+
+    /* Parameter adjustments */
+    --wsave;
+
+    /* Function Body */
+    if (*n == 1) {
+	return 0;
+    }
+    rffti1_(n, &wsave[*n + 1], (int_4 *)&wsave[(*n << 1) + 1]); /* (int *) rajoute Reza 29/11/99 */
+    return 0;
+} /* rffti_ */
+
+/*  ------ File rffti1.f ------ */
+/* Subroutine */ int rffti1_(int_4 *n, r_4 *wa, int_4 *ifac)
+{
+    /* Initialized data */
+
+    static int_4 ntryh[4] = { 4,2,3,5 };
+
+    /* System generated locals */
+    int_4 i__1, i__2, i__3;
+
+    /* Builtin functions */
+/*   r_8 cos(r_8truc), sin(r_8truc);  Remplace par math.h , Reza 29/11/99 */
+
+    /* Local variables */
+    static r_4 argh;
+    static int_4 ntry, i__, j;
+    static r_4 argld;
+    static int_4 k1, l1, l2, ib;
+    static r_4 fi;
+    static int_4 ld, ii, nf, ip, nl, is, nq, nr;
+    static r_4 arg;
+    static int_4 ido, ipm;
+    static r_4 tpi;
+    static int_4 nfm1;
+
+    /* Parameter adjustments */
+    --ifac;
+    --wa;
+
+    /* Function Body */
+    nl = *n;
+    nf = 0;
+    j = 0;
+L101:
+    ++j;
+    if (j - 4 <= 0) {
+	goto L102;
+    } else {
+	goto L103;
+    }
+L102:
+    ntry = ntryh[j - 1];
+    goto L104;
+L103:
+    ntry += 2;
+L104:
+    nq = nl / ntry;
+    nr = nl - ntry * nq;
+    if (nr != 0) {
+	goto L101;
+    } else {
+	goto L105;
+    }
+L105:
+    ++nf;
+    ifac[nf + 2] = ntry;
+    nl = nq;
+    if (ntry != 2) {
+	goto L107;
+    }
+    if (nf == 1) {
+	goto L107;
+    }
+    i__1 = nf;
+    for (i__ = 2; i__ <= i__1; ++i__) {
+	ib = nf - i__ + 2;
+	ifac[ib + 2] = ifac[ib + 1];
+/* L106: */
+    }
+    ifac[3] = 2;
+L107:
+    if (nl != 1) {
+	goto L104;
+    }
+    ifac[1] = *n;
+    ifac[2] = nf;
+    tpi = 6.28318530717959f;
+    argh = tpi / (r_4) (*n);
+    is = 0;
+    nfm1 = nf - 1;
+    l1 = 1;
+    if (nfm1 == 0) {
+	return 0;
+    }
+    i__1 = nfm1;
+    for (k1 = 1; k1 <= i__1; ++k1) {
+	ip = ifac[k1 + 2];
+	ld = 0;
+	l2 = l1 * ip;
+	ido = *n / l2;
+	ipm = ip - 1;
+	i__2 = ipm;
+	for (j = 1; j <= i__2; ++j) {
+	    ld += l1;
+	    i__ = is;
+	    argld = (r_4) ld * argh;
+	    fi = 0.f;
+	    i__3 = ido;
+	    for (ii = 3; ii <= i__3; ii += 2) {
+		i__ += 2;
+		fi += 1.f;
+		arg = fi * argld;
+		wa[i__ - 1] = cos(arg);
+		wa[i__] = sin(arg);
+/* L108: */
+	    }
+	    is += ido;
+/* L109: */
+	}
+	l1 = l2;
+/* L110: */
+    }
+    return 0;
+} /* rffti1_ */
+
+/*  ------ File sinqb.f ------ */
+/* Subroutine */ int sinqb_(int_4 *n, r_4 *x, r_4 *wsave)
+{
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Local variables */
+    static int_4 k;
+    extern /* Subroutine */ int cosqb_(int_4 *, r_4 *, r_4 *);
+    static r_4 xhold;
+    static int_4 kc, ns2;
+
+    /* Parameter adjustments */
+    --wsave;
+    --x;
+
+    /* Function Body */
+    if (*n > 1) {
+	goto L101;
+    }
+    x[1] *= 4.f;
+    return 0;
+L101:
+    ns2 = *n / 2;
+    i__1 = *n;
+    for (k = 2; k <= i__1; k += 2) {
+	x[k] = -x[k];
+/* L102: */
+    }
+    cosqb_(n, &x[1], &wsave[1]);
+    i__1 = ns2;
+    for (k = 1; k <= i__1; ++k) {
+	kc = *n - k;
+	xhold = x[k];
+	x[k] = x[kc + 1];
+	x[kc + 1] = xhold;
+/* L103: */
+    }
+    return 0;
+} /* sinqb_ */
+
+/*  ------ File sinqf.f ------ */
+/* Subroutine */ int sinqf_(int_4 *n, r_4 *x, r_4 *wsave)
+{
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Local variables */
+    static int_4 k;
+    extern /* Subroutine */ int cosqf_(int_4 *, r_4 *, r_4 *);
+    static r_4 xhold;
+    static int_4 kc, ns2;
+
+    /* Parameter adjustments */
+    --wsave;
+    --x;
+
+    /* Function Body */
+    if (*n == 1) {
+	return 0;
+    }
+    ns2 = *n / 2;
+    i__1 = ns2;
+    for (k = 1; k <= i__1; ++k) {
+	kc = *n - k;
+	xhold = x[k];
+	x[k] = x[kc + 1];
+	x[kc + 1] = xhold;
+/* L101: */
+    }
+    cosqf_(n, &x[1], &wsave[1]);
+    i__1 = *n;
+    for (k = 2; k <= i__1; k += 2) {
+	x[k] = -x[k];
+/* L102: */
+    }
+    return 0;
+} /* sinqf_ */
+
+/*  ------ File sinqi.f ------ */
+/* Subroutine */ int sinqi_(int_4 *n, r_4 *wsave)
+{
+    extern /* Subroutine */ int cosqi_(int_4 *, r_4 *);
+
+    /* Parameter adjustments */
+    --wsave;
+
+    /* Function Body */
+    cosqi_(n, &wsave[1]);
+    return 0;
+} /* sinqi_ */
+
+/*  ------ File sint.f ------ */
+/* Subroutine */ int sint_(int_4 *n, r_4 *x, r_4 *wsave)
+{
+    extern /* Subroutine */ int sint1_(int_4 *, r_4 *, r_4 *, r_4 *, 
+	    r_4 *, int_4 *);
+    static int_4 np1, iw1, iw2, iw3;
+
+    /* Parameter adjustments */
+    --wsave;
+    --x;
+
+    /* Function Body */
+    np1 = *n + 1;
+    iw1 = *n / 2 + 1;
+    iw2 = iw1 + np1;
+    iw3 = iw2 + np1;
+    sint1_(n, &x[1], &wsave[1], &wsave[iw1], &wsave[iw2], (int_4 *)&wsave[iw3]);  /* (int *) rajoute Reza 29/11/99 */
+    return 0;
+} /* sint_ */
+
+/*  ------ File sint1.f ------ */
+/* Subroutine */ int sint1_(int_4 *n, r_4 *war, r_4 *was, r_4 *xh, r_4 *
+	x, int_4 *ifac)
+{
+    /* Initialized data */
+
+    static r_4 sqrt3 = 1.73205080756888f;
+
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Local variables */
+    static int_4 modn, i__, k;
+    static r_4 xhold, t1, t2;
+    extern /* Subroutine */ int rfftf1_(int_4 *, r_4 *, r_4 *, r_4 *, 
+	    int_4 *);
+    static int_4 kc, np1, ns2;
+
+    /* Parameter adjustments */
+    --ifac;
+    --x;
+    --xh;
+    --was;
+    --war;
+
+    /* Function Body */
+    i__1 = *n;
+    for (i__ = 1; i__ <= i__1; ++i__) {
+	xh[i__] = war[i__];
+	war[i__] = x[i__];
+/* L100: */
+    }
+    if ((i__1 = *n - 2) < 0) {
+	goto L101;
+    } else if (i__1 == 0) {
+	goto L102;
+    } else {
+	goto L103;
+    }
+L101:
+    xh[1] += xh[1];
+    goto L106;
+L102:
+    xhold = sqrt3 * (xh[1] + xh[2]);
+    xh[2] = sqrt3 * (xh[1] - xh[2]);
+    xh[1] = xhold;
+    goto L106;
+L103:
+    np1 = *n + 1;
+    ns2 = *n / 2;
+    x[1] = 0.f;
+    i__1 = ns2;
+    for (k = 1; k <= i__1; ++k) {
+	kc = np1 - k;
+	t1 = xh[k] - xh[kc];
+	t2 = was[k] * (xh[k] + xh[kc]);
+	x[k + 1] = t1 + t2;
+	x[kc + 1] = t2 - t1;
+/* L104: */
+    }
+    modn = *n % 2;
+    if (modn != 0) {
+	x[ns2 + 2] = xh[ns2 + 1] * 4.f;
+    }
+    rfftf1_(&np1, &x[1], &xh[1], &war[1], &ifac[1]);
+    xh[1] = x[1] * .5f;
+    i__1 = *n;
+    for (i__ = 3; i__ <= i__1; i__ += 2) {
+	xh[i__ - 1] = -x[i__];
+	xh[i__] = xh[i__ - 2] + x[i__ - 1];
+/* L105: */
+    }
+    if (modn != 0) {
+	goto L106;
+    }
+    xh[*n] = -x[*n + 1];
+L106:
+    i__1 = *n;
+    for (i__ = 1; i__ <= i__1; ++i__) {
+	x[i__] = war[i__];
+	war[i__] = xh[i__];
+/* L107: */
+    }
+    return 0;
+} /* sint1_ */
+
+/*  ------ File sinti.f ------ */
+/* Subroutine */ int sinti_(int_4 *n, r_4 *wsave)
+{
+    /* Initialized data */
+
+    static r_4 pi = 3.14159265358979f;
+
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Builtin functions */
+/*    r_8 sin(r_8truc);  remplace par math.h , Reza 29/11/99 */
+
+    /* Local variables */
+    static int_4 k;
+    extern /* Subroutine */ int rffti_(int_4 *, r_4 *);
+    static r_4 dt;
+    static int_4 np1, ns2;
+
+    /* Parameter adjustments */
+    --wsave;
+
+    /* Function Body */
+    if (*n <= 1) {
+	return 0;
+    }
+    ns2 = *n / 2;
+    np1 = *n + 1;
+    dt = pi / (r_4) np1;
+    i__1 = ns2;
+    for (k = 1; k <= i__1; ++k) {
+	wsave[k] = sin(k * dt) * 2.f;
+/* L101: */
+    }
+    rffti_(&np1, &wsave[ns2 + 1]);
+    return 0;
+} /* sinti_ */
+
+/* --------------------------------------------------------------- */
+/* -------------- make a r_8 version of the library ----------- */
+/* --------------------------------------------------------------- */
+
+/* Subroutine */ int cdfftb_(int_4 *n, r_8 *c__, r_8 *wsave)
+{
+    extern /* Subroutine */ int cdfftb1_(int_4 *, r_8 *, r_8 *, r_8 *, 
+	    int_8 *);
+    static int_4 iw1, iw2;
+
+    /* Parameter adjustments */
+    --wsave;
+    --c__;
+
+    /* Function Body */
+    if (*n == 1) {
+	return 0;
+    }
+    iw1 = *n + *n + 1;
+    iw2 = iw1 + *n + *n;
+    cdfftb1_(n, &c__[1], &wsave[1], &wsave[iw1], (int_8 *)&wsave[iw2]); /* (int *) rajoute Reza 29/11/99 */
+    return 0;
+} /* cdfftb_ */
+
+/*  ------ File cdfftb1.f ------ */
+/* Subroutine */ int cdfftb1_(int_4 *n, r_8 *c__, r_8 *ch, r_8 *wa, 
+	int_8 *ifac)
+{
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Local variables */
+    static int_4 idot, i__;
+    extern /* Subroutine */ int dpassb_(int_4 *, int_4 *, int_4 *, 
+	    int_4 *, int_4 *, r_8 *, r_8 *, r_8 *, r_8 *, r_8 *, 
+	    r_8 *);
+    static int_4 k1, l1, l2, n2;
+    extern /* Subroutine */ int dpassb2_(int_4 *, int_4 *, r_8 *, r_8 *, 
+	    r_8 *), dpassb3_(int_4 *, int_4 *, r_8 *, r_8 *, r_8 *, 
+	    r_8 *), dpassb4_(int_4 *, int_4 *, r_8 *, r_8 *, r_8 *, 
+	    r_8 *, r_8 *), dpassb5_(int_4 *, int_4 *, r_8 *, r_8 *, 
+	    r_8 *, r_8 *, r_8 *, r_8 *);
+    static int_4 na, nf, ip, iw, ix2, ix3, ix4, nac, ido, idl1;
+
+    /* Parameter adjustments */
+    --ifac;
+    --wa;
+    --ch;
+    --c__;
+
+    /* Function Body */
+    nf = ifac[2];
+    na = 0;
+    l1 = 1;
+    iw = 1;
+    i__1 = nf;
+    for (k1 = 1; k1 <= i__1; ++k1) {
+	ip = ifac[k1 + 2];
+	l2 = ip * l1;
+	ido = *n / l2;
+	idot = ido + ido;
+	idl1 = idot * l1;
+	if (ip != 4) {
+	    goto L103;
+	}
+	ix2 = iw + idot;
+	ix3 = ix2 + idot;
+	if (na != 0) {
+	    goto L101;
+	}
+	dpassb4_(&idot, &l1, &c__[1], &ch[1], &wa[iw], &wa[ix2], &wa[ix3]);
+	goto L102;
+L101:
+	dpassb4_(&idot, &l1, &ch[1], &c__[1], &wa[iw], &wa[ix2], &wa[ix3]);
+L102:
+	na = 1 - na;
+	goto L115;
+L103:
+	if (ip != 2) {
+	    goto L106;
+	}
+	if (na != 0) {
+	    goto L104;
+	}
+	dpassb2_(&idot, &l1, &c__[1], &ch[1], &wa[iw]);
+	goto L105;
+L104:
+	dpassb2_(&idot, &l1, &ch[1], &c__[1], &wa[iw]);
+L105:
+	na = 1 - na;
+	goto L115;
+L106:
+	if (ip != 3) {
+	    goto L109;
+	}
+	ix2 = iw + idot;
+	if (na != 0) {
+	    goto L107;
+	}
+	dpassb3_(&idot, &l1, &c__[1], &ch[1], &wa[iw], &wa[ix2]);
+	goto L108;
+L107:
+	dpassb3_(&idot, &l1, &ch[1], &c__[1], &wa[iw], &wa[ix2]);
+L108:
+	na = 1 - na;
+	goto L115;
+L109:
+	if (ip != 5) {
+	    goto L112;
+	}
+	ix2 = iw + idot;
+	ix3 = ix2 + idot;
+	ix4 = ix3 + idot;
+	if (na != 0) {
+	    goto L110;
+	}
+	dpassb5_(&idot, &l1, &c__[1], &ch[1], &wa[iw], &wa[ix2], &wa[ix3], &wa[
+		ix4]);
+	goto L111;
+L110:
+	dpassb5_(&idot, &l1, &ch[1], &c__[1], &wa[iw], &wa[ix2], &wa[ix3], &wa[
+		ix4]);
+L111:
+	na = 1 - na;
+	goto L115;
+L112:
+	if (na != 0) {
+	    goto L113;
+	}
+	dpassb_(&nac, &idot, &ip, &l1, &idl1, &c__[1], &c__[1], &c__[1], &ch[1]
+		, &ch[1], &wa[iw]);
+	goto L114;
+L113:
+	dpassb_(&nac, &idot, &ip, &l1, &idl1, &ch[1], &ch[1], &ch[1], &c__[1], 
+		&c__[1], &wa[iw]);
+L114:
+	if (nac != 0) {
+	    na = 1 - na;
+	}
+L115:
+	l1 = l2;
+	iw += (ip - 1) * idot;
+/* L116: */
+    }
+    if (na == 0) {
+	return 0;
+    }
+    n2 = *n + *n;
+    i__1 = n2;
+    for (i__ = 1; i__ <= i__1; ++i__) {
+	c__[i__] = ch[i__];
+/* L117: */
+    }
+    return 0;
+} /* cdfftb1_ */
+
+/*  ------ File cdfftf.f ------ */
+/* Subroutine */ int cdfftf_(int_4 *n, r_8 *c__, r_8 *wsave)
+{
+    extern /* Subroutine */ int cdfftf1_(int_4 *, r_8 *, r_8 *, r_8 *, 
+	    int_8 *);
+    static int_4 iw1, iw2;
+
+    /* Parameter adjustments */
+    --wsave;
+    --c__;
+
+    /* Function Body */
+    if (*n == 1) {
+	return 0;
+    }
+    iw1 = *n + *n + 1;
+    iw2 = iw1 + *n + *n;
+    cdfftf1_(n, &c__[1], &wsave[1], &wsave[iw1], (int_8 *)&wsave[iw2]); /* (int *) rajoute Reza 29/11/99 */
+    return 0;
+} /* cdfftf_ */
+
+/*  ------ File cdfftf1.f ------ */
+/* Subroutine */ int cdfftf1_(int_4 *n, r_8 *c__, r_8 *ch, r_8 *wa, 
+	int_8 *ifac)
+{
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Local variables */
+    static int_4 idot, i__;
+    extern /* Subroutine */ int dpassf_(int_4 *, int_4 *, int_4 *, 
+	    int_4 *, int_4 *, r_8 *, r_8 *, r_8 *, r_8 *, r_8 *, 
+	    r_8 *);
+    static int_4 k1, l1, l2, n2;
+    extern /* Subroutine */ int dpassf2_(int_4 *, int_4 *, r_8 *, r_8 *, 
+	    r_8 *), dpassf3_(int_4 *, int_4 *, r_8 *, r_8 *, r_8 *, 
+	    r_8 *), dpassf4_(int_4 *, int_4 *, r_8 *, r_8 *, r_8 *, 
+	    r_8 *, r_8 *), dpassf5_(int_4 *, int_4 *, r_8 *, r_8 *, 
+	    r_8 *, r_8 *, r_8 *, r_8 *);
+    static int_4 na, nf, ip, iw, ix2, ix3, ix4, nac, ido, idl1;
+
+    /* Parameter adjustments */
+    --ifac;
+    --wa;
+    --ch;
+    --c__;
+
+    /* Function Body */
+    nf = ifac[2];
+    na = 0;
+    l1 = 1;
+    iw = 1;
+    i__1 = nf;
+    for (k1 = 1; k1 <= i__1; ++k1) {
+	ip = ifac[k1 + 2];
+	l2 = ip * l1;
+	ido = *n / l2;
+	idot = ido + ido;
+	idl1 = idot * l1;
+	if (ip != 4) {
+	    goto L103;
+	}
+	ix2 = iw + idot;
+	ix3 = ix2 + idot;
+	if (na != 0) {
+	    goto L101;
+	}
+	dpassf4_(&idot, &l1, &c__[1], &ch[1], &wa[iw], &wa[ix2], &wa[ix3]);
+	goto L102;
+L101:
+	dpassf4_(&idot, &l1, &ch[1], &c__[1], &wa[iw], &wa[ix2], &wa[ix3]);
+L102:
+	na = 1 - na;
+	goto L115;
+L103:
+	if (ip != 2) {
+	    goto L106;
+	}
+	if (na != 0) {
+	    goto L104;
+	}
+	dpassf2_(&idot, &l1, &c__[1], &ch[1], &wa[iw]);
+	goto L105;
+L104:
+	dpassf2_(&idot, &l1, &ch[1], &c__[1], &wa[iw]);
+L105:
+	na = 1 - na;
+	goto L115;
+L106:
+	if (ip != 3) {
+	    goto L109;
+	}
+	ix2 = iw + idot;
+	if (na != 0) {
+	    goto L107;
+	}
+	dpassf3_(&idot, &l1, &c__[1], &ch[1], &wa[iw], &wa[ix2]);
+	goto L108;
+L107:
+	dpassf3_(&idot, &l1, &ch[1], &c__[1], &wa[iw], &wa[ix2]);
+L108:
+	na = 1 - na;
+	goto L115;
+L109:
+	if (ip != 5) {
+	    goto L112;
+	}
+	ix2 = iw + idot;
+	ix3 = ix2 + idot;
+	ix4 = ix3 + idot;
+	if (na != 0) {
+	    goto L110;
+	}
+	dpassf5_(&idot, &l1, &c__[1], &ch[1], &wa[iw], &wa[ix2], &wa[ix3], &wa[
+		ix4]);
+	goto L111;
+L110:
+	dpassf5_(&idot, &l1, &ch[1], &c__[1], &wa[iw], &wa[ix2], &wa[ix3], &wa[
+		ix4]);
+L111:
+	na = 1 - na;
+	goto L115;
+L112:
+	if (na != 0) {
+	    goto L113;
+	}
+	dpassf_(&nac, &idot, &ip, &l1, &idl1, &c__[1], &c__[1], &c__[1], &ch[1]
+		, &ch[1], &wa[iw]);
+	goto L114;
+L113:
+	dpassf_(&nac, &idot, &ip, &l1, &idl1, &ch[1], &ch[1], &ch[1], &c__[1], 
+		&c__[1], &wa[iw]);
+L114:
+	if (nac != 0) {
+	    na = 1 - na;
+	}
+L115:
+	l1 = l2;
+	iw += (ip - 1) * idot;
+/* L116: */
+    }
+    if (na == 0) {
+	return 0;
+    }
+    n2 = *n + *n;
+    i__1 = n2;
+    for (i__ = 1; i__ <= i__1; ++i__) {
+	c__[i__] = ch[i__];
+/* L117: */
+    }
+    return 0;
+} /* cdfftf1_ */
+
+/*  ------ File cdffti.f ------ */
+/* Subroutine */ int cdffti_(int_4 *n, r_8 *wsave)
+{
+    extern /* Subroutine */ int cdffti1_(int_4 *, r_8 *, int_8 *);
+    static int_4 iw1, iw2;
+
+    /* Parameter adjustments */
+    --wsave;
+
+    /* Function Body */
+    if (*n == 1) {
+	return 0;
+    }
+    iw1 = *n + *n + 1;
+    iw2 = iw1 + *n + *n;
+    cdffti1_(n, &wsave[iw1], (int_8 *)&wsave[iw2]); /* (int *) rajoute Reza 29/11/99 */
+    return 0;
+} /* cdffti_ */
+
+/*  ------ File cdffti1.f ------ */
+/* Subroutine */ int cdffti1_(int_4 *n, r_8 *wa, int_8 *ifac)
+{
+    /* Initialized data */
+
+    static int_4 ntryh[4] = { 3,4,2,5 };
+
+    /* System generated locals */
+    int_4 i__1, i__2, i__3;
+
+    /* Builtin functions */
+/*    r_8 cos(r_8truc), sin(r_8truc);  remplace par math.h  Reza 29/11/99 */
+
+    /* Local variables */
+    static r_8 argh;
+    static int_4 idot, ntry, i__, j;
+    static r_8 argld;
+    static int_4 i1, k1, l1, l2, ib;
+    static r_8 fi;
+    static int_4 ld, ii, nf, ip, nl, nq, nr;
+    static r_8 arg;
+    static int_4 ido, ipm;
+    static r_8 tpi;
+
+    /* Parameter adjustments */
+    --ifac;
+    --wa;
+
+    /* Function Body */
+    nl = *n;
+    nf = 0;
+    j = 0;
+L101:
+    ++j;
+    if (j - 4 <= 0) {
+	goto L102;
+    } else {
+	goto L103;
+    }
+L102:
+    ntry = ntryh[j - 1];
+    goto L104;
+L103:
+    ntry += 2;
+L104:
+    nq = nl / ntry;
+    nr = nl - ntry * nq;
+    if (nr != 0) {
+	goto L101;
+    } else {
+	goto L105;
+    }
+L105:
+    ++nf;
+    ifac[nf + 2] = ntry;
+    nl = nq;
+    if (ntry != 2) {
+	goto L107;
+    }
+    if (nf == 1) {
+	goto L107;
+    }
+    i__1 = nf;
+    for (i__ = 2; i__ <= i__1; ++i__) {
+	ib = nf - i__ + 2;
+	ifac[ib + 2] = ifac[ib + 1];
+/* L106: */
+    }
+    ifac[3] = 2;
+L107:
+    if (nl != 1) {
+	goto L104;
+    }
+    ifac[1] = *n;
+    ifac[2] = nf;
+    tpi = 6.28318530717959f;
+    argh = tpi / (r_8) (*n);
+    i__ = 2;
+    l1 = 1;
+    i__1 = nf;
+    for (k1 = 1; k1 <= i__1; ++k1) {
+	ip = ifac[k1 + 2];
+	ld = 0;
+	l2 = l1 * ip;
+	ido = *n / l2;
+	idot = ido + ido + 2;
+	ipm = ip - 1;
+	i__2 = ipm;
+	for (j = 1; j <= i__2; ++j) {
+	    i1 = i__;
+	    wa[i__ - 1] = 1.f;
+	    wa[i__] = 0.f;
+	    ld += l1;
+	    fi = 0.f;
+	    argld = (r_8) ld * argh;
+	    i__3 = idot;
+	    for (ii = 4; ii <= i__3; ii += 2) {
+		i__ += 2;
+		fi += 1.f;
+		arg = fi * argld;
+		wa[i__ - 1] = cos(arg);
+		wa[i__] = sin(arg);
+/* L108: */
+	    }
+	    if (ip <= 5) {
+		goto L109;
+	    }
+	    wa[i1 - 1] = wa[i__ - 1];
+	    wa[i1] = wa[i__];
+L109:
+	    ;
+	}
+	l1 = l2;
+/* L110: */
+    }
+    return 0;
+} /* cdffti1_ */
+
+/*  ------ File dcosqb.f ------ */
+/* Subroutine */ int dcosqb_(int_4 *n, r_8 *x, r_8 *wsave)
+{
+    /* Initialized data */
+
+    static r_8 tsqrt2 = 2.82842712474619f;
+
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Local variables */
+    static r_8 x1;
+    extern /* Subroutine */ int dcosqb1_(int_4 *, r_8 *, r_8 *, r_8 *);
+
+    /* Parameter adjustments */
+    --wsave;
+    --x;
+
+    /* Function Body */
+    if ((i__1 = *n - 2) < 0) {
+	goto L101;
+    } else if (i__1 == 0) {
+	goto L102;
+    } else {
+	goto L103;
+    }
+L101:
+    x[1] *= 4.f;
+    return 0;
+L102:
+    x1 = (x[1] + x[2]) * 4.f;
+    x[2] = tsqrt2 * (x[1] - x[2]);
+    x[1] = x1;
+    return 0;
+L103:
+    dcosqb1_(n, &x[1], &wsave[1], &wsave[*n + 1]);
+    return 0;
+} /* dcosqb_ */
+
+/*  ------ File dcosqb1.f ------ */
+/* Subroutine */ int dcosqb1_(int_4 *n, r_8 *x, r_8 *w, r_8 *xh)
+{
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Local variables */
+    static int_4 modn, i__, k;
+    extern /* Subroutine */ int dfftb_(int_4 *, r_8 *, r_8 *);
+    static int_4 kc, np2, ns2;
+    static r_8 xim1;
+
+    /* Parameter adjustments */
+    --xh;
+    --w;
+    --x;
+
+    /* Function Body */
+    ns2 = (*n + 1) / 2;
+    np2 = *n + 2;
+    i__1 = *n;
+    for (i__ = 3; i__ <= i__1; i__ += 2) {
+	xim1 = x[i__ - 1] + x[i__];
+	x[i__] -= x[i__ - 1];
+	x[i__ - 1] = xim1;
+/* L101: */
+    }
+    x[1] += x[1];
+    modn = *n % 2;
+    if (modn == 0) {
+	x[*n] += x[*n];
+    }
+    dfftb_(n, &x[1], &xh[1]);
+    i__1 = ns2;
+    for (k = 2; k <= i__1; ++k) {
+	kc = np2 - k;
+	xh[k] = w[k - 1] * x[kc] + w[kc - 1] * x[k];
+	xh[kc] = w[k - 1] * x[k] - w[kc - 1] * x[kc];
+/* L102: */
+    }
+    if (modn == 0) {
+	x[ns2 + 1] = w[ns2] * (x[ns2 + 1] + x[ns2 + 1]);
+    }
+    i__1 = ns2;
+    for (k = 2; k <= i__1; ++k) {
+	kc = np2 - k;
+	x[k] = xh[k] + xh[kc];
+	x[kc] = xh[k] - xh[kc];
+/* L103: */
+    }
+    x[1] += x[1];
+    return 0;
+} /* dcosqb1_ */
+
+/*  ------ File dcosqf.f ------ */
+/* Subroutine */ int dcosqf_(int_4 *n, r_8 *x, r_8 *wsave)
+{
+    /* Initialized data */
+
+    static r_8 sqrt2 = 1.4142135623731f;
+
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Local variables */
+    static r_8 tsqx;
+    extern /* Subroutine */ int dcosqf1_(int_4 *, r_8 *, r_8 *, r_8 *);
+
+    /* Parameter adjustments */
+    --wsave;
+    --x;
+
+    /* Function Body */
+    if ((i__1 = *n - 2) < 0) {
+	goto L102;
+    } else if (i__1 == 0) {
+	goto L101;
+    } else {
+	goto L103;
+    }
+L101:
+    tsqx = sqrt2 * x[2];
+    x[2] = x[1] - tsqx;
+    x[1] += tsqx;
+L102:
+    return 0;
+L103:
+    dcosqf1_(n, &x[1], &wsave[1], &wsave[*n + 1]);
+    return 0;
+} /* dcosqf_ */
+
+/*  ------ File dcosqf1.f ------ */
+/* Subroutine */ int dcosqf1_(int_4 *n, r_8 *x, r_8 *w, r_8 *xh)
+{
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Local variables */
+    static int_4 modn, i__, k;
+    extern /* Subroutine */ int dfftf_(int_4 *, r_8 *, r_8 *);
+    static int_4 kc, np2, ns2;
+    static r_8 xim1;
+
+    /* Parameter adjustments */
+    --xh;
+    --w;
+    --x;
+
+    /* Function Body */
+    ns2 = (*n + 1) / 2;
+    np2 = *n + 2;
+    i__1 = ns2;
+    for (k = 2; k <= i__1; ++k) {
+	kc = np2 - k;
+	xh[k] = x[k] + x[kc];
+	xh[kc] = x[k] - x[kc];
+/* L101: */
+    }
+    modn = *n % 2;
+    if (modn == 0) {
+	xh[ns2 + 1] = x[ns2 + 1] + x[ns2 + 1];
+    }
+    i__1 = ns2;
+    for (k = 2; k <= i__1; ++k) {
+	kc = np2 - k;
+	x[k] = w[k - 1] * xh[kc] + w[kc - 1] * xh[k];
+	x[kc] = w[k - 1] * xh[k] - w[kc - 1] * xh[kc];
+/* L102: */
+    }
+    if (modn == 0) {
+	x[ns2 + 1] = w[ns2] * xh[ns2 + 1];
+    }
+    dfftf_(n, &x[1], &xh[1]);
+    i__1 = *n;
+    for (i__ = 3; i__ <= i__1; i__ += 2) {
+	xim1 = x[i__ - 1] - x[i__];
+	x[i__] = x[i__ - 1] + x[i__];
+	x[i__ - 1] = xim1;
+/* L103: */
+    }
+    return 0;
+} /* dcosqf1_ */
+
+/*  ------ File dcosqi.f ------ */
+/* Subroutine */ int dcosqi_(int_4 *n, r_8 *wsave)
+{
+    /* Initialized data */
+
+    static r_8 pih = 1.57079632679491f;
+
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Builtin functions */
+/*    r_8 cos(r_8truc); remplace par math.h  Reza 29/11/99 */
+
+    /* Local variables */
+    static int_4 k;
+    extern /* Subroutine */ int dffti_(int_4 *, r_8 *);
+    static r_8 fk, dt;
+
+    /* Parameter adjustments */
+    --wsave;
+
+    /* Function Body */
+    dt = pih / (r_8) (*n);
+    fk = 0.f;
+    i__1 = *n;
+    for (k = 1; k <= i__1; ++k) {
+	fk += 1.f;
+	wsave[k] = cos(fk * dt);
+/* L101: */
+    }
+    dffti_(n, &wsave[*n + 1]);
+    return 0;
+} /* dcosqi_ */
+
+/*  ------ File dcost.f ------ */
+/* Subroutine */ int dcost_(int_4 *n, r_8 *x, r_8 *wsave)
+{
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Local variables */
+    static int_4 modn, i__, k;
+    extern /* Subroutine */ int dfftf_(int_4 *, r_8 *, r_8 *);
+    static r_8 c1, t1, t2;
+    static int_4 kc;
+    static r_8 xi;
+    static int_4 nm1, np1;
+    static r_8 x1h;
+    static int_4 ns2;
+    static r_8 tx2, x1p3, xim2;
+
+    /* Parameter adjustments */
+    --wsave;
+    --x;
+
+    /* Function Body */
+    nm1 = *n - 1;
+    np1 = *n + 1;
+    ns2 = *n / 2;
+    if ((i__1 = *n - 2) < 0) {
+	goto L106;
+    } else if (i__1 == 0) {
+	goto L101;
+    } else {
+	goto L102;
+    }
+L101:
+    x1h = x[1] + x[2];
+    x[2] = x[1] - x[2];
+    x[1] = x1h;
+    return 0;
+L102:
+    if (*n > 3) {
+	goto L103;
+    }
+    x1p3 = x[1] + x[3];
+    tx2 = x[2] + x[2];
+    x[2] = x[1] - x[3];
+    x[1] = x1p3 + tx2;
+    x[3] = x1p3 - tx2;
+    return 0;
+L103:
+    c1 = x[1] - x[*n];
+    x[1] += x[*n];
+    i__1 = ns2;
+    for (k = 2; k <= i__1; ++k) {
+	kc = np1 - k;
+	t1 = x[k] + x[kc];
+	t2 = x[k] - x[kc];
+	c1 += wsave[kc] * t2;
+	t2 = wsave[k] * t2;
+	x[k] = t1 - t2;
+	x[kc] = t1 + t2;
+/* L104: */
+    }
+    modn = *n % 2;
+    if (modn != 0) {
+	x[ns2 + 1] += x[ns2 + 1];
+    }
+    dfftf_(&nm1, &x[1], &wsave[*n + 1]);
+    xim2 = x[2];
+    x[2] = c1;
+    i__1 = *n;
+    for (i__ = 4; i__ <= i__1; i__ += 2) {
+	xi = x[i__];
+	x[i__] = x[i__ - 2] - x[i__ - 1];
+	x[i__ - 1] = xim2;
+	xim2 = xi;
+/* L105: */
+    }
+    if (modn != 0) {
+	x[*n] = xim2;
+    }
+L106:
+    return 0;
+} /* dcost_ */
+
+/*  ------ File dcosti.f ------ */
+/* Subroutine */ int dcosti_(int_4 *n, r_8 *wsave)
+{
+    /* Initialized data */
+
+    static r_8 pi = 3.14159265358979f;
+
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Builtin functions */
+/*    r_8 sin(r_8truc), cos(r_8truc);  remplace par math.h  Reza 29/11/99 */
+
+    /* Local variables */
+    static int_4 k;
+    extern /* Subroutine */ int dffti_(int_4 *, r_8 *);
+    static int_4 kc;
+    static r_8 fk, dt;
+    static int_4 nm1, np1, ns2;
+
+    /* Parameter adjustments */
+    --wsave;
+
+    /* Function Body */
+    if (*n <= 3) {
+	return 0;
+    }
+    nm1 = *n - 1;
+    np1 = *n + 1;
+    ns2 = *n / 2;
+    dt = pi / (r_8) nm1;
+    fk = 0.f;
+    i__1 = ns2;
+    for (k = 2; k <= i__1; ++k) {
+	kc = np1 - k;
+	fk += 1.f;
+	wsave[k] = sin(fk * dt) * 2.f;
+	wsave[kc] = cos(fk * dt) * 2.f;
+/* L101: */
+    }
+    dffti_(&nm1, &wsave[*n + 1]);
+    return 0;
+} /* dcosti_ */
+
+/*  ------ File dezfft1.f ------ */
+/* Subroutine */ int dezfft1_(int_4 *n, r_8 *wa, int_8 *ifac)
+{
+    /* Initialized data */
+
+    static int_4 ntryh[4] = { 4,2,3,5 };
+    static r_8 tpi = 6.28318530717959f;
+
+    /* System generated locals */
+    int_4 i__1, i__2, i__3;
+
+    /* Builtin functions */
+/*    r_8 cos(r_8truc), sin(r_8truc);  remplace par math.h  Reza 29/11/99  */
+
+    /* Local variables */
+    static r_8 argh;
+    static int_4 ntry, i__, j, k1, l1, l2, ib, ii, nf, ip, nl, is, nq, nr;
+    static r_8 ch1, sh1;
+    static int_4 ido, ipm;
+    static r_8 dch1, ch1h, arg1, dsh1;
+    static int_4 nfm1;
+
+    /* Parameter adjustments */
+    --ifac;
+    --wa;
+
+    /* Function Body */
+    nl = *n;
+    nf = 0;
+    j = 0;
+L101:
+    ++j;
+    if (j - 4 <= 0) {
+	goto L102;
+    } else {
+	goto L103;
+    }
+L102:
+    ntry = ntryh[j - 1];
+    goto L104;
+L103:
+    ntry += 2;
+L104:
+    nq = nl / ntry;
+    nr = nl - ntry * nq;
+    if (nr != 0) {
+	goto L101;
+    } else {
+	goto L105;
+    }
+L105:
+    ++nf;
+    ifac[nf + 2] = ntry;
+    nl = nq;
+    if (ntry != 2) {
+	goto L107;
+    }
+    if (nf == 1) {
+	goto L107;
+    }
+    i__1 = nf;
+    for (i__ = 2; i__ <= i__1; ++i__) {
+	ib = nf - i__ + 2;
+	ifac[ib + 2] = ifac[ib + 1];
+/* L106: */
+    }
+    ifac[3] = 2;
+L107:
+    if (nl != 1) {
+	goto L104;
+    }
+    ifac[1] = *n;
+    ifac[2] = nf;
+    argh = tpi / (r_8) (*n);
+    is = 0;
+    nfm1 = nf - 1;
+    l1 = 1;
+    if (nfm1 == 0) {
+	return 0;
+    }
+    i__1 = nfm1;
+    for (k1 = 1; k1 <= i__1; ++k1) {
+	ip = ifac[k1 + 2];
+	l2 = l1 * ip;
+	ido = *n / l2;
+	ipm = ip - 1;
+	arg1 = (r_8) l1 * argh;
+	ch1 = 1.f;
+	sh1 = 0.f;
+	dch1 = cos(arg1);
+	dsh1 = sin(arg1);
+	i__2 = ipm;
+	for (j = 1; j <= i__2; ++j) {
+	    ch1h = dch1 * ch1 - dsh1 * sh1;
+	    sh1 = dch1 * sh1 + dsh1 * ch1;
+	    ch1 = ch1h;
+	    i__ = is + 2;
+	    wa[i__ - 1] = ch1;
+	    wa[i__] = sh1;
+	    if (ido < 5) {
+		goto L109;
+	    }
+	    i__3 = ido;
+	    for (ii = 5; ii <= i__3; ii += 2) {
+		i__ += 2;
+		wa[i__ - 1] = ch1 * wa[i__ - 3] - sh1 * wa[i__ - 2];
+		wa[i__] = ch1 * wa[i__ - 2] + sh1 * wa[i__ - 3];
+/* L108: */
+	    }
+L109:
+	    is += ido;
+/* L110: */
+	}
+	l1 = l2;
+/* L111: */
+    }
+    return 0;
+} /* dezfft1_ */
+
+/*  ------ File dezfftb.f ------ */
+/* Subroutine */ int dezfftb_(int_4 *n, r_8 *r__, r_8 *azero, r_8 *a, 
+	r_8 *b, r_8 *wsave)
+{
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Local variables */
+    static int_4 i__;
+    extern /* Subroutine */ int dfftb_(int_4 *, r_8 *, r_8 *);
+    static int_4 ns2;
+
+    /* Parameter adjustments */
+    --wsave;
+    --b;
+    --a;
+    --r__;
+
+    /* Function Body */
+    if ((i__1 = *n - 2) < 0) {
+	goto L101;
+    } else if (i__1 == 0) {
+	goto L102;
+    } else {
+	goto L103;
+    }
+L101:
+    r__[1] = *azero;
+    return 0;
+L102:
+    r__[1] = *azero + a[1];
+    r__[2] = *azero - a[1];
+    return 0;
+L103:
+    ns2 = (*n - 1) / 2;
+    i__1 = ns2;
+    for (i__ = 1; i__ <= i__1; ++i__) {
+	r__[i__ * 2] = a[i__] * .5f;
+	r__[(i__ << 1) + 1] = b[i__] * -.5f;
+/* L104: */
+    }
+    r__[1] = *azero;
+    if (*n % 2 == 0) {
+	r__[*n] = a[ns2 + 1];
+    }
+    dfftb_(n, &r__[1], &wsave[*n + 1]);
+    return 0;
+} /* dezfftb_ */
+
+/*  ------ File dezfftf.f ------ */
+/* Subroutine */ int dezfftf_(int_4 *n, r_8 *r__, r_8 *azero, r_8 *a, 
+	r_8 *b, r_8 *wsave)
+{
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Local variables */
+    static int_4 i__;
+    extern /* Subroutine */ int dfftf_(int_4 *, r_8 *, r_8 *);
+    static r_8 cf;
+    static int_4 ns2;
+    static r_8 cfm;
+    static int_4 ns2m;
+
+
+/*                       VERSION 3  JUNE 1979 */
+
+    /* Parameter adjustments */
+    --wsave;
+    --b;
+    --a;
+    --r__;
+
+    /* Function Body */
+    if ((i__1 = *n - 2) < 0) {
+	goto L101;
+    } else if (i__1 == 0) {
+	goto L102;
+    } else {
+	goto L103;
+    }
+L101:
+    *azero = r__[1];
+    return 0;
+L102:
+    *azero = (r__[1] + r__[2]) * .5f;
+    a[1] = (r__[1] - r__[2]) * .5f;
+    return 0;
+L103:
+    i__1 = *n;
+    for (i__ = 1; i__ <= i__1; ++i__) {
+	wsave[i__] = r__[i__];
+/* L104: */
+    }
+    dfftf_(n, &wsave[1], &wsave[*n + 1]);
+    cf = 2.f / (r_8) (*n);
+    cfm = -cf;
+    *azero = cf * .5f * wsave[1];
+    ns2 = (*n + 1) / 2;
+    ns2m = ns2 - 1;
+    i__1 = ns2m;
+    for (i__ = 1; i__ <= i__1; ++i__) {
+	a[i__] = cf * wsave[i__ * 2];
+	b[i__] = cfm * wsave[(i__ << 1) + 1];
+/* L105: */
+    }
+    if (*n % 2 == 1) {
+	return 0;
+    }
+    a[ns2] = cf * .5f * wsave[*n];
+    b[ns2] = 0.f;
+    return 0;
+} /* dezfftf_ */
+
+/*  ------ File dezffti.f ------ */
+/* Subroutine */ int dezffti_(int_4 *n, r_8 *wsave)
+{
+    extern /* Subroutine */ int dezfft1_(int_4 *, r_8 *, int_8 *);
+
+    /* Parameter adjustments */
+    --wsave;
+
+    /* Function Body */
+    if (*n == 1) {
+	return 0;
+    }
+    dezfft1_(n, &wsave[(*n << 1) + 1], (int_8 *)&wsave[*n * 3 + 1]);
+    return 0;
+} /* dezffti_ */
+
+/*  ------ File dpassb.f ------ */
+/* Subroutine */ int dpassb_(int_4 *nac, int_4 *ido, int_4 *ip, int_4 *
+	l1, int_4 *idl1, r_8 *cc, r_8 *c1, r_8 *c2, r_8 *ch, r_8 *ch2, 
+	r_8 *wa)
+{
+    /* System generated locals */
+    int_4 ch_dim1, ch_dim2, ch_offset, cc_dim1, cc_dim2, cc_offset, c1_dim1,
+	     c1_dim2, c1_offset, c2_dim1, c2_offset, ch2_dim1, ch2_offset, 
+	    i__1, i__2, i__3;
+
+    /* Local variables */
+    static int_4 idij, idlj, idot, ipph, i__, j, k, l, jc, lc, ik, nt, idj, 
+	    idl, inc, idp;
+    static r_8 wai, war;
+    static int_4 ipp2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    c1_dim1 = *ido;
+    c1_dim2 = *l1;
+    c1_offset = c1_dim1 * (c1_dim2 + 1) + 1;
+    c1 -= c1_offset;
+    cc_dim1 = *ido;
+    cc_dim2 = *ip;
+    cc_offset = cc_dim1 * (cc_dim2 + 1) + 1;
+    cc -= cc_offset;
+    ch2_dim1 = *idl1;
+    ch2_offset = ch2_dim1 + 1;
+    ch2 -= ch2_offset;
+    c2_dim1 = *idl1;
+    c2_offset = c2_dim1 + 1;
+    c2 -= c2_offset;
+    --wa;
+
+    /* Function Body */
+    idot = *ido / 2;
+    nt = *ip * *idl1;
+    ipp2 = *ip + 2;
+    ipph = (*ip + 1) / 2;
+    idp = *ip * *ido;
+
+    if (*ido < *l1) {
+	goto L106;
+    }
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    i__3 = *ido;
+	    for (i__ = 1; i__ <= i__3; ++i__) {
+		ch[i__ + (k + j * ch_dim2) * ch_dim1] = cc[i__ + (j + k * 
+			cc_dim2) * cc_dim1] + cc[i__ + (jc + k * cc_dim2) * 
+			cc_dim1];
+		ch[i__ + (k + jc * ch_dim2) * ch_dim1] = cc[i__ + (j + k * 
+			cc_dim2) * cc_dim1] - cc[i__ + (jc + k * cc_dim2) * 
+			cc_dim1];
+/* L101: */
+	    }
+/* L102: */
+	}
+/* L103: */
+    }
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 1; i__ <= i__2; ++i__) {
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = cc[i__ + (k * cc_dim2 + 1) * 
+		    cc_dim1];
+/* L104: */
+	}
+/* L105: */
+    }
+    goto L112;
+L106:
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	i__2 = *ido;
+	for (i__ = 1; i__ <= i__2; ++i__) {
+	    i__3 = *l1;
+	    for (k = 1; k <= i__3; ++k) {
+		ch[i__ + (k + j * ch_dim2) * ch_dim1] = cc[i__ + (j + k * 
+			cc_dim2) * cc_dim1] + cc[i__ + (jc + k * cc_dim2) * 
+			cc_dim1];
+		ch[i__ + (k + jc * ch_dim2) * ch_dim1] = cc[i__ + (j + k * 
+			cc_dim2) * cc_dim1] - cc[i__ + (jc + k * cc_dim2) * 
+			cc_dim1];
+/* L107: */
+	    }
+/* L108: */
+	}
+/* L109: */
+    }
+    i__1 = *ido;
+    for (i__ = 1; i__ <= i__1; ++i__) {
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = cc[i__ + (k * cc_dim2 + 1) * 
+		    cc_dim1];
+/* L110: */
+	}
+/* L111: */
+    }
+L112:
+    idl = 2 - *ido;
+    inc = 0;
+    i__1 = ipph;
+    for (l = 2; l <= i__1; ++l) {
+	lc = ipp2 - l;
+	idl += *ido;
+	i__2 = *idl1;
+	for (ik = 1; ik <= i__2; ++ik) {
+	    c2[ik + l * c2_dim1] = ch2[ik + ch2_dim1] + wa[idl - 1] * ch2[ik 
+		    + (ch2_dim1 << 1)];
+	    c2[ik + lc * c2_dim1] = wa[idl] * ch2[ik + *ip * ch2_dim1];
+/* L113: */
+	}
+	idlj = idl;
+	inc += *ido;
+	i__2 = ipph;
+	for (j = 3; j <= i__2; ++j) {
+	    jc = ipp2 - j;
+	    idlj += inc;
+	    if (idlj > idp) {
+		idlj -= idp;
+	    }
+	    war = wa[idlj - 1];
+	    wai = wa[idlj];
+	    i__3 = *idl1;
+	    for (ik = 1; ik <= i__3; ++ik) {
+		c2[ik + l * c2_dim1] += war * ch2[ik + j * ch2_dim1];
+		c2[ik + lc * c2_dim1] += wai * ch2[ik + jc * ch2_dim1];
+/* L114: */
+	    }
+/* L115: */
+	}
+/* L116: */
+    }
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	i__2 = *idl1;
+	for (ik = 1; ik <= i__2; ++ik) {
+	    ch2[ik + ch2_dim1] += ch2[ik + j * ch2_dim1];
+/* L117: */
+	}
+/* L118: */
+    }
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	i__2 = *idl1;
+	for (ik = 2; ik <= i__2; ik += 2) {
+	    ch2[ik - 1 + j * ch2_dim1] = c2[ik - 1 + j * c2_dim1] - c2[ik + 
+		    jc * c2_dim1];
+	    ch2[ik - 1 + jc * ch2_dim1] = c2[ik - 1 + j * c2_dim1] + c2[ik + 
+		    jc * c2_dim1];
+	    ch2[ik + j * ch2_dim1] = c2[ik + j * c2_dim1] + c2[ik - 1 + jc * 
+		    c2_dim1];
+	    ch2[ik + jc * ch2_dim1] = c2[ik + j * c2_dim1] - c2[ik - 1 + jc * 
+		    c2_dim1];
+/* L119: */
+	}
+/* L120: */
+    }
+    *nac = 1;
+    if (*ido == 2) {
+	return 0;
+    }
+    *nac = 0;
+    i__1 = *idl1;
+    for (ik = 1; ik <= i__1; ++ik) {
+	c2[ik + c2_dim1] = ch2[ik + ch2_dim1];
+/* L121: */
+    }
+    i__1 = *ip;
+    for (j = 2; j <= i__1; ++j) {
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    c1[(k + j * c1_dim2) * c1_dim1 + 1] = ch[(k + j * ch_dim2) * 
+		    ch_dim1 + 1];
+	    c1[(k + j * c1_dim2) * c1_dim1 + 2] = ch[(k + j * ch_dim2) * 
+		    ch_dim1 + 2];
+/* L122: */
+	}
+/* L123: */
+    }
+    if (idot > *l1) {
+	goto L127;
+    }
+    idij = 0;
+    i__1 = *ip;
+    for (j = 2; j <= i__1; ++j) {
+	idij += 2;
+	i__2 = *ido;
+	for (i__ = 4; i__ <= i__2; i__ += 2) {
+	    idij += 2;
+	    i__3 = *l1;
+	    for (k = 1; k <= i__3; ++k) {
+		c1[i__ - 1 + (k + j * c1_dim2) * c1_dim1] = wa[idij - 1] * ch[
+			i__ - 1 + (k + j * ch_dim2) * ch_dim1] - wa[idij] * 
+			ch[i__ + (k + j * ch_dim2) * ch_dim1];
+		c1[i__ + (k + j * c1_dim2) * c1_dim1] = wa[idij - 1] * ch[i__ 
+			+ (k + j * ch_dim2) * ch_dim1] + wa[idij] * ch[i__ - 
+			1 + (k + j * ch_dim2) * ch_dim1];
+/* L124: */
+	    }
+/* L125: */
+	}
+/* L126: */
+    }
+    return 0;
+L127:
+    idj = 2 - *ido;
+    i__1 = *ip;
+    for (j = 2; j <= i__1; ++j) {
+	idj += *ido;
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    idij = idj;
+	    i__3 = *ido;
+	    for (i__ = 4; i__ <= i__3; i__ += 2) {
+		idij += 2;
+		c1[i__ - 1 + (k + j * c1_dim2) * c1_dim1] = wa[idij - 1] * ch[
+			i__ - 1 + (k + j * ch_dim2) * ch_dim1] - wa[idij] * 
+			ch[i__ + (k + j * ch_dim2) * ch_dim1];
+		c1[i__ + (k + j * c1_dim2) * c1_dim1] = wa[idij - 1] * ch[i__ 
+			+ (k + j * ch_dim2) * ch_dim1] + wa[idij] * ch[i__ - 
+			1 + (k + j * ch_dim2) * ch_dim1];
+/* L128: */
+	    }
+/* L129: */
+	}
+/* L130: */
+    }
+    return 0;
+} /* dpassb_ */
+
+/*  ------ File dpassb2.f ------ */
+/* Subroutine */ int dpassb2_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, 
+	r_8 *wa1)
+{
+    /* System generated locals */
+    int_4 cc_dim1, cc_offset, ch_dim1, ch_dim2, ch_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k;
+    static r_8 ti2, tr2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_offset = cc_dim1 * 3 + 1;
+    cc -= cc_offset;
+    --wa1;
+
+    /* Function Body */
+    if (*ido > 2) {
+	goto L102;
+    }
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	ch[(k + ch_dim2) * ch_dim1 + 1] = cc[((k << 1) + 1) * cc_dim1 + 1] + 
+		cc[((k << 1) + 2) * cc_dim1 + 1];
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 1] = cc[((k << 1) + 1) * cc_dim1 
+		+ 1] - cc[((k << 1) + 2) * cc_dim1 + 1];
+	ch[(k + ch_dim2) * ch_dim1 + 2] = cc[((k << 1) + 1) * cc_dim1 + 2] + 
+		cc[((k << 1) + 2) * cc_dim1 + 2];
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 2] = cc[((k << 1) + 1) * cc_dim1 
+		+ 2] - cc[((k << 1) + 2) * cc_dim1 + 2];
+/* L101: */
+    }
+    return 0;
+L102:
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 2; i__ <= i__2; i__ += 2) {
+	    ch[i__ - 1 + (k + ch_dim2) * ch_dim1] = cc[i__ - 1 + ((k << 1) + 
+		    1) * cc_dim1] + cc[i__ - 1 + ((k << 1) + 2) * cc_dim1];
+	    tr2 = cc[i__ - 1 + ((k << 1) + 1) * cc_dim1] - cc[i__ - 1 + ((k <<
+		     1) + 2) * cc_dim1];
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = cc[i__ + ((k << 1) + 1) * 
+		    cc_dim1] + cc[i__ + ((k << 1) + 2) * cc_dim1];
+	    ti2 = cc[i__ + ((k << 1) + 1) * cc_dim1] - cc[i__ + ((k << 1) + 2)
+		     * cc_dim1];
+	    ch[i__ + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * ti2 + 
+		    wa1[i__] * tr2;
+	    ch[i__ - 1 + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * tr2 
+		    - wa1[i__] * ti2;
+/* L103: */
+	}
+/* L104: */
+    }
+    return 0;
+} /* dpassb2_ */
+
+/*  ------ File dpassb3.f ------ */
+/* Subroutine */ int dpassb3_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, 
+	r_8 *wa1, r_8 *wa2)
+{
+    /* Initialized data */
+
+    static r_8 taur = -.5f;
+    static r_8 taui = .866025403784439f;
+
+    /* System generated locals */
+    int_4 cc_dim1, cc_offset, ch_dim1, ch_dim2, ch_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k;
+    static r_8 ci2, ci3, di2, di3, cr2, cr3, dr2, dr3, ti2, tr2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_offset = (cc_dim1 << 2) + 1;
+    cc -= cc_offset;
+    --wa1;
+    --wa2;
+
+    /* Function Body */
+    if (*ido != 2) {
+	goto L102;
+    }
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	tr2 = cc[(k * 3 + 2) * cc_dim1 + 1] + cc[(k * 3 + 3) * cc_dim1 + 1];
+	cr2 = cc[(k * 3 + 1) * cc_dim1 + 1] + taur * tr2;
+	ch[(k + ch_dim2) * ch_dim1 + 1] = cc[(k * 3 + 1) * cc_dim1 + 1] + tr2;
+	ti2 = cc[(k * 3 + 2) * cc_dim1 + 2] + cc[(k * 3 + 3) * cc_dim1 + 2];
+	ci2 = cc[(k * 3 + 1) * cc_dim1 + 2] + taur * ti2;
+	ch[(k + ch_dim2) * ch_dim1 + 2] = cc[(k * 3 + 1) * cc_dim1 + 2] + ti2;
+	cr3 = taui * (cc[(k * 3 + 2) * cc_dim1 + 1] - cc[(k * 3 + 3) * 
+		cc_dim1 + 1]);
+	ci3 = taui * (cc[(k * 3 + 2) * cc_dim1 + 2] - cc[(k * 3 + 3) * 
+		cc_dim1 + 2]);
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 1] = cr2 - ci3;
+	ch[(k + ch_dim2 * 3) * ch_dim1 + 1] = cr2 + ci3;
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 2] = ci2 + cr3;
+	ch[(k + ch_dim2 * 3) * ch_dim1 + 2] = ci2 - cr3;
+/* L101: */
+    }
+    return 0;
+L102:
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 2; i__ <= i__2; i__ += 2) {
+	    tr2 = cc[i__ - 1 + (k * 3 + 2) * cc_dim1] + cc[i__ - 1 + (k * 3 + 
+		    3) * cc_dim1];
+	    cr2 = cc[i__ - 1 + (k * 3 + 1) * cc_dim1] + taur * tr2;
+	    ch[i__ - 1 + (k + ch_dim2) * ch_dim1] = cc[i__ - 1 + (k * 3 + 1) *
+		     cc_dim1] + tr2;
+	    ti2 = cc[i__ + (k * 3 + 2) * cc_dim1] + cc[i__ + (k * 3 + 3) * 
+		    cc_dim1];
+	    ci2 = cc[i__ + (k * 3 + 1) * cc_dim1] + taur * ti2;
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = cc[i__ + (k * 3 + 1) * 
+		    cc_dim1] + ti2;
+	    cr3 = taui * (cc[i__ - 1 + (k * 3 + 2) * cc_dim1] - cc[i__ - 1 + (
+		    k * 3 + 3) * cc_dim1]);
+	    ci3 = taui * (cc[i__ + (k * 3 + 2) * cc_dim1] - cc[i__ + (k * 3 + 
+		    3) * cc_dim1]);
+	    dr2 = cr2 - ci3;
+	    dr3 = cr2 + ci3;
+	    di2 = ci2 + cr3;
+	    di3 = ci2 - cr3;
+	    ch[i__ + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * di2 + 
+		    wa1[i__] * dr2;
+	    ch[i__ - 1 + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * dr2 
+		    - wa1[i__] * di2;
+	    ch[i__ + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 1] * di3 + wa2[
+		    i__] * dr3;
+	    ch[i__ - 1 + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 1] * dr3 - 
+		    wa2[i__] * di3;
+/* L103: */
+	}
+/* L104: */
+    }
+    return 0;
+} /* dpassb3_ */
+
+/*  ------ File dpassb4.f ------ */
+/* Subroutine */ int dpassb4_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, 
+	r_8 *wa1, r_8 *wa2, r_8 *wa3)
+{
+    /* System generated locals */
+    int_4 cc_dim1, cc_offset, ch_dim1, ch_dim2, ch_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k;
+    static r_8 ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, 
+	    tr3, tr4;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_offset = cc_dim1 * 5 + 1;
+    cc -= cc_offset;
+    --wa1;
+    --wa2;
+    --wa3;
+
+    /* Function Body */
+    if (*ido != 2) {
+	goto L102;
+    }
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	ti1 = cc[((k << 2) + 1) * cc_dim1 + 2] - cc[((k << 2) + 3) * cc_dim1 
+		+ 2];
+	ti2 = cc[((k << 2) + 1) * cc_dim1 + 2] + cc[((k << 2) + 3) * cc_dim1 
+		+ 2];
+	tr4 = cc[((k << 2) + 4) * cc_dim1 + 2] - cc[((k << 2) + 2) * cc_dim1 
+		+ 2];
+	ti3 = cc[((k << 2) + 2) * cc_dim1 + 2] + cc[((k << 2) + 4) * cc_dim1 
+		+ 2];
+	tr1 = cc[((k << 2) + 1) * cc_dim1 + 1] - cc[((k << 2) + 3) * cc_dim1 
+		+ 1];
+	tr2 = cc[((k << 2) + 1) * cc_dim1 + 1] + cc[((k << 2) + 3) * cc_dim1 
+		+ 1];
+	ti4 = cc[((k << 2) + 2) * cc_dim1 + 1] - cc[((k << 2) + 4) * cc_dim1 
+		+ 1];
+	tr3 = cc[((k << 2) + 2) * cc_dim1 + 1] + cc[((k << 2) + 4) * cc_dim1 
+		+ 1];
+	ch[(k + ch_dim2) * ch_dim1 + 1] = tr2 + tr3;
+	ch[(k + ch_dim2 * 3) * ch_dim1 + 1] = tr2 - tr3;
+	ch[(k + ch_dim2) * ch_dim1 + 2] = ti2 + ti3;
+	ch[(k + ch_dim2 * 3) * ch_dim1 + 2] = ti2 - ti3;
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 1] = tr1 + tr4;
+	ch[(k + (ch_dim2 << 2)) * ch_dim1 + 1] = tr1 - tr4;
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 2] = ti1 + ti4;
+	ch[(k + (ch_dim2 << 2)) * ch_dim1 + 2] = ti1 - ti4;
+/* L101: */
+    }
+    return 0;
+L102:
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 2; i__ <= i__2; i__ += 2) {
+	    ti1 = cc[i__ + ((k << 2) + 1) * cc_dim1] - cc[i__ + ((k << 2) + 3)
+		     * cc_dim1];
+	    ti2 = cc[i__ + ((k << 2) + 1) * cc_dim1] + cc[i__ + ((k << 2) + 3)
+		     * cc_dim1];
+	    ti3 = cc[i__ + ((k << 2) + 2) * cc_dim1] + cc[i__ + ((k << 2) + 4)
+		     * cc_dim1];
+	    tr4 = cc[i__ + ((k << 2) + 4) * cc_dim1] - cc[i__ + ((k << 2) + 2)
+		     * cc_dim1];
+	    tr1 = cc[i__ - 1 + ((k << 2) + 1) * cc_dim1] - cc[i__ - 1 + ((k <<
+		     2) + 3) * cc_dim1];
+	    tr2 = cc[i__ - 1 + ((k << 2) + 1) * cc_dim1] + cc[i__ - 1 + ((k <<
+		     2) + 3) * cc_dim1];
+	    ti4 = cc[i__ - 1 + ((k << 2) + 2) * cc_dim1] - cc[i__ - 1 + ((k <<
+		     2) + 4) * cc_dim1];
+	    tr3 = cc[i__ - 1 + ((k << 2) + 2) * cc_dim1] + cc[i__ - 1 + ((k <<
+		     2) + 4) * cc_dim1];
+	    ch[i__ - 1 + (k + ch_dim2) * ch_dim1] = tr2 + tr3;
+	    cr3 = tr2 - tr3;
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = ti2 + ti3;
+	    ci3 = ti2 - ti3;
+	    cr2 = tr1 + tr4;
+	    cr4 = tr1 - tr4;
+	    ci2 = ti1 + ti4;
+	    ci4 = ti1 - ti4;
+	    ch[i__ - 1 + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * cr2 
+		    - wa1[i__] * ci2;
+	    ch[i__ + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * ci2 + 
+		    wa1[i__] * cr2;
+	    ch[i__ - 1 + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 1] * cr3 - 
+		    wa2[i__] * ci3;
+	    ch[i__ + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 1] * ci3 + wa2[
+		    i__] * cr3;
+	    ch[i__ - 1 + (k + (ch_dim2 << 2)) * ch_dim1] = wa3[i__ - 1] * cr4 
+		    - wa3[i__] * ci4;
+	    ch[i__ + (k + (ch_dim2 << 2)) * ch_dim1] = wa3[i__ - 1] * ci4 + 
+		    wa3[i__] * cr4;
+/* L103: */
+	}
+/* L104: */
+    }
+    return 0;
+} /* dpassb4_ */
+
+/*  ------ File dpassb5.f ------ */
+/* Subroutine */ int dpassb5_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, 
+	r_8 *wa1, r_8 *wa2, r_8 *wa3, r_8 *wa4)
+{
+    /* Initialized data */
+
+    static r_8 tr11 = .309016994374947f;
+    static r_8 ti11 = .951056516295154f;
+    static r_8 tr12 = -.809016994374947f;
+    static r_8 ti12 = .587785252292473f;
+
+    /* System generated locals */
+    int_4 cc_dim1, cc_offset, ch_dim1, ch_dim2, ch_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k;
+    static r_8 ci2, ci3, ci4, ci5, di3, di4, di5, di2, cr2, cr3, cr5, cr4, 
+	    ti2, ti3, ti4, ti5, dr3, dr4, dr5, dr2, tr2, tr3, tr4, tr5;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_offset = cc_dim1 * 6 + 1;
+    cc -= cc_offset;
+    --wa1;
+    --wa2;
+    --wa3;
+    --wa4;
+
+    /* Function Body */
+    if (*ido != 2) {
+	goto L102;
+    }
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	ti5 = cc[(k * 5 + 2) * cc_dim1 + 2] - cc[(k * 5 + 5) * cc_dim1 + 2];
+	ti2 = cc[(k * 5 + 2) * cc_dim1 + 2] + cc[(k * 5 + 5) * cc_dim1 + 2];
+	ti4 = cc[(k * 5 + 3) * cc_dim1 + 2] - cc[(k * 5 + 4) * cc_dim1 + 2];
+	ti3 = cc[(k * 5 + 3) * cc_dim1 + 2] + cc[(k * 5 + 4) * cc_dim1 + 2];
+	tr5 = cc[(k * 5 + 2) * cc_dim1 + 1] - cc[(k * 5 + 5) * cc_dim1 + 1];
+	tr2 = cc[(k * 5 + 2) * cc_dim1 + 1] + cc[(k * 5 + 5) * cc_dim1 + 1];
+	tr4 = cc[(k * 5 + 3) * cc_dim1 + 1] - cc[(k * 5 + 4) * cc_dim1 + 1];
+	tr3 = cc[(k * 5 + 3) * cc_dim1 + 1] + cc[(k * 5 + 4) * cc_dim1 + 1];
+	ch[(k + ch_dim2) * ch_dim1 + 1] = cc[(k * 5 + 1) * cc_dim1 + 1] + tr2 
+		+ tr3;
+	ch[(k + ch_dim2) * ch_dim1 + 2] = cc[(k * 5 + 1) * cc_dim1 + 2] + ti2 
+		+ ti3;
+	cr2 = cc[(k * 5 + 1) * cc_dim1 + 1] + tr11 * tr2 + tr12 * tr3;
+	ci2 = cc[(k * 5 + 1) * cc_dim1 + 2] + tr11 * ti2 + tr12 * ti3;
+	cr3 = cc[(k * 5 + 1) * cc_dim1 + 1] + tr12 * tr2 + tr11 * tr3;
+	ci3 = cc[(k * 5 + 1) * cc_dim1 + 2] + tr12 * ti2 + tr11 * ti3;
+	cr5 = ti11 * tr5 + ti12 * tr4;
+	ci5 = ti11 * ti5 + ti12 * ti4;
+	cr4 = ti12 * tr5 - ti11 * tr4;
+	ci4 = ti12 * ti5 - ti11 * ti4;
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 1] = cr2 - ci5;
+	ch[(k + ch_dim2 * 5) * ch_dim1 + 1] = cr2 + ci5;
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 2] = ci2 + cr5;
+	ch[(k + ch_dim2 * 3) * ch_dim1 + 2] = ci3 + cr4;
+	ch[(k + ch_dim2 * 3) * ch_dim1 + 1] = cr3 - ci4;
+	ch[(k + (ch_dim2 << 2)) * ch_dim1 + 1] = cr3 + ci4;
+	ch[(k + (ch_dim2 << 2)) * ch_dim1 + 2] = ci3 - cr4;
+	ch[(k + ch_dim2 * 5) * ch_dim1 + 2] = ci2 - cr5;
+/* L101: */
+    }
+    return 0;
+L102:
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 2; i__ <= i__2; i__ += 2) {
+	    ti5 = cc[i__ + (k * 5 + 2) * cc_dim1] - cc[i__ + (k * 5 + 5) * 
+		    cc_dim1];
+	    ti2 = cc[i__ + (k * 5 + 2) * cc_dim1] + cc[i__ + (k * 5 + 5) * 
+		    cc_dim1];
+	    ti4 = cc[i__ + (k * 5 + 3) * cc_dim1] - cc[i__ + (k * 5 + 4) * 
+		    cc_dim1];
+	    ti3 = cc[i__ + (k * 5 + 3) * cc_dim1] + cc[i__ + (k * 5 + 4) * 
+		    cc_dim1];
+	    tr5 = cc[i__ - 1 + (k * 5 + 2) * cc_dim1] - cc[i__ - 1 + (k * 5 + 
+		    5) * cc_dim1];
+	    tr2 = cc[i__ - 1 + (k * 5 + 2) * cc_dim1] + cc[i__ - 1 + (k * 5 + 
+		    5) * cc_dim1];
+	    tr4 = cc[i__ - 1 + (k * 5 + 3) * cc_dim1] - cc[i__ - 1 + (k * 5 + 
+		    4) * cc_dim1];
+	    tr3 = cc[i__ - 1 + (k * 5 + 3) * cc_dim1] + cc[i__ - 1 + (k * 5 + 
+		    4) * cc_dim1];
+	    ch[i__ - 1 + (k + ch_dim2) * ch_dim1] = cc[i__ - 1 + (k * 5 + 1) *
+		     cc_dim1] + tr2 + tr3;
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = cc[i__ + (k * 5 + 1) * 
+		    cc_dim1] + ti2 + ti3;
+	    cr2 = cc[i__ - 1 + (k * 5 + 1) * cc_dim1] + tr11 * tr2 + tr12 * 
+		    tr3;
+	    ci2 = cc[i__ + (k * 5 + 1) * cc_dim1] + tr11 * ti2 + tr12 * ti3;
+	    cr3 = cc[i__ - 1 + (k * 5 + 1) * cc_dim1] + tr12 * tr2 + tr11 * 
+		    tr3;
+	    ci3 = cc[i__ + (k * 5 + 1) * cc_dim1] + tr12 * ti2 + tr11 * ti3;
+	    cr5 = ti11 * tr5 + ti12 * tr4;
+	    ci5 = ti11 * ti5 + ti12 * ti4;
+	    cr4 = ti12 * tr5 - ti11 * tr4;
+	    ci4 = ti12 * ti5 - ti11 * ti4;
+	    dr3 = cr3 - ci4;
+	    dr4 = cr3 + ci4;
+	    di3 = ci3 + cr4;
+	    di4 = ci3 - cr4;
+	    dr5 = cr2 + ci5;
+	    dr2 = cr2 - ci5;
+	    di5 = ci2 - cr5;
+	    di2 = ci2 + cr5;
+	    ch[i__ - 1 + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * dr2 
+		    - wa1[i__] * di2;
+	    ch[i__ + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * di2 + 
+		    wa1[i__] * dr2;
+	    ch[i__ - 1 + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 1] * dr3 - 
+		    wa2[i__] * di3;
+	    ch[i__ + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 1] * di3 + wa2[
+		    i__] * dr3;
+	    ch[i__ - 1 + (k + (ch_dim2 << 2)) * ch_dim1] = wa3[i__ - 1] * dr4 
+		    - wa3[i__] * di4;
+	    ch[i__ + (k + (ch_dim2 << 2)) * ch_dim1] = wa3[i__ - 1] * di4 + 
+		    wa3[i__] * dr4;
+	    ch[i__ - 1 + (k + ch_dim2 * 5) * ch_dim1] = wa4[i__ - 1] * dr5 - 
+		    wa4[i__] * di5;
+	    ch[i__ + (k + ch_dim2 * 5) * ch_dim1] = wa4[i__ - 1] * di5 + wa4[
+		    i__] * dr5;
+/* L103: */
+	}
+/* L104: */
+    }
+    return 0;
+} /* dpassb5_ */
+
+/*  ------ File dpassf.f ------ */
+/* Subroutine */ int dpassf_(int_4 *nac, int_4 *ido, int_4 *ip, int_4 *
+	l1, int_4 *idl1, r_8 *cc, r_8 *c1, r_8 *c2, r_8 *ch, r_8 *ch2, 
+	r_8 *wa)
+{
+    /* System generated locals */
+    int_4 ch_dim1, ch_dim2, ch_offset, cc_dim1, cc_dim2, cc_offset, c1_dim1,
+	     c1_dim2, c1_offset, c2_dim1, c2_offset, ch2_dim1, ch2_offset, 
+	    i__1, i__2, i__3;
+
+    /* Local variables */
+    static int_4 idij, idlj, idot, ipph, i__, j, k, l, jc, lc, ik, nt, idj, 
+	    idl, inc, idp;
+    static r_8 wai, war;
+    static int_4 ipp2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    c1_dim1 = *ido;
+    c1_dim2 = *l1;
+    c1_offset = c1_dim1 * (c1_dim2 + 1) + 1;
+    c1 -= c1_offset;
+    cc_dim1 = *ido;
+    cc_dim2 = *ip;
+    cc_offset = cc_dim1 * (cc_dim2 + 1) + 1;
+    cc -= cc_offset;
+    ch2_dim1 = *idl1;
+    ch2_offset = ch2_dim1 + 1;
+    ch2 -= ch2_offset;
+    c2_dim1 = *idl1;
+    c2_offset = c2_dim1 + 1;
+    c2 -= c2_offset;
+    --wa;
+
+    /* Function Body */
+    idot = *ido / 2;
+    nt = *ip * *idl1;
+    ipp2 = *ip + 2;
+    ipph = (*ip + 1) / 2;
+    idp = *ip * *ido;
+
+    if (*ido < *l1) {
+	goto L106;
+    }
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    i__3 = *ido;
+	    for (i__ = 1; i__ <= i__3; ++i__) {
+		ch[i__ + (k + j * ch_dim2) * ch_dim1] = cc[i__ + (j + k * 
+			cc_dim2) * cc_dim1] + cc[i__ + (jc + k * cc_dim2) * 
+			cc_dim1];
+		ch[i__ + (k + jc * ch_dim2) * ch_dim1] = cc[i__ + (j + k * 
+			cc_dim2) * cc_dim1] - cc[i__ + (jc + k * cc_dim2) * 
+			cc_dim1];
+/* L101: */
+	    }
+/* L102: */
+	}
+/* L103: */
+    }
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 1; i__ <= i__2; ++i__) {
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = cc[i__ + (k * cc_dim2 + 1) * 
+		    cc_dim1];
+/* L104: */
+	}
+/* L105: */
+    }
+    goto L112;
+L106:
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	i__2 = *ido;
+	for (i__ = 1; i__ <= i__2; ++i__) {
+	    i__3 = *l1;
+	    for (k = 1; k <= i__3; ++k) {
+		ch[i__ + (k + j * ch_dim2) * ch_dim1] = cc[i__ + (j + k * 
+			cc_dim2) * cc_dim1] + cc[i__ + (jc + k * cc_dim2) * 
+			cc_dim1];
+		ch[i__ + (k + jc * ch_dim2) * ch_dim1] = cc[i__ + (j + k * 
+			cc_dim2) * cc_dim1] - cc[i__ + (jc + k * cc_dim2) * 
+			cc_dim1];
+/* L107: */
+	    }
+/* L108: */
+	}
+/* L109: */
+    }
+    i__1 = *ido;
+    for (i__ = 1; i__ <= i__1; ++i__) {
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = cc[i__ + (k * cc_dim2 + 1) * 
+		    cc_dim1];
+/* L110: */
+	}
+/* L111: */
+    }
+L112:
+    idl = 2 - *ido;
+    inc = 0;
+    i__1 = ipph;
+    for (l = 2; l <= i__1; ++l) {
+	lc = ipp2 - l;
+	idl += *ido;
+	i__2 = *idl1;
+	for (ik = 1; ik <= i__2; ++ik) {
+	    c2[ik + l * c2_dim1] = ch2[ik + ch2_dim1] + wa[idl - 1] * ch2[ik 
+		    + (ch2_dim1 << 1)];
+	    c2[ik + lc * c2_dim1] = -wa[idl] * ch2[ik + *ip * ch2_dim1];
+/* L113: */
+	}
+	idlj = idl;
+	inc += *ido;
+	i__2 = ipph;
+	for (j = 3; j <= i__2; ++j) {
+	    jc = ipp2 - j;
+	    idlj += inc;
+	    if (idlj > idp) {
+		idlj -= idp;
+	    }
+	    war = wa[idlj - 1];
+	    wai = wa[idlj];
+	    i__3 = *idl1;
+	    for (ik = 1; ik <= i__3; ++ik) {
+		c2[ik + l * c2_dim1] += war * ch2[ik + j * ch2_dim1];
+		c2[ik + lc * c2_dim1] -= wai * ch2[ik + jc * ch2_dim1];
+/* L114: */
+	    }
+/* L115: */
+	}
+/* L116: */
+    }
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	i__2 = *idl1;
+	for (ik = 1; ik <= i__2; ++ik) {
+	    ch2[ik + ch2_dim1] += ch2[ik + j * ch2_dim1];
+/* L117: */
+	}
+/* L118: */
+    }
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	i__2 = *idl1;
+	for (ik = 2; ik <= i__2; ik += 2) {
+	    ch2[ik - 1 + j * ch2_dim1] = c2[ik - 1 + j * c2_dim1] - c2[ik + 
+		    jc * c2_dim1];
+	    ch2[ik - 1 + jc * ch2_dim1] = c2[ik - 1 + j * c2_dim1] + c2[ik + 
+		    jc * c2_dim1];
+	    ch2[ik + j * ch2_dim1] = c2[ik + j * c2_dim1] + c2[ik - 1 + jc * 
+		    c2_dim1];
+	    ch2[ik + jc * ch2_dim1] = c2[ik + j * c2_dim1] - c2[ik - 1 + jc * 
+		    c2_dim1];
+/* L119: */
+	}
+/* L120: */
+    }
+    *nac = 1;
+    if (*ido == 2) {
+	return 0;
+    }
+    *nac = 0;
+    i__1 = *idl1;
+    for (ik = 1; ik <= i__1; ++ik) {
+	c2[ik + c2_dim1] = ch2[ik + ch2_dim1];
+/* L121: */
+    }
+    i__1 = *ip;
+    for (j = 2; j <= i__1; ++j) {
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    c1[(k + j * c1_dim2) * c1_dim1 + 1] = ch[(k + j * ch_dim2) * 
+		    ch_dim1 + 1];
+	    c1[(k + j * c1_dim2) * c1_dim1 + 2] = ch[(k + j * ch_dim2) * 
+		    ch_dim1 + 2];
+/* L122: */
+	}
+/* L123: */
+    }
+    if (idot > *l1) {
+	goto L127;
+    }
+    idij = 0;
+    i__1 = *ip;
+    for (j = 2; j <= i__1; ++j) {
+	idij += 2;
+	i__2 = *ido;
+	for (i__ = 4; i__ <= i__2; i__ += 2) {
+	    idij += 2;
+	    i__3 = *l1;
+	    for (k = 1; k <= i__3; ++k) {
+		c1[i__ - 1 + (k + j * c1_dim2) * c1_dim1] = wa[idij - 1] * ch[
+			i__ - 1 + (k + j * ch_dim2) * ch_dim1] + wa[idij] * 
+			ch[i__ + (k + j * ch_dim2) * ch_dim1];
+		c1[i__ + (k + j * c1_dim2) * c1_dim1] = wa[idij - 1] * ch[i__ 
+			+ (k + j * ch_dim2) * ch_dim1] - wa[idij] * ch[i__ - 
+			1 + (k + j * ch_dim2) * ch_dim1];
+/* L124: */
+	    }
+/* L125: */
+	}
+/* L126: */
+    }
+    return 0;
+L127:
+    idj = 2 - *ido;
+    i__1 = *ip;
+    for (j = 2; j <= i__1; ++j) {
+	idj += *ido;
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    idij = idj;
+	    i__3 = *ido;
+	    for (i__ = 4; i__ <= i__3; i__ += 2) {
+		idij += 2;
+		c1[i__ - 1 + (k + j * c1_dim2) * c1_dim1] = wa[idij - 1] * ch[
+			i__ - 1 + (k + j * ch_dim2) * ch_dim1] + wa[idij] * 
+			ch[i__ + (k + j * ch_dim2) * ch_dim1];
+		c1[i__ + (k + j * c1_dim2) * c1_dim1] = wa[idij - 1] * ch[i__ 
+			+ (k + j * ch_dim2) * ch_dim1] - wa[idij] * ch[i__ - 
+			1 + (k + j * ch_dim2) * ch_dim1];
+/* L128: */
+	    }
+/* L129: */
+	}
+/* L130: */
+    }
+    return 0;
+} /* dpassf_ */
+
+/*  ------ File dpassf2.f ------ */
+/* Subroutine */ int dpassf2_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, 
+	r_8 *wa1)
+{
+    /* System generated locals */
+    int_4 cc_dim1, cc_offset, ch_dim1, ch_dim2, ch_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k;
+    static r_8 ti2, tr2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_offset = cc_dim1 * 3 + 1;
+    cc -= cc_offset;
+    --wa1;
+
+    /* Function Body */
+    if (*ido > 2) {
+	goto L102;
+    }
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	ch[(k + ch_dim2) * ch_dim1 + 1] = cc[((k << 1) + 1) * cc_dim1 + 1] + 
+		cc[((k << 1) + 2) * cc_dim1 + 1];
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 1] = cc[((k << 1) + 1) * cc_dim1 
+		+ 1] - cc[((k << 1) + 2) * cc_dim1 + 1];
+	ch[(k + ch_dim2) * ch_dim1 + 2] = cc[((k << 1) + 1) * cc_dim1 + 2] + 
+		cc[((k << 1) + 2) * cc_dim1 + 2];
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 2] = cc[((k << 1) + 1) * cc_dim1 
+		+ 2] - cc[((k << 1) + 2) * cc_dim1 + 2];
+/* L101: */
+    }
+    return 0;
+L102:
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 2; i__ <= i__2; i__ += 2) {
+	    ch[i__ - 1 + (k + ch_dim2) * ch_dim1] = cc[i__ - 1 + ((k << 1) + 
+		    1) * cc_dim1] + cc[i__ - 1 + ((k << 1) + 2) * cc_dim1];
+	    tr2 = cc[i__ - 1 + ((k << 1) + 1) * cc_dim1] - cc[i__ - 1 + ((k <<
+		     1) + 2) * cc_dim1];
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = cc[i__ + ((k << 1) + 1) * 
+		    cc_dim1] + cc[i__ + ((k << 1) + 2) * cc_dim1];
+	    ti2 = cc[i__ + ((k << 1) + 1) * cc_dim1] - cc[i__ + ((k << 1) + 2)
+		     * cc_dim1];
+	    ch[i__ + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * ti2 - 
+		    wa1[i__] * tr2;
+	    ch[i__ - 1 + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * tr2 
+		    + wa1[i__] * ti2;
+/* L103: */
+	}
+/* L104: */
+    }
+    return 0;
+} /* dpassf2_ */
+
+/*  ------ File dpassf3.f ------ */
+/* Subroutine */ int dpassf3_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, 
+	r_8 *wa1, r_8 *wa2)
+{
+    /* Initialized data */
+
+    static r_8 taur = -.5f;
+    static r_8 taui = -.866025403784439f;
+
+    /* System generated locals */
+    int_4 cc_dim1, cc_offset, ch_dim1, ch_dim2, ch_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k;
+    static r_8 ci2, ci3, di2, di3, cr2, cr3, dr2, dr3, ti2, tr2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_offset = (cc_dim1 << 2) + 1;
+    cc -= cc_offset;
+    --wa1;
+    --wa2;
+
+    /* Function Body */
+    if (*ido != 2) {
+	goto L102;
+    }
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	tr2 = cc[(k * 3 + 2) * cc_dim1 + 1] + cc[(k * 3 + 3) * cc_dim1 + 1];
+	cr2 = cc[(k * 3 + 1) * cc_dim1 + 1] + taur * tr2;
+	ch[(k + ch_dim2) * ch_dim1 + 1] = cc[(k * 3 + 1) * cc_dim1 + 1] + tr2;
+	ti2 = cc[(k * 3 + 2) * cc_dim1 + 2] + cc[(k * 3 + 3) * cc_dim1 + 2];
+	ci2 = cc[(k * 3 + 1) * cc_dim1 + 2] + taur * ti2;
+	ch[(k + ch_dim2) * ch_dim1 + 2] = cc[(k * 3 + 1) * cc_dim1 + 2] + ti2;
+	cr3 = taui * (cc[(k * 3 + 2) * cc_dim1 + 1] - cc[(k * 3 + 3) * 
+		cc_dim1 + 1]);
+	ci3 = taui * (cc[(k * 3 + 2) * cc_dim1 + 2] - cc[(k * 3 + 3) * 
+		cc_dim1 + 2]);
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 1] = cr2 - ci3;
+	ch[(k + ch_dim2 * 3) * ch_dim1 + 1] = cr2 + ci3;
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 2] = ci2 + cr3;
+	ch[(k + ch_dim2 * 3) * ch_dim1 + 2] = ci2 - cr3;
+/* L101: */
+    }
+    return 0;
+L102:
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 2; i__ <= i__2; i__ += 2) {
+	    tr2 = cc[i__ - 1 + (k * 3 + 2) * cc_dim1] + cc[i__ - 1 + (k * 3 + 
+		    3) * cc_dim1];
+	    cr2 = cc[i__ - 1 + (k * 3 + 1) * cc_dim1] + taur * tr2;
+	    ch[i__ - 1 + (k + ch_dim2) * ch_dim1] = cc[i__ - 1 + (k * 3 + 1) *
+		     cc_dim1] + tr2;
+	    ti2 = cc[i__ + (k * 3 + 2) * cc_dim1] + cc[i__ + (k * 3 + 3) * 
+		    cc_dim1];
+	    ci2 = cc[i__ + (k * 3 + 1) * cc_dim1] + taur * ti2;
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = cc[i__ + (k * 3 + 1) * 
+		    cc_dim1] + ti2;
+	    cr3 = taui * (cc[i__ - 1 + (k * 3 + 2) * cc_dim1] - cc[i__ - 1 + (
+		    k * 3 + 3) * cc_dim1]);
+	    ci3 = taui * (cc[i__ + (k * 3 + 2) * cc_dim1] - cc[i__ + (k * 3 + 
+		    3) * cc_dim1]);
+	    dr2 = cr2 - ci3;
+	    dr3 = cr2 + ci3;
+	    di2 = ci2 + cr3;
+	    di3 = ci2 - cr3;
+	    ch[i__ + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * di2 - 
+		    wa1[i__] * dr2;
+	    ch[i__ - 1 + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * dr2 
+		    + wa1[i__] * di2;
+	    ch[i__ + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 1] * di3 - wa2[
+		    i__] * dr3;
+	    ch[i__ - 1 + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 1] * dr3 + 
+		    wa2[i__] * di3;
+/* L103: */
+	}
+/* L104: */
+    }
+    return 0;
+} /* dpassf3_ */
+
+/*  ------ File dpassf4.f ------ */
+/* Subroutine */ int dpassf4_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, 
+	r_8 *wa1, r_8 *wa2, r_8 *wa3)
+{
+    /* System generated locals */
+    int_4 cc_dim1, cc_offset, ch_dim1, ch_dim2, ch_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k;
+    static r_8 ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, 
+	    tr3, tr4;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_offset = cc_dim1 * 5 + 1;
+    cc -= cc_offset;
+    --wa1;
+    --wa2;
+    --wa3;
+
+    /* Function Body */
+    if (*ido != 2) {
+	goto L102;
+    }
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	ti1 = cc[((k << 2) + 1) * cc_dim1 + 2] - cc[((k << 2) + 3) * cc_dim1 
+		+ 2];
+	ti2 = cc[((k << 2) + 1) * cc_dim1 + 2] + cc[((k << 2) + 3) * cc_dim1 
+		+ 2];
+	tr4 = cc[((k << 2) + 2) * cc_dim1 + 2] - cc[((k << 2) + 4) * cc_dim1 
+		+ 2];
+	ti3 = cc[((k << 2) + 2) * cc_dim1 + 2] + cc[((k << 2) + 4) * cc_dim1 
+		+ 2];
+	tr1 = cc[((k << 2) + 1) * cc_dim1 + 1] - cc[((k << 2) + 3) * cc_dim1 
+		+ 1];
+	tr2 = cc[((k << 2) + 1) * cc_dim1 + 1] + cc[((k << 2) + 3) * cc_dim1 
+		+ 1];
+	ti4 = cc[((k << 2) + 4) * cc_dim1 + 1] - cc[((k << 2) + 2) * cc_dim1 
+		+ 1];
+	tr3 = cc[((k << 2) + 2) * cc_dim1 + 1] + cc[((k << 2) + 4) * cc_dim1 
+		+ 1];
+	ch[(k + ch_dim2) * ch_dim1 + 1] = tr2 + tr3;
+	ch[(k + ch_dim2 * 3) * ch_dim1 + 1] = tr2 - tr3;
+	ch[(k + ch_dim2) * ch_dim1 + 2] = ti2 + ti3;
+	ch[(k + ch_dim2 * 3) * ch_dim1 + 2] = ti2 - ti3;
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 1] = tr1 + tr4;
+	ch[(k + (ch_dim2 << 2)) * ch_dim1 + 1] = tr1 - tr4;
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 2] = ti1 + ti4;
+	ch[(k + (ch_dim2 << 2)) * ch_dim1 + 2] = ti1 - ti4;
+/* L101: */
+    }
+    return 0;
+L102:
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 2; i__ <= i__2; i__ += 2) {
+	    ti1 = cc[i__ + ((k << 2) + 1) * cc_dim1] - cc[i__ + ((k << 2) + 3)
+		     * cc_dim1];
+	    ti2 = cc[i__ + ((k << 2) + 1) * cc_dim1] + cc[i__ + ((k << 2) + 3)
+		     * cc_dim1];
+	    ti3 = cc[i__ + ((k << 2) + 2) * cc_dim1] + cc[i__ + ((k << 2) + 4)
+		     * cc_dim1];
+	    tr4 = cc[i__ + ((k << 2) + 2) * cc_dim1] - cc[i__ + ((k << 2) + 4)
+		     * cc_dim1];
+	    tr1 = cc[i__ - 1 + ((k << 2) + 1) * cc_dim1] - cc[i__ - 1 + ((k <<
+		     2) + 3) * cc_dim1];
+	    tr2 = cc[i__ - 1 + ((k << 2) + 1) * cc_dim1] + cc[i__ - 1 + ((k <<
+		     2) + 3) * cc_dim1];
+	    ti4 = cc[i__ - 1 + ((k << 2) + 4) * cc_dim1] - cc[i__ - 1 + ((k <<
+		     2) + 2) * cc_dim1];
+	    tr3 = cc[i__ - 1 + ((k << 2) + 2) * cc_dim1] + cc[i__ - 1 + ((k <<
+		     2) + 4) * cc_dim1];
+	    ch[i__ - 1 + (k + ch_dim2) * ch_dim1] = tr2 + tr3;
+	    cr3 = tr2 - tr3;
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = ti2 + ti3;
+	    ci3 = ti2 - ti3;
+	    cr2 = tr1 + tr4;
+	    cr4 = tr1 - tr4;
+	    ci2 = ti1 + ti4;
+	    ci4 = ti1 - ti4;
+	    ch[i__ - 1 + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * cr2 
+		    + wa1[i__] * ci2;
+	    ch[i__ + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * ci2 - 
+		    wa1[i__] * cr2;
+	    ch[i__ - 1 + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 1] * cr3 + 
+		    wa2[i__] * ci3;
+	    ch[i__ + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 1] * ci3 - wa2[
+		    i__] * cr3;
+	    ch[i__ - 1 + (k + (ch_dim2 << 2)) * ch_dim1] = wa3[i__ - 1] * cr4 
+		    + wa3[i__] * ci4;
+	    ch[i__ + (k + (ch_dim2 << 2)) * ch_dim1] = wa3[i__ - 1] * ci4 - 
+		    wa3[i__] * cr4;
+/* L103: */
+	}
+/* L104: */
+    }
+    return 0;
+} /* dpassf4_ */
+
+/*  ------ File dpassf5.f ------ */
+/* Subroutine */ int dpassf5_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, 
+	r_8 *wa1, r_8 *wa2, r_8 *wa3, r_8 *wa4)
+{
+    /* Initialized data */
+
+    static r_8 tr11 = .309016994374947f;
+    static r_8 ti11 = -.951056516295154f;
+    static r_8 tr12 = -.809016994374947f;
+    static r_8 ti12 = -.587785252292473f;
+
+    /* System generated locals */
+    int_4 cc_dim1, cc_offset, ch_dim1, ch_dim2, ch_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k;
+    static r_8 ci2, ci3, ci4, ci5, di3, di4, di5, di2, cr2, cr3, cr5, cr4, 
+	    ti2, ti3, ti4, ti5, dr3, dr4, dr5, dr2, tr2, tr3, tr4, tr5;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_offset = cc_dim1 * 6 + 1;
+    cc -= cc_offset;
+    --wa1;
+    --wa2;
+    --wa3;
+    --wa4;
+
+    /* Function Body */
+    if (*ido != 2) {
+	goto L102;
+    }
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	ti5 = cc[(k * 5 + 2) * cc_dim1 + 2] - cc[(k * 5 + 5) * cc_dim1 + 2];
+	ti2 = cc[(k * 5 + 2) * cc_dim1 + 2] + cc[(k * 5 + 5) * cc_dim1 + 2];
+	ti4 = cc[(k * 5 + 3) * cc_dim1 + 2] - cc[(k * 5 + 4) * cc_dim1 + 2];
+	ti3 = cc[(k * 5 + 3) * cc_dim1 + 2] + cc[(k * 5 + 4) * cc_dim1 + 2];
+	tr5 = cc[(k * 5 + 2) * cc_dim1 + 1] - cc[(k * 5 + 5) * cc_dim1 + 1];
+	tr2 = cc[(k * 5 + 2) * cc_dim1 + 1] + cc[(k * 5 + 5) * cc_dim1 + 1];
+	tr4 = cc[(k * 5 + 3) * cc_dim1 + 1] - cc[(k * 5 + 4) * cc_dim1 + 1];
+	tr3 = cc[(k * 5 + 3) * cc_dim1 + 1] + cc[(k * 5 + 4) * cc_dim1 + 1];
+	ch[(k + ch_dim2) * ch_dim1 + 1] = cc[(k * 5 + 1) * cc_dim1 + 1] + tr2 
+		+ tr3;
+	ch[(k + ch_dim2) * ch_dim1 + 2] = cc[(k * 5 + 1) * cc_dim1 + 2] + ti2 
+		+ ti3;
+	cr2 = cc[(k * 5 + 1) * cc_dim1 + 1] + tr11 * tr2 + tr12 * tr3;
+	ci2 = cc[(k * 5 + 1) * cc_dim1 + 2] + tr11 * ti2 + tr12 * ti3;
+	cr3 = cc[(k * 5 + 1) * cc_dim1 + 1] + tr12 * tr2 + tr11 * tr3;
+	ci3 = cc[(k * 5 + 1) * cc_dim1 + 2] + tr12 * ti2 + tr11 * ti3;
+	cr5 = ti11 * tr5 + ti12 * tr4;
+	ci5 = ti11 * ti5 + ti12 * ti4;
+	cr4 = ti12 * tr5 - ti11 * tr4;
+	ci4 = ti12 * ti5 - ti11 * ti4;
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 1] = cr2 - ci5;
+	ch[(k + ch_dim2 * 5) * ch_dim1 + 1] = cr2 + ci5;
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 2] = ci2 + cr5;
+	ch[(k + ch_dim2 * 3) * ch_dim1 + 2] = ci3 + cr4;
+	ch[(k + ch_dim2 * 3) * ch_dim1 + 1] = cr3 - ci4;
+	ch[(k + (ch_dim2 << 2)) * ch_dim1 + 1] = cr3 + ci4;
+	ch[(k + (ch_dim2 << 2)) * ch_dim1 + 2] = ci3 - cr4;
+	ch[(k + ch_dim2 * 5) * ch_dim1 + 2] = ci2 - cr5;
+/* L101: */
+    }
+    return 0;
+L102:
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 2; i__ <= i__2; i__ += 2) {
+	    ti5 = cc[i__ + (k * 5 + 2) * cc_dim1] - cc[i__ + (k * 5 + 5) * 
+		    cc_dim1];
+	    ti2 = cc[i__ + (k * 5 + 2) * cc_dim1] + cc[i__ + (k * 5 + 5) * 
+		    cc_dim1];
+	    ti4 = cc[i__ + (k * 5 + 3) * cc_dim1] - cc[i__ + (k * 5 + 4) * 
+		    cc_dim1];
+	    ti3 = cc[i__ + (k * 5 + 3) * cc_dim1] + cc[i__ + (k * 5 + 4) * 
+		    cc_dim1];
+	    tr5 = cc[i__ - 1 + (k * 5 + 2) * cc_dim1] - cc[i__ - 1 + (k * 5 + 
+		    5) * cc_dim1];
+	    tr2 = cc[i__ - 1 + (k * 5 + 2) * cc_dim1] + cc[i__ - 1 + (k * 5 + 
+		    5) * cc_dim1];
+	    tr4 = cc[i__ - 1 + (k * 5 + 3) * cc_dim1] - cc[i__ - 1 + (k * 5 + 
+		    4) * cc_dim1];
+	    tr3 = cc[i__ - 1 + (k * 5 + 3) * cc_dim1] + cc[i__ - 1 + (k * 5 + 
+		    4) * cc_dim1];
+	    ch[i__ - 1 + (k + ch_dim2) * ch_dim1] = cc[i__ - 1 + (k * 5 + 1) *
+		     cc_dim1] + tr2 + tr3;
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = cc[i__ + (k * 5 + 1) * 
+		    cc_dim1] + ti2 + ti3;
+	    cr2 = cc[i__ - 1 + (k * 5 + 1) * cc_dim1] + tr11 * tr2 + tr12 * 
+		    tr3;
+	    ci2 = cc[i__ + (k * 5 + 1) * cc_dim1] + tr11 * ti2 + tr12 * ti3;
+	    cr3 = cc[i__ - 1 + (k * 5 + 1) * cc_dim1] + tr12 * tr2 + tr11 * 
+		    tr3;
+	    ci3 = cc[i__ + (k * 5 + 1) * cc_dim1] + tr12 * ti2 + tr11 * ti3;
+	    cr5 = ti11 * tr5 + ti12 * tr4;
+	    ci5 = ti11 * ti5 + ti12 * ti4;
+	    cr4 = ti12 * tr5 - ti11 * tr4;
+	    ci4 = ti12 * ti5 - ti11 * ti4;
+	    dr3 = cr3 - ci4;
+	    dr4 = cr3 + ci4;
+	    di3 = ci3 + cr4;
+	    di4 = ci3 - cr4;
+	    dr5 = cr2 + ci5;
+	    dr2 = cr2 - ci5;
+	    di5 = ci2 - cr5;
+	    di2 = ci2 + cr5;
+	    ch[i__ - 1 + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * dr2 
+		    + wa1[i__] * di2;
+	    ch[i__ + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 1] * di2 - 
+		    wa1[i__] * dr2;
+	    ch[i__ - 1 + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 1] * dr3 + 
+		    wa2[i__] * di3;
+	    ch[i__ + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 1] * di3 - wa2[
+		    i__] * dr3;
+	    ch[i__ - 1 + (k + (ch_dim2 << 2)) * ch_dim1] = wa3[i__ - 1] * dr4 
+		    + wa3[i__] * di4;
+	    ch[i__ + (k + (ch_dim2 << 2)) * ch_dim1] = wa3[i__ - 1] * di4 - 
+		    wa3[i__] * dr4;
+	    ch[i__ - 1 + (k + ch_dim2 * 5) * ch_dim1] = wa4[i__ - 1] * dr5 + 
+		    wa4[i__] * di5;
+	    ch[i__ + (k + ch_dim2 * 5) * ch_dim1] = wa4[i__ - 1] * di5 - wa4[
+		    i__] * dr5;
+/* L103: */
+	}
+/* L104: */
+    }
+    return 0;
+} /* dpassf5_ */
+
+/*  ------ File dadb2.f ------ */
+/* Subroutine */ int dadb2_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, 
+	r_8 *wa1)
+{
+    /* System generated locals */
+    int_4 cc_dim1, cc_offset, ch_dim1, ch_dim2, ch_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k, ic;
+    static r_8 ti2, tr2;
+    static int_4 idp2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_offset = cc_dim1 * 3 + 1;
+    cc -= cc_offset;
+    --wa1;
+
+    /* Function Body */
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	ch[(k + ch_dim2) * ch_dim1 + 1] = cc[((k << 1) + 1) * cc_dim1 + 1] + 
+		cc[*ido + ((k << 1) + 2) * cc_dim1];
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 1] = cc[((k << 1) + 1) * cc_dim1 
+		+ 1] - cc[*ido + ((k << 1) + 2) * cc_dim1];
+/* L101: */
+    }
+    if ((i__1 = *ido - 2) < 0) {
+	goto L107;
+    } else if (i__1 == 0) {
+	goto L105;
+    } else {
+	goto L102;
+    }
+L102:
+    idp2 = *ido + 2;
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 3; i__ <= i__2; i__ += 2) {
+	    ic = idp2 - i__;
+	    ch[i__ - 1 + (k + ch_dim2) * ch_dim1] = cc[i__ - 1 + ((k << 1) + 
+		    1) * cc_dim1] + cc[ic - 1 + ((k << 1) + 2) * cc_dim1];
+	    tr2 = cc[i__ - 1 + ((k << 1) + 1) * cc_dim1] - cc[ic - 1 + ((k << 
+		    1) + 2) * cc_dim1];
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = cc[i__ + ((k << 1) + 1) * 
+		    cc_dim1] - cc[ic + ((k << 1) + 2) * cc_dim1];
+	    ti2 = cc[i__ + ((k << 1) + 1) * cc_dim1] + cc[ic + ((k << 1) + 2) 
+		    * cc_dim1];
+	    ch[i__ - 1 + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 2] * tr2 
+		    - wa1[i__ - 1] * ti2;
+	    ch[i__ + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 2] * ti2 + 
+		    wa1[i__ - 1] * tr2;
+/* L103: */
+	}
+/* L104: */
+    }
+    if (*ido % 2 == 1) {
+	return 0;
+    }
+L105:
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	ch[*ido + (k + ch_dim2) * ch_dim1] = cc[*ido + ((k << 1) + 1) * 
+		cc_dim1] + cc[*ido + ((k << 1) + 1) * cc_dim1];
+	ch[*ido + (k + (ch_dim2 << 1)) * ch_dim1] = -(cc[((k << 1) + 2) * 
+		cc_dim1 + 1] + cc[((k << 1) + 2) * cc_dim1 + 1]);
+/* L106: */
+    }
+L107:
+    return 0;
+} /* dadb2_ */
+
+/*  ------ File dadb3.f ------ */
+/* Subroutine */ int dadb3_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, 
+	r_8 *wa1, r_8 *wa2)
+{
+    /* Initialized data */
+
+    static r_8 taur = -.5f;
+    static r_8 taui = .866025403784439f;
+
+    /* System generated locals */
+    int_4 cc_dim1, cc_offset, ch_dim1, ch_dim2, ch_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k, ic;
+    static r_8 ci2, ci3, di2, di3, cr2, cr3, dr2, dr3, ti2, tr2;
+    static int_4 idp2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_offset = (cc_dim1 << 2) + 1;
+    cc -= cc_offset;
+    --wa1;
+    --wa2;
+
+    /* Function Body */
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	tr2 = cc[*ido + (k * 3 + 2) * cc_dim1] + cc[*ido + (k * 3 + 2) * 
+		cc_dim1];
+	cr2 = cc[(k * 3 + 1) * cc_dim1 + 1] + taur * tr2;
+	ch[(k + ch_dim2) * ch_dim1 + 1] = cc[(k * 3 + 1) * cc_dim1 + 1] + tr2;
+	ci3 = taui * (cc[(k * 3 + 3) * cc_dim1 + 1] + cc[(k * 3 + 3) * 
+		cc_dim1 + 1]);
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 1] = cr2 - ci3;
+	ch[(k + ch_dim2 * 3) * ch_dim1 + 1] = cr2 + ci3;
+/* L101: */
+    }
+    if (*ido == 1) {
+	return 0;
+    }
+    idp2 = *ido + 2;
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 3; i__ <= i__2; i__ += 2) {
+	    ic = idp2 - i__;
+	    tr2 = cc[i__ - 1 + (k * 3 + 3) * cc_dim1] + cc[ic - 1 + (k * 3 + 
+		    2) * cc_dim1];
+	    cr2 = cc[i__ - 1 + (k * 3 + 1) * cc_dim1] + taur * tr2;
+	    ch[i__ - 1 + (k + ch_dim2) * ch_dim1] = cc[i__ - 1 + (k * 3 + 1) *
+		     cc_dim1] + tr2;
+	    ti2 = cc[i__ + (k * 3 + 3) * cc_dim1] - cc[ic + (k * 3 + 2) * 
+		    cc_dim1];
+	    ci2 = cc[i__ + (k * 3 + 1) * cc_dim1] + taur * ti2;
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = cc[i__ + (k * 3 + 1) * 
+		    cc_dim1] + ti2;
+	    cr3 = taui * (cc[i__ - 1 + (k * 3 + 3) * cc_dim1] - cc[ic - 1 + (
+		    k * 3 + 2) * cc_dim1]);
+	    ci3 = taui * (cc[i__ + (k * 3 + 3) * cc_dim1] + cc[ic + (k * 3 + 
+		    2) * cc_dim1]);
+	    dr2 = cr2 - ci3;
+	    dr3 = cr2 + ci3;
+	    di2 = ci2 + cr3;
+	    di3 = ci2 - cr3;
+	    ch[i__ - 1 + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 2] * dr2 
+		    - wa1[i__ - 1] * di2;
+	    ch[i__ + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 2] * di2 + 
+		    wa1[i__ - 1] * dr2;
+	    ch[i__ - 1 + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 2] * dr3 - 
+		    wa2[i__ - 1] * di3;
+	    ch[i__ + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 2] * di3 + wa2[
+		    i__ - 1] * dr3;
+/* L102: */
+	}
+/* L103: */
+    }
+    return 0;
+} /* dadb3_ */
+
+/*  ------ File dadb4.f ------ */
+/* Subroutine */ int dadb4_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, 
+	r_8 *wa1, r_8 *wa2, r_8 *wa3)
+{
+    /* Initialized data */
+
+    static r_8 sqrt2 = 1.414213562373095f;
+
+    /* System generated locals */
+    int_4 cc_dim1, cc_offset, ch_dim1, ch_dim2, ch_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k, ic;
+    static r_8 ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, 
+	    tr3, tr4;
+    static int_4 idp2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_offset = cc_dim1 * 5 + 1;
+    cc -= cc_offset;
+    --wa1;
+    --wa2;
+    --wa3;
+
+    /* Function Body */
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	tr1 = cc[((k << 2) + 1) * cc_dim1 + 1] - cc[*ido + ((k << 2) + 4) * 
+		cc_dim1];
+	tr2 = cc[((k << 2) + 1) * cc_dim1 + 1] + cc[*ido + ((k << 2) + 4) * 
+		cc_dim1];
+	tr3 = cc[*ido + ((k << 2) + 2) * cc_dim1] + cc[*ido + ((k << 2) + 2) *
+		 cc_dim1];
+	tr4 = cc[((k << 2) + 3) * cc_dim1 + 1] + cc[((k << 2) + 3) * cc_dim1 
+		+ 1];
+	ch[(k + ch_dim2) * ch_dim1 + 1] = tr2 + tr3;
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 1] = tr1 - tr4;
+	ch[(k + ch_dim2 * 3) * ch_dim1 + 1] = tr2 - tr3;
+	ch[(k + (ch_dim2 << 2)) * ch_dim1 + 1] = tr1 + tr4;
+/* L101: */
+    }
+    if ((i__1 = *ido - 2) < 0) {
+	goto L107;
+    } else if (i__1 == 0) {
+	goto L105;
+    } else {
+	goto L102;
+    }
+L102:
+    idp2 = *ido + 2;
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 3; i__ <= i__2; i__ += 2) {
+	    ic = idp2 - i__;
+	    ti1 = cc[i__ + ((k << 2) + 1) * cc_dim1] + cc[ic + ((k << 2) + 4) 
+		    * cc_dim1];
+	    ti2 = cc[i__ + ((k << 2) + 1) * cc_dim1] - cc[ic + ((k << 2) + 4) 
+		    * cc_dim1];
+	    ti3 = cc[i__ + ((k << 2) + 3) * cc_dim1] - cc[ic + ((k << 2) + 2) 
+		    * cc_dim1];
+	    tr4 = cc[i__ + ((k << 2) + 3) * cc_dim1] + cc[ic + ((k << 2) + 2) 
+		    * cc_dim1];
+	    tr1 = cc[i__ - 1 + ((k << 2) + 1) * cc_dim1] - cc[ic - 1 + ((k << 
+		    2) + 4) * cc_dim1];
+	    tr2 = cc[i__ - 1 + ((k << 2) + 1) * cc_dim1] + cc[ic - 1 + ((k << 
+		    2) + 4) * cc_dim1];
+	    ti4 = cc[i__ - 1 + ((k << 2) + 3) * cc_dim1] - cc[ic - 1 + ((k << 
+		    2) + 2) * cc_dim1];
+	    tr3 = cc[i__ - 1 + ((k << 2) + 3) * cc_dim1] + cc[ic - 1 + ((k << 
+		    2) + 2) * cc_dim1];
+	    ch[i__ - 1 + (k + ch_dim2) * ch_dim1] = tr2 + tr3;
+	    cr3 = tr2 - tr3;
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = ti2 + ti3;
+	    ci3 = ti2 - ti3;
+	    cr2 = tr1 - tr4;
+	    cr4 = tr1 + tr4;
+	    ci2 = ti1 + ti4;
+	    ci4 = ti1 - ti4;
+	    ch[i__ - 1 + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 2] * cr2 
+		    - wa1[i__ - 1] * ci2;
+	    ch[i__ + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 2] * ci2 + 
+		    wa1[i__ - 1] * cr2;
+	    ch[i__ - 1 + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 2] * cr3 - 
+		    wa2[i__ - 1] * ci3;
+	    ch[i__ + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 2] * ci3 + wa2[
+		    i__ - 1] * cr3;
+	    ch[i__ - 1 + (k + (ch_dim2 << 2)) * ch_dim1] = wa3[i__ - 2] * cr4 
+		    - wa3[i__ - 1] * ci4;
+	    ch[i__ + (k + (ch_dim2 << 2)) * ch_dim1] = wa3[i__ - 2] * ci4 + 
+		    wa3[i__ - 1] * cr4;
+/* L103: */
+	}
+/* L104: */
+    }
+    if (*ido % 2 == 1) {
+	return 0;
+    }
+L105:
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	ti1 = cc[((k << 2) + 2) * cc_dim1 + 1] + cc[((k << 2) + 4) * cc_dim1 
+		+ 1];
+	ti2 = cc[((k << 2) + 4) * cc_dim1 + 1] - cc[((k << 2) + 2) * cc_dim1 
+		+ 1];
+	tr1 = cc[*ido + ((k << 2) + 1) * cc_dim1] - cc[*ido + ((k << 2) + 3) *
+		 cc_dim1];
+	tr2 = cc[*ido + ((k << 2) + 1) * cc_dim1] + cc[*ido + ((k << 2) + 3) *
+		 cc_dim1];
+	ch[*ido + (k + ch_dim2) * ch_dim1] = tr2 + tr2;
+	ch[*ido + (k + (ch_dim2 << 1)) * ch_dim1] = sqrt2 * (tr1 - ti1);
+	ch[*ido + (k + ch_dim2 * 3) * ch_dim1] = ti2 + ti2;
+	ch[*ido + (k + (ch_dim2 << 2)) * ch_dim1] = -sqrt2 * (tr1 + ti1);
+/* L106: */
+    }
+L107:
+    return 0;
+} /* dadb4_ */
+
+/*  ------ File dadb5.f ------ */
+/* Subroutine */ int dadb5_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, 
+	r_8 *wa1, r_8 *wa2, r_8 *wa3, r_8 *wa4)
+{
+    /* Initialized data */
+
+    static r_8 tr11 = .309016994374947f;
+    static r_8 ti11 = .951056516295154f;
+    static r_8 tr12 = -.809016994374947f;
+    static r_8 ti12 = .587785252292473f;
+
+    /* System generated locals */
+    int_4 cc_dim1, cc_offset, ch_dim1, ch_dim2, ch_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k, ic;
+    static r_8 ci2, ci3, ci4, ci5, di3, di4, di5, di2, cr2, cr3, cr5, cr4, 
+	    ti2, ti3, ti4, ti5, dr3, dr4, dr5, dr2, tr2, tr3, tr4, tr5;
+    static int_4 idp2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_offset = cc_dim1 * 6 + 1;
+    cc -= cc_offset;
+    --wa1;
+    --wa2;
+    --wa3;
+    --wa4;
+
+    /* Function Body */
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	ti5 = cc[(k * 5 + 3) * cc_dim1 + 1] + cc[(k * 5 + 3) * cc_dim1 + 1];
+	ti4 = cc[(k * 5 + 5) * cc_dim1 + 1] + cc[(k * 5 + 5) * cc_dim1 + 1];
+	tr2 = cc[*ido + (k * 5 + 2) * cc_dim1] + cc[*ido + (k * 5 + 2) * 
+		cc_dim1];
+	tr3 = cc[*ido + (k * 5 + 4) * cc_dim1] + cc[*ido + (k * 5 + 4) * 
+		cc_dim1];
+	ch[(k + ch_dim2) * ch_dim1 + 1] = cc[(k * 5 + 1) * cc_dim1 + 1] + tr2 
+		+ tr3;
+	cr2 = cc[(k * 5 + 1) * cc_dim1 + 1] + tr11 * tr2 + tr12 * tr3;
+	cr3 = cc[(k * 5 + 1) * cc_dim1 + 1] + tr12 * tr2 + tr11 * tr3;
+	ci5 = ti11 * ti5 + ti12 * ti4;
+	ci4 = ti12 * ti5 - ti11 * ti4;
+	ch[(k + (ch_dim2 << 1)) * ch_dim1 + 1] = cr2 - ci5;
+	ch[(k + ch_dim2 * 3) * ch_dim1 + 1] = cr3 - ci4;
+	ch[(k + (ch_dim2 << 2)) * ch_dim1 + 1] = cr3 + ci4;
+	ch[(k + ch_dim2 * 5) * ch_dim1 + 1] = cr2 + ci5;
+/* L101: */
+    }
+    if (*ido == 1) {
+	return 0;
+    }
+    idp2 = *ido + 2;
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 3; i__ <= i__2; i__ += 2) {
+	    ic = idp2 - i__;
+	    ti5 = cc[i__ + (k * 5 + 3) * cc_dim1] + cc[ic + (k * 5 + 2) * 
+		    cc_dim1];
+	    ti2 = cc[i__ + (k * 5 + 3) * cc_dim1] - cc[ic + (k * 5 + 2) * 
+		    cc_dim1];
+	    ti4 = cc[i__ + (k * 5 + 5) * cc_dim1] + cc[ic + (k * 5 + 4) * 
+		    cc_dim1];
+	    ti3 = cc[i__ + (k * 5 + 5) * cc_dim1] - cc[ic + (k * 5 + 4) * 
+		    cc_dim1];
+	    tr5 = cc[i__ - 1 + (k * 5 + 3) * cc_dim1] - cc[ic - 1 + (k * 5 + 
+		    2) * cc_dim1];
+	    tr2 = cc[i__ - 1 + (k * 5 + 3) * cc_dim1] + cc[ic - 1 + (k * 5 + 
+		    2) * cc_dim1];
+	    tr4 = cc[i__ - 1 + (k * 5 + 5) * cc_dim1] - cc[ic - 1 + (k * 5 + 
+		    4) * cc_dim1];
+	    tr3 = cc[i__ - 1 + (k * 5 + 5) * cc_dim1] + cc[ic - 1 + (k * 5 + 
+		    4) * cc_dim1];
+	    ch[i__ - 1 + (k + ch_dim2) * ch_dim1] = cc[i__ - 1 + (k * 5 + 1) *
+		     cc_dim1] + tr2 + tr3;
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = cc[i__ + (k * 5 + 1) * 
+		    cc_dim1] + ti2 + ti3;
+	    cr2 = cc[i__ - 1 + (k * 5 + 1) * cc_dim1] + tr11 * tr2 + tr12 * 
+		    tr3;
+	    ci2 = cc[i__ + (k * 5 + 1) * cc_dim1] + tr11 * ti2 + tr12 * ti3;
+	    cr3 = cc[i__ - 1 + (k * 5 + 1) * cc_dim1] + tr12 * tr2 + tr11 * 
+		    tr3;
+	    ci3 = cc[i__ + (k * 5 + 1) * cc_dim1] + tr12 * ti2 + tr11 * ti3;
+	    cr5 = ti11 * tr5 + ti12 * tr4;
+	    ci5 = ti11 * ti5 + ti12 * ti4;
+	    cr4 = ti12 * tr5 - ti11 * tr4;
+	    ci4 = ti12 * ti5 - ti11 * ti4;
+	    dr3 = cr3 - ci4;
+	    dr4 = cr3 + ci4;
+	    di3 = ci3 + cr4;
+	    di4 = ci3 - cr4;
+	    dr5 = cr2 + ci5;
+	    dr2 = cr2 - ci5;
+	    di5 = ci2 - cr5;
+	    di2 = ci2 + cr5;
+	    ch[i__ - 1 + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 2] * dr2 
+		    - wa1[i__ - 1] * di2;
+	    ch[i__ + (k + (ch_dim2 << 1)) * ch_dim1] = wa1[i__ - 2] * di2 + 
+		    wa1[i__ - 1] * dr2;
+	    ch[i__ - 1 + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 2] * dr3 - 
+		    wa2[i__ - 1] * di3;
+	    ch[i__ + (k + ch_dim2 * 3) * ch_dim1] = wa2[i__ - 2] * di3 + wa2[
+		    i__ - 1] * dr3;
+	    ch[i__ - 1 + (k + (ch_dim2 << 2)) * ch_dim1] = wa3[i__ - 2] * dr4 
+		    - wa3[i__ - 1] * di4;
+	    ch[i__ + (k + (ch_dim2 << 2)) * ch_dim1] = wa3[i__ - 2] * di4 + 
+		    wa3[i__ - 1] * dr4;
+	    ch[i__ - 1 + (k + ch_dim2 * 5) * ch_dim1] = wa4[i__ - 2] * dr5 - 
+		    wa4[i__ - 1] * di5;
+	    ch[i__ + (k + ch_dim2 * 5) * ch_dim1] = wa4[i__ - 2] * di5 + wa4[
+		    i__ - 1] * dr5;
+/* L102: */
+	}
+/* L103: */
+    }
+    return 0;
+} /* dadb5_ */
+
+/*  ------ File dadbg.f ------ */
+/* Subroutine */ int dadbg_(int_4 *ido, int_4 *ip, int_4 *l1, int_4 *
+	idl1, r_8 *cc, r_8 *c1, r_8 *c2, r_8 *ch, r_8 *ch2, r_8 *wa)
+{
+    /* Initialized data */
+
+    static r_8 tpi = 6.28318530717959f;
+
+    /* System generated locals */
+    int_4 ch_dim1, ch_dim2, ch_offset, cc_dim1, cc_dim2, cc_offset, c1_dim1,
+	     c1_dim2, c1_offset, c2_dim1, c2_offset, ch2_dim1, ch2_offset, 
+	    i__1, i__2, i__3;
+
+    /* Builtin functions */
+/*    r_8 cos(r_8truc), sin(r_8truc);  remplace par math.h  Reza 29/11/99 */
+
+    /* Local variables */
+    static int_4 idij, ipph, i__, j, k, l, j2, ic, jc, lc, ik, is;
+    static r_8 dc2, ai1, ai2, ar1, ar2, ds2;
+    static int_4 nbd;
+    static r_8 dcp, arg, dsp, ar1h, ar2h;
+    static int_4 idp2, ipp2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    c1_dim1 = *ido;
+    c1_dim2 = *l1;
+    c1_offset = c1_dim1 * (c1_dim2 + 1) + 1;
+    c1 -= c1_offset;
+    cc_dim1 = *ido;
+    cc_dim2 = *ip;
+    cc_offset = cc_dim1 * (cc_dim2 + 1) + 1;
+    cc -= cc_offset;
+    ch2_dim1 = *idl1;
+    ch2_offset = ch2_dim1 + 1;
+    ch2 -= ch2_offset;
+    c2_dim1 = *idl1;
+    c2_offset = c2_dim1 + 1;
+    c2 -= c2_offset;
+    --wa;
+
+    /* Function Body */
+    arg = tpi / (r_8) (*ip);
+    dcp = cos(arg);
+    dsp = sin(arg);
+    idp2 = *ido + 2;
+    nbd = (*ido - 1) / 2;
+    ipp2 = *ip + 2;
+    ipph = (*ip + 1) / 2;
+    if (*ido < *l1) {
+	goto L103;
+    }
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 1; i__ <= i__2; ++i__) {
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = cc[i__ + (k * cc_dim2 + 1) * 
+		    cc_dim1];
+/* L101: */
+	}
+/* L102: */
+    }
+    goto L106;
+L103:
+    i__1 = *ido;
+    for (i__ = 1; i__ <= i__1; ++i__) {
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    ch[i__ + (k + ch_dim2) * ch_dim1] = cc[i__ + (k * cc_dim2 + 1) * 
+		    cc_dim1];
+/* L104: */
+	}
+/* L105: */
+    }
+L106:
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	j2 = j + j;
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    ch[(k + j * ch_dim2) * ch_dim1 + 1] = cc[*ido + (j2 - 2 + k * 
+		    cc_dim2) * cc_dim1] + cc[*ido + (j2 - 2 + k * cc_dim2) * 
+		    cc_dim1];
+	    ch[(k + jc * ch_dim2) * ch_dim1 + 1] = cc[(j2 - 1 + k * cc_dim2) *
+		     cc_dim1 + 1] + cc[(j2 - 1 + k * cc_dim2) * cc_dim1 + 1];
+/* L107: */
+	}
+/* L108: */
+    }
+    if (*ido == 1) {
+	goto L116;
+    }
+    if (nbd < *l1) {
+	goto L112;
+    }
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    i__3 = *ido;
+	    for (i__ = 3; i__ <= i__3; i__ += 2) {
+		ic = idp2 - i__;
+		ch[i__ - 1 + (k + j * ch_dim2) * ch_dim1] = cc[i__ - 1 + ((j 
+			<< 1) - 1 + k * cc_dim2) * cc_dim1] + cc[ic - 1 + ((j 
+			<< 1) - 2 + k * cc_dim2) * cc_dim1];
+		ch[i__ - 1 + (k + jc * ch_dim2) * ch_dim1] = cc[i__ - 1 + ((j 
+			<< 1) - 1 + k * cc_dim2) * cc_dim1] - cc[ic - 1 + ((j 
+			<< 1) - 2 + k * cc_dim2) * cc_dim1];
+		ch[i__ + (k + j * ch_dim2) * ch_dim1] = cc[i__ + ((j << 1) - 
+			1 + k * cc_dim2) * cc_dim1] - cc[ic + ((j << 1) - 2 + 
+			k * cc_dim2) * cc_dim1];
+		ch[i__ + (k + jc * ch_dim2) * ch_dim1] = cc[i__ + ((j << 1) - 
+			1 + k * cc_dim2) * cc_dim1] + cc[ic + ((j << 1) - 2 + 
+			k * cc_dim2) * cc_dim1];
+/* L109: */
+	    }
+/* L110: */
+	}
+/* L111: */
+    }
+    goto L116;
+L112:
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	i__2 = *ido;
+	for (i__ = 3; i__ <= i__2; i__ += 2) {
+	    ic = idp2 - i__;
+	    i__3 = *l1;
+	    for (k = 1; k <= i__3; ++k) {
+		ch[i__ - 1 + (k + j * ch_dim2) * ch_dim1] = cc[i__ - 1 + ((j 
+			<< 1) - 1 + k * cc_dim2) * cc_dim1] + cc[ic - 1 + ((j 
+			<< 1) - 2 + k * cc_dim2) * cc_dim1];
+		ch[i__ - 1 + (k + jc * ch_dim2) * ch_dim1] = cc[i__ - 1 + ((j 
+			<< 1) - 1 + k * cc_dim2) * cc_dim1] - cc[ic - 1 + ((j 
+			<< 1) - 2 + k * cc_dim2) * cc_dim1];
+		ch[i__ + (k + j * ch_dim2) * ch_dim1] = cc[i__ + ((j << 1) - 
+			1 + k * cc_dim2) * cc_dim1] - cc[ic + ((j << 1) - 2 + 
+			k * cc_dim2) * cc_dim1];
+		ch[i__ + (k + jc * ch_dim2) * ch_dim1] = cc[i__ + ((j << 1) - 
+			1 + k * cc_dim2) * cc_dim1] + cc[ic + ((j << 1) - 2 + 
+			k * cc_dim2) * cc_dim1];
+/* L113: */
+	    }
+/* L114: */
+	}
+/* L115: */
+    }
+L116:
+    ar1 = 1.f;
+    ai1 = 0.f;
+    i__1 = ipph;
+    for (l = 2; l <= i__1; ++l) {
+	lc = ipp2 - l;
+	ar1h = dcp * ar1 - dsp * ai1;
+	ai1 = dcp * ai1 + dsp * ar1;
+	ar1 = ar1h;
+	i__2 = *idl1;
+	for (ik = 1; ik <= i__2; ++ik) {
+	    c2[ik + l * c2_dim1] = ch2[ik + ch2_dim1] + ar1 * ch2[ik + (
+		    ch2_dim1 << 1)];
+	    c2[ik + lc * c2_dim1] = ai1 * ch2[ik + *ip * ch2_dim1];
+/* L117: */
+	}
+	dc2 = ar1;
+	ds2 = ai1;
+	ar2 = ar1;
+	ai2 = ai1;
+	i__2 = ipph;
+	for (j = 3; j <= i__2; ++j) {
+	    jc = ipp2 - j;
+	    ar2h = dc2 * ar2 - ds2 * ai2;
+	    ai2 = dc2 * ai2 + ds2 * ar2;
+	    ar2 = ar2h;
+	    i__3 = *idl1;
+	    for (ik = 1; ik <= i__3; ++ik) {
+		c2[ik + l * c2_dim1] += ar2 * ch2[ik + j * ch2_dim1];
+		c2[ik + lc * c2_dim1] += ai2 * ch2[ik + jc * ch2_dim1];
+/* L118: */
+	    }
+/* L119: */
+	}
+/* L120: */
+    }
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	i__2 = *idl1;
+	for (ik = 1; ik <= i__2; ++ik) {
+	    ch2[ik + ch2_dim1] += ch2[ik + j * ch2_dim1];
+/* L121: */
+	}
+/* L122: */
+    }
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    ch[(k + j * ch_dim2) * ch_dim1 + 1] = c1[(k + j * c1_dim2) * 
+		    c1_dim1 + 1] - c1[(k + jc * c1_dim2) * c1_dim1 + 1];
+	    ch[(k + jc * ch_dim2) * ch_dim1 + 1] = c1[(k + j * c1_dim2) * 
+		    c1_dim1 + 1] + c1[(k + jc * c1_dim2) * c1_dim1 + 1];
+/* L123: */
+	}
+/* L124: */
+    }
+    if (*ido == 1) {
+	goto L132;
+    }
+    if (nbd < *l1) {
+	goto L128;
+    }
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    i__3 = *ido;
+	    for (i__ = 3; i__ <= i__3; i__ += 2) {
+		ch[i__ - 1 + (k + j * ch_dim2) * ch_dim1] = c1[i__ - 1 + (k + 
+			j * c1_dim2) * c1_dim1] - c1[i__ + (k + jc * c1_dim2) 
+			* c1_dim1];
+		ch[i__ - 1 + (k + jc * ch_dim2) * ch_dim1] = c1[i__ - 1 + (k 
+			+ j * c1_dim2) * c1_dim1] + c1[i__ + (k + jc * 
+			c1_dim2) * c1_dim1];
+		ch[i__ + (k + j * ch_dim2) * ch_dim1] = c1[i__ + (k + j * 
+			c1_dim2) * c1_dim1] + c1[i__ - 1 + (k + jc * c1_dim2) 
+			* c1_dim1];
+		ch[i__ + (k + jc * ch_dim2) * ch_dim1] = c1[i__ + (k + j * 
+			c1_dim2) * c1_dim1] - c1[i__ - 1 + (k + jc * c1_dim2) 
+			* c1_dim1];
+/* L125: */
+	    }
+/* L126: */
+	}
+/* L127: */
+    }
+    goto L132;
+L128:
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	i__2 = *ido;
+	for (i__ = 3; i__ <= i__2; i__ += 2) {
+	    i__3 = *l1;
+	    for (k = 1; k <= i__3; ++k) {
+		ch[i__ - 1 + (k + j * ch_dim2) * ch_dim1] = c1[i__ - 1 + (k + 
+			j * c1_dim2) * c1_dim1] - c1[i__ + (k + jc * c1_dim2) 
+			* c1_dim1];
+		ch[i__ - 1 + (k + jc * ch_dim2) * ch_dim1] = c1[i__ - 1 + (k 
+			+ j * c1_dim2) * c1_dim1] + c1[i__ + (k + jc * 
+			c1_dim2) * c1_dim1];
+		ch[i__ + (k + j * ch_dim2) * ch_dim1] = c1[i__ + (k + j * 
+			c1_dim2) * c1_dim1] + c1[i__ - 1 + (k + jc * c1_dim2) 
+			* c1_dim1];
+		ch[i__ + (k + jc * ch_dim2) * ch_dim1] = c1[i__ + (k + j * 
+			c1_dim2) * c1_dim1] - c1[i__ - 1 + (k + jc * c1_dim2) 
+			* c1_dim1];
+/* L129: */
+	    }
+/* L130: */
+	}
+/* L131: */
+    }
+L132:
+    if (*ido == 1) {
+	return 0;
+    }
+    i__1 = *idl1;
+    for (ik = 1; ik <= i__1; ++ik) {
+	c2[ik + c2_dim1] = ch2[ik + ch2_dim1];
+/* L133: */
+    }
+    i__1 = *ip;
+    for (j = 2; j <= i__1; ++j) {
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    c1[(k + j * c1_dim2) * c1_dim1 + 1] = ch[(k + j * ch_dim2) * 
+		    ch_dim1 + 1];
+/* L134: */
+	}
+/* L135: */
+    }
+    if (nbd > *l1) {
+	goto L139;
+    }
+    is = -(*ido);
+    i__1 = *ip;
+    for (j = 2; j <= i__1; ++j) {
+	is += *ido;
+	idij = is;
+	i__2 = *ido;
+	for (i__ = 3; i__ <= i__2; i__ += 2) {
+	    idij += 2;
+	    i__3 = *l1;
+	    for (k = 1; k <= i__3; ++k) {
+		c1[i__ - 1 + (k + j * c1_dim2) * c1_dim1] = wa[idij - 1] * ch[
+			i__ - 1 + (k + j * ch_dim2) * ch_dim1] - wa[idij] * 
+			ch[i__ + (k + j * ch_dim2) * ch_dim1];
+		c1[i__ + (k + j * c1_dim2) * c1_dim1] = wa[idij - 1] * ch[i__ 
+			+ (k + j * ch_dim2) * ch_dim1] + wa[idij] * ch[i__ - 
+			1 + (k + j * ch_dim2) * ch_dim1];
+/* L136: */
+	    }
+/* L137: */
+	}
+/* L138: */
+    }
+    goto L143;
+L139:
+    is = -(*ido);
+    i__1 = *ip;
+    for (j = 2; j <= i__1; ++j) {
+	is += *ido;
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    idij = is;
+	    i__3 = *ido;
+	    for (i__ = 3; i__ <= i__3; i__ += 2) {
+		idij += 2;
+		c1[i__ - 1 + (k + j * c1_dim2) * c1_dim1] = wa[idij - 1] * ch[
+			i__ - 1 + (k + j * ch_dim2) * ch_dim1] - wa[idij] * 
+			ch[i__ + (k + j * ch_dim2) * ch_dim1];
+		c1[i__ + (k + j * c1_dim2) * c1_dim1] = wa[idij - 1] * ch[i__ 
+			+ (k + j * ch_dim2) * ch_dim1] + wa[idij] * ch[i__ - 
+			1 + (k + j * ch_dim2) * ch_dim1];
+/* L140: */
+	    }
+/* L141: */
+	}
+/* L142: */
+    }
+L143:
+    return 0;
+} /* dadbg_ */
+
+/*  ------ File dadf2.f ------ */
+/* Subroutine */ int dadf2_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, 
+	r_8 *wa1)
+{
+    /* System generated locals */
+    int_4 ch_dim1, ch_offset, cc_dim1, cc_dim2, cc_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k, ic;
+    static r_8 ti2, tr2;
+    static int_4 idp2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_offset = ch_dim1 * 3 + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_dim2 = *l1;
+    cc_offset = cc_dim1 * (cc_dim2 + 1) + 1;
+    cc -= cc_offset;
+    --wa1;
+
+    /* Function Body */
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	ch[((k << 1) + 1) * ch_dim1 + 1] = cc[(k + cc_dim2) * cc_dim1 + 1] + 
+		cc[(k + (cc_dim2 << 1)) * cc_dim1 + 1];
+	ch[*ido + ((k << 1) + 2) * ch_dim1] = cc[(k + cc_dim2) * cc_dim1 + 1] 
+		- cc[(k + (cc_dim2 << 1)) * cc_dim1 + 1];
+/* L101: */
+    }
+    if ((i__1 = *ido - 2) < 0) {
+	goto L107;
+    } else if (i__1 == 0) {
+	goto L105;
+    } else {
+	goto L102;
+    }
+L102:
+    idp2 = *ido + 2;
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 3; i__ <= i__2; i__ += 2) {
+	    ic = idp2 - i__;
+	    tr2 = wa1[i__ - 2] * cc[i__ - 1 + (k + (cc_dim2 << 1)) * cc_dim1] 
+		    + wa1[i__ - 1] * cc[i__ + (k + (cc_dim2 << 1)) * cc_dim1];
+	    ti2 = wa1[i__ - 2] * cc[i__ + (k + (cc_dim2 << 1)) * cc_dim1] - 
+		    wa1[i__ - 1] * cc[i__ - 1 + (k + (cc_dim2 << 1)) * 
+		    cc_dim1];
+	    ch[i__ + ((k << 1) + 1) * ch_dim1] = cc[i__ + (k + cc_dim2) * 
+		    cc_dim1] + ti2;
+	    ch[ic + ((k << 1) + 2) * ch_dim1] = ti2 - cc[i__ + (k + cc_dim2) *
+		     cc_dim1];
+	    ch[i__ - 1 + ((k << 1) + 1) * ch_dim1] = cc[i__ - 1 + (k + 
+		    cc_dim2) * cc_dim1] + tr2;
+	    ch[ic - 1 + ((k << 1) + 2) * ch_dim1] = cc[i__ - 1 + (k + cc_dim2)
+		     * cc_dim1] - tr2;
+/* L103: */
+	}
+/* L104: */
+    }
+    if (*ido % 2 == 1) {
+	return 0;
+    }
+L105:
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	ch[((k << 1) + 2) * ch_dim1 + 1] = -cc[*ido + (k + (cc_dim2 << 1)) * 
+		cc_dim1];
+	ch[*ido + ((k << 1) + 1) * ch_dim1] = cc[*ido + (k + cc_dim2) * 
+		cc_dim1];
+/* L106: */
+    }
+L107:
+    return 0;
+} /* dadf2_ */
+
+/*  ------ File dadf3.f ------ */
+/* Subroutine */ int dadf3_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, 
+	r_8 *wa1, r_8 *wa2)
+{
+    /* Initialized data */
+
+    static r_8 taur = -.5f;
+    static r_8 taui = .866025403784439f;
+
+    /* System generated locals */
+    int_4 ch_dim1, ch_offset, cc_dim1, cc_dim2, cc_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k, ic;
+    static r_8 ci2, di2, di3, cr2, dr2, dr3, ti2, ti3, tr2, tr3;
+    static int_4 idp2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_offset = (ch_dim1 << 2) + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_dim2 = *l1;
+    cc_offset = cc_dim1 * (cc_dim2 + 1) + 1;
+    cc -= cc_offset;
+    --wa1;
+    --wa2;
+
+    /* Function Body */
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	cr2 = cc[(k + (cc_dim2 << 1)) * cc_dim1 + 1] + cc[(k + cc_dim2 * 3) * 
+		cc_dim1 + 1];
+	ch[(k * 3 + 1) * ch_dim1 + 1] = cc[(k + cc_dim2) * cc_dim1 + 1] + cr2;
+	ch[(k * 3 + 3) * ch_dim1 + 1] = taui * (cc[(k + cc_dim2 * 3) * 
+		cc_dim1 + 1] - cc[(k + (cc_dim2 << 1)) * cc_dim1 + 1]);
+	ch[*ido + (k * 3 + 2) * ch_dim1] = cc[(k + cc_dim2) * cc_dim1 + 1] + 
+		taur * cr2;
+/* L101: */
+    }
+    if (*ido == 1) {
+	return 0;
+    }
+    idp2 = *ido + 2;
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 3; i__ <= i__2; i__ += 2) {
+	    ic = idp2 - i__;
+	    dr2 = wa1[i__ - 2] * cc[i__ - 1 + (k + (cc_dim2 << 1)) * cc_dim1] 
+		    + wa1[i__ - 1] * cc[i__ + (k + (cc_dim2 << 1)) * cc_dim1];
+	    di2 = wa1[i__ - 2] * cc[i__ + (k + (cc_dim2 << 1)) * cc_dim1] - 
+		    wa1[i__ - 1] * cc[i__ - 1 + (k + (cc_dim2 << 1)) * 
+		    cc_dim1];
+	    dr3 = wa2[i__ - 2] * cc[i__ - 1 + (k + cc_dim2 * 3) * cc_dim1] + 
+		    wa2[i__ - 1] * cc[i__ + (k + cc_dim2 * 3) * cc_dim1];
+	    di3 = wa2[i__ - 2] * cc[i__ + (k + cc_dim2 * 3) * cc_dim1] - wa2[
+		    i__ - 1] * cc[i__ - 1 + (k + cc_dim2 * 3) * cc_dim1];
+	    cr2 = dr2 + dr3;
+	    ci2 = di2 + di3;
+	    ch[i__ - 1 + (k * 3 + 1) * ch_dim1] = cc[i__ - 1 + (k + cc_dim2) *
+		     cc_dim1] + cr2;
+	    ch[i__ + (k * 3 + 1) * ch_dim1] = cc[i__ + (k + cc_dim2) * 
+		    cc_dim1] + ci2;
+	    tr2 = cc[i__ - 1 + (k + cc_dim2) * cc_dim1] + taur * cr2;
+	    ti2 = cc[i__ + (k + cc_dim2) * cc_dim1] + taur * ci2;
+	    tr3 = taui * (di2 - di3);
+	    ti3 = taui * (dr3 - dr2);
+	    ch[i__ - 1 + (k * 3 + 3) * ch_dim1] = tr2 + tr3;
+	    ch[ic - 1 + (k * 3 + 2) * ch_dim1] = tr2 - tr3;
+	    ch[i__ + (k * 3 + 3) * ch_dim1] = ti2 + ti3;
+	    ch[ic + (k * 3 + 2) * ch_dim1] = ti3 - ti2;
+/* L102: */
+	}
+/* L103: */
+    }
+    return 0;
+} /* dadf3_ */
+
+/*  ------ File dadf4.f ------ */
+/* Subroutine */ int dadf4_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, 
+	r_8 *wa1, r_8 *wa2, r_8 *wa3)
+{
+    /* Initialized data */
+
+    static r_8 hsqt2 = .7071067811865475f;
+
+    /* System generated locals */
+    int_4 cc_dim1, cc_dim2, cc_offset, ch_dim1, ch_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k, ic;
+    static r_8 ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, 
+	    tr3, tr4;
+    static int_4 idp2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_offset = ch_dim1 * 5 + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_dim2 = *l1;
+    cc_offset = cc_dim1 * (cc_dim2 + 1) + 1;
+    cc -= cc_offset;
+    --wa1;
+    --wa2;
+    --wa3;
+
+    /* Function Body */
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	tr1 = cc[(k + (cc_dim2 << 1)) * cc_dim1 + 1] + cc[(k + (cc_dim2 << 2))
+		 * cc_dim1 + 1];
+	tr2 = cc[(k + cc_dim2) * cc_dim1 + 1] + cc[(k + cc_dim2 * 3) * 
+		cc_dim1 + 1];
+	ch[((k << 2) + 1) * ch_dim1 + 1] = tr1 + tr2;
+	ch[*ido + ((k << 2) + 4) * ch_dim1] = tr2 - tr1;
+	ch[*ido + ((k << 2) + 2) * ch_dim1] = cc[(k + cc_dim2) * cc_dim1 + 1] 
+		- cc[(k + cc_dim2 * 3) * cc_dim1 + 1];
+	ch[((k << 2) + 3) * ch_dim1 + 1] = cc[(k + (cc_dim2 << 2)) * cc_dim1 
+		+ 1] - cc[(k + (cc_dim2 << 1)) * cc_dim1 + 1];
+/* L101: */
+    }
+    if ((i__1 = *ido - 2) < 0) {
+	goto L107;
+    } else if (i__1 == 0) {
+	goto L105;
+    } else {
+	goto L102;
+    }
+L102:
+    idp2 = *ido + 2;
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 3; i__ <= i__2; i__ += 2) {
+	    ic = idp2 - i__;
+	    cr2 = wa1[i__ - 2] * cc[i__ - 1 + (k + (cc_dim2 << 1)) * cc_dim1] 
+		    + wa1[i__ - 1] * cc[i__ + (k + (cc_dim2 << 1)) * cc_dim1];
+	    ci2 = wa1[i__ - 2] * cc[i__ + (k + (cc_dim2 << 1)) * cc_dim1] - 
+		    wa1[i__ - 1] * cc[i__ - 1 + (k + (cc_dim2 << 1)) * 
+		    cc_dim1];
+	    cr3 = wa2[i__ - 2] * cc[i__ - 1 + (k + cc_dim2 * 3) * cc_dim1] + 
+		    wa2[i__ - 1] * cc[i__ + (k + cc_dim2 * 3) * cc_dim1];
+	    ci3 = wa2[i__ - 2] * cc[i__ + (k + cc_dim2 * 3) * cc_dim1] - wa2[
+		    i__ - 1] * cc[i__ - 1 + (k + cc_dim2 * 3) * cc_dim1];
+	    cr4 = wa3[i__ - 2] * cc[i__ - 1 + (k + (cc_dim2 << 2)) * cc_dim1] 
+		    + wa3[i__ - 1] * cc[i__ + (k + (cc_dim2 << 2)) * cc_dim1];
+	    ci4 = wa3[i__ - 2] * cc[i__ + (k + (cc_dim2 << 2)) * cc_dim1] - 
+		    wa3[i__ - 1] * cc[i__ - 1 + (k + (cc_dim2 << 2)) * 
+		    cc_dim1];
+	    tr1 = cr2 + cr4;
+	    tr4 = cr4 - cr2;
+	    ti1 = ci2 + ci4;
+	    ti4 = ci2 - ci4;
+	    ti2 = cc[i__ + (k + cc_dim2) * cc_dim1] + ci3;
+	    ti3 = cc[i__ + (k + cc_dim2) * cc_dim1] - ci3;
+	    tr2 = cc[i__ - 1 + (k + cc_dim2) * cc_dim1] + cr3;
+	    tr3 = cc[i__ - 1 + (k + cc_dim2) * cc_dim1] - cr3;
+	    ch[i__ - 1 + ((k << 2) + 1) * ch_dim1] = tr1 + tr2;
+	    ch[ic - 1 + ((k << 2) + 4) * ch_dim1] = tr2 - tr1;
+	    ch[i__ + ((k << 2) + 1) * ch_dim1] = ti1 + ti2;
+	    ch[ic + ((k << 2) + 4) * ch_dim1] = ti1 - ti2;
+	    ch[i__ - 1 + ((k << 2) + 3) * ch_dim1] = ti4 + tr3;
+	    ch[ic - 1 + ((k << 2) + 2) * ch_dim1] = tr3 - ti4;
+	    ch[i__ + ((k << 2) + 3) * ch_dim1] = tr4 + ti3;
+	    ch[ic + ((k << 2) + 2) * ch_dim1] = tr4 - ti3;
+/* L103: */
+	}
+/* L104: */
+    }
+    if (*ido % 2 == 1) {
+	return 0;
+    }
+L105:
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	ti1 = -hsqt2 * (cc[*ido + (k + (cc_dim2 << 1)) * cc_dim1] + cc[*ido + 
+		(k + (cc_dim2 << 2)) * cc_dim1]);
+	tr1 = hsqt2 * (cc[*ido + (k + (cc_dim2 << 1)) * cc_dim1] - cc[*ido + (
+		k + (cc_dim2 << 2)) * cc_dim1]);
+	ch[*ido + ((k << 2) + 1) * ch_dim1] = tr1 + cc[*ido + (k + cc_dim2) * 
+		cc_dim1];
+	ch[*ido + ((k << 2) + 3) * ch_dim1] = cc[*ido + (k + cc_dim2) * 
+		cc_dim1] - tr1;
+	ch[((k << 2) + 2) * ch_dim1 + 1] = ti1 - cc[*ido + (k + cc_dim2 * 3) *
+		 cc_dim1];
+	ch[((k << 2) + 4) * ch_dim1 + 1] = ti1 + cc[*ido + (k + cc_dim2 * 3) *
+		 cc_dim1];
+/* L106: */
+    }
+L107:
+    return 0;
+} /* dadf4_ */
+
+/*  ------ File dadf5.f ------ */
+/* Subroutine */ int dadf5_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, 
+	r_8 *wa1, r_8 *wa2, r_8 *wa3, r_8 *wa4)
+{
+    /* Initialized data */
+
+    static r_8 tr11 = .309016994374947f;
+    static r_8 ti11 = .951056516295154f;
+    static r_8 tr12 = -.809016994374947f;
+    static r_8 ti12 = .587785252292473f;
+
+    /* System generated locals */
+    int_4 cc_dim1, cc_dim2, cc_offset, ch_dim1, ch_offset, i__1, i__2;
+
+    /* Local variables */
+    static int_4 i__, k, ic;
+    static r_8 ci2, di2, ci4, ci5, di3, di4, di5, ci3, cr2, cr3, dr2, dr3, 
+	    dr4, dr5, cr5, cr4, ti2, ti3, ti5, ti4, tr2, tr3, tr4, tr5;
+    static int_4 idp2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_offset = ch_dim1 * 6 + 1;
+    ch -= ch_offset;
+    cc_dim1 = *ido;
+    cc_dim2 = *l1;
+    cc_offset = cc_dim1 * (cc_dim2 + 1) + 1;
+    cc -= cc_offset;
+    --wa1;
+    --wa2;
+    --wa3;
+    --wa4;
+
+    /* Function Body */
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	cr2 = cc[(k + cc_dim2 * 5) * cc_dim1 + 1] + cc[(k + (cc_dim2 << 1)) * 
+		cc_dim1 + 1];
+	ci5 = cc[(k + cc_dim2 * 5) * cc_dim1 + 1] - cc[(k + (cc_dim2 << 1)) * 
+		cc_dim1 + 1];
+	cr3 = cc[(k + (cc_dim2 << 2)) * cc_dim1 + 1] + cc[(k + cc_dim2 * 3) * 
+		cc_dim1 + 1];
+	ci4 = cc[(k + (cc_dim2 << 2)) * cc_dim1 + 1] - cc[(k + cc_dim2 * 3) * 
+		cc_dim1 + 1];
+	ch[(k * 5 + 1) * ch_dim1 + 1] = cc[(k + cc_dim2) * cc_dim1 + 1] + cr2 
+		+ cr3;
+	ch[*ido + (k * 5 + 2) * ch_dim1] = cc[(k + cc_dim2) * cc_dim1 + 1] + 
+		tr11 * cr2 + tr12 * cr3;
+	ch[(k * 5 + 3) * ch_dim1 + 1] = ti11 * ci5 + ti12 * ci4;
+	ch[*ido + (k * 5 + 4) * ch_dim1] = cc[(k + cc_dim2) * cc_dim1 + 1] + 
+		tr12 * cr2 + tr11 * cr3;
+	ch[(k * 5 + 5) * ch_dim1 + 1] = ti12 * ci5 - ti11 * ci4;
+/* L101: */
+    }
+    if (*ido == 1) {
+	return 0;
+    }
+    idp2 = *ido + 2;
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 3; i__ <= i__2; i__ += 2) {
+	    ic = idp2 - i__;
+	    dr2 = wa1[i__ - 2] * cc[i__ - 1 + (k + (cc_dim2 << 1)) * cc_dim1] 
+		    + wa1[i__ - 1] * cc[i__ + (k + (cc_dim2 << 1)) * cc_dim1];
+	    di2 = wa1[i__ - 2] * cc[i__ + (k + (cc_dim2 << 1)) * cc_dim1] - 
+		    wa1[i__ - 1] * cc[i__ - 1 + (k + (cc_dim2 << 1)) * 
+		    cc_dim1];
+	    dr3 = wa2[i__ - 2] * cc[i__ - 1 + (k + cc_dim2 * 3) * cc_dim1] + 
+		    wa2[i__ - 1] * cc[i__ + (k + cc_dim2 * 3) * cc_dim1];
+	    di3 = wa2[i__ - 2] * cc[i__ + (k + cc_dim2 * 3) * cc_dim1] - wa2[
+		    i__ - 1] * cc[i__ - 1 + (k + cc_dim2 * 3) * cc_dim1];
+	    dr4 = wa3[i__ - 2] * cc[i__ - 1 + (k + (cc_dim2 << 2)) * cc_dim1] 
+		    + wa3[i__ - 1] * cc[i__ + (k + (cc_dim2 << 2)) * cc_dim1];
+	    di4 = wa3[i__ - 2] * cc[i__ + (k + (cc_dim2 << 2)) * cc_dim1] - 
+		    wa3[i__ - 1] * cc[i__ - 1 + (k + (cc_dim2 << 2)) * 
+		    cc_dim1];
+	    dr5 = wa4[i__ - 2] * cc[i__ - 1 + (k + cc_dim2 * 5) * cc_dim1] + 
+		    wa4[i__ - 1] * cc[i__ + (k + cc_dim2 * 5) * cc_dim1];
+	    di5 = wa4[i__ - 2] * cc[i__ + (k + cc_dim2 * 5) * cc_dim1] - wa4[
+		    i__ - 1] * cc[i__ - 1 + (k + cc_dim2 * 5) * cc_dim1];
+	    cr2 = dr2 + dr5;
+	    ci5 = dr5 - dr2;
+	    cr5 = di2 - di5;
+	    ci2 = di2 + di5;
+	    cr3 = dr3 + dr4;
+	    ci4 = dr4 - dr3;
+	    cr4 = di3 - di4;
+	    ci3 = di3 + di4;
+	    ch[i__ - 1 + (k * 5 + 1) * ch_dim1] = cc[i__ - 1 + (k + cc_dim2) *
+		     cc_dim1] + cr2 + cr3;
+	    ch[i__ + (k * 5 + 1) * ch_dim1] = cc[i__ + (k + cc_dim2) * 
+		    cc_dim1] + ci2 + ci3;
+	    tr2 = cc[i__ - 1 + (k + cc_dim2) * cc_dim1] + tr11 * cr2 + tr12 * 
+		    cr3;
+	    ti2 = cc[i__ + (k + cc_dim2) * cc_dim1] + tr11 * ci2 + tr12 * ci3;
+	    tr3 = cc[i__ - 1 + (k + cc_dim2) * cc_dim1] + tr12 * cr2 + tr11 * 
+		    cr3;
+	    ti3 = cc[i__ + (k + cc_dim2) * cc_dim1] + tr12 * ci2 + tr11 * ci3;
+	    tr5 = ti11 * cr5 + ti12 * cr4;
+	    ti5 = ti11 * ci5 + ti12 * ci4;
+	    tr4 = ti12 * cr5 - ti11 * cr4;
+	    ti4 = ti12 * ci5 - ti11 * ci4;
+	    ch[i__ - 1 + (k * 5 + 3) * ch_dim1] = tr2 + tr5;
+	    ch[ic - 1 + (k * 5 + 2) * ch_dim1] = tr2 - tr5;
+	    ch[i__ + (k * 5 + 3) * ch_dim1] = ti2 + ti5;
+	    ch[ic + (k * 5 + 2) * ch_dim1] = ti5 - ti2;
+	    ch[i__ - 1 + (k * 5 + 5) * ch_dim1] = tr3 + tr4;
+	    ch[ic - 1 + (k * 5 + 4) * ch_dim1] = tr3 - tr4;
+	    ch[i__ + (k * 5 + 5) * ch_dim1] = ti3 + ti4;
+	    ch[ic + (k * 5 + 4) * ch_dim1] = ti4 - ti3;
+/* L102: */
+	}
+/* L103: */
+    }
+    return 0;
+} /* dadf5_ */
+
+/*  ------ File dadfg.f ------ */
+/* Subroutine */ int dadfg_(int_4 *ido, int_4 *ip, int_4 *l1, int_4 *
+	idl1, r_8 *cc, r_8 *c1, r_8 *c2, r_8 *ch, r_8 *ch2, r_8 *wa)
+{
+    /* Initialized data */
+
+    static r_8 tpi = 6.28318530717959f;
+
+    /* System generated locals */
+    int_4 ch_dim1, ch_dim2, ch_offset, cc_dim1, cc_dim2, cc_offset, c1_dim1,
+	     c1_dim2, c1_offset, c2_dim1, c2_offset, ch2_dim1, ch2_offset, 
+	    i__1, i__2, i__3;
+
+    /* Builtin functions */
+/*    r_8 cos(r_8truc), sin(r_8truc);   */
+
+    /* Local variables */
+    static int_4 idij, ipph, i__, j, k, l, j2, ic, jc, lc, ik, is;
+    static r_8 dc2, ai1, ai2, ar1, ar2, ds2;
+    static int_4 nbd;
+    static r_8 dcp, arg, dsp, ar1h, ar2h;
+    static int_4 idp2, ipp2;
+
+    /* Parameter adjustments */
+    ch_dim1 = *ido;
+    ch_dim2 = *l1;
+    ch_offset = ch_dim1 * (ch_dim2 + 1) + 1;
+    ch -= ch_offset;
+    c1_dim1 = *ido;
+    c1_dim2 = *l1;
+    c1_offset = c1_dim1 * (c1_dim2 + 1) + 1;
+    c1 -= c1_offset;
+    cc_dim1 = *ido;
+    cc_dim2 = *ip;
+    cc_offset = cc_dim1 * (cc_dim2 + 1) + 1;
+    cc -= cc_offset;
+    ch2_dim1 = *idl1;
+    ch2_offset = ch2_dim1 + 1;
+    ch2 -= ch2_offset;
+    c2_dim1 = *idl1;
+    c2_offset = c2_dim1 + 1;
+    c2 -= c2_offset;
+    --wa;
+
+    /* Function Body */
+    arg = tpi / (r_8) (*ip);
+    dcp = cos(arg);
+    dsp = sin(arg);
+    ipph = (*ip + 1) / 2;
+    ipp2 = *ip + 2;
+    idp2 = *ido + 2;
+    nbd = (*ido - 1) / 2;
+    if (*ido == 1) {
+	goto L119;
+    }
+    i__1 = *idl1;
+    for (ik = 1; ik <= i__1; ++ik) {
+	ch2[ik + ch2_dim1] = c2[ik + c2_dim1];
+/* L101: */
+    }
+    i__1 = *ip;
+    for (j = 2; j <= i__1; ++j) {
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    ch[(k + j * ch_dim2) * ch_dim1 + 1] = c1[(k + j * c1_dim2) * 
+		    c1_dim1 + 1];
+/* L102: */
+	}
+/* L103: */
+    }
+    if (nbd > *l1) {
+	goto L107;
+    }
+    is = -(*ido);
+    i__1 = *ip;
+    for (j = 2; j <= i__1; ++j) {
+	is += *ido;
+	idij = is;
+	i__2 = *ido;
+	for (i__ = 3; i__ <= i__2; i__ += 2) {
+	    idij += 2;
+	    i__3 = *l1;
+	    for (k = 1; k <= i__3; ++k) {
+		ch[i__ - 1 + (k + j * ch_dim2) * ch_dim1] = wa[idij - 1] * c1[
+			i__ - 1 + (k + j * c1_dim2) * c1_dim1] + wa[idij] * 
+			c1[i__ + (k + j * c1_dim2) * c1_dim1];
+		ch[i__ + (k + j * ch_dim2) * ch_dim1] = wa[idij - 1] * c1[i__ 
+			+ (k + j * c1_dim2) * c1_dim1] - wa[idij] * c1[i__ - 
+			1 + (k + j * c1_dim2) * c1_dim1];
+/* L104: */
+	    }
+/* L105: */
+	}
+/* L106: */
+    }
+    goto L111;
+L107:
+    is = -(*ido);
+    i__1 = *ip;
+    for (j = 2; j <= i__1; ++j) {
+	is += *ido;
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    idij = is;
+	    i__3 = *ido;
+	    for (i__ = 3; i__ <= i__3; i__ += 2) {
+		idij += 2;
+		ch[i__ - 1 + (k + j * ch_dim2) * ch_dim1] = wa[idij - 1] * c1[
+			i__ - 1 + (k + j * c1_dim2) * c1_dim1] + wa[idij] * 
+			c1[i__ + (k + j * c1_dim2) * c1_dim1];
+		ch[i__ + (k + j * ch_dim2) * ch_dim1] = wa[idij - 1] * c1[i__ 
+			+ (k + j * c1_dim2) * c1_dim1] - wa[idij] * c1[i__ - 
+			1 + (k + j * c1_dim2) * c1_dim1];
+/* L108: */
+	    }
+/* L109: */
+	}
+/* L110: */
+    }
+L111:
+    if (nbd < *l1) {
+	goto L115;
+    }
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    i__3 = *ido;
+	    for (i__ = 3; i__ <= i__3; i__ += 2) {
+		c1[i__ - 1 + (k + j * c1_dim2) * c1_dim1] = ch[i__ - 1 + (k + 
+			j * ch_dim2) * ch_dim1] + ch[i__ - 1 + (k + jc * 
+			ch_dim2) * ch_dim1];
+		c1[i__ - 1 + (k + jc * c1_dim2) * c1_dim1] = ch[i__ + (k + j *
+			 ch_dim2) * ch_dim1] - ch[i__ + (k + jc * ch_dim2) * 
+			ch_dim1];
+		c1[i__ + (k + j * c1_dim2) * c1_dim1] = ch[i__ + (k + j * 
+			ch_dim2) * ch_dim1] + ch[i__ + (k + jc * ch_dim2) * 
+			ch_dim1];
+		c1[i__ + (k + jc * c1_dim2) * c1_dim1] = ch[i__ - 1 + (k + jc 
+			* ch_dim2) * ch_dim1] - ch[i__ - 1 + (k + j * ch_dim2)
+			 * ch_dim1];
+/* L112: */
+	    }
+/* L113: */
+	}
+/* L114: */
+    }
+    goto L121;
+L115:
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	i__2 = *ido;
+	for (i__ = 3; i__ <= i__2; i__ += 2) {
+	    i__3 = *l1;
+	    for (k = 1; k <= i__3; ++k) {
+		c1[i__ - 1 + (k + j * c1_dim2) * c1_dim1] = ch[i__ - 1 + (k + 
+			j * ch_dim2) * ch_dim1] + ch[i__ - 1 + (k + jc * 
+			ch_dim2) * ch_dim1];
+		c1[i__ - 1 + (k + jc * c1_dim2) * c1_dim1] = ch[i__ + (k + j *
+			 ch_dim2) * ch_dim1] - ch[i__ + (k + jc * ch_dim2) * 
+			ch_dim1];
+		c1[i__ + (k + j * c1_dim2) * c1_dim1] = ch[i__ + (k + j * 
+			ch_dim2) * ch_dim1] + ch[i__ + (k + jc * ch_dim2) * 
+			ch_dim1];
+		c1[i__ + (k + jc * c1_dim2) * c1_dim1] = ch[i__ - 1 + (k + jc 
+			* ch_dim2) * ch_dim1] - ch[i__ - 1 + (k + j * ch_dim2)
+			 * ch_dim1];
+/* L116: */
+	    }
+/* L117: */
+	}
+/* L118: */
+    }
+    goto L121;
+L119:
+    i__1 = *idl1;
+    for (ik = 1; ik <= i__1; ++ik) {
+	c2[ik + c2_dim1] = ch2[ik + ch2_dim1];
+/* L120: */
+    }
+L121:
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    c1[(k + j * c1_dim2) * c1_dim1 + 1] = ch[(k + j * ch_dim2) * 
+		    ch_dim1 + 1] + ch[(k + jc * ch_dim2) * ch_dim1 + 1];
+	    c1[(k + jc * c1_dim2) * c1_dim1 + 1] = ch[(k + jc * ch_dim2) * 
+		    ch_dim1 + 1] - ch[(k + j * ch_dim2) * ch_dim1 + 1];
+/* L122: */
+	}
+/* L123: */
+    }
+
+    ar1 = 1.f;
+    ai1 = 0.f;
+    i__1 = ipph;
+    for (l = 2; l <= i__1; ++l) {
+	lc = ipp2 - l;
+	ar1h = dcp * ar1 - dsp * ai1;
+	ai1 = dcp * ai1 + dsp * ar1;
+	ar1 = ar1h;
+	i__2 = *idl1;
+	for (ik = 1; ik <= i__2; ++ik) {
+	    ch2[ik + l * ch2_dim1] = c2[ik + c2_dim1] + ar1 * c2[ik + (
+		    c2_dim1 << 1)];
+	    ch2[ik + lc * ch2_dim1] = ai1 * c2[ik + *ip * c2_dim1];
+/* L124: */
+	}
+	dc2 = ar1;
+	ds2 = ai1;
+	ar2 = ar1;
+	ai2 = ai1;
+	i__2 = ipph;
+	for (j = 3; j <= i__2; ++j) {
+	    jc = ipp2 - j;
+	    ar2h = dc2 * ar2 - ds2 * ai2;
+	    ai2 = dc2 * ai2 + ds2 * ar2;
+	    ar2 = ar2h;
+	    i__3 = *idl1;
+	    for (ik = 1; ik <= i__3; ++ik) {
+		ch2[ik + l * ch2_dim1] += ar2 * c2[ik + j * c2_dim1];
+		ch2[ik + lc * ch2_dim1] += ai2 * c2[ik + jc * c2_dim1];
+/* L125: */
+	    }
+/* L126: */
+	}
+/* L127: */
+    }
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	i__2 = *idl1;
+	for (ik = 1; ik <= i__2; ++ik) {
+	    ch2[ik + ch2_dim1] += c2[ik + j * c2_dim1];
+/* L128: */
+	}
+/* L129: */
+    }
+
+    if (*ido < *l1) {
+	goto L132;
+    }
+    i__1 = *l1;
+    for (k = 1; k <= i__1; ++k) {
+	i__2 = *ido;
+	for (i__ = 1; i__ <= i__2; ++i__) {
+	    cc[i__ + (k * cc_dim2 + 1) * cc_dim1] = ch[i__ + (k + ch_dim2) * 
+		    ch_dim1];
+/* L130: */
+	}
+/* L131: */
+    }
+    goto L135;
+L132:
+    i__1 = *ido;
+    for (i__ = 1; i__ <= i__1; ++i__) {
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    cc[i__ + (k * cc_dim2 + 1) * cc_dim1] = ch[i__ + (k + ch_dim2) * 
+		    ch_dim1];
+/* L133: */
+	}
+/* L134: */
+    }
+L135:
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	j2 = j + j;
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    cc[*ido + (j2 - 2 + k * cc_dim2) * cc_dim1] = ch[(k + j * ch_dim2)
+		     * ch_dim1 + 1];
+	    cc[(j2 - 1 + k * cc_dim2) * cc_dim1 + 1] = ch[(k + jc * ch_dim2) *
+		     ch_dim1 + 1];
+/* L136: */
+	}
+/* L137: */
+    }
+    if (*ido == 1) {
+	return 0;
+    }
+    if (nbd < *l1) {
+	goto L141;
+    }
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	j2 = j + j;
+	i__2 = *l1;
+	for (k = 1; k <= i__2; ++k) {
+	    i__3 = *ido;
+	    for (i__ = 3; i__ <= i__3; i__ += 2) {
+		ic = idp2 - i__;
+		cc[i__ - 1 + (j2 - 1 + k * cc_dim2) * cc_dim1] = ch[i__ - 1 + 
+			(k + j * ch_dim2) * ch_dim1] + ch[i__ - 1 + (k + jc * 
+			ch_dim2) * ch_dim1];
+		cc[ic - 1 + (j2 - 2 + k * cc_dim2) * cc_dim1] = ch[i__ - 1 + (
+			k + j * ch_dim2) * ch_dim1] - ch[i__ - 1 + (k + jc * 
+			ch_dim2) * ch_dim1];
+		cc[i__ + (j2 - 1 + k * cc_dim2) * cc_dim1] = ch[i__ + (k + j *
+			 ch_dim2) * ch_dim1] + ch[i__ + (k + jc * ch_dim2) * 
+			ch_dim1];
+		cc[ic + (j2 - 2 + k * cc_dim2) * cc_dim1] = ch[i__ + (k + jc *
+			 ch_dim2) * ch_dim1] - ch[i__ + (k + j * ch_dim2) * 
+			ch_dim1];
+/* L138: */
+	    }
+/* L139: */
+	}
+/* L140: */
+    }
+    return 0;
+L141:
+    i__1 = ipph;
+    for (j = 2; j <= i__1; ++j) {
+	jc = ipp2 - j;
+	j2 = j + j;
+	i__2 = *ido;
+	for (i__ = 3; i__ <= i__2; i__ += 2) {
+	    ic = idp2 - i__;
+	    i__3 = *l1;
+	    for (k = 1; k <= i__3; ++k) {
+		cc[i__ - 1 + (j2 - 1 + k * cc_dim2) * cc_dim1] = ch[i__ - 1 + 
+			(k + j * ch_dim2) * ch_dim1] + ch[i__ - 1 + (k + jc * 
+			ch_dim2) * ch_dim1];
+		cc[ic - 1 + (j2 - 2 + k * cc_dim2) * cc_dim1] = ch[i__ - 1 + (
+			k + j * ch_dim2) * ch_dim1] - ch[i__ - 1 + (k + jc * 
+			ch_dim2) * ch_dim1];
+		cc[i__ + (j2 - 1 + k * cc_dim2) * cc_dim1] = ch[i__ + (k + j *
+			 ch_dim2) * ch_dim1] + ch[i__ + (k + jc * ch_dim2) * 
+			ch_dim1];
+		cc[ic + (j2 - 2 + k * cc_dim2) * cc_dim1] = ch[i__ + (k + jc *
+			 ch_dim2) * ch_dim1] - ch[i__ + (k + j * ch_dim2) * 
+			ch_dim1];
+/* L142: */
+	    }
+/* L143: */
+	}
+/* L144: */
+    }
+    return 0;
+} /* dadfg_ */
+
+/*  ------ File dfftb.f ------ */
+/* Subroutine */ int dfftb_(int_4 *n, r_8 *r__, r_8 *wsave)
+{
+    extern /* Subroutine */ int dfftb1_(int_4 *, r_8 *, r_8 *, r_8 *, 
+	    int_8 *);
+
+    /* Parameter adjustments */
+    --wsave;
+    --r__;
+
+    /* Function Body */
+    if (*n == 1) {
+	return 0;
+    }
+    dfftb1_(n, &r__[1], &wsave[1], &wsave[*n + 1], (int_8 *)&wsave[(*n << 1) + 1]); /* (int *) rajoute Reza 29/11/99 */
+    return 0;
+} /* dfftb_ */
+
+/*  ------ File dfftb1.f ------ */
+/* Subroutine */ int dfftb1_(int_4 *n, r_8 *c__, r_8 *ch, r_8 *wa, 
+	int_8 *ifac)
+{
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Local variables */
+    extern /* Subroutine */ int dadb2_(int_4 *, int_4 *, r_8 *, r_8 *, 
+	    r_8 *), dadb3_(int_4 *, int_4 *, r_8 *, r_8 *, r_8 *, 
+	    r_8 *), dadb4_(int_4 *, int_4 *, r_8 *, r_8 *, r_8 *, 
+	    r_8 *, r_8 *), dadb5_(int_4 *, int_4 *, r_8 *, r_8 *, 
+	    r_8 *, r_8 *, r_8 *, r_8 *);
+    static int_4 i__;
+    extern /* Subroutine */ int dadbg_(int_4 *, int_4 *, int_4 *, 
+	    int_4 *, r_8 *, r_8 *, r_8 *, r_8 *, r_8 *, r_8 *);
+    static int_4 k1, l1, l2, na, nf, ip, iw, ix2, ix3, ix4, ido, idl1;
+
+    /* Parameter adjustments */
+    --ifac;
+    --wa;
+    --ch;
+    --c__;
+
+    /* Function Body */
+    nf = ifac[2];
+    na = 0;
+    l1 = 1;
+    iw = 1;
+    i__1 = nf;
+    for (k1 = 1; k1 <= i__1; ++k1) {
+	ip = ifac[k1 + 2];
+	l2 = ip * l1;
+	ido = *n / l2;
+	idl1 = ido * l1;
+	if (ip != 4) {
+	    goto L103;
+	}
+	ix2 = iw + ido;
+	ix3 = ix2 + ido;
+	if (na != 0) {
+	    goto L101;
+	}
+	dadb4_(&ido, &l1, &c__[1], &ch[1], &wa[iw], &wa[ix2], &wa[ix3]);
+	goto L102;
+L101:
+	dadb4_(&ido, &l1, &ch[1], &c__[1], &wa[iw], &wa[ix2], &wa[ix3]);
+L102:
+	na = 1 - na;
+	goto L115;
+L103:
+	if (ip != 2) {
+	    goto L106;
+	}
+	if (na != 0) {
+	    goto L104;
+	}
+	dadb2_(&ido, &l1, &c__[1], &ch[1], &wa[iw]);
+	goto L105;
+L104:
+	dadb2_(&ido, &l1, &ch[1], &c__[1], &wa[iw]);
+L105:
+	na = 1 - na;
+	goto L115;
+L106:
+	if (ip != 3) {
+	    goto L109;
+	}
+	ix2 = iw + ido;
+	if (na != 0) {
+	    goto L107;
+	}
+	dadb3_(&ido, &l1, &c__[1], &ch[1], &wa[iw], &wa[ix2]);
+	goto L108;
+L107:
+	dadb3_(&ido, &l1, &ch[1], &c__[1], &wa[iw], &wa[ix2]);
+L108:
+	na = 1 - na;
+	goto L115;
+L109:
+	if (ip != 5) {
+	    goto L112;
+	}
+	ix2 = iw + ido;
+	ix3 = ix2 + ido;
+	ix4 = ix3 + ido;
+	if (na != 0) {
+	    goto L110;
+	}
+	dadb5_(&ido, &l1, &c__[1], &ch[1], &wa[iw], &wa[ix2], &wa[ix3], &wa[
+		ix4]);
+	goto L111;
+L110:
+	dadb5_(&ido, &l1, &ch[1], &c__[1], &wa[iw], &wa[ix2], &wa[ix3], &wa[
+		ix4]);
+L111:
+	na = 1 - na;
+	goto L115;
+L112:
+	if (na != 0) {
+	    goto L113;
+	}
+	dadbg_(&ido, &ip, &l1, &idl1, &c__[1], &c__[1], &c__[1], &ch[1], &ch[
+		1], &wa[iw]);
+	goto L114;
+L113:
+	dadbg_(&ido, &ip, &l1, &idl1, &ch[1], &ch[1], &ch[1], &c__[1], &c__[1]
+		, &wa[iw]);
+L114:
+	if (ido == 1) {
+	    na = 1 - na;
+	}
+L115:
+	l1 = l2;
+	iw += (ip - 1) * ido;
+/* L116: */
+    }
+    if (na == 0) {
+	return 0;
+    }
+    i__1 = *n;
+    for (i__ = 1; i__ <= i__1; ++i__) {
+	c__[i__] = ch[i__];
+/* L117: */
+    }
+    return 0;
+} /* dfftb1_ */
+
+/*  ------ File dfftf.f ------ */
+/* Subroutine */ int dfftf_(int_4 *n, r_8 *r__, r_8 *wsave)
+{
+    extern /* Subroutine */ int dfftf1_(int_4 *, r_8 *, r_8 *, r_8 *, 
+	    int_8 *);
+
+    /* Parameter adjustments */
+    --wsave;
+    --r__;
+
+    /* Function Body */
+    if (*n == 1) {
+	return 0;
+    }
+    dfftf1_(n, &r__[1], &wsave[1], &wsave[*n + 1], (int_8 *)&wsave[(*n << 1) + 1]);/* (int *) rajoute Reza 29/11/99 */
+    return 0;
+} /* dfftf_ */
+
+/*  ------ File dfftf1.f ------ */
+/* Subroutine */ int dfftf1_(int_4 *n, r_8 *c__, r_8 *ch, r_8 *wa, 
+	int_8 *ifac)
+{
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Local variables */
+    extern /* Subroutine */ int dadf2_(int_4 *, int_4 *, r_8 *, r_8 *, 
+	    r_8 *), dadf3_(int_4 *, int_4 *, r_8 *, r_8 *, r_8 *, 
+	    r_8 *), dadf4_(int_4 *, int_4 *, r_8 *, r_8 *, r_8 *, 
+	    r_8 *, r_8 *), dadf5_(int_4 *, int_4 *, r_8 *, r_8 *, 
+	    r_8 *, r_8 *, r_8 *, r_8 *);
+    static int_4 i__;
+    extern /* Subroutine */ int dadfg_(int_4 *, int_4 *, int_4 *, 
+	    int_4 *, r_8 *, r_8 *, r_8 *, r_8 *, r_8 *, r_8 *);
+    static int_4 k1, l1, l2, na, kh, nf, ip, iw, ix2, ix3, ix4, ido, idl1;
+
+    /* Parameter adjustments */
+    --ifac;
+    --wa;
+    --ch;
+    --c__;
+
+    /* Function Body */
+    nf = ifac[2];
+    na = 1;
+    l2 = *n;
+    iw = *n;
+    i__1 = nf;
+    for (k1 = 1; k1 <= i__1; ++k1) {
+	kh = nf - k1;
+	ip = ifac[kh + 3];
+	l1 = l2 / ip;
+	ido = *n / l2;
+	idl1 = ido * l1;
+	iw -= (ip - 1) * ido;
+	na = 1 - na;
+	if (ip != 4) {
+	    goto L102;
+	}
+	ix2 = iw + ido;
+	ix3 = ix2 + ido;
+	if (na != 0) {
+	    goto L101;
+	}
+	dadf4_(&ido, &l1, &c__[1], &ch[1], &wa[iw], &wa[ix2], &wa[ix3]);
+	goto L110;
+L101:
+	dadf4_(&ido, &l1, &ch[1], &c__[1], &wa[iw], &wa[ix2], &wa[ix3]);
+	goto L110;
+L102:
+	if (ip != 2) {
+	    goto L104;
+	}
+	if (na != 0) {
+	    goto L103;
+	}
+	dadf2_(&ido, &l1, &c__[1], &ch[1], &wa[iw]);
+	goto L110;
+L103:
+	dadf2_(&ido, &l1, &ch[1], &c__[1], &wa[iw]);
+	goto L110;
+L104:
+	if (ip != 3) {
+	    goto L106;
+	}
+	ix2 = iw + ido;
+	if (na != 0) {
+	    goto L105;
+	}
+	dadf3_(&ido, &l1, &c__[1], &ch[1], &wa[iw], &wa[ix2]);
+	goto L110;
+L105:
+	dadf3_(&ido, &l1, &ch[1], &c__[1], &wa[iw], &wa[ix2]);
+	goto L110;
+L106:
+	if (ip != 5) {
+	    goto L108;
+	}
+	ix2 = iw + ido;
+	ix3 = ix2 + ido;
+	ix4 = ix3 + ido;
+	if (na != 0) {
+	    goto L107;
+	}
+	dadf5_(&ido, &l1, &c__[1], &ch[1], &wa[iw], &wa[ix2], &wa[ix3], &wa[
+		ix4]);
+	goto L110;
+L107:
+	dadf5_(&ido, &l1, &ch[1], &c__[1], &wa[iw], &wa[ix2], &wa[ix3], &wa[
+		ix4]);
+	goto L110;
+L108:
+	if (ido == 1) {
+	    na = 1 - na;
+	}
+	if (na != 0) {
+	    goto L109;
+	}
+	dadfg_(&ido, &ip, &l1, &idl1, &c__[1], &c__[1], &c__[1], &ch[1], &ch[
+		1], &wa[iw]);
+	na = 1;
+	goto L110;
+L109:
+	dadfg_(&ido, &ip, &l1, &idl1, &ch[1], &ch[1], &ch[1], &c__[1], &c__[1]
+		, &wa[iw]);
+	na = 0;
+L110:
+	l2 = l1;
+/* L111: */
+    }
+    if (na == 1) {
+	return 0;
+    }
+    i__1 = *n;
+    for (i__ = 1; i__ <= i__1; ++i__) {
+	c__[i__] = ch[i__];
+/* L112: */
+    }
+    return 0;
+} /* dfftf1_ */
+
+/*  ------ File dffti.f ------ */
+/* Subroutine */ int dffti_(int_4 *n, r_8 *wsave)
+{
+    extern /* Subroutine */ int dffti1_(int_4 *, r_8 *, int_8 *);
+
+    /* Parameter adjustments */
+    --wsave;
+
+    /* Function Body */
+    if (*n == 1) {
+	return 0;
+    }
+    dffti1_(n, &wsave[*n + 1], (int_8 *)&wsave[(*n << 1) + 1]); /* (int *) rajoute Reza 29/11/99 */
+    return 0;
+} /* dffti_ */
+
+/*  ------ File dffti1.f ------ */
+/* Subroutine */ int dffti1_(int_4 *n, r_8 *wa, int_8 *ifac)
+{
+    /* Initialized data */
+
+    static int_4 ntryh[4] = { 4,2,3,5 };
+
+    /* System generated locals */
+    int_4 i__1, i__2, i__3;
+
+    /* Builtin functions */
+/*    r_8 cos(r_8truc), sin(r_8truc); remplace par math.h  Reza 29/11/99 */
+
+    /* Local variables */
+    static r_8 argh;
+    static int_4 ntry, i__, j;
+    static r_8 argld;
+    static int_4 k1, l1, l2, ib;
+    static r_8 fi;
+    static int_4 ld, ii, nf, ip, nl, is, nq, nr;
+    static r_8 arg;
+    static int_4 ido, ipm;
+    static r_8 tpi;
+    static int_4 nfm1;
+
+    /* Parameter adjustments */
+    --ifac;
+    --wa;
+
+    /* Function Body */
+    nl = *n;
+    nf = 0;
+    j = 0;
+L101:
+    ++j;
+    if (j - 4 <= 0) {
+	goto L102;
+    } else {
+	goto L103;
+    }
+L102:
+    ntry = ntryh[j - 1];
+    goto L104;
+L103:
+    ntry += 2;
+L104:
+    nq = nl / ntry;
+    nr = nl - ntry * nq;
+    if (nr != 0) {
+	goto L101;
+    } else {
+	goto L105;
+    }
+L105:
+    ++nf;
+    ifac[nf + 2] = ntry;
+    nl = nq;
+    if (ntry != 2) {
+	goto L107;
+    }
+    if (nf == 1) {
+	goto L107;
+    }
+    i__1 = nf;
+    for (i__ = 2; i__ <= i__1; ++i__) {
+	ib = nf - i__ + 2;
+	ifac[ib + 2] = ifac[ib + 1];
+/* L106: */
+    }
+    ifac[3] = 2;
+L107:
+    if (nl != 1) {
+	goto L104;
+    }
+    ifac[1] = *n;
+    ifac[2] = nf;
+    tpi = 6.28318530717959f;
+    argh = tpi / (r_8) (*n);
+    is = 0;
+    nfm1 = nf - 1;
+    l1 = 1;
+    if (nfm1 == 0) {
+	return 0;
+    }
+    i__1 = nfm1;
+    for (k1 = 1; k1 <= i__1; ++k1) {
+	ip = ifac[k1 + 2];
+	ld = 0;
+	l2 = l1 * ip;
+	ido = *n / l2;
+	ipm = ip - 1;
+	i__2 = ipm;
+	for (j = 1; j <= i__2; ++j) {
+	    ld += l1;
+	    i__ = is;
+	    argld = (r_8) ld * argh;
+	    fi = 0.f;
+	    i__3 = ido;
+	    for (ii = 3; ii <= i__3; ii += 2) {
+		i__ += 2;
+		fi += 1.f;
+		arg = fi * argld;
+		wa[i__ - 1] = cos(arg);
+		wa[i__] = sin(arg);
+/* L108: */
+	    }
+	    is += ido;
+/* L109: */
+	}
+	l1 = l2;
+/* L110: */
+    }
+    return 0;
+} /* dffti1_ */
+
+/*  ------ File dsinqb.f ------ */
+/* Subroutine */ int dsinqb_(int_4 *n, r_8 *x, r_8 *wsave)
+{
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Local variables */
+    static int_4 k;
+    extern /* Subroutine */ int dcosqb_(int_4 *, r_8 *, r_8 *);
+    static r_8 xhold;
+    static int_4 kc, ns2;
+
+    /* Parameter adjustments */
+    --wsave;
+    --x;
+
+    /* Function Body */
+    if (*n > 1) {
+	goto L101;
+    }
+    x[1] *= 4.f;
+    return 0;
+L101:
+    ns2 = *n / 2;
+    i__1 = *n;
+    for (k = 2; k <= i__1; k += 2) {
+	x[k] = -x[k];
+/* L102: */
+    }
+    dcosqb_(n, &x[1], &wsave[1]);
+    i__1 = ns2;
+    for (k = 1; k <= i__1; ++k) {
+	kc = *n - k;
+	xhold = x[k];
+	x[k] = x[kc + 1];
+	x[kc + 1] = xhold;
+/* L103: */
+    }
+    return 0;
+} /* dsinqb_ */
+
+/*  ------ File dsinqf.f ------ */
+/* Subroutine */ int dsinqf_(int_4 *n, r_8 *x, r_8 *wsave)
+{
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Local variables */
+    static int_4 k;
+    extern /* Subroutine */ int dcosqf_(int_4 *, r_8 *, r_8 *);
+    static r_8 xhold;
+    static int_4 kc, ns2;
+
+    /* Parameter adjustments */
+    --wsave;
+    --x;
+
+    /* Function Body */
+    if (*n == 1) {
+	return 0;
+    }
+    ns2 = *n / 2;
+    i__1 = ns2;
+    for (k = 1; k <= i__1; ++k) {
+	kc = *n - k;
+	xhold = x[k];
+	x[k] = x[kc + 1];
+	x[kc + 1] = xhold;
+/* L101: */
+    }
+    dcosqf_(n, &x[1], &wsave[1]);
+    i__1 = *n;
+    for (k = 2; k <= i__1; k += 2) {
+	x[k] = -x[k];
+/* L102: */
+    }
+    return 0;
+} /* dsinqf_ */
+
+/*  ------ File dsinqi.f ------ */
+/* Subroutine */ int dsinqi_(int_4 *n, r_8 *wsave)
+{
+    extern /* Subroutine */ int dcosqi_(int_4 *, r_8 *);
+
+    /* Parameter adjustments */
+    --wsave;
+
+    /* Function Body */
+    dcosqi_(n, &wsave[1]);
+    return 0;
+} /* dsinqi_ */
+
+/*  ------ File dsint.f ------ */
+/* Subroutine */ int dsint_(int_4 *n, r_8 *x, r_8 *wsave)
+{
+    extern /* Subroutine */ int dsint1_(int_4 *, r_8 *, r_8 *, r_8 *, 
+	    r_8 *, int_8 *);
+    static int_4 np1, iw1, iw2, iw3;
+
+    /* Parameter adjustments */
+    --wsave;
+    --x;
+
+    /* Function Body */
+    np1 = *n + 1;
+    iw1 = *n / 2 + 1;
+    iw2 = iw1 + np1;
+    iw3 = iw2 + np1;
+    dsint1_(n, &x[1], &wsave[1], &wsave[iw1], &wsave[iw2], (int_8 *) &wsave[iw3]); /* (int *) rajoute Reza 29/11/99 */
+    return 0;
+} /* dsint_ */
+
+/*  ------ File dsint1.f ------ */
+/* Subroutine */ int dsint1_(int_4 *n, r_8 *war, r_8 *was, r_8 *xh, r_8 *
+	x, int_8 *ifac)
+{
+    /* Initialized data */
+
+    static r_8 sqrt3 = 1.73205080756888f;
+
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Local variables */
+    static int_4 modn, i__, k;
+    static r_8 xhold, t1, t2;
+    extern /* Subroutine */ int dfftf1_(int_4 *, r_8 *, r_8 *, r_8 *, 
+	    int_8 *);
+    static int_4 kc, np1, ns2;
+
+    /* Parameter adjustments */
+    --ifac;
+    --x;
+    --xh;
+    --was;
+    --war;
+
+    /* Function Body */
+    i__1 = *n;
+    for (i__ = 1; i__ <= i__1; ++i__) {
+	xh[i__] = war[i__];
+	war[i__] = x[i__];
+/* L100: */
+    }
+    if ((i__1 = *n - 2) < 0) {
+	goto L101;
+    } else if (i__1 == 0) {
+	goto L102;
+    } else {
+	goto L103;
+    }
+L101:
+    xh[1] += xh[1];
+    goto L106;
+L102:
+    xhold = sqrt3 * (xh[1] + xh[2]);
+    xh[2] = sqrt3 * (xh[1] - xh[2]);
+    xh[1] = xhold;
+    goto L106;
+L103:
+    np1 = *n + 1;
+    ns2 = *n / 2;
+    x[1] = 0.f;
+    i__1 = ns2;
+    for (k = 1; k <= i__1; ++k) {
+	kc = np1 - k;
+	t1 = xh[k] - xh[kc];
+	t2 = was[k] * (xh[k] + xh[kc]);
+	x[k + 1] = t1 + t2;
+	x[kc + 1] = t2 - t1;
+/* L104: */
+    }
+    modn = *n % 2;
+    if (modn != 0) {
+	x[ns2 + 2] = xh[ns2 + 1] * 4.f;
+    }
+    dfftf1_(&np1, &x[1], &xh[1], &war[1], &ifac[1]);
+    xh[1] = x[1] * .5f;
+    i__1 = *n;
+    for (i__ = 3; i__ <= i__1; i__ += 2) {
+	xh[i__ - 1] = -x[i__];
+	xh[i__] = xh[i__ - 2] + x[i__ - 1];
+/* L105: */
+    }
+    if (modn != 0) {
+	goto L106;
+    }
+    xh[*n] = -x[*n + 1];
+L106:
+    i__1 = *n;
+    for (i__ = 1; i__ <= i__1; ++i__) {
+	x[i__] = war[i__];
+	war[i__] = xh[i__];
+/* L107: */
+    }
+    return 0;
+} /* dsint1_ */
+
+/*  ------ File dsinti.f ------ */
+/* Subroutine */ int dsinti_(int_4 *n, r_8 *wsave)
+{
+    /* Initialized data */
+
+    static r_8 pi = 3.14159265358979f;
+
+    /* System generated locals */
+    int_4 i__1;
+
+    /* Builtin functions */
+/*    r_8 sin(r_8truc);  remplace par math.h  Reza 29/11/99 */
+
+    /* Local variables */
+    static int_4 k;
+    extern /* Subroutine */ int dffti_(int_4 *, r_8 *);
+    static r_8 dt;
+    static int_4 np1, ns2;
+
+    /* Parameter adjustments */
+    --wsave;
+
+    /* Function Body */
+    if (*n <= 1) {
+	return 0;
+    }
+    ns2 = *n / 2;
+    np1 = *n + 1;
+    dt = pi / (r_8) np1;
+    i__1 = ns2;
+    for (k = 1; k <= i__1; ++k) {
+	wsave[k] = sin(k * dt) * 2.f;
+/* L101: */
+    }
+    dffti_(&np1, &wsave[ns2 + 1]);
+    return 0;
+} /* dsinti_ */
+
Index: /tags/V_Dec2002/SophyaLib/NTools/fftpackc.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/fftpackc.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/fftpackc.h	(revision 2309)
@@ -0,0 +1,133 @@
+#ifndef FFTPACK_H_SEEN
+#define FFTPACK_H_SEEN
+
+#include "machdefs.h"
+/* #include "f2c.h" -- Remplace par ce qui suit */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+  /* typedef int integer;
+  typedef unsigned uinteger;
+  typedef char *address;
+  typedef short int shortint;
+  typedef float real;
+  typedef double doublereal;
+  typedef struct { float r, i; } complex;
+  typedef struct { double r, i; } doublecomplex;  */
+
+/* typedef int_4 logical;
+typedef short int shortlogical;
+typedef char logical1;
+typedef char integer1; */
+
+/* ---------------------- */
+
+extern int cfftb_(int_4 *n, r_4 *c__, r_4 *wsave);
+extern int cfftb1_(int_4 *n, r_4 *c__, r_4 *ch, r_4 *wa, int_4 *ifac);
+extern int cfftf_(int_4 *n, r_4 *c__, r_4 *wsave);
+extern int cfftf1_(int_4 *n, r_4 *c__, r_4 *ch, r_4 *wa, int_4 *ifac);
+extern int cffti_(int_4 *n, r_4 *wsave);
+extern int cffti1_(int_4 *n, r_4 *wa, int_4 *ifac);
+extern int cosqb_(int_4 *n, r_4 *x, r_4 *wsave);
+extern int cosqb1_(int_4 *n, r_4 *x, r_4 *w, r_4 *xh);
+extern int cosqf_(int_4 *n, r_4 *x, r_4 *wsave);
+extern int cosqf1_(int_4 *n, r_4 *x, r_4 *w, r_4 *xh);
+extern int cosqi_(int_4 *n, r_4 *wsave);
+extern int cost_(int_4 *n, r_4 *x, r_4 *wsave);
+extern int costi_(int_4 *n, r_4 *wsave);
+extern int ezfft1_(int_4 *n, r_4 *wa, int_4 *ifac);
+extern int ezfftb_(int_4 *n, r_4 *r__, r_4 *azero, r_4 *a, r_4 *b, r_4 *wsave);
+extern int ezfftf_(int_4 *n, r_4 *r__, r_4 *azero, r_4 *a, r_4 *b, r_4 *wsave);
+extern int ezffti_(int_4 *n, r_4 *wsave);
+extern int passb_(int_4 *nac, int_4 *ido, int_4 *ip, int_4 *l1, int_4 *idl1, r_4 *cc, r_4 *c1, r_4 *c2, r_4 *ch, r_4 *ch2, r_4 *wa);
+extern int passb2_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, r_4 *wa1);
+extern int passb3_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, r_4 *wa1, r_4 *wa2);
+extern int passb4_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, r_4 *wa1, r_4 *wa2, r_4 *wa3);
+extern int passb5_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, r_4 *wa1, r_4 *wa2, r_4 *wa3, r_4 *wa4);
+extern int passf_(int_4 *nac, int_4 *ido, int_4 *ip, int_4 *l1, int_4 *idl1, r_4 *cc, r_4 *c1, r_4 *c2, r_4 *ch, r_4 *ch2, r_4 *wa);
+extern int passf2_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, r_4 *wa1);
+extern int passf3_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, r_4 *wa1, r_4 *wa2);
+extern int passf4_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, r_4 *wa1, r_4 *wa2, r_4 *wa3);
+extern int passf5_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, r_4 *wa1, r_4 *wa2, r_4 *wa3, r_4 *wa4);
+extern int radb2_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, r_4 *wa1);
+extern int radb3_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, r_4 *wa1, r_4 *wa2);
+extern int radb4_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, r_4 *wa1, r_4 *wa2, r_4 *wa3);
+extern int radb5_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, r_4 *wa1, r_4 *wa2, r_4 *wa3, r_4 *wa4);
+extern int radbg_(int_4 *ido, int_4 *ip, int_4 *l1, int_4 *idl1, r_4 *cc, r_4 *c1, r_4 *c2, r_4 *ch, r_4 *ch2, r_4 *wa);
+extern int radf2_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, r_4 *wa1);
+extern int radf3_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, r_4 *wa1, r_4 *wa2);
+extern int radf4_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, r_4 *wa1, r_4 *wa2, r_4 *wa3);
+extern int radf5_(int_4 *ido, int_4 *l1, r_4 *cc, r_4 *ch, r_4 *wa1, r_4 *wa2, r_4 *wa3, r_4 *wa4);
+extern int radfg_(int_4 *ido, int_4 *ip, int_4 *l1, int_4 *idl1, r_4 *cc, r_4 *c1, r_4 *c2, r_4 *ch, r_4 *ch2, r_4 *wa);
+extern int rfftb_(int_4 *n, r_4 *r__, r_4 *wsave);
+extern int rfftb1_(int_4 *n, r_4 *c__, r_4 *ch, r_4 *wa, int_4 *ifac);
+extern int rfftf_(int_4 *n, r_4 *r__, r_4 *wsave);
+extern int rfftf1_(int_4 *n, r_4 *c__, r_4 *ch, r_4 *wa, int_4 *ifac);
+extern int rffti_(int_4 *n, r_4 *wsave);
+extern int rffti1_(int_4 *n, r_4 *wa, int_4 *ifac);
+extern int sinqb_(int_4 *n, r_4 *x, r_4 *wsave);
+extern int sinqf_(int_4 *n, r_4 *x, r_4 *wsave);
+extern int sinqi_(int_4 *n, r_4 *wsave);
+extern int sint_(int_4 *n, r_4 *x, r_4 *wsave);
+extern int sint1_(int_4 *n, r_4 *war, r_4 *was, r_4 *xh, r_4 *x, int_4 *ifac);
+extern int sinti_(int_4 *n, r_4 *wsave);
+
+/* ---------------------- */
+
+extern int cdfftb_(int_4 *n, r_8 *c__, r_8 *wsave);
+extern int cdfftb1_(int_4 *n, r_8 *c__, r_8 *ch, r_8 *wa, int_8 *ifac);
+extern int cdfftf_(int_4 *n, r_8 *c__, r_8 *wsave);
+extern int cdfftf1_(int_4 *n, r_8 *c__, r_8 *ch, r_8 *wa, int_8 *ifac);
+extern int cdffti_(int_4 *n, r_8 *wsave);
+extern int cdffti1_(int_4 *n, r_8 *wa, int_8 *ifac);
+extern int dcosqb_(int_4 *n, r_8 *x, r_8 *wsave);
+extern int dcosqb1_(int_4 *n, r_8 *x, r_8 *w, r_8 *xh);
+extern int dcosqf_(int_4 *n, r_8 *x, r_8 *wsave);
+extern int dcosqf1_(int_4 *n, r_8 *x, r_8 *w, r_8 *xh);
+extern int dcosqi_(int_4 *n, r_8 *wsave);
+extern int dcost_(int_4 *n, r_8 *x, r_8 *wsave);
+extern int dcosti_(int_4 *n, r_8 *wsave);
+extern int dezfft1_(int_4 *n, r_8 *wa, int_8 *ifac);
+extern int dezfftb_(int_4 *n, r_8 *r__, r_8 *azero, r_8 *a, r_8 *b, r_8 *wsave);
+extern int dezfftf_(int_4 *n, r_8 *r__, r_8 *azero, r_8 *a, r_8 *b, r_8 *wsave);
+extern int dezffti_(int_4 *n, r_8 *wsave);
+extern int dpassb_(int_4 *nac, int_4 *ido, int_4 *ip, int_4 *l1, int_4 *idl1, r_8 *cc, r_8 *c1, r_8 *c2, r_8 *ch, r_8 *ch2, r_8 *wa);
+extern int dpassb2_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, r_8 *wa1);
+extern int dpassb3_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, r_8 *wa1, r_8 *wa2);
+extern int dpassb4_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, r_8 *wa1, r_8 *wa2, r_8 *wa3);
+extern int dpassb5_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, r_8 *wa1, r_8 *wa2, r_8 *wa3, r_8 *wa4);
+extern int dpassf_(int_4 *nac, int_4 *ido, int_4 *ip, int_4 *l1, int_4 *idl1, r_8 *cc, r_8 *c1, r_8 *c2, r_8 *ch, r_8 *ch2, r_8 *wa);
+extern int dpassf2_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, r_8 *wa1);
+extern int dpassf3_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, r_8 *wa1, r_8 *wa2);
+extern int dpassf4_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, r_8 *wa1, r_8 *wa2, r_8 *wa3);
+extern int dpassf5_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, r_8 *wa1, r_8 *wa2, r_8 *wa3, r_8 *wa4);
+extern int dadb2_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, r_8 *wa1);
+extern int dadb3_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, r_8 *wa1, r_8 *wa2);
+extern int dadb4_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, r_8 *wa1, r_8 *wa2, r_8 *wa3);
+extern int dadb5_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, r_8 *wa1, r_8 *wa2, r_8 *wa3, r_8 *wa4);
+extern int dadbg_(int_4 *ido, int_4 *ip, int_4 *l1, int_4 *idl1, r_8 *cc, r_8 *c1, r_8 *c2, r_8 *ch, r_8 *ch2, r_8 *wa);
+extern int dadf2_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, r_8 *wa1);
+extern int dadf3_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, r_8 *wa1, r_8 *wa2);
+extern int dadf4_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, r_8 *wa1, r_8 *wa2, r_8 *wa3);
+extern int dadf5_(int_4 *ido, int_4 *l1, r_8 *cc, r_8 *ch, r_8 *wa1, r_8 *wa2, r_8 *wa3, r_8 *wa4);
+extern int dadfg_(int_4 *ido, int_4 *ip, int_4 *l1, int_4 *idl1, r_8 *cc, r_8 *c1, r_8 *c2, r_8 *ch, r_8 *ch2, r_8 *wa);
+extern int dfftb_(int_4 *n, r_8 *r__, r_8 *wsave);
+extern int dfftb1_(int_4 *n, r_8 *c__, r_8 *ch, r_8 *wa, int_8 *ifac);
+extern int dfftf_(int_4 *n, r_8 *r__, r_8 *wsave);
+extern int dfftf1_(int_4 *n, r_8 *c__, r_8 *ch, r_8 *wa, int_8 *ifac);
+extern int dffti_(int_4 *n, r_8 *wsave);
+extern int dffti1_(int_4 *n, r_8 *wa, int_8 *ifac);
+extern int dsinqb_(int_4 *n, r_8 *x, r_8 *wsave);
+extern int dsinqf_(int_4 *n, r_8 *x, r_8 *wsave);
+extern int dsinqi_(int_4 *n, r_8 *wsave);
+extern int dsint_(int_4 *n, r_8 *x, r_8 *wsave);
+extern int dsint1_(int_4 *n, r_8 *war, r_8 *was, r_8 *xh, r_8 *x, int_8 *ifac);
+extern int dsinti_(int_4 *n, r_8 *wsave);
+
+/* Rerunning f2c -P may change prototypes or declarations. */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*  FFTPACK_H_SEEN */
Index: /tags/V_Dec2002/SophyaLib/NTools/fftpserver.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/fftpserver.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/fftpserver.cc	(revision 2309)
@@ -0,0 +1,301 @@
+#include "fftpserver.h"
+#include "fftpackc.h"
+
+#include <iostream.h>
+
+
+/*! 
+  \class SOPHYA::FFTPackServer
+  \ingroup NTools
+  An implementation of FFTServerInterface based on fftpack, for 
+  one dimensional arrays.
+
+The class calls the c library ``fftpack'', which is accessible and documented
+at http://www.netlib.org/fftpack/.  However, the class functions do not
+necessarily correspond with the equivalent fftpack function.  For example,
+fftpack "forward" transformations are in fact inverse fourier transformations.
+
+Due to the way that fftpack manages
+its work arrays, an object can run faster if the length of the input arrays
+does not change.  For example, if you need to do a series of FFT's
+of differing length, it may be more efficient to create an fftserver object
+for each length.
+
+  \code
+  #include "fftpserver.h"
+  // ...
+  TVector<r_8> in(32);
+  TVector< complex<r_8> > out;
+  in = RandomSequence();
+  FFTPackServer ffts;
+  ffts.setNormalize(true);  // To have normalized transforms
+  cout << " FFTServer info string= " << ffts.getInfo() << endl;
+  cout << "in= " << in << endl;
+  cout << " Calling ffts.FFTForward(in, out) : " << endl;
+  ffts.FFTForward(in, out);
+  cout << "out= " << out << endl;
+  \endcode
+*/
+
+
+FFTPackServer::FFTPackServer()
+   : FFTServerInterface("FFTPackServer using extended FFTPack (C-version) package")
+  , ckR4("FFTPackServer: ", true, true) , ckR8("FFTPackServer: ", true, true)
+{
+//the working array and its size for the different
+//possible numerical types
+  sz_rfft = 0;     
+  ws_rfft = NULL;  
+  sz_dfft = 0;     
+  ws_dfft = NULL;  
+  sz_cfft = 0;
+  ws_cfft = NULL;
+  sz_cdfft = 0;
+  ws_cdfft = NULL;
+}
+
+FFTPackServer::~FFTPackServer()
+{
+if (ws_rfft) delete[] ws_rfft;
+if (ws_dfft) delete[] ws_dfft;
+if (ws_cfft) delete[] ws_cfft;
+if (ws_cdfft) delete[] ws_cdfft;
+}
+
+FFTServerInterface * FFTPackServer::Clone()
+{
+  return (new FFTPackServer);
+}
+
+
+void FFTPackServer::FFTForward(TArray< complex<r_8> > const & in, TArray< complex<r_8> > & out)
+{
+  ckR8.CheckResize(in, out);
+  out = in;
+  fftf(out.Size(), out.Data());
+  if (getNormalize()) out *= (1./(r_8)(in.Size()));
+}
+
+void FFTPackServer::FFTBackward(TArray< complex<r_8> > const & in, TArray< complex<r_8> > & out)
+{
+  ckR8.CheckResize(in, out);
+  out = in;
+  fftb(out.Size(), out.Data());
+}
+
+
+void FFTPackServer::FFTForward(TArray< complex<r_4> > const & in, TArray< complex<r_4> > & out)
+{
+  ckR4.CheckResize(in, out);  
+  out = in;
+  fftf(out.Size(), out.Data());
+  if (getNormalize()) out *= (1./(r_4)(in.Size()));
+}
+
+void FFTPackServer::FFTBackward(TArray< complex<r_4> > const & in, TArray< complex<r_4> > & out)
+{
+  ckR4.CheckResize(in, out);  
+  out = in;
+  fftb(out.Size(), out.Data());
+}
+
+void FFTPackServer::FFTForward(TArray< r_4 > const & in, TArray< complex<r_4> > & out)
+{
+  ckR4.CheckResize(in, out);  
+  TArray< r_4 > inout(in, false);
+  fftf(inout.Size(), inout.Data());
+  ReShapetoCompl(inout, out);
+  if (getNormalize()) out *= complex<r_4>((1./(r_4)(in.Size())), 0.);
+}
+
+void FFTPackServer::FFTBackward(TArray< complex<r_4> > const & in, TArray< r_4 > & out,
+				bool usoutsz)
+{
+  ckR4.CheckResize(in, out, usoutsz);    
+  ReShapetoReal(in, out);
+  fftb(out.Size(), out.Data());
+}
+
+
+void FFTPackServer::FFTForward(TArray< r_8 > const & in, TArray< complex<r_8> > & out)
+{
+  ckR8.CheckResize(in, out);  
+  TArray< r_8 > inout(in, false);
+  fftf(inout.Size(), inout.Data());
+  ReShapetoCompl(inout, out);
+  if (getNormalize()) out *= complex<r_8>((1./(r_8)(in.Size())), 0.);
+}
+
+void FFTPackServer::FFTBackward(TArray< complex<r_8> > const & in, TArray< r_8 > & out,
+				bool usoutsz)
+{
+  ckR8.CheckResize(in, out, usoutsz);  
+  ReShapetoReal(in, out);
+  fftb(out.Size(), out.Data());
+}
+
+
+template <class T>
+void FFTPack_ReShapetoReal(TArray< complex<T> > const & ina, TArray< T >  & outa)
+{
+  TVector< complex<T> > in(ina);
+  TVector< T > out(outa);
+  sa_size_t n = in.NElts();
+  T thr = FFTArrayChecker<T>::ZeroThreshold();
+  sa_size_t ncs = ( (in(n-1).imag() < -thr) || (in(n-1).imag() > thr) )
+                  ? 2*n-1 : 2*n-2;
+
+  if (out.NElts() != ncs) {
+     cerr << "DEBUG-FFTPack_ReShapetoReal() ncs = " << ncs 
+	  << " out.NElts()= " << out.NElts() << endl;
+    throw SzMismatchError("FFTPack_ReShapetoReal() - Wrong output array size !");
+  }
+
+  sa_size_t k;
+
+  out(0) = in(0).real();
+  for(k=1;k<n-1;k++) {
+    out(2*k-1) = in(k).real();
+    out(2*k) = in(k).imag();
+  }
+  if (ncs == n*2-2)  out(ncs-1) = in(n-1).real();
+  else { out(ncs-2) = in(n-1).real();  out(ncs-1) = in(n-1).imag(); }
+
+  return;
+}
+
+template <class T>
+void FFTPack_ReShapetoCompl(TArray< T > const & ina, TArray< complex<T> > & outa)
+{
+  TVector< T > in(ina);
+  TVector< complex<T> > out(outa);
+  sa_size_t n = in.NElts();
+  sa_size_t ncs = n/2+1;
+  sa_size_t nc = (n%2 != 0) ? n/2+1 : n/2;
+  if (out.NElts() != ncs) {
+    cerr << "DBG-ReShapetoCompl() ncs=" << ncs 
+	 << " out.NElts()= " << out.NElts() << endl;
+    throw SzMismatchError("FFTPack_ReShapetoCompl() - Wrong output array size !");
+  }
+  out(0) = complex<T> (in(0),0.);
+  for(int k=1;k<nc;k++)
+    out(k) =  complex<r_4> (in(2*k-1), in(2*k));
+  if (n%2 == 0) out(ncs-1) = complex<T>(in(n-1), 0.);
+
+  return;
+}
+
+void FFTPackServer::ReShapetoReal(TArray< complex<r_8> > const & in, TArray< r_8 >  & out)
+{
+  FFTPack_ReShapetoReal<r_8>(in, out);
+}
+
+void FFTPackServer::ReShapetoCompl(TArray< r_8 > const & in, TArray< complex<r_8> > & out)
+{
+  FFTPack_ReShapetoCompl<r_8>(in, out);
+}
+
+void FFTPackServer::ReShapetoReal(TArray< complex<r_4> > const & in, TArray< r_4 >  & out)
+{
+  FFTPack_ReShapetoReal<r_4>(in, out);
+}
+
+void FFTPackServer::ReShapetoCompl(TArray< r_4 > const & in, TArray< complex<r_4> > & out)
+{
+  FFTPack_ReShapetoCompl<r_4>(in, out);
+}
+
+void FFTPackServer::checkint_rfft(int_4 l)
+{
+  if (sz_rfft == l) return;       //checkint functions check and reallocate
+                                  //memory for the work arrays when performing
+  if (ws_rfft) delete[] ws_rfft;  //a transform
+  sz_rfft = l;
+  ws_rfft = new r_4[2*l+15];
+  rffti_(&l, ws_rfft);
+}
+
+void FFTPackServer::checkint_cfft(int_4 l)
+{
+  if (sz_cfft == l) return;
+
+  if (ws_cfft) delete[] ws_cfft;
+  sz_cfft = l;
+  ws_cfft = new r_4[4*l+15];
+  cffti_(&l, ws_cfft);
+}
+
+void FFTPackServer::checkint_dfft(int_4 l)
+{
+  if (sz_dfft == l) return;
+
+  if (ws_dfft) delete[] ws_dfft;
+  sz_dfft = l;
+  ws_dfft = new r_8[2*l+15];
+  dffti_(&l, ws_dfft);
+}
+
+void FFTPackServer::checkint_cdfft(int_4 l)
+{
+  if (sz_cdfft == l) return;
+
+  if (ws_cdfft) delete[] ws_cdfft;
+  sz_cdfft = l;
+  ws_cdfft = new r_8[4*l+15];
+  cdffti_(&l, ws_cdfft);
+}
+
+/* In general forward transformations are resorted since fftpack functions
+   return inverse transformations */
+
+void FFTPackServer::fftf(int_4 l, r_4* inout)
+{
+  checkint_rfft(l);
+  rfftf_(&l, inout, ws_rfft);
+  //  for (int k= 2;k<=(l+1)/2;k++) inout[2*k-2]=-inout[2*k-2];
+}
+
+void FFTPackServer::fftf(int_4 l, r_8* inout)
+{
+  checkint_dfft(l);
+  dfftf_(&l, inout, ws_dfft);
+  //  for (int k= 2;k<=(l+1)/2;k++) inout[2*k-2]=-inout[2*k-2];
+}
+
+void FFTPackServer::fftf(int_4 l, complex<r_4>* inout)
+{
+  checkint_cfft(l);
+  cfftf_(&l, (r_4 *)(inout), ws_cfft);
+}
+
+void FFTPackServer::fftf(int_4 l, complex<r_8>* inout)
+{
+  checkint_cdfft(l);
+  cdfftf_(&l, (r_8*)(inout), ws_cdfft);
+}
+
+void FFTPackServer::fftb(int_4 l, r_4* inout)
+{
+  checkint_rfft(l);
+  rfftb_(&l, inout, ws_rfft);
+}
+
+void FFTPackServer::fftb(int_4 l, r_8* inout)
+{
+  checkint_dfft(l);
+  dfftb_(&l, inout, ws_dfft);
+}
+
+void FFTPackServer::fftb(int_4 l, complex<r_4>* inout)
+{
+  checkint_cfft(l);
+  cfftb_(&l, (r_4 *)(inout), ws_cfft);
+}
+
+void FFTPackServer::fftb(int_4 l, complex<r_8>* inout)
+{
+  checkint_cdfft(l);
+  cdfftb_(&l, (r_8 *)(inout), ws_cdfft);
+}
+
+
Index: /tags/V_Dec2002/SophyaLib/NTools/fftpserver.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/fftpserver.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/fftpserver.h	(revision 2309)
@@ -0,0 +1,79 @@
+//   FFT (Fast Fourier Transform) Server based on FFTPack
+//        R. Ansari     1999-2000
+// DAPNIA/SPP (Saclay) / CEA    LAL - IN2P3/CNRS  (Orsay)
+
+#ifndef  FFTPServer_H_SEEN
+#define  FFTPServer_H_SEEN
+
+#include "fftservintf.h"
+
+// implementation de FFTServerInterface en utilisant FFTPack 
+
+namespace SOPHYA {
+
+//! An FFT server based on fftpack.
+class FFTPackServer : public FFTServerInterface {
+ public:
+  FFTPackServer();
+  virtual ~FFTPackServer();
+
+  // Implementation de l'interface FFTServerInterface
+
+  virtual FFTServerInterface * Clone();
+
+  // Transforme unidimensionnel sur des double
+  virtual void FFTForward(TArray< complex<r_8> > const & in, TArray< complex<r_8> > & out);
+  virtual void FFTBackward(TArray< complex<r_8> > const & in, TArray< complex<r_8> > & out);
+  virtual void FFTForward(TArray< r_8 > const & in, TArray< complex<r_8> > & out);
+  virtual void FFTBackward(TArray< complex<r_8> > const & in, TArray< r_8 > & out, 
+			   bool usoutsz=false);
+
+  // Transforme unidimensionnel sur des float
+  virtual void FFTForward(TArray< complex<r_4> > const & in, TArray< complex<r_4> > & out);
+  virtual void FFTBackward(TArray< complex<r_4> > const & in, TArray< complex<r_4> > & out);
+  virtual void FFTForward(TArray< r_4 > const & in, TArray< complex<r_4> > & out);
+  virtual void FFTBackward(TArray< complex<r_4> > const & in, TArray< r_4 > & out,
+			   bool usoutsz=false);
+
+// Methodes statiques pour reordonner les donnees
+  static void ReShapetoReal(TArray< complex<r_8> > const & in, TArray< r_8 >  & out);
+  static void ReShapetoCompl(TArray< r_8 > const & in, TArray< complex<r_8> > & out); 
+  static void ReShapetoReal(TArray< complex<r_4> > const & in, TArray< r_4 >  & out);
+  static void ReShapetoCompl(TArray< r_4 > const & in, TArray< complex<r_4> > & out); 
+
+  //  Methodes propres a cette classe
+  virtual void fftf(int_4 l, float* inout);
+  virtual void fftb(int_4 l, float* inout);
+  virtual void fftf(int_4 l, double* inout);
+  virtual void fftb(int_4 l, double* inout);
+  virtual void fftf(int_4 l, complex<float>* inout);
+  virtual void fftb(int_4 l, complex<float>* inout);
+  virtual void fftf(int_4 l, complex<double>* inout);
+  virtual void fftb(int_4 l, complex<double>* inout);
+
+ protected:
+  virtual void checkint_rfft(int_4 l);
+  virtual void checkint_dfft(int_4 l);
+  virtual void checkint_cfft(int_4 l);
+  virtual void checkint_cdfft(int_4 l);
+
+  int sz_rfft;
+  r_4* ws_rfft;
+
+  int sz_cfft;
+  r_4* ws_cfft;
+
+  int sz_dfft;
+  r_8* ws_dfft;
+
+  int sz_cdfft;
+  r_8* ws_cdfft;
+
+  FFTArrayChecker<r_4> ckR4;
+  FFTArrayChecker<r_8> ckR8;
+};
+
+} // Fin du namespace
+
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/fftservintf.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/fftservintf.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/fftservintf.cc	(revision 2309)
@@ -0,0 +1,407 @@
+#include "fftservintf.h"
+
+
+/*!
+  \class SOPHYA::FFTServerInterface
+  \ingroup NTools
+  Defines the interface for FFT (Fast Fourier Transform) operations.
+  Definitions : 
+    - Sampling period \b T
+    - Sampling frequency \b fs=1/T
+    - Total number of samples \b N
+    - Frequency step in Fourier space \b =fs/N=1/(N*T)
+    - Component frequencies
+        - k=0      ->  0
+	- k=1      ->  1/(N*T)
+	- k        ->  k/(N*T)
+	- k=N/2    ->  1/(2*T)   (Nyquist frequency)
+	- k>N/2    ->  k/(N*T)   (or negative frequency -(N-k)/(N*T))
+
+  For a sampling period T=1, the computed Fourier components correspond to :
+  \verbatim
+  0  1/N  2/N  ... 1/2  1/2+1/N  1/2+2/N ... 1-2/N  1-1/N
+  0  1/N  2/N  ... 1/2                   ...  -2/N   -1/N
+  \endverbatim
+
+  For complex one-dimensional transforms:
+  \f[
+  out(i) = F_{norm} \Sigma_{j} \ e^{-2 \pi \sqrt{-1} \ i \  j} \ {\rm (forward)}
+  \f]
+  \f[
+  out(i) = F_{norm} \Sigma_{j} \ e^{2 \pi \sqrt{-1} \ i \  j} \ {\rm (backward)}
+  \f]
+  i,j= 0..N-1 , where N is the input or the output array size.
+
+  For complex multi-dimensional transforms:
+  \f[
+  out(i1,i2,...,id) = F_{norm} \Sigma_{j1} \Sigma_{j2} ... \Sigma_{jd} \ 
+  e^{-2 \pi \sqrt{-1} \ i1 \ j1} ... e^{-2 \pi \sqrt{-1} \ id \ jd} \ {\rm (forward)}
+  \f]
+  \f[
+  out(i1,i2,...,id) = F_{norm} \Sigma_{j1} \Sigma_{j2} ... \Sigma_{jd} \ 
+  e^{2 \pi \sqrt{-1} \ i1 \ j1} ... e^{2 \pi \sqrt{-1} \ id \ jd} \ {\rm (backward)}
+  \f]
+
+  For real forward transforms, the input array is real, and
+  the output array complex, with Fourier components up to k=N/2.
+  For real backward transforms, the input array is complex and
+  the output array is real. 
+*/
+
+/* --Methode-- */
+FFTServerInterface::FFTServerInterface(string info)
+{
+  _info = info;
+  _fgnorm = true;
+}
+
+/* --Methode-- */
+FFTServerInterface::~FFTServerInterface()
+{
+}
+
+// ----------------- Transforme pour les double -------------------
+
+/* --Methode-- */
+//! Forward Fourier transform for double precision complex data 
+/*!
+  \param in : Input complex array
+  \param out : Output complex array
+ */
+void FFTServerInterface::FFTForward(TArray< complex<r_8> > const &, TArray< complex<r_8> > &)
+{
+  throw NotAvailableOperation("FFTServer::FFTForward(TArray...) Unsupported operation !");
+}
+
+/* --Methode-- */
+//! Backward (inverse) Fourier transform for double precision complex data 
+/*!
+  \param in : Input complex array
+  \param out : Output complex array
+ */
+void FFTServerInterface::FFTBackward(TArray< complex<r_8> > const &, TArray< complex<r_8> > &)
+{
+  throw NotAvailableOperation("FFTServer::FFTBackward(TArray...) Unsupported operation !");
+}
+
+/* --Methode-- */
+//! Forward Fourier transform for double precision real input data
+/*!
+  \param in : Input real array
+  \param out : Output complex array
+ */
+void FFTServerInterface::FFTForward(TArray< r_8 > const &, TArray< complex<r_8> > &)
+{
+  throw NotAvailableOperation("FFTServer::FFTForward(TArray...) Unsupported operation !");
+}
+
+/* --Methode-- */
+//! Backward (inverse) Fourier transform for double precision real output data 
+/*!
+  \param in : Input complex array
+  \param out : Output real array
+  \param usoutsz : if true, use the output array size for computing the inverse FFT.
+ */
+void FFTServerInterface::FFTBackward(TArray< complex<r_8> > const &, TArray< r_8 > &, bool)
+{
+  throw NotAvailableOperation("FFTServer::FFTBackward(TArray...) Unsupported operation !");
+}
+
+
+// ----------------- Transforme pour les float -------------------
+
+/* --Methode-- */
+//! Forward Fourier transform for complex data 
+/*!
+  \param in : Input complex array
+  \param out : Output complex array
+ */
+void FFTServerInterface::FFTForward(TArray< complex<r_4> > const &, TArray< complex<r_4> > &)
+{
+  throw NotAvailableOperation("FFTServer::FFTForward(TArray r_4 ... ) Unsupported operation !");
+}
+
+/* --Methode-- */
+//! Backward (inverse) Fourier transform for complex data 
+/*!
+  \param in : Input complex array
+  \param out : Output complex array
+ */
+void FFTServerInterface::FFTBackward(TArray< complex<r_4> > const &, TArray< complex<r_4> > &)
+{
+  throw NotAvailableOperation("FFTServer::FFTBackward(TArray r_4 ... ) Unsupported operation !");
+}
+
+/* --Methode-- */
+//! Forward Fourier transform for real input data
+/*!
+  \param in : Input real array
+  \param out : Output complex array
+ */
+void FFTServerInterface::FFTForward(TArray< r_4 > const &, TArray< complex<r_4> > &)
+{
+  throw NotAvailableOperation("FFTServer::FFTForward(TArray r_4 ... ) Unsupported operation !");
+}
+
+/* --Methode-- */
+//! Backward (inverse) Fourier transform for real output data 
+/*!
+  \param in : Input complex array
+  \param out : Output real array
+  \param usoutsz : if true, use the output array size for computing the inverse FFT.
+ */
+void FFTServerInterface::FFTBackward(TArray< complex<r_4> > const &, TArray< r_4 > &, bool)
+{
+  throw NotAvailableOperation("FFTServer::FFTBackward(TArray r_4 ... ) Unsupported operation !");
+}
+
+
+// ----------------- Transformation de normalisation pour les energies -------------------
+
+/* --Methode-- */
+//! Compute the transform to be applied to "fftx=FFT(x)" so that "x" and "FFT(x)" have the same energy
+/*!
+\return The factor to be applied to the FFT energy such that we get the same energy as for the x.
+\verbatim
+  fftx is computed by: FFTForward(x,fftx)
+  Energy of x    : Ex    = sum{|x(i)|^2}      i=0,x.Size()-1
+  Energy of fftx : Efftx = sum{|fftx(i)^2|}   i=0,fftx.Size()-1
+        ( usually x.Size() != fftx.Size() )
+  -------------------------------------------------------------------
+  |  TransfEnergyFFT return A and B such that : Ex = A * Efftx + B  |
+  |                  and Norm such that : Ex = Norm * Efftx         |
+  -------------------------------------------------------------------
+  To normalize the fftx vector apply : "fftx *= sqrt(Norm)"
+\endverbatim
+*/
+r_8 FFTServerInterface::TransfEnergyFFT
+     (TVector< complex<r_8> > const& x, TVector< complex<r_8> > const& fftx, r_8& A, r_8& B)
+{
+  B=0.;
+  if(getNormalize()) A = x.Size(); else A = 1./x.Size();
+  r_8 norm = A;
+  return norm;
+}
+
+//! Compute the transform to be applied to "fftx=FFT(x)" so that "x" and "FFT(x)" have the same energy
+r_8 FFTServerInterface::TransfEnergyFFT
+     (TVector< complex<r_4> > const & x, TVector< complex<r_4> > const & fftx, r_8& A, r_8& B)
+{
+  B=0.;
+  if(getNormalize()) A = x.Size(); else A = 1./x.Size();
+  r_8 norm = A;
+  return norm;
+}
+
+//! Compute the transform to be applied to "fftx=FFT(x)" so that "x" and "FFT(x)" have the same energy
+r_8 FFTServerInterface::TransfEnergyFFT
+     (TVector< r_8 > const & x, TVector< complex<r_8> > const & fftx, r_8& A, r_8& B)
+{
+  A= 2.;
+  B=  - abs(fftx(0)*fftx(0));
+  if(x.Size()%2 == 0) B -= abs(fftx(fftx.Size()-1)*fftx(fftx.Size()-1));
+  if(getNormalize()) {A *= x.Size(); B *= x.Size();}
+     else            {A /= x.Size(); B /= x.Size();}
+  r_8 norm = 0.;
+  for(int_4 i=0;i<fftx.Size();i++) norm += abs(fftx(i)*fftx(i));
+  if(norm>0.) norm = (A*norm+B)/norm;
+  return norm;
+}
+
+//! Compute the transform to be applied to "fftx=FFT(x)" so that "x" and "FFT(x)" have the same energy
+r_8 FFTServerInterface::TransfEnergyFFT
+     (TVector< r_4 > const & x, TVector< complex<r_4> > const & fftx, r_8& A, r_8& B)
+{
+  A= 2.;
+  B=  - abs(fftx(0)*fftx(0));
+  if(x.Size()%2 == 0) B -= abs(fftx(fftx.Size()-1)*fftx(fftx.Size()-1));
+  if(getNormalize()) {A *= x.Size(); B *= x.Size();}
+     else            {A /= x.Size(); B /= x.Size();}
+  r_8 norm = 0.;
+  for(int_4 i=0;i<fftx.Size();i++) norm += abs(fftx(i)*fftx(i));
+  if(norm>0.) norm = (A*norm+B)/norm;
+  return norm;
+}
+
+
+/* --Methode-- */
+/*!
+  \class SOPHYA::FFTArrayChecker
+  \ingroup NTools
+  Service class for checking array size and resizing output arrays,
+  to be used by FFTServer classes
+*/
+
+template <class T>
+FFTArrayChecker<T>::FFTArrayChecker(string msg, bool checkpack, bool onedonly)
+{
+  _msg = msg + " FFTArrayChecker::";
+  _checkpack = checkpack;
+  _onedonly = onedonly;
+}
+
+/* --Methode-- */
+template <class T>
+FFTArrayChecker<T>::~FFTArrayChecker()
+{
+}
+
+template <class T>
+T FFTArrayChecker<T>::ZeroThreshold()
+{
+  return(0);
+}
+
+r_8 FFTArrayChecker< r_8 >::ZeroThreshold()
+{
+  return(1.e-18);
+}
+
+r_4 FFTArrayChecker< r_4 >::ZeroThreshold()
+{
+  return(1.e-9);
+}
+
+/* --Methode-- */
+template <class T>
+int FFTArrayChecker<T>::CheckResize(TArray< complex<T> > const & in, TArray< complex<T> > & out)
+{
+  int k;
+  string msg;
+  if (in.Size() < 1) {
+    msg = _msg + "CheckResize(complex in, complex out) - Unallocated input array !";
+    throw(SzMismatchError(msg));
+  }
+  if (_checkpack) 
+    if ( !in.IsPacked() ) {
+      msg = _msg + "CheckResize(complex in, complex out) - Not packed input array !";
+      throw(SzMismatchError(msg));
+    }
+  int ndg1 = 0;
+  for(k=0; k<in.NbDimensions(); k++) 
+    if (in.Size(k) > 1)  ndg1++;
+  if (_onedonly) 
+    if (ndg1 > 1) {
+      msg = _msg + "CheckResize(complex in, complex out) - Only 1-D array accepted !";
+      throw(SzMismatchError(msg));
+    }
+  out.ReSize(in);
+  //  sa_size_t sz[BASEARRAY_MAXNDIMS];
+  //  for(k=0; k<in.NbDimensions(); k++) 
+  //    sz[k] = in.Size(k);
+  //  out.ReSize(in.NbDimensions(), sz);
+
+  return(ndg1);
+}
+
+/* --Methode-- */
+template <class T>
+int FFTArrayChecker<T>::CheckResize(TArray< T > const & in, TArray< complex<T> > & out)
+{
+  int k;
+  string msg;
+  if (in.Size() < 1) {
+    msg = _msg + "CheckResize(real in, complex out) - Unallocated input array !";
+    throw(SzMismatchError(msg));
+  }
+  if (_checkpack) 
+    if ( !in.IsPacked() ) {
+      msg = _msg + "CheckResize(real in, complex out) - Not packed input array !";
+      throw(SzMismatchError(msg));
+    }
+  int ndg1 = 0;
+  for(k=0; k<in.NbDimensions(); k++) 
+    if (in.Size(k) > 1)  ndg1++;
+  if (_onedonly) 
+    if (ndg1 > 1) {
+      msg = _msg + "CheckResize(real in, complex out) - Only 1-D array accepted !";
+      throw(SzMismatchError(msg));
+    }
+  sa_size_t sz[BASEARRAY_MAXNDIMS];
+  // 
+  if (ndg1 > 1) {
+    sz[0] = in.Size(0)/2+1; 
+    for(k=1; k<in.NbDimensions(); k++) 
+      sz[k] = in.Size(k); 
+  }
+  else {
+    for(k=0; k<BASEARRAY_MAXNDIMS; k++)  sz[k] = 1; 
+    sz[in.MaxSizeKA()] = in.Size(in.MaxSizeKA())/2+1;
+    //    sz[k] = in.Size(k)/2+1; 
+    //    sz[k] = (in.Size(k)%2 != 0) ? in.Size(k)/2+1 : in.Size(k)/2;
+  }
+  out.ReSize(in.NbDimensions(), sz);
+
+  return(ndg1);
+}
+
+/* --Methode-- */
+template <class T>
+int FFTArrayChecker<T>::CheckResize(TArray< complex<T> > const & in, TArray< T > & out, 
+				    bool usoutsz)
+{
+  int k;
+  string msg;
+  if (in.Size() < 1) {
+    msg = _msg + "CheckResize(complex in, real out) - Unallocated input array !";
+    throw(SzMismatchError(msg));
+  }
+  if (_checkpack) 
+    if ( !in.IsPacked() ) {
+      msg = _msg + "CheckResize(complex in, real out) - Not packed input array !";
+      throw(SzMismatchError(msg));
+    }
+  int ndg1 = 0;
+  for(k=0; k<in.NbDimensions(); k++) 
+    if (in.Size(k) > 1)  ndg1++;
+  if (_onedonly) 
+    if (ndg1 > 1) {
+      msg = _msg + "CheckResize(complex in, real out) - Only 1-D array accepted !";
+      throw(SzMismatchError(msg));
+    }
+  if (usoutsz) { // We have to use output array size 
+    bool fgerr = false;
+    if (ndg1 > 1) {
+      if (in.Size(0) != out.Size(0)/2+1) fgerr = true;
+    }      
+    else {
+      if (in.Size(in.MaxSizeKA()) != out.Size(in.MaxSizeKA())/2+1) fgerr = true;
+    }
+    if (fgerr) {
+	msg = _msg + "CheckResize(complex in, real out) - Incompatible in-out sizes !";
+	throw(SzMismatchError(msg));
+    }
+  }
+  else {  // We have to resize the output array 
+    sa_size_t sz[BASEARRAY_MAXNDIMS];
+    if (ndg1 > 1) {
+      sz[0] = 2*in.Size(0)-1;
+      for(k=1; k<in.NbDimensions(); k++) 
+	sz[k] = in.Size(k);
+    //      sz[k] = in.Size(k)*2-1;
+    }
+    else {
+      for(k=0; k<BASEARRAY_MAXNDIMS; k++)  sz[k] = 1; 
+      T thr = ZeroThreshold();
+      sa_size_t n = in.Size(in.MaxSizeKA());
+      sa_size_t ncs = ( (in[n-1].imag() < -thr) || (in[n-1].imag() > thr) )
+                      ? 2*n-1 : 2*n-2;
+      sz[in.MaxSizeKA()] = ncs;
+    }
+  out.ReSize(in.NbDimensions(), sz);
+  }
+
+  return(ndg1);
+
+}
+
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template FFTArrayChecker<r_4>
+#pragma define_template FFTArrayChecker<r_8>
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class FFTArrayChecker<r_4>;
+template class FFTArrayChecker<r_8>;
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/fftservintf.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/fftservintf.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/fftservintf.h	(revision 2309)
@@ -0,0 +1,107 @@
+//   FFT (Fast Fourier Transform) Server Interface
+//        R. Ansari     1999-2000
+// DAPNIA/SPP (Saclay) / CEA    LAL - IN2P3/CNRS  (Orsay)
+
+#ifndef  FFTServerIntf_H_SEEN
+#define  FFTServerIntf_H_SEEN
+
+#include "machdefs.h"
+#include "pexceptions.h"
+#include <complex>
+#include "tmatrix.h"
+#include "tvector.h"
+
+// Classe definissant l'interface pour les transformees de Fourier 
+// L'implementation par defaut est vide et lance une exception 
+
+namespace SOPHYA {
+
+class FFTServerInterface {
+ public:
+
+// Methodes de la classe 
+  FFTServerInterface(string info);
+  virtual ~FFTServerInterface();
+
+  
+  virtual FFTServerInterface * Clone() = 0;
+
+//! Set/clear the flag for normalizing Fourier transforms.
+  inline void setNormalize(bool fg=false) { _fgnorm = fg; }
+//! Returns the status of normalization flag for the server
+  inline bool getNormalize() const { return(_fgnorm); } 
+//! Returns the information string associated with the server
+  inline string getInfo() const { return _info; }
+
+  //---------------------------------------------------
+  // Transforme N-dim sur des doubles
+  virtual void FFTForward(TArray< complex<r_8> > const & in, TArray< complex<r_8> > & out);
+  virtual void FFTBackward(TArray< complex<r_8> > const & in, TArray< complex<r_8> > & out);
+  virtual r_8  TransfEnergyFFT(TVector< complex<r_8> > const & x, TVector< complex<r_8> > const& fftx
+                              , r_8& A, r_8& B);
+   //! Compute the factor to be applied to "fftx=FFT(x)" so that "x" and "FFT(x)" have the same energy
+  virtual inline r_8  TransfEnergyFFT(TVector< complex<r_8> > const & x, TVector< complex<r_8> > const& fftx)
+                      {r_8 A,B; return TransfEnergyFFT(x,fftx,A,B);}
+
+  virtual void FFTForward(TArray< r_8 > const & in, TArray< complex<r_8> > & out); 
+  virtual void FFTBackward(TArray< complex<r_8> > const & in, TArray< r_8 > & out, 
+			   bool usoutsz=false);
+  virtual r_8  TransfEnergyFFT(TVector< r_8 > const & x, TVector< complex<r_8> > const& fftx
+                              , r_8& A, r_8& B);
+   //! Compute the factor to be applied to "fftx=FFT(x)" so that "x" and "FFT(x)" have the same energy
+  virtual inline r_8  TransfEnergyFFT(TVector< r_8 > const & x, TVector< complex<r_8> > const& fftx)
+                      {r_8 A,B; return TransfEnergyFFT(x,fftx,A,B);}
+
+  // Transforme N-dim sur des float
+  virtual void FFTForward(TArray< complex<r_4> > const & in, TArray< complex<r_4> > & out);
+  virtual void FFTBackward(TArray< complex<r_4> > const & in, TArray< complex<r_4> > & out);
+  virtual r_8  TransfEnergyFFT(TVector< complex<r_4> > const & x, TVector< complex<r_4> > const& fftx
+                              , r_8& A, r_8& B);
+   //! Compute the factor to be applied to "fftx=FFT(x)" so that "x" and "FFT(x)" have the same energy
+  virtual inline r_8  TransfEnergyFFT(TVector< complex<r_4> > const & x, TVector< complex<r_4> > const& fftx)
+                      {r_8 A,B; return TransfEnergyFFT(x,fftx,A,B);}
+
+  virtual void FFTForward(TArray< r_4 > const & in, TArray< complex<r_4> > & out);
+  virtual void FFTBackward(TArray< complex<r_4> > const & in, TArray< r_4 > & out,
+			   bool usoutsz=false);
+  virtual r_8  TransfEnergyFFT(TVector< r_4 > const & x, TVector< complex<r_4> > const& fftx
+                              , r_8& A, r_8& B);
+   //! Compute the factor to be applied to "fftx=FFT(x)" so that "x" and "FFT(x)" have the same energy
+  virtual inline r_8  TransfEnergyFFT(TVector< r_4 > const & x, TVector< complex<r_4> > const& fftx)
+                      {r_8 A,B; return TransfEnergyFFT(x,fftx,A,B);}
+
+ protected:
+
+  bool _fgnorm;
+  string _info;
+  
+};
+
+
+template <class T> 
+class FFTArrayChecker {
+public:
+		FFTArrayChecker(string msg, bool checkpack=true, 
+				bool onedonly=false);
+  virtual	~FFTArrayChecker();
+  static T	ZeroThreshold();
+  
+  inline void	SetMsg(string const & msg) { _msg = msg; }
+  inline void	CheckPackedArray(bool ck=true) { _checkpack = ck; }
+  inline void	Accept1DOnly(bool ac1d=false) { _onedonly = ac1d; }
+
+  virtual int	CheckResize(TArray< complex<T> > const & in, TArray< complex<T> > & out);
+  virtual int	CheckResize(TArray< T > const & in, TArray< complex<T> > & out);
+  virtual int	CheckResize(TArray< complex<T> > const & in, TArray< T > & out, 
+			    bool usoutsz=false);
+
+protected:
+  string _msg;
+  bool _checkpack;
+  bool _onedonly;
+
+};
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/fmath.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/fmath.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/fmath.h	(revision 2309)
@@ -0,0 +1,36 @@
+/*    Declaration de fonctions math pour float   */
+
+#ifndef  FMATH_H_SEEN
+#define  FMATH_H_SEEN
+
+/* float math functions declarations using #define removed
+   to avoid compilation problems - Sophya code modified 
+   accordingly - 
+   C++ overloaded math functions should be used instead
+                                        R. Ansari
+
+if defined(OSF1)
+define   fexp(x)       expf(x)
+define   fsqrt(x)      sqrtf(x)
+define   flog10(x)     log10f(x)
+define   flog(x)       logf(x)
+elif !defined(IRIX64)
+define   fexp(x)     ((float)(exp((double)(x))))
+define   expf(x)     ((float)(exp((double)(x))))
+define   fabsf(x)    ((float)(fabs((double)(x))))
+define   fsqrt(x)    ((float)(sqrt((double)(x))))
+define   sqrtf(x)    ((float)(sqrt((double)(x))))
+define   flog10(x)   ((float)(log10((double)(x))))
+define   log10f(x)   ((float)(log10((double)(x))))
+define   flog(x)     ((float)(log((double)(x))))
+define   logf(x)     ((float)(log((double)(x))))
+define   floorf(x)   ((float) floor((double)(x)))
+define   ceilf(x)    ((float) ceil((double)(x)))
+define   powf(x,y)    ((float) pow((double)(x), (double)(y)))
+endif
+
+*/
+
+
+#endif
+
Index: /tags/V_Dec2002/SophyaLib/NTools/generaldata.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/generaldata.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/generaldata.cc	(revision 2309)
@@ -0,0 +1,1153 @@
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream.h>
+#ifndef NO_VALUES_H
+#include <values.h>
+#endif
+#include <math.h>
+#include <string.h>
+#include <string>
+
+#include "strutil.h"
+#include "nbtri.h"
+#include "generalfit.h"
+#include "generaldata.h"
+#include "pexceptions.h"
+#include "objfio.h"
+
+//================================================================
+// GeneralFitData
+//================================================================
+
+/*!
+  \class SOPHYA::GeneralFitData
+  \ingroup NTools
+  Classe de stoquage de donnees a plusieurs variables avec erreur
+  sur l'ordonnee et sur les abscisses (options) :
+
+  \f$ {x0(i),Ex0(i), x1(i),Ex1(i), x2(i),Ex2(i) ... ; Y(i),EY(i)} \f$
+  \verbatim
+   Pour memoire, structure du rangement (n=mNVar):
+   - Valeur des abscisses mXP (idem pour mErrXP):
+     x0,x1,x2,...,xn   x0,x1,x2,...,xn  ....  x0,x1,x2,....,xn
+     |  1er point  |   |  2sd point  |  ....  | point mNData |
+     Donc abscisse J=[0,mNVar[ du point numero I=[0,mNData[: mXP[I*mNVar+J]
+   - Valeur de l'ordonnee mF (idem pour mErr et mOK):
+            f                f                      f
+     |  1er point  |  |  2sd point  |  .... | point mNData |
+     Donc point numero I [0,mNData[ : mF[i]
+  \endverbatim
+*/
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Constructeur. ``nVar'' represente la dimension de l'espace des abscisses,
+  ``ndatalloc'' le nombre maximum de points et ``errx'' si non nul
+  indique que l'on fournit des erreurs sur les ``nVar'' variables en abscisse.
+*/
+GeneralFitData::GeneralFitData(unsigned int nVar, unsigned int ndatalloc, uint_2 errx)
+  : mNVar(0), mNDataAlloc(0), mNData(0), mNDataGood(0), mOk_EXP(0)
+  , mXP(NULL), mErrXP(NULL), mF(NULL), mErr(NULL), mOK(NULL)
+  , BuffVar(NULL), BuffVarR4(NULL)
+{
+try {
+  Alloc(nVar,ndatalloc,errx);
+} catch(PException e) {
+  cout << "Exception : " << typeid(e).name() << " " << e.Msg() << endl;
+  throw;
+}
+}
+
+/*!
+  Constructeur par copie. Si ``clean'' est ``true''
+  seules les donnees valides de ``data'' sont copiees.
+  Si ``clean'' est ``false'' (defaut) toutes les donnees
+  sont copiees et la taille totale de ``data'' est allouee
+  meme si elle est plus grande que la taille des donnees stoquees.
+*/
+GeneralFitData::GeneralFitData(const GeneralFitData& data, bool clean)
+  : mNVar(0), mNDataAlloc(0), mNData(0), mNDataGood(0), mOk_EXP(0)
+  , mXP(NULL), mErrXP(NULL), mF(NULL), mErr(NULL), mOK(NULL)
+  , BuffVar(NULL), BuffVarR4(NULL)
+{
+try {
+  Alloc(data.mNVar,((clean)?data.mNDataGood:data.mNDataAlloc),((data.mErrXP)?1:0));
+} catch(PException e) {
+  cout << "Exception : " << typeid(e).name() << " " << e.Msg() << endl;
+  throw;
+}
+
+ // Remplissage
+ if(data.mNData>0) {
+   r_8* ret;
+   for(int i=0;i<data.mNData;i++) {
+     if( clean && data.mOK[i]==0 ) continue;
+       ret = data.GetVec(i,NULL);
+       memcpy(mXP+mNData*mNVar,ret,mNVar*sizeof(r_8));
+       if(mErrXP) memcpy(mErrXP+mNData*mNVar,ret+mNVar,mNVar*sizeof(r_8));
+       mF[mNData]   = ret[2*mNVar];
+       mErr[mNData] = ret[2*mNVar+1];
+       mOK[mNData]  = (uint_2) (ret[2*mNVar+2]+0.001);
+       if(mOK[mNData]!=0) mNDataGood++;
+       mNData++;
+   }
+ }
+
+ END_CONSTRUCTOR
+}
+
+/*!
+  Constructeur par defaut.
+*/
+GeneralFitData::GeneralFitData()
+  : mNVar(0), mNDataAlloc(0), mNData(0), mNDataGood(0), mOk_EXP(0)
+  , mXP(NULL), mErrXP(NULL), mF(NULL), mErr(NULL), mOK(NULL)
+  , BuffVar(NULL), BuffVarR4(NULL)
+{
+ END_CONSTRUCTOR
+}
+
+/*!
+  Destructeur
+*/
+GeneralFitData::~GeneralFitData()
+{
+ Delete();
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Pour redefinir la structure de donnees (ou la creer si on a utilise
+  le createur par defaut). Voir les explications des arguments
+  dans les commentaires du constructeur. Si ``errx''\<0 alors
+  la valeur prise est celle definie auparavent.
+*/
+void GeneralFitData::Alloc(unsigned int nVar, unsigned int ndatalloc, int_2 errx)
+{
+ASSERT( nVar>0 && ndatalloc>0 );
+
+Delete();
+
+if(errx>=0) mOk_EXP = (uint_2) errx;
+mNVar = nVar;
+mNDataAlloc = ndatalloc;
+
+try {
+  mXP  = new r_8[nVar*ndatalloc];
+  if(mOk_EXP) mErrXP  = new r_8[nVar*ndatalloc];
+  mF   = new r_8[ndatalloc];
+  mErr = new r_8[ndatalloc];
+  mOK  = new uint_2[ndatalloc];
+  BuffVar   = new r_8[2*nVar+3];
+  BuffVarR4 = (r_4 *) BuffVar;
+} catch(PException e) {
+  throw(AllocationError("GeneralFitData::Alloc allocation error\n"));
+}
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+   Gestion des des-allocations
+*/
+void GeneralFitData::Delete()
+{
+mNVar = mNDataAlloc = mNData = mNDataGood = 0;
+if( mXP  != NULL ) {delete [] mXP;  mXP  = NULL;}
+if( mErrXP  != NULL ) {delete [] mErrXP;  mErrXP  = NULL;}
+if( mF   != NULL ) {delete [] mF;   mF   = NULL;}
+if( mErr != NULL ) {delete [] mErr; mErr = NULL;}
+if( mOK  != NULL ) {delete [] mOK;  mOK  = NULL;}
+if( BuffVar  != NULL ) {delete [] BuffVar; BuffVar = NULL; BuffVarR4 = NULL;}
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Remise a zero de la structure pour nouveau remplissage (pas d'arg)
+  ou remise a la position ``ptr'' (si arg). Les donnees apres ``ptr''
+  sont sur-ecrites.
+*/
+void GeneralFitData::SetDataPtr(int ptr)
+{
+ ASSERT(ptr >= 0 && ptr < mNDataAlloc);
+ mNData = ptr;
+ mNDataGood = 0;
+ if(ptr==0) return;
+ for(int i=0;i<mNData;i++) if(mOK[i]) mNDataGood++;
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Pour tuer un point
+*/
+void GeneralFitData::KillData(int i)
+{
+ ASSERT(i >= 0 && i < mNData);
+
+ if( ! mOK[i] ) return;
+ mOK[i] = 0;
+ mNDataGood--;
+}
+
+/*!
+  Pour tuer une serie de points
+*/
+void GeneralFitData::KillData(int i1,int i2)
+{
+ ASSERT(i1 >= 0 && i1 < mNData);
+ ASSERT(i2 >= 0 && i2 < mNData);
+ ASSERT(i1 <= i2 );
+
+ for(int i=i1;i<=i2;i++) KillData(i);
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Pour re-valider le point numero i ([0,NData]).
+*/
+void GeneralFitData::ValidData(int i)
+{
+ ASSERT(i >= 0 && i < mNData);
+
+ if( mOK[i] ) return;
+ if( mErr[i]<=0. ) return;
+ if(mOk_EXP) {
+   for(int j=0;j<mNVar;j++) if(mErrXP[i*mNVar+j]<=0.) return;
+ }
+ mOK[i] = 1;
+ mNDataGood++;
+}
+
+/*!
+  Pour re-valider les points numeros i1 a i2.
+*/
+void GeneralFitData::ValidData(int i1,int i2)
+{
+ ASSERT(i1 >= 0 && i1 < mNData);
+ ASSERT(i2 >= 0 && i2 < mNData);
+ ASSERT(i1 <= i2 );
+
+ for(int i=i1;i<=i2;i++) ValidData(i);
+}
+
+/*!
+  Pour re-valider tous les points.
+*/
+void GeneralFitData::ValidData()
+{
+ for(int i=0;i<mNData;i++) ValidData(i);
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Pour redefinir un point a \f$ {x,[errx] ; f,err} \f$
+*/
+void GeneralFitData::RedefineData1(int i,double x,double f,double err,double errx)
+{
+ RedefineData(i,&x,f,err,&errx);
+}
+
+/*!
+  Pour redefinir un point a \f$ {x,[errx], y,[erry] ; f,err} \f$ 
+*/
+void GeneralFitData::RedefineData2(int i,double x,double y,double f
+                                  ,double err,double errx,double erry)
+{
+ double xp[2] = {x,y};
+ double errxp[2] = {errx,erry};
+ RedefineData(i,xp,f,err,errxp);
+}
+
+/*!
+  Pour redefinir un point a
+  \f$ {xp[0],[errxp[0]], xp[1],[errxp[1]], xp[2],[errxp[2]],... ; f,err} \f$ 
+*/
+void GeneralFitData::RedefineData(int i,double* xp,double f,double err,double* errxp)
+{
+ ASSERT(i>=0 && i<mNData);
+ bool ok = true;
+
+ int ip = mNVar*i;
+ for(int j=0;j<mNVar;j++) mXP[ip+j] = xp[j];
+ if(mOk_EXP) {
+   if(errxp) {
+     for(int j=0;j<mNVar;j++)
+       {mErrXP[ip+j] = errxp[j]; if(errxp[j]<=0.) ok=false;}
+   } else {
+     for(int j=0;j<mNVar;j++) mErrXP[ip+j] = Def_ErrX;
+     ok=false;
+   }
+ }
+ mF[i] = f;
+ mErr[i] = err;  if(err<=0.) ok = false;
+ if(ok) {
+   if(! mOK[i]) {mOK[i]=1; mNDataGood++;}
+ } else {
+   if(  mOK[i]) {mOK[i]=0; mNDataGood--;}
+ }
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Pour ajouter un point \f$ {x,[errx] ; f,err} \f$
+*/
+void GeneralFitData::AddData1(double x, double f, double err, double errx)
+{
+ AddData(&x,f,err,&errx);
+}
+
+/*!
+  Pour ajouter un point \f$ {x,[errx], y,[erry] ; f,err} \f$ 
+*/
+void GeneralFitData::AddData2(double x, double y, double f
+                             , double err, double errx, double erry)
+{
+ double xp[2] = {x,y};
+ double errxp[2] = {errx,erry};
+ AddData(xp,f,err,errxp);
+}
+
+/*!
+  Pour ajouter un point
+  \f$ {xp[0],[errxp[0]], xp[1],[errxp[1]], xp[2],[errxp[2]],... ; f,err} \f$
+*/
+void GeneralFitData::AddData(double* xp, double f, double err,double* errxp)
+{
+ ASSERT(mNData < mNDataAlloc);
+ bool ok = true;
+
+ int ip = mNVar*mNData;
+ for(int i=0;i<mNVar;i++) mXP[ip+i] = xp[i];
+ if(mOk_EXP) {
+   if(errxp) {
+     for(int j=0;j<mNVar;j++)
+       {mErrXP[ip+j] = errxp[j]; if(errxp[j]<=0.) ok=false;}
+   } else {
+     for(int j=0;j<mNVar;j++) mErrXP[ip+j] = Def_ErrX;
+     ok=false;
+   }
+ }
+ mF[mNData] = f;
+ mErr[mNData] = err;
+ if(err<=0.) ok = false;
+ if(ok) { mOK[mNData]=1; mNDataGood++; } else mOK[mNData]=0;
+ mNData++;
+}
+
+/*!
+  Pour ajouter un point
+ \f$ {xp[0],[errxp[0]], xp[1],[errxp[1]], xp[2],[errxp[2]],... ; f,err} \f$ 
+*/
+void GeneralFitData::AddData(float* xp, float f, float err, float* errxp)
+{
+ {for(int i=0;i<mNVar;i++) BuffVar[i] = (double) xp[i];}
+ if(errxp) for(int i=0;i<mNVar;i++) BuffVar[mNVar+i] = (double) errxp[i];
+ AddData(BuffVar,(double) f,(double)  err,BuffVar+mNVar);
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Pour remplir la structure de donnees d'un seul coup avec
+  \f$ {x(i),[errx(i)] ; f(i),err(i)} \f$
+*/
+void GeneralFitData::SetData1(int nData
+            , double* x, double* f, double *err, double *errx)
+{
+ ASSERT(nData>0 && mNData+nData<=mNDataAlloc);
+
+ for(int i=0;i<nData;i++) {
+   double ex = (errx) ? errx[i]: Def_ErrX;
+   double ef = (err ) ? err[i]:  Def_ErrF;
+   AddData1(x[i],f[i],ef,ex);
+ }
+}
+
+/*!
+  Pour remplir la structure de donnees d'un seul coup avec
+  \f$ {x(i),[errx(i)] ; f(i),err(i)} \f$
+*/
+void GeneralFitData::SetData1(int nData
+            , float* x, float* f, float* err, float *errx)
+{
+ ASSERT(nData>0 && mNData+nData<=mNDataAlloc);
+
+ for(int i=0;i<nData;i++) {
+   double ex = (errx) ? (double) errx[i]: Def_ErrX;
+   double ef = (err ) ? (double) err[i]:  Def_ErrF;
+   AddData1((double) x[i],(double) f[i],ef,ex);
+ }
+}
+
+/*!
+  Pour remplir la structure de donnees d'un seul coup avec
+  \f$ {x(i),[errx(i)], y(i),[erry(i)], ; f(i),err(i)} \f$
+*/
+void GeneralFitData::SetData2(int nData, double* x, double* y, double* f
+                             ,double *err,double *errx,double *erry)
+{
+ ASSERT(nData>0 && mNData+nData<=mNDataAlloc);
+
+ for(int i=0;i<nData;i++) {
+   double ex = (errx) ? (double) errx[i]: Def_ErrX;
+   double ey = (erry) ? (double) erry[i]: Def_ErrX;
+   double ef = (err ) ? (double) err[i]:  Def_ErrF;
+   AddData2(x[i],y[i],f[i],ef,ex,ey);
+ }
+}
+
+/*!
+  Pour remplir la structure de donnees d'un seul coup avec
+ \f$ {x(i),[errx(i)], y(i),[erry(i)], ; f(i),err(i)} \f$
+*/
+void GeneralFitData::SetData2(int nData, float* x, float* y, float* f
+                             ,float *err,float *errx,float *erry)
+{
+ ASSERT(nData>0 && mNData+nData<=mNDataAlloc);
+
+ for(int i=0;i<nData;i++) {
+   double ex = (errx) ? (double) errx[i]: Def_ErrX;
+   double ey = (erry) ? (double) erry[i]: Def_ErrX;
+   double ef = (err ) ? (double) err[i]:  Def_ErrF;
+   AddData2((double) x[i],(double) y[i],(double) f[i],ef,ex,ey);
+ }
+}
+
+/*!
+  Pour remplir la structure de donnees d'un seul coup avec
+  \f$ {X0(i),[EX0(i)], X1(i),[EX1(i)], X2(i),[EX2(i)], ... ; F(i),Err(i)} \f$
+
+  Attention: si la structure est n'est pas vide, les tableaux sont copies
+  apres les donnees pre-existantes (qui ne sont donc pas detruites). Pour
+  effacer les donnees pre-existantes utiliser SetDataPtr(0).
+  \verbatim
+      Ici **xp est un pointeur sur un tableau de pointeurs tq
+        xp[0] = &X0[0], xp[1] = &X1[0], xp[2] = &X2[0] ...
+      ou X0,X1,X2,... sont les tableaux X0[nData] X1[nData] X2[nData] ...
+      des variables (meme commentaire pour errxp).
+  \endverbatim
+*/
+void GeneralFitData::SetData(int nData,double** xp, double *f
+                            , double *err, double** errxp)
+{
+ ASSERT(nData>0 && mNData+nData<=mNDataAlloc);
+ if(mOk_EXP && !errxp) {for(int j=0;j<mNVar;j++) BuffVar[mNVar+j] = Def_ErrX;}
+
+ for(int i=0;i<nData;i++) {
+   {for(int j=0;j<mNVar;j++) BuffVar[j] = *(xp[j]+i);}
+   if(mOk_EXP && errxp)
+     {for(int j=0;j<mNVar;j++) BuffVar[mNVar+j] = *(errxp[j]+i);}
+   double ef = (err) ? err[i]:  Def_ErrF;
+   AddData(BuffVar,f[i],ef,BuffVar+mNVar);
+ }
+}
+
+/*!
+  Voir commentaire ci-dessus.
+*/
+void GeneralFitData::SetData(int nData,float** xp, float *f
+                            , float *err, float** errxp)
+{
+ ASSERT(nData>0 && mNData+nData<=mNDataAlloc);
+
+ if(mOk_EXP && !errxp) {for(int j=0;j<mNVar;j++) BuffVar[mNVar+j] = Def_ErrX;}
+
+ for(int i=0;i<nData;i++) {
+   {for(int j=0;j<mNVar;j++) BuffVar[j] = (double) *(xp[j]+i);}
+   if(mOk_EXP && errxp)
+     {for(int j=0;j<mNVar;j++) BuffVar[mNVar+j] = (double) *(errxp[j]+i);}
+   double ef = (err) ? err[i]:  Def_ErrF;
+   AddData(BuffVar,(double) f[i],ef,BuffVar+mNVar);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Impression de l'etat de la structure de donnees
+*/
+void GeneralFitData::PrintStatus() const
+{
+  cout<<"GeneralFitData:: "<<endl
+      <<"NVar="<<mNVar<<" NDataAlloc="<<mNDataAlloc<<" Ok_EXP="<<mOk_EXP
+      <<" ,NData="<<mNData<<" NDataGood="<<mNDataGood<<endl
+      <<"  mXP="<<mXP<<"  [mErrXP="<<mErrXP<<"] mF="<<mF<<" mErr="<<mErr
+      <<" mOK="<<mOK<<endl;
+}
+
+/*!
+  Impression du point i
+*/
+void GeneralFitData::PrintData(int i) const
+{
+ ASSERT(i>=0 && i<mNData);
+
+ cout<<" "<<i<<" F( ";
+ {for(int j=0;j<mNVar;j++) cout<<" "<<Absc(j,i);}
+ if(mOk_EXP) {
+   cout<<"  ;  ";
+   for(int j=0;j<mNVar;j++) cout<<" "<<EAbsc(j,i);
+ }
+ cout<<")= "<<Val(i)<<" "<<EVal(i)<<" ("<<IsValid(i)<<")\n";
+}
+
+/*!
+  Impression des points i1 a i2
+*/
+void GeneralFitData::PrintData(int i1,int i2) const
+{
+ if(i1<0) i1=0;
+ if(i1>=mNData) i1 = mNData-1;
+ if(i2>=mNData) i2 = mNData-1;
+ if(i1>i2) i2 = mNData-1;
+
+ cout<<"GeneralFitData::PrintData[NData="
+     <<mNData<<"/ NDataGood="<<mNDataGood<<"]"<<endl;
+ for(int i=i1;i<=i2;i++) PrintData(i);
+ cout<<flush;
+}
+
+/*!
+  Impression de tous les points
+*/
+void GeneralFitData::PrintData() const
+{
+ ASSERT(mNData>0);
+
+ PrintData(0,mNData-1);
+}
+
+/*!
+  Impression de l'etat de la structure de donnees avec bornes sur "s"
+*/
+void GeneralFitData::Show(ostream& os) const
+{
+double min,max;
+os<<"GeneralFitData:: NVar,ErrX="<<mNVar<<","<<mOk_EXP
+  <<" Data: "<<mNData<<" Good,Alloc="<<mNDataGood<<","<<mNDataAlloc<<endl;
+for(int k=0;k<2*NVar()+3;k++) {
+  GetMinMax(k,min,max);
+  os<<" - "<<k<<" "<<ColumnName(k)<<"  ,  "<<min<<","<<max<<endl;
+}
+return;
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Retourne les numeros des points de valeurs minimum et maximum
+  de la variable ``var'':
+  \verbatim
+    La variable "var" est de la forme : var = AB avec
+     B = 0 : variable d'ordonnee Y (valeur de A indifferente)
+     B = 1 : erreur variable d'ordonnee EY (valeur de A indifferente)
+     B = 2 : variable d'abscisse X numero A #[0,NVar[
+     B = 3 : erreur variable d'abscisse EX numero A #[0,NVar[
+    - Return NData checked si ok, -1 si probleme.
+  \endverbatim
+*/
+int GeneralFitData::GetMnMx(int var,int& imin,int& imax) const
+{
+imin = imax = -1;
+int ix = var/10;
+var = var%10;
+if(var<0 || var>3) return -1;
+if(var>=2 && (ix<0 || ix>=mNVar) ) return -1;
+double min=1., max=-1.;
+int ntest = 0;
+for(int i=0;i<mNData;i++) {
+  if( ! IsValid(i) ) continue;
+  double v;
+  if(var==1)          v = EVal(i);
+    else if(var==2)   v = Absc(ix,i);
+      else if(var==3) v = EAbsc(ix,i);
+        else          v = Val(i);
+  if(ntest==0) {min = max = v; imin = imax = i;}
+  if(v<min) {min = v; imin = i;}
+  if(v>max) {max = v; imax = i;}
+  ntest++;
+}
+return ntest;
+}
+
+/*!
+  Retourne le minimum et le maximum de la variable ``var''
+  (cf commentaires GetMnMx).
+*/
+int GeneralFitData::GetMnMx(int var,double& min,double& max) const
+{
+min = 1.; max = -1.;
+int imin,imax;
+int ntest = GetMnMx(var,imin,imax);
+if(ntest<=0) return ntest;
+int ix = var/10;
+var = var%10;
+if(var==0) {
+  if(imin>=0) min = Val(imin);
+  if(imax>=0) max = Val(imax);
+} else if(var==1) {
+  if(imin>=0) min = EVal(imin);
+  if(imax>=0) max = EVal(imax);
+} else if(var==2) {
+  if(imin>=0) min = Absc(ix,imin);
+  if(imax>=0) max = Absc(ix,imax);
+} else if(var==3) {
+  if(imin>=0) min = EAbsc(ix,imin);
+  if(imax>=0) max = EAbsc(ix,imax);
+}
+return ntest;
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+//
+  Retourne la moyenne et le sigma de la variable ``var''
+  (cf commentaires GetMnMx).
+  \verbatim
+    - Return : nombre de donnees utilisees, -1 si pb, -2 si sigma<0.
+    - Seuls les points valides de valeur entre min,max sont utilises.
+      Si min>=max pas de coupures sur les valeurs.
+  \endverbatim
+*/
+int GeneralFitData::GetMeanSigma(int var,double& mean,double& sigma,double min,double max) const
+{
+mean = sigma = 0.;
+int ix = var/10;
+var = var%10;
+if(var<0 || var>3) return -1;
+if(var>=2 && (ix<0 || ix>=mNVar) ) return -1;
+int ntest = 0;
+for(int i=0;i<mNData;i++) {
+  if( ! IsValid(i) ) continue;
+  double v;
+  if(var==1)          v = EVal(i);
+    else if(var==2)   v = Absc(ix,i);
+      else if(var==3) v = EAbsc(ix,i);
+        else          v = Val(i);
+  if(min<max && (v<min || max<v)) continue;
+  mean += v;
+  sigma += v*v;
+  ntest++;
+}
+if(ntest==0) {
+  mean = sigma = 0.;
+} else {
+  mean /= (double)ntest;
+  sigma = sigma/(double)ntest - mean*mean;
+  if(sigma<0.) ntest = -2;
+  else if(sigma>0.) sigma = sqrt(sigma);
+}
+return ntest;
+}
+
+/*!
+  Retourne le mode de la variable ``var''
+  (cf commentaires GetMnMx).
+  \verbatim
+    - Return : nombre de donnees utilisees, -1 si pb.
+    - Seuls les points valides de valeur entre min,max sont utilises.
+      Si min>=max pas de coupures sur les valeurs.
+    - Le calcul du mode est approximee par la formule:
+        Mode = Median - coeff*(Mean-Median)   (def: coeff=0.8)
+    - Kendall and Stuart donne coeff=2., mais coeff peut etre regle.
+  \endverbatim
+*/
+int GeneralFitData::GetMoMeMed(int var,double& mode,double& mean,double& median,
+                               double min,double max,double coeff) const
+{
+mode = mean = median = 0.;
+if(mNData<=0) return -1;
+int ix = var/10;
+var = var%10;
+if(var<0 || var>3) return -1;
+if(var>=2 && (ix<0 || ix>=mNVar) ) return -1;
+double* buff = new double[mNData];
+int ntest = 0;
+for(int i=0;i<mNData;i++) {
+  if( ! IsValid(i) ) continue;
+  double v;
+  if(var==1)          v = EVal(i);
+    else if(var==2)   v = Absc(ix,i);
+      else if(var==3) v = EAbsc(ix,i);
+        else          v = Val(i);
+  if(min<max && (v<min || max<v)) continue;
+  buff[ntest] = v;
+  mean += v;
+  ntest++;
+}
+if(ntest==0) {
+  mean = 0.;
+} else {
+  mean /= (double)ntest;
+  qsort(buff,(size_t) ntest,sizeof(double),qSort_Dble);
+  int im;
+  if(ntest%2==1) {
+    // nombre impair de points
+    im = ntest/2;
+    median = buff[im];
+  } else {
+    // nombre pair de points
+    im = (ntest-1)/2;
+    median = (buff[im]+buff[im+1])/2.;
+  }
+  mode = median - coeff*(mean-median);
+}
+delete [] buff;
+return ntest;
+}
+
+/*!
+  Cf description ci-dessus ``GetMoMeMed''.
+*/
+int GeneralFitData::GetMode(int var,double& mode,double min,double max,double coeff) const
+{
+double mean,median;
+return GetMoMeMed(var,mode,mean,median,min,max,coeff);
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Pour fiter un polynome de degre ``degre''. On fite
+  Y=f(X-xc) ou Y=Val et X=Absc(varx). Si ``ey'' est ``true''
+  le fit prend en compte les erreurs stoquees dans EVal,
+  sinon fit sans erreurs. Le resultat du fit est retourne
+  dans le polynome ``pol''. On re-centre les abscisses X de ``xc''.
+  \verbatim
+  Return:
+     -   Res = le residu du fit
+     -   -1 si degre<0
+     -   -2 si probleme sur numero de variable X
+     -   -4 si NDataGood<0
+     -   -5 si nombre de data trouves differents de NDataGood
+  \endverbatim
+*/
+double GeneralFitData::PolFit(int varx,Poly& pol,int degre,bool ey,double xc) const
+{
+if(degre<0) return -1.;
+if(varx<0 || varx>=mNVar) return -2.;
+if(mNDataGood<=0) return -4.;
+TVector<r_8> x(mNDataGood);
+TVector<r_8> y(mNDataGood);
+TVector<r_8> ey2(1);
+if(ey) ey2.Realloc(mNDataGood,true);
+int ntest = 0;
+for(int i=0;i<mNData;i++) {
+  if( ! IsValid(i) ) continue;
+  if(ntest>=mNDataGood) return -5.;
+  x(ntest) = Absc(varx,i) - xc;
+  y(ntest) = Val(i);
+  if(ey) ey2(ntest) = EVal(i)*EVal(i);
+  ntest++;
+}
+double res = 0.;
+if(ey) {
+  TVector<r_8> errcoef(1);
+  res = pol.Fit(x,y,ey2,degre,errcoef);
+} else {
+  res = pol.Fit(x,y,degre);
+}
+return res;
+}
+
+/*!
+  Pour fiter un polynome de degre ``degre1''. On fite
+  Z=f(X-xc,Y-yc) ou Z=Val et X=Absc(varx) et Y=Absc(vary).
+  Si ``ey'' est ``true'' le fit prend en compte les erreurs
+  stoquees dans EVal, sinon fit sans erreurs. Si ``degre2''
+  negatif, le fit determine un polynome en X,Y de degre
+  total ``degre`''. Si ``degre2'' positif ou nul, le fit
+  demande un fit de ``degre1'' pour la variable X et de degre
+  ``degre2'' sur la variable Y. Le resultat du fit est retourne
+  dans le polynome ``pol''. On re-centre les abscisses X de ``xc''
+  et Y de ``yc''.
+  \verbatim
+    Return:
+     -   Res = le residu du fit
+     -   -1 si degre<0
+     -   -2 si probleme sur numero de variable X
+     -   -3 si probleme sur numero de variable Y
+     -   -4 si NDataGood<0
+     -   -5 si nombre de data trouves different de NDataGood
+  \endverbatim
+*/
+double GeneralFitData::PolFit(int varx,int vary,Poly2& pol,int degre1,int degre2,bool ez
+                             ,double xc,double yc) const
+{
+if(degre1<0) return -1.;
+if(varx<0 || varx>=mNVar) return -2.;
+if(vary<0 || vary>=mNVar || vary==varx) return -3.;
+if(mNDataGood<=0) return -4.;
+TVector<r_8> x(mNDataGood);
+TVector<r_8> y(mNDataGood);
+TVector<r_8> z(mNDataGood);
+TVector<r_8> ez2(1);
+if(ez) ez2.Realloc(mNDataGood,true);
+int ntest = 0;
+for(int i=0;i<mNData;i++) {
+  if( ! IsValid(i) ) continue;
+  if(ntest>=mNDataGood) return -5.;
+  x(ntest) = Absc(varx,i) - xc;
+  y(ntest) = Absc(vary,i) - yc;
+  z(ntest) = Val(i);
+  if(ez) ez2(ntest) = EVal(i)*EVal(i);
+  ntest++;
+}
+double res = 0.;
+if(ez) {
+  TVector<r_8> errcoef(1);
+  if(degre2>0) res = pol.Fit(x,y,z,ez2,degre1,degre2,errcoef);
+  else         res = pol.Fit(x,y,z,ez2,degre1,errcoef);
+} else {
+  if(degre2>0) res = pol.Fit(x,y,z,degre1,degre2);
+  else         res = pol.Fit(x,y,z,degre1);
+}
+return res;
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Retourne une classe contenant les residus du fit ``gfit''.
+*/
+GeneralFitData GeneralFitData::FitResidus(GeneralFit& gfit) const
+{
+if(gfit.GetNVar()!=mNVar)
+  throw(SzMismatchError("GeneralFitData::FitResidus: size mismatch\n"));
+return gfit.DataResidus(true);
+}
+
+/*!
+  Retourne une classe contenant la function du fit ``gfit''.
+*/
+GeneralFitData GeneralFitData::FitFunction(GeneralFit& gfit) const
+{
+if(gfit.GetNVar()!=mNVar)
+  throw(SzMismatchError("GeneralFitData::FitFunction: size mismatch\n"));
+return gfit.DataFunction(true);
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+//
+  Retourne la donnee `n' dans le vecteur de double `ret'.
+  \verbatim
+    Par defaut, ret=NULL et le buffer interne de la classe est retourne
+    - Les donnees sont rangees dans l'ordre:
+       x0,x1,x2,... ; ex0,ex1,ex2,...  ; y ; ey ; ok(0/1)
+       |<- NVar ->| + |<-   NVar   ->| + 1 +  1 +  1
+      Le vecteur ret a la taille 2*NVar+2+1
+  \endverbatim
+*/
+r_8* GeneralFitData::GetVec(int n, r_8* ret)   const
+{
+int i;
+if (ret == NULL) ret = BuffVar;
+for(i=0; i<2*mNVar+3; i++)  ret[i] = 0.;
+if (n >= mNData) return(ret);
+
+memcpy(ret, mXP+n*mNVar, mNVar*sizeof(r_8));
+if(mErrXP) memcpy(ret+mNVar, mErrXP+n*mNVar, mNVar*sizeof(r_8));
+ret[2*mNVar] = mF[n];
+ret[2*mNVar+1] = mErr[n];
+ret[2*mNVar+2] = (double) mOK[n];
+return(ret);
+}
+
+/*!
+  Retourne la donnee `n' dans le vecteur de float `ret'
+  (meme commentaires que pour GetVec).
+*/
+r_4* GeneralFitData::GetVecR4(int n, r_4* ret)   const
+{
+if (ret == NULL) ret = BuffVarR4;
+double *buff = new double[2*mNVar+3];
+GetVec(n,buff);
+for(int i=0;i<2*mNVar+3;i++) ret[i] = (float) buff[i];
+delete [] buff;
+return ret;
+}
+
+//////////////////////////////////////////////////////////////////////
+// ------- Implementation de  l interface NTuple  ---------
+
+/*!
+  Retourne le nombre de ligne = NData() (pour interface NTuple)
+*/
+uint_4 GeneralFitData::NbLines() const
+{
+return(NData());
+}
+
+/*!
+  Retourne le nombre de colonnes du ntuple equivalent:
+  \verbatim
+    Exemple: on a une fonction sur un espace a 4 dimensions:
+    "x0,x1,x2,x3    , ex0,ex1,ex2,ex3    , y,   ey ,    ok"
+      0  1  2  3        4   5   6   7      8     9      10
+      |        |        |           |      |     |       |        
+      0       nv-1     nv         2*nv-1  2*nv  2*nv+1  2*nv+2
+    soit 2*nvar+3 variables/colonnes.
+  \endverbatim
+  (pour interface NTuple)
+*/
+uint_4 GeneralFitData::NbColumns() const
+{
+return(2*NVar()+3);
+}
+
+//! Pour interface NTuple
+r_8 * GeneralFitData::GetLineD(int n) const
+{
+return(GetVec(n,NULL));
+}
+
+//! Pour interface NTuple
+r_8 GeneralFitData::GetCell(int n, int k) const
+{
+if(k<0 || k>=2*NVar()+3) return 0.;
+r_8 * val = GetVec(n,NULL);
+return val[k];
+}
+
+//! Pour interface NTuple
+r_8 GeneralFitData::GetCell(int n, string const & nom) const
+{
+int k = ColumnIndex(nom);
+return(GetCell(n,k));
+}
+
+/*!
+  Retourne le minimum et le maximum de la variable `k' (pour interface NTuple).
+*/
+void GeneralFitData::GetMinMax(int k, double& min, double& max)  const
+{
+int var;
+if(k<0 || k>=2*NVar()+3) return;
+else if(k<NVar())      var = 10*k+2;          // Variable Xi
+else if(k<2*NVar())    var = 10*(k-NVar())+3; // Variable EXi
+else if(k==2*NVar())   var = 0;               // Variable Y
+else if(k==2*NVar()+1) var = 1;               // Variable EY
+else {min=0.; max=1.; return;}                // Variable Ok
+GetMnMx(var,min,max);
+return;
+}
+
+//! Pour interface NTuple
+void GeneralFitData::GetMinMax(string const & nom, double& min, double& max)   const
+{
+int k = ColumnIndex(nom);
+GetMinMax(k,min,max);
+}
+
+//! Pour interface NTuple
+int GeneralFitData::ColumnIndex(string const & nom)  const
+{
+char str[64]; int k = -1;
+strcpy(str,nom.c_str()); strip(str,'L',' ');
+if(str[0]=='y') return 2*NVar();
+if(str[0]=='o') return 2*NVar()+2;
+if(str[0]=='x') {sscanf(str,"x%d",&k); return k;}
+if(str[0]=='e')
+  if(str[1]=='y') return 2*NVar()+1;
+  else if(str[1]=='x') {sscanf(str,"ex%d",&k); return NVar()+k;}
+return -1;
+}
+
+//! Pour interface NTuple
+string GeneralFitData::ColumnName(int k) const
+{
+if(k==2*NVar())                return string("y");
+else if(k==2*NVar()+1)         return string("ey");
+else if(k==2*NVar()+2)         return string("ok");
+else if(k<0 || k>=2*NVar()+3)  return string("");
+
+char str[64] = "";
+if(k<NVar()) sprintf(str,"x%d",k);
+else if(k<2*NVar()) sprintf(str,"ex%d",k-NVar());
+return string(str);
+}
+
+/*!
+  Retourne une chaine de caracteres avec la declaration des noms de 
+  variables. si "nomx!=NULL" , des instructions d'affectation
+  a partir d'un tableau "nomx[i]" sont ajoutees (pour interface NTuple).
+*/
+string GeneralFitData::VarList_C(const char* nomx)  const
+{
+char buff[256];
+string rets;
+int i;
+rets = "\ndouble";
+for(i=0; i<mNVar; i++) {
+  sprintf(buff," x%d, ex%d",i,i);
+  rets += buff;
+  if(i!=mNVar-1) rets += ","; else rets += ";\n";
+}
+sprintf(buff,"\ndouble y, ey, ok;\n");
+rets += buff;
+if (nomx) {
+  for(i=0; i<mNVar; i++) {
+    sprintf(buff,"x%d=%s[%d];\n", i, nomx, i);
+    rets += buff;
+  }
+  for(i=0; i<mNVar; i++) {
+    sprintf(buff,"ex%d=%s[%d];\n", i, nomx, mNVar+i);
+    rets += buff;
+  }
+  sprintf(buff,"y=%s[%d];\ney=%s[%d];\nok=%s[%d];\n"
+         ,nomx,2*mNVar,nomx,2*mNVar+1,nomx,2*mNVar+2);
+  rets += buff;
+}
+
+return(rets);
+}
+
+
+//! Compute errors according to specifications
+/*!
+  \param val : value of the function
+  \param err : value of the default error
+  \param errtype : type of error according to enum FitErrType (def=DefaultError)
+  \param errscale : scaling (or value) of the error (def=1.)
+  \param errmin : minimum value of the error (def=0.)
+  \param nozero : if true, do not return negative errors but
+                  set them to zero (def=false)
+  \return : return the error computed according to specifications
+  \verbatim
+  - val is the value to be fitted ex: val = f(x,y,...)
+  - err is the error by default we want to set.
+  - errtype = DefaultError  : errtmp = errscale*err
+    errtype = ConstantError : errtmp = errscale
+    errtype = SqrtError     : errtmp = errscale*sqrt(|val|)
+    errtype = ProporError   : errtmp = errscale*|val|
+  - errscale <=0 then errscale=1
+  - errmin >=0 if errtmp>0  return max(errtmp,errmin)
+               if errtmp<=0 return errtmp
+    errmin <0  if errtmp>0  return max(errtmp,|errmin|)
+               if errtmp<=0 return |errmin|
+  \endverbatim
+ */
+double GeneralFitData::ComputeError(double val,double err,FitErrType errtype
+			           ,double errscale,double errmin,bool nozero)
+{
+ bool errminneg=false;
+ if(errmin<0.) {errminneg=true; errmin*=-1.;}
+ if(errscale<0.) errscale=1.;
+
+ // Choix du type d'erreur
+ if(errtype==ConstantError)    err = errscale;
+ else if(errtype==SqrtError)   err = errscale*sqrt(fabs(val));
+ else if(errtype==ProporError) err = errscale*fabs(val);
+
+ // Gestion du minimum a partir de la valeur calculee precedemment "err"
+ // Ex1: errmin=1.,  err=10.     ==> 10.
+ //                  err=0.5     ==> 1.
+ //                  err=0.      ==> 0.
+ //                  err=-2.     ==> -2.
+ // Ex2: errmin=-1., err=10.     ==> 10.
+ //                  err=0.5     ==> 1.
+ //                  err=0.      ==> 1.
+ //                  err=-2.     ==> 11.
+ if(err>0.) err = (err>errmin) ? err: errmin;
+ else if(errminneg) err = errmin;
+
+ // ne pas retourner d'erreurs negatives si demande
+ if(nozero && err<0.) err=0.;
+
+ return err;
+}
+
+///////////////////////////////////////////////////////////
+// --------------------------------------------------------
+//   Les objets delegues pour la gestion de persistance 
+// --------------------------------------------------------
+///////////////////////////////////////////////////////////
+
+
+void ObjFileIO<GeneralFitData>::ReadSelf(PInPersist& is)
+{
+char strg[256];
+
+if(dobj==NULL) dobj=new GeneralFitData;
+  else         dobj->Delete();
+
+// Lecture entete
+is.GetLine(strg, 255);
+
+// Ecriture des valeurs de definitions
+int_4 nvar,ndatalloc,ndata,ndatagood;
+is.Get(nvar);
+is.Get(ndatalloc);
+is.Get(ndata);
+is.Get(ndatagood);
+is.Get(dobj->mOk_EXP);
+if(nvar<=0 || ndatalloc<=0 || ndata<=0 || ndatagood<0 || ndatalloc<ndata) return;
+
+// Allocation de la place (attention Alloc efface mNData,mNDataGood);
+dobj->Alloc(nvar,ndatalloc,-1);
+dobj->mNData = ndata;
+dobj->mNDataGood = ndatagood;
+
+// Lecture des datas
+is.GetLine(strg, 255);
+int blen = dobj->mNVar + 3;
+if(dobj->mOk_EXP) blen += dobj->mNVar;
+double *buff = new double[blen];
+for(int i=0;i<dobj->mNData;i++) {
+  is.Get(buff, blen);
+  int ip = i*dobj->mNVar;
+  {for(int j=0;j<dobj->mNVar;j++)  dobj->mXP[ip+j] = buff[j];}
+  dobj->mF[i] = buff[dobj->mNVar];
+  dobj->mErr[i] = buff[dobj->mNVar+1];
+  dobj->mOK[i] = (uint_2)(buff[dobj->mNVar+2]+0.01);
+  if(dobj->mOk_EXP) {for(int j=0;j<dobj->mNVar;j++)
+                        dobj->mErrXP[ip+j] = buff[dobj->mNVar+3+j];}
+}
+delete [] buff;
+
+return;
+}
+
+void ObjFileIO<GeneralFitData>::WriteSelf(POutPersist& os) const
+{
+if (dobj == NULL)   return;
+char strg[256];
+
+// Ecriture entete pour identifier facilement
+sprintf(strg,"GeneralFitData: NVar=%d NDataAlloc=%d NData=%d NDataGood=%d Ok_EXP=%d"
+       ,dobj->mNVar,dobj->mNDataAlloc,dobj->mNData,dobj->mNDataGood,dobj->mOk_EXP);
+os.PutLine(strg);
+
+// Ecriture des valeurs de definitions
+os.Put(dobj->mNVar);
+os.Put(dobj->mNDataAlloc);
+os.Put(dobj->mNData);
+os.Put(dobj->mNDataGood);
+os.Put(dobj->mOk_EXP);
+if(dobj->mNVar<=0 || dobj->mNDataAlloc<=0 || dobj->mNData<=0 || dobj->mNDataGood<0) return;
+
+// Ecriture des datas (on n'ecrit que mNData / mNDataAlloc)
+sprintf(strg
+       ,"GeneralFitData: Abscisses, Ordonnee, Erreur Ordonnee, Flag, Erreur Abscisses");
+os.PutLine(strg);
+
+int blen = dobj->mNVar + 3;
+if(dobj->mOk_EXP) blen += dobj->mNVar;
+double *buff = new double[blen];
+for(int i=0;i<dobj->mNData;i++) {
+  {for(int j=0;j<dobj->mNVar;j++) buff[j] = dobj->Absc(j,i);}
+  buff[dobj->mNVar] = dobj->Val(i);
+  buff[dobj->mNVar+1] = dobj->EVal(i);
+  buff[dobj->mNVar+2] = (double) dobj->IsValid(i);
+  if(dobj->mOk_EXP) {for(int j=0;j<dobj->mNVar;j++) buff[dobj->mNVar+3+j] = dobj->EAbsc(j,i);}
+  os.Put(buff, blen);
+}
+delete [] buff;
+
+return;
+}
+
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template ObjFileIO<GeneralFitData>
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class ObjFileIO<GeneralFitData>;
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/generaldata.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/generaldata.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/generaldata.h	(revision 2309)
@@ -0,0 +1,197 @@
+// This may look like C code, but it is really -*- C++ -*-
+//                         C.Magneville          04/99
+#ifndef GENERALDATA_SEEN
+#define GENERALDATA_SEEN
+
+#include "objfio.h"
+#include <iostream.h>
+#include "pexceptions.h"
+#include "ppersist.h"
+#include "ntupintf.h"
+#include "poly.h"
+
+namespace SOPHYA {
+
+class GeneralFit;
+
+//================================================================
+// GENERALFITDATA
+//================================================================
+
+//! Classe de stoquage de donnees a plusieurs variables avec erreur
+class GeneralFitData : public AnyDataObj , public NTupleInterface {
+  friend class GeneralFit;
+  friend class ObjFileIO<GeneralFitData>;
+public:
+  //! Valeurs par defaut pour l'utilisation des erreurs
+  enum {
+    Def_ErrF = 1, //!< erreurs sur F par defaut
+    Def_ErrX = 0  //!< pas d'erreurs sur les variables X,Y,... par defaut
+    };
+
+  GeneralFitData(unsigned int nVar, unsigned int nDataAlloc, uint_2 errx=0);
+  GeneralFitData(const GeneralFitData& data, bool clean=false);
+  GeneralFitData();
+  virtual ~GeneralFitData();
+
+  void Alloc(unsigned int nVar, unsigned int nDataAlloc, int_2 errx=-1);
+  void SetDataPtr(int ptr = 0);
+
+  void KillData(int i);
+  void KillData(int i1,int i2);
+
+  void ValidData(int i);
+  void ValidData(int i1,int i2);
+  void ValidData();
+
+  void RedefineData1(int i,double x,double f,double err=Def_ErrF,double errx=Def_ErrX);
+  void RedefineData2(int i,double x,double y,double f,double err=Def_ErrF
+                    ,double errx=Def_ErrX,double erry=Def_ErrX);
+  void RedefineData(int i,double* xp,double f,double err=Def_ErrF,double* errxp=NULL);
+
+  void AddData1(double x, double f, double err=Def_ErrF,double errx=Def_ErrX);
+  void AddData2(double x, double y, double f, double err=Def_ErrF
+               ,double errx=Def_ErrX,double erry=Def_ErrX);
+  void AddData(double* xp, double f, double err=Def_ErrF,double* errxp=NULL);
+  void AddData(float* xp, float f, float err=Def_ErrF,float* errxp=NULL);
+
+  void SetData1(int nData,double* x,double* f,double *err=NULL,double *errx=NULL);
+  void SetData1(int nData,float* x,float* f,float* err=NULL,float *errx=NULL);
+  void SetData2(int nData,double* x,double* y,double* f,double *err=NULL
+               ,double *errx=NULL,double *erry=NULL);
+  void SetData2(int nData,float* x,float* y,float* f,float* err=NULL
+               ,float *errx=NULL,float *erry=NULL);
+  void SetData(int nData,double** xp,double *f,double *err=NULL,double** errxp=NULL);
+  void SetData(int nData,float** xp,float* f,float* err=NULL,float** errxp=NULL);
+
+  void PrintStatus() const;
+  void PrintData(int i) const;
+  void PrintData(int i1,int i2) const;
+  void PrintData() const;
+  void Show(ostream& os) const;
+  inline void Show() const {Show(cout);}
+
+  //! Retourne la place restante dans la structure (nombre de donnees que l'on peut encore stoquer).
+  inline int GetSpaceFree() const { return mNDataAlloc - mNData; }
+  //! Retourne le nombre de variables Xi
+  inline int NVar()       const {return mNVar;}
+  //! Retourne le nombre de donnees
+  inline int NData()      const {return mNData;}
+  //! Retourne le nombre de bonnes donnees (utilisees pour le fit)
+  inline int NDataGood()  const {return mNDataGood;}
+  //! Retourne la place maximale allouee pour les donnees
+  inline int NDataAlloc() const {return mNDataAlloc;}
+
+  //! Retourne 1 si point valide, sinon 0
+  inline unsigned short int IsValid(int i) const
+                {if(i>=0 && i<mNData) return mOK[i]; else return 0;}
+  //! Retourne ``true'' si il y a des erreurs sur les variables d'abscisse, ``false'' sinon.
+  inline bool HasXErrors() {if(mErrXP) return true; else return false;}
+
+  //! Retourne l'abscisse pour 1 dimension (y=f(x)) donnee I
+  inline double X1(int i) const
+                {if(i>=0 && i<mNData) return mXP[i]; else return 0.;}
+  //! Retourne la 1er abscisse (X) pour (v=f(x,y,z,...)) donnee I
+  inline double X(int i) const
+                {if(i>=0 && i<mNData) return mXP[i*mNVar]; else return 0.;}
+  //! Retourne la 2sd abscisse (Y) pour (v=f(x,y,z,...)) donnee I
+  inline double Y(int i) const
+                {if(i>=0 && i<mNData && 1<mNVar) return mXP[i*mNVar+1]; else return 0.;}
+  //! etourne la 3ieme abscisse (Z) pour (v=f(x,y,z,...)) donnee I
+  inline double Z(int i) const
+                {if(i>=0 && i<mNData && 2<mNVar) return mXP[i*mNVar+2]; else return 0.;}
+  //! Retourne la Jieme abscisse (Xj) pour (v=f(x0,x1,x2,...)) donnee I
+  inline double Absc(int j,int i) const
+                {if(i>=0 && i<mNData && j<mNVar)return mXP[i*mNVar+j]; else return 0.;}
+  //! Retourne la valeur de la Ieme donnee
+  inline double Val(int i) const
+                {if(i>=0 && i<mNData) return mF[i]; else return 0.;}
+
+  //! Retourne l'erreur (dx) sur l'abscisse pour 1 dimension (y=f(x)) donnee I
+  inline double EX1(int i) const
+                {if(mErrXP && i>=0 && i<mNData) return mErrXP[i]; else return 0.;}
+  //! Retourne l'erreur (dx) sur la 1er abscisse (X) pour (v=f(x,y,z,...)) donnee I
+  inline double EX(int i) const
+                {if(mErrXP && i>=0 && i<mNData) return mErrXP[i*mNVar]; else return 0.;}
+  //! Retourne l'erreur (dy) sur la 2sd abscisse (Y) pour (v=f(x,y,z,...)) donnee I
+  inline double EY(int i) const
+                {if(mErrXP && i>=0 && i<mNData && 1<mNVar) return mErrXP[i*mNVar+1];
+                 else return 0.;}
+  //! Retourne l'erreur (dz) sur la 3ieme abscisse (Z) pour (v=f(x,y,z,...)) donnee I
+  inline double EZ(int i) const
+                {if(mErrXP && i>=0 && i<mNData && 2<mNVar) return mErrXP[i*mNVar+2];
+                 else return 0.;}
+  //! Retourne l'erreur (dxj) sur la Jieme abscisse (Xj) pour (v=f(x0,x1,x2,...)) donnee I
+  inline double EAbsc(int j,int i) const
+                {if(mErrXP && i>=0 && i<mNData && j<mNVar) return mErrXP[i*mNVar+j];
+                 else return 0.;}
+  //! Retourne l'erreur de la Ieme donnee
+  inline double EVal(int i) const
+                {if(i>=0 && i<mNData) return mErr[i]; else return 0.;}
+
+  r_8* GetVec(int n, r_8* ret=NULL) const;
+  r_4* GetVecR4(int n, r_4* ret=NULL) const;
+  int GetMnMx(int var,int& imin,int& imax) const;
+  int GetMnMx(int var,double& min,double& max) const;
+  int GetMeanSigma(int var,double& mean,double& sigma,double min=1.,double max=-1.) const;
+  int GetMoMeMed(int var,double& mode,double& mean,double& median,
+                 double min=1.,double max=-1.,double coeff=0.8) const;
+  int GetMode(int var,double& mode,double min=1.,double max=-1.,double coeff=0.8) const;
+  double PolFit(int varx,Poly& pol,int degre,bool ey=true,double xc=0.) const;
+  double PolFit(int varx,int vary,Poly2& pol,int degre1,int degre2=-1,bool ez=true
+               ,double xc=0.,double yc=0.) const;
+  GeneralFitData FitResidus(GeneralFit& gfit) const;
+  GeneralFitData FitFunction(GeneralFit& gfit) const;
+
+// Declaration de l interface NTuple
+  virtual uint_4        NbLines() const;
+  virtual uint_4        NbColumns() const;
+  virtual r_8 *         GetLineD(int n) const;
+  virtual r_8		GetCell(int n, int k) const;
+  virtual r_8		GetCell(int n, string const & nom) const;
+  virtual void		GetMinMax(int k, double& min, double& max) const; 
+  virtual void		GetMinMax(string const & nom, double& min, double& max) const;
+  virtual int           ColumnIndex(string const & nom) const;
+  virtual string        ColumnName(int k) const;
+  virtual string	VarList_C(const char* nomx=NULL) const;
+
+  enum FitErrType {DefaultError,ConstantError,SqrtError,ProporError};
+  static double ComputeError(double val,double err,FitErrType errtype=DefaultError
+			    ,double errscale=1.,double errmin=0.,bool nozero=false);
+
+protected:
+  void Delete();
+
+  int_4   mNVar;        //!< number of variables
+  int_4   mNDataAlloc;  //!< space allocated for datas
+  int_4   mNData;       //!< number of datas
+  int_4   mNDataGood;   //!< number of good datas (not killed)
+  uint_2  mOk_EXP;      //!< true if errors on variables X,Y,..
+  r_8* mXP;             //!< x0 y0 z0, x1 y1 z1, ..., xn yn zn 
+  r_8* mErrXP;          //!< Ex0 Ey0 Ez0, Ex1 Ey1 Ez1, ..., Exn Eyn Ezn 
+  r_8* mF;              //!< F0, F1, ...., Fn
+  r_8* mErr;            //!< EF0, EF1, ...., EFn
+  uint_2* mOK;          //!< 1 si pt valid, 0 sinon
+  r_8* BuffVar;         //!< dummy buffer
+  r_4* BuffVarR4;       //!< dummy buffer
+};
+
+inline ostream& operator << (ostream& s, GeneralFitData const & g)
+                         {g.Show(s); return(s);}
+
+/////////////////////////////////////////////////////////////////////////
+// Classe pour la gestion de persistance
+
+//! For persistance management
+inline POutPersist& operator << (POutPersist& os, GeneralFitData & obj)
+{ ObjFileIO<GeneralFitData> fio(&obj);  fio.Write(os);  return(os); }
+//! For persistance management
+inline PInPersist& operator >> (PInPersist& is, GeneralFitData & obj)
+{ ObjFileIO<GeneralFitData> fio(&obj);  fio.Read(is);  return(is); }
+
+// Classe pour la gestion de persistance
+// ObjFileIO<GeneralFitData>
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/generalfit.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/generalfit.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/generalfit.cc	(revision 2309)
@@ -0,0 +1,1768 @@
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream.h>
+#include <math.h>
+#ifdef __MWERKS__
+   #include "mwerksmath.h" // Portage mac D. Y.
+#include "unixmac.h"
+#endif
+#include <string.h>
+#include <string>
+
+#include "pexceptions.h"
+#include "generalfit.h"
+#include "sopemtx.h"
+
+#define EPS_FIT_MIN 1.e-8
+
+//================================================================
+// GeneralFunction
+//================================================================
+
+/*!
+  \class SOPHYA::GeneralFunction
+  \ingroup NTools
+   Classe de fonctions parametrees a plusieurs variables:
+  \f$ F[x1,x2,x3,...:a1,a2,a3,...] \f$
+*/
+
+//////////////////////////////////////////////////////////////////////
+/*!
+ Creation d'une fonction de `nVar' variables et `nPar' parametres:
+ \f$ F[x(1),x(2),x(3),...x(nVar) : a(1),a(2),a(3),...,a(nPar)] \f$
+*/
+GeneralFunction::GeneralFunction(unsigned int nVar, unsigned int nPar)
+  : mNVar(nVar), mNPar(nPar)
+{
+ ASSERT( nVar > 0 && nPar > 0 );
+ deltaParm = new double[nPar];
+ tmpParm   = new double[nPar];
+ END_CONSTRUCTOR
+}
+
+GeneralFunction::~GeneralFunction()
+{
+ delete[] deltaParm;
+ delete[] tmpParm;
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Valeur et Derivees de la fonction (fct virtuelle par defaut).
+*/
+double GeneralFunction::Val_Der(double const xp[], double const* parm
+                               , double *DgDpar)
+{
+ for(int i=0;i<mNPar;i++) tmpParm[i] = parm[i];
+ {for(int i=0;i<mNPar;i++) {
+   double d = deltaParm[i];
+   if(d==0.) { DgDpar[i] = 0.; continue;}
+   tmpParm[i] -= d/2.;
+   double vg = Value(xp,tmpParm);
+   tmpParm[i] += d;
+   double vd = Value(xp,tmpParm);
+   DgDpar[i] = (vd - vg)/d;
+   tmpParm[i] = parm[i];
+ }}
+ return Value(xp, parm);
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Definition de la variation du parametre numPar
+  pour calculer la derivee automatiquement.
+*/
+void GeneralFunction::SetDeltaParm(int numPar, double d)
+{
+ ASSERT(numPar >= 0 && numPar < mNPar);
+ deltaParm[numPar] = d;
+}
+
+
+/*!
+  Idem precedente fonction mais pour tous les parametres
+*/
+void GeneralFunction::SetDeltaParm(double const* dparam)
+{
+ for(int i=0;i<mNPar;i++) deltaParm[i] = dparam[i];
+}
+
+//================================================================
+// GeneralFunc
+//================================================================
+
+/*!
+  \class SOPHYA::GeneralFunc
+  \ingroup NTools
+  Classe de fonctions parametrees a plusieurs variables
+  derivant de ``GeneralFunction''. Permet de definir
+  une fonction a fiter sans passer par une classe derivee
+  en utilisant l'ecriture courante du C. La fonction
+  retournant les derivees par rapport aux parametres du fit
+  peut etre egalement fournie (optionnel).
+*/
+
+/////////////////////////////////////////////////////////////////
+/*!
+  Createur, on passe le nom ``fun'' de la fonction a la mode C.
+  On peut optionellement egalement passer le nom de la fonction
+  ``funder'' qui retourne les valeurs des derivees par rapport
+  aux parametres du fit.
+  \verbatim
+    ----------------------
+    Exemple d'utilisation:
+    ----------------------
+    include "generalfit.h"
+    ...
+    double   gaussc(double const* x,double const* p);
+    double d_gaussc(double const* x,double const* p,double* dp);
+    ...
+    main {
+     ...
+     // Fit SANS calcul automatique des derivees
+     GeneralFunc      myfunc(2,7,gaussc);
+     GeneralFit       myfit(&myfunc);
+     ...
+     myfit.Fit();
+     ...
+     // Fit AVEC calcul automatique des derivees
+     GeneralFunc      myfunc(2,7,gaussc,d_gaussc);
+     GeneralFit       myfit(&myfunc);
+     ...
+     myfit.Fit();
+    }
+    // Definition de la fonction a fitter a la mode C
+    double gaussc(double const* x,double const* p)
+    // Fonction: X=(x[0]-p[1])/p[3], Y=(x[1]-p[2])/p[4],
+    //  f = p[0]*exp{-0.5*[X^2+Y^2-2*p[5]*X*Y]} + p[6]
+    {
+     double X = (x[0]-p[1])/p[3];
+     double Y = (x[1]-p[2])/p[4];
+     return p[0]*exp(-(X*X+Y*Y-2*p[5]*X*Y)/2)+p[6];
+    }
+    // Definition de la fonction des derivees / parametres
+    // Cette fonction retourne aussi la valeur de la fonction a fitter.
+    double d_gaussc(double const* x,double const* p,double* dp)
+    {
+     dp[0] = derivee de gaussc par rapport au parametre p[0]
+     ...
+     dp[6] = derivee de gaussc par rapport au parametre p[6]
+     return gaussc(x,p);
+    }
+  \endverbatim
+*/
+GeneralFunc::GeneralFunc(unsigned int nvar, unsigned int npar
+             , double (*fun) (double const*, double const*)
+             , double (*funder) (double const*, double const*, double*) )
+: GeneralFunction(nvar,npar), tmpFun(fun), tmpFunDer(funder)
+{
+}
+
+GeneralFunc::~GeneralFunc()
+{
+}
+
+double GeneralFunc::Value(double const xp[], double const* Par)
+{
+return tmpFun(xp,Par);
+}
+
+double GeneralFunc::Val_Der(double const xp[],double const* parm, double* DgDpar)
+{
+if(tmpFunDer) return tmpFunDer(xp,parm,DgDpar);
+  else        return GeneralFunction::Val_Der(xp,parm,DgDpar);
+}
+
+//================================================================
+// GeneralXi2
+//================================================================
+
+/*!
+  \class SOPHYA::GeneralXi2
+  \ingroup NTools
+  Classe de Xi2 a plusieurs parametres :
+  \f$ Xi2[a1,a2,a3,...] \f$
+*/
+
+//////////////////////////////////////////////////////////////////////
+/*!
+//
+  Creation d'un Xi2 de `nPar' parametres.
+  \f$ Xi2[a(1),a(2),a(3),...,a(nPar)] \f$
+*/
+GeneralXi2::GeneralXi2(unsigned int nPar)
+  : mNPar(nPar)
+{ 
+ ASSERT( nPar>0 );
+ deltaParm = new double[nPar];
+ END_CONSTRUCTOR
+}
+
+GeneralXi2::~GeneralXi2()
+{
+ delete[] deltaParm;
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Derivee du Xi2 par rapport au parametre `i'
+  pour les valeurs `parm' des parametres.
+*/
+double GeneralXi2::Derivee(GeneralFitData& data, int i, double* parm)
+{
+ int dum;
+ double d = deltaParm[i];
+ parm[i] -= d/2.;
+ double vg = Value(data, parm,dum);
+ parm[i] += d;
+ double vd = Value(data, parm,dum);
+ parm[i] -= d/2.;
+ return (vd - vg)/d;
+}
+
+/*!
+  Derivee seconde du Xi2 par rapport aux parametres `i' et `j'
+  pour les valeurs `parm' des parametres. Attention, cette fonction
+  calcule d/di(dC2/dj), valeur qui est numeriquement differente
+  de d/dj(dC2/di).
+  \verbatim
+   
+    **** Remarque: Derivee2 = dXi2/dPi.dPj represente le Hessien.
+    Derivee2(k,l)= dXi2/dPk.dPl
+                 = 2*SUMi{1/Si^2*[df(xi;P)/dPk * df(xi;P)/dPl]
+                          + [yi-f(xi;P)] * df(xi;P)/dPk.dPl }
+    ou (xi,yi) sont les points de mesure. "Si" l'erreur sur le point i
+       SUMi represente la somme sur les points de mesure
+       f(x;P) represente le modele parametrique a fitter
+       "P" represente l'ensemble des parametres et "Pi" le ieme parametre
+    Les composantes du Hessien dependent des derivees 1ere et 2sd du modele
+    a fitter f(x;P) selon les parametres "Pi". La prise en compte des derivees
+    secondes est un facteur destabilisant. De plus le facteur [yi-f(xi;P)]
+    devant la derivee 2sd est seulement l'erreur de mesure aleatoire qui
+    n'est pas correlee avec le modele. Le terme avec la derivee 2sd
+    tend donc a s'annuler et peut donc etre omis.
+    (cf. Numerical Recipes in C, chap 15 Modeling of Data, Nonlinear Models,
+     Calculation of the Gradient and Hessian p682,683)
+   
+    **** Conseil: Il est conseille a l'utilisateur de sur-ecrire
+    la fonction virtuelle Derivee2 et de la remplacer par:
+    Derivee2(k,l) = 2*SUMi{1/Si^2*[df(xi;P)/dPk * df(xi;P)/dPl]}
+  \endverbatim
+*/
+double GeneralXi2::Derivee2(GeneralFitData& data, int i, int j, double* parm)
+{
+ double d = deltaParm[i];
+ parm[i] -= d/2.;
+ double vg = Derivee(data,j,parm);
+ parm[i] += d;
+ double vd = Derivee(data,j,parm);
+ parm[i] -= d/2.;
+ d = (vd - vg)/d;
+ return d;
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Definition de la variation 'd' du parametre 'numPar'
+  pour calculer la derivee automatiquement.
+*/
+void GeneralXi2::SetDeltaParm(int numPar, double d)
+{
+ ASSERT(numPar >= 0 && numPar < mNPar);
+  
+ deltaParm[numPar] = d;
+}
+
+/*!
+  Idem precedente fonction mais pour tous les parametres.
+*/
+void GeneralXi2::SetDeltaParm(double const* dparam)
+{
+ for(int i=0;i<mNPar;i++) deltaParm[i] = dparam[i];
+}
+
+//================================================================
+// GeneralFit
+//================================================================
+//                                Christophe 8/11/93 La Silla
+//                                re-codage C++ 16/01/96 Saclay
+
+/*!
+  \class SOPHYA::GeneralFit
+  \ingroup NTools
+  Classe de fit d'une GeneralFunction sur une GeneralFitData
+  */
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Creation d'une classe de fit pour la `GeneralFunction f'.
+*/
+GeneralFit::GeneralFit(GeneralFunction* f)
+  : mNVar         (f->NVar()),
+    mNPar         (f->NPar()),
+    mFunction     (f),
+    mFuncXi2      (NULL),
+
+    Param         (f->NPar()),
+    errParam      (f->NPar()),
+    stepParam     (f->NPar()),
+    minParam      (f->NPar()),
+    maxParam      (f->NPar()),
+    minStepDeriv  (f->NPar()),
+    Eps           (f->NPar()),
+  
+    ATGA          (f->NPar(), f->NPar()),
+    BETA          (f->NPar()),
+    ATGA_Try      (f->NPar(), f->NPar()),
+    BETA_Try      (f->NPar()),
+    C             (f->NPar()),
+    D             (f->NPar())
+{
+ ASSERT(mNVar>0 && mNPar>0);
+ ASSERT(mNPar<1000000);
+
+ TRY {
+   General_Init();
+ } CATCHALL {
+   THROW_SAME;
+ } ENDTRY
+
+ END_CONSTRUCTOR
+}
+
+/*!
+  Creation d'une classe de fit pour le `GeneralXi2 f'.
+  L'emploi de cette methode n'est pas conseillee car elle
+  calcule automatiquement la derivee 2sd du Xi2 par rapport
+  aux parametres, ce qui entraine un manque de robustesse
+  et qui ne garanti pas que la matrice de covariance soit
+  definie positive (il est possible de surecrire
+  la methode virtuelle Derivee2 pour palier ce probleme).
+*/
+GeneralFit::GeneralFit(GeneralXi2* f)
+  : mNVar         (0),
+    mNPar         (f->NPar()),
+    mFunction     (NULL),
+    mFuncXi2      (f),
+
+    Param         (f->NPar()),
+    errParam      (f->NPar()),
+    stepParam     (f->NPar()),
+    minParam      (f->NPar()),
+    maxParam      (f->NPar()),
+    minStepDeriv  (f->NPar()),
+    Eps           (f->NPar()),
+  
+    ATGA          (f->NPar(), f->NPar()),
+    BETA          (f->NPar()),
+    ATGA_Try      (f->NPar(), f->NPar()),
+    BETA_Try      (f->NPar()),
+    C             (f->NPar()),
+    D             (f->NPar())
+{
+ ASSERT( mNPar>0 );
+ ASSERT( mNPar < 1000000 );
+
+ TRY {
+   General_Init();
+ } CATCHALL {
+   THROW_SAME;
+ } ENDTRY
+
+ END_CONSTRUCTOR
+}
+
+//
+void GeneralFit::General_Init(void)
+// Initialisation des diverses variables
+{
+ mNtry      = 0;
+ mNParFree  = mNPar;
+ mNParBound = 0;
+
+ mData      = NULL;
+
+ fixParam   = NULL;
+ boundParam = NULL;
+ nameParam  = NULL;
+
+ Lambda_Fac = 10.;
+ stopChi2   = 0.01;
+ maxStep    = 100;
+ nStopMx    = 3;
+ stopChi2SMx = stopChi2;
+ nStopLent  = 0;
+ debugLevel = 0;
+ FileStep = NULL;
+  
+ Chi2       = 0.;
+ mNddl      = -1;
+ nStep      = 0;
+ nStop      = 0;
+ nStopL     = 0;
+ Lambda     = 0.001;
+
+ GetIntEnv("PDEBUG_GENERALFIT",debugLevel);
+
+ TRY {
+   fixParam   = new unsigned short int[mNPar];
+   boundParam = new unsigned short int[mNPar];
+   nameParam  = new string[mNPar];
+ } CATCHALL {
+   cout<<"GeneralFit::GeneralFit Impossible d'allouer l'espace"<<endl;
+   THROW_SAME;
+ } ENDTRY
+
+ Param        = (double)  0.;
+ errParam     = (double)  0.;
+ stepParam    = (double)  1.;
+ minParam     = (double)  1.;
+ maxParam     = (double) -1.;
+ minStepDeriv = (double) 0.;
+ Eps          = (double) EPS_FIT_MIN;
+ char str[8];
+ for(int i=0;i<mNPar;i++) {
+   sprintf(str,"P%d",i);
+   fixParam[i]   = 0;
+   boundParam[i] = 0;
+   nameParam[i]  = str;
+ }
+}
+
+GeneralFit::~GeneralFit()
+{
+ delete[] fixParam;
+ delete[] boundParam;
+ delete[] nameParam;
+ if(FileStep!=NULL) fclose(FileStep);
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Pour ecrire les iterations dans le fichier filename
+*/
+void GeneralFit::WriteStep(char *filename)
+{
+
+#if defined(__DECCXX) || defined(__KCC__) || defined(__aCC__)
+if(filename==NULL) filename = const_cast<char *>("generalfit.iter");
+#else
+if(filename==NULL) filename = "generalfit.iter";
+#endif
+FileStep = fopen(filename,"w");
+if(FileStep==NULL) THROW(nullPtrErr);
+}
+
+/*!
+  Niveau de debug
+  (voir aussi la variable d'environnement PDEBUG_GENERALFIT).
+*/
+void GeneralFit::SetDebug(int level)
+{
+ debugLevel = ( level < 0 ) ? 0: level;
+ if(debugLevel>0) cout<<"SetDebug_level "<<debugLevel<<endl;
+}
+
+/*!
+  Nombre maximum d'iterations permis.
+*/
+void GeneralFit::SetMaxStep(int n)
+{
+ maxStep = ( n <= 1 ) ? 100: n;
+ if(debugLevel>0) cout<<"SetMaxStep "<<maxStep<<endl;
+}
+
+/*!
+  Facteur de multiplication/division de Lambda selon
+  que le Chi2 a augmente ou diminue.
+*/
+void GeneralFit::SetLambda_Fac(double fac)
+{
+  Lambda_Fac = (fac>1.) ? fac : 10.;
+}
+
+/*!
+  Critere de convergence sur le Chi2.
+*/
+void GeneralFit::SetStopChi2(double s)
+{
+ stopChi2 = ( s <= 0. ) ? 0.01: s;
+ if(debugLevel>0) cout<<"SetStopChi2 "<<stopChi2<<endl;
+}
+
+/*!
+  Precision des calculs (cf \ref GeneralFit_Fit "descriptif general").
+*/
+void GeneralFit::SetEps(double ep)
+{
+ ep = (ep<=0.) ? EPS_FIT_MIN: ep;
+ if(debugLevel>0) cout<<"SetEps "<<ep<<endl;
+ for(int i=0;i<mNPar;i++) SetEps(i,ep);
+}
+
+/*!
+  Precision des calculs pour le parametre n.
+*/
+void GeneralFit::SetEps(int n,double ep)
+{
+ ASSERT(n>=0 && n<mNPar);
+ Eps(n) = (ep<=0.) ? EPS_FIT_MIN: ep;
+ if(debugLevel>0) cout<<"SetEps("<<n<<") = "<<Eps(n)<<endl;
+}
+
+/*!
+  Critere de convergence sur le nombre de stop en chi2
+  dans le cas ou le chi2 augmente de moins de stopchi2
+  (cf \ref GeneralFit_Fit "descriptif general").
+
+  Si nstopmx<=0, alors ce critere de convergence n'est pas applique.
+
+  Si stopchi2<=0, alors la valeur generale mise par SetStopChi2()
+  est utilisee.
+*/
+void GeneralFit::SetStopMx(int nstopmx,double stopchi2)
+{
+ nStopMx = (nstopmx>0) ? nstopmx : 0;
+ stopChi2SMx = (stopchi2>0.) ? stopchi2 : stopChi2;
+ if(debugLevel>0) cout<<"SetStopMx: nStopMx="<<nStopMx
+                      <<" stopChi2SMx="<<stopChi2SMx<<endl;
+}
+
+/*!
+  Critere de convergence sur le nombre de stop en chi2
+  dans le cas ou le chi2 diminue (cf \ref GeneralFit_Fit "descriptif general").
+
+  Si nstopl<=0, alors ce critere de convergence n'est pas applique.
+*/
+void GeneralFit::SetStopLent(int nstoplent)
+{
+ nStopLent = (nstoplent>0) ? nstoplent : 0;
+ if(debugLevel>0) cout<<"SetStopLent "<<nStopLent<<endl;
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Pour changer la fonction a fitter en cours de route
+  (On ne peut passer d'un fit sur une GeneralFunction
+  a un fit sur un GeneralXi2 sans recreer la classe).
+*/
+void GeneralFit::SetFunction(GeneralFunction* f)
+{
+ ASSERT( mFuncXi2  == NULL );
+ ASSERT( f != NULL );
+ ASSERT( f->NVar() == mNVar );
+ ASSERT( f->NPar() == mNPar );
+ mFunction = f;
+ if(debugLevel>0) cout<<"SetFunction "<<mFunction<<endl;
+}
+
+/*!
+  Pour changer le Xi2 a fitter en cours de route
+  (On ne peut passer d'un fit sur une GeneralFunction
+  a un fit sur un GeneralXi2 sans recreer la classe).
+*/
+void GeneralFit::SetFuncXi2(GeneralXi2* f)
+{
+ ASSERT( mFunction == NULL );
+ ASSERT( f != NULL );
+ ASSERT( f->NPar() == mNPar );
+ mFuncXi2  = f;
+ if(debugLevel>0) cout<<"SetFuncXi2 "<<mFuncXi2<<endl;
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Pour connecter une structure de donnees.
+*/
+void GeneralFit::SetData(GeneralFitData* data)
+{
+ if( mFunction != NULL ) {
+   ASSERT( data->NVar()==mNVar );
+ }
+ mData = data;
+ mNddl = mData->NDataGood() - mNParFree;
+ if(debugLevel>0)
+   cout<<"SetData "<<mData<<" data pour "<<mNddl<<" ddl"<<endl;
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Definition du parametre "n" a fitter.
+*/
+void GeneralFit::SetParam(int n,double value,double step
+                         ,double min,double max)
+{
+ ASSERT(n>=0 && n<mNPar);
+
+ Param(n)     = value;
+ if(step>0.) {
+   if( fixParam[n] ) { fixParam[n]=0; mNParFree++;}
+ } else {
+   if( ! fixParam[n] ) { fixParam[n]=1; mNParFree--;}
+ }
+ stepParam(n) = step;
+ minParam(n)  = min;
+ maxParam(n)  = max;
+ if(max>min) {
+   if( ! boundParam[n] ) {boundParam[n]=1; mNParBound++;}
+ } else {
+   if( boundParam[n] ) {boundParam[n]=0; mNParBound--;}
+ }
+  
+ if(debugLevel) {cout<<"Set_"; PrintParm(n);}
+}
+
+/*!
+  Definition du parametre "n" a fitter
+*/
+void GeneralFit::SetParam(int n, string const& name
+                        ,double value,double step,double min,double max)
+{
+ ASSERT(n>=0 && n<mNPar);
+ SetParam(n,value,step,min,max);
+ nameParam[n] = name;
+ if(debugLevel) {cout<<"Set_Param "; PrintParm(n);}
+}
+
+/*!
+  Definition du parametre "n" a fitter
+*/
+void GeneralFit::SetParam(int n,double value)
+{
+ ASSERT(n>=0 && n<mNPar);
+ Param(n) = value;
+ if(debugLevel) {cout<<"Set_Param "; PrintParm(n);}
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Definition du pas de depart du parametre "n"
+  Si negatif ou nul, parametre fixe.
+*/
+void GeneralFit::SetStep(int n,double step)
+{
+ ASSERT(n>=0 && n<mNPar);
+ if(step>0.) {
+   if( fixParam[n] ) { fixParam[n]=0; mNParFree++;}
+ } else {
+   if( ! fixParam[n] ) { fixParam[n]=1; mNParFree--;}
+ }
+ stepParam(n) = step;
+ if(debugLevel) {cout<<"Set_Step"; PrintParm(n);}
+}
+
+/*!
+  Definition du pas minimum `val' pour le parametre `i'
+  pouvant etre utilise dans le calcul automatique des derivees
+  (soit de la fonction, soit du Xi2 selon les parametres du fit).
+  Si nul pas de limite, si negatif alors `EPS(i)' (cf SetEps).
+  Inutile dans le cas ou les derivees sont donnees
+  par l'utilisateur.
+*/
+void GeneralFit::SetMinStepDeriv(int i,double val)
+{
+ ASSERT(i>=0 && i<mNPar);
+ if(val<0.) minStepDeriv(i) = Eps(i);
+   else     minStepDeriv(i) = val;
+ if(debugLevel>0) cout<<"SetMinStepDeriv("<<i<<") = "<<minStepDeriv(i)<<endl;
+}
+
+/*!
+  Definition du pas minimum `val' pour tout les parametres
+  (voir description SetMinStepDeriv ci-dessus).
+*/
+void GeneralFit::SetMinStepDeriv(double val)
+{
+ if(debugLevel>0) cout<<"SetMinStepDeriv "<<val<<endl;
+ for(int i=0;i<mNPar;i++) SetMinStepDeriv(i,val);
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Definition des bornes du parametre "n"
+  Si max<=min, parametre non-borne.
+*/
+void GeneralFit::SetBound(int n, double min, double max)
+{
+ ASSERT(n>=0 && n<mNPar && max>min);
+
+ minParam(n)  = min;
+ maxParam(n)  = max;
+ if( ! boundParam[n] ) {
+   boundParam[n] = 1;
+   mNParBound++;
+   if(debugLevel>0)
+     cout<<"SetBound "<<n<<" min="<<min<<" max="<<max
+         <<" (Nbound="<<mNParBound<<")"<<endl;
+ }
+}
+
+/*!
+  Pour re-borner le parametre "n" aux bornes par defaut
+*/
+void GeneralFit::SetBound(int n)
+{
+ ASSERT(n>=0 && n<mNPar && maxParam(n)>minParam(n));
+ SetBound(n,minParam(n),maxParam(n));
+}
+
+/*!
+  Pour ne plus borner le parametre "n"
+*/
+void GeneralFit::SetUnBound(int n)
+{
+ ASSERT(n>=0 && n<mNPar);
+
+ if( boundParam[n] ) {
+   boundParam[n] = 0;
+   mNParBound--;
+   if(debugLevel>0) cout<<" SetUnBound "<<n
+                        <<" (Nbound="<<mNParBound<<")"<<endl;
+ }
+}
+
+/*!
+  Pour ne plus borner tous les parametres
+*/
+void GeneralFit::SetUnBound()
+{
+ for(int i=0;i<mNPar;i++) SetUnBound(i);
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Pour fixer le parametre "n" a la valeur "v"
+*/
+void GeneralFit::SetFix(int n,double v)
+{
+ ASSERT(n>=0 && n<mNPar);
+
+ Param(n) = v;
+ if( ! fixParam[n] ) {
+   fixParam[n] = 1;
+   mNParFree--;
+ }
+ if(debugLevel>0) cout<<" SetFix "<<n
+                      <<" v="<<v
+                      <<" (Nfree="<<mNParFree
+                      <<")"<<endl;
+}
+
+/*!
+  Pour fixer le parametre "n" a la valeur par defaut
+*/
+void GeneralFit::SetFix(int n)
+{
+ ASSERT(n>=0 && n<mNPar);
+ SetFix(n,Param(n));
+}
+
+/*!
+  Pour liberer le parametre "n"
+*/
+void GeneralFit::SetFree(int n)
+{
+ ASSERT(n>=0 && n<mNPar);
+
+ if( fixParam[n] ) {
+   fixParam[n] = 0;
+   mNParFree++;
+   if(debugLevel>0) cout<<" SetFree "<<n
+                        <<"   Step "<<stepParam(n)
+                        <<" (Nfree="<<mNParFree<<")"<<endl;
+   if(stepParam(n)<=0.)
+     cout<<"ATTENTION SetFree["<<n<<"] avec step<=0 "
+         <<stepParam(n)<<endl;
+ }
+}
+
+/*!
+  Pour liberer tous les parametres
+*/
+void GeneralFit::SetFree()
+{
+ for(int i=0;i<mNPar;i++) SetFree(i);
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Retourne la valeur du parametre "n"
+*/
+double GeneralFit::GetParm(int n)
+{
+ ASSERT(n>=0 && n<mNPar);
+ return Param(n);
+}
+
+/*!
+  Retourne les valeurs des parametres dans un vecteur.
+*/
+TVector<r_8> GeneralFit::GetParm()
+{
+return Param;
+}
+
+/*!
+  Retourne la valeur de l'erreur du parametre "n"
+*/
+double GeneralFit::GetParmErr(int n)
+{
+ ASSERT(n>=0 && n<mNPar);
+ return errParam(n);
+}
+
+/*!
+  Retourne la covariance pour les parametre `i' et `j'
+*/
+double GeneralFit::GetCoVar(int i,int j)
+{
+ ASSERT(i>=0 && i<mNPar && j>=0 && j<mNPar);
+ return ATGA(i,j);
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Retourne la valeur du pas du parametre "n"
+*/
+double GeneralFit::GetStep(int n)
+{
+ ASSERT(n>=0 && n<mNPar);
+ return stepParam(n);
+}
+
+/*!
+  Retourne la valeur de la borne superieure du parametre "n"
+*/
+double GeneralFit::GetMax(int n)
+{
+ ASSERT(n>=0 && n<mNPar);
+ return maxParam(n);
+}
+
+/*!
+  Retourne la valeur de la borne inferieure du parametre "n"
+*/
+double GeneralFit::GetMin(int n)
+{
+ ASSERT(n>=0 && n<mNPar);
+ return minParam(n);
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Impression du status du fit
+*/
+void GeneralFit::PrintStatus()
+{
+ cout<<"GeneralFit::PrintStatus"
+     <<" mData="<<mData
+     <<" mFunction="<<mFunction
+     <<" mFuncXi2="<<mFuncXi2
+     <<endl;
+ cout<<" mNVar="<<mNVar
+     <<" mNPar="<<mNPar
+     <<" mNParFree="<<mNParFree
+     <<" mNParBound="<<mNParBound
+     <<endl;
+ cout<<" Lambda_Fac="<<Lambda_Fac
+     <<" stopChi2="<<stopChi2
+     <<" maxStep="<<maxStep
+     <<" nStopMx="<<nStopMx<<" stopChi2SMx="<<stopChi2SMx
+     <<" nStopLent="<<nStopLent
+     <<" debugLevel="<<debugLevel
+     <<endl;
+ PrintParm();
+}
+
+/*!
+  Impression des resultats du fit
+*/
+void GeneralFit::PrintFit()
+{
+ cout<<"PrintFit: Chi2="<<Chi2
+     <<" Lambda="<<Lambda
+     <<" nStep="<<nStep
+     <<" nStop="<<nStop
+     <<" nStopL="<<nStopL
+     <<" nDDL="<<mNddl
+     <<endl;
+ PrintParm();
+}
+
+/*!
+  Impression des informations relatives au parametre "n"
+*/
+void GeneralFit::PrintParm(int n)
+{
+ ASSERT(n>=0 && n<mNPar);
+
+ cout<<"Par["<<n<<"] "<<nameParam[n]
+     <<" F"<<fixParam[n]
+     <<" B"<<boundParam[n]
+     <<" : "<<Param(n)
+     <<" +/- "<<errParam(n)
+     <<" : "<<stepParam(n)
+     <<" "<<minParam(n)
+     <<" "<<maxParam(n)
+     <<" : "<<Eps(n)
+     <<" "<<minStepDeriv(n)
+     <<endl;
+}
+
+/*!
+  Impression des informations relatives a tous les parametres
+*/
+void GeneralFit::PrintParm()
+{
+ cout<<"*** Parametres : fix bnd : par err : step min max : eps dmin\n";
+ for (int i=0; i<mNPar; i++) PrintParm(i);
+ cout<<endl;
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Methode de fit.
+  \anchor GeneralFit_Fit
+  \verbatim
+     Fonction de fit de la fonction f(x,y,z,...:p1,p2,...,pn)
+             sur les donnees x[i],y[i],z[i],...,F[i],ErrF[i]
+     - Methode:   fit des moindres carres dans le cas non lineaire
+     - Reference: Statistical and Computational Methods in Data Analysis
+                 Siegmund Brandt, North-Holland 1970  p 204-206.
+                 Introduction des limites pour la variation des parametres (cmv).
+                 Increment des parametres selon la methode de Levenberg-Marquardt
+     (Numerical Recipes in C, chap 15 Modeling of Data, Nonlinear Models,
+      Levenberg-Marquardt Method p683)
+     - Gestion des parametres bornes:
+        si p est un parametre borne entre pmin et pmax, le parametre fitte est q
+        tel que     q = tang((p-C)/D)    ....   p = C + D*atan(q)
+        ou   C = (pmin+pmax)/2.  et   D = (pmax-pmin)/Pi
+        On a  dq = (1+q**2)/D * dp    ....   dp = D/(1+q**2) * dq
+        et    dF/dq = dF/dp * dp/dq = D/(1+q**2) * dF/dp
+              dF/dp = dF/dq * dq/dp = (1+q**2)/D * dF/dp
+                                      ^ q
+                      |               |              *| "tang()"
+                      |               |              *|
+                      |               |              *|
+                      |               |             * |
+                      |               |            *  |
+                      |               |          *    |
+                      |               |       *       |
+                  Pmin|              C|   *           |Pmax
+        --------------|---------------*---------------|--------------> p
+                 -Pi/2|           *   |0              |Pi/2
+                      |       *       |               |
+                      |    *          |               |
+                      |  *            |               |
+                      | *             |               |
+                      |*              |               |
+                      |*              |               |
+                      |*              |               |
+                      <------------------- D --------->
+   
+     - Criteres de convergence, arrets standards:
+       - SOIT: le Chi2 est descendu de moins de stopChi2
+               entre l'iteration n et n+1
+               (stopChi2 est change par SetStopChi2)
+       - SOIT: 1. le chi2 est remonte de moins de stopChi2SMx et
+               2. les parametres libres ont varie de moins de Eps(i)
+                  pendant les nStopmx dernieres iterations
+               Si nStopmx<=0, alors ce critere n'est pas applique (def=3).
+               (nStopmx,stopChi2SMx sont changes par SetStopMx, Eps par SetEps)
+   
+     - Criteres de convergence, arrets par non-convergence:
+       - plus de "maxStep" iterations.
+   
+     - Criteres de convergence, arrets speciaux:
+       - Si l'utilisateur a demande explicitement la methode d'arret
+         "SetStopLent()", arret si :
+           1. le Chi2 est descendu et
+           2. les parametres libres ont varies de moins de Eps
+              pendant les nStopLent dernieres iterations.
+              (nStopLent est change par SetStopLent, Eps par SetEps)
+   
+     - Remarques diverses:
+        Les points avec erreurs <=0 ne sont pas utilises dans le fit.
+        Les bornes des parametres ne peuvent etre atteintes
+     - entrees:
+        la fonction est definie par une classe GeneralFunction
+        les donnees sont passees par une classe GeneralFitData
+        le nombre de parametres et le nombre de variables doivent etre
+           coherents entre GeneralFunction GeneralFitData GeneralFit
+     - Return: 
+          la function elle meme retourne le nombre d'iterations  du fit si succes
+          -1  : si le nombre de degre de liberte est <0
+          -10 : si l'inversion de la matrice des erreurs n'a pas ete possible
+          -11 : si un element diagonal de la matrice des covariances est <=0
+          -20 : si le fit n'a pas converge (nstep>nNstepMX)
+          -100-N : si le parametre "N" est initialise hors limites
+          -200-N : si le parametre "N" atteint sa limite inferieure
+          -300-N : si le parametre "N" atteint sa limite superieure
+  \endverbatim
+*/
+int GeneralFit::Fit()
+{
+ volatile double oldChi2;
+ TMatrix<r_8> COVAR(mNPar,mNPar);
+ TVector<r_8> DA(mNPar);
+ TVector<r_8> dparam(mNPar);
+ TVector<r_8> paramTry(mNPar);
+ TVector<r_8> param_tr(mNPar);
+ TVector<r_8> paramTry_tr(mNPar);
+ TVector<r_8> step_tr(mNPar);
+ nStop = nStopL = nStep = 0;
+ Chi2 = oldChi2 = 0.;
+ Lambda = 0.001;
+ mNddl = mData->NDataGood() - mNParFree;
+ if(mNddl<0) return -1;
+ mNtry++;
+
+ if(debugLevel>= 2)
+   cout<<"\n********* DEBUT GENERALFIT.FIT() **************"<<endl;
+
+ // set matrices C,D dans le cas de parametres bornes
+ if(mNParBound>0) Set_Bound_C_D();
+
+ if(debugLevel>= 2) PrintStatus();
+
+ // check de la coherence des operations et assignations
+ CheckSanity();
+
+ // Pour les parametres bornes on verifie
+ // qu'ils sont initialises dans leurs limites
+ {for(int i=0;i<mNPar;i++) {
+   if( !boundParam[i] || fixParam[i] ) continue;
+   if( minParam(i)<Param(i) && Param(i)<maxParam(i) ) continue;
+   /* if(debugLevel>= 1) */
+    cout<<"Parametre "<<i<<" initialise hors limites "
+        <<minParam(i)<<" < "<<Param(i)
+        <<" < "<<maxParam(i)<<endl;
+   return(-100-i);
+ }}
+
+ // premier essai d'initialisation
+ param_tr = p_vers_tr(Param);
+ dparam = stepParam / 2.;
+ put_in_limits_for_deriv(Param,dparam);
+ if(mFunction!=NULL) mFunction->SetDeltaParm(dparam.Data());
+   else if(mFuncXi2!=NULL) mFuncXi2->SetDeltaParm(dparam.Data());
+ step_tr = dp_vers_dtr(stepParam,param_tr);
+
+ if(debugLevel>= 2) {
+   cout<<"ESSAI numero 1: Param:"<<endl;
+   cout<<Param;
+   cout<<"param_tr:"<<endl;
+   cout<<param_tr;
+   cout<<"step_tr:"<<endl;
+   cout<<step_tr;
+ }
+ if(mFunction!=NULL) TryFunc(Param,param_tr);
+   else if(mFuncXi2!=NULL) TryXi2(Param,param_tr);
+ ATGA = ATGA_Try;
+ BETA = BETA_Try;
+ oldChi2 = Chi2;
+
+ // Iterations
+ while (1) {
+   nStep++;
+
+   // un nouvel essai (si Lambda!=0)
+   {for(int i=0; i<mNPar; i++)
+       if(! fixParam[i] ) ATGA(i,i) *= 1 + Lambda;
+          else  ATGA(i,i) = 1.;}
+
+   // Calcul de la matrice des covariances
+#ifdef __mac__
+   COVAR = SimpleMatrixOperation<r_8>::Inverse(ATGA); /* $CHECK$  Reza 10/3/2000 */
+#else
+   TRY {
+     COVAR = SimpleMatrixOperation<r_8>::Inverse(ATGA); /* $CHECK$  Reza 10/3/2000 */
+   } CATCHALL {
+     if(debugLevel>0) {
+       cout<<"Pb inversion matrice ATGA:"<<endl;
+       cout<<ATGA;
+     }
+     return(-10);
+   } ENDTRY
+#endif
+
+   if (debugLevel >= 3) {
+     cout<<"Matrice (tA G A)^-1 = \n";
+     cout<<COVAR;
+   }
+
+   // calculs des deplacements a effectuer
+   DA = COVAR * BETA;
+   if (debugLevel >=2) {
+     cout<<"Correction parametres DA : \n";
+     cout<<DA;
+   }
+   
+
+   //////////////////////////////////////////////////
+   ////////////////// Arret du Fit //////////////////
+   // si Lambda = 0, le fit a converge on s'arrete
+   //                ou bien on a trop d'iterations
+   //////////////////////////////////////////////////
+   if(Lambda == 0 || nStep > maxStep) {
+     // trop d'iterations
+     if(nStep>maxStep) 
+       cout<<"GeneralFit : pas de convergence"<<endl;
+     // Probleme de matrice de covariance non-definie positive?
+     bool bad_covar = false;
+     {for(int i=0; i<mNPar; i++) {
+       if( fixParam[i] ) errParam(i) = 0.;
+       else {
+         stepParam(i) = DA(i);
+         if( COVAR(i,i)<=0. ) {
+            if( debugLevel>0 )
+              cout<<"Erreur: Par["<<i<<"]="<<param_tr(i)
+                  <<" ("<<Param(i)<<") COVAR()="<<COVAR(i,i)
+                  <<" step="<<DA(i)<<endl;
+             errParam(i) = 0.;
+             bad_covar = true;
+         } else {
+           errParam(i) = sqrt( COVAR(i,i) );
+	 }
+       }
+     }}
+     // print de debug pour parametres bornes
+     if(debugLevel>= 2) {
+       cout<<"param_tr:"<<endl;
+       cout<<param_tr;
+       cout<<"stepParam_tr:"<<endl;
+       cout<<stepParam;
+       cout<<"errParam_tr:"<<endl;
+       cout<<errParam;
+     }
+     // Calcul de la matrice des covariances
+     {for(int i=0; i<mNPar; i++) {
+        for(int j=0; j<mNPar; j++) {
+          if( fixParam[i] || fixParam[j] ) {
+            // Parametre fixe, on retourne l'identite
+            if(i==j) ATGA(i,j) = 1.; else ATGA(i,j) = 0.;
+	  } else if( errParam(i)<=0. || errParam(j)<=0.) {
+            // parametres avec mauvaise variance, on retourne 0
+            ATGA(i,j) = 0;
+	  } else {
+            // parametres OK
+            ATGA(i,j) = COVAR(i,j)/(errParam(i)*errParam(j));
+	  }
+	}
+     }}
+     if (debugLevel >= 1) {
+       cout<<">>> Matrice des Covariances = \n";
+       cout<<ATGA;
+     }
+     // Calcul du step et de l'erreur finale en tenant
+     // compte des parametres bornes
+     stepParam = dtr_vers_dp(stepParam,param_tr);
+     errParam  = dtr_vers_dp(errParam,param_tr);
+     // Print si demande et code de retour.
+     if (debugLevel>0 ) PrintFit();
+     if(nStep>maxStep) return(-20);
+       else if(bad_covar) return(-11);
+         else return(nStep);
+   }
+   ////////////////////////////////////////////////////////
+   ////////////////// Fin d'Arret du Fit //////////////////
+   ////////////////////////////////////////////////////////
+
+   // Gestion des deplacements
+   {for (int i=0; i<mNPar; i++) {
+     if( fixParam[i] ) { DA(i) = 0; continue;}
+     // le premier deplacement ne peut etre plus grand que stepParam
+     if( nStep == 1 && fabs(DA(i)) > step_tr(i) ) {
+       DA(i) = DA(i) < 0. ? -step_tr(i) : step_tr(i);
+       if(debugLevel>1 ) cout<<"Excursion parametre "<<i
+                             <<" limitee a "<<DA(i)<<endl;
+     }
+   }}
+   paramTry_tr = param_tr + DA;
+   paramTry = tr_vers_p(paramTry_tr);
+   dparam = dtr_vers_dp(DA,paramTry_tr);
+   dparam /= 2.;
+   put_in_limits_for_deriv(paramTry,dparam);
+   {for(int i=0; i<mNPar; i++) {
+     if( ! boundParam[i] ) continue;
+     if(paramTry(i) <= minParam(i)) {
+       if(debugLevel>0) cout<<"Parametre "<<i
+                            <<" limite au minimum"<<endl;
+       Param(i) = minParam(i);
+       return(-200-i);
+     } else if (paramTry(i) >= maxParam(i)) {
+       if(debugLevel>0) cout<<"Parametre "<<i
+                            <<" limite au maximum"<<endl;
+       Param(i) = maxParam(i);
+       return(-300-i);
+     }
+   }}
+
+   // Nouvel essai
+   if(mFunction!=NULL) mFunction->SetDeltaParm(dparam.Data());
+     else if(mFuncXi2!=NULL) mFuncXi2->SetDeltaParm(dparam.Data());
+   if(debugLevel >= 2) {
+     cout<<">>>>>>>>>>> ESSAI avec nouveaux parametres\n";
+     cout<<"paramTry:\n";
+     cout<<paramTry;
+     cout<<"paramTry_tr:\n";
+     cout<<paramTry_tr;
+     cout<<"dparam:\n";
+     cout<<dparam;
+   }
+   if(mFunction!=NULL) TryFunc(paramTry,paramTry_tr);
+     else if(mFuncXi2!=NULL) TryXi2(paramTry,paramTry_tr);
+
+   if (debugLevel >= 2)
+     cout<<"step "<<nStep<<" Chi2 : old="<<oldChi2
+         <<" new="<<Chi2<<" d="<<Chi2-oldChi2<<endl;
+   if(FileStep) write_in_step(Chi2,paramTry);
+
+   // *************************************************************
+   // ****************** quelle strategie sur Lambda ???? *********
+   // *************************************************************
+   if (Chi2 < oldChi2) {
+     // ****************** le Chi2 est descendu ******************
+     nStop = 0;
+     if(nStopLent>0) {
+       // Arret special demande, comment se comporte les parametres?
+       int k=0;
+       for (int i=0; i<mNPar; i++) if( (!fixParam[i]) &&
+              (fabs(param_tr(i)-paramTry_tr(i))<Eps(i))) k++;
+       if (k==mNParFree) nStopL++; // Tous les parametres ont peu varies
+          else nStopL=0;
+       if (debugLevel>=2) cout<<k<<" parametres sur "<<mNParFree
+                              <<" ont peu varies, nStopL="<<nStopL<<endl;
+     } else nStopL = 0;
+     // Preparation des parametres pour iteration suivante
+     ATGA = ATGA_Try;
+     BETA = BETA_Try;
+     param_tr = paramTry_tr;
+     Param = paramTry;
+     Lambda *= 1./Lambda_Fac;
+     // Arret ?
+     if (oldChi2-Chi2<stopChi2) {
+       // arret normal, convergence
+        Lambda = 0;
+        if (debugLevel >= 2)
+          cout<<"Arret>> demande car Chi2 decroit et oldChi2-Chi2= "
+	      <<oldChi2-Chi2<<"<"<<stopChi2<<endl;
+     } else if (nStopLent>0 && nStopL >= nStopLent) {
+       // arret demande par SetStopLent, variation lente des parametres
+       Lambda = 0.;
+       if (debugLevel >= 2) 
+         cout<<"Arret>> demande car Chi2 decroit et nStop(lent)= "
+             <<nStopL<<">="<<nStopLent<<endl;
+     }
+     oldChi2 = Chi2;
+     if (debugLevel >= 2) cout<<"Succes essai: Lambda divided by "
+                              <<Lambda_Fac<<" -> "<<Lambda<<endl;
+   } else {
+     // ****************** le Chi2 est remonte ******************
+     nStopL = 0;
+     if(nStopMx>0 && Chi2-oldChi2<stopChi2SMx) {
+       // Il est remonte tres peu, comment se comporte les parametres?
+       int k=0;
+       for (int i=0; i<mNPar; i++) if( (!fixParam[i]) &&
+              (fabs(param_tr(i)-paramTry_tr(i))<Eps(i))) k++;
+       if (k==mNParFree) nStop++; // Tous les parametres ont peu varies
+          else nStop=0;
+       if (debugLevel>=2) cout<<k<<" parametres sur "<<mNParFree
+                              <<" ont peu varies, nStop="<<nStop<<endl;
+     } else nStop = 0;
+     // Preparation des parametres pour iteration suivante
+     Lambda *= Lambda_Fac;
+     // Arret ?
+     if (nStopMx>0 && nStop>=nStopMx) {
+       // arret normal, convergence car ci2 varie peu et parametres aussi
+       Lambda = 0.;
+       if (debugLevel >= 2) 
+         cout<<"Arret>> demande car Chi2 croit et nstop= "
+             <<nStop<<">="<<nStopMx<<endl;
+     }
+     Chi2 = oldChi2;
+     if (debugLevel >= 2)
+       cout<<"Echec essai: Lambda multiplied by "<<Lambda_Fac
+           <<" -> "<<Lambda<<" nStop="<<nStop<<endl;
+   }
+
+ } // fin des iterations
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Recalcul du Chi2 a partir des parametres courants (`par==NULL')
+  ou a partir du tableau de parametres `par'.
+  Retourne le chi2 et le nombre de degres de liberte.
+  Si nddl<0 probleme.
+*/
+double GeneralFit::ReCalChi2(int& nddl, double *par)
+{
+double c2 = -1.;
+if(par==NULL) par = Param.Data();
+if( mData->NData() <= 0 ) {nddl = -100; return 0.;}
+
+if( mFunction != NULL ) {
+
+  double e,result;
+
+  nddl = 0; c2  = 0.;
+  for(int k=0; k<mData->NData(); k++) {
+    if (! mData->mOK[k]) continue;
+    e = mData->mErr[k];
+    result = mFunction->Value(&mData->mXP[mNVar*k],par);
+    c2 += (mData->mF[k]-result)*(mData->mF[k]-result)/(e*e);
+    nddl++;
+  }
+  nddl -= mNParFree;
+
+  return c2;
+
+} else if( mFuncXi2 != NULL ) {
+
+  c2 = mFuncXi2->Value(*mData,par,nddl);
+  nddl -= mNParFree;
+  return c2;
+
+} else {
+
+  cout<<"GeneralFit::ReCalChi2_Erreur: mFunction && mFuncXi2 == NULL"<<endl;
+  nddl = -1;
+  return c2;
+}
+
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Retourne une structure ``GeneralFitData'' contenant
+  les residus du fit (val-func) pour les points du fit.
+  Si ``clean'' est ``true''
+  seules les donnees valides de ``data'' sont copiees.
+  Si ``clean'' est ``false'' (defaut) toutes les donnees
+  sont copiees et la taille totale de ``data'' est allouee
+  meme si elle est plus grande que la taille des donnees stoquees.
+*/
+GeneralFitData GeneralFit::DataResidus(bool clean)
+{
+if(!mData || !mFunction)
+  throw(NullPtrError("GeneralFit::DataResidus: NULL pointer\n"));
+GeneralFitData datres(*mData,clean);
+for(int k=0; k<datres.NData(); k++)
+  datres.mF[k] -=
+    mFunction->Value(&datres.mXP[datres.NVar()*k],Param.Data());
+return datres;
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Retourne une structure ``GeneralFitData'' contenant
+  les valeurs de la fonction fittee pour les points du fit.
+  (voir commentaires pour ``clean'' dans ``DataResidus'')
+*/
+GeneralFitData GeneralFit::DataFunction(bool clean)
+{
+if(!mData || !mFunction)
+  throw(NullPtrError("GeneralFit::DataFunction: NULL pointer\n"));
+GeneralFitData datres(*mData,clean);
+for(int k=0; k<datres.NData(); k++)
+  datres.mF[k] =
+    mFunction->Value(&datres.mXP[datres.NVar()*k],Param.Data());
+return datres;
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  Imprime le commentaire lie a l'erreur rc retournee par Fit()
+  (voir le commentaire de la methode `Fit()')
+*/
+void GeneralFit::PrintFitErr(int rc)
+{
+int n;
+if(rc>0) return;
+
+if(rc==-1)
+  cout<<"rc = "<<rc<<"  : number of degres of freedom is <0"<<endl;
+  //cout<<"rc = "<<rc<<"  : le nombre de degre de liberte est <0"<<endl;
+
+else if(rc==-10)
+  cout<<"rc = "<<rc<<" : matrix inversion has failed"<<endl;
+  //cout<<"rc = "<<rc<<" : l'inversion de la matrice des erreurs n'a pas ete possible"<<endl;
+
+else if(rc==-11)
+  cout<<"rc = "<<rc<<" : one of the diagonal elements of covariance matrix is <=0"<<endl;
+  //cout<<"rc = "<<rc<<" : un element diagonal de la matrice des covariances est <=0"<<endl;
+
+else if(rc==-20)
+  cout<<"rc = "<<rc<<" : failed convergence (nstep>nNstepMX="<<maxStep<<")"<<endl;
+  //cout<<"rc = "<<rc<<" : le fit n'a pas converge (nstep>nNstepMX="<<maxStep<<")"<<endl;
+
+else if(rc>-200 && rc<=-100) {
+  n = -100-rc;
+  cout<<"rc = "<<rc<<" : parameter "<<n<<" ("<<nameParam[n]
+      <<") has been initialized outside limits"<<endl;
+  //cout<<"rc = "<<rc<<" : le parametre "<<n<<" ("<<nameParam[n]
+  //    <<") est initialise hors limites"<<endl;
+}
+
+else if(rc>-300 && rc<=-200) {
+  n = -200-rc;
+  cout<<"rc = "<<rc<<" : parameter "<<n<<" ("<<nameParam[n]
+      <<") has reached its upper limit"<<endl;
+  //cout<<"rc = "<<rc<<" : le parametre "<<n<<" ("<<nameParam[n]
+  //    <<") atteint sa limite inferieure"<<endl;
+}
+
+else if(rc>-400 && rc<=-300) {
+  n = -300-rc;
+  cout<<"rc = "<<rc<<" : parameter "<<n<<" ("<<nameParam[n]
+      <<") has reached its lower limit"<<endl;
+  //cout<<"rc = "<<rc<<" : le parametre "<<n<<" ("<<nameParam[n]
+  //    <<") atteint sa limite superieure"<<endl;
+}
+
+else
+  cout<<"rc = "<<rc<<" : unknown error"<<endl;
+  //cout<<"rc = "<<rc<<" : type d'erreur inconnue"<<endl;
+
+}
+
+//////////////////////////////////////////////////////////////////////
+// Fonctions privees
+//////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////
+void GeneralFit::write_in_step(double ci2,TVector<r_8>& par)
+{
+if(FileStep==NULL) return;
+fprintf(FileStep,"%d %d %f",mNtry,nStep,ci2);
+for(int i=0; i<mNPar; i++) fprintf(FileStep," %f",par(i));
+fprintf(FileStep,"\n");
+}
+
+//////////////////////////////////////////////////////////////////////
+void GeneralFit::TryFunc(TVector<r_8>& par,TVector<r_8>& par_tr)
+{
+  BETA_Try = 0;
+  ATGA_Try = 0;
+  Chi2  = 0;
+  TVector<r_8> deriv(mNPar);
+  TVector<r_8> derivtr(mNPar);
+  double result;
+
+  for(int k=0; k<mData->NData(); k++) {
+    if (! mData->mOK[k]) continue;
+    double e = mData->mErr[k];
+    if(mNParBound==0)
+       result = mFunction->Val_Der(&mData->mXP[mNVar*k]
+                                  ,par.Data(),derivtr.Data());
+    else {
+       result = mFunction->Val_Der(&mData->mXP[mNVar*k]
+                                  ,par.Data(),deriv.Data());
+       dtr_vers_dp(deriv,par_tr,derivtr);
+    }
+    double Gkk = 1/(e*e);
+    double Ck  = mData->mF[k] - result;
+    Chi2 += Ck*Ck*Gkk;
+    for(int j=0; j<mNPar; j++) {
+      if( fixParam[j] ) continue;
+      for(int i=0; i<mNPar; i++)
+        if(!fixParam[i]) ATGA_Try(i,j) += derivtr(i)*Gkk*derivtr(j);
+      BETA_Try(j) += derivtr(j) * Gkk * Ck;
+    }
+  }
+
+  if (debugLevel >= 3) {
+    cout<<"Try: matrice ( At * G * A )_Try\n";
+    cout<<ATGA_Try;
+    cout<<"Try: beta_Try:\n";
+    cout<<BETA_Try;
+  }
+}
+
+//////////////////////////////////////////////////////////////////////
+void GeneralFit::TryXi2(TVector<r_8>& par,TVector<r_8>& par_tr)
+{
+  double c, *parloc;
+  BETA_Try = 0;
+  ATGA_Try = 0;
+  Chi2  = 0;
+
+  parloc = par.Data();  // He oui, encore ces ... de const*
+  Chi2 = mFuncXi2->Value(*mData,parloc,mNddl);
+  mNddl -= mNParFree;
+
+  // Calcul des derivees du Xi2 (vecteur du gradient)
+  {for(int i=0;i<mNPar; i++) {
+    if( fixParam[i] ) continue;
+    c = c_dtr_vers_dp(i,par_tr(i));
+    BETA_Try(i) = -0.5 * mFuncXi2->Derivee(*mData,i,parloc) * c;
+  }}
+
+  // Calcul des derivees 2sd du Xi2 (matrice de courbure ou 0.5*Hessien)
+  double c1,c2;
+  {for(int i=0;i<mNPar; i++) {
+    if( fixParam[i] ) continue;
+    c1 = c_dtr_vers_dp(i,par_tr(i));
+    for(int j=0;j<mNPar; j++) {
+      if( fixParam[j] ) continue;
+      c2 = c_dtr_vers_dp(j,par_tr(j));
+      ATGA_Try(i,j) = 0.5 * mFuncXi2->Derivee2(*mData,i,j,parloc) *c1*c2;
+    }
+  }}
+  // et on symetrise car d/di(dC2/dj) =  d/dj(dC2/di) mathematiquement
+  // mais malheureusement pas numeriquement.
+  if( mNPar>1) {
+    for(int i=0;i<mNPar-1; i++) {
+      if( fixParam[i] ) continue;
+      for(int j=i+1;j<mNPar; j++) {
+        if( fixParam[j] ) continue;
+        c1 = 0.5*(ATGA_Try(i,j) + ATGA_Try(j,i));
+        ATGA_Try(i,j) = c1;
+        ATGA_Try(j,i) = c1;
+      }
+    }
+  }
+  
+  if (debugLevel >= 3) {
+    cout<<"Try: matrice ( At * G * A )_Try\n";
+    cout<<ATGA_Try;
+    cout<<"Try: beta_Try:\n";
+    cout<<BETA_Try;
+  }
+}
+
+//////////////////////////////////////////////////////////////////////
+void GeneralFit::CheckSanity()
+{
+  ASSERT( mData != NULL );
+  ASSERT( mFunction != NULL || mFuncXi2 != NULL );
+  if( mFunction != NULL ) {
+    ASSERT( mFunction->NVar() == mNVar );
+    ASSERT( mData->NVar() == mNVar );
+  }
+  ASSERT( mNParFree > 0 && mNParFree <= mNPar );
+  ASSERT( mNParBound >= 0 && mNParBound <= mNPar );
+  ASSERT( mNParFree <= mData->NDataGood() );
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  \verbatim
+  C = (min+max)/2
+  D = (max-min)/Pi
+  \endverbatim
+*/
+void GeneralFit::Set_Bound_C_D(int i)
+{
+  // ASSERT(i>=0 && i<mNPar);
+ C(i) = D(i) = 0.;
+ if( !boundParam[i] || fixParam[i] ) return;
+ C(i) = (maxParam(i)+minParam(i))/2.;
+ D(i) = (maxParam(i)-minParam(i))/M_PI;
+}
+
+//////////////////////////////////////////////////////////////////////
+void GeneralFit::Set_Bound_C_D()
+{
+ for(int i=0;i<mNPar;i++) Set_Bound_C_D(i);
+ if(debugLevel>= 2) {
+   cout<<"Set_Bound_C_D: C=\n";
+   cout<<C;
+   cout<<"Set_Bound_C_D: D=\n";
+   cout<<D;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  \verbatim
+  tr = tan( (p-C)/D )
+  \endverbatim
+*/
+double GeneralFit::p_vers_tr(int i,double p)
+{
+ // ASSERT(i>=0 && i<mNPar);
+ double tr = p;
+ if(boundParam[i]) tr = tan((p-C(i))/D(i));
+ return(tr);
+}
+
+//////////////////////////////////////////////////////////////////////
+TVector<r_8> GeneralFit::p_vers_tr(TVector<r_8> const& p)
+{
+ TVector<r_8> tr(p,false);
+ for(int i=0;i<mNPar;i++) {
+   if( fixParam[i] || ! boundParam[i] ) continue;
+   tr(i) = p_vers_tr(i,p(i));
+ }
+ return(tr);
+}
+
+//////////////////////////////////////////////////////////////////////
+void GeneralFit::p_vers_tr(TVector<r_8> const& p,TVector<r_8>& tr)
+{
+ for(int i=0;i<mNPar;i++) {
+   if( fixParam[i] ) continue;
+   if( ! boundParam[i] ) tr(i) = p(i);
+     else tr(i) = tan((p(i)-C(i))/D(i));
+ }
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  \verbatim
+  p = C+D*atan(tr)
+  \endverbatim
+*/
+double GeneralFit::tr_vers_p(int i,double tr)
+{
+ // ASSERT(i>=0 && i<mNPar);
+ double p = tr;
+ if(boundParam[i]) p = C(i)+D(i)*atan(tr);
+ return(p);
+}
+
+//////////////////////////////////////////////////////////////////////
+TVector<r_8> GeneralFit::tr_vers_p(TVector<r_8> const& tr)
+{
+ TVector<r_8> p(tr,false);
+ for(int i=0;i<mNPar;i++) {
+   if( fixParam[i] || ! boundParam[i] ) continue;
+   p(i) = tr_vers_p(i,tr(i));
+ }
+ return(p);
+}
+
+//////////////////////////////////////////////////////////////////////
+void GeneralFit::tr_vers_p(TVector<r_8> const& tr,TVector<r_8>& p)
+{
+ for(int i=0;i<mNPar;i++) {
+   if( fixParam[i] ) continue;
+   if( ! boundParam[i] ) p(i) = tr(i);
+     else p(i) = C(i)+D(i)*atan(tr(i));
+ }
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  \verbatim
+  dtr = (1+tr**2)/D * dp = (1+tan( (p-C)/D )**2)/D * dp = coeff * dp
+  attention: df/dp = (1+tr**2)/D * dF/dtr = coeff * dF/dtr
+  \endverbatim
+*/
+double GeneralFit::c_dp_vers_dtr(int i,double tr)
+{
+ // ASSERT(i>=0 && i<mNPar);
+ double coeff = 1.;
+ if(boundParam[i]) coeff = (1.+tr*tr)/D(i);
+ return(coeff);
+}
+
+//////////////////////////////////////////////////////////////////////
+TVector<r_8> GeneralFit::dp_vers_dtr(TVector<r_8> const& dp,TVector<r_8> const& tr)
+{
+ TVector<r_8> dtr(dp,false);
+ for(int i=0;i<mNPar;i++) {
+   if( fixParam[i] || ! boundParam[i] ) continue;
+   dtr(i) *= c_dp_vers_dtr(i,tr(i));
+ }
+ return(dtr);
+}
+
+//////////////////////////////////////////////////////////////////////
+void GeneralFit::dp_vers_dtr(TVector<r_8> const& dp,TVector<r_8> const& tr,TVector<r_8>& dtr)
+{
+ for(int i=0;i<mNPar;i++) {
+   if( fixParam[i] ) continue;
+   if( ! boundParam[i] ) dtr(i) = dp(i);
+     else dtr(i) = (1.+tr(i)*tr(i))/D(i) * dp(i);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  \verbatim
+  dp = D/(1+tr**2) * dtr = coeff * dtr
+  attention: df/dtr = D/(1+tr**2) * dF/dp = coeff * dF/dp
+  \endverbatim
+*/
+double GeneralFit::c_dtr_vers_dp(int i,double tr)
+{
+  // ASSERT(i>=0 && i<mNPar);
+ double coeff = 1.;
+ if(boundParam[i]) coeff = D(i)/(1.+tr*tr);
+ return(coeff);
+}
+
+//////////////////////////////////////////////////////////////////////
+TVector<r_8> GeneralFit::dtr_vers_dp(TVector<r_8> const& dtr,TVector<r_8> const& tr)
+{
+ TVector<r_8> dp(dtr,false);
+ for(int i=0;i<mNPar;i++) {
+   if( fixParam[i] || ! boundParam[i] ) continue;
+   dp(i) *= c_dtr_vers_dp(i,tr(i));
+ }
+ return(dp);
+}
+
+//////////////////////////////////////////////////////////////////////
+// inline fonction pour aller + vite dans le try()
+//void GeneralFit::dtr_vers_dp(TVector<r_8> const& dtr,TVector<r_8> const& tr,TVector<r_8>& dp)
+
+//////////////////////////////////////////////////////////////////////
+/*!
+  \verbatim
+  1-/ Redefinit dp pour qu'il soit superieur a minStepDeriv
+  2-/ Redefinit dp pour que p+/-dp reste dans les limites (parametre borne)
+  Si hors limites alors:
+      p-dp <= min_p : dp = (p-min_p)*dist
+      p+dp >= max_p : dp = (max_p-p)*dist
+  \endverbatim
+*/
+int GeneralFit::put_in_limits_for_deriv(TVector<r_8> const& p,TVector<r_8>& dp,double dist)
+{
+ int nchanged = 0;
+ bool changed;
+ double dp_old;
+
+ for(int i=0;i<mNPar;i++) {
+   if( fixParam[i] ) {dp(i)=0.; continue;} // Pas calcul derivee pour param fixe
+
+   if( fabs(dp(i))<minStepDeriv(i) ) {
+     // On ne redefinit dp que si minStepDeriv>0.
+     dp_old = dp(i);
+     if(dp(i)>=0.) dp(i) = minStepDeriv(i); else dp(i) = -minStepDeriv(i);
+     if(debugLevel>=2)
+       cout<<"put_in_limits_for_deriv(range) dp["<<i<<"]=abs("<<dp_old
+           <<") <"<<minStepDeriv(i)<<" changed to "<<dp(i)<<endl;
+   }
+
+   if( !boundParam[i] ) continue;
+
+   changed = false;
+   if( p(i)-dp(i)<=minParam(i) ) {
+     dp_old = dp(i);
+     dp(i) = dist*(p(i)-minParam(i));
+     changed = true;
+     if(debugLevel>=2)
+       cout<<"put_in_limits_for_deriv(min) p["<<i<<"]="<<p(i)<<" >="
+           <<minParam(i)<<" .. dp="<<dp_old<<" -> dp="<<dp(i)<<endl;
+   }
+
+   if( p(i)+dp(i)>=maxParam(i) ) {
+     dp_old = dp(i);
+     dp(i) = dist*(maxParam(i)-p(i));
+     changed = true;
+     if(debugLevel>=2)
+       cout<<"put_in_limits_for_deriv(max) p["<<i<<"]="<<p(i)<<" <="
+           <<maxParam(i)<<" .. dp="<<dp_old<<" -> dp="<<dp(i)<<endl;
+   }
+
+   if(changed) nchanged++;
+ }
+
+ return nchanged;
+}
+
Index: /tags/V_Dec2002/SophyaLib/NTools/generalfit.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/generalfit.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/generalfit.h	(revision 2309)
@@ -0,0 +1,260 @@
+// This may look like C code, but it is really -*- C++ -*-
+#ifndef GENERALFIT_SEEN
+#define GENERALFIT_SEEN
+
+#include "pexceptions.h"
+#include "tvector.h"
+#include "generaldata.h"
+
+namespace SOPHYA {
+
+//================================================================
+// GeneralFunction
+//================================================================
+
+//! Classe de fonctions parametrees a plusieurs variables
+class GeneralFunction {
+public:
+  GeneralFunction(unsigned int nVar, unsigned int nPar);
+  virtual ~GeneralFunction();
+
+  //! Valeur de la fonction a definir par l'utilisateur (fct virtuelle pure)
+  virtual double Value(double const xp[], double const* parm)=0;
+  //! Valeur de la fonction derivee selon les parametres pouvant etre redefinie
+  virtual double Val_Der(double const xp[], double const* parm
+                        , double* DgDpar);
+
+  void SetDeltaParm(int numPar, double delta=0.);
+  void SetDeltaParm(double const* dparam);
+
+  //! Retourne le nombre de variables Xi
+  inline int     NVar() const {return mNVar;}
+  //! Retourne le nombre de parametres Ai
+  inline int     NPar() const {return mNPar;}
+
+protected:
+  const int mNVar;  //!< nombre de variables f(x,y,z,...)
+  const int mNPar;  //!< nombre de parametres
+
+  double *deltaParm;
+  double *tmpParm;
+};
+
+//================================================================
+// GeneralFunc
+//================================================================
+
+//! Classe de fonctions parametrees a plusieurs variables type C
+class GeneralFunc : public GeneralFunction {
+public:
+  GeneralFunc(unsigned int nvar, unsigned int npar
+        ,double (*fun)(double const*,double const*) 
+        ,double (*funder)(double const*, double const*, double*)=NULL);
+  virtual ~GeneralFunc();
+
+  virtual double Value(double const xp[], double const* Par);
+  virtual double Val_Der(double const xp[],double const* parm
+                        , double* DgDpar);
+
+protected:
+  double (*tmpFun)   (double const*, double const*);
+  double (*tmpFunDer)(double const*, double const*, double*);
+};
+
+//================================================================
+// GeneralXi2
+//================================================================
+
+class GeneralFitData;
+
+//! Classe de Xi2 a plusieurs parametres
+class GeneralXi2 {
+public:
+  GeneralXi2(unsigned int nPar);
+  virtual ~GeneralXi2();
+
+  /*!
+  Valeur du Xi2 a definir par l'utilisateur (fct virtuelle pure)
+  a partir des donnees de `data'. l'utilisateur doit egalement
+  retourner le nombre de points de mesure utilises dans le calcul
+  du Xi2 (`ndataused').
+  */
+  virtual double Value(GeneralFitData& data, double* parm, int& ndataused)=0;
+  virtual double Derivee(GeneralFitData& data, int i, double* parm);
+  virtual double Derivee2(GeneralFitData& data, int i,int j, double* parm);
+
+  void SetDeltaParm(int numPar, double delta=0.);
+  void SetDeltaParm(double const* dparam);
+
+  //! Retourne le nombre de parametres Ai.
+  inline int     NPar() const {return mNPar;}
+
+protected:
+  const int mNPar;  //!< nombre de parametres
+
+  double *deltaParm;
+};
+
+//================================================================
+// GENERALFIT
+//================================================================
+
+//! Classe de fit d'une GeneralFunction sur une GeneralFitData
+class GeneralFit {
+public:
+  GeneralFit(GeneralFunction* f);
+  GeneralFit(GeneralXi2* f);
+  ~GeneralFit();
+
+  void            WriteStep(char *filename = NULL);
+  void            SetDebug(int level = 0);
+  void            SetMaxStep(int n = 100);
+  void            SetLambda_Fac(double fac = 10.);
+  void            SetStopChi2(double s = 0.01);
+  void            SetEps(double ep = 1.e-8);
+  void            SetEps(int n,double ep = 1.e-8);
+  void            SetStopMx(int nstopmx = 3, double stopchi2 = -1.);
+  void            SetStopLent(int nstoplent = 3);
+  void            SetFunction(GeneralFunction*);
+  void            SetFuncXi2(GeneralXi2*);
+  void            SetData(GeneralFitData*);
+  void            SetParam(int n,double value, double step
+                          ,double min=1., double max=-1.);
+  void            SetParam(int n,string const&
+                          ,double value, double step
+                          ,double min=1., double max=-1.);
+  void            SetParam(int n,double value);
+  void            SetStep(int n,double value);
+  void            SetMinStepDeriv(int i,double val = 0.);
+  void            SetMinStepDeriv(double val = 0.);
+  void            SetBound(int n,double min,double max);
+  void            SetBound(int n);
+  void            SetUnBound(int n);
+  void            SetUnBound();
+  void            SetFix(int n,double v);
+  void            SetFix(int n);
+  void            SetFree(int n);
+  void            SetFree();
+
+  double          GetParm(int);
+  TVector<r_8>    GetParm();
+  double          GetParmErr(int);
+  double          GetCoVar(int,int);
+  double          GetStep(int n);
+  double          GetMax(int n);
+  double          GetMin(int n);
+  //! Retourne le Chi2
+  inline double   GetChi2()    const {return Chi2;};
+  //! Retourne le Chi2 reduit
+  inline double   GetChi2Red() const {
+                        if(mNddl<=0) return (double) mNddl;
+                        return Chi2/(double) mNddl;
+                                     };
+  //! Retourne la precision de convergence pour le parametre i.
+  inline double   GetEps(int i) const {return Eps(i);};
+  //! Retourne le nombre de degres de liberte
+  inline int      GetNddl()    const {return mNddl;};
+  //! Retourne le nombre d'iterations
+  inline int      GetNStep()   const {return nStep;};
+  //! Retourne le nombre de variables
+  inline int      GetNVar()    const {return mNVar;};
+  //! Retourne le nombre de parametres
+  inline int      GetNPar()    const {return mNPar;};
+  //! Retourne le nombre de parametres libres
+  inline int      GetNFree()   const {return mNParFree;};
+  //! Retourne le nombre de parametres bornes
+  inline int      GetNBound()  const {return mNParBound;};
+  //! Retourne le nstop de convergence
+  inline int      GetNStop()   const {return nStop;};
+  //! Retourne le nstop de convergence lente.
+  inline int      GetNStopLent()   const {return nStopLent;};
+  //! Retourne le pointeur sur la GeneralFunction utilisee.
+  inline GeneralFunction*  GetFunction() const {return mFunction;};
+  //! Retourne le pointeur sur la GeneralFitData utilisee.
+  inline GeneralFitData*   GetGData() const {return mData;};
+
+  void            PrintStatus();
+  void            PrintFit();
+  void            PrintParm(int n);
+  void            PrintParm();
+
+  int             Fit();
+  double          ReCalChi2(int& nddl, double* par = NULL);
+  GeneralFitData  DataResidus(bool clean=true);
+  GeneralFitData  DataFunction(bool clean=true);
+  void            PrintFitErr(int rc);
+
+protected:
+  int             mNtry;       //!< numero d'appel de la routine de fit.
+  int             mNVar;       //!< nombre de variables f(x,y,z,...)
+  int             mNPar;       //!< nombre de parametres
+  int             mNParFree;   //!< nombre de parametres libres
+  int             mNParBound;  //!< nombre de parametres bornes
+  GeneralFunction*  mFunction;
+  GeneralXi2*       mFuncXi2;
+  GeneralFitData*   mData;
+
+  TVector<r_8>    Param;
+  TVector<r_8>    errParam;
+  TVector<r_8>    stepParam;
+  TVector<r_8>    minParam;
+  TVector<r_8>    maxParam;
+  TVector<r_8>    minStepDeriv;
+  TVector<r_8>    Eps;
+  unsigned short int* fixParam;
+  unsigned short int* boundParam;
+  string*             nameParam;
+  
+  double          Lambda_Fac;
+  double          stopChi2;
+  int             maxStep;
+  int             nStopMx;
+  double          stopChi2SMx;
+  int             nStopLent;
+  int             debugLevel;
+  FILE            *FileStep;
+  
+  TMatrix<r_8>    ATGA;
+  TVector<r_8>    BETA;
+  TMatrix<r_8>    ATGA_Try;
+  TVector<r_8>    BETA_Try;
+  TVector<r_8>    C;
+  TVector<r_8>    D;
+  
+  double          Chi2;
+  int             mNddl;
+  int             nStep;
+  int             nStop, nStopL;
+  double          Lambda;
+  
+  // Fonctions privees
+  void         write_in_step(double ci2,TVector<r_8>& par);
+  void         General_Init(void);
+  void         TryFunc(TVector<r_8>& par,TVector<r_8>& par_tr);
+  void         TryXi2(TVector<r_8>& par,TVector<r_8>& par_tr);
+  void         CheckSanity();
+  void         Set_Bound_C_D(int i);
+  void         Set_Bound_C_D();
+  double       p_vers_tr(int i,double p);
+  TVector<r_8> p_vers_tr(TVector<r_8> const& p);
+  void         p_vers_tr(TVector<r_8> const& p,TVector<r_8>& tr);
+  double       tr_vers_p(int i,double tr);
+  TVector<r_8> tr_vers_p(TVector<r_8> const& tr);
+  void         tr_vers_p(TVector<r_8> const& tr,TVector<r_8>& p);
+  double       c_dp_vers_dtr(int i,double tr);
+  TVector<r_8> dp_vers_dtr(TVector<r_8> const& dp,TVector<r_8> const& tr);
+  void         dp_vers_dtr(TVector<r_8> const& dp,TVector<r_8> const& tr,TVector<r_8>& dtr);
+  double       c_dtr_vers_dp(int i,double tr);
+  TVector<r_8> dtr_vers_dp(TVector<r_8> const& dtr,TVector<r_8> const& tr);
+  int          put_in_limits_for_deriv(TVector<r_8> const& p,TVector<r_8>& dp,double dist=0.66);
+  inline void dtr_vers_dp(TVector<r_8> const& dtr,TVector<r_8> const& tr,TVector<r_8>& dp)
+              {  for(int i=0;i<mNPar;i++)
+                   { if( fixParam[i] ) continue;
+                     if( ! boundParam[i] ) dp(i) = dtr(i);
+                       else dp(i) = D(i)/(1.+tr(i)*tr(i)) * dtr(i); }
+              };
+};
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/history_eros
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/history_eros	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/history_eros	(revision 2309)
@@ -0,0 +1,224 @@
+NTools from Outils++
+-----------> cspline.cc
+   Repository revision:	1.5	/projects/Eros/CVSEros/CodeCxx/Outils/cspline.cc,v
+   OK                   1.5
+-----------> cspline.h
+   Repository revision:	1.4	/projects/Eros/CVSEros/CodeCxx/Outils/cspline.h,v
+   OK                   1.4
+-----------> cvector.cc
+   Repository revision:	1.8	/projects/Eros/CVSEros/CodeCxx/Outils/cvector.cc,v
+   OK                   1.8
+-----------> cvector.h
+   Repository revision:	1.7	/projects/Eros/CVSEros/CodeCxx/Outils/cvector.h,v
+   OK                   1.7
+-----------> datacards.cc
+   Repository revision:	1.18	/projects/Eros/CVSEros/CodeCxx/Outils/datacards.cc,v
+   OK                   1.18
+-----------> datacards.h
+   Repository revision:	1.10	/projects/Eros/CVSEros/CodeCxx/Outils/datacards.h,v
+   MAJ                  1.11   (pour namespace std de KCC)
+-----------> datatypes.cc
+   Repository revision:	1.5	/projects/Eros/CVSEros/CodeCxx/Outils/datatypes.cc,v
+   OK                   1.5
+-----------> datatypes.h
+   Repository revision:	1.4	/projects/Eros/CVSEros/CodeCxx/Outils/datatypes.h,v
+   OK                   1.4
+-----------> dates.cc
+   Repository revision:	1.11	/projects/Eros/CVSEros/CodeCxx/Outils/dates.cc,v
+   OK                   1.11
+-----------> dates.h
+   Repository revision:	1.9	/projects/Eros/CVSEros/CodeCxx/Outils/dates.h,v
+   MAJ                  1.10
+-----------> difeq.cc
+   Repository revision:	1.9	/projects/Eros/CVSEros/CodeCxx/Outils/difeq.cc,v
+   OK                   1.9
+-----------> difeq.h
+   Repository revision:	1.6	/projects/Eros/CVSEros/CodeCxx/Outils/difeq.h,v
+   OK                   1.6
+-----------> dvlist.cc
+   Repository revision:	1.9	/projects/Eros/CVSEros/CodeCxx/Outils/dvlist.cc,v
+   OK                   1.9
+-----------> dvlist.h
+   Repository revision:	1.14	/projects/Eros/CVSEros/CodeCxx/Outils/dvlist.h,v
+   MAJ                  1.16
+-----------> fct1dfit.cc
+   Repository revision:	1.7	/projects/Eros/CVSEros/CodeCxx/Outils/fct1dfit.cc,v
+   OK                   1.7
+-----------> fct1dfit.h
+   Repository revision:	1.4	/projects/Eros/CVSEros/CodeCxx/Outils/fct1dfit.h,v
+   OK                   1.4
+-----------> fct2dfit.cc
+   Repository revision:	1.8	/projects/Eros/CVSEros/CodeCxx/Outils/fct2dfit.cc,v
+   MAJ                  1.9
+-----------> fct2dfit.h
+   Repository revision:	1.4	/projects/Eros/CVSEros/CodeCxx/Outils/fct2dfit.h,v
+   OK                   1.4
+-----------> generaldata.cc
+   Repository revision:	1.6	/projects/Eros/CVSEros/CodeCxx/Outils/generaldata.cc,v
+   MAJ                  1.9
+-----------> generaldata.h
+   Repository revision:	1.4	/projects/Eros/CVSEros/CodeCxx/Outils/generaldata.h,v
+   MAJ                  1.5
+-----------> generalfit.cc
+   Repository revision:	1.47	/projects/Eros/CVSEros/CodeCxx/Outils/generalfit.cc,v
+   MAJ                  1.51
+-----------> generalfit.h
+   Repository revision:	1.20	/projects/Eros/CVSEros/CodeCxx/Outils/generalfit.h,v
+   OK                   1.20
+-----------> hisprof.cc
+   Repository revision:	1.3	/projects/Eros/CVSEros/CodeCxx/Outils/hisprof.cc,v
+   OK                   1.3
+-----------> hisprof.h
+   Repository revision:	1.3	/projects/Eros/CVSEros/CodeCxx/Outils/hisprof.h,v
+   OK                   1.3
+-----------> histos.cc
+   Repository revision:	1.27	/projects/Eros/CVSEros/CodeCxx/Outils/histos.cc,v
+   OK                   1.27
+-----------> histos.h
+   Repository revision:	1.19	/projects/Eros/CVSEros/CodeCxx/Outils/histos.h,v
+   OK                   1.19
+-----------> histos2.cc
+   Repository revision:	1.17	/projects/Eros/CVSEros/CodeCxx/Outils/histos2.cc,v
+   MAJ                  1.19
+-----------> histos2.h
+   Repository revision:	1.15	/projects/Eros/CVSEros/CodeCxx/Outils/histos2.h,v
+   MAJ                  1.16
+-----------> integ.cc
+   Repository revision:	1.8	/projects/Eros/CVSEros/CodeCxx/Outils/integ.cc,v
+   OK                   1.8
+-----------> integ.h
+   Repository revision:	1.6	/projects/Eros/CVSEros/CodeCxx/Outils/integ.h,v
+   MAJ                  1.7
+-----------> linfit.cc
+   Repository revision:	1.4	/projects/Eros/CVSEros/CodeCxx/Outils/linfit.cc,v
+   OK                   1.4
+-----------> linfit.h
+   Repository revision:	1.7	/projects/Eros/CVSEros/CodeCxx/Outils/linfit.h,v
+   OK                   1.7
+-----------> matrix.cc
+   Repository revision:	1.17	/projects/Eros/CVSEros/CodeCxx/Outils/matrix.cc,v
+   MAJ                  1.18
+-----------> matrix.h
+   Repository revision:	1.8	/projects/Eros/CVSEros/CodeCxx/Outils/matrix.h,v
+   OK                   1.8
+-----------> median.cc
+   Repository revision:	1.1	/projects/Eros/CVSEros/CodeCxx/Outils/median.cc,v
+   OK                   1.1
+-----------> median.h
+   Repository revision:	1.1	/projects/Eros/CVSEros/CodeCxx/Outils/median.h,v
+   OK                   1.1
+-----------> nbconst.h
+   Repository revision:	1.6	/projects/Eros/CVSEros/CodeCxx/Outils/nbconst.h,v
+   MAJ                  1.7     juste un commentaire /**/ en //
+
+-----------> ntupintf.cc 
+   Repository revision: 1.3     /projects/Eros/CVSEros/CodeCxx/Outils/ntupintf.h,v
+   OK - ajoute
+-----------> ntupintf.h 
+   Repository revision: 1.4     /projects/Eros/CVSEros/CodeCxx/Outils/ntupintf.h,v
+   OK - ajoute
+-----------> ntuple.cc
+   Repository revision:	1.12	/projects/Eros/CVSEros/CodeCxx/Outils/ntuple.cc,v
+   OK                   1.19
+-----------> ntuple.h
+   MAJ                  1.15
+   Repository revision:	1.9	/projects/Eros/CVSEros/CodeCxx/Outils/ntuple.h,v
+-----------> outilsinit.cc
+   Repository revision:	1.2	/projects/Eros/CVSEros/CodeCxx/Outils/outilsinit.cc,v
+                        1.3   Ajout de XNTuple, pas fait
+-----------> outilsinit.h
+   Repository revision:	1.3	/projects/Eros/CVSEros/CodeCxx/Outils/outilsinit.h,v
+   OK                   1.3
+-----------> pclassids.h
+   Repository revision:	1.8	/projects/Eros/CVSEros/CodeCxx/Outils/pclassids.h,v
+   MAJ                  1.9     ClassId_XNTuple 
+-----------> peida.h
+   Repository revision:	1.4	/projects/Eros/CVSEros/CodeCxx/Outils/peida.h,v
+   OK                   1.4
+-----------> pemath.h
+   Repository revision:	1.2	/projects/Eros/CVSEros/CodeCxx/Outils/pemath.h,v
+   OK                   1.2
+-----------> perandom.cc
+   Repository revision:	1.11	/projects/Eros/CVSEros/CodeCxx/Outils/perandom.cc,v
+   OK                   1.11
+-----------> perandom.h
+   Repository revision:	1.8	/projects/Eros/CVSEros/CodeCxx/Outils/perandom.h,v
+   OK                   1.8
+-----------> poly.cc
+   Repository revision:	1.10	/projects/Eros/CVSEros/CodeCxx/Outils/poly.cc,v
+   MAJ                  1.12
+-----------> poly.h
+   Repository revision:	1.8	/projects/Eros/CVSEros/CodeCxx/Outils/poly.h,v
+   OK                   1.8
+-----------> pversion.cc
+   Repository revision:	1.4	/projects/Eros/CVSEros/CodeCxx/Outils/pversion.cc,v
+   OK                   1.4
+-----------> pversion.h
+   Repository revision:	1.37	/projects/Eros/CVSEros/CodeCxx/Outils/pversion.h,v
+   OK                   1.42    rien a faire - numero de version
+   
+-----------> rk4cdifeq.cc
+   Repository revision:	1.4	/projects/Eros/CVSEros/CodeCxx/Outils/rk4cdifeq.cc,v
+   OK                   1.4
+-----------> rk4cdifeq.h
+   Repository revision:	1.2	/projects/Eros/CVSEros/CodeCxx/Outils/rk4cdifeq.h,v
+   OK                   1.2
+-----------> simplesort.cc
+   Repository revision:	1.9	/projects/Eros/CVSEros/CodeCxx/Outils/simplesort.cc,v
+   OK                   1.9
+-----------> simplesort.h
+   Repository revision:	1.11	/projects/Eros/CVSEros/CodeCxx/Outils/simplesort.h,v
+   MAJ                  1.12    KCC std
+   
+-----------> simps2d.h
+   Repository revision:	1.1	/projects/Eros/CVSEros/CodeCxx/Outils/simps2d.h,v
+   OK                   1.1
+-----------> tabmath.cc
+   Repository revision:	1.3	/projects/Eros/CVSEros/CodeCxx/Outils/tabmath.cc,v
+   OK                   1.3
+-----------> tabmath.h
+   Repository revision:	1.2	/projects/Eros/CVSEros/CodeCxx/Outils/tabmath.h,v
+   OK                   1.2
+-----------> utils.cc
+   Repository revision:	1.9	/projects/Eros/CVSEros/CodeCxx/Outils/utils.cc,v
+   OK                   1.9
+-----------> utils.h
+   Repository revision:	1.14	/projects/Eros/CVSEros/CodeCxx/Outils/utils.h,v
+   OK                   1.15    KCC std
+-----------> xntuple.cc
+   Repository revision: 1.8     /projects/Eros/CVSEros/CodeCxx/Outils/xntuple.cc,v
+   OK
+-----------> xntuple.h
+   Repository revision: 1.6     /projects/Eros/CVSEros/CodeCxx/Outils/xntuple.h,v
+   OK
+
+NTools from Images++
+-----------> cimage.cc
+   Repository revision:	1.36	/projects/Eros/CVSEros/CodeCxx/Images/cimage.cc,v
+   MAJ                  1.38
+-----------> cimage.h
+   Repository revision:	1.22	/projects/Eros/CVSEros/CodeCxx/Images/cimage.h,v
+   OK                   1.22
+-----------> dynccd.cc
+   Repository revision:	1.20	/projects/Eros/CVSEros/CodeCxx/Images/dynccd.cc,v
+   OK                   1.20
+-----------> dynccd.h
+   Repository revision:	1.11	/projects/Eros/CVSEros/CodeCxx/Images/dynccd.h,v
+   OK                   1.11
+-----------> imageop.cc
+   Repository revision:	1.27	/projects/Eros/CVSEros/CodeCxx/Images/imageop.cc,v
+   MAJ                  1.28    NoiseFiltImage
+-----------> imageop.h
+   Repository revision:	1.17	/projects/Eros/CVSEros/CodeCxx/Images/imageop.h,v
+   MAJ                  1.18    
+-----------> rzimage.cc
+   Repository revision:	1.29	/projects/Eros/CVSEros/CodeCxx/Images/rzimage.cc,v
+   OK                   1.29
+-----------> rzimage.h
+   Repository revision:	1.13	/projects/Eros/CVSEros/CodeCxx/Images/rzimage.h,v
+   OK                   1.13
+-----------> rzvect.h
+   Repository revision:	1.6	/projects/Eros/CVSEros/CodeCxx/Images/rzvect.h,v
+   OK                   1.6
+
+
Index: /tags/V_Dec2002/SophyaLib/NTools/imageop.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/imageop.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/imageop.cc	(revision 2309)
@@ -0,0 +1,1314 @@
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "simplesort.h"
+#include "nbmath.h"
+#include "histos.h"
+#include "datatypes.h"
+#include "imageop.h"
+#include "nbtri.h"
+
+
+//++
+//  Module	Operations sur les images (C++)
+//  Lib	Images++
+//  include	imageop.h
+//
+//	Operations sur les images.
+//--
+
+
+// Outils prives.
+template <class T>
+float RzCmvSigmaCiel(T const * pix,int nx,int ny,int ndata,int bin,
+		     int taille,float frac,int deg,
+		     float low,float high,int deb);
+
+#ifdef IMGRGCHECK
+#define CHECKIMG2(_img_,_x_,_y_)                                  \
+      if ((_x_ >= (_img_).siz_x) || (_y_ >= (_img_).siz_y) ||              \
+          (_x_ < 0) || (_y_ < 0)) THROW(rangeCheckErr);  \
+      if (!(_img_).ImagePtr()) THROW(nullPtrErr)
+#else
+#if defined(IMGVOIDCHECK)
+#define CHECKIMG2(_img_,_x_,_y_) \
+      if (!(_img_).ImagePtr()) THROW(NullPtrErr)
+#else
+#define CHECKIMG2(_img_,_x_,_y_)
+#endif
+#endif /* IMGRGCHECK */
+
+// Les fonctions
+
+/* Nouvelle-Fonction */
+
+template <class T>
+void CleanImagesOld(int nImg, Image<T>** imgTab, double nSig,
+                 double lowbad, double highbad)
+
+/*  Nettoie une serie d'image a partir de l'histo de la  */
+/* serie de valeurs pour chaque pixel (Voir E. Aubourg)  */
+
+{
+  if (lowbad < MinRange((T)0))
+    lowbad = MinRange((T)0);
+
+  if (highbad > MaxRange((T)0))
+    highbad = MaxRange((T)0);
+
+  if (lowbad >= highbad)
+    {lowbad = MinRange((T)0); highbad = MaxRange((T)0);}
+  Histo h(lowbad, highbad, 500);
+
+  for (int i=0; i<imgTab[0]->XSize(); i++)
+    for (int j=0; j<imgTab[0]->YSize(); j++) {
+      h.Zero();
+      int k;
+      for (k=0; k<nImg; k++)
+        h.Add((*imgTab[k])(i,j));
+      float x0, s0=0;
+      x0 = h.CleanedMean(s0);
+      float low = x0 - s0*nSig; if (low < lowbad) low = lowbad;
+      float hi  = x0 + s0*nSig; // if (hi  > highbad) hi = highbad;
+      for (k=0; k<nImg; k++)
+        if ((*imgTab[k])(i,j) > hi || (*imgTab[k])(i,j) < low)
+          (*imgTab[k])(i,j) = 0;
+    }
+}
+
+/* Nouvelle-Fonction */
+
+template <class T>
+//++
+void CleanImages(int nImg, Image<T>** imgTab, double nSig,
+                 double lowbad, double highbad)
+//
+//	Nettoie une serie de `nImg' images `imgTab' a partir
+//	d'une moyenne tronquee a `nSig' sigma
+//	de la serie de valeurs pour chaque pixel.
+//	Les valeurs des pixels sont prises entre `lowbad' et `highbad'.
+//--
+{
+  if (lowbad < MinRange((T)0))
+    lowbad = MinRange((T)0);
+
+  if (highbad > MaxRange((T)0))
+    highbad = MaxRange((T)0);
+
+  if (lowbad >= highbad)
+    {lowbad = MinRange((T)0); highbad = MaxRange((T)0);}
+  
+  double sx, sx2, sig, mean;
+  int n;
+
+  for (int i=0; i<imgTab[0]->XSize(); i++)
+    for (int j=0; j<imgTab[0]->YSize(); j++) {
+      sig = 1e20; mean = 0;
+      for (int l = 0; l<3; l++) {
+        double low = mean - nSig*sig;
+        if (low < lowbad) low = lowbad;
+        double high = mean + nSig*sig;
+        if (high > highbad) high = highbad;
+        sx = sx2 = n = 0;
+        for (int k=0; k<nImg; k++) {
+          double p = (*imgTab[k])(i,j);
+          if (p > low && p < high) {
+            sx += p;
+            sx2 += p*p;
+            n++;
+          }
+        }
+        if (n>0) {
+          mean = sx / n;
+          sig  = sqrt( sx2/n - (sx/n)*(sx/n) );
+        } // sinon on laisse tel quel, ca sera coupe...
+      }
+      double low = mean - nSig*sig;
+      if (low < lowbad) low = lowbad;
+      double high = mean + nSig*sig;
+      if (high > highbad) high = highbad;
+      for (int k=0; k<nImg; k++)
+        if ((*imgTab[k])(i,j) > high || (*imgTab[k])(i,j) < low)
+          (*imgTab[k])(i,j) = 0;
+    }
+}
+
+/* Nouvelle-Fonction */
+
+template <class T>
+//++
+float ImgFondCielHisto(Image<T> const& img, float binWidth, int degree, float frac,
+                       float low, float high, int debug)
+//
+//	Calcul du fond de ciel par histogrammation. L'histogramme
+//	va de `low' a `high' avec une largeur de bin `binWidth'.
+//	La valeur la plus probalbe est fittee par un polynome de degre
+//	`degree' en utilisant les bins entourant le maximum
+//	a `frac' pourcent de sa hauteur.
+//--
+{
+  // CHECKIMG2(img,0,0);
+
+  if (degree < 2 || degree > 3)
+    degree = 3;
+
+  if (frac <= 0 || frac >= 1)
+    frac = 0.5;
+
+  if (low < MinRange((T)0)+2)
+    low = MinRange((T)0)+2;
+
+  if (high > MaxRange((T)0)-2)
+    high = MaxRange((T)0)-2;
+
+  if (low >= high)
+    {low = MinRange((T)0); high = MaxRange((T)0);}
+
+// verifier binwidth
+
+//  if ( binWidth < 65536.0/img.XSize()*img.YSize() )
+//    binWidth = 65536.0/img.XSize()*img.YSize();
+
+  if (binWidth<0)
+    binWidth = 1;
+
+  if (debug > 1)
+    cout << __FUNCTION__ << " binWidth =" << binWidth <<
+      ", degree = " << degree <<
+      ", frac = "   << frac   <<
+      ", low = "    << low    <<
+      ", high = "   << high   << endl;
+
+  int nBins = int(((double)high-(double)low)/(double)binWidth + 1);
+  Histo hist(low, high, nBins);
+
+  int nPix = img.XSize()*img.YSize();
+  for (int i=0; i<nPix; i++)
+    hist.Add(img[i]);
+
+  hist(0) = 0;
+
+  float fd = hist.FitMax(degree, frac, debug);
+
+  (float&) img.fond = fd;
+
+  return fd;
+}
+
+
+/* Nouvelle-Fonction */
+
+template <class T>
+float ImgSigmaCiel(Image<T> const& img, int ndata, int binWidth,
+		   int taille, float frac, int degree,
+		   float low, float high, int debug)
+{
+  (float&) img.sigmaFond = RzCmvSigmaCiel(img.ImagePtr(), img.XSize(), img.YSize(),
+				 ndata, binWidth, taille, frac,
+				 degree, low, high, debug);
+  return img.sigmaFond;
+}
+
+
+/* Nouvelle-Fonction */
+
+template <class T>
+//++
+float RzCmvSigmaCiel(T const* pix,int nx,int ny,int ndata,int bin,
+		     int taille,float frac,int deg,
+		     float low,float high,int deb)
+//
+//	Calcul du fond de ciel par histogrammation
+//
+//| INPUT:
+//|   - pix   : tableau pix[nx][ny]
+//|   - nx,ny : dimensions du tableau pix
+//|   - ndata : nombre de donnees a utiliser
+//|   - bin   : largeur du bin en ADU
+//|   - taille: 1/2 dimension de l'histogramme en ADU
+//|   - frac  : fraction du maximum au dessus de laquelle on fite
+//|   - deg   : degre fit polynome sous la gaussienne (0 ou 2)
+//|   - low   : valeur basse limite en ADU
+//|   - high  : valeur haute limite en ADU
+//|   - deb   : flag de debug
+//--
+//++
+//| OUTPUT:
+//|   - retourne : le sigma du fond de ciel si OK
+//|                -1 si probleme definition
+//|                -2 si probleme allocation
+//|                -3 si probleme remplissage histogramme
+//|                -4 si probleme recherche maximum
+//|                -5 si probleme calcul fraction du maximum
+//|                -6 si probleme nombre de bin
+//|                -7 si probleme nombre de fit
+//| 
+//--
+//                // EA seul changement par rapport a la version C :
+//                // pix est un T*, en template. -> C++ necessaire.
+{
+FLOATDOUBLE X,Y,EY;
+double (*Fun) (double ,double *,double *);
+int_4 npar;
+double par[6], epar[6],minpar[6],maxpar[6],stepar[6],stochi2;
+int_4 i,j,i1,j1,j2,n,ip,nbin,inc,ibin0,max,imax,lmax,b1,b2;
+float *histo,*xbin,*ehisto,fwhm,rc;
+double vp,pxv;
+
+/* set reasonable parameters */
+Fun = Gauss1DPolF ;
+if ( deg<=1 ) deg=0;  else deg=2;
+low = ( low < 0 ) ? 0 : low;
+high = ( high > 65530 ) ? 65530 : high;
+if ( low >= high ) { low=0; high = 65530;}
+bin = ( bin <= 0 ) ? 1 : bin;
+nbin = int(2.*taille /bin + 1);
+if ( nbin < 20 ) nbin = 20;
+if ( nbin >= 65530 ) nbin = 65530;
+ibin0 = int(-nbin*bin/2.);
+inc = int(nx*ny / ndata); inc = int(sqrt( (double) inc ));
+inc = (inc<1) ? 1 : inc;
+if(deb>1)
+  { printf("Sigma_Ciel: pix[%d,%d] ndata=%d bin=%d taille=%d"
+          ,nx,ny,ndata,bin,taille);
+  printf(" frac=%f low=%g high=%g nbin=%d ibin0=%d inc=%d\n"
+        ,frac,low,high,nbin,ibin0,inc); }
+if ( nx < 5 || ny < 5 ) return (-1.);
+
+/* allocate place for histogramme */
+if ( (histo  = (float *) calloc(nbin, sizeof(float)) ) == NULL )
+       return(-2.);
+if ( (xbin   = (float *) calloc(nbin, sizeof(float)) ) == NULL )
+       {free(histo); return(-2.);}
+if ( (ehisto = (float *) calloc(nbin, sizeof(float)) ) == NULL )
+       {free(histo); free(xbin); return(-2.);}
+
+/* fill histogramme */
+ndata=0;
+for (j=1;j<ny-1;j=j+inc) { for (i=1;i<nx-1;i=i+inc) {
+  ip = (int)(*(pix+j*nx+i));
+  if ( ip < low || ip > high ) continue;
+  vp = (double) ip;
+  pxv = 0.; n=0;
+  for(j1=j-1;j1<=j+1;j1++) { for(i1=i-1;i1<=i+1;i1++) {
+    if ( i1 == i && j1 == j ) continue;
+    ip = (int)(*(pix+j1*nx+i1));
+    if ( ip < low || ip > high ) continue;
+    pxv += (double) ip;
+    n++;
+  } }
+  if ( n != 8 ) continue;
+  vp = vp - pxv/n;
+  ip = int((vp-ibin0)/bin);
+  if( ip<0 || ip >= nbin ) continue;
+  histo[ip]++;
+  ndata++;
+} }
+for(i=0;i<nbin;i++)
+  { xbin[i] = (float) ibin0 + ( (float) i + 0.5 ) * (float) bin;
+  ehisto[i] = (histo[i]<1.) ? -1. : sqrt((double) histo[i]);}
+
+if(deb>1) printf("     nombre de data corrects = %d\n",ndata);
+if( ndata < 1 ) {rc= -3.; goto END;}
+
+/* find maximum */
+max = -1; imax = -1;
+for(i=nbin-1;i>=0;i--) if(histo[i]>max) { max=int(histo[i]); imax=i;}
+if(deb>1) printf("     maxi histo = %d (bin=%d)\n",max,imax);
+if ( imax == -1 || imax == 0 || imax == nbin-1 ) {rc= -4.; goto END;}
+if(deb>2) {
+  for(i=imax-10;i<=imax+10;i++) if(i>=0 && i<nbin) printf(" %5f",xbin[i]);
+  printf("\n");
+  for(i=imax-10;i<=imax+10;i++) if(i>=0 && i<nbin) printf(" %5d",(int) histo[i]);
+  printf("\n"); }
+
+/* find limites a half maximum */
+lmax = (int) ( (float) max * 0.5 );
+for(b1=imax;b1>0;b1--)    if(histo[b1]<=lmax) break;
+for(b2=imax;b2<nbin;b2++)  if(histo[b2]<=lmax) break;
+fwhm = (xbin[b2]-xbin[b1]);
+if(deb>1) printf("     fwhm = %f (%d,%d)\n",fwhm,b1,b2);
+
+/* find limites a frac*max */
+lmax = (int) ( (float) max * frac ) + 1;
+if( lmax < 1 )
+   {if(deb>1) printf("     lmax=%d\n",lmax); rc= -5.; goto END;}
+for(b1=imax;b1>0;b1--)    if(histo[b1]<=lmax) break;
+for(b2=imax;b2<nbin;b2++)  if(histo[b2]<=lmax) break;
+
+n=0;
+for(i=b1;i<=b2;i++) if( histo[i] > 0 ) n++;
+if(deb>1) printf("     limites bin %d %d (v=%d) bin non nuls=%d\n"
+                ,b1,b2,lmax,n);
+/* pas assez de bin, on en ajoute artificiellement */
+/* 8 est une borne large pour fiter gauss + parab (3+3) */
+if( n < 8 ) {
+  j1 = b1; j2 = b2;
+  for(i=1;i<nbin;i++) {
+    if ( b1-i >= 0 ) j1=b1-i;
+    if ( b2+i < nbin ) j2=b2+i;
+    if ( histo[j1] > 0 ) n++;
+    if ( histo[j2] > 0 ) n++;
+    if( n >= 6 ) break;
+  }
+  b1 = j1; b2 = j2;
+  if(deb>1) printf("     Re-update des limites bin %d %d (v=%d) bin non nuls=%d\n"
+                  ,b1,b2,lmax,n);
+}
+if( n < 4 ) {rc= -6.; goto END;}
+ndata = n;
+
+/* fit dans les limites */
+npar = 3+deg+1; Set_FitFunDPol(deg);
+if(ndata<8) {npar=4; Set_FitFunDPol(0);}
+if(ndata<5) {npar=3; Set_FitFunDPol(-1);}
+X.fx  = xbin;
+Y.fx  = histo;
+EY.fx = ehisto;
+stochi2 = 0.0001;
+n = nbin;
+par[0] = max;
+par[1] = histo[imax-1]*xbin[imax-1]+histo[imax]*xbin[imax]+histo[imax+1]*xbin[imax+1];
+par[1] = par[1]/(histo[imax-1]+histo[imax]+histo[imax+1]);
+par[2] = (fwhm<1.) ? 1. : fwhm/2.36;
+par[3] = par[4] = par[5] = 0.;
+stepar[0] = par[0]/20.; stepar[1] = 1.; stepar[2] = par[2]/5.;
+stepar[3] = 1.; stepar[5] = 0.1;
+stepar[4] =  0.;
+for(i=0;i<6;i++) {minpar[i] = 1.; maxpar[i] = -1.;}
+minpar[2] = 0.1; maxpar[2] = 65530.;
+if(deb>1) printf("     choix de fit a %d parametres b1=%d,b2=%d,ndata=%d)\n"
+                ,npar,b1,b2,ndata);
+
+i = (deb>=3) ? deb-2 : 0 ;
+vp = FitFun(Fun,FITFUN_FLOAT,X,Y,EY,&n,b1,b2,par
+           ,epar,stepar,minpar,maxpar,npar,stochi2,50,i);
+
+if( vp<=0. && vp != -4. ) {rc= -7.; goto END;}
+rc = par[2];
+if(deb>1) printf("     sigma=%f (h=%f centrage=%f) xi2=%f (%f pour %d)\n"
+                ,rc,par[0],par[1],vp,vp/(n-npar),npar);
+
+END:
+free(histo); free(xbin); free(ehisto);
+return(rc);
+}
+
+/* ................................................................................. */
+/*                  Filtrage ( Convolution ) d' images                               */
+/* ................................................................................. */
+
+/* Nouvelle-Fonction */
+template <class T>
+//++
+Image<T> * FilterImage(Image<T> const * pim, Image<T> * pom, ImageR4 *matx)
+//
+//	Filtrage ( Convolution ) d'une image `pim' par une matrice carree
+//	representee par l'ImageR4 `matx'.
+//	Le resultat se retrouve dans `pom'.
+//	Si `pom' = NULL, elle est cree.
+//	`pim' et `pom' doivent avoir la meme taille.
+//--
+{
+ 
+float vpix, *mxe;
+bool fgcr;
+int i,j,k,l,m,n;
+int ndim, nd2;
+
+fgcr = false;
+
+if ((pim == NULL) || (matx == NULL))
+  { printf(" FilterImage_Erreur : pim ou matx = NULL ! \n");
+  return(NULL);  }
+if (matx->XSize() != matx->YSize())
+  { printf("FilterImage_Erreur: Filtrage par matrice carre uniquement (%d,%d)\n",
+            matx->XSize(), matx->YSize());  return(NULL); }
+ndim = matx->XSize();
+if ( (ndim < 3) || ((ndim%2) == 0) || (ndim > 25))
+  { printf("FilterImage_Erreur: Pb dimension matrice (%d) (Impair, entre 3 et 25)\n", ndim);
+  return(NULL); }
+if (pom == NULL)
+  {  pom = new Image<T>(pim->XSize(), pim->YSize(), false);   fgcr = true; }
+
+if ( (pim->XSize() != pom->XSize()) || (pim->YSize() != pom->YSize()) )
+  { printf("FilterImage_Erreur : Taille pim et pom differentes ! \n") ;
+  if (fgcr) delete pom;   return(NULL) ;}
+
+nd2 = ndim/2;
+
+/*  Traitement de la partie centrale */
+for(j=nd2; j<(pom->YSize()-nd2); j++)
+  {
+  for(i=nd2; i<(pom->XSize()-nd2); i++)
+    {
+    vpix = 0.;   mxe = matx->ImagePtr();
+    for(l=-nd2; l<=nd2; l++)
+      for(k=-nd2; k<=nd2; k++)
+         { vpix += (float)((*pim)((i+k), (j+l))) * (*mxe);
+         mxe++; }
+    (*pom)(i, j) = (T)vpix;
+    }
+  }
+
+/*  Traitement bord en Y  en haut */
+for(j=0; j<nd2; j++)
+  {
+  for(i=nd2; i<(pom->XSize()-nd2); i++)
+    {
+    vpix = 0.;  mxe = matx->ImagePtr();
+    for(l=-nd2; l<=nd2; l++)
+
+      for(k=-nd2; k<=nd2; k++)
+        {
+        m = i+k;  n = j+l;
+        if (n < 0)  n = 0;
+        vpix += (float)((*pim)(m, n)) * (*mxe);
+        mxe++;
+        }
+    (*pom)(i, j) = (T)vpix;
+    }
+  }
+
+/* Traitement bord en Y en bas  */
+for(j=(pom->YSize()-nd2); j<pom->YSize(); j++)
+  {
+  for(i=nd2; i<(pom->XSize()-nd2); i++)
+    {
+    vpix = 0.;  mxe = matx->ImagePtr();
+    for(l=-nd2; l<=nd2; l++)
+      for(k=-nd2; k<=nd2; k++)
+        {
+        m = i+k;  n = j+l;
+        if (n >= pim->YSize())  n = (pim->YSize()-1);
+        vpix += (float)((*pim)(m, n)) * (*mxe);
+        mxe++;
+        }
+    (*pom)(i, j) = (T)vpix;
+    }
+  }
+
+/*  traitement bords en X et coins */
+for(j=0; j<pom->YSize(); j++)
+  {
+  for(i=0; i<nd2; i++)
+    {
+    vpix = 0.;  mxe = matx->ImagePtr();
+    for(l=-nd2; l<=nd2; l++)
+      for(k=-nd2; k<=nd2; k++)
+        {
+        m = i+k;  n = j+l;
+        if (m < 0)  m = 0;
+        if (n < 0)  n = 0;
+        if (n >= pim->YSize())  n = (pim->YSize()-1);
+        vpix += (float)((*pim)(m, n)) * (*mxe);
+        mxe++;
+        }
+    (*pom)(i, j) = (T)vpix;
+    }
+  for(i=(pom->XSize()-nd2); i<pom->XSize(); i++)
+    {
+    vpix = 0.;  mxe = matx->ImagePtr();
+    for(l=-nd2; l<=nd2; l++)
+      for(k=-nd2; k<=nd2; k++)
+        {
+        m = i+k;  n = j+l;
+        if (m >= pim->XSize())  m = (pim->XSize()-1);
+        if (n < 0)  n = 0;
+        if (n >= pim->YSize())  n = (pim->YSize()-1);
+        vpix += (float)((*pim)(m, n)) * (*mxe);
+        mxe++;
+        }
+    (*pom)(i, j) = (T)vpix;
+    }
+  }
+
+
+return(pom);
+
+}
+
+/* Nouvelle-Fonction */
+//++
+ImageR4* NoiseFiltImage(ImageR4& img, ImageR4& filtre, DynCCD& dynccd)
+//	Calcule une image de bruit, a partir de "img" et de "dynccd"
+//	prenant en compte le filtre de convolution "filtre".
+//	L'image de bruit renvoyee contient les correlations de bruit entre
+//	pixels, du au filtrage (convolution) de l'image "img" par le 
+//	filtre "filtre".
+//--
+{
+  ImageR4* ImgBrt = NoiseImage(&img,&dynccd);
+
+  int i,j;  
+  for (i=0; i<ImgBrt->XSize(); i++)
+    for (j=0; j<ImgBrt->YSize(); j++)  (*ImgBrt)(i,j) =(*ImgBrt)(i,j) *(*ImgBrt)(i,j);
+
+  ImageR4 Filter2(filtre.XSize(), filtre.YSize()) ;
+  for (i=0; i<filtre.XSize(); i++)
+    for (j=0; j<filtre.YSize(); j++) (Filter2)(i,j) = filtre(i,j) * filtre(i,j);  
+ 
+  ImageR4* out2;
+  out2 = new ImageR4(ImgBrt->XSize(), ImgBrt->YSize());
+  FilterImage(ImgBrt, out2, &Filter2);   
+  for (i=0; i<out2->XSize(); i++)
+    for (j=0; j<out2->YSize(); j++)  (*out2)(i,j) =sqrt((*out2)(i,j));
+  delete ImgBrt;
+  return(out2);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+/* Nouvelle-Fonction    CMV 14/10/97 */
+template <class T>
+//++
+Image<T> * FilterStat(Image<T> const * pim, Image<T> * pom
+                     ,int N,int M,float lowbad,float highbad)
+//
+//	Filtrage median d'une image `(*pim)'.
+//	Le resultat se retrouve dans `(*pom)'.
+//	Si pom = NULL l'image de sortie est cree automatiquement.
+//	pim et pom doivent avoir la meme taille.
+//	Le masque de calcul du filtre median est un rectangle `N'x`M'
+//	La dynamique de l'image est `lowbad,highbad'.
+//	Si lowbad>=highbad dynamique infinie.
+//--
+{
+if(pim == NULL)
+  {printf(" FilterStat_Erreur : pim = NULL ! \n");
+  return(NULL);}
+if( N<=0 || M<=0 )
+  {printf("FilterStat_Erreur: Filtrage par matrice (%d,%d)\n",N,M);
+  return(NULL);}
+bool fgcr = false;
+if(pom == NULL)
+  {pom = new Image<T>(pim->XSize(), pim->YSize(), false);   fgcr = true;}
+if( (pim->XSize() != pom->XSize()) || (pim->YSize() != pom->YSize()) )
+  { printf("FilterImage_Erreur : Taille pim et pom differentes ! \n");
+  if(fgcr) delete pom;   return(NULL);}
+
+T low  = (T) lowbad;
+T high = (T) highbad;
+if(high>low) fgcr = true; else fgcr = false;
+
+N /= 2; M /= 2;
+double * tab = new double[(2*N+1)*(2*M+1)];
+
+for(int j=0;j<pom->YSize();j++) {
+  for(int i=0;i<pom->XSize();i++) {
+    int n=0;
+    for(int jj=j-M;jj<=j+M;jj++) {
+      if( jj<0 || jj >= pom->YSize() ) continue;
+      for(int ii=i-N;ii<=i+N;ii++) {
+        if( ii<0 || ii >= pom->XSize() ) continue;
+          if( fgcr && ( (*pim)(ii,jj)<=low || high<=(*pim)(ii,jj) ) ) continue;
+          tab[n] = (double) (*pim)(ii,jj);
+          n++;
+      }
+    }
+    if(n==0) (*pom)(i,j) = 0;
+    else if(n==1) (*pom)(i,j) = (T) tab[0];
+    else {
+      HeapSort(n,tab);
+      if(n%2==1) (*pom)(i,j) = (T) tab[(n-1)/2];
+      else (*pom)(i,j) = (T) (tab[n/2]+tab[n/2-1])/2.;
+    }
+  }
+}
+
+delete [] tab;
+return(pom);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+/* Nouvelle-Fonction    CMV 7/8/98 */
+template <class T>
+//++
+Image<T> * CSplineImage(Image<T> const & f1,double pxsz,double x0,double y0,int natural)
+//
+//	Fonction retournant un pointeur sur une image qui contient
+//	le Spline 3 a 2 dimensions de l'images f1 (NULL est retourne si probleme).
+//	`pxsz' est la taille du pixel de l'image retournee en considerant
+//	que l'image `f1' en entree a une taille de pixel egale a 1.
+//	`x0,y0' est le decalage eventuel a appliquer de l'image origine a
+//	l'image retournee, ce decalage etant mesure en unites de pixels
+//	de l'image origine (1).
+//	`natural' a la signification decrite dans la classe `CSpline2'.
+//	Attention, la taille de l'image retournee sera `nx/pxsz' et `ny/pxsz'.
+//	Pour eviter les problemes d'extrapolation sur les bords de l'image
+//	d'origine, il leurs est assigne la valeur du centre du pixel auquel ils
+//	appartiennent.
+//--
+{
+//// open for result
+int nx = f1.XSize();
+int ny = f1.YSize();
+float dum;
+dum = nx/pxsz;
+int dx = (int) (dum+0.5);
+dum = ny/pxsz;
+int dy = (int) (dum+0.5);
+cout<<"Taille image en entree: "<<nx<<" "<<ny<<endl
+    <<"Taille image en sortie: "<<dx<<" "<<dy<<" (pix size="<<pxsz<<")"<<endl
+    <<"Decalage en x="<<x0<<" en y="<<y0<<endl;
+if(nx<=1 || ny<=1) return NULL;
+if(dx<=0 || dy<=0) return NULL;
+
+Image<T> *f2 = NULL;
+TRY {
+  f2 = new Image<T>(dx,dy);
+} CATCHALL {
+  cout<<"Impossible d'ouvrir le fichier resultat"<<endl;
+  return NULL;
+} ENDTRY
+
+//// Spline 3 2D ... nx+2 pour tenir compte des effets de bords !
+double *x = new double[nx+2];
+double *y = new double[ny+2];
+double *z = new double[(nx+2)*(ny+2)];
+{
+int k;
+// Centre pixel (0,0) en (0.5,0.5) et on ajoute les coordonnees
+// des bords pour extrapolation sur tout l'intervalle.
+// Les coordonnees vont de [0,nx] et [0,ny] (valeurs extremes comprises).
+x[0] = 0.; x[nx+1] = nx;
+y[0] = 0.; y[ny+1] = ny;
+for(k=1;k<=nx;k++) x[k] = k-0.5;
+for(k=1;k<=ny;k++) y[k] = k-0.5;
+// Remplissage des valeurs avec effet de bord [0] et [nx+1],[ny+1].
+k = 0;
+int ii,jj;
+for(int j=0;j<ny+2;j++) {
+  jj = j-1;
+  if(jj<0) jj=0; else if(jj>=ny) jj=ny-1;
+  for(int i=0;i<nx+2;i++) {
+    ii = i-1;
+    if(ii<0) ii=0; else if(ii>=nx) ii=nx-1;
+    z[k] = (double) f1(ii,jj);
+    k++;
+  }
+}
+}
+
+CSpline2 spl(nx+2,x,ny+2,y,z,natural,true);
+spl.ComputeCSpline();
+
+*f2 = 0.;
+{
+// Attention au decalage possible !
+// Les valeurs vont de [0.5*pxsz,(dx-0.5)*pxsz] idem pour y...
+// a corriger eventuellement du decalage x0,y0.
+double xmin = -pxsz/10000., xmax = nx+pxsz/10000.;
+double ymin = -pxsz/10000., ymax = ny+pxsz/10000.;
+for(int j=0;j<dy;j++) {
+  double yy = (j+0.5)*pxsz - y0;
+  if( yy<=ymin || yy>=ymax ) continue;
+  for(int i=0;i<dx;i++) {
+    double xx = (i+0.5)*pxsz - x0;
+    if( xx<=xmin || xx>=xmax ) continue;
+    (*f2)(i,j) = (T) spl.CSplineInt(xx,yy);
+}}}
+
+//// nettoyage
+delete [] x;
+delete [] y;
+delete [] z;
+
+return f2;
+}
+//////////////////////////////////////////////////////////////////////////////
+
+
+
+/* Nouvelle-Fonction */
+int FondSigmaCiel(RzImage *pim, float low, float high,int pvsz
+              ,float nbsig1,float nbsig2,float nbsig3
+              ,float binsg,float frac,int modu,int deb)
+{
+int rc;
+
+  switch (pim->PixelType())
+    {
+    case kuint_2:
+      {
+      ImageU2 imt((RzImage&)(*pim));
+      rc = imt.FondSigmaCiel(low, high, pvsz, nbsig1, nbsig2, nbsig3, binsg, frac, modu, deb);
+      pim->fond = imt.fond;
+      pim->sigmaFond = imt.sigmaFond;
+      break;
+      }
+    case kint_2:
+      {
+      ImageI2 imt((RzImage&)(*pim));
+      rc = imt.FondSigmaCiel(low, high, pvsz, nbsig1, nbsig2, nbsig3, binsg, frac, modu, deb);
+      pim->fond = imt.fond;
+      pim->sigmaFond = imt.sigmaFond;
+      break;
+      }
+    case kint_4:
+      {
+      ImageI4 imt((RzImage&)(*pim));
+      rc = imt.FondSigmaCiel(low, high, pvsz, nbsig1, nbsig2, nbsig3, binsg, frac, modu, deb);
+      pim->fond = imt.fond;
+      pim->sigmaFond = imt.sigmaFond;
+      break;
+      }
+    case kr_4:
+      {
+      ImageR4 imt((RzImage&)(*pim));
+      rc = imt.FondSigmaCiel(low, high, pvsz, nbsig1, nbsig2, nbsig3, binsg, frac, modu, deb);
+      pim->fond = imt.fond;
+      pim->sigmaFond = imt.sigmaFond;
+      break;
+      }
+    default:
+      {
+      cout<<"FindSigmaCiel: type d'image non-prevu "<<(int) pim->PixelType()<<endl;
+      exit(-1);
+      }
+    }
+
+return(rc);
+}
+
+/* Nouvelle-Fonction */
+int CalFondImage(RzImage *pim, double low, double high, int action)
+
+/*  ATTENTION: Adaptation a partir d'une version C              */ 
+/*             CalculFond() de imgstat.c                        */
+ 
+/*  Cette fonction calcule le fond et le sigma du ciel a la CMV */
+/*  CMV / E.Aubourg / Reza                                      */
+/*  action Bit 0  CheckDyn()                                    */
+/*         Bit 1  ImgFondCielHisto()                            */
+/*         Bit 2  ImgSigmaCiel                                  */
+/*         Bit 3  FondSig2Ciel()                                */
+/*         Bit 1+2+3 (=14)   Fond_Ciel() + Sigma_Ciel() Si OK   */
+/*                            FondSig2Ciel()  sinon             */
+/*  action = 0  ou  >= 15  CheckDyn + Bit 1+2+3 (=14)           */
+/*  Rc=0 OK  Erreur Sinon                                       */
+/*  Sortie : Mise a jour de la struct RzImage                   */
+
+{
+int n,ok,rc,fga;
+float fnd, sg;
+
+int nbsig, vitesse, nbin;
+float minaff, maxaff, minpix, maxpix;
+float fracmax,fracnul,fracsat;
+char *meth;
+
+#define DBG  0
+
+if (action >= 15)   action = 15;
+if (action <= 0)  action = 15;
+fga = action;
+fnd = sg = -1.;
+ok = 1;
+
+if (action & 1)  
+  { pim->CheckDyn(low, high); 
+   action--;  }
+
+n = pim->XSize()*pim->YSize();
+
+if (action & 6)
+  {
+  int npu = (n/4 < 5000) ? 5000 : n/4;
+  meth = (char *)"Fond/Sig";
+  switch (pim->PixelType())
+    {
+    case kuint_2:
+      {
+      ImageU2 imt((RzImage&)(*pim));
+      if (action & 2) 
+        fnd = ImgFondCielHisto(imt, 1.0f, 2, 0.5f, (float)low, (float)high, DBG);
+      if (action & 4)
+        {  sg = ImgSigmaCiel(imt, npu, 1, 200, 0.1f, 2, 
+			     (float)low, (float)high, DBG);
+          if (sg < -1.e-3 )  ok = 0; }
+      break;
+      }
+    case kint_2:
+      {
+      ImageI2 imt((RzImage&)(*pim));
+      if (action & 2) 
+        fnd = ImgFondCielHisto(imt, 1.0f, 2, 0.5f, (float)low, (float)high, DBG);
+      if (action & 4)
+        {  sg = ImgSigmaCiel(imt, npu, 1, 200, 0.1f, 2,
+			     (float)low, (float)high, DBG);
+          if (sg < -1.e-3 )  ok = 0; }
+      break;
+      }
+    case kint_4:
+      {
+      ImageI4 imt((RzImage&)(*pim));
+      if (action & 2) 
+        fnd = ImgFondCielHisto(imt, 1.0f, 2, 0.5f, (float)low, (float)high, DBG);
+      if (action & 4)
+        {  sg = ImgSigmaCiel(imt, npu, 1, 200, 0.1f, 2, 
+			     (float)low, (float)high, DBG);
+          if (sg < -1.e-3 )  ok = 0; }
+      break;
+      }
+    case kr_4:
+      {
+      ImageR4 imt((RzImage&)(*pim));
+      if (action & 2) 
+        fnd = ImgFondCielHisto(imt, 1.0f, 2, 0.5f, (float)low, (float)high, DBG);
+      if (action & 4)
+        {  sg = ImgSigmaCiel(imt, npu, 1, 200, 0.1f, 2, 
+			     (float)low,(float) high, DBG);
+          if (sg < -1.e-3 )  ok = 0; }
+      break;
+      }
+
+    case kuint_4:
+    case kr_8:
+      cerr << "CalFondImage(RzImage *, ...) Unsupported image type (kuint_4/kr_8) " 
+           << (int) pim->PixelType() << "\n" ; 
+      break;
+    default:
+      cerr << "CalFondImage(RzImage *, ...) Unknown image type !! " << (int) pim->PixelType() << "\n" ;
+    break;
+    }
+
+  }
+
+if ( (action == 8) || (!ok && (action & 8)) )
+  {
+  fracmax = 0.85;   nbsig = 1;     vitesse = 3;
+  minpix = low;   maxpix = high;  nbin = 10000;
+  rc = RzFondSig2Ciel(pim, vitesse, fracmax, nbsig, nbin,  
+                      &minpix, &maxpix, &fnd, &sg,
+                      &minaff, &maxaff, &fracnul, &fracsat);
+  if (rc != 0)   ok = 0;
+  meth = (char *)"FondSig2";
+  }
+
+if (ok > 0)     /*  Mise a jour */ 
+  {
+  if (fnd > -1.)  pim->fond = fnd; 
+  if (sg > -1. )  pim->sigmaFond = sg;     
+  printf("CalculFond_Info: Meth=%s (%d) Fond/Sig= %5g %4g Nul/Sat=%d %d\n",
+         meth, fga, fnd, sg, pim->nbNul, pim->nbSat);
+  return(0);
+  }
+else
+  {
+  printf("CalculFond_Erreur: Action=%d  NbNul/Sat=%d %d\n",fga,
+          pim->nbNul, pim->nbSat);
+  return(1);
+  }
+
+}
+
+
+
+/* Nouvelle-Fonction */
+
+int RzFondSig2Ciel(RzImage * pim, int vitesse, float FracMax, int NbSigmas, int NBin,
+	           float *MinPix, float *MaxPix, float *Fond, float *SigFond,
+                   float *MinAff, float *MaxAff, float *FracNul, float *FracSature)
+
+/*   ATTENTION : Cette fonction a ete mis en C++, pour traiter des   */
+/*               RzImage a partir de la fonction FondSig2Ciel()      */
+/*               de imgstat.c                                        */
+/*                                        R. Ansari  04/95           */
+
+/*    Cette fonction calcule les valeurs suivantes pour une image    */
+/*    Arguments d'entree :                                           */
+/*     - pim : Pointeur RzImage                                      */
+/*     - vitesse : 1 pixel / vitesse pris en compte                  */
+/*     - FracMax : Parametre de calcul (voir ci-dessous)             */
+/*     - NbSigmas: MinAff =  Fond + NbSigmas*SigFond                 */
+/*       **Note : Si NbSigmas < 0 , on prend :                       */
+/*                 MinAff =  Fond + NbSigmas*SigFond                 */
+/*              et MaxAff =  Fond - NbSigmas*SigFond                 */
+/*         Dans ce cas la gamme d'affichage fait ressortir le fond.  */
+/*     - NBin : Nb de bins de l'histo                                */
+/*     - La valeur mini des pixels et la valeur de saturation        */
+/*       (ValNul et ValSat) doivent etre fournies ds Min/MaxPix      */
+/*              sorties :                                            */
+/*  - MinPix,MaxPix = Valeurs Min et Max des pixels  (<ValSat)       */
+/*  - Fond =  Pic de l'histo des pixels                              */
+/*  - SigFond = sigma du fond calcule par la relation                */
+/*     NbPixel(Fond+SigFond) =  Pic histo * 0.606 (=Exp(-0.5))       */
+/*  - MinAff = Bruit + NbSigmas * Sigma bruit                        */
+/*  - MaxAff est calcule tel que la relation suivante soit verifie   */
+/*     NbPixel(MinAff<Pixel<MaxAff) =  Nb de pixel entre Min-MaxAff  */
+/*      = FracMax * NbPixel(MinAff<Pixel<ValSat                      */
+/*  - FracNul = Nb pixel < ValNul / Nb total pixel                   */
+/*  - FracSat = Nb pixel satures (>ValSat) / Nb total pixel          */
+
+/*     return code : 0 OK , 1 Erreur calloc                          */
+/*                   2 : Pic histos non trouve                       */
+/*                   3,4 : Probleme de Min/MaxAff avec ValSat        */
+/*                   5 : Gamme dynamique minimale non respectee      */
+/*                         (MaxAff - MinAff > MINDYNAMIC             */
+
+{
+
+#define MINNBIN 100
+#define MAXNBIN 32765
+
+int nbin;
+
+float minhis = 0., maxhis = 65530. , binwidth;
+int xdim, ydim;
+int_4 under,over,tothis;
+int_4 *phis;
+float ValNul,ValSat;
+int_4 *q;
+
+float val;
+int i;
+float min, max;
+int_4 nbpix,nbpix2, imin, imax;
+int bin,binmax;
+int sigl,sigr;
+float fracfond,fracsignal;
+
+float MINDYNAMIC = 5;          /* Gamme dynamique minimale (MaxAff-MinAff)*/
+
+#define FRACPIC		0.6065     /*  Valeur de exp(-0.5)   */
+
+xdim = pim->XSize();
+ydim = pim->YSize();
+
+ValNul = *MinPix;
+ValSat = *MaxPix;
+if ((ValSat < ValNul+0.01))  ValSat = ValNul+0.01;  
+
+nbin = NBin;
+if (nbin < MINNBIN)  nbin = MINNBIN;
+if (nbin > MAXNBIN)  nbin = MAXNBIN;
+
+if (vitesse < 1)  vitesse = 1;
+if (vitesse > xdim*ydim/100)  vitesse = xdim*ydim/100;
+
+
+/*  Je modifie min et max histo et nbin en fonction de valnul et valsat */
+/*  je garde binwidth constant     */
+
+binwidth = (ValSat-ValNul) / nbin;
+minhis = ValNul;
+maxhis = minhis + nbin*binwidth;
+
+
+(*MinAff) = minhis;
+(*MaxAff) = maxhis;
+*MinPix = 0.;
+*MaxPix = -1.;
+*Fond = -1.;
+*SigFond = -1.;
+*FracNul = 0.0;
+*FracSature = 0.0;
+
+/* allocation dynamique de memoire */
+phis = new int_4[nbin];
+
+/* mise a zero de l'histogramme */
+for ( q=phis ; q<phis+nbin ; *q++ = 0 )  ;
+under = over = tothis = 0;
+
+
+
+nbpix2 = nbpix = 0;
+min = ValSat+1.;
+max = ValNul-1;
+
+/*   Boucle sur les pixels   */
+/*     Pour aller plus vite, on prend un pixel sur 7   */
+for ( i = 0 ; i < xdim*ydim ; i += vitesse )
+  {
+  val = pim->IValue(i);
+
+   /*   Calcul PixMax/Min et NbPix sature  */
+  if (val > ValSat)  nbpix++;
+  else {
+    if(val < ValNul) nbpix2++;
+    else {
+	    if (val > max) max = val;
+	    else if (val < min) min = val;
+	}
+  }
+
+   /* remplissage de l'histogramme */
+  bin = (int)((val - minhis) / binwidth) ;
+  if ( bin < 0 )  under++;
+  else 
+    {
+    if (bin < nbin) { (*(phis+bin))++; tothis++; }
+    else   over++; 
+    }
+  }     /*  Fin de for : Boucle sur les pixels   */
+
+(*MinPix) = min; 
+(*MaxPix) = max;
+/*       Ne pas oublier le facteur vitesse pour le calcul FracSatue  */
+(*FracNul) = (float)(nbpix2 * vitesse) / (float)(xdim*ydim); 
+(*FracSature) = (float)(nbpix * vitesse) / (float)(xdim*ydim); 
+
+/*  On verifie qu'il y a eu une entree ds l'histo */
+if (tothis <= 0)
+  { delete[] phis;  return(2); }
+  
+/* recherche du maximum */
+binmax = -1 ; imax = -1 ; q = phis;
+for ( i = 0 ; i < nbin ;  i++, q++ )
+  if ( *(q) > imax ) {imax = *(q) ; binmax = i ;}
+
+if ( (binmax < 0) || (binmax >= nbin) )
+  { delete[] phis;  return(2); }
+
+*Fond = minhis + binmax * binwidth;   
+
+/*   On va chercher le sigma du fond  */
+imin = (int_4) ( (float)(imax) * FRACPIC ) ;
+
+/*
+printf("StatsDebug : min/maxhis  %g  %g  (nbin= %d) w=%g\n",
+        minhis,maxhis,nbin,binwidth);
+printf(".binmax= %d  imax(=pic) = %d  , imin= %d  \n ",binmax,imax,imin);   
+*/
+
+nbpix = 0;
+
+sigr = 0;
+q = phis+binmax;
+while ( ((*q) > imin) && (sigr < (nbin-binmax)) ) 
+  { sigr++; nbpix += (*q) ; q++; }
+
+sigl = 0;
+q = phis+binmax;
+while ( ((*q) > imin) && (sigl < binmax) ) 
+  { sigl++; nbpix += (*q) ; q--; }
+nbpix -= (*(phis+binmax));
+
+(*SigFond) = (float)(sigl+sigr)*binwidth/2.; 
+fracfond = (float)(nbpix) / (float)(tothis);
+
+(*MinAff) = minhis+(binmax-sigl)*binwidth;
+(*MaxAff) = minhis+(binmax+sigr)*binwidth;
+
+
+/*   Check sur NbSigmas  :  */
+if (NbSigmas == 0) NbSigmas = 1;
+if (NbSigmas < 0)    /*   On considere le cas ou NbSigmas est negatif   */
+  {
+  if ( (bin = binmax+NbSigmas*sigr) < 0 )  bin = 0;
+  (*MinAff) = minhis + (float)bin*binwidth;
+  if ( (bin = binmax-NbSigmas*sigr) >= nbin ) bin = nbin-1;
+  (*MaxAff) = minhis + (float)bin*binwidth;
+  goto sortie;
+  }
+
+if ( (bin = binmax+NbSigmas*sigl) >= nbin ) 
+  { delete[] phis;  return(4); }
+
+(*MinAff) = minhis + bin*binwidth;
+
+/*   Calcul du nb de pixel entre MinAff et ValSat  */
+nbpix = 0;
+for( q = phis+bin ; q < phis+nbin ; q++)  nbpix += (*q);
+
+fracsignal = (float)(nbpix) / (float)(tothis+over+under);
+nbpix = (int_4)((float)nbpix * FracMax);
+nbpix2 = 0; q = phis+bin; i = bin;
+while( (nbpix2 < nbpix) && (i < nbin) )  
+  { nbpix2 += (*q); i++; q++; }
+
+(*MaxAff) = minhis + (float)i*binwidth;
+
+
+sortie:        /*   On sort en liberant l'espace   */
+
+/*
+printf("  Stats..Debug : Fond,sigl,sigr,SigFond = %g,%d,%d,%g \n",
+(*Fond),sigl,sigr,(*SigFond));
+ printf("    Min/MaxPix= %g  %g , Min/MaxAff= %g  %g \n",(*MinPix),
+(*MaxPix),(*MinAff),(*MaxAff));
+printf("    FracFond,FracSignal %g  %g  FracNul,FracSat  %g  %g\n",
+       fracfond,fracsignal,(*FracNul),(*FracSature));   
+*/
+
+delete[] phis;
+if ( (*MaxAff) < ((*MinAff)+MINDYNAMIC) )  return(5);
+return(0);
+
+}
+
+
+// ********** INSTANCES
+
+#if defined(__xlC) || defined(__aCC__)
+void instancetempimageop(int n)
+{
+/* Cette fonction sert uniquement a forcer le compilo a instancier les
+  classes/fonctions template   */
+
+int m = n-50;
+ImageU2  iu2(n,n), *tiu2[5], xiu2(n,n);
+ImageI2  ii2(n,n), *tii2[5], xii2(n,n);
+ImageI4  ii4(n,n), *tii4[5], xii4(n,n);
+ImageR4  ir4(n,n), *tir4[5], xir4(n,n);
+
+ImageR4  matx(5,5);
+
+RzCmvSigmaCiel(iu2.ImagePtr(), n, n, 100, 50, 50, (float)0.5, 2, (float)0., (float)65000., 0);
+RzCmvSigmaCiel(ii2.ImagePtr(), n, n, 100, 50, 50, (float)0.5, 2, (float)0., (float)65000., 0);
+RzCmvSigmaCiel(ii4.ImagePtr(), n, n, 100, 50, 50, (float)0.5, 2, (float)0., (float)65000., 0);
+RzCmvSigmaCiel(ir4.ImagePtr(), n, n, 100, 50, 50, (float)0.5, 2, (float)0., (float)65000., 0);
+
+ImgFondCielHisto(iu2);
+ImgFondCielHisto(ii2);
+ImgFondCielHisto(ii4);
+ImgFondCielHisto(ir4);
+
+ImgSigmaCiel(iu2, 100, 1, 100);
+ImgSigmaCiel(ii2, 100, 1, 100);
+ImgSigmaCiel(ii4, 100, 1, 100);
+ImgSigmaCiel(ir4, 100, 1, 100);
+
+CleanImages(5, tiu2); 
+CleanImages(5, tii2); 
+CleanImages(5, tii4); 
+CleanImages(5, tir4); 
+
+
+FilterImage(&iu2, &xiu2, &matx);
+FilterImage(&ii2, &xii2, &matx);
+FilterImage(&ii4, &xii4, &matx);
+FilterImage(&ir4, &xir4, &matx);
+
+FilterStat(&iu2, &xiu2,(int)3,(int)3,(float)1.,(float)-1.);
+FilterStat(&ii2, &xii2,(int)3,(int)3,(float)1.,(float)-1.);
+FilterStat(&ii4, &xii4,(int)3,(int)3,(float)1.,(float)-1.);
+FilterStat(&ir4, &xir4,(int)3,(int)3,(float)1.,(float)-1.);
+
+CSplineImage(iu2,(double)1,(double)0,(double)0,(int)0);
+CSplineImage(ii2,(double)1,(double)0,(double)0,(int)0);
+CSplineImage(ii4,(double)1,(double)0,(double)0,(int)0);
+CSplineImage(ir4,(double)1,(double)0,(double)0,(int)0);
+
+return;
+}
+
+#endif
+
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+
+#pragma define_template RzCmvSigmaCiel<uint_2>
+#pragma define_template RzCmvSigmaCiel<int_2>
+#pragma define_template RzCmvSigmaCiel<int_4>
+#pragma define_template RzCmvSigmaCiel<r_4>
+
+#pragma define_template ImgFondCielHisto<uint_2>
+#pragma define_template ImgFondCielHisto<int_2>
+#pragma define_template ImgFondCielHisto<int_4>
+#pragma define_template ImgFondCielHisto<r_4>
+
+#pragma define_template ImgSigmaCiel<uint_2>
+#pragma define_template ImgSigmaCiel<int_2>
+#pragma define_template ImgSigmaCiel<int_4>
+#pragma define_template ImgSigmaCiel<r_4>
+
+#pragma define_template CleanImages<uint_2>
+#pragma define_template CleanImages<int_2>
+#pragma define_template CleanImages<int_4>
+#pragma define_template CleanImages<r_4>
+
+
+#pragma define_template FilterImage<uint_2>
+#pragma define_template FilterImage<int_2>
+#pragma define_template FilterImage<int_4>
+#pragma define_template FilterImage<r_4>
+
+#pragma define_template FilterStat<uint_2>
+#pragma define_template FilterStat<int_2>
+#pragma define_template FilterStat<int_4>
+#pragma define_template FilterStat<r_4>
+
+#pragma define_template CSplineImage<uint_2>
+#pragma define_template CSplineImage<int_2>
+#pragma define_template CSplineImage<int_4>
+#pragma define_template CSplineImage<r_4>
+
+#endif
+
+
+#if ( defined(ANSI_TEMPLATES) && !defined(__aCC__) )
+template float RzCmvSigmaCiel<uint_2 const>(uint_2 const*, int, int, int, int, int, float, int, float, float, int);
+template float RzCmvSigmaCiel< int_2 const>( int_2 const*, int, int, int, int, int, float, int, float, float, int);
+template float RzCmvSigmaCiel< int_4 const>( int_4 const*, int, int, int, int, int, float, int, float, float, int);
+template float RzCmvSigmaCiel<   r_4 const>(   r_4 const*, int, int, int, int, int, float, int, float, float, int);
+template float ImgFondCielHisto<uint_2>(Image<uint_2> const&, float, int, float, float , float , int);
+template float ImgFondCielHisto< int_2>(Image< int_2> const&, float, int, float, float , float , int);
+template float ImgFondCielHisto< int_4>(Image< int_4> const&, float, int, float, float , float , int);
+template float ImgFondCielHisto<   r_4>(Image<   r_4> const&, float, int, float, float , float , int);
+template float ImgSigmaCiel<uint_2>(Image<uint_2> const& img, int, int, int, float, int, float , float, int);
+template float ImgSigmaCiel< int_2>(Image< int_2> const& img, int, int, int, float, int, float , float, int);
+template float ImgSigmaCiel< int_4>(Image< int_4> const& img, int, int, int, float, int, float , float, int);
+template float ImgSigmaCiel<   r_4>(Image<   r_4> const& img, int, int, int, float, int, float , float, int);
+template void CleanImages<uint_2>(int, Image<uint_2>**, double, double, double);
+template void CleanImages< int_2>(int, Image< int_2>**, double, double, double);
+template void CleanImages< int_4>(int, Image< int_4>**, double, double, double);
+template void CleanImages<   r_4>(int, Image<   r_4>**, double, double, double);
+
+
+template Image<uint_2>* FilterImage<uint_2>(Image<uint_2> const *, Image<uint_2>*, ImageR4 *);
+template Image< int_2>* FilterImage< int_2>(Image< int_2> const *, Image< int_2>*, ImageR4 *);
+template Image< int_4>* FilterImage< int_4>(Image< int_4> const *, Image< int_4>*, ImageR4 *);
+template Image<   r_4>* FilterImage<   r_4>(Image<   r_4> const *, Image<   r_4>*, ImageR4 *);
+
+template Image<uint_2>* FilterStat<uint_2>(Image<uint_2> const *, Image<uint_2>*,int,int,float,float);
+template Image< int_2>* FilterStat< int_2>(Image< int_2> const *, Image< int_2>*,int,int,float,float);
+template Image< int_4>* FilterStat< int_4>(Image< int_4> const *, Image< int_4>*,int,int,float,float);
+template Image<   r_4>* FilterStat<   r_4>(Image<   r_4> const *, Image<   r_4>*,int,int,float,float);
+
+template Image<uint_2>* CSplineImage<uint_2>(Image<uint_2> const &,double,double,double,int);
+template Image< int_2>* CSplineImage< int_2>(Image< int_2> const &,double,double,double,int);
+template Image< int_4>* CSplineImage< int_4>(Image< int_4> const &,double,double,double,int);
+template Image<   r_4>* CSplineImage<   r_4>(Image<   r_4> const &,double,double,double,int);
+
+#endif
+
+
+#ifdef GNU_TEMPLATES
+template float RzCmvSigmaCiel(uint_2 const*, int, int, int, int, int, float, int, float, float, int);
+template float RzCmvSigmaCiel( int_2 const*, int, int, int, int, int, float, int, float, float, int);
+template float RzCmvSigmaCiel( int_4 const*, int, int, int, int, int, float, int, float, float, int);
+template float RzCmvSigmaCiel(   r_4 const*, int, int, int, int, int, float, int, float, float, int);
+template float ImgFondCielHisto(Image<uint_2> const&, float, int, float, float , float , int);
+template float ImgFondCielHisto(Image< int_2> const&, float, int, float, float , float , int);
+template float ImgFondCielHisto(Image< int_4> const&, float, int, float, float , float , int);
+template float ImgFondCielHisto(Image<   r_4> const&, float, int, float, float , float , int);
+template float ImgSigmaCiel(Image<uint_2> const& img, int, int, int, float, int, float , float, int);
+template float ImgSigmaCiel(Image< int_2> const& img, int, int, int, float, int, float , float, int);
+template float ImgSigmaCiel(Image< int_4> const& img, int, int, int, float, int, float , float, int);
+template float ImgSigmaCiel(Image<   r_4> const& img, int, int, int, float, int, float , float, int);
+template void CleanImages(int, Image<uint_2>**, double, double, double);
+template void CleanImages(int, Image< int_2>**, double, double, double);
+template void CleanImages(int, Image< int_4>**, double, double, double);
+template void CleanImages(int, Image<   r_4>**, double, double, double);
+
+
+template Image<uint_2>* FilterImage(Image<uint_2> const *, Image<uint_2>*, ImageR4 *);
+template Image< int_2>* FilterImage(Image< int_2> const *, Image< int_2>*, ImageR4 *);
+template Image< int_4>* FilterImage(Image< int_4> const *, Image< int_4>*, ImageR4 *);
+template Image<   r_4>* FilterImage(Image<   r_4> const *, Image<   r_4>*, ImageR4 *);
+
+template Image<uint_2>* FilterStat(Image<uint_2> const *, Image<uint_2>*,int,int,float,float);
+template Image< int_2>* FilterStat(Image< int_2> const *, Image< int_2>*,int,int,float,float);
+template Image< int_4>* FilterStat(Image< int_4> const *, Image< int_4>*,int,int,float,float);
+template Image<   r_4>* FilterStat(Image<   r_4> const *, Image<   r_4>*,int,int,float,float);
+
+template Image<uint_2>* CSplineImage(Image<uint_2> const &,double,double,double,int);
+template Image< int_2>* CSplineImage(Image< int_2> const &,double,double,double,int);
+template Image< int_4>* CSplineImage(Image< int_4> const &,double,double,double,int);
+template Image<   r_4>* CSplineImage(Image<   r_4> const &,double,double,double,int);
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/imageop.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/imageop.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/imageop.h	(revision 2309)
@@ -0,0 +1,69 @@
+// This may look like C code, but it is really -*- C++ -*-
+
+// Operations non elementaires sur les images.
+// Les operations elementaires sont des methodes de la classe.
+
+//    C. Magneville  (Version C)  E. Aubourg / R. Ansari C++
+
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef IMAGEOP_H_SEEN
+#define IMAGEOP_H_SEEN
+
+#include "cimage.h"
+#include "cspline.h"
+#include "dynccd.h"
+
+template <class T>
+void CleanImages(int nImg, Image<T>** imgTab, double nSig=1,
+                 double lowbad=-1e20, double highbad=1e20);
+
+
+template <class T>
+float ImgFondCielHisto(Image<T> const& img, float binWidth=1, int degre=2, 
+                       float frac=0.5f,
+                       float low=-999999.0, float high=999999.0,
+                       int debug=0);
+template <class T>
+float ImgSigmaCiel(Image<T> const& img, int ndata, int binWidth, int taille,
+                   float frac=0.5f, int degre=2,
+                   float low=-999999.0, float high=999999.0,
+                   int debug=0);
+
+int CalFondImage(RzImage *pim, double low, double high, int action);
+
+int FondSigmaCiel(RzImage *pim, float low, float high, int pvsz=100
+              ,float nbsig1=3.5f,float nbsig2=7.f,float nbsig3=5.f
+              ,float binsg=0.5f,float frac=0.33f,int modu=1,int deb=0);
+
+int RzFondSig2Ciel(RzImage * pim, int vitesse, float FracMax, int NbSigmas, int NBin, 
+	               float *MinPix, float *MaxPix, float *Fond, float *SigFond,
+                   float *MinAff, float *MaxAff, float *FracNul, float *FracSature);
+
+template <class T>
+float FondLocal(Image<T> const & image, float xcentre, float ycentre,
+                float rayon1, float rayon2, float fraclow, float frachigh, int lp=0);
+
+// Filtrage / convolution d'images 
+
+template <class T>
+Image<T> * FilterImage(Image<T> const * pim, Image<T> * pom, ImageR4 *matx);
+
+// Calcul une image de bruit prenant en compte le filtre de convolution
+ImageR4* NoiseFiltImage(ImageR4& img, ImageR4& filtre, DynCCD& dynccd);
+
+///////////////////////////////////////////////////////////////////
+//// Filtre statistique d'images
+template <class T>
+Image<T> * FilterStat(Image<T> const * pim, Image<T> * pom
+                     ,int N,int M,float lowbad,float highbad);
+///////////////////////////////////////////////////////////////////
+//// Spline d'images
+template <class T>
+Image<T> * CSplineImage(Image<T> const& f1,double pxsz=1.,double x0=0.,double y0=0.
+                       ,int natural=(int)CSpline::NaturalAll);
+///////////////////////////////////////////////////////////////////
+
+
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/integ.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/integ.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/integ.cc	(revision 2309)
@@ -0,0 +1,520 @@
+#include "integ.h"
+#include "generalfit.h"
+
+// A faire :
+//   1 dans GLInteg, optimiser recalcul en utilisant des poids
+//     calcules sur [0,1] et chgt de variable
+//   2 dans GLInteg, distinction nStep = subdivisions de l'intervalle,
+//     et on applique GL d'ordre "ordre" sur chaque subdivision, en
+//     utilisant le (1)
+
+//++
+// Class	Integrator
+// Lib		Outils++ 
+// include	integ.h
+//
+//	Classe abstraite d'intégration numérique 1D.
+//	On fournit une fonction double f(double) au constructeur, ou
+//	une GeneralFunction avec des paramètres définis.
+//	L'objet Integrator est convertible en valeur double qui est la valeur
+//	de l'intégrale. Diverses méthodes permettent de choisir des options
+//	de calcul, et ces méthodes retournent une référence sur l'objet, pour
+//	permettre une notation chaînée.
+//--
+//++ 
+// Links	Implementations
+// TrpzInteg
+// GLInteg
+//--
+
+//++
+// Titre	Constructeurs
+//--
+
+//++
+Integrator::Integrator()
+//
+//	Constructeur par défaut. L'objet n'est pas utilisable en l'état.
+//--
+
+: mFunc(NULL), mGFF(NULL), mGFFParm(NULL),
+  mNStep(50), mDX(-1), mReqPrec(-1),
+  mXMin(0), mXMax(1)
+{}
+
+//++
+Integrator::Integrator(FUNC f, double xmin, double xmax)
+//
+//	Constructeur à partir de la fonction double->double, et des
+//	bornes d'intégration.
+//--
+: mFunc(f), mGFF(NULL), mGFFParm(NULL),
+  mNStep(50), mDX(-1), mReqPrec(-1),
+  mXMin(xmin), mXMax(xmax)
+{}
+
+Integrator::Integrator(fun f, double xmin, double xmax)
+//
+//	Constructeur à partir de la fonction double->double, et des
+//	bornes d'intégration.
+//--
+: mFunc(new Function(f)), mGFF(NULL), mGFFParm(NULL),
+  mNStep(50), mDX(-1), mReqPrec(-1),
+  mXMin(xmin), mXMax(xmax)
+{}
+
+
+//++
+Integrator::Integrator(FUNC f)
+// 
+//	Constructeur sans spécifier les bornes. Elles sont positionnées
+//	à [0,1], et on pourra les modifier plus tard.
+//--
+: mFunc(f), mGFF(NULL), mGFFParm(NULL),
+  mNStep(50), mDX(-1), mReqPrec(-1),
+  mXMin(0), mXMax(1)
+{}
+
+//++
+Integrator::Integrator(fun f)
+// 
+//	Constructeur sans spécifier les bornes. Elles sont positionnées
+//	à [0,1], et on pourra les modifier plus tard.
+//--
+: mFunc(new Function(f)), mGFF(NULL), mGFFParm(NULL),
+  mNStep(50), mDX(-1), mReqPrec(-1),
+  mXMin(0), mXMax(1)
+{}
+
+//++
+Integrator::Integrator(GeneralFunction* gff, double* par, double xmin, double xmax)
+//
+//	Constructeur à partir d'une GeneralFunction. La fonction doit être une
+//	fonction de une variable, et on fournit les valeurs des paramètres ainsi
+//	que les bornes d'intégration.
+//--
+: mFunc(NULL), mGFF(gff), mGFFParm(par),
+  mNStep(50), mDX(-1), mReqPrec(-1),
+  mXMin(xmin), mXMax(xmax)
+{
+  DBASSERT(gff->NVar() == 1);
+}
+
+//++
+Integrator::Integrator(GeneralFunction* gff, double* par)
+//
+//	Constructeur à partir d'une GeneralFunction. La fonction doit être une
+//	fonction de une variable, et on fournit les valeurs des paramètres. 
+//	On ne spécifie pas les bornes. Elles sont positionnées
+//	à [0,1], et on pourra les modifier plus tard.
+//--
+: mFunc(NULL), mGFF(gff), mGFFParm(par),
+  mNStep(50), mDX(-1), mReqPrec(-1),
+  mXMin(0), mXMax(1)
+{
+  DBASSERT(gff->NVar() == 1);
+}
+
+Integrator::~Integrator()
+{delete mFunc;}
+
+//++
+// Titre	Méthodes
+//--
+
+//++
+Integrator& 
+Integrator::NStep(int n)
+//
+//	Spécifie le nombre de pas pour l'intégration numérique.
+//	La signification peut dépendre de la méthode d'intégration.
+//--
+{
+  mNStep = n;
+  mDX = mReqPrec = -1;
+  StepsChanged();
+  return *this;
+}
+
+//++
+Integrator& 
+Integrator::DX(double d)
+//
+//	Spécifie le pas d'intégration.
+//	La signification peut dépendre de la méthode d'intégration.
+//--
+{
+  mDX = d;
+  mNStep = mReqPrec = -1;
+  StepsChanged();
+  return *this;
+}
+
+//++
+Integrator& 
+Integrator::ReqPrec(double p)
+//
+//	Spécifie la précision souhaitée. 
+//	La signification peut dépendre de la méthode d'intégration.
+//	Non disponible dans toutes les méthodes d'intégration.
+//--
+{
+  DBASSERT( !"Pas encore implemente !");
+  mReqPrec = p;
+  mDX = mNStep = -1;
+  StepsChanged();
+  return *this;
+}
+
+//++
+Integrator& 
+Integrator::Limits(double xmin, double xmax)
+//
+//	Spécifie les bornes de l'intégrale.
+//--
+{
+  mXMin = xmin;
+  mXMax = xmax;
+  LimitsChanged();
+  return *this;
+}
+
+//++
+Integrator& 
+Integrator::Func(FUNC f)
+//
+//	Spécifie la fonction à intégrer, sous forme double f(double).
+//--
+{
+  mFunc = f;
+  mGFFParm = NULL;
+  mFunc = NULL;
+  FuncChanged();
+  return *this;
+}
+
+//++
+Integrator& 
+Integrator::Func(GeneralFunction* gff, double* par)
+//
+//	Spécifie la fonction à intégrer, sous forme de GeneralFunction
+//	à une variable, et les paramètres sont fournis.
+//--
+{
+  mGFF = gff;
+  mGFFParm = par;
+  mFunc = NULL;
+  DBASSERT(gff->NVar() == 1);
+  FuncChanged();
+  return *this;
+}
+
+double
+Integrator::FVal(double x) const
+{
+  DBASSERT( mFunc || (mGFF && mGFFParm) );
+  return mFunc ? (*mFunc)(x) : mGFF->Value(&x, mGFFParm); 
+  }
+
+double
+Integrator::ValueBetween(double xmin, double xmax)
+{
+  Limits(xmin,xmax);
+  return Value();
+}
+
+//++
+// Class	TrpzInteg
+// Lib		Outils++ 
+// include	integ.h
+//
+//	Classe d'intégration par la méthode des trapèzes.
+//	Voir Integrator pour les méthodes. Le nombre de pas
+//	est le nombre de trapèze, le pas d'intégration est
+//	la largeur des trapèzez. Impossible de demander une
+//	précision.
+//
+//--
+//++
+// Links	Parents
+// Integrator
+//--
+
+//++
+// Titre	Constructeurs
+//	Voir Integrator pour les détails.
+//--
+
+//++
+TrpzInteg::TrpzInteg()
+//
+//--
+{}
+
+//++
+TrpzInteg::TrpzInteg(FUNC f, double xmin, double xmax)
+//
+//--
+: Integrator(f, xmin, xmax)
+{}
+//++
+TrpzInteg::TrpzInteg(fun f, double xmin, double xmax)
+//
+//--
+: Integrator(f, xmin, xmax)
+{}
+
+//++
+TrpzInteg::TrpzInteg(FUNC f)
+//
+//--
+: Integrator(f)
+{}
+
+TrpzInteg::TrpzInteg(fun f)
+//
+//--
+: Integrator(f)
+{}
+
+//++
+TrpzInteg::TrpzInteg(GeneralFunction* gff, double* par, double xmin, double xmax)
+//
+//--
+: Integrator(gff, par, xmin, xmax)
+{}
+
+//++
+TrpzInteg::TrpzInteg(GeneralFunction* gff, double* par)
+//
+//--
+: Integrator(gff, par)
+{}
+
+TrpzInteg::~TrpzInteg()
+{}
+
+double
+TrpzInteg::Value()
+{
+  double dx = mDX;
+  double nstep = mNStep;
+
+  if (dx > 0)
+    nstep = (mXMax - mXMin)/dx;
+
+  if (nstep <= 0)
+    nstep = 10;
+
+  dx = (mXMax - mXMin) / nstep;
+
+  double s = (FVal(mXMin) + FVal(mXMax))/2;
+  double x = dx + mXMin;
+  for (int i=1; i<nstep; i++, x += dx)
+    s += FVal(x);
+    
+  return s * dx;
+}
+
+
+
+//++
+// Class	GLInteg
+// Lib		Outils++ 
+// include	integ.h
+//
+//	Classe d'intégration par la méthode de Gauss-Legendre.
+//	Voir Integrator pour les méthodes. 
+//	Pour le moment, nstep est l'ordre de la méthode.
+//	Il est prévu un jour de spécifier l'ordre, et que NStep
+//	découpe en intervalles sur chacun desquels on applique GL.
+//	Le principe de la méthode est de calculer les valeurs de la 
+//	fonction aux zéros des polynomes de Legendre. Avec les poids
+//	qui vont bien, GL d'ordre n est exacte pour des polynomes de 
+//	degré <= 2n+1.
+//	Impossible de demander une précision donnée.
+//
+//--
+//++
+// Links	Parents
+// Integrator
+//--
+
+//++
+// Titre	Constructeurs
+//	Voir Integrator pour les détails.
+//--
+
+
+
+
+//++
+GLInteg::GLInteg()
+//
+//--
+: mXPos(NULL), mWeights(NULL)
+{}
+
+
+//++
+GLInteg::GLInteg(FUNC f, double xmin, double xmax)
+//
+//--
+: Integrator(f, xmin, xmax), mXPos(NULL), mWeights(NULL), mOrder(8)
+{
+  NStep(1);
+}
+GLInteg::GLInteg(fun f, double xmin, double xmax)
+//
+//--
+: Integrator(f, xmin, xmax), mXPos(NULL), mWeights(NULL), mOrder(8)
+{
+  NStep(1);
+}
+//++
+GLInteg::GLInteg(FUNC f)
+//
+//--
+: Integrator(f), mXPos(NULL), mWeights(NULL), mOrder(8)
+{
+  NStep(1);
+}
+GLInteg::GLInteg(fun f)
+//
+//--
+: Integrator(f), mXPos(NULL), mWeights(NULL), mOrder(8)
+{
+  NStep(1);
+}
+
+//++
+GLInteg::GLInteg(GeneralFunction* gff, double* par, double xmin, double xmax)
+//
+//--
+: Integrator(gff, par, xmin, xmax), mXPos(NULL), mWeights(NULL), mOrder(8)
+{
+  NStep(1);
+}
+
+//++
+GLInteg::GLInteg(GeneralFunction* gff, double* par)
+//
+//--
+: Integrator(gff, par), mXPos(NULL), mWeights(NULL), mOrder(8)
+{
+  NStep(1);
+}
+
+GLInteg::~GLInteg()
+{
+  delete[] mXPos;
+  delete[] mWeights;
+  mXPos = mWeights = NULL;
+}
+
+void
+GLInteg::InvalWeights()
+{
+  delete[] mXPos;
+  delete[] mWeights;
+  mXPos = mWeights = NULL;
+}
+
+
+void
+GLInteg::LimitsChanged()
+{
+  ComputeBounds();
+}
+
+void
+GLInteg::StepsChanged()
+{
+  ComputeBounds();
+}
+
+GLInteg&
+GLInteg::AddBound(double x)
+{
+  if (x<=mXMin || x>=mXMax) THROW(rangeCheckErr); 
+  // On introduira les classes d'exections apres reflexion et de maniere systematique (Rz+cmv)
+  // if (x<=mXMin || x>=mXMax) throw range_error("GLInteg::AddBound  bound outside interval");
+  mBounds.insert(x);
+  return *this;
+}
+
+
+GLInteg&
+GLInteg::SetOrder(int order)
+{
+  mOrder = order;
+  InvalWeights();
+  return *this;
+}
+
+
+
+double
+GLInteg::Value()
+{
+  if (!mXPos) ComputeWeights();
+  double s = 0;
+  set<double>::iterator i=mBounds.begin();
+  set<double>::iterator j=i; j++;
+  while (j != mBounds.end()) {
+    double s1 = 0;
+    double x1 = *i;
+    double x2 = *j;
+    for (int k=0; k<mOrder; k++)
+       s1 += mWeights[k] * FVal(x1 + (x2-x1)*mXPos[k]);
+    s += s1*(x2-x1);
+    i++; j++;
+  }
+  return s;
+}
+
+void
+GLInteg::ComputeBounds()
+{
+  mBounds.erase(mBounds.begin(), mBounds.end());
+  for (int i=0; i<=mNStep; i++) 
+    mBounds.insert(mXMin + (mXMax-mXMin)*i/mNStep);
+}
+
+void
+GLInteg::ComputeWeights()
+{
+   const double EPS_gauleg = 3.0e-11;
+
+   int m=(mOrder+1)/2;
+   const double xxMin = 0;
+   const double xxMax = 1;
+   
+   mXPos    = new double[mOrder];
+   mWeights = new double[mOrder];
+   
+   double xm=0.5*(xxMax+xxMin);
+   double xl=0.5*(xxMax-xxMin);
+   for (int i=1;i<=m;i++)  {
+      double z=cos(3.141592654*(i-0.25)/(mOrder+0.5));
+      double z1, pp;
+      do {
+         double p1=1.0;
+         double p2=0.0;
+         for (int j=1;j<=mOrder;j++) {
+            double p3=p2;
+            p2=p1;
+            p1=((2.0*j-1.0)*z*p2-(j-1.0)*p3)/j;
+         }
+         pp=mOrder*(z*p1-p2)/(z*z-1.0);
+         z1=z;
+         z=z1-p1/pp;
+      } while (fabs(z-z1) > EPS_gauleg);
+      mXPos[i-1]         = xm-xl*z;
+      mXPos[mOrder-i]    = xm+xl*z;
+      mWeights[i-1]      = 2.0*xl/((1.0-z*z)*pp*pp);
+      mWeights[mOrder-i] = mWeights[i-1];
+   }
+
+}
+
Index: /tags/V_Dec2002/SophyaLib/NTools/integ.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/integ.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/integ.h	(revision 2309)
@@ -0,0 +1,110 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Simple integrator 
+//        E. Aubourg        1996-...
+// DAPNIA/SPP (Saclay) / CEA    LAL - IN2P3/CNRS  (Orsay)
+
+#ifndef INTEG_H_SEEN
+#define INTEG_H_SEEN
+
+#include "machdefs.h"
+#include "pexceptions.h"
+#include <set>
+#include "classfunc.h"
+
+namespace SOPHYA {
+
+class GeneralFunction;
+
+class Integrator {
+public:
+  //typedef double(*FUNC)(double);
+  typedef ClassFunc *FUNC;
+  typedef double (*fun)(double);
+
+  Integrator();
+  Integrator(FUNC, double xmin, double xmax);
+  Integrator(FUNC);
+
+  Integrator(fun, double xmin, double xmax);
+  Integrator(fun);
+
+  Integrator(GeneralFunction*, double* par, double xmin, double xmax);
+  Integrator(GeneralFunction*, double* par);
+  virtual ~Integrator();
+
+  virtual double Value() = 0;
+  virtual double ValueBetween(double xmin, double xmax);
+  virtual operator double() {return Value();}
+
+  virtual Integrator& NStep(int);
+  virtual Integrator& DX(double);
+  virtual Integrator& ReqPrec(double);   // NOT YET !
+  virtual Integrator& Limits(double xmin, double xmax);
+  virtual Integrator& Func(FUNC);
+  virtual Integrator& Func(GeneralFunction*, double* par);
+
+protected:
+  FUNC             mFunc;
+  GeneralFunction* mGFF;
+  double*          mGFFParm;
+
+  int              mNStep;   // -1 si pas fixe
+  double           mDX;
+  double           mReqPrec;
+  double           mXMin, mXMax;
+  
+  double           FVal(double x) const;
+  virtual void     LimitsChanged() {}
+  virtual void     StepsChanged() {}
+  virtual void     FuncChanged() {}
+};
+
+
+
+class TrpzInteg : public Integrator {
+public:
+  TrpzInteg();
+  TrpzInteg(FUNC, double xmin, double xmax);
+  TrpzInteg(FUNC);
+  TrpzInteg(fun, double xmin, double xmax);
+  TrpzInteg(fun);
+  TrpzInteg(GeneralFunction*, double* par, double xmin, double xmax);
+  TrpzInteg(GeneralFunction*, double* par);
+
+  ~TrpzInteg();
+
+  virtual double Value();
+};
+
+class GLInteg : public Integrator {
+public:
+  GLInteg();
+  GLInteg(FUNC, double xmin, double xmax);
+  GLInteg(FUNC);
+  GLInteg(fun, double xmin, double xmax);
+  GLInteg(fun);
+  GLInteg(GeneralFunction*, double* par, double xmin, double xmax);
+  GLInteg(GeneralFunction*, double* par);
+
+  ~GLInteg();
+
+  virtual double Value();
+  virtual GLInteg& AddBound(double x);
+  virtual GLInteg& SetOrder(int order);
+protected:
+
+  double* mXPos;     // integration entre 0 et 1
+  double* mWeights;  // integration entre 0 et 1
+  int     mOrder;    // ordre GL
+  set<double> mBounds; // limites des intervalles d'integration
+  
+  void ComputeWeights();
+  void LimitsChanged();
+  void StepsChanged();
+  void InvalWeights();
+  void ComputeBounds();
+};
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/linfit.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/linfit.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/linfit.h	(revision 2309)
@@ -0,0 +1,16 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// $Id: linfit.h,v 1.7 2000-04-03 17:41:07 ansari Exp $
+//
+
+// Routines de fit lineaire, avec ou sans erreurs, en fournissant
+// les fonctions ou les valeurs.
+#ifndef LINFIT_SEEN
+#define LINFIT_SEEN
+
+// Mis ds TArray/sopemtx.h  - fichier garde pour back-compatibilite
+//                                       Reza 03/2000
+#include "sopemtx.h"
+
+
+#endif // LINFIT_SEEN 
Index: /tags/V_Dec2002/SophyaLib/NTools/matxop.c
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/matxop.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/matxop.c	(revision 2309)
@@ -0,0 +1,904 @@
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <math.h>
+
+
+#include "matxop.h"
+#include "nbmath.h"
+
+/*  Fonctions de manipulation de matrices et de vecteurs    */
+/*  Resolution de systemes lineaires                        */
+
+/*                              R. Ansari  Juillet 1993     */
+/*                              LaSilla (Chili)             */
+
+
+#define MXXFLOAT        1.e36
+
+
+
+/* Nouvelle-Fonction */
+
+int IVecxVec(int *v1, int *v2, int n)
+
+/*  Produit scalaire de deux vecteurs entiers       */
+/*  Retour (int) = v1(n) . v2(n)                    */
+
+{
+register int i,rc;
+register int *ip1, *ip2;
+
+ip1 = v1;  ip2 = v2;
+rc = 0;
+/* for(i=0; i<n; i++)  rc += *(ip1+i) * *(ip2+i); */
+for(i=0; i<n; i++)  rc += *ip1++ * *ip2++;
+return(rc);
+}
+
+
+/* Nouvelle-Fonction */
+
+float RVecxVec(float *v1, float *v2, int n)
+
+/*  Produit scalaire de deux vecteurs reels           */
+/*  Retour (float) = v1(n) . v2(n)                    */
+
+{
+register int i;
+register float rc;
+register float *fp1, *fp2;
+
+fp1 = v1;  fp2 = v2;
+rc = 0.0;
+/* for(i=0; i<n; i++)  rc += *(fp1+i) * *(fp2+i); */
+for(i=0; i<n; i++)  rc += *fp1++ * *fp2++;
+return(rc);
+}
+
+
+/* Nouvelle-Fonction */
+
+double DVecxVec(double *v1, double *v2, int n)
+
+/*  Produit scalaire de deux vecteurs double          */
+/*  Retour (float) = v1(n) . v2(n)                    */
+
+{
+register int i;
+register double rc;
+register double *fp1, *fp2;
+
+fp1 = v1;  fp2 = v2;
+rc = 0.0;
+/* for(i=0; i<n; i++)  rc += *(fp1+i) * *(fp2+i); */
+for(i=0; i<n; i++)  rc += *fp1++ * *fp2++;
+return(rc);
+}
+
+
+/* Nouvelle-Fonction */
+
+void  IMatxVec(int *mx, int *vi, int *vo, int n)
+
+/*  Matrice * Vecteur  (Entiers)     Integer           */
+/*  Vecteur Vo(n) = Matrice Mx(n,n) . Vi(n)            */
+
+{
+register  int *vp, *mxp;
+register int s;
+register int j,i;
+
+vp = vi;   mxp = mx;
+
+for (i=0; i<n; i++)
+  { s = 0;  
+  for(j=0; j<n; j++)   s += *(mxp+j) * *(vp+j);
+  *(vo+i) = s;  mxp += n; }
+
+return;
+}
+
+
+/* Nouvelle-Fonction */
+
+void  RMatxVec(float *mx, float *vi, float *vo, int n)
+
+/*  Matrice * Vecteur  (Reels)     float               */
+/*  Vecteur Vo(n) = Matrice Mx(n,n) . Vi(n)            */
+
+
+/*  Matrice * Vecteur  (Reels)  */
+{
+register  float *vp, *mxp;
+register float s;
+register int j,i;
+
+vp = vi;   mxp = mx;
+
+for (i=0; i<n; i++)
+  { s = 0;  
+  for(j=0; j<n; j++)   s += *(mxp+j) * *(vp+j);
+  *(vo+i) = s;  mxp += n; }
+
+return;
+}
+
+
+/* Nouvelle-Fonction */
+
+void  DMatxVec(double *mx, double *vi, double *vo, int n)
+
+/*  Matrice * Vecteur  (double)     double             */
+/*  Vecteur Vo(n) = Matrice Mx(n,n) . Vi(n)            */
+
+
+/*  Matrice * Vecteur  (Reels)  */
+{
+register  double *vp, *mxp;
+register double s;
+register int j,i;
+
+vp = vi;   mxp = mx;
+
+for (i=0; i<n; i++)
+  { s = 0;  
+  for(j=0; j<n; j++)   s += *(mxp+j) * *(vp+j);
+  *(vo+i) = s;  mxp += n; }
+
+return;
+}
+
+
+
+
+/* Nouvelle-Fonction */
+
+float SolveRLinSyst(float *mx, float *b, float *x, int n)
+
+/*  Resolution de systeme lineaire                           */
+/*  Matrice Mx(n,n) * Vecteur X(n) = Vecteur B(n)            */
+/*  Inconnu : vecteur X                                      */
+/*  Retour = Determinant du systeme (=0 Pb)  et X[]          */
+/*  Note : Au retour le vecteur B(n) et la matrice Mx(n,n)   */
+/*  sont modifies. Mx(n,n) contient une matrice triangulaire */
+/*  superieure                                               */                          
+
+{
+int i,k;
+register int j;
+register float *fp1, *fp2;
+double det;
+float vt1;
+register float vt2;
+register float six;
+int pivok;
+
+
+#define  MINPIVOT   1.e-15
+#define  MINDETER   1.e-15
+
+
+
+for (i=0; i<n-1; i++)   /*  Boucle sur les pivots */
+  {
+
+/*  printf("\n Iteration %d : \n",i);
+  for (k=0; k<n; k++)
+    {
+    for (j=0; j<n; j++)  printf(" %10g ",*(mx+k*n+j));
+    printf("    b= %10g \n",*(b+k));
+    }  */
+
+  fp1 = fp2 = mx+i*n;  
+  vt1 = *(fp1+i) ;
+
+  if ((vt1 < MINPIVOT) && (vt1 > -MINPIVOT) )   /* Pivot trop petit  */
+    {
+    pivok = 0;
+    for (k=i+1; k<n; k++)
+      {
+      vt1 = *(mx+k*n+i) ;
+      if ((vt1 > MINPIVOT) || (vt1 < -MINPIVOT) )
+        {
+        fp2 = mx+k*n;  
+        for (j=i; j<n; j++)
+          {
+          *(fp1+j) += *(fp2+j);
+          }
+        *(b+i) += *(b+k);
+        vt1 = *(fp1+i) ;  
+        fp2 = fp1;
+        pivok = 1;
+        break;
+        }
+      }
+    if (!pivok)  return(0.0);
+    }    
+
+  for (k=i+1; k<n; k++)
+    {
+    fp1 += n;
+    vt2 = *(fp1+i) / vt1 ; 
+    for (j=i+1; j<n; j++)  
+      *(fp1+j) -= (vt2 * *(fp2+j));
+
+    *(fp1+i) = 0.0;  
+    *(b+k) -= (vt2 * *(b+i)) ;
+    }
+
+  }
+
+/*   Calcul du determinant  */
+det = 1.0;
+for (i=0; i<n; i++)  det *= *(mx+i*n+i);
+if ((det < MINDETER) && (det > -MINDETER) )  return(0.0);
+if (det > MXXFLOAT)  det = MXXFLOAT;
+if (det < -MXXFLOAT)  det = -MXXFLOAT;
+
+
+for(i=n-1; i>=0; i--)
+  {
+  fp1 = mx+i*n;
+  six = *(b+i);
+  for (j=i+1; j<n; j++)  six -= (x[j] * *(fp1+j) );
+  x[i] = six / (*(fp1+i));
+
+/*  printf("  Solution X[%2d] = %g \n",i,x[i]);  */
+  }
+
+return(det);
+}
+
+
+
+
+
+/* Nouvelle-Fonction */
+
+double SolveDLinSyst(double *mx, double *b, double *x, int n)
+
+/*  Resolution de systeme lineaire                           */
+/*  Matrice Mx(n,n) * Vecteur X(n) = Vecteur B(n)            */
+/*  Inconnu : vecteur X                                      */
+/*  Retour = Determinant du systeme (=0 Pb)  et X[]          */
+/*  Note : Au retour le vecteur B(n) et la matrice Mx(n,n)   */
+/*  sont modifies. Mx(n,n) contient une matrice triangulaire */
+/*  superieure                                               */                          
+
+{
+int i,k;
+register int j;
+register double *fp1, *fp2;
+double det;
+double vt1;
+register double vt2;
+register double six;
+int pivok;
+
+
+#define  DMINPIVOT   1.e-25
+#define  DMINDETER   1.e-30
+
+
+
+for (i=0; i<n-1; i++)   /*  Boucle sur les pivots */
+  {
+
+/*  printf("\n Iteration %d : \n",i);
+  for (k=0; k<n; k++)
+    {
+    for (j=0; j<n; j++)  printf(" %10g ",*(mx+k*n+j));
+    printf("    b= %10g \n",*(b+k));
+    }  */
+
+  fp1 = fp2 = mx+i*n;  
+  vt1 = *(fp1+i) ;
+
+  if ((vt1 < DMINPIVOT) && (vt1 > -DMINPIVOT) )   /* Pivot trop petit  */
+    {
+    pivok = 0;
+    for (k=i+1; k<n; k++)
+      {
+      vt1 = *(mx+k*n+i) ;
+      if ((vt1 > DMINPIVOT) || (vt1 < -DMINPIVOT) )
+        {
+        fp2 = mx+k*n;  
+        for (j=i; j<n; j++)
+          {
+          *(fp1+j) += *(fp2+j);
+          }
+        *(b+i) += *(b+k);
+        vt1 = *(fp1+i) ;  
+        fp2 = fp1;
+        pivok = 1;
+        break;
+        }
+      }
+    if (!pivok)  return(0.0);
+    }    
+
+  for (k=i+1; k<n; k++)
+    {
+    fp1 += n;
+    vt2 = *(fp1+i) / vt1 ; 
+    for (j=i+1; j<n; j++)  
+      *(fp1+j) -= (vt2 * *(fp2+j));
+
+    *(fp1+i) = 0.0;  
+    *(b+k) -= (vt2 * *(b+i)) ;
+    }
+
+  }
+
+/*   Calcul du determinant  */
+det = 1.0;
+for (i=0; i<n; i++)  det *= *(mx+i*n+i);
+if ((det < DMINDETER) && (det > -DMINDETER) )  return(0.0);
+if (det > MXXFLOAT)  det = MXXFLOAT;
+if (det < -MXXFLOAT)  det = -MXXFLOAT;
+
+
+for(i=n-1; i>=0; i--)
+  {
+  fp1 = mx+i*n;
+  six = *(b+i);
+  for (j=i+1; j<n; j++)  six -= (x[j] * *(fp1+j) );
+  x[i] = six / (*(fp1+i));
+
+/*  printf("  Solution X[%2d] = %g \n",i,x[i]);  */
+  }
+
+return(det);
+}
+
+
+
+
+/*    ==============================================================  */
+/*   Fonctions de Fit lineaire de Xi2                                 */
+/*    ==============================================================  */
+
+/*   .......... Fit avec vecteurs depart reels ...............      */
+
+static int FFBusy = -1;                /*  Flag Deja Busy (GetFitVect effectue)  */
+static int FNVarMax = 0;               /*  Nb Maxi de variables a ajuster        */
+static int FVLenMax = 0;               /*  Longueur maxi des vecteurs            */
+static float **FVeci = NULL;           /*  Vecteurs en entree  *Vecf = Y         */
+                                       /*                      *(Vecf+i) = X[i]  */
+static float **FVecf = NULL;           /*  Vecteurs *FVecf = *FVecf+2 = B = M.X  */                                           
+                                       /*           *(FVecf+1) = La sortie = Ai  */
+static float *FVSpace = NULL;          /*  Espace pour les *FVeci                */  
+static float *FVSpacef = NULL;         /*    "   "    "    *FVecf                */
+static double  *FFMtx = NULL;          /*  Matrice a inverser = M                */
+static double  *FFMtx2 = NULL;         /*   Copie de M                           */
+static double  *FFSort = NULL;         /*  RFitLinErr() pour Sortie GausPiv()    */
+                                       /*  FNVarMax Lignes * (FNVarMax+1) Col.   */
+                                       /*  Col1= Solution, Col2..N+1 : MatInv    */        
+
+
+int InitRFitLin(int nvarmx, int szv)
+
+/*  Initialisation du fit de Xi2 Entier             */
+/*  Allocation d'espace memoire                     */
+/*  nvarmx = Nb maxi de variable                    */
+/*  szv = Taille maxi des vecteurs de points        */
+
+{
+int i;
+
+FFBusy = -1;
+nvarmx ++;
+if (nvarmx < 7)  nvarmx = 7;
+if (szv < 25) szv = 25;
+
+if ( (FVeci = (float**) malloc(nvarmx*sizeof(float *))) == NULL )
+  { printf("InitRFitLin_Erreur: (Pb malloc(Veci)) \n");
+  return(1);
+  }
+
+if ( (FVSpace = (float*)  malloc(nvarmx*szv*sizeof(float))) == NULL )
+  { printf("InitRFitLin_Erreur: (Pb malloc(VSpace)) \n");
+  free(FVeci);
+  return(2);
+  }
+
+for(i=0; i<nvarmx; i++)  *(FVeci+i) = FVSpace+i*szv;
+
+
+if ( (FVecf = (float**) malloc(3*sizeof(float *))) == NULL )
+  { printf("InitRFitLin_Erreur: (Pb malloc(Vecf)) \n");
+  free(FVeci);
+  free(FVSpace);
+  return(3);
+  }
+
+if ( (FVSpacef = (float*) malloc(3*szv*sizeof(float))) == NULL )
+  { printf("InitRFitLin_Erreur: (Pb malloc(VSpacef)) \n");
+  free(FVeci);
+  free(FVSpace);
+  free(FVecf);
+  return(4);
+  }
+
+for(i=0; i<3; i++)  *(FVecf+i) = FVSpacef+i*szv;
+
+
+if ( (FFMtx = (double*) malloc(nvarmx*nvarmx*sizeof(double))) == NULL )
+  { printf("InitRFitLin_Erreur: (Pb malloc(FMtx)) \n");
+  free(FVeci);
+  free(FVSpace);
+  free(FVecf);
+  free(FVSpacef);
+  return(5);
+  }
+
+if ( (FFMtx2 = (double*) malloc(nvarmx*nvarmx*sizeof(double))) == NULL )
+  { printf("InitRFitLin_Erreur: (Pb malloc(FMtx2)) \n");
+  free(FVeci);
+  free(FVSpace);
+  free(FVecf);
+  free(FVSpacef);
+  free(FFMtx);
+  return(6);
+  }
+
+if ( (FFSort = (double*) malloc((nvarmx+1)*nvarmx*sizeof(double))) == NULL )
+  { printf("InitRFitLin_Erreur: (Pb malloc(FFSort)) \n");
+  free(FVeci);
+  free(FVSpace);
+  free(FVecf);
+  free(FVSpacef);
+  free(FFMtx);
+  free(FFMtx2);
+  return(7);
+  }
+
+FFBusy = 0;
+FNVarMax = nvarmx-1;
+FVLenMax = szv;
+
+return(0);
+}
+
+
+/* Nouvelle-Fonction */
+void EndRFitLin()
+{
+
+if (FVeci != NULL)  free(FVeci);
+if (FVSpace != NULL)  free(FVSpace);
+if (FVecf != NULL)  free(FVecf);
+if (FVSpacef != NULL)  free(FVSpacef);
+if (FFMtx != NULL)  free(FFMtx);
+if (FFMtx2 != NULL)  free(FFMtx2);
+if (FFSort != NULL)  free(FFSort);
+
+FVeci = NULL;
+FVSpace = NULL;
+FVecf = NULL;
+FVSpacef = NULL;
+FFMtx = NULL;
+FFMtx2 = NULL;
+
+FFBusy = -1;
+FNVarMax = 0;
+FVLenMax = 0;
+return;
+}
+
+
+/* Nouvelle-Fonction */
+
+float **GetRFitVect(int nvar, int vsz)
+/*  reservation de l'espace des vecteurs pour le fit  */
+{
+int nvmx, vszmx;
+
+if (FFBusy > 0)  
+  { printf("GetRFitVect_Erreur:  FFBusy= %d \n",FFBusy);
+  return(NULL);  }
+if ((nvar < 1) || (vsz < 1) )  
+  { printf("GetRFitVect_Erreur:  NVar,VSz= %d %d \n",nvar,vsz);
+  return(NULL);  }
+if ((nvar > FNVarMax) || (vsz > FVLenMax) || (FFBusy < 0))
+  {
+  EndRFitLin();
+  if (nvar > FNVarMax)   nvmx = nvar;
+  else  nvmx = FNVarMax;
+  if (vsz > FVLenMax)  vszmx = vsz;
+  else vszmx = FVLenMax;
+  if (InitRFitLin(nvmx, vszmx) != 0)  return(NULL);
+  }
+
+FFBusy = 1;
+return(FVeci);
+}
+
+
+/* Nouvelle-Fonction */
+void FreeRFitVect()
+{
+FFBusy = 0;
+return;
+}
+
+/* Nouvelle-Fonction */
+
+float RFitLin(int nd, int vsz, float *XVar)
+
+/*  Effectue le fit de Xi2 pour nd inconnu, Taille vecteurs vsz */
+/*  Les vecteurs doivent etre remplis auparavant                */
+/*  Retourne la valeur du Xi2 du fit, Negatif si Pb.            */
+
+{
+int i,j;
+register float *ip;
+register float *fp, *fp2;
+register double x;
+register float y;
+register float *ffmtx, *ffmtx2;
+float det, rc;
+
+
+if ((nd > FNVarMax) || (vsz > FVLenMax) )   {rc = -1000.0;  goto Fin; }
+
+/*  Fabrication matrice du syteme lineaire a resoudre  */
+ffmtx = (float *)FFMtx;
+ffmtx2 = (float *)FFMtx2;
+for(i=0; i<nd; i++)
+  {
+  fp = ffmtx+i*nd;   fp2 = ffmtx2+i*nd;
+  ip = *(FVeci+i+1);
+
+/*  Elements diagonals  */
+  *(fp2+i) = *(fp+i) = RVecxVec( ip, ip, vsz) ;  
+ 
+  for(j=i+1; j<nd; j++)  
+    {                /* Les autres elements  */
+    *(fp2+j) = *(fp+j) = RVecxVec( ip, *(FVeci+j+1), vsz) ;
+  /* Matrice symetrique */ 
+    *(ffmtx2+j*nd+i) = *(ffmtx+j*nd+i) = *(fp+j);  
+    }
+
+/*  Second membre  M.X = B   */
+  fp = *FVecf;  fp2 = *(FVecf+2);
+  *(fp2+i) = *(fp+i) = RVecxVec( ip, *FVeci, vsz) ;
+  
+  }
+
+/*  On resoud le systeme lineaire : */
+det = SolveRLinSyst(ffmtx, *FVecf, *(FVecf+1), nd);
+if (det == 0.0)   {rc = -500.0;  goto Fin; }
+
+/*  On calcule le Xi2  */
+x = RVecxVec( *FVeci, *FVeci, vsz);
+fp = *(FVecf+2);  
+for(i=0; i<nd; i++)
+  {
+  XVar[i] = y = *(*(FVecf+1)+i);  
+  fp2 = ffmtx2+i*nd+i;   
+  x += (y * y * *fp2);
+  x -= ( 2.0 * ( y * *(fp+i) ) );
+  for (j=i+1; j<nd; j++)  
+    { fp2++;  
+    x += 2.0 * y * *(*(FVecf+1)+j) * *fp2 ;  }    
+  }
+
+rc = (float)x;
+
+Fin:
+FreeRFitVect();
+return(rc);
+}
+
+
+
+/* Nouvelle-Fonction */
+
+float RFitLinErr(int nd, int vsz, float *XVar, float *Err)
+
+/*  Effectue le fit de Xi2 pour nd inconnu, Taille vecteurs vsz */
+/*  Les vecteurs doivent etre remplis auparavant                */
+/*  Retourne la valeur du Xi2 du fit, Negatif si Pb.            */
+
+{
+int i,j,md;
+register float *ip;
+register double *dp, *dp2;
+register float *fp;
+register double x,y;
+float rc;
+double det;
+
+
+if ((nd > FNVarMax) || (vsz > FVLenMax) )   {rc = -1000.0;  goto Fin; }
+
+md = nd+1;  
+/*  Mise a zero de la matrice de sortie et creation matrice identite */
+for(i=0; i<nd*md; i++)  FFSort[i] = 0.;
+for(i=1; i<nd*md; i += md+1) FFSort[i] = 1.;  
+
+/*  Fabrication matrice du syteme lineaire a resoudre  */
+
+for(i=0; i<nd; i++)
+  {
+  dp = FFMtx+i*nd;   dp2 = FFMtx2+i*nd;
+  ip = *(FVeci+i+1);
+
+/*  Elements diagonals  */
+  *(dp+i) = *(dp2+i) = RVecxVec( ip, ip, vsz) ;  
+ 
+  for(j=i+1; j<nd; j++)  
+    {                /* Les autres elements  */
+    *(dp+j) = *(dp2+j) = RVecxVec( ip, *(FVeci+j+1), vsz) ;
+  /* Matrice symetrique */ 
+    *(FFMtx+j*nd+i) = *(FFMtx2+j*nd+i) = *(dp+j);  
+    }
+
+/*  Second membre  M.X = B   */
+  dp = FFSort+i*md;  fp = *(FVecf+2);  
+  *dp = *(fp+i) = RVecxVec( ip, *FVeci, vsz) ;
+  
+  }
+
+
+/*  Appel GausPiv pour resoudre le systeme et inverser la matrice */
+det = GausPiv(FFMtx, nd, nd, FFSort, md, md, 0);
+/* printf("Det= %g Resul= %g %g %g \n",det,FFSort[0], FFSort[md], FFSort[2*md]); */
+if (det == 0.0)  {rc = -500.0;  goto Fin; } 
+ 
+/*  On calcule le Xi2   Et remplissage vecteurs sortie */
+
+x = RVecxVec( *FVeci, *FVeci, vsz);
+fp = *(FVecf+2);  
+for(i=0; i<nd; i++)
+  {
+  y = FFSort[1+i*(md+1)]; 
+  Err[i] = (y >= 0.) ? (float)sqrt(y) : -(float)sqrt(-y);
+  XVar[i]= y =FFSort[i*md];
+ 
+  dp2 = FFMtx2+i*nd+i;  
+  x += (y * y * *dp2);
+  x -= ( 2.0 * ( y * (double)*(fp+i) ) );
+  for (j=i+1; j<nd; j++)  
+    { dp2++;  
+    x += 2.0 *  y * FFSort[j*md] * *dp2 ;  }    
+  }
+rc = (float)x;
+
+Fin:
+FreeRFitVect();
+return(rc);
+}
+
+
+
+
+/*   .......... Fit avec vecteurs depart double ...............      */
+
+/*   Voir description des variables ds IniRFitLin()   */
+static int DFBusy = -1;
+static int DNVarMax = 0;
+static int DVLenMax = 0;
+static double **DVeci = NULL;
+static double **DVecf = NULL;
+static double *DVSpace = NULL;
+static double *DVSpacef = NULL;
+static double  *DFMtx = NULL;
+static double  *DFMtx2 = NULL;
+
+
+int InitDFitLin(int nvarmx, int szv)
+
+/*  Initialisation du fit de Xi2 Entier             */
+/*  Allocation d'espace memoire                     */
+/*  nvarmx = Nb maxi de variable                    */
+/*  szv = Taille maxi des vecteurs de points        */
+
+{
+int i;
+
+DFBusy = -1;
+nvarmx ++;
+if (nvarmx < 7)  nvarmx = 7;
+if (szv < 25) szv = 25;
+
+if ( (DVeci = (double**) malloc(nvarmx*sizeof(double *))) == NULL )
+  { printf("InitDFitLin_Erreur: (Pb malloc(Veci)) \n");
+  return(1);
+  }
+
+if ( (DVSpace = (double*) malloc(nvarmx*szv*sizeof(double))) == NULL )
+  { printf("InitDFitLin_Erreur: (Pb malloc(VSpace)) \n");
+  free(DVeci);
+  return(2);
+  }
+
+for(i=0; i<nvarmx; i++)  *(DVeci+i) = DVSpace+i*szv;
+
+
+if ( (DVecf = (double**) malloc(3*sizeof(double *))) == NULL )
+  { printf("InitDFitLin_Erreur: (Pb malloc(Vecf)) \n");
+  free(DVeci);
+  free(DVSpace);
+  return(3);
+  }
+
+if ( (DVSpacef = (double*) malloc(3*szv*sizeof(double))) == NULL )
+  { printf("InitDFitLin_Erreur: (Pb malloc(VSpacef)) \n");
+  free(DVeci);
+  free(DVSpace);
+  free(DVecf);
+  return(4);
+  }
+
+for(i=0; i<3; i++)  *(DVecf+i) = DVSpacef+i*szv;
+
+
+if ( (DFMtx = (double*) malloc(nvarmx*nvarmx*sizeof(double))) == NULL )
+  { printf("InitDFitLin_Erreur: (Pb malloc(FMtx)) \n");
+  free(DVeci);
+  free(DVSpace);
+  free(DVecf);
+  free(DVSpacef);
+  return(5);
+  }
+
+if ( (DFMtx2 = (double*) malloc(nvarmx*nvarmx*sizeof(double))) == NULL )
+  { printf("InitDFitLin_Erreur: (Pb malloc(FMtx2)) \n");
+  free(DVeci);
+  free(DVSpace);
+  free(DVecf);
+  free(DVSpacef);
+  free(DFMtx);
+  return(6);
+  }
+
+DFBusy = 0;
+DNVarMax = nvarmx-1;
+DVLenMax = szv;
+
+return(0);
+}
+
+
+/* Nouvelle-Fonction */
+void EndDFitLin()
+{
+
+if (DVeci != NULL)  free(DVeci);
+if (DVSpace != NULL)  free(DVSpace);
+if (DVecf != NULL)  free(DVecf);
+if (DVSpacef != NULL)  free(DVSpacef);
+if (DFMtx != NULL)  free(DFMtx);
+if (DFMtx2 != NULL)  free(DFMtx2);
+
+DVeci = NULL;
+DVSpace = NULL;
+DVecf = NULL;
+DVSpacef = NULL;
+DFMtx = DFMtx2 = NULL;
+
+DFBusy = -1;
+DNVarMax = 0;
+DVLenMax = 0;
+return;
+}
+
+
+/* Nouvelle-Fonction */
+
+double **GetDFitVect(int nvar, int vsz)
+/*  reservation de l'espace des vecteurs pour le fit  */
+{
+int nvmx, vszmx;
+
+if (DFBusy > 0)  return(NULL);
+if ( (nvar < 1) || (vsz < 1) ) return(NULL);
+if ((nvar > DNVarMax) || (vsz > DVLenMax) || (DFBusy < 0))
+  {
+  EndDFitLin();
+  if (nvar > DNVarMax)   nvmx = nvar;
+  else  nvmx = DNVarMax;
+  if (vsz > DVLenMax)  vszmx = vsz;
+  else vszmx = DVLenMax;
+  InitDFitLin(nvmx, vszmx);
+  }
+
+DFBusy = 1;
+return(DVeci);
+}
+
+
+/* Nouvelle-Fonction */
+void FreeDFitVect()
+{
+DFBusy = 0;
+return;
+}
+
+
+/* Nouvelle-Fonction */
+
+double DFitLin(int nd, int vsz, double *XVar)
+
+/*  Effectue le fit de Xi2 pour nd inconnu, Taille vecteurs vsz */
+/*  Les vecteurs doivent etre remplis auparavant                */
+/*  Retourne la valeur du Xi2 du fit, Negatif si Pb.            */
+
+{
+int i,j;
+register double *ip;
+register double *fp, *fp2;
+register double x,y;
+double det,rc;
+
+
+if ((nd > DNVarMax) || (vsz > DVLenMax) )   { rc = -1000.;  goto Fin; }
+
+/*   Impression de debug  */
+/* 
+for(i=0; i<nd+1; i++)
+  {
+  ip = *(DVeci+i);
+  printf("DFitLin_Debug Veci[%d][0..5]= %lg %lg %lg %lg %lg %lg \n",
+       i,*ip, *(ip+1), *(ip+2), *(ip+3), *(ip+4), *(ip+5));  
+  } 
+*/
+
+
+/*  Fabrication matrice du syteme lineaire a resoudre  */
+
+for(i=0; i<nd; i++)
+  {
+  fp = DFMtx+i*nd;   fp2 = DFMtx2+i*nd;
+  ip = *(DVeci+i+1);
+
+/*  Elements diagonals  */
+  *(fp2+i) = *(fp+i) =  DVecxVec( ip, ip, vsz) ;  
+ 
+  for(j=i+1; j<nd; j++)  
+    {                /* Les autres elements  */
+    *(fp2+j) = *(fp+j) = DVecxVec( ip, *(DVeci+j+1), vsz) ;
+  /* Matrice symetrique */ 
+    *(DFMtx2+j*nd+i) = *(DFMtx+j*nd+i) = *(fp+j);  
+    }
+
+/*  Second membre  M.X = B   */
+  fp = *DVecf;  fp2 = *(DVecf+2);
+  *(fp2+i) = *(fp+i) = DVecxVec( ip, *DVeci, vsz) ;
+  
+  }
+
+/* 
+printf("DFitLin_Debug B[0..5]= %lg %lg %lg %lg %lg %lg \n",
+       *fp2, *(fp2+1), *(fp2+2), *(fp2+3), *(fp2+4), *(fp2+5));
+*/
+
+/*  On resoud le systeme lineaire : */
+fp = *(DVecf+1);
+det = SolveDLinSyst(DFMtx, *DVecf, fp, nd);
+if (det == 0.0)   { rc = -500.;  goto Fin; }
+
+/*  On calcule le Xi2  */
+x = DVecxVec( *DVeci, *DVeci, vsz);
+for(i=0; i<nd; i++)   /* Et on remplit le vecteur de sortie */
+  {
+  fp2 = DFMtx2+i*nd+i;   y = XVar[i] = *(*(DVecf+1)+i);  
+  x += (y * y * *fp2);
+  x -= ( 2.0 * ( y * *(*(DVecf+2)+i) ) );
+  for (j=i+1; j<nd; j++)  
+    { fp2++;  
+    x += ( 2.0 * ( y * *(*(DVecf+1)+j) * *fp2 ) );  }    
+  }
+rc = x;
+
+
+Fin:
+FreeDFitVect();
+return(rc);
+}
+
+
+
Index: /tags/V_Dec2002/SophyaLib/NTools/matxop.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/matxop.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/matxop.h	(revision 2309)
@@ -0,0 +1,57 @@
+/*  Fonctions de manipulation de matrices et de vecteurs    */
+/*  Resolution de systemes lineaires                        */
+
+/*                              R. Ansari  Juillet 1993     */
+/*  Note: 07/94 Fonction GausPiv(Inversion Matrice) CMV     */
+/*        est utilisee pour  R/DFitLinErr()                 */
+
+#ifndef MATXOP_H_SEEN
+#define MATXOP_H_SEEN
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*   Declaration des fonctions   */
+
+/*  Operation Vecteurs/ Matrices   */
+int IVecxVec(int *v1, int *v2, int n);
+float RVecxVec(float *v1, float *v2, int n);
+double DVecxVec(double *v1, double *v2, int n);
+void  IMatxVec(int *mx, int *vi, int *vo, int n);
+void  RMatxVec(float *mx, float *vi, float *vo, int n);
+void  DMatxVec(double *mx, double *vi, double *vo, int n);
+
+/*  Resolution  de systemes lineaires  */
+float SolveRLinSyst(float *mx, float *b, float *x, int n);
+double SolveDLinSyst(double *mx, double *b, double *x, int n);
+
+
+/*  Ajustement de Chi2   */
+
+/*  Ajustement avec vecteurs de depart Reels  */
+int InitRFitLin(int nstmx, int szv);
+void EndRFitLin(void);
+float **GetRFitVect(int nvar, int vsz);
+void FreeRFitVect(void);
+float RFitLin(int nd, int vsz, float *XVar);
+float RFitLinErr(int nd, int vsz, float *XVar, float *Err);
+
+/*  Ajustement avec vecteurs de depart double  */
+int InitDFitLin(int nstmx, int szv);
+void EndDFitLin(void);
+double **GetDFitVect(int nvar, int vsz);
+void FreeDFitVect(void);
+double DFitLin(int nd, int vsz, double *XVar);
+double DFitLinErr(int nd, int vsz, double *XVar, double *Err);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
+
+
Index: /tags/V_Dec2002/SophyaLib/NTools/median.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/median.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/median.cc	(revision 2309)
@@ -0,0 +1,25 @@
+#if 0
+#include "median.h"
+#include <algorithm>
+
+float MedianFilter(float tab[], int n)
+{
+  sort(tab, tab+n);
+  return (n%2 ? tab[n/2] : (tab[n/2]+tab[n/2-1])/2);
+}
+
+double MedianFilter(double tab[], int n)
+{
+  sort(tab, tab+n);
+  return (n%2 ? tab[n/2] : (tab[n/2]+tab[n/2-1])/2);
+}
+
+void   MedianFilterWindowIdx(float const data[], int ndata, int width, 
+			     int index[])
+{
+  float* tab = new float[witdh];
+
+
+  delete[] tab;
+}
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/median.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/median.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/median.h	(revision 2309)
@@ -0,0 +1,28 @@
+// This may look like C code, but it is really -*- C++ -*-
+
+#include "machdefs.h"
+
+// Filtre median, retourne la valeur mediane du tableau tab.
+//  *** Le tableau est modifie (trie par ordre croissant)
+float  MedianFilter(float  tab[], int n); 
+double MedianFilter(double tab[], int n);
+int    MedianFilterIdx(float tab[], int n); 
+int    MedianFilterIdx(double tab[], int n); 
+
+// Filtre median sur fenetre glissante. 
+// data[index[i]] est la ieme valeur filtree
+void   MedianFilterWindowIdx(float const data[], int ndata, int width, 
+			     int index[]);
+
+// Filtre median sur fenetre glissante. 
+// fdata[] est le tableau filtre
+void   MedianFilterWindow(float const data[], int ndata, int width,
+			  float fdata[]);
+
+// Filtre median sur fenetre glissante. 
+// fdata[] est le tableau filtre. assoc sont des donnees associees,
+// par exemple des erreurs, qui sont reordonnees avec la meme permutation
+// dans fassoc.
+void   MedianFilterWindow(float const data[], float const assoc[],
+			  int ndata, int width,
+			  float[] fdata, float fassoc[]);
Index: /tags/V_Dec2002/SophyaLib/NTools/nbconst.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/nbconst.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/nbconst.h	(revision 2309)
@@ -0,0 +1,82 @@
+/* quelques fonctions mathematiques et constantes utiles */
+/*                                         cmv  23/06/94 */
+#ifndef NBCONST_H_SEEN
+#define NBCONST_H_SEEN
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* EA conflit entre les diverses copies de nbmath.h, nbconst.h... A nettoyer... */
+#undef Pi
+#undef Pis2
+#undef DeuxPi
+#undef SPi
+#undef S2Pi
+#undef Rac2
+#undef Log2
+#undef LnPi
+#undef LgPi
+#undef Ln10
+#undef DftoDm
+#undef Hln2pi
+#undef DegenRad
+#undef JourSec
+#undef AnSec
+
+#undef UAenKM
+#undef UAenLY
+#undef KPCenKM
+#undef KPCenUA
+#undef KPenLY
+#undef LYenKM
+#undef RSolenKM
+#undef RTenKM
+#undef MSolenKg
+#undef GC_RE
+
+#undef GRAND  
+#undef GRAND2 
+#undef IGRAND 
+
+#define Pi     (double) (3.1415926535897931)   /*!< Pi */
+#define Pis2   (double) (1.57079632679489655)  /*!< Pi/2 */
+#define DeuxPi (double) (6.2831853071795862)   /*!< 2*Pi */
+#define SPi    (double) (1.7724538509055159)   /*!< sqrt(Pi) */
+#define S2Pi   (double) (2.5066282746310002)   /*!< sqrt(2*Pi) */
+#define Rac2   (double) (1.4142135623730950)   /*!< sqrt(2) */
+#define Log2   (double) (0.30102999566398119)  /*!< log10(2) */
+#define LnPi   (double) (1.1447298858494002)   /*!< ln(Pi) */
+#define LgPi   (double) (0.49714987269413385)  /*!< log10(Pi) */
+#define Ln10   (double) (2.3025850929940456)   /*!< ln(10) */
+#define DftoDm (double) (1.0857362047581295)   /*!< 2.5/ln(10) */
+#define Hln2pi (double) (0.91893853320467267)  /*!< Ln(2*pi)/2 */
+#define DegenRad (double) (0.0174532925199)    /*!< nombre de radians dans un degre */
+#define AMnenRad (double) (0.000290888208665)    /*!< nombre de radians dans une arc minute */
+
+#define JourSec (float) (86400.)    /*!< nombre de secondes dans 24H */
+#define AnSec  (int) (31557600)     /*!< nombre de secondes dans 365.25 jours */
+
+#define UAenKM (double) (149597870.) /*!< nombre de kilometres dans une unite astronomique */
+#define UAenLY (double) (1.5812507406e-5) /*!< unite astronomique en annees lumiere */
+#define KPCenKM (double) (3.0856775807e+16) /*!< nombre de kilometres dans un kiloparsec */
+#define KPCenUA (double) (206264806.248) /*!< nombre d'unites astronomiques dans un kiloparsec */
+#define KPenLY (double) (3261.5637763) /*!< kiloparsec en annees lumiere */
+#define LYenKM (double) (9.4607304725808*e+12) /*!< annee lumiere en kilometres */
+#define RSolenKM (double) (6.9599e+5) /*!< Rayon solaire en kilometres */
+#define RTenKM (double) (6378.14) /*!< rayon equatorial terrestre en kilometres */
+
+#define MSolenKg (double) (1.9891e+30) /*!< masse solaire en kilogramme */
+
+#define GC_RE ((double) 4.7854172e-17) /*!< G/c**2 en unites kpc/Mo */
+
+#define GRAND  (float) (1.e+35)
+#define GRAND2 (double) (1.e+35)
+#define IGRAND (int_4) (2147483647)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/nbinteg.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/nbinteg.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/nbinteg.h	(revision 2309)
@@ -0,0 +1,146 @@
+/* Pour integration par la methode "higher order gaussian terms" */
+/*                                                cmv   23/06/94 */
+
+#ifndef NBINTEG_H_SEEN
+#define NBINTEG_H_SEEN
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*=============================================================*/
+static int mIhoq2 = 2;
+static double Ihoq2X[2] =
+   { -0.288675135, 0.288675135 };
+static double Ihoq2W[2] =
+   {  0.500000000, 0.500000000 };
+/*=============================================================*/
+static int mIhoq3 = 3;
+static double Ihoq3X[3] =
+   { -0.387298335, 0.000000000, 0.387298335 };
+static double Ihoq3W[3] =
+   {  0.277777778, 0.444444444, 0.277777778 };
+/*=============================================================*/
+static int mIhoq4 = 4;
+static double Ihoq4X[4] =
+   { -0.430568156,-0.169990522, 0.169990522, 0.430568156 };
+static double Ihoq4W[4] =
+   {  0.173927423, 0.326072577, 0.326072577, 0.173927423 };
+/*=============================================================*/
+static int mIhoq5 = 5;
+static double Ihoq5X[5] =
+   { -0.453089923,-0.269234655, 0.000000000, 0.269234655,
+      0.453089923 };
+static double Ihoq5W[5] =
+   {  0.118463443, 0.239314335, 0.284444444, 0.239314335,
+      0.118463443 };
+/*=============================================================*/
+static int mIhoq6 = 6;
+static double Ihoq6X[6] =
+   { -0.466234757,-0.330604693,-0.119309593, 0.119309593,
+      0.330604693, 0.466234757 };
+static double Ihoq6W[6] =
+   {  0.085662246, 0.180380787, 0.233956967, 0.233956967,
+      0.180380787, 0.085662246 };
+/*=============================================================*/
+static int mIhoq7 = 7;
+static double Ihoq7X[7] =
+   { -0.474553956,-0.370765593,-0.202922576, 0.000000000,
+      0.202922576, 0.370765593, 0.474553956 };
+static double Ihoq7W[7] =
+   {  0.064742483, 0.139852696, 0.190915025, 0.208979592,
+      0.190915025, 0.139852696, 0.064742483 };
+/*=============================================================*/
+static int mIhoq8 = 8;
+static double Ihoq8X[8] =
+   { -0.480144928,-0.398333239,-0.262766205,-0.091717321,
+      0.091717321, 0.262766205, 0.398333239, 0.480144928 };
+static double Ihoq8W[8] =
+   {  0.050614268, 0.111190517, 0.156853323, 0.181341892,
+      0.181341892, 0.156853323, 0.111190517, 0.050614268 };
+/*=============================================================*/
+static int mIhoq9 = 9;
+static double Ihoq9X[9] =
+   { -0.484080120,-0.418015554,-0.306685716,-0.162126712,
+      0.000000000, 0.162126712, 0.306685716, 0.418015554,
+      0.484080120 };
+static double Ihoq9W[9] =
+   {  0.040637194, 0.090324080, 0.130305348, 0.156173539,
+      0.165119678, 0.156173539, 0.130305348, 0.090324080,
+      0.040637194 };
+/*=============================================================*/
+static int mIhoq10 = 10;
+static double Ihoq10X[10] =
+   { -0.486953264,-0.432531683,-0.339704784,-0.216697697,
+     -0.074437169, 0.074437169, 0.216697697, 0.339704784,
+      0.432531683, 0.486953264 };
+static double Ihoq10W[10] =
+   {  0.033335672, 0.074725675, 0.109543181, 0.134633360,
+      0.147762112, 0.147762112, 0.134633360, 0.109543181,
+      0.074725675, 0.033335672 };
+/*=============================================================*/
+static int mIhoq16 = 16;
+static double Ihoq16X[16] =
+   { -0.494700467,-0.472287512,-0.432815601,-0.377702204,
+     -0.308938122,-0.229008389,-0.140801775,-0.047506255,
+      0.047506255, 0.140801775, 0.229008389, 0.308938122,
+      0.377702204, 0.432815601, 0.472287512, 0.494700467 };
+static double Ihoq16W[16] =
+   {  0.013576230, 0.031126762, 0.047579256, 0.062314486,
+      0.074797994, 0.084578260, 0.091301708, 0.094725305,
+      0.094725305, 0.091301708, 0.084578260, 0.074797994,
+      0.062314486, 0.047579256, 0.031126762, 0.013576230 };
+/*=============================================================*/
+
+
+/* Integration 2D domaine carre */
+/* Selon Abramowitz p892-893 formule 25.462, residu ordre 0.5**6 */
+/* 0.387298=0.5*sqrt(3/5)  0.197531=16/81  0.123457=10/81  0.077160=25/324 */
+/*  */
+#if defined(SIMPSON9)
+  static int   nd2d = 9;
+  static float dx2d[9] = { 0.000000 ,  0.000000 ,  0.000000
+                         ,-0.387298 ,  0.387298 , -0.387298
+                         , 0.387298 , -0.387298 ,  0.387298 };
+  static float dy2d[9] = { 0.000000 , -0.387298 ,  0.387298
+                         , 0.000000 ,  0.000000 , -0.387298
+                         , 0.387298 ,  0.387298 , -0.387298 };
+  static float  w2d[9] = { 0.197531 ,  0.123457 ,  0.123457
+                         , 0.123457 ,  0.123457 ,  0.077157
+                         , 0.0771605,  0.0771605,  0.0771605};
+#elif defined(SIMPSON4)
+  static int   nd2d = 4;
+  static float dx2d[4] = { 0.288675, 0.288675,-0.288675,-0.288675 };
+  static float dy2d[4] = { 0.288675,-0.288675, 0.288675,-0.288675 };
+  static float  w2d[4] = { 0.250000, 0.250000, 0.250000, 0.250000 };
+#elif defined(INTEG5)
+  static int   nd2d = 5;
+  static float dx2d[5] = { 0. , -0.3, -0.3,  0.3, 0.3 };
+  static float dy2d[5] = { 0. , -0.3,  0.3, -0.3, 0.3 };
+  static float  w2d[5] = { 0.2,  0.2,  0.2,  0.2, 0.2 };
+#elif  defined(NOINTEG)
+  static int   nd2d = 1;
+  static float dx2d[1] = { 0. };
+  static float dy2d[1] = { 0. };
+  static float  w2d[1] = { 1. };
+#else
+  static int   nd2d = 0;
+  static float dx2d[1] = { 999999. };
+  static float dy2d[1] = { 999999. };
+  static float  w2d[1] = { 0. };
+#endif
+
+
+/* Coeff pour le calcul du volume de f(x,y,z) dans des cubes 3D */
+static int   nd3d = 6;
+static float dx3d[6] = { 0.5, -0.5, 0.0,  0.0, 0.0,  0.0  };
+static float dy3d[6] = { 0.0,  0.0, 0.5, -0.5, 0.0,  0.0  };
+static float dz3d[6] = { 0.0,  0.0, 0.0,  0.0, 0.5, -0.5  };
+static float  w3d[6] = { 0.166667, 0.166667, 0.166667, 
+                         0.166667, 0.166667, 0.166667 };
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Index: /tags/V_Dec2002/SophyaLib/NTools/nbmath.c
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/nbmath.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/nbmath.c	(revision 2309)
@@ -0,0 +1,2735 @@
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <math.h>
+#include "nbmath.h"
+#include "matxop.h"
+#include "nbinteg.h"
+#include "nbtri.h"
+
+#define ITMAX 256
+#define EPS 3.0e-7
+#define DEB_GausPiv 0
+#define DEB_MeanSig 0
+
+/*
+++ 
+  Module	Fonction mathematiques (C)
+  Lib	LibsUtil
+  include	nbmath.h
+
+	Fonction mathematiques (C)
+--
+*/
+
+void FitFun_MrqCof( double (*FunFit) (double ,double *,double *) ,int_4 type
+           ,FLOATDOUBLE temps,FLOATDOUBLE mag,FLOATDOUBLE err
+           ,int_4 *ndata,int_4 I1,int_4 I2
+           ,double *parcur,int_4 npar,int_4 *ind
+           ,double *ATGA,double *BETA,double *ci2,int_4 deb);
+void nbgcf(double *gammcf,double a,double x,double *gln);
+void nbgser(double *gamser,double a,double x,double *gln);
+
+
+static int FITFUN_DPOL = -1;
+
+
+/*=========================================================================*/
+/*                                      Christophe 8/11/93 La Silla */
+/*
+++
+double FitFun
+|        ( double (*FunFit) (double ,double *,double *) ,int_4 type
+|        ,FLOATDOUBLE temps,FLOATDOUBLE mag,FLOATDOUBLE err
+|        ,int_4 *ndata,int_4 I1,int_4 I2
+|        ,double *par,double *epar,double *stepar
+|        ,double *minpar,double *maxpar,int_4 npar
+|        ,double stochi2,int_4 NstepMX,int_4 deb)
+
+	Pour fitter une fonction parametrique sur des donnees.
+	(Obsolete, utilisez GeneralFit en C++).
+--
+*/
+/*
+++
+| Fonction de fit de la courbe FunFit sur les donnees
+| - Methode:   fit des moindres carres dans le cas non lineaire
+| - Reference: Statistical and Computational Methods in Data Analysis
+|              Siegmund Brandt, North-Holland 1970  p 204-206.
+|              Introduction des limites pour la variation des parametres (cmv).
+|              Increment des parametres selon la methode de Levenberg-Marquardt
+|              (Numerical Receipes in C p 542)
+| - Remarques diverses:
+|     Les points avec erreurs negatives ou nulles ne sont pas
+|                utilises dans le fit.
+|     Si le fit est hautement non lineaire, il faut donner de bonnes
+|                approximations pour les parametres de depart.
+|     Les limites minpar,maxpar sont des limites absolues mais possibles
+| - Memo personnel:
+|     data = Ti, Fi ERRi  i=0,n-1
+|     parametres Pj  j=1,npar
+|     fonction FunFit(t,P1,P2,..,Pnpar)
+|     matrice A(n,4) = [Aij] = - [dg(T)/dPj]  pour t=Ti
+|     matrice G(n,n) = [Gij] = matrice diagonale 1/ERRj**2
+|     matrice C(n) = [Ci] = (Fi - FunFit(t,P1,P2,..,Pnpar))
+|     Pj(iteration n) = Pj(iteration n-1) + Zj
+--
+*/
+/*
+++
+| -----------
+| | ENTREES |
+| -----------
+| - FunFit  fonction a fiter
+| - type    type des donnees a fiter (union temps,mag,err):
+|           float=FITFUN_FLOAT / double=FITFUN_DOUBLE
+| - temps:  union FLOATDOUBLE des tableaux des temps:
+| - mag:    union FLOATDOUBLE des tableaux des magnitudes:
+| - err:    union FLOATDOUBLE des tableaux des erreurs sur la magnitude
+| - ndata:  nombre de donnees en entree, donc en c:
+| - I1:     indice de depart pour le fit
+| - I2:     indice de fin pour le fit
+|           (si I2 <= I1 defaut: 1,*ndata)
+| - par:    contient les valeurs d'initialisation des parametres
+| - stepar: si >0. on fit le parametre, sinon parametre fixe
+| - minpar: les valeurs minimum pouvant prendre les parametres
+| - maxpar: les valeurs minimum pouvant prendre les parametres
+|           (si maxpar[i] <= minpar[i] pas de limitation sur le parametre i)
+| - stochi2:la valeur de variation du chi2 d'une iteration l'autre
+|           en dessous de laquelle on arrete d'iterer:
+|           (si <=0 le default est 0.01).
+| - npar:   nombre de parametres du fit *par --> *(par+npar-1)
+| - NstepMX:nombre maximum d'iterations
+| - deb:    niveau de print (0/1/2/3)
+--
+*/
+/*
+++
+| ----------
+| | SORTIES |
+| ----------
+| - ndata: nombre de donnees utilisees dans le fit
+| - par: contient les valeurs fitees des parametres
+| - epar: contient les erreurs sur les valeurs fitees des parametres
+| - FitFun: la function elle meme retourne le Xi2 du fit si succes
+|       -1. si l'inversion de la matrice des erreurs n'a pas ete possible
+|       -2. si les parametres initiaux sont en desaccord avec les limites
+|       -3. si le nombre de donnees est inferieur au nombre de parametres
+|       -4. si le fit n'a pas converge (nstep>nNstepMX)
+--
+*/
+/*
+++
+| --------------
+| | MEMO PERSO |
+| --------------
+| la structure FLOATDOUBLE:
+| union FloatDouble {
+|   float  *fx;
+|   double *dx;
+| };
+| - Si les tableaux temps,mag,emag sont des float alors
+|   temps.fx doit contenir l'adresse du tableau des temps
+|            (et idem pour mag.fx et err.fx)
+| - Si les tableaux temps,mag,emag sont des double alors
+|   temps.dx doit contenir l'adresse du tableau des temps
+|            (et idem pour mag.dx et err.dx)
+--
+*/
+double FitFun( double (*FunFit) (double ,double *,double *) ,int_4 type
+             ,FLOATDOUBLE temps,FLOATDOUBLE mag,FLOATDOUBLE err
+             ,int_4 *ndata,int_4 I1,int_4 I2
+             ,double *par,double *epar,double *stepar
+             ,double *minpar,double *maxpar,int_4 npar
+             ,double stochi2,int_4 NstepMX,int_4 deb)
+{
+int_4 ind[NPAR_FITFUN], i, j, k, nstep, nparsave, nstop, nstopMX;
+double LimitC2,lambda,eps;
+double ATGA[NPAR_FITFUN][NPAR_FITFUN], COVAR[NPAR_FITFUN][NPAR_FITFUN]
+     , ALPHA[NPAR_FITFUN][NPAR_FITFUN];
+double DA[NPAR_FITFUN], BETA[NPAR_FITFUN];
+double parcur[NPAR_FITFUN],partry[NPAR_FITFUN];
+double ci2, ci20;
+
+/* initialisation */
+if( type != FITFUN_FLOAT && type != FITFUN_DOUBLE) {
+  printf("FitFun: Type de variable non prevue dans union FLOATDOUBLE %d\n",type);
+  exit(-1);
+}
+
+if(npar>NPAR_FITFUN) {
+  printf("FitFun: trop de parametres npar=%d > NPAR_FITFUN=%d\n",npar,NPAR_FITFUN);
+  exit(-1);
+}
+nstopMX = 3;
+eps = 1.e-8;
+LimitC2=0.01;
+if ( stochi2 > 0. ) LimitC2 = stochi2;      /* test des valeurs d'arret */
+nstop = 0;
+
+/* fit du centre autour des valeurs estimees */
+nparsave = npar;
+for (i=0;i<nparsave;i++) parcur[i] = *(par+i);
+
+npar=0;
+for (i=0;i<nparsave;i++) {
+  ind[i]= -1;
+  *(epar+i) = 0.;
+  partry[i] = *(parcur+i);
+  if ( stepar[i] > 0. ) {
+    ind[npar]=i;
+    npar++;
+} }
+
+if ( I2 <= I1 ) { I1 = 0; I2 = *ndata-1;}
+if ( I2-I1+1 < npar ) {
+  printf("le nombre de donnees %d est inferieur au nombre de parametres %d\n"
+        ,I2-I1+1,npar);
+  return(-3.);
+}
+ 
+for (j=0;j<npar;j++) {
+  i = ind[j];
+  if(*(maxpar+i)>*(minpar+i) && (*(parcur+i)<=*(minpar+i) || *(parcur+i)>=*(maxpar+i))) {
+    printf("Parametre %d initialise hors limites: %f # [%f,%f]\n"
+          ,i,*(parcur+i),*(minpar+i),*(maxpar+i));
+    return(-2.);
+} }
+
+if ( deb >= 2 ) {
+  printf("\n******************* ENTREE DANS FitFun ");
+  printf("npar=%d LimitC2=%f\n",npar,LimitC2);
+  printf("parametres"); for(i=0;i<nparsave;i++) printf(" %f",*(parcur+i)); printf("\n");
+  if ( deb >= 3 ) {
+    printf("       ind"); for(i=0;i<nparsave;i++) printf(" %12d",*(ind+i)); printf("\n");
+    printf("    stepar"); for(i=0;i<nparsave;i++) printf(" %12.5g",*(stepar+i)); printf("\n");
+    printf("    minpar"); for(i=0;i<nparsave;i++) printf(" %12.5g",*(minpar+i)); printf("\n");
+    printf("    maxpar"); for(i=0;i<nparsave;i++) printf(" %12.5g",*(maxpar+i)); printf("\n");
+} }
+
+/* premiere essai avec les parametres d'initialisation */
+
+FitFun_MrqCof(FunFit,type,temps,mag,err,ndata,I1,I2,parcur,npar,ind,ALPHA[0],BETA,&ci2,deb);
+
+ci20 = ci2;
+lambda = 0.001;
+
+if ( *ndata < npar ) {
+  printf("le nombre de donnees %d est inferieur au nombre de parametres %d\n",*ndata,npar);
+  return(-3.);
+}
+
+if ( deb >= 2 ) printf("Passage d'initialisation ci2= %e, lambda=%e\n",ci2,lambda);
+
+/* et maintenant les iterations */
+
+nstep = 0;
+/************************ ITERATIONS *******************************************/
+ITERATE:
+nstep++;
+
+if ( deb >= 2 ) printf("------------------------- pas %d\n",nstep);
+
+if(nstep > NstepMX) {
+  printf("FitFun: Le fit n'a pas converge (trop d'iterations %d).\n",nstep);
+  if (deb>0 ) {
+    printf("== Parametres finals:");
+    for(k=0;k<nparsave;k++) printf(" %15.8e",parcur[k]); printf("\n");
+    for(i=0;i<npar;i++) { *(epar+ind[i]) = -1.; par[ind[i]] = parcur[ind[i]];}
+  }
+  return(-4.);
+}
+
+for(j=0;j<npar;j++) {
+  for(i=0;i<npar;i++) ATGA[j][i] = ALPHA[j][i];
+  ATGA[j][j] *= 1.0 + lambda;
+}
+
+/* inversion de   ( At * G * A ) */
+if( GausPiv(ATGA[0],NPAR_FITFUN,npar,COVAR[0],NPAR_FITFUN,npar,1) == 0. ) {
+  printf("La matrice des erreurs n'est pas inversible\n");
+  return(-1.);
+}
+if( deb >= 3 ) {
+  printf("matrice 1/( At * G * A )\n");
+  for ( i=0; i<npar; i++ ) {
+    for ( j=0; j<npar; j++ ) printf(" %15.8e",COVAR[i][j]);
+    printf("\n");
+} }
+
+/* compute next increment */
+for(i=0;i<npar;i++) {
+  DA[i] = 0.;
+  for(j=0;j<npar;j++) DA[i] += COVAR[i][j] * BETA[j];
+}
+if ( deb >= 2 ) {
+  printf("Correction parametres proposee:");
+  for (i=0;i<npar;i++) printf(" %12.5e",DA[i]); printf("\n");
+}
+
+/* on s'arrete la, il y a eu convergence */
+if ( lambda == 0. ) {
+  for(i=0;i<npar;i++) { *(epar+ind[i]) = sqrt(COVAR[i][i]); par[ind[i]] = parcur[ind[i]];}
+  if (deb>0 ) {
+    printf("===============================================================\n");
+    printf("== ci2= %15.8e (%15.8e) ndata= %d nstep= %d\n",ci2,ci2/(*ndata-npar+1),*ndata,nstep);
+    printf("== Parametres finals:"); for(k=0;k<nparsave;k++) printf(" %15.8e", par[k]); printf("\n");
+    printf("==               +/- "); for(k=0;k<nparsave;k++) printf(" %15.8e",epar[k]); printf("\n");
+    printf("===============================================================\n");
+  }
+  return( (float) ci2 );
+}
+
+/* essai des nouveaux parametres */
+for(j=0;j<npar;j++) {
+  k = ind[j];
+  if( nstep == 1 && fabs(DA[j]) > stepar[k] ) {
+    partry[k] = parcur[k] + stepar[k] * DA[j] / fabs(DA[j]);
+  } else {
+    partry[k] = parcur[k] + DA[j];
+  }
+  if(maxpar[k] > minpar[k] ) {
+    if( partry[k] < minpar[k] ) {
+      partry[k] = minpar[k];
+      if(deb>=2) printf("Parametre %3d limite au minimum %e\n",k,partry[k]);
+    }
+    if( partry[k] > maxpar[k] ) {
+      partry[k] = maxpar[k];
+      if(deb>=2) printf("Parametre %3d limite au maximum %e\n",k,partry[k]);
+    }
+} }
+if ( deb>=2)
+  {
+  printf("essai avec");
+  for(k=0;k<nparsave;k++) printf(" %15.8e", partry[k]);
+  printf("\n");
+  }
+
+/* calcul du nouveau ci2 avec partry */
+FitFun_MrqCof(FunFit,type,temps,mag,err,ndata,I1,I2,partry,npar,ind,ATGA[0],DA,&ci2,deb);
+if(deb>=2) printf("Ci2: old=%e new=%e %e\n",ci20,ci2,ci2-ci20);
+
+/* test sur l'evolution du ci2 et la strategie a suivre */
+if ( ci2 < ci20 ) {
+  nstop = 0;
+  for (j=0;j<npar;j++) {
+    for(i=0;i<npar;i++) ALPHA[j][i] = ATGA[j][i];
+    BETA[j] = DA[j];
+    parcur[ind[j]] = partry[ind[j]];
+  }
+  lambda *= 0.1;
+  if( ci20 - ci2 < LimitC2 ) lambda = 0.;
+  ci20 = ci2;
+  if(deb>=2) {
+    printf("lambda divided by 10. %e\n",lambda);
+    printf("Nouveaux parametres"); for(k=0;k<nparsave;k++) printf(" %12.5e",parcur[k]); printf("\n");
+  }
+} else {
+  /* on arrete si pas assez de variation de chi2 + pas assez de variation de parametres */
+  if( ci2 - ci20 < LimitC2 ) {
+    k=0;
+    for(i=0;i<npar;i++) if( fabs( parcur[ind[i]] - partry[ind[i]] ) < eps ) k++;
+    if(k == npar) { nstop++; } else { nstop=0;};
+    /* printf("ci2-ci20=%f npar=%d (%d) nstop=%d\n"
+           ,ci2-ci20,npar,k,nstop); */
+  } else {
+    nstop = 0;
+  }
+  lambda *= 10.;
+  if(nstop>=nstopMX) lambda = 0.;
+  ci2 = ci20;
+  if(deb>=2) printf("Echec essai, lambda multiplied by 10. %e\n",lambda);
+}
+
+goto ITERATE;
+
+}
+
+/*=========================================================================*/
+void FitFun_MrqCof(double (*FunFit) (double ,double *,double *) ,int_4 type
+           ,FLOATDOUBLE temps,FLOATDOUBLE mag,FLOATDOUBLE err
+           ,int_4 *ndata,int_4 I1,int_4 I2
+           ,double *parcur,int_4 npar,int_4 *ind
+           ,double *ATGA,double *BETA,double *ci2,int_4 deb)
+{
+int_4 i, j, k;
+double deriv[NPAR_FITFUN], t, f, e, Gkk, Ck, funfit;
+
+for (i=0; i<npar;i++) { BETA[i] = 0.; for (j=0; j<npar;j++) *(ATGA+i*NPAR_FITFUN+j) = 0.;}
+*ci2 = 0.;
+*ndata = 0;
+
+/* calcul de  ( At * G * A ) */
+for (k=I1; k<=I2; k++) {
+  e = (type == FITFUN_FLOAT) ? *(err.fx + k) : *(err.dx + k);
+  if ( e > 0. ) {
+    (*ndata)++;
+    t = (type == FITFUN_FLOAT) ? *(temps.fx + k) : *(temps.dx + k);
+    f = (type == FITFUN_FLOAT) ? *(mag.fx   + k) : *(mag.dx + k);
+    funfit = FunFit(t,parcur,deriv);
+    Gkk = 1./e/e;
+    Ck = f - funfit;
+    *ci2 += Ck*Ck*Gkk;
+    for ( j=0; j<npar; j++ ) {
+      for ( i=j; i<npar; i++ ) *(ATGA+i*NPAR_FITFUN+j) += deriv[ind[i]] * Gkk * deriv[ind[j]];
+      BETA[j] += deriv[ind[j]] * Gkk * Ck;
+} } }
+
+for(j=1;j<npar;j++) for(i=0;i<j;i++) *(ATGA+i*NPAR_FITFUN+j) = *(ATGA+j*NPAR_FITFUN+i);
+
+if( deb >= 3 ) {
+  printf("matrice ( At * G * A )\n");
+  for ( i=0; i<npar; i++ ) {
+    for ( j=0; j<npar; j++ ) printf(" %15.8e",*(ATGA+i*NPAR_FITFUN+j));
+    printf("\n");
+  }
+  printf("BETA:");
+  for ( j=0; j<npar; j++ ) printf(" %15.8e",BETA[j]);
+  printf("\n");
+}
+
+}
+
+/*=========================================================================*/
+/*                                          Christophe 8/11/93 La Silla */
+/*
+++
+double GausPiv(double *A,int_4 nca,int_4 n,double *B,int_4 ncb,int_4 m,int_4 Inv)
+	Inversion de matrice par la methode du pivot de Gauss.
+--
+*/
+/*
+++
+| Inv=0: resolution d'un systeme A(n,n) * X(n,m) = B(n,m)  
+|        en entree matrices A,B de taille A[?>=n][nca>=n] et B[?>=n][ncb>=m]
+|        en sortie la matrice B contient le resultat X
+| Inv#0: inversion de la matrice A(n,n)
+|        en entree matrice A
+|        en sortie la matrice B contient le resultat 1/A 
+| GausPiv: retourne le determinant (0. si non-inversible!)
+--
+*/
+/*
+++
+|Remarque: 
+|-matrice A[?>=n][nca>=n],
+|       element Aij = "A'[i][j] de ss matrice A'[n][n]" = *(A+i*nca+j)
+|       ou 0<=i<n indice de ligne; ou 0<=j<n indice de colonne; 
+|-matrice B[?>=n][ncb>=m],
+|       element Bij = "B'[i][j] de ss matrice B'[n][m]" = *(B+i*ncb+j)
+|       ou 0<=i<n indice de ligne; ou 0<=j<m indice de colonne;
+|exemple 1: on veut resoudre le systeme A(4,4) * X = B(4,3)
+|           et on definit dans le prog appelant: double A[12][7],B[32][5]
+|           on appelle: GausPiv(&A[0][0],7,4,&B[0][0],5,3,0)
+|exemple 2: on veut resoudre le systeme A(4,4) * X = B(4)
+|           et on definit dans le prog appelant: double A[4][4],B[4]
+|           on appelle: GausPiv(A[0],4,4,B,1,1,0)
+|exemple 3: on veut resoudre le systeme A(4,4) * X = B(4)
+|           et on definit dans le prog appelant: double A[9][4],B[7,3]
+|           on appelle: GausPiv(A[0],4,4,B,3,1,0)
+|Methode: methode de gauss avec choix du pivot maximum
+|Reference: Statistical and Computational Methods in Data Analysis
+|           Siegmund Brandt, North-Holland 1970  p 350-361.
+|Attention: la matrice A est detruite et la matrice B aussi (evidemment)
+--
+*/
+double GausPiv(double *A,int_4 nca,int_4 n,double *B,int_4 ncb,int_4 m,int_4 Inv)
+{
+int_4 deb=DEB_GausPiv;
+int_4 i,j,k,l,i1,i2,j1,j2,j3,j4,ij,ii,il,lj,kj,k1,nj,kk,ik,nn,kmax,i1max;
+double amax,save,det;
+
+if ( n < 1 ) {
+  printf("GausPiv: pas de resolution de systeme de dimension %d\n",n);
+  return(0.);
+}
+
+/* ********************************************************** */
+/* cas d'une inversion de matrice: on met B = matrice identite*/
+/* ********************************************************** */
+if ( Inv != 0 ) {
+  if ( m != n ) {
+    printf("GausPiv: Vous voulez inverser une matrice non carree %d %d\n",n,m);
+    return(0.);
+  }
+  for (i=0;i<n;i++) {
+    for (j=0;j<n;j++) {
+      if ( i != j ) { *(B+i*ncb+j) = 0.; } else { *(B+i*ncb+j) = 1.;}
+} } }
+
+if ( deb>0 ) {
+  printf("** Matrices de depart\n");
+  printf("Matrice A %d %d:\n",nca,n);
+  for (i=0;i<n;i++) {
+    for (j=0;j<n;j++) printf(" %15.8e",*(A+i*nca+j));
+    printf("\n");
+  }
+  printf("Matrice B %d %d:\n",ncb,m);
+  for (i=0;i<n;i++) {
+    for (j=0;j<m;j++) printf(" %15.8e",*(B+i*ncb+j));
+    printf("\n");
+} }
+
+/* ***************************************************************** */
+/*    reduction de la matrice A a la forme triangulaire superieure   */
+/* ***************************************************************** */
+det=1.;
+kmax = n-1;
+for (k=0;k<kmax;k++) {         /* on travaille sur la ligne k */
+  if ( deb>0 ) printf("-----> reduction ligne %d\n",k);
+  amax=0.;    /*recherche du plus grand coeff pour le pivot*/
+  j2=k;       /* dans col k pour les lignes >= k */
+  for (j1=k;j1<n;j1++) {
+    ik = j1*nca+k;
+    if( fabs(amax)-fabs(*(A+ik)) < 0. ) {
+      amax = *(A+ik);
+      j2 = j1;
+  } }
+  if ( deb>0 ) printf("pivot sur la ligne %d max= %f\n",j2,amax);
+  if ( j2 != k ) {      /* echange des lignes k et j2 si necessaire*/
+    for (j=k;j<n;j++) {
+      j3=k*nca+j;
+      j4=j2*nca+j;
+      save = *(A+j3);
+      *(A+j3) = *(A+j4);
+      *(A+j4) = save;
+    }
+    for (j=0;j<m;j++) {
+      j3=k*ncb+j;
+      j4=j2*ncb+j;
+      save = *(B+j3);
+      *(B+j3) = *(B+j4);
+      *(B+j4) = save;
+    }
+    if ( deb>0 ) {
+      printf("Matrice A echange des lignes %d et %d :\n",k,j2);
+      for (i=0;i<n;i++) {
+        for (j=0;j<n;j++) printf(" %15.8e",*(A+i*nca+j));
+        printf("\n");
+      }
+      printf("Matrice B echange des lignes %d et %d :\n",k,j2);
+      for (i=0;i<n;i++) {
+        for (j=0;j<m;j++) printf(" %15.8e",*(B+i*ncb+j));
+        printf("\n");
+  } } }
+  k1=k+1;  /* on effectue la substitution-soustraction sur les lignes qui suivent*/
+  kk = k*nca+k;      /* c'est le pivot*/
+  if ( deb>0 ) printf("valeur du pivot %f\n",*(A+kk));
+  if ( *(A+kk) == 0. ) {
+    /* printf("Matrice non-inversible: pivot %d nul\n",k); */
+    return(0.);
+  } else { det *= *(A+kk); }
+  for (i=k1;i<n;i++) {
+    ik = i*nca+k;  /* c est le premier element de la ligne i */
+    for (j=k1;j<n;j++) {
+      ij= i*nca+j;
+      kj= k*nca+j;
+      *(A+ij) += -*(A+kj) * *(A+ik) / *(A+kk);
+    }
+    for (j=0;j<m;j++) {
+      ij= i*ncb+j;
+      kj= k*ncb+j;
+      *(B+ij) += -*(B+kj) * *(A+ik) / *(A+kk);
+  } }
+  if ( deb>0 ) {
+    printf("Matrice A:\n");
+    for (i=0;i<n;i++) {
+      for (j=0;j<n;j++) printf(" %15.8e",*(A+i*nca+j));
+      printf("\n");
+    }
+    printf("Matrice B:\n");
+    for (i=0;i<n;i++) {
+      for (j=0;j<m;j++) printf(" %15.8e",*(B+i*ncb+j));
+      printf("\n");
+} } }     /* fin du travail sur la ligne k */
+det *= *(A+(n-1)*nca+(n-1));
+if ( deb>0 ) printf("Determinant de A= %e\n",det);
+
+/* ********************************************************** */
+/*       back substitution                                    */
+/* ********************************************************** */
+nn=(n-1)*nca+(n-1);     /* l'element (n,n) */
+for (j=0;j<m;j++) {
+  nj=(n-1)*ncb+j;
+  if ( *(A+nn) == 0. ) {
+    /* printf("Matrice non-inversible pivot (%d,%d) nul\n",n-1,n-1); */
+    return(0.);
+  }
+  *(B+nj) /= *(A+nn);   /* la derniere ligne traitee a part*/
+  i1max=n-1;
+  if( i1max >= 0 ) {    /* les lignes n-1 a 1 dans cet ordre*/
+    for(i1=1;i1<=i1max;i1++) {
+      i=n-1-i1;         /* ici i va de n-2 a 0 */
+      ij=i*ncb+j;
+      ii=i*nca+i;
+      i2=i+1;           /* pour la ligne i on somme de i+1 a n */
+      for (l=i2;l<n;l++) {
+        il=i*nca+l;
+        lj=l*ncb+j;
+        *(B+ij) -= *(A+il) * *(B+lj);
+      }
+      if ( *(A+ii) == 0. ) {
+        /* printf("Matrice non-inversible pivot (%d,%d) nul\n",i,i); */
+        return(0.);
+      }
+      *(B+ij) /= *(A+ii);
+} } }
+if ( deb>0 ) {
+  printf("-----> Matrice B resultat:\n");
+  for (i=0;i<n;i++) {
+    for (j=0;j<m;j++) printf(" %15.8e",*(B+i*ncb+j));
+    printf("\n");
+} }
+return(det);
+}
+
+/*=========================================================================*/
+/*                                       CMV 17/11/92  */
+/*
+++
+int_4 paramga -
+  (float sxin, float syin, float rhoin -
+  , float *smax, float *axisrat, float *tiltdeg)
+
+	Pour transformer le sx,sy,rho d'une gaussienne en sa,sc/sa,teta.
+--
+*/
+/*
+++
+| - input : sx ]0,inf] ,sy ]0,inf] ,rho ]-1,+1[
+| - output : smax (longeur du grand axe), axisrat (rapport des axes ]0.,1.])
+|     tiltdeg (angle entre le grand axe et l'axe ox en degre ]-90,+90])
+| - Les fonctions sont:
+| exp[-0.5*{[(x/SX)**2-2*RHO/(SX*SY)*x*y+(y/SY)**2]/(1-RHO**2)}]
+| exp[-0.5*{ (A/SA)**2                  +(C/SC)**2            }]
+| - Remarque: sx,sy representent les sigmas des variables x,y et
+| sont differents des sigmas des coupes x=0 et y=0 qui valent:
+|    sigmaX(y=0) = sx*sqrt(1-ro^2) different de sx
+|    sigmaY(x=0) = sy*sqrt(1-ro^2) different de sy
+--
+*/
+int_4 paramga(float sxin, float syin, float rhoin
+             , float *smax, float *axisrat, float *tiltdeg)
+/*
+Cf Formulae and Methods in Experimental Data Evaluation Vol. 1
+rechercher a Bivariate gaussian distribution
+*/
+{
+double sx,sy,rho,a,b,c,alpha,coscar,sincar,cossin,sa,sc;
+
+*smax = 0.; *axisrat = 0.; *tiltdeg = 0.; a = 0.; b = 0.; c = 0.;
+
+/* lecture des arguments */
+sx = sxin;  sy = syin;  rho = rhoin;
+
+/* cas des coniques degenerees ou erreurs dans les parametres*/
+if ( sx <= 0. || sy <= 0. || rho > 1. || rho < -1. ) return(-1);
+
+/* sortie fit : [(x/SX)**2 - 2*RHO/(SX*SY)*x*y + (y/SY)**2]/(1-RHO**2) = 1
+   equation ellipse: A*x**2 + 2*B*x*y + C*y**2  = 1       */
+sa = (1.-rho*rho);
+a = 1./sx/sx/sa;  b = -rho/sx/sy/sa;  c = 1./sy/sy/sa;
+
+/* cas des coniques degenerees (droites limites) */
+if ( rho == 1. || rho == -1. ) return(-2);
+
+/* axes principaux OX OY pour : x = cos(ALPHA)*X - sin(APLHA)*Y
+        (ALPHA = (ox,oX))       y = sin(ALPHA)*X + cos(APLHA)*Y
+  soit   ( A*cos**2 + C*sin**2 + 2*B*cos*sin )*X**2
+     +   ( A*sin**2 + C*cos**2 - 2*B*cos*sin )*Y**2
+     + 2*( -A*cos*sin + C*cos*sin + B*(cos**2-sin**2) )*X*Y
+                   = (X/SA)**2 + (Y/SC)**2 = 1
+  et oX oY axes principaux pour : Tan ( 2*ALPHA ) = 2*B/(A-C) */
+
+if ( a == c && rho == 0. ) {
+  /*  cas d'un cercle */
+  coscar = 0.5;    sincar = coscar;    cossin = coscar;    alpha = 0.;
+} else {
+  if ( a == c ) {
+    /* cas SX=SY ellipse a +/-45 degres */
+    if ( rho > 0. ) {
+      /* cas +45 degres */
+      alpha = Pi / 4.;
+    } else {
+      /* cas -45 degres */
+      alpha = -Pi / 4.;
+    }
+  } else {
+    /* cas general */
+    alpha = atan(2.*b/(a-c)) /2.;
+  }
+  coscar = cos(alpha);
+  sincar = sin(alpha);
+  cossin = coscar*sincar;
+  coscar *= coscar;
+  sincar *= sincar;
+  alpha *= 180./Pi;
+}
+
+sa = a*coscar+c*sincar+2.*b*cossin;
+sc = c*coscar+a*sincar-2.*b*cossin;
+sa = ( sa < 0. ) ? 1./sqrt(-sa) : 1./sqrt(sa);
+sc = ( sc < 0. ) ? 1./sqrt(-sc) : 1./sqrt(sc);
+
+if ( sa >= sc ) {
+  *smax = sa;
+  *axisrat = sc/sa;
+  *tiltdeg = alpha;
+} else {
+  *smax = sc;
+  *axisrat = sa/sc;
+  *tiltdeg = alpha+90.;
+  if ( *tiltdeg > 90. ) *tiltdeg = *tiltdeg-180.;
+}
+
+return(0);
+}
+
+/*========================================================================*/
+/*                               CMV 21/01/94 */
+/*
+++
+int_4 gaparam -
+  (float smax, float axisrat, float tiltdeg -
+  , float *sxin, float *syin, float *rhoin)
+
+	Pour transformer le sa,sc/sa,tiltdeg d'une gaussienne en sx,sy,rho
+	Pour calculer les parametres d'une gaussienne
+--
+*/
+/*
+++
+| - input : sa ]0,inf] ,axisrat ]0,1] ,tiltdeg ]-90,+90]
+|         sa (longeur du grand axe), axisrat (rapport des axes )
+|         tiltdeg (angle entre le grand axe et l'axe ox en degre)
+| - output : sx ]0,inf] , sy ]0,inf] , rho ]-1,1[
+| - Les fonctions sont:
+| exp[-0.5*{ (A/SA)**2                  +(C/SC)**2            }]
+| exp[-0.5*{[(x/SX)**2-2*RHO/(SX*SY)*x*y+(y/SY)**2]/(1-RHO**2)}]
+| - Voir aussi la remarque de la fonction paramga.
+--
+*/
+int_4 gaparam(float smax, float axisrat, float tiltdeg
+             , float *sxin, float *syin, float *rhoin)
+{
+double sx,sy,rho,alpha,coscar,sincar,cossin,sa,sc,a,b,c;
+
+*sxin = 0.; *syin = 0.; *rhoin = 0.;
+
+/* cas des coniques degenerees ou erreurs dans les parametres*/
+if ( smax <= 0. || axisrat <= 0. || axisrat > 1. ) return(-1);
+
+/* lecture des arguments */
+sa = smax;  sc = sa*axisrat;  alpha = tiltdeg*Pi/180.;
+
+coscar = cos(alpha);
+sincar = sin(alpha);
+cossin = coscar*sincar;
+coscar *= coscar;
+sincar *= sincar;
+
+a = 1./(coscar/sa/sa + sincar/sc/sc);
+  a = sqrt(a);         /* = sqrt(1-ro**2)*sx */
+b = 1./(sincar/sa/sa + coscar/sc/sc);
+  b = sqrt(b);         /* = sqrt(1-ro**2)*sy */
+c = cossin*(-1./sa/sa + 1./sc/sc);
+rho = c*a*b;
+sx = a / sqrt(1.-rho*rho);
+sy = b / sqrt(1.-rho*rho);
+
+*sxin = sx; *syin = sy; *rhoin = rho;
+
+return(0);
+}
+
+/*===================================================================*/
+/*
+++
+double nberfc(double x)
+	Erreur fonction complementaire: -log10(erfc)
+	Pratiquement pour avoir la proba que
+	]-inf,-x] U [x,+inf[ selon une loi gaussiene centree et normee
+	il faut appeler nberfc(x/sqrt(2))
+	Le job tiens compte de la saturation machine pour x grand.
+	La valeur est approximee au developpement limite de erfc
+	( see . Abramowitz p299 7.1.23 )
+--
+*/
+double nberfc(double x)
+{
+double v;
+if(x<0.) return(0.);
+if ( x < 10. ) {
+  v = erfc(x);
+  v = -log10(v);
+} else {
+  v = 2.*x*x;
+  v = 1./v - 3./(v*v) + 15./(v*v*v);
+  v += LnPi/2. + log(x) + x*x;
+  v /= Ln10;
+}
+return(v);
+}
+
+/*=========================================================================*/
+/*
+++
+float probnb(float sci2,int_4 inddl,int_4 *ipass)
+	Retourne -log10(p) ou p est la probabilte que le chi2
+	d'une fluctuation inddl points soit superieur a sci2.
+	ipass est le type de calcul utilise.
+--
+*/
+float probnb(float sci2,int_4 inddl,int_4 *ipass)
+{
+int_4 it;
+float nddl;
+double ci2,a1,a2,p,q,val,terme1,terme2,terme3,terme4,teradd,xnprim;
+
+*ipass = 0;
+val = 0.;
+nddl = inddl;
+ci2 = sci2;
+a1 = nddl/2.;
+a2 = ci2/2.;
+
+q = nbgammq(a1,a2);
+if(q>0. && q<1.) {
+  val = -log10(q);   /* moins le log10 de la proba que le chi2 soit > ci2 */
+  *ipass = 1;
+} else if ( q==1.) {
+  p = nbgammp(a1,a2);
+  val = p/Ln10;      /* -log10(q) = -log(1-p)/Ln10 = -(p)/Ln10 = p/Ln10 */
+  *ipass = 2;
+} else {
+  /* approximation de mimile */
+  xnprim = nddl / 2. - 1.;
+  terme1 = nddl / 2. * Log2;        /* 1/2**n */
+  terme2 = Hln2pi + (xnprim+0.5)*log(xnprim) - xnprim + 1./(12.*xnprim);
+  terme2 /= Ln10;         /* formule de stirling pour Gamma[nddl/2] */
+  terme3 = ci2/2. - xnprim*log(ci2);
+  terme3 /= Ln10;         /* exp(-ci2/2)*ci2**(n/2-1) */
+  terme4 = teradd = 1.;
+  for ( it=1; it <= inddl-2; it +=2) {
+    teradd *= ( (double) (nddl -1.) - (double) it ) / ci2;
+    terme4 += teradd;
+    if ( teradd < 1.e-4 ) break;
+  }
+  terme4 = -log10(2.*terme4);
+  val = terme1 + terme2 + terme3 + terme4;
+  *ipass = 3;
+}
+return ((float) val);
+}
+
+/*=========================================================================*/
+/*
+++
+double nbgammln(double xx)
+	Fonction log de la fonction Gamma
+--
+*/
+double nbgammln(double xx)
+{
+   double x,tmp,ser;
+   static double cof[6]={76.18009173,-86.50532033,24.01409822,
+      -1.231739516,0.120858003e-2,-0.536382e-5};
+   int_4 j;
+
+   x=xx-1.0;
+   tmp=x+5.5;
+   tmp -= (x+0.5)*log(tmp);
+   ser=1.0;
+   for (j=0;j<=5;j++) {
+      x += 1.0;
+      ser += cof[j]/x;
+   }
+   return -tmp+log(2.50662827465*ser);
+}
+
+/*=========================================================================*/
+/*
+++
+double nbgammq(double a,double x)
+	Fonction GammaQ
+--
+*/
+double nbgammq(double a,double x)
+{
+   double gamser,gammcf,gln;
+
+   if (x < 0.0 || a <= 0.0) { printf("Invalid arguments in routine NBGAMMQ (%f,%f)\n"
+                                    ,a,x); exit(-1);}
+   if (x < (a+1.0)) {
+      nbgser(&gamser,a,x,&gln);
+      return 1.0-gamser;
+   } else {
+      nbgcf(&gammcf,a,x,&gln);
+      return gammcf;
+   }
+}
+
+/*=========================================================================*/
+/*
+++
+double nbgammp(double a,double x)
+	Fonction GammaP
+--
+*/
+double nbgammp(double a,double x)
+{
+   double gamser,gammcf,gln;
+
+   if (x < 0.0 || a <= 0.0) { printf("Invalid arguments in routine NBGAMMP (%f,%f)\n"
+                                    ,a,x); exit(-1);}
+   if (x < (a+1.0)) {
+      nbgser(&gamser,a,x,&gln);
+      return gamser;
+   } else {
+      nbgcf(&gammcf,a,x,&gln);
+      return 1.0-gammcf;
+   }
+}
+
+/*=========================================================================*/
+void nbgcf(double *gammcf,double a,double x,double *gln)
+{
+   int_4 n;
+   double gold=0.0,g,fac=1.0,b1=1.0;
+   double b0=0.0,anf,ana,an,a1,a0=1.0;
+
+   *gln=nbgammln(a);
+   a1=x;
+   for (n=1;n<=ITMAX;n++) {
+      an=(double) n;
+      ana=an-a;
+      a0=(a1+a0*ana)*fac;
+      b0=(b1+b0*ana)*fac;
+      anf=an*fac;
+      a1=x*a0+anf*a1;
+      b1=x*b0+anf*b1;
+      if (a1) {
+         fac=1.0/a1;
+         g=b1*fac;
+         if (fabs((g-gold)/g) < EPS) {
+            *gammcf=exp(-x+a*log(x)-(*gln))*g;
+            return;
+         }
+         gold=g;
+      }
+   }
+   printf("a too large, ITMAX too small in routine NBGCF (%f,%f)\n",a,x); exit(-1);
+}
+
+/*=========================================================================*/
+void nbgser(double *gamser,double a,double x,double *gln)
+{
+   int_4 n;
+   double sum,del,ap;
+
+   *gln=nbgammln(a);
+   if (x <= 0.0) {
+      if (x < 0.0) { printf("x less than 0 in routine NBGSER (%f,%f)\n",a,x); exit(-1); }
+      *gamser=0.0;
+      return;
+   } else {
+      ap=a;
+      del=sum=1.0/a;
+      for (n=1;n<=ITMAX;n++) {
+         ap += 1.0;
+         del *= x/ap;
+         sum += del;
+         if (fabs(del) < fabs(sum)*EPS) {
+            *gamser=sum*exp(-x+a*log(x)-(*gln));
+            return;
+         }
+      }
+      printf("a too large, ITMAX too small in routine NBGSER (%f,%f)\n",a,x); exit(-1);
+      return;
+   }
+}
+
+/*==========================================================================*/
+/*
+++
+void Set_Ihoq(int degre,int *mIhoqN,double *IhoqNX,double *IhoqNW)
+	Set mIhoqN,IhoqNX,IhoqNW pour integration Gauss-Legendre
+--
+*/
+void Set_Ihoq(int degre,int *mIhoqN,double *IhoqNX,double *IhoqNW)
+{
+switch (degre) {
+  case  2:
+         *mIhoqN = mIhoq2;
+          IhoqNX = Ihoq2X;
+          IhoqNW = Ihoq2W;
+          break;
+  case  3:
+         *mIhoqN = mIhoq3;
+          IhoqNX = Ihoq3X;
+          IhoqNW = Ihoq3W;
+          break;
+  case  4:
+         *mIhoqN = mIhoq4;
+          IhoqNX = Ihoq4X;
+          IhoqNW = Ihoq4W;
+          break;
+  case  5:
+         *mIhoqN = mIhoq5;
+          IhoqNX = Ihoq5X;
+          IhoqNW = Ihoq5W;
+          break;
+  case  6:
+         *mIhoqN = mIhoq6;
+          IhoqNX = Ihoq6X;
+          IhoqNW = Ihoq6W;
+          break;
+  case  7:
+         *mIhoqN = mIhoq7;
+          IhoqNX = Ihoq7X;
+          IhoqNW = Ihoq7W;
+          break;
+  case  8:
+         *mIhoqN = mIhoq8;
+          IhoqNX = Ihoq8X;
+          IhoqNW = Ihoq8W;
+          break;
+  case  9:
+         *mIhoqN = mIhoq9;
+          IhoqNX = Ihoq9X;
+          IhoqNW = Ihoq9W;
+          break;
+  case 10:
+         *mIhoqN = mIhoq10;
+          IhoqNX = Ihoq10X;
+          IhoqNW = Ihoq10W;
+          break;
+  case 16:
+         *mIhoqN = mIhoq16;
+          IhoqNX = Ihoq16X;
+          IhoqNW = Ihoq16W;
+          break;
+  default:
+         *mIhoqN = mIhoq8;
+          IhoqNX = Ihoq8X;
+          IhoqNW = Ihoq8W;
+          break;
+}
+return;
+}
+
+/*==========================================================================*/
+/*
+++
+int Get_Ihoq(int degre,double *ihoqnx,double *ihoqnw)
+	Ecrit les positions et les poids pour l'integration de Gauss-Legendre
+	dans les tableaux *ihoqnx,*ihoqnw.
+	Retourne le nombre de points.
+	Si *ihoqnx==NULL ou *ihoqnw==NULL
+	retourne seulement le nombre de points (cad la taille minimale
+        que doivent les tableaux *ihoqnx,*ihoqnw).
+--
+*/
+int Get_Ihoq(int degre,double *ihoqnx,double *ihoqnw)
+{
+int mIhoqN, i;
+double *IhoqNX, *IhoqNW;
+switch (degre) {
+  case  2:
+          mIhoqN = mIhoq2;
+          IhoqNX = Ihoq2X;
+          IhoqNW = Ihoq2W;
+          break;
+  case  3:
+          mIhoqN = mIhoq3;
+          IhoqNX = Ihoq3X;
+          IhoqNW = Ihoq3W;
+          break;
+  case  4:
+          mIhoqN = mIhoq4;
+          IhoqNX = Ihoq4X;
+          IhoqNW = Ihoq4W;
+          break;
+  case  5:
+          mIhoqN = mIhoq5;
+          IhoqNX = Ihoq5X;
+          IhoqNW = Ihoq5W;
+          break;
+  case  6:
+          mIhoqN = mIhoq6;
+          IhoqNX = Ihoq6X;
+          IhoqNW = Ihoq6W;
+          break;
+  case  7:
+          mIhoqN = mIhoq7;
+          IhoqNX = Ihoq7X;
+          IhoqNW = Ihoq7W;
+          break;
+  case  8:
+          mIhoqN = mIhoq8;
+          IhoqNX = Ihoq8X;
+          IhoqNW = Ihoq8W;
+          break;
+  case  9:
+          mIhoqN = mIhoq9;
+          IhoqNX = Ihoq9X;
+          IhoqNW = Ihoq9W;
+          break;
+  case 10:
+          mIhoqN = mIhoq10;
+          IhoqNX = Ihoq10X;
+          IhoqNW = Ihoq10W;
+          break;
+  case 16:
+          mIhoqN = mIhoq16;
+          IhoqNX = Ihoq16X;
+          IhoqNW = Ihoq16W;
+          break;
+  default:
+          mIhoqN = mIhoq8;
+          IhoqNX = Ihoq8X;
+          IhoqNW = Ihoq8W;
+          break;
+}
+if( ihoqnx!=NULL && ihoqnw!=NULL ) {
+  for(i=0;i<mIhoqN;i++) {
+    ihoqnx[i] = IhoqNX[i];
+    ihoqnw[i] = IhoqNW[i];
+  }
+}
+return(mIhoqN);
+}
+
+/*===================================================================*/
+#define EPS_gauleg 3.0e-11
+/*
+++
+void nbgauleg(double x1,double x2,double *x,double *w,int n)
+	Integration des fonctions a une dimension y=f(x)
+	par la Methode de Gauss-Legendre.
+	Calcul des coefficients du developpement
+--
+*/
+/*
+++
+| INPUT:
+|  x1,x2 : bornes de l'intervalle (dans nbinteg.h -> x1=-0.5 x2=0.5)
+|  n = degre du developpement
+| OUTPUT:
+|  x[] = valeur des abscisses ou l'on calcule (dim=n)
+|  w[] = valeur des coefficients associes
+| REMARQUES:
+|  - x et w doivent au moins etre dimensionner a n.
+|  - l'integration est rigoureuse si sur l'intervalle d'integration
+|    la fonction f(x) peut etre approximee par un polynome
+|    de degre 2*m (monome le + haut x**(2*n-1) )
+|  - Voir la fonction Integ_Fun pour un calcul d'ordre 8
+--
+*/
+void nbgauleg(double x1,double x2,double *x,double *w,int n)
+{
+   int m,j,i;
+   double z1,z,xm,xl,pp,p3,p2,p1;
+
+   m=(n+1)/2;
+   xm=0.5*(x2+x1);
+   xl=0.5*(x2-x1);
+   for (i=1;i<=m;i++)  {
+      z=cos(3.141592654*(i-0.25)/(n+0.5));
+      do {
+         p1=1.0;
+         p2=0.0;
+         for (j=1;j<=n;j++) {
+            p3=p2;
+            p2=p1;
+            p1=((2.0*j-1.0)*z*p2-(j-1.0)*p3)/j;
+         }
+         pp=n*(z*p1-p2)/(z*z-1.0);
+         z1=z;
+         z=z1-p1/pp;
+      } while (fabs(z-z1) > EPS_gauleg);
+      x[i-1]=xm-xl*z;
+      x[n-i]=xm+xl*z;
+      w[i-1]=2.0*xl/((1.0-z*z)*pp*pp);
+      w[n-i]=w[i-1];
+   }
+}
+#undef EPS_gauleg
+
+/*==========================================================================*/
+/*
+++
+double Integ_Fun(double xmin,double xmax,double (*fonc)(double),int npas)
+	Pour integrer la fonction fonc de xmin a xmax sur npas.
+	On emploit une methode Higher-order-gaussienne d'ordre 8, ce qui
+	fait un calcul equivalent de N*npas pas.
+--
+*/
+double Integ_Fun(double xmin,double xmax,double (*fonc)(double),int npas)
+{
+int i,j;
+double dlim,sum,xc,xci;
+
+if( xmax <= xmin ) return(0.);
+if( npas <= 0 ) npas=1;
+sum = 0.;
+dlim = (xmax-xmin)/npas;
+for(i=0;i<npas;i++) {
+  xci = (double) i + 0.5;
+  for(j=0;j<mIhoq8;j++) {
+    xc = xmin + ( xci + Ihoq8X[j] ) * dlim;
+    sum += fonc(xc) * Ihoq8W[j];
+} }
+return(sum*dlim);
+}
+
+/*=========================================================================*/
+/*
+++
+double Integ_Fun_2D -
+  (double (*fonc)(double x,double y) -
+  ,double xmin,double xmax,double ymin,double ymax -
+  ,int npasx,int npasy)
+
+	Integration 2D de fonc(x,y) dans le carre [xmin,xmax] et [ymin,ymax]
+--
+*/
+double Integ_Fun_2D(double (*fonc)(double x,double y)
+                ,double xmin,double xmax,double ymin,double ymax
+                ,int npasx,int npasy)
+{
+int i,j;
+double x,y,pasx,pasy,sum,sumy;
+
+pasx = (xmax-xmin)/npasx;
+pasy = (ymax-ymin)/npasy;
+
+sum = 0.;
+for(i=0;i<npasx;i++) {
+  x = xmin + ((double) i + 0.5 ) * pasx;
+  sumy = 0.;
+  for(j=0;j<npasy;j++) {
+    y = ymin + ((double) j + 0.5 ) * pasy;
+    sumy += fonc(x,y);
+  }
+  sum += sumy;
+}
+return( sum*pasx*pasy);
+}
+
+/*=========================================================================*/
+/*                                    Christophe 01/07/94 */
+/*
+++
+void Set_FitFunDPol(int DPol)
+	Pour donner l'ordre du polynome pour le fit.
+--
+*/
+void Set_FitFunDPol(int DPol) 
+{
+FITFUN_DPOL = DPol;
+}
+
+/*==================================================================*/
+/*                                             Christophe 01/07/94  */
+/*
+++
+double Gauss1DPolF(double x,double *Par,double *DgDpar) 
+	Fonction de fit Gausienne+polynome.
+--
+*/
+/*
+++
+|  f(x) = par[0]*exp[-0.5*( (x-par[1]) / par[2] )**2 ]
+|        +par[3] + par[4]*x + .... + par[3+FITFUN_DPOL]*x**FITFUN_DPOL
+|  FITFUN_DPOL peut etre definit avec la routine Set_FitFunDPol
+--
+*/
+double Gauss1DPolF(double x,double *Par,double *DgDpar) 
+{
+double f,xc,xc2,e,xpow;
+int i;
+
+xc = (x-Par[1])/Par[2];
+xc2 = xc*xc;
+e = exp(-0.5*xc2);
+f = Par[0]*e;
+
+DgDpar[0] = e;
+DgDpar[1] = xc / Par[2] *f;
+DgDpar[2] = xc2/ Par[2] *f;
+
+if(FITFUN_DPOL>=0) {
+  xpow = 1.;
+  for(i=0;i<=FITFUN_DPOL;i++) {
+    DgDpar[3+i] = xpow;
+    f += Par[3+i]*xpow;
+    xpow *= x;
+  }
+}
+
+return (f);
+}
+
+/*==================================================================*/
+/*                                             Christophe 29/08/95  */
+/*
+++
+double GaussI1DPol(double x,double *Par,double *DgDpar) 
+	Fonction de fit Gausienne integree+polynome.
+--
+*/
+/*
+++
+|  f(x) = par[0] / (sqrt(2*Pi)*par[2]) * exp[-0.5*( (x-par[1]) / par[2] )**2 ]
+|        +par[3] + par[4]*x + .... + par[3+FITFUN_DPOL]*x**FITFUN_DPOL
+|  FITFUN_DPOL peut etre definit avec la routine Set_FitFunDPol
+--
+*/
+double GaussI1DPol(double x,double *Par,double *DgDpar) 
+{
+double f,xc,xc2,e,xpow;
+int i;
+
+xc = (x-Par[1])/Par[2];
+xc2 = xc*xc;
+e = exp(-0.5*xc2)/(S2Pi*Par[2]);
+f = Par[0]*e;
+
+DgDpar[0] = e;
+DgDpar[1] = xc / Par[2] *f;
+DgDpar[2] = (xc2-1.)/ Par[2] *f;
+
+if(FITFUN_DPOL>=0) {
+  xpow = 1.;
+  for(i=0;i<=FITFUN_DPOL;i++) {
+    DgDpar[3+i] = xpow;
+    f += Par[3+i]*xpow;
+    xpow *= x;
+  }
+}
+
+return (f);
+}
+
+/*====================================================================*/
+/*                                             Christophe 01/07/94    */
+/*
+++
+double Polyn1D(double x,double *Par,double *DgDpar) 
+	Fonction de fit de polynome.
+--
+*/
+/*
+++
+|  f(x) = par[0] + par[1]*x + .... + par[FITFUN_DPOL]*x**FITFUN_DPOL
+|  FITFUN_DPOL peut etre definit avec la routine Set_FitFunDPol
+--
+*/
+double Polyn1D(double x,double *Par,double *DgDpar) 
+{
+double f,xpow;
+int i,DPol;
+
+DPol = (FITFUN_DPOL<0) ? 0 : FITFUN_DPOL ;
+xpow = 1.;
+f = 0.;
+for(i=0;i<=DPol;i++)
+  {
+  DgDpar[i] = xpow;
+  f += Par[i]*xpow;
+  xpow *= x;
+  }
+return (f);
+}
+
+/*=========================================================================*/
+/*
+++
+double FitProp(double *x,double *y,double *ey,int *n,double *a1)
+	Fit d'une proportion a1: y = a1 * x
+--
+*/
+/*
+++
+| Input:
+|    x = tableau des abscisses
+|    y = tableau des ordonnees
+|    ey = erreurs sur les y
+|    n = nombre de donnees en entree
+| Output:
+|    n = nombre de points utilises (point non utilise si ey<=0)
+|    a1 coefficient
+| Return:
+|    valeur du xi2 si fit reussi,
+|    -1. si pas assez de points
+|    -2. si determinant negatif
+--
+*/
+double FitProp(double *x,double *y,double *ey,int *n,double *a1)
+{
+register int i,np;
+register double X2,XY,Y2,w;
+
+np=0;
+X2=XY=Y2=*a1=0.;
+for(i=0;i<*n;i++) {
+  if(ey[i]<=0.) continue;
+  np++;
+  w = ey[i]*ey[i];
+  X2 += x[i]*x[i]/w;
+  XY += x[i]*y[i]/w;
+  Y2 += y[i]*y[i]/w;
+}
+*n = np;
+if(np<1) return(-1.);
+if(X2==0.) return(-2.);
+*a1 = XY/X2;
+w = Y2 + *a1**a1*X2 -2.**a1*XY;
+return(w);
+}
+
+/*=========================================================================*/
+/*
+++
+double FitLin(double *x,double *y,double *ey,int *n,double *a0,double *a1)
+	Fit d'une droite: y=a0+a1*x
+--
+*/
+/*
+++
+| Input:
+|    x = tableau des abscisses
+|    y = tableau des ordonnees
+|    ey = erreurs sur les y
+|    n = nombre de donnees en entree
+| Output:
+|    n = nombre de points utilises (point non utilise si ey<=0)
+|    a0,a1 coefficients de la droite
+| Return:
+|    valeur du xi2 si fit reussi,
+|    -1. si pas assez de points
+|    -2. si determinant negatif
+--
+*/
+double FitLin(double *x,double *y,double *ey,int *n,double *a0,double *a1)
+{
+register int i,np;
+register double I,X,X2,Y,XY,Y2,w;
+
+np=0;
+Y2=I=X=X2=Y=XY=*a0=*a1=0.;
+for(i=0;i<*n;i++) {
+  if(ey[i]<=0.) continue;
+  np++;
+  w = ey[i]*ey[i];
+  I  += 1./w;
+  X  += x[i]/w;
+  X2 += x[i]*x[i]/w;
+  Y  += y[i]/w;
+  Y2 += y[i]*y[i]/w;
+  XY += x[i]*y[i]/w;
+}
+*n = np;
+if(np<2) return(-1.);
+w = X*X-X2*I;
+if(w==0.) return(-2.);
+*a1 = (Y*X-XY*I)/w;
+*a0 = (X*XY-X2*Y)/w;
+w = Y2 + *a0**a0*I + *a1**a1*X2
+    + 2.*( - Y**a0  - *a1*XY + *a0**a1*X );
+return(w);
+}
+
+/*=========================================================================*/
+/*
+++
+double FitPar(double *x,double *y,double *ey,int *n,double *a0,double *a1,double *a2)
+	Fit d'une parabole: y=a0+a1.x+a2.x^2
+--
+*/
+/*
+++
+| Input:
+|    x = tableau des abscisses
+|    y = tableau des ordonnees
+|    ey = erreurs sur les y
+|    n = nombre de donnees en entree
+| Output:
+|    n = nombre de points utilises (point non utilise si ey<=0)
+|    a0,a1 coefficients de la droite
+| Return:
+|    valeur du xi2 si fit reussi,
+|    -1. si pas assez de points
+|    -2. si determinant negatif
+--
+*/
+double FitPar(double *x,double *y,double *ey,int *n,double *a0,double *a1,double *a2)
+{
+register int i,np;
+register double I,X,X2,X3,X4,Y,Y2,XY,X2Y,w,x2;
+
+np=0;
+I=X=X2=X3=X4=Y=Y2=XY=X2Y=*a0=*a1=*a2=0.;
+
+for(i=0;i<*n;i++) {
+  if(ey[i]<=0.) continue;
+  np++;
+  x2 = x[i]*x[i];
+  w = ey[i]*ey[i];
+  I   += 1./w;
+  X   += x[i]/w;
+  X2  += x2/w;
+  X3  += x2*x[i]/w;
+  X4  += x2*x2/w;
+  Y   += y[i]/w;
+  Y2  += y[i]*y[i]/w;
+  XY  += x[i]*y[i]/w;
+  X2Y += x2*y[i]/w;
+}
+*n = np;
+if(np<3) return(-1.);
+w = X2*(X2*X2-X3*X) -X*(X3*X2-X4*X) +I*(X3*X3-X4*X2);
+if(w==0.) return(-2.);
+*a2 =  (Y*(X2*X2-X3*X)  -XY*(X*X2-X3*I)  +X2Y*(X*X-X2*I)  )/w;
+*a1 = -(Y*(X3*X2-X4*X)  -XY*(X2*X2-X4*I) +X2Y*(X2*X-X3*I) )/w;
+*a0 =  (Y*(X3*X3-X4*X2) -XY*(X2*X3-X4*X) +X2Y*(X2*X2-X3*X))/w;
+w = Y2 + *a0**a0*I + *a1**a1*X2 + *a2**a2*X4
+    +2.*( -Y**a0  -*a1*XY -*a2*X2Y
+          +*a0**a1*X +*a0**a2*X2+*a1**a2*X3 );
+return(w);
+}
+
+/*=========================================================================*/
+/*
+++
+double FitParLin -
+  (double *xx,double *y,double *ey,int *n,double x0,int Deg_d -
+  ,double *a0,double *a1,double *b1,double *b2)
+
+--
+*/
+/*
+++
+| Fit d'une parabole: y=a0+b1*(x-x0)+b2*(x-x0)**2
+|                                     pour x>x0
+|    et d'une droite: y=a0+a1*(x-x0)  pour x<=x0
+| Input:
+|    x = tableau des abscisses
+|    y = tableau des ordonnees
+|    ey = erreurs sur les y
+|    n = nombre de donnees en entree
+|    x0 = abscisse du point pivot (il n'est pas fitte)
+|    Deg_d = degre du fit a droite de x0 (1 ou 2)
+| Output:
+|    n = nombre de points utilises (point non utilise si ey<=0)
+|    a0,a1 coefficients de la droite
+|    a0,b1,b2 coefficients de la parabole
+--
+*/
+/*
+++
+| Return:
+|    valeur du xi2 si fit reussi,
+|    -1. si pas assez de points
+|    -2. si determinant negatif
+| Remarque:
+|    Il faut evidemment au moins 2 points a gauche du pivot x0
+|                       et 3 points a droite du pivot x0
+| Matrices A * a = B :
+|        |   I_   X_g   X_d X2_d |   | a0 |   |    Y_ |
+|        |  X_g  X2_g     0    0 | * | a1 | = |  XY_g |
+|        |  X_d     0  X2_d X3_d |   | b1 |   |  XY_d |
+|        | X2_d     0  X3_d X4_d |   | b2 |   | X2Y_d |
+--
+*/
+double FitParLin(double *xx,double *y,double *ey,int *n,double x0,int Deg_d
+                ,double *a0,double *a1,double *b1,double *b2)
+{
+int i,np,npg,npd,nddl;
+double w,x,x2,A[4][4],B[4];
+double Y2,I,Y,X_g,X2_g,XY_g,X_d,X2_d,X3_d,X4_d,XY_d,X2Y_d;
+
+if( Deg_d<1 || Deg_d>2 ) Deg_d=2;
+nddl = Deg_d + 2;
+*a0=*a1=*b1=*b2=0.;
+Y2=I=Y=X_g=X2_g=XY_g=X_d=X2_d=X3_d=X4_d=XY_d=X2Y_d=0.;
+np=npg=npd=0;
+for(i=0;i<*n;i++) {
+  if(ey[i]<=0.) continue;
+  np++;
+  x = xx[i]-x0;
+  x2 = x*x;
+  w = ey[i]*ey[i];
+  I  += 1./w;
+  Y  += y[i]/w;
+  Y2 += y[i]*y[i]/w;
+  if(x<=0.) {
+    if(x<0.) npg++;
+    X_g  += x/w;
+    X2_g += x2/w;
+    XY_g += x*y[i]/w;;
+  } else {
+    npd++;
+    X_d   += x/w;
+    X2_d  += x2/w;
+    X3_d  += x2*x/w;
+    X4_d  += x2*x2/w;
+    XY_d  += x*y[i]/w;;
+    X2Y_d += x2*y[i]/w;;
+  }
+}
+*n = np;
+A[0][0] = I;
+A[1][1] = X2_g;
+A[3][3] = X4_d;
+A[0][1] = A[1][0] = X_g;
+A[0][2] = A[2][0] = X_d;
+A[3][2] = A[2][3] = X3_d;
+A[0][3] = A[3][0] = A[2][2] = X2_d;
+A[1][2] = A[2][1] = A[1][3] = A[3][1] = 0.;
+B[0] = Y;
+B[1] = XY_g;
+B[2] = XY_d;
+B[3] = X2Y_d;
+if( np<4 || npg < 1 || npd < 2 ) return(-1.);
+w = GausPiv(&A[0][0],4,nddl,B,1,1,0);
+if(w==0.) return(-2.);
+*a0 = B[0];
+*a1 = B[1];
+*b1 = B[2];
+if(nddl==4) *b2 = B[3];
+w = Y2 + *a0**a0*I + *a1**a1*X2_g + *b1**b1*X2_d + *b2**b2*X4_d
+  + 2.*( - *a0*Y - *a1*XY_g + *a0**a1*X_g
+         - *b1*XY_d - *b2*X2Y_d + *a0**b1*X_d + *a0**b2*X2_d + *b1**b2*X3_d
+       );
+return(w);
+}
+
+/*=========================================================================*/
+/*
+++
+double FitPropClean(double *x,double *y,double *ey,int *n,double per_clean,double *a1)
+	Fit de y(i) = a1*x(i) en deux passes:
+--
+*/
+/*
+++
+|   1-/ fit avec tous les points
+|   2-/ fit ou on enleve les per_clean*n points les plus eloignes
+| Input:
+|    x = tableau des abscisses
+|    y = tableau des ordonnees
+|    ey = erreurs sur les y
+|    n = nombre de donnees en entree
+|    per_clean = pourcentage des points a tuer pour la seconde passe
+--
+*/
+/*
+++
+| Output:
+|    n = nombre de points utilises (point non utilise si ey<=0)
+|    a1 = coefficients de proportionalite
+| Return:
+|    valeur du xi2 si fit reussi,
+|    -1. si echec fit passe no 1
+|    -2. si echec fit passe no 2
+|    -3. si probleme malloc
+|    -4. si probleme nombre de points a tuer
+--
+*/
+double FitPropClean(double *x,double *y,double *ey,int *n,double per_clean,double *a1)
+{
+int npt,k,i,nclass;
+double *clas,aa1,c2,cut;
+
+*a1 =0.;
+
+/* 1ere passe */
+npt = *n;
+c2 = FitProp(x,y,ey,&npt,&aa1);
+if(c2<0.) {*n = npt; return(-1.);}
+*a1 = aa1;
+/* printf("pass 1: %g*x c2=%g/%d\n",*a1,c2,npt); */
+
+clas = (double*) malloc( *n * sizeof(double) );
+if( clas == NULL ) {*n=npt; return(-3.);}
+
+/* elimination des mauvais points */
+nclass = 0;
+for(i=0;i<*n;i++) {
+  if(ey[i]<=0.) continue;
+  c2 = (y[i]-aa1*x[i])/ey[i];
+  clas[nclass] = c2*c2;
+  nclass++;
+}
+qsort(clas,(size_t) nclass,(size_t) sizeof(double),qSort_Dble);
+k = (int) ( (1. - per_clean ) * (double) nclass );
+if(k<0) k=0;
+if(k>=nclass) k = nclass-1;
+cut = clas[k];
+k = 0;
+for(i=0;i<*n;i++) {
+  clas[i] = ey[i];
+  c2 = (y[i]-aa1*x[i])/ey[i];
+  c2 *= c2;
+  if(ey[i]>0. && c2>cut) {clas[i] = -1.; k++;}
+}
+/* printf("nombre pt tues %d cut=%g\n",k,cut); */
+
+/* 2sd passe */
+npt = *n;
+c2 = FitProp(x,y,clas,&npt,&aa1);
+if(c2<0.) {*n = npt; free(clas); return(-2.);}
+*a1 = aa1;
+*n = npt;
+/* printf("pass 2: %g*x c2=%g/%d\n",*a1,c2,npt); */
+
+free(clas);
+return(c2);
+}
+
+/*=========================================================================*/
+/*
+++
+double FitLinClean -
+  (double *x,double *y,double *ey,int *n -
+  ,double per_clean,double *a0,double *a1)
+
+	Fit de y(i) = a0 + a1*x(i) en deux passes:
+--
+*/
+/*
+++
+|   1-/ fit avec tous les points
+|   2-/ fit ou on enleve les per_clean*n points les plus eloignes
+| Input:
+|    x = tableau des abscisses
+|    y = tableau des ordonnees
+|    ey = erreurs sur les y
+|    n = nombre de donnees en entree
+|    per_clean = pourcentage des points a tuer pour la seconde passe
+| Output:
+|    n = nombre de points utilises (point non utilise si ey<=0)
+|    a0,a1 = coefficients de la droite
+--
+*/
+/*
+++
+| Return:
+|    valeur du xi2 si fit reussi,
+|    -1. si echec fit passe no 1
+|    -2. si echec fit passe no 2
+|    -3. si probleme malloc
+|    -4. si probleme nombre de points a tuer
+--
+*/
+double FitLinClean(double *x,double *y,double *ey,int *n
+                  ,double per_clean,double *a0,double *a1)
+{
+int npt,k,i,nclass;
+double *clas,aa0,aa1,c2,cut;
+
+*a0 = *a1 =0.;
+
+/* 1ere passe */
+npt = *n;
+c2 = FitLin(x,y,ey,&npt,&aa0,&aa1);
+if(c2<0.) {*n = npt; return(-1.);}
+*a0 = aa0;
+*a1 = aa1;
+/* printf("pass 1: %g + %g*x c2=%g/%d\n",*a0,*a1,c2,npt); */
+
+clas = (double*) malloc( *n * sizeof(double) );
+if( clas == NULL ) {*n=npt; return(-3.);}
+
+/* elimination des mauvais points */
+nclass = 0;
+for(i=0;i<*n;i++) {
+  if(ey[i]<=0.) continue;
+  c2 = (y[i]-(aa0+aa1*x[i]))/ey[i];
+  clas[nclass] = c2*c2;
+  nclass++;
+}
+qsort(clas,(size_t) nclass,(size_t) sizeof(double),qSort_Dble);
+k = (int) ( (1. - per_clean ) * (double) nclass );
+if(k<0) k=0;
+if(k>=nclass) k = nclass-1;
+cut = clas[k];
+k = 0;
+for(i=0;i<*n;i++) {
+  clas[i] = ey[i];
+  c2 = (y[i]-(aa0+aa1*x[i]))/ey[i];
+  c2 *= c2;
+  if(ey[i]>0. && c2>cut) {clas[i] = -1.; k++;}
+}
+/* printf("nombre pt tues %d cut=%g\n",k,cut); */
+
+/* 2sd passe */
+npt = *n;
+c2 = FitLin(x,y,clas,&npt,&aa0,&aa1);
+if(c2<0.) {*n = npt; free(clas); return(-2.);}
+*a0 = aa0;
+*a1 = aa1;
+*n = npt;
+/* printf("pass 2: %g + %g*x c2=%g/%d\n",*a0,*a1,c2,npt); */
+
+free(clas);
+return(c2);
+}
+
+/*===================================================================*/
+/*
+++
+double FitParClean -
+  (double *x,double *y,double *ey,int *n -
+  ,double per_clean,double *a0,double *a1,double *a2)
+
+	Fit de y(i) = a0 + a1*x(i) + a2*x(i)^2 en deux passes:
+--
+*/
+/*
+++
+|   1-/ fit avec tous les points
+|   2-/ fit ou on enleve les per_clean*n points les plus eloignes
+| Input:
+|    x = tableau des abscisses
+|    y = tableau des ordonnees
+|    ey = erreurs sur les y
+|    n = nombre de donnees en entree
+|    per_clean = pourcentage des points a tuer pour la seconde passe
+| Output:
+|    n = nombre de points utilises (point non utilise si ey<=0)
+|    a0,a1,a2 = coefficients de la parabole
+| Return:
+|    valeur du xi2 si fit reussi,
+|    -1. si echec fit passe no 1
+|    -2. si echec fit passe no 2
+|    -3. si probleme malloc
+|    -4. si probleme nombre de points a tuer
+--
+*/
+double FitParClean(double *x,double *y,double *ey,int *n
+                  ,double per_clean,double *a0,double *a1,double *a2)
+{
+int npt,k,i,nclass;
+double *clas,aa0,aa1,aa2,c2,cut;
+
+*a0 = *a1 = *a2 =0.;
+
+/* 1ere passe */
+npt = *n;
+c2 = FitPar(x,y,ey,&npt,&aa0,&aa1,&aa2);
+if(c2<0.) {*n = npt; return(-1.);}
+*a0 = aa0;
+*a1 = aa1;
+*a2 = aa2;
+/* printf("pass 1: %g + %g*x + %g*x**2 c2=%g/%d\n",*a0,*a1,*a2,c2,npt); */
+
+clas = (double*) malloc( *n * sizeof(double) );
+if( clas == NULL ) {*n=npt; return(-3.);}
+
+/* elimination des mauvais points */
+nclass = 0;
+for(i=0;i<*n;i++) {
+  if(ey[i]<=0.) continue;
+  c2 = (y[i]-(aa0+aa1*x[i]+aa2*x[i]*x[i]))/ey[i];
+  clas[nclass] = c2*c2;
+  nclass++;
+}
+qsort(clas,(size_t) nclass,(size_t) sizeof(double),qSort_Dble);
+k = (int) ( (1. - per_clean ) * (double) nclass );
+if(k<0) k=0;
+if(k>=nclass) k = nclass-1;
+cut = clas[k];
+k = 0;
+for(i=0;i<*n;i++) {
+  clas[i] = ey[i];
+  c2 = (y[i]-(aa0+aa1*x[i]+aa2*x[i]*x[i]))/ey[i];
+  c2 *= c2;
+  if(ey[i]>0. && c2>cut) {clas[i] = -1.; k++;}
+}
+/* printf("nombre pt tues %d cut=%g\n",k,cut); */
+
+/* 2sd passe */
+npt = *n;
+c2 = FitPar(x,y,clas,&npt,&aa0,&aa1,&aa2);
+if(c2<0.) {*n = npt; free(clas); return(-2.);}
+*a0 = aa0;
+*a1 = aa1;
+*a2 = aa2;
+*n = npt;
+/* printf("pass 2: %g + %g*x + %g*x**2 c2=%g/%d\n",*a0,*a1,*a2,c2,npt); */
+
+free(clas);
+return(c2);
+}
+
+/*===========================================================*/
+/*
+++
+float interpole(float m,int n,float *t1,float *t2)
+	Interpolation lineaire y=f(x):
+--
+*/
+/*
+++
+|   t1[n] = tableau des x
+|   t2[n] = tableau des y
+|   m = valeur ou on interpole
+|   RETURN: f(m)
+--
+*/
+float interpole(float m,int n,float *t1,float *t2)
+{
+int i,n1;
+float r;
+
+if ( n == 1 ) return ( t2[0] );
+
+n1=n-1;
+if ( m < t1[0] )  m=t1[0];
+if ( m > t1[n1] ) m=t1[n1];
+
+for(i=0;i<n;i++) if ( m <= t1[i] ) break;
+i = (i==0) ? 1  : i;
+i = (i==n) ? n1 : i;
+
+r = t2[i-1] + (t2[i]-t2[i-1]) / (t1[i]-t1[i-1]) * (m-t1[i-1]);
+
+/*
+printf("interpole: i=%3d m=%g t1=%g %g t2=%g %g r=%g\n"
+      ,i,m,t1[i-1],t1[i],t2[i-1],t2[i],r);
+for(i=0;i<n;i++) printf(" (%g,%g)",t1[i],t2[i]); printf("\n");
+*/
+
+return(r);
+}
+
+/*=========================================================*/
+/*                         Christophe 10/11/93 La Silla    */
+/*
+++
+int_4 MeanSig(float *mag,float *err,int_4 *ndata,float nsigma,float *mean,float *sigma)
+	Fonction de calcul de la moyenne tronquee et du sigma d'un tableau
+--
+*/
+/*
+++
+| Methode: 1-/ moyenne-sigma, 2-/ moyenne tronquee et sigma,
+| ENTREE:
+|  mag: magnitude
+|  err: erreur sur la magnitude
+|  ndata: nombre de donnees
+|  nsigma: nombre de sigma dans lequel on calcule le maximum
+|          si <=0, une seule passe pour la moyenne
+| SORTIE:
+|  ndata: nombre de data utilises pour calculer mean et sigma
+|  mean: moyenne des donnees
+|  sigma: sigma des donnees
+|  MeanSig: 0 si calcul ok, <0 sinon
+--
+*/
+int_4 MeanSig(float *mag,float *err,int_4 *ndata,float nsigma,float *mean,float *sigma)
+{
+int_4 deb=DEB_MeanSig;
+int_4 pass,passmx,i,n=0;
+double m,s2,v,scut;
+
+*mean = *sigma = 0.;
+passmx = ( nsigma <= 0. ) ? 1 : 2 ;
+for (pass=1;pass<=passmx;pass++) {
+  m = s2 = 0.;
+  n=0;
+  scut = GRAND;
+  if( pass == 2 ) scut=nsigma* *sigma;
+  for (i=0;i<*ndata;i++) {
+    v = *(mag+i);
+    if( *(err+i) > 0. && fabs(v-*mean) < scut ) {
+      n++;
+      m += v;
+      s2 += v * v;
+  } }
+  if ( n >= 2 ) {
+    *mean = m / n;
+    *sigma = sqrt( s2 / n - m/n * m/n );
+  } else {
+    *mean = *sigma = 0.;
+    *ndata=n;
+    return(-1);
+  }
+  if ( deb>0 ) printf("MeanSig: pass=%d mean=%f sigma=%f n=%d\n"
+                   ,pass,*mean,*sigma,n);
+}
+*ndata=n;
+return(0);
+}
+
+/*=========================================================================*/
+/*
+++
+int Most_Probable -
+  ( float *val, int nval, float binin, int nmoy -
+  , float low, float high, float *most, int deb)
+
+	Pour calculer la valeur la plus probable par maximum d'histogramme.
+--
+*/
+/*
+++
+| INPUT:
+|  - val= pointeur sur un tableau de valeurs (float).
+|  - nval= nombre de valeurs a traiter.
+|  - binin= taille du bin.
+|  - nmoy= la valeur retournee est la moyenne de +/- nmoy bins
+|          autour du max de l'histo.
+|  - low, high= les valeurs permises mini et maxi des valeurs
+|                (si low>high calcul automatique).
+|  - deb= niveau de debug.
+| OUTPUT:
+|  - most = valeur la plus probable.
+| RETURN CODE:
+|  -1 : nval <=0
+|  -2 : bin <=0
+|  -3 : low>=high apres cadrage automatique
+|  -4 : nombre de valeurs remplies nul au niveau de la 1ere passe
+|  -51 : pas trouve de maximum 1ere passe
+|  -52 : pas trouve de maximum 2sd passe
+--
+*/
+int Most_Probable( float *val, int nval, float binin, int nmoy
+                 , float low, float high, float *most, int deb)
+{
+int histo[503],i,nbin,n,ib,ibmax,vmax,pass;
+float bin,xmax=0.;
+double moy,sum;
+
+if(deb>1) printf("Most_Probable: nval=%d binin=%f nmoy=%d low,high=%f %f\n"
+                ,nval,binin,nmoy,low,high);
+if (nval<=0) return(-1);
+if (binin<=0.) return(-2);
+nmoy = (nmoy<0) ? 0 : nmoy;
+if(low>= high) {
+  low = GRAND;
+  high = -low;
+  for(i=0;i<nval;i++) {if(val[i]>high) high=val[i]; if(val[i]<low) low=val[i];}
+}
+if(deb>1) printf("nmoy=%d low,high=%f %f\n",nmoy,low,high);
+if(low>= high) return(-3);
+
+/* premiere passe "nbin" bins entre low et high, nbin=min(high-low)/bin+1,501) */
+/* seconde  passe "nbin" autour du maxi 1ere passe, nbin=min(high-low)/bin,501) */
+
+for ( pass=1;pass<=2;pass++) {
+
+  bin=binin;
+  nbin = (int) ( (high-low)/bin ) + 1;
+  if(nbin>501) {
+    nbin = 501;
+    if(pass!=1){
+      low  = xmax - 250*binin - binin/2.;
+      high = xmax + 250*binin + binin/2.;
+  } }
+  /* re-scaling du bin pour etre sur */ 
+  bin=(high-low)/nbin;
+  if(deb>1) printf("pass=%2d low,high=%f %f bin=%f nbin=%d\n"
+                  ,pass,low,high,bin,nbin);
+  for(i=0;i<nbin;i++) histo[i]=0;
+  n=0;
+  for(i=0;i<nval;i++) {
+    if( val[i]>=high || val[i]<low ) continue;
+    ib = (int) ((val[i]-low)/bin);
+    if( ib<0 && ib >= nbin ) continue;
+    histo[ib]++;
+    n++;
+  }
+  if(n<=0) return (-4);
+  vmax = -1; ibmax= -1;
+  if(n<=0) return (-4);
+  for(i=0;i<nbin;i++) {
+    if(histo[i]<vmax) continue;
+    vmax = histo[i];
+    ibmax = i;
+  }
+  if(ibmax<0) return (-50-pass);
+  xmax = low + ibmax*bin + bin/2.;
+  if(deb>1) printf("bin du maximum %5d (%d) abscisse=%f\n",ibmax,vmax,xmax);
+  if(deb>3) {
+    printf("histogramme:\n");
+    for (i= ibmax-25;i<=ibmax+25;i++) {
+      if (i<0) continue;
+      if (i>=nbin) break;
+      printf(" %5d",histo[i]);
+      if(i%10==9) printf("\n");
+    }
+    printf("\n");
+  }
+}
+
+sum = moy =0.; n=0;
+for (i= -nmoy;i<=nmoy;i++) {
+  if (ibmax-i>=0 && ibmax+i<nbin) {
+    moy += ( xmax + i * bin ) * histo[ibmax+i];
+    sum += (double) histo[ibmax+i];
+    n++;
+} }
+
+*most = moy / sum;
+if(deb>0) printf("Most_probable: most=%f (avec %d points)\n",*most,n);
+
+return(0);
+
+}
+
+/*============================================================*/
+/*                                      Christophe 27/01/95   */
+/*
+++
+float Ajust_GaFn
+|    (int Ns,float *fcfr
+|    ,float *haut,float *ehaut,float *mean,float *emean
+|    ,float *sigma,float *esigma,float *fond,float *efond
+|    ,int fixfond,int NBIN_RESOL
+|    ,float perc_net,float frac_sgb,float dyn_sgb,int deb)
+
+	Fonction de fit gaussienne + fond (1D) du tableau fcfr
+	avec reglage des parametres d'entree.
+--
+*/
+/*
+++
+| ATTENTION: le tableau fcfr est modifie !!!              
+| ---------                                               
+| ENTREES:                                                
+|   Ns = nombre d'entrees dans fcfr
+|   fcfr = tableau des valeurs a fitter
+|   fond = valeur a donner au fond si fixfond = 1
+|   fixfond =  1 fond fixe dans le fit a la valeur fond
+|           =  2 fond fixe dans le fit a une valeur
+|                     calculee automatiquement sur
+|                     les bords de l'histogramme 
+|           >  2 fond fixe a zero (<=> 1 + fond=0)
+|           <= 0 fond libre dans le fit
+|   NBIN_RESOL = nombre maxi de bins pour l'histo de fit
+|                de la resolution
+|   perc_net = pourcentage de donnees a nettoyer pour
+|              calculer mean,sigma de la 1ere passe
+|   frac_sgb = le bin de fit sera sigma*fracsgb
+|              ou sigma est calcule en premiere passe
+|   dyn_sgb = limites de l'histo de fit
+|        xmin=mean-dyn_sgb*sigma , xmax=mean+dyn_sgb*sigma
+|   deb = niveau de debug
+--
+*/
+/*
+++
+| SORTIES:                                                
+|   haut = valeur de la hauteur
+|   ehaut = erreur sur la valeur de la hauteur
+|   mean = valeur moyenne du decalage
+|   emean = erreur sur la valeur moyenne du decalage
+|   sigma = valeur de la resolution
+|   esigma = erreur sur la valeur de la resolution
+|   fond = valeur du fond
+|   efond = erreur sur la valeur du fond 
+|   return code = chi2 du fit  (<0 si Pb)
+--
+*/
+float Ajust_GaFn(int Ns,float *fcfr
+           ,float *haut,float *ehaut,float *mean,float *emean
+           ,float *sigma,float *esigma,float *fond,float *efond
+           ,int fixfond,int NBIN_RESOL
+           ,float perc_net,float frac_sgb,float dyn_sgb,int deb)
+{
+int_4 i,j,i1,i2,nbin,ibin,entries;
+float c2,xmin,xmax,binw,ymax;
+float *y,*ey,*x;
+double m,s;
+FLOATDOUBLE X,Y,EY;
+double (*Fun) (double ,double *,double *);
+int_4 npar,n;
+double par[4], epar[4],minpar[4],maxpar[4],stepar[4],stochi2;
+
+fixfond = ( fixfond <= 0 ) ? 0 : fixfond;
+perc_net = ( perc_net >= 1. || perc_net < 0. ) ? 0.1 : perc_net;
+NBIN_RESOL = ( NBIN_RESOL <= 0 ) ? 50 : NBIN_RESOL;
+frac_sgb = ( frac_sgb <= 0. ) ? 0.5 : frac_sgb;
+dyn_sgb  = ( dyn_sgb  <= 0. ) ? 5.0 : dyn_sgb;
+x = y = ey = NULL;
+x  = (float *) calloc(NBIN_RESOL+2,sizeof(float));
+y  = (float *) calloc(NBIN_RESOL+2,sizeof(float));
+ey = (float *) calloc(NBIN_RESOL+2,sizeof(float));
+if ( x==NULL || y==NULL || ey==NULL ) {c2 = -100.; goto END;}
+
+if(deb>0) printf("Ajust_GaFn[%d] perc_net=%f nbin=%d frac_sgb=%f dyn_sgb=%f\n"
+              ,Ns,perc_net,NBIN_RESOL,frac_sgb,dyn_sgb);
+
+/* on vire perc_net % des points a gauche et a droite de la distribution */
+qsort(fcfr,(size_t) Ns,(size_t) sizeof(float),qSort_Float);
+i = perc_net * Ns;
+if(perc_net>0. && i==0) i=1;
+i1 = i; i2 = Ns-1-i;
+if(deb>1) {
+  printf("  df/f=");
+  for(j=0;j<10;j++) printf("%8.2f ",fcfr[j]);
+  printf("\n");
+  printf("selection de %d (%f) a %d (%f)\n",i1,fcfr[i1],i2,fcfr[i2]);
+}
+if(i2<=i1) { c2= -101.; goto END;}
+
+/* calcul mean et sigma 1ere passe */
+m = s = 0.; j = 0;
+for(i=i1;i<=i2;i++) {m += fcfr[i]; s += fcfr[i]*fcfr[i]; j++;}
+m /= j;
+s = sqrt(s/j - m*m);
+*mean = m; *sigma = s;
+if(deb>1) printf("premiere passe: mean=%f sigma=%f\n",*mean,*sigma);
+
+/* remplissage histo a +/- dyn_sgb * sigma */
+xmin = *mean - dyn_sgb* *sigma;
+xmax = *mean + dyn_sgb* *sigma;
+if(xmin>=xmax) {c2 = -102.; goto END;}
+binw = *sigma * frac_sgb;
+nbin = (xmax-xmin)/binw;
+if(nbin<6) nbin=6; if(nbin>NBIN_RESOL) nbin=NBIN_RESOL;
+binw = (xmax-xmin)/nbin;
+for(i=0;i<nbin;i++)
+    {x[i] = xmin + ((float) i + 0.5)*binw; y[i] = 0.;}
+if(deb>1) {
+  printf("histo[%d] lim=[%f,%f] bw=%f x=\n"
+        ,nbin,xmin,xmax,binw);
+  for(j=0;j<nbin;j++)
+    {printf("%8.2f ",x[j]); if(j%10==9) printf("\n");}
+  if(j%10!=0) printf("\n");
+}
+entries = 0;
+for(i=0;i<Ns;i++) { ibin = (fcfr[i]-xmin)/binw;
+         if(ibin>=0 && ibin<nbin) {y[ibin]+=1.; entries++;} }
+ymax = 0.;
+for(i=0;i<nbin;i++) {ey[i] = (y[i]>1.)? sqrt((double) y[i]) : 1.;
+                    if(y[i]>ymax) ymax=y[i];}
+if(deb>1) {
+  printf("histo (entries=%d) ymax=%f y=\n",entries,ymax);
+  for(j=0;j<nbin;j++)
+    {printf("%8.0f ",y[j]); if(j%10==9) printf("\n");}
+  if(j%10!=0) printf("\n");
+  if(deb>2) {
+    printf("histo ey=\n");
+    for(j=0;j<nbin;j++)
+      {printf("%8.0f ",ey[j]); if(j%10==9) printf("\n");}
+    if(j%10!=0) printf("\n"); }
+}
+if(ymax<2.) {c2 = -103.; goto END;}
+
+if(fixfond!=1) {
+  *fond = (y[0]+y[1]+y[nbin-1]+y[nbin-2])/4.;
+  if(fixfond>2) *fond = 0.;
+}
+*haut = ymax - *fond;
+
+/* fit gaussienne + fond constant */
+Fun = Gauss1DPolF ; Set_FitFunDPol(0);
+X.fx  = x;
+Y.fx  = y;
+EY.fx = ey;
+par[0] = *haut;
+par[1] = *mean;
+par[2] = *sigma;
+par[3] = *fond;
+stepar[0] = par[0]/10.; stepar[1] = par[2]/5.;
+stepar[2] = par[2]/10.; stepar[3] = 0.5;
+if(fixfond) { stepar[3] = 0.; epar[3]=0.;}
+for(i=0;i<4;i++) {minpar[i] = 1.; maxpar[i] = -1.;}
+minpar[2] = 0.00001; maxpar[2] = 9999.;
+npar = 4;
+stochi2 = 0.0001;
+n = nbin;
+j = (deb>2)? 1:0;
+c2 = FitFun(Fun,FITFUN_FLOAT,X,Y,EY,&n,0,0,par
+           ,epar,stepar,minpar,maxpar,npar,stochi2,60,j);
+
+END:
+
+if( c2 > 0. ) {
+  *haut  =  par[0]; *mean  =  par[1]; *sigma  =  par[2]; *fond  =  par[3];
+  *ehaut = epar[0]; *emean = epar[1]; *esigma = epar[2]; *efond = epar[3];
+} else {
+  *ehaut = *emean = *esigma = *efond = 0.;
+}
+if(x !=NULL) free(x);
+if(y !=NULL) free(y);
+if(ey!=NULL) free(ey);
+
+return(c2);
+}
+
+/*==========================================================*/
+/*                                    Christophe 27/03/95   */
+/*
+++
+float HFit_GaFn -
+  (int Ns,float *fcfr -
+  ,float *haut,float *ehaut,float *mean,float *emean -
+  ,float *sigma,float *esigma,float *fond,float *efond -
+  ,int fixfond,int nbin,float xmin,float xmax,int deb)
+
+	Fonction de fit gaussienne + fond (1D) du tableau fcfr
+	dans un histo de "nbin" bins de "xmin a xmax"
+--
+*/
+/*
+++
+| ENTREES:
+|   Ns = nombre d'entrees dans fcfr
+|   fcfr = tableau des valeurs a fitter
+|   mean = valeur de depart pour la moyenne
+|   sigma = valeur de depart pour le sigma
+|   fond = valeur de depart pour le fond
+|   fixfond > 0  fond fixe dans le fit a la valeur fond
+|           <= 0 fond libre dans le fit
+|   nbin = nombre de bins pour l'histo de fit
+|   xmin = valeur inferieure de l'histo
+|   xmax = valeur superieure de l'histo
+|   deb = niveau de debug
+--
+*/
+/*
+++
+| SORTIES:
+|   haut = valeur de la hauteur
+|   ehaut = erreur sur la valeur de la hauteur
+|   mean = valeur moyenne du decalage
+|   emean = erreur sur la valeur moyenne du decalage
+|   sigma = valeur de la resolution
+|   esigma = erreur sur la valeur de la resolution
+|   fond = valeur du fond
+|   efond = erreur sur la valeur du fond
+|   return code = chi2 du fit  (<0 si Pb)
+--
+*/
+float HFit_GaFn(int Ns,float *fcfr
+           ,float *haut,float *ehaut,float *mean,float *emean
+           ,float *sigma,float *esigma,float *fond,float *efond
+           ,int fixfond,int nbin,float xmin,float xmax,int deb)
+{
+int_4 i,j,ibin,entries;
+float c2,binw,ymax;
+float *y,*ey,*x;
+FLOATDOUBLE X,Y,EY;
+double (*Fun) (double ,double *,double *);
+int_4 npar,n;
+double par[4], epar[4],minpar[4],maxpar[4],stepar[4],stochi2;
+
+if(xmax<=xmin) return(-102);
+fixfond = ( fixfond <= 0 ) ? 0 : fixfond;
+nbin = ( nbin <= 0 ) ? 50 : nbin;
+x = y = ey = NULL;
+x  = (float *) calloc(nbin+2,sizeof(float));
+y  = (float *) calloc(nbin+2,sizeof(float));
+ey = (float *) calloc(nbin+2,sizeof(float));
+if ( x==NULL || y==NULL || ey==NULL ) {c2 = -100.; goto END;}
+
+if(deb>0) printf("HFit_GaFn[%d pts] nbin=%d de %g a %g\n"
+              ,Ns,nbin,xmin,xmax);
+
+/* remplissage histo */
+binw = (xmax-xmin)/nbin;
+for(i=0;i<nbin;i++) {x[i]=xmin+((float) i +0.5)*binw; y[i]=0.;}
+if(deb>1) {
+  printf("histo[%d] lim=[%f,%f] bw=%f x=\n",nbin,xmin,xmax,binw);
+  for(j=0;j<nbin;j++){printf("%8.2f ",x[j]); if(j%10==9) printf("\n");}
+  if(j%10!=0) printf("\n");
+}
+entries = 0;
+for(i=0;i<Ns;i++) {
+  ibin = (fcfr[i]-xmin)/binw;
+  if(ibin>=0 && ibin<nbin) {y[ibin]+=1.; entries++;}
+}
+
+ymax = 0.;
+for(i=0;i<nbin;i++) {ey[i] = (y[i]>1.)? sqrt((double) y[i]) : 1.;
+                    if(y[i]>ymax) ymax=y[i];}
+if(deb>1) {
+  printf("histo (entries=%d) ymax=%f y=\n",entries,ymax);
+  for(j=0;j<nbin;j++){printf("%8.0f ",y[j]); if(j%10==9)printf("\n");}
+  if(j%10!=0) printf("\n");
+  if(deb>2) {
+    printf("histo ey=\n");
+    for(j=0;j<nbin;j++){printf("%8.0f ",ey[j]); if(j%10==9)printf("\n");}
+    if(j%10!=0) printf("\n");
+} }
+if(ymax<2.) {c2 = -103.; goto END;}
+
+*haut = ymax - *fond;
+
+/* fit gaussienne + fond constant */
+Fun = Gauss1DPolF ; Set_FitFunDPol(0);
+X.fx  = x;
+Y.fx  = y;
+EY.fx = ey;
+par[0] = *haut;
+par[1] = *mean;
+par[2] = *sigma;
+par[3] = *fond;
+stepar[0] = par[0]/10.; stepar[1] = par[2]/5.;
+stepar[2] = par[2]/10.; stepar[3] = 0.5;
+if(fixfond) { stepar[3] = 0.; epar[3]=0.;}
+for(i=0;i<4;i++) {minpar[i] = 1.; maxpar[i] = -1.;}
+minpar[2] = 0.00001; maxpar[2] = 9999.;
+npar = 4;
+stochi2 = 0.0001;
+n = nbin;
+j = (deb>2)? 1:0;
+c2 = FitFun(Fun,FITFUN_FLOAT,X,Y,EY,&n,0,0,par
+           ,epar,stepar,minpar,maxpar,npar,stochi2,60,j);
+
+END:
+
+if( c2 > 0. ) {
+  *haut  =  par[0]; *mean  =  par[1]; *sigma  =  par[2]; *fond  =  par[3];
+  *ehaut = epar[0]; *emean = epar[1]; *esigma = epar[2]; *efond = epar[3];
+} else {
+  *ehaut = *emean = *esigma = *efond = 0.;
+}
+if(x !=NULL) free(x);
+if(y !=NULL) free(y);
+if(ey!=NULL) free(ey);
+
+return(c2);
+}
+
+/*==============================================================*/
+/*                                    Christophe 15/02/95       */
+/*
+++
+int Ajust_MnSg -
+  (int Ns,float *fcfr -
+  ,float *mean,float *emean,float *sigma,float *esigma -
+  ,float perc_net,float n_sigma,int deb)
+
+	Calcul mean sigma tronques du tableau fcfr.
+--
+*/
+/*
+++
+| ATTENTION: le tableau fcfr est modifie
+| ---------
+| Methode:
+|  1- calcul de la moyenne Mcent en enlevant perc_net% des pts
+|     les + faibles et perc_net% des pts les + forts
+|  2- calcul de la valeur cutup correspondant a 2*perc_net%
+|     des pts les + hauts en valeur absolue (fcfr-Mcent)
+|  3- calcul moyenne et sigma en enlevant les points ayant
+|        abs(fcfr-Mcent) > cutup    (1ere passe)
+|  4- calcul moyenne et sigma en enlevant les points ayant
+|        abs(fcfr-Mcent) > cutup   et
+|        abs(fcfr-M(1ere passe)) > n_sigma*sigma(1ere passe)
+--
+*/
+/*
+++
+| ENTREES:
+|   Ns = nombre d'entrees dans fcfr
+|   fcfr = tableau des valeurs a fitter
+|   perc_net = pourcentage de donnees a nettoyer pour
+|              calculer mean,sigma
+|   n_sigma = nombre de sigma en passe 2 pour
+|              calculer mean,sigma
+|   deb = niveau de debug
+| SORTIES:
+|   mean = valeur moyenne du decalage
+|   emean = erreur sur la valeur moyenne du decalage
+|   sigma = valeur de la resolution
+|   esigma = erreur sur la valeur de la resolution
+|   return code = nombre de points utilises (<0 si Pb)
+--
+*/
+int Ajust_MnSg(int Ns,float *fcfr
+           ,float *mean,float *emean,float *sigma,float *esigma
+           ,float perc_net,float n_sigma,int deb)
+{
+int i,i1,i2,n,nvire,pass;
+double m,s,mcent,cutup,cuts;
+float *dum;
+
+/* set up des valeurs par defaut */
+perc_net = ( perc_net >= 1. || perc_net < 0. ) ? 0.1 : perc_net;
+n_sigma = ( n_sigma <= 0. ) ? 3.0 : n_sigma;
+nvire = perc_net * Ns;
+if(perc_net>0. && nvire==0) nvire=1;
+*emean = *esigma = -1.;
+if(deb>0) printf("Ajust_MnSg[%d] perc_net=%f (vire=%d) n_sigma=%f\n"
+                ,Ns,perc_net,nvire,n_sigma);
+
+/* on ordonne par ordre croissant de fcfr */
+qsort(fcfr,(size_t) Ns,(size_t) sizeof(float),qSort_Float);
+i1 = nvire; i2 = Ns-1-nvire;
+if(deb>1) printf("    select de %d (%f) a %d (%f)\n",i1,fcfr[i1],i2,fcfr[i2]);
+if(i2<=i1) return(-101);
+
+/* on vire perc_net % des points a gauche et a droite de la distribution */
+mcent = 0.; n = 0;
+for(i=i1;i<=i2;i++) {mcent += fcfr[i]; n++;}
+if(n<1) return(-102);
+mcent /= (double) n;
+if(deb>1) printf("    mean cent=%f sur %d points\n",mcent,n);
+
+/* allocate space and fill absolute value */
+if( (dum  = (float *) calloc(Ns,sizeof(float))) == NULL ) return(-103);
+for(i=0;i<Ns;i++) dum[i] = fabs( mcent - fcfr[i] );
+
+/* on ordonne par ordre croissant de abs(fcfr-mcent) */
+qsort(dum,(size_t) Ns,(size_t) sizeof(float),qSort_Float);
+i = Ns-1-2*nvire;
+if(i<0) {n= -104; goto END_Ajust_MnSg;}
+
+/* on vire 2.*perc_net % des points les + hauts de la distribution */
+cutup = dum[i];
+if(deb>1) printf("    cutup=%f sur %d points\n",cutup,i);
+
+/* calcul mean et sigma en 2 passes avec coupure n_sigma*sigma(1ere passe)*/
+cuts = GRAND2;
+for(pass=1;pass<=2;pass++) {
+  m = s = 0.; n = 0;
+  for(i=0;i<Ns;i++) {
+    if( fabs(mcent-fcfr[i]) > cutup ) continue;
+    if( fabs((double) (*mean-fcfr[i])) > cuts ) continue;
+    m += fcfr[i];
+    s += fcfr[i]*fcfr[i];
+    n++;
+  }
+  if(n<=2) {n= -105; *mean = *sigma = -1.; goto END_Ajust_MnSg;}
+  m /= n;
+  s = s/n - m*m;
+  if(s<=0.) {n= -106; *mean = *sigma = -1.; goto END_Ajust_MnSg;}
+  s = sqrt(s);
+  *mean = m;
+  *sigma = s;
+  cuts = n_sigma * s;
+  if(deb>1)
+    printf("    pass=%d mean=%g sigma=%g (%d pts) cuts=%f\n"
+          ,pass,*mean,*sigma,n,cuts);
+}
+
+*emean = s/sqrt((double) n);
+*esigma = s/sqrt(2. * (double) n);
+if(deb>0) printf("mean=%g (+/-%g) sigma=%g (+/-%g) sur %d pts\n"
+              ,*mean,*emean,*sigma,*esigma,n);
+
+END_Ajust_MnSg:
+if( dum != NULL ) free(dum);
+return(n);
+}
+
+/*=================================================================*/
+/*                                       Nathalie 16/02/95         */
+/*
+++
+float Int3DCube(float(*fonction)(float,float,float),float step,float precision)
+	Cette fonction calcule l'integrale 3D: f(x,y,z)dx.dy.dz
+	L'integrale est calculee en incrementant des couronnes cubiques
+	centrees sur le point de coordonnees (0,0,0)
+--
+*/
+/*
+++
+| ENTREES:
+|   fonction = f(x,y,z)
+|   step = pas de l'integration
+|   precision = coupure en dV(couronne i)/Vtot(couronnes 0 a i)
+| SORTIES:
+|   return: l'integrale
+| REMARQUES:
+|   la fonction f(x,y,z) doit decroitre tres vite en r**2
+--
+*/
+float Int3DCube(float(*fonction)(float,float,float),float step,float precision)
+{
+
+  float f;
+  double vol,volprec;
+  int ecart,i,j,k,l;
+  int encore,deb=0;
+
+  vol = volprec = 0.;
+
+  /* contribution du cube central */
+  for(l=0;l<nd3d;l++) {
+    f = fonction(dx3d[l]*step,dy3d[l]*step,dz3d[l]*step);
+    vol += f*w3d[l];
+  }
+  ecart = 1;
+
+  /* increment en couronnes cubiques de 2*ecart+1 de cote */  
+  do {
+    volprec = vol;
+    for (i= -ecart;i<=ecart;i++) for(l=0;l<nd3d;l++) {
+      for(j= -ecart;j<=ecart;j++) {
+	f=fonction((i+dx3d[l])*step,(j+dy3d[l])*step,(-ecart+dz3d[l])*step);
+	vol += f*w3d[l];
+	f=fonction((i+dx3d[l])*step,(j+dy3d[l])*step,( ecart+dz3d[l])*step);
+	vol += f*w3d[l];
+      }
+
+      for(k= -ecart+1;k<=ecart-1;k++) {
+	f=fonction((i+dx3d[l])*step,(-ecart+dy3d[l])*step,(k+dz3d[l])*step);
+	vol += f*w3d[l];
+	f=fonction((i+dx3d[l])*step,( ecart+dy3d[l])*step,(k+dz3d[l])*step);
+	vol += f*w3d[l];
+      }
+    }
+    for (j= -ecart+1;j<=ecart-1;j++) for(k= -ecart+1;k<=ecart-1;k++) 
+      for(l=0;l<nd3d;l++) {
+	f=fonction((-ecart+dx3d[l])*step,(j+dy3d[l])*step,(k+dz3d[l])*step);
+	vol += f*w3d[l];
+	f=fonction(( ecart+dx3d[l])*step,(j+dy3d[l])*step,(k+dz3d[l])*step);
+	vol += f*w3d[l];
+    }
+
+    ecart = ecart + 1;
+    encore = ((fabs((vol-volprec)/vol) > precision) || (ecart <= 2) );
+    if(deb>1) printf("ec=%d v=%g deltav/v=%g\n"
+           ,ecart-1,vol*step*step*step,((vol-volprec)/vol));
+  } while(encore);
+
+  vol *= step * step* step;
+  if(deb>0) printf("\nVol = %g\n",vol); 
+  return(vol);
+}
+
+
+/*=================================================================*/
+/*                                             cmv  6/11/97        */
+/*
+++
+int IntFaisDr -
+  (int n,float *cs,float *sn,float *p,float *x0,float *y0 -
+  ,int npass,float perclean,int lp)
+
+	Pour calculer le point d'intersection moyen
+	d'un faisceau de droites.
+--
+*/
+/*
+++
+| L'equation des droites est sous la forme:
+|      cos(alpha)*x + sin(alpha)*y = p
+| [cos(alpha),sin(alpha)] coordonnees du vecteur unitaire joignant
+| l'origine au point de moindre approche de la droite a l'origine.
+| p est la distance de la droite a l'origine.
+--
+*/
+/*
+++
+| -- Input:
+|  n  : nombre de droites
+|  cs : tableau des coefficients cos(alpha)
+|  sn : tableau des coefficients sin(alpha)
+|  p  : tableau des coefficients p
+|  npass    : nombre de passes de nettoyage
+|  perclean : pourcentage d'etoiles a tuer
+|             d'une passe a la suivante
+|      ex: perclean=0.2, si il y a 200 etoiles dans une passe
+|      la passe suivante en utilisera 160 et la suivante 128.
+|  lp : niveau d'impression
+--
+*/
+/*
+++
+| -- Output:
+|  x0 : valeur de l'abscisse du point d'intersection moyen trouve
+|  y0 :             ordonnee
+| -- Return:
+|  nombre de droites utilisees pour le calcul de x0,y0
+--
+*/
+int IntFaisDr(int n,float *cs,float *sn,float *p,float *x0,float *y0
+             ,int npass,float perclean,int lp)
+{
+int i,j,ns, nsuse=-9, ipass;
+double sumC2,sumS2,sumCS,sumCP,sumSP,den;
+float *d2=NULL, d2cut=-1.;
+unsigned short *good=NULL;
+
+*x0 = *y0 = 0.;
+if(n<=1) return(-1);
+if(lp<0) lp=0;\
+if(npass<=0) npass=1;
+if(perclean<=0.) { perclean=0.; npass=1;}
+if(lp)
+  printf("IntFaisDr avec %d points en %d passes avec nettoyage de %g%%\n"
+        ,n,npass,perclean*100);
+
+d2 = (float *) malloc(n * sizeof(float));
+if(d2==NULL) {
+  if(lp)
+    printf("allocation de %d float impossible\n",n);
+  return(-2);
+}
+good = (unsigned short *) malloc(n * sizeof(unsigned short));
+if(good==NULL) {
+  if(lp)
+    printf("allocation de %d unsigned short impossible\n",n);
+  free(d2);
+  return(-3);
+}
+for(i=0;i<n;i++) good[i]=1;
+
+for(ipass=1;ipass<=npass;ipass++) {
+
+  /* Calcul du point d'intersection pour la passe ipass */
+  sumC2=sumS2=sumCS=sumCP=sumSP=0.;
+  ns=0;
+  for(i=0;i<n;i++) {
+    if( !good[i] ) continue;
+    sumC2 += cs[i]*cs[i];
+    sumS2 += sn[i]*sn[i];
+    sumCS += cs[i]*sn[i];
+    sumCP += cs[i]*p[i];
+    sumSP += sn[i]*p[i];
+    ns++;
+  }
+  den = sumCS*sumCS - sumC2*sumS2;
+  if(den==0.) {
+    if(lp)
+      printf("denominateur nul pass=%d, sumCS=%g sumC2=%g sumS2=%g pour %d dr\n"
+            ,ipass,sumCS,sumC2,sumS2,ns);
+    free(d2); free(good);
+    return(-100-ipass);
+  }
+  if(ns<2) {
+    if(lp) printf("Pas ou plus assez de droites %d\n",ns);
+    return(nsuse);
+  }
+  *x0 = (sumSP*sumCS - sumCP*sumS2)/den;
+  *y0 = (sumCP*sumCS - sumSP*sumC2)/den;
+  nsuse = ns;
+  if(lp) printf("Pass=%d, %d dr x0=%g y0=%g\n",ipass,nsuse,*x0,*y0);
+  if(ipass==npass) break;
+
+  /* Calcul de la coupure en distance**2 pour la passe suivante */
+  ns = 0;
+  for(i=0;i<n;i++) {
+    if( !good[i] ) continue;
+    d2[ns] = (*x0*cs[i] * *y0*sn[i]-p[i]);
+    d2[ns] *= d2[ns];
+    ns++;
+  }  
+  qsort(d2,(size_t) ns,sizeof(float),qSort_Float);
+  j = (int) (ns-ns*perclean); if(j<0) j=0;  if(j>=ns) j=ns-1;
+  d2cut = d2[j];
+  ns=0;
+  for(i=0;i<n;i++) {
+    if( !good[i] ) continue;
+    den = (*x0*cs[i] * *y0*sn[i]-p[i]);
+    den *= den;
+    if( den>d2cut ) good[i]=0; else ns++;
+  }
+  if(lp>1)
+    printf("  next pass: i=%d  cut=%g -> restera %d dr\n",j,d2cut,ns);
+}
+
+free(d2); free(good);
+return(nsuse);
+}
Index: /tags/V_Dec2002/SophyaLib/NTools/nbmath.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/nbmath.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/nbmath.h	(revision 2309)
@@ -0,0 +1,96 @@
+/* quelques fonctions mathematiques et constantes utiles */
+/*                                         cmv  23/06/94 */
+#ifndef NBMATH_H_SEEN
+#define NBMATH_H_SEEN
+
+#include "machdefs.h"
+#include "smathconst.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* pour le fit 1-dim */
+#define NPAR_FITFUN 10
+#define FITFUN_FLOAT 1
+#define FITFUN_DOUBLE 2
+union FloatDouble { float  *fx; double *dx; };
+typedef union FloatDouble FLOATDOUBLE;
+
+double FitFun( double (*FunFit) (double ,double *,double *) ,int_4 type
+             ,FLOATDOUBLE temps,FLOATDOUBLE mag,FLOATDOUBLE err
+             ,int_4 *ndata,int_4 I1,int_4 I2
+             ,double *par,double *epar,double *stepar
+             ,double *minpar,double *maxpar,int_4 npar
+             ,double stochi2,int_4 NstepMX,int_4 deb);
+
+double GausPiv(double *A,int_4 nca,int_4 n,double *B,int_4 ncb,int_4 m,int_4 Inv);
+
+int_4 paramga(float sxin, float syin, float rhoin
+             , float *smax, float *axisrat, float *tiltdeg);
+int_4 gaparam(float smax, float axisrat, float tiltdeg
+             , float *sxin, float *syin, float *rhoin);
+
+double nberfc(double x);
+float probnb(float sci2,int_4 inddl,int_4 *ipass);
+double nbgammln(double xx);
+double nbgammq(double a,double x);
+double nbgammp(double a,double x);
+
+void Set_Ihoq(int degre,int *mIhoqN,double *IhoqNX,double *IhoqNW);
+int Get_Ihoq(int degre,double *IhoqNX,double *IhoqNW);
+void nbgauleg(double x1,double x2,double *x,double *w,int n);
+double Integ_Fun(double xmin,double xmax,double (*fonc)(double),int npas);
+double Integ_Fun_2D(double (*fonc)(double x,double y)
+                ,double xmin,double xmax,double ymin,double ymax
+                ,int npasx,int npasy);
+
+void Set_FitFunDPol(int DPol);
+double Gauss1DPolF(double x,double *Par,double *DgDpar);
+double GaussI1DPol(double x,double *Par,double *DgDpar);
+double Polyn1D(double x,double *Par,double *DgDpar); 
+
+double FitProp(double *x,double *y,double *ey,int *n,double *a1);
+double FitLin(double *x,double *y,double *ey,int *n
+             ,double *a0,double *a1);
+double FitPar(double *x,double *y,double *ey,int *n
+             ,double *a0,double *a1,double *a2);
+double FitParLin(double *xx,double *y,double *ey,int *n,double x0,int Deg_d
+                ,double *a0,double *a1,double *b1,double *b2);
+double FitPropClean(double *x,double *y,double *ey,int *n
+                  ,double per_clean,double *a1);
+double FitLinClean(double *x,double *y,double *ey,int *n
+                  ,double per_clean,double *a0,double *a1);
+double FitParClean(double *x,double *y,double *ey,int *n
+                  ,double per_clean,double *a0,double *a1,double *a2);
+
+float interpole(float x,int n,float *t1,float *t2);
+
+int_4 MeanSig(float *mag,float *err,int_4 *ndata,float nsigma,float *mean,float *sigma);
+int Most_Probable( float *val, int nval, float binin, int nmoy
+                 , float low, float high, float *most, int deb);
+float Ajust_GaFn(int Ns,float *fcfr
+           ,float *haut,float *ehaut,float *mean,float *emean
+           ,float *sigma,float *esigma,float *fond,float *efond
+           ,int fixfond,int NBIN_RESOL
+           ,float perc_net,float frac_sgb,float dyn_sgb,int deb);
+float HFit_GaFn(int Ns,float *fcfr
+           ,float *haut,float *ehaut,float *mean,float *emean
+           ,float *sigma,float *esigma,float *fond,float *efond
+           ,int fixfond,int nbin,float xmin,float xmax,int deb);
+int Ajust_MnSg(int Ns,float *fcfr
+           ,float *mean,float *emean,float *sigma,float *esigma
+           ,float perc_net,float n_sigma,int deb);
+
+float Int3DCube(float(*fonction)(float, float, float), float step, 
+	       float precision);
+
+int IntFaisDr(int n,float *cs,float *sn,float *p,float *x0,float *y0
+             ,int npass,float perclean,int lp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/nbrandom.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/nbrandom.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/nbrandom.h	(revision 2309)
@@ -0,0 +1,13 @@
+/* fonctions pour generateurs aleatoires */
+/*                         cmv  23/06/94 */
+
+#ifndef NBRANDOM_H_SEEN
+#define NBRANDOM_H_SEEN
+
+/*   Pour compatibilite anterieure R. Ansari 04/2000  */
+/*                remplace par srandgen.h             */
+
+#include "srandgen.h"
+
+#endif
+
Index: /tags/V_Dec2002/SophyaLib/NTools/nbtri.c
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/nbtri.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/nbtri.c	(revision 2309)
@@ -0,0 +1,520 @@
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include "nbtri.h"
+
+/* 
+++ 
+  Module	Tri de tableaux (C)
+  Lib	LibsUtil
+  include	nbtri.h
+
+	Tri de tableaux et indexation.
+--
+*/
+
+/*=========================================================================*/
+/*
+++
+  void HeapSort(int n,double *ra_int)
+	On reordonne par ordre numerique croissant
+	le tableau ra_int[n]: Numerical Recipes mode C.
+--
+*/
+void HeapSort(int n,double *ra_int)
+{
+   int l,j,ir,i;
+   double rra,*ra;
+
+   /* attention, Numerical recipes prend des tableaux de 1 a n on remet
+      de 0 a n-1 en decramentant le pointeur du tableau d'entree*/
+   ra = ra_int-1;
+
+   l=(n >> 1)+1;
+   ir=n;
+   for (;;) {
+      if (l > 1)
+         rra=ra[--l];
+      else {
+         rra=ra[ir];
+         ra[ir]=ra[1];
+         if (--ir == 1) {
+            ra[1]=rra;
+            return;
+         }
+      }
+      i=l;
+      j=l << 1;
+      while (j <= ir) {
+         if (j < ir && ra[j] < ra[j+1]) ++j;
+         if (rra < ra[j]) {
+            ra[i]=ra[j];
+            j += (i=j);
+         }
+         else j=ir+1;
+      }
+      ra[i]=rra;
+   }
+}
+
+/*=========================================================================*/
+/*
+++
+  void HeapSortF(int n,float *ra_int)
+	On reordonne par ordre numerique croissant
+	le tableau ra_int[n]: Numerical Recipes mode C.
+--
+*/
+void HeapSortF(int n,float *ra_int)
+{
+   int l,j,ir,i;
+   float rra,*ra;
+
+   /* attention, Numerical reciepes prend des tableaux de 1 a n on remet
+      de 0 a n-1 en decramentant le pointeur du tableau d'entree*/
+   ra = ra_int-1;
+
+   l=(n >> 1)+1;
+   ir=n;
+   for (;;) {
+      if (l > 1)
+         rra=ra[--l];
+      else {
+         rra=ra[ir];
+         ra[ir]=ra[1];
+         if (--ir == 1) {
+            ra[1]=rra;
+            return;
+         }
+      }
+      i=l;
+      j=l << 1;
+      while (j <= ir) {
+         if (j < ir && ra[j] < ra[j+1]) ++j;
+         if (rra < ra[j]) {
+            ra[i]=ra[j];
+            j += (i=j);
+         }
+         else j=ir+1;
+      }
+      ra[i]=rra;
+   }
+}
+
+/*=========================================================================*/
+/*
+++
+  void HeapSortF2(int n,float *ra_int,float *ra2_int)
+	On reordonne par ordre numerique croissant
+	le tableau ra_int[n] et ra2_int en parralelle.
+	Numerical Recipes mode C.
+--
+*/
+void HeapSortF2(int n,float *ra_int,float *ra2_int)
+{
+   int l,j,ir,i;
+   float rra,rra2,*ra,*ra2;
+
+   /* attention, Numerical reciepes prend des tableaux de 1 a n on remet
+      de 0 a n-1 en decramentant le pointeur du tableau d'entree*/
+   ra = ra_int-1;
+   ra2 = ra2_int-1;
+
+   l=(n >> 1)+1;
+   ir=n;
+   for (;;) {
+      if (l > 1)
+        {rra=ra[--l];   rra2=ra2[l];}
+      else {
+         rra=ra[ir];    rra2=ra2[ir];
+         ra[ir]=ra[1];   ra2[ir]=ra2[1];
+         if (--ir == 1) {
+            ra[1]=rra;  ra2[1]=rra2;
+            return;
+         }
+      }
+      i=l;
+      j=l << 1;
+      while (j <= ir) {
+         if (j < ir && ra[j] < ra[j+1]) ++j;
+         if (rra < ra[j]) {
+            ra[i]=ra[j];  ra2[i]=ra2[j];
+            j += (i=j);
+         }
+         else j=ir+1;
+      }
+      ra[i]=rra;   ra2[i]=rra2;
+   }
+}
+
+/*=========================================================================*/
+/*
+++
+  int_4 tri_double ( double *tab, int_4 *indx,int_4 N)
+	Methode de tri sans finesse (double boucles).
+| entree : tab -> tableau de double de longueur N (0 a N-1 )
+| sortie : indx -> tableau d'entiers de longueur N : la case i   
+|          contient le classement du ieme element dans tab  
+| Retourne:  0 si tri impossible
+|            1 si tri reussi
+--
+*/
+int_4 tri_double ( double *tab, int_4 *indx,int_4 N)
+{
+int_4 i,j,k;
+
+if (N<=0) return (-1);
+
+for (i=0; i<N ; i++) indx[i]=i;
+if (N==1) return (N);
+
+/* classement dans l'ordre croissant */
+for (i=1; i< N ; i++)
+  { 
+
+  if ( *(tab+indx[i]) < *(tab+indx[i-1]) )
+    { 
+     k = indx[i-1];
+     indx[i-1] = indx[i];
+     indx[i] = k;
+
+     if ( i > 1 )
+        for (j=i ; j>=1 ; j--)
+          { if ( *(tab+indx[j]) < *(tab+indx[j-1]) )
+            { 
+            k = indx[j-1];
+            indx[j-1] = indx[j];
+            indx[j] = k;
+    } } } }
+
+return (N) ;
+}
+
+/*=========================================================================*/
+/*
+++
+  int_4 tri_float ( float *tab, int_4 *indx,int_4 N)
+	Methode de tri sans finesse (double boucles).
+| entree : tab -> tableau de flottant de longueur N (0 a N-1 )
+| sortie : indx -> tableau d'entiers de longueur N : la case i   
+|          contient le classement du ieme element dans tab  
+| Retourne:  0 si tri impossible
+|            1 si tri reussi
+--
+*/
+int_4 tri_float ( float *tab, int_4 *indx,int_4 N)
+{
+int_4 i,j,k;
+
+if (N<=0) return (-1);
+
+for (i=0; i<N ; i++) indx[i]=i;
+if (N==1) return (N);
+
+/* classement dans l'ordre croissant */
+for (i=1; i< N ; i++)
+  { 
+
+  if ( *(tab+indx[i]) < *(tab+indx[i-1]) )
+    { 
+     k = indx[i-1];
+     indx[i-1] = indx[i];
+     indx[i] = k;
+
+     if ( i > 1 )
+        for (j=i ; j>=1 ; j--)
+          { if ( *(tab+indx[j]) < *(tab+indx[j-1]) )
+            { 
+            k = indx[j-1];
+            indx[j-1] = indx[j];
+            indx[j] = k;
+    } } } }
+
+return (N) ;
+}
+
+/*=========================================================================*/
+/*
+++
+  int_4 tri_entier ( int_4 *tab,int_4 *indx,int_4 N)
+	Methode de tri sans finesse (double boucles).
+| entree : tab -> tableau d'entiers de longueur N (0 a N-1 )
+| sortie : indx -> tableau d'entiers de longueur N : la case i   
+|          contient le classement du ieme element dans tab  
+| Retourne:  0 si tri impossible
+|            1 si tri reussi
+--
+*/
+int_4 tri_entier ( int_4 *tab,int_4 *indx,int_4 N)
+{
+int_4 i,j,k;
+
+if (N<=0) return (-1);
+
+for (i=0; i<N ; i++) indx[i]=i;
+if (N==1) return (N);
+
+/* classement dans l'ordre croissant */
+for (i=1; i< N ; i++)
+  { 
+
+  if ( *(tab+indx[i]) < *(tab+indx[i-1]) )
+    { 
+     k = indx[i-1];
+     indx[i-1] = indx[i];
+     indx[i] = k;
+
+     if ( i > 1 )
+        for (j=i ; j>=1 ; j--)
+          { if ( *(tab+indx[j]) < *(tab+indx[j-1]) )
+            { 
+            k = indx[j-1];
+            indx[j-1] = indx[j];
+            indx[j] = k;
+    } } } }
+
+return (N) ;
+}
+
+/*===================================================================================*/
+/*
+++
+  int qSort_Float(const void *a1,const void *a2)
+	Fonction de tri de `float' a utiliser dans qsort.
+--
+*/
+int qSort_Float(const void *a1,const void *a2)
+{
+if( *((float *) a1) < *((float *) a2) ) return(-1);
+if( *((float *) a1) > *((float *) a2) ) return( 1);
+return(0);
+}
+
+/*===================================================================================*/
+/*
+++
+  int qSort_Dble(const void *a1,const void *a2)
+	Fonction de tri de `double' a utiliser dans qsort.
+--
+*/
+int qSort_Dble(const void *a1,const void *a2)
+{
+if( *((double *) a1) < *((double *) a2) ) return(-1);
+if( *((double *) a1) > *((double *) a2) ) return( 1);
+return(0);
+}
+
+/*===================================================================================*/
+/*
+++
+  int qSort_Int(const void  *a1,const void  *a2)
+	Fonction de tri de `int' a utiliser dans qsort.
+--
+*/
+int qSort_Int(const void  *a1,const void  *a2)
+{
+if( *((int *) a1) < *((int *) a2) ) return(-1);
+if( *((int *) a1) > *((int *) a2) ) return( 1);
+return(0);
+}
+
+/*===================================================================================*/
+/*
+++
+  int qSort_Ushort(const void  *a1,const void  *a2)
+	Fonction de tri de `unsigned short' a utiliser dans qsort.
+--
+*/
+int qSort_Ushort(const void  *a1,const void  *a2)
+{
+if( *((unsigned short *) a1) < *((unsigned short *) a2) ) return(-1);
+if( *((unsigned short *) a1) > *((unsigned short *) a2) ) return( 1);
+return(0);
+}
+
+/*===================================================================================*/
+/*
+++
+  int qSort_Short(const void  *a1,const void  *a2)
+	Fonction de tri de `short' a utiliser dans qsort.
+--
+*/
+int qSort_Short(const void  *a1,const void  *a2)
+{
+if( *((short *) a1) < *((short *) a2) ) return(-1);
+if( *((short *) a1) > *((short *) a2) ) return( 1);
+return(0);
+}
+
+/*===================================================================================*/
+/*
+++
+  void IndexR4(int_4 n, float* arr_c, int_4* indx_c)
+	Indexes an array arr[1..n], i.e., outputs the array indx[1..n]
+	such that arr[indx[j]] is in ascending order for j=1,2,,N.
+	The input quantities n and arr are not changed.
+--
+*/
+#define SWAP_INDEXR4(a,b) itemp=(a);(a)=(b);(b)=itemp;
+#define M 7
+#define NSTACK 50
+void IndexR4(int_4 n, float* arr_c, int_4* indx_c)
+/* encore du Num.Rec. avec tableaux commencant a 1. */
+{
+        float *arr; int_4 *indx;
+	int_4 i,indxt,ir=n,itemp,j,k,l=1;
+	int_4 jstack=0;
+	float a;
+        int_4 istack[NSTACK+1];
+
+        arr = arr_c-1;
+        indx = indx_c-1;
+
+	for (j=1;j<=n;j++) indx[j]=j;
+	for (;;) {
+		if (ir-l < M) {
+			for (j=l+1;j<=ir;j++) {
+				indxt=indx[j];
+				a=arr[indxt];
+				for (i=j-1;i>=1;i--) {
+					if (arr[indx[i]] <= a) break;
+					indx[i+1]=indx[i];
+				}
+				indx[i+1]=indxt;
+			}
+			if (jstack == 0) break;
+			ir=istack[jstack--];
+			l=istack[jstack--];
+		} else {
+			k=(l+ir) >> 1;
+			SWAP_INDEXR4(indx[k],indx[l+1]);
+			if (arr[indx[l+1]] > arr[indx[ir]]) {
+				SWAP_INDEXR4(indx[l+1],indx[ir])
+			}
+			if (arr[indx[l]] > arr[indx[ir]]) {
+				SWAP_INDEXR4(indx[l],indx[ir])
+			}
+			if (arr[indx[l+1]] > arr[indx[l]]) {
+				SWAP_INDEXR4(indx[l+1],indx[l])
+			}
+			i=l+1;
+			j=ir;
+			indxt=indx[l];
+			a=arr[indxt];
+			for (;;) {
+				do i++; while (arr[indx[i]] < a);
+				do j--; while (arr[indx[j]] > a);
+				if (j < i) break;
+				SWAP_INDEXR4(indx[i],indx[j])
+			}
+			indx[l]=indx[j];
+			indx[j]=indxt;
+			jstack += 2;
+			if (jstack > NSTACK) {
+                          printf("NSTACK too small in indexx. %d>%d",jstack,NSTACK);
+                          exit(-1);
+			}
+			if (ir-i+1 >= j-l) {
+				istack[jstack]=ir;
+				istack[jstack-1]=i;
+				ir=j-1;
+			} else {
+				istack[jstack]=j-1;
+				istack[jstack-1]=l;
+				l=i;
+			}
+		}
+	}
+        /* pour avoir un retour d'indice entre 0 et n-1 */
+	for (j=0;j<n;j++) indx_c[j]=indx_c[j]-1;
+}
+#undef SWAP_INDEXR4
+#undef M
+#undef NSTACK
+
+/*===================================================================================*/
+/*
+++
+  void IndexR8(int_4 n, double* arr_c, int_4* indx_c)
+	Indexes an array arr[1..n], i.e., outputs the array indx[1..n]
+	such that arr[indx[j]] is in ascending order for j=1,2,,N.
+	The input quantities n and arr are not changed.
+--
+*/
+#define SWAP_INDEXR8(a,b) itemp=(a);(a)=(b);(b)=itemp;
+#define M 7
+#define NSTACK 50
+void IndexR8(int_4 n, double* arr_c, int_4* indx_c)
+/* encore du Num.Rec. avec tableaux commencant a 1. */
+{
+        double *arr; int_4 *indx;
+	int_4 i,indxt,ir=n,itemp,j,k,l=1;
+	int_4 jstack=0;
+	double a;
+        int_4 istack[NSTACK+1];
+
+        arr = arr_c-1;
+        indx = indx_c-1;
+
+	for (j=1;j<=n;j++) indx[j]=j;
+	for (;;) {
+		if (ir-l < M) {
+			for (j=l+1;j<=ir;j++) {
+				indxt=indx[j];
+				a=arr[indxt];
+				for (i=j-1;i>=1;i--) {
+					if (arr[indx[i]] <= a) break;
+					indx[i+1]=indx[i];
+				}
+				indx[i+1]=indxt;
+			}
+			if (jstack == 0) break;
+			ir=istack[jstack--];
+			l=istack[jstack--];
+		} else {
+			k=(l+ir) >> 1;
+			SWAP_INDEXR8(indx[k],indx[l+1]);
+			if (arr[indx[l+1]] > arr[indx[ir]]) {
+				SWAP_INDEXR8(indx[l+1],indx[ir])
+			}
+			if (arr[indx[l]] > arr[indx[ir]]) {
+				SWAP_INDEXR8(indx[l],indx[ir])
+			}
+			if (arr[indx[l+1]] > arr[indx[l]]) {
+				SWAP_INDEXR8(indx[l+1],indx[l])
+			}
+			i=l+1;
+			j=ir;
+			indxt=indx[l];
+			a=arr[indxt];
+			for (;;) {
+				do i++; while (arr[indx[i]] < a);
+				do j--; while (arr[indx[j]] > a);
+				if (j < i) break;
+				SWAP_INDEXR8(indx[i],indx[j])
+			}
+			indx[l]=indx[j];
+			indx[j]=indxt;
+			jstack += 2;
+			if (jstack > NSTACK) {
+                          printf("NSTACK too small in indexx. %d>%d",jstack,NSTACK);
+                          exit(-1);
+			}
+			if (ir-i+1 >= j-l) {
+				istack[jstack]=ir;
+				istack[jstack-1]=i;
+				ir=j-1;
+			} else {
+				istack[jstack]=j-1;
+				istack[jstack-1]=l;
+				l=i;
+			}
+		}
+	}
+        /* pour avoir un retour d'indice entre 0 et n-1 */
+	for (j=0;j<n;j++) indx_c[j]=indx_c[j]-1;
+}
+#undef SWAP_INDEXR8
+#undef M
+#undef NSTACK
Index: /tags/V_Dec2002/SophyaLib/NTools/nbtri.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/nbtri.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/nbtri.h	(revision 2309)
@@ -0,0 +1,37 @@
+/* fonction de tri */
+/*    cmv 23/06/94 */
+
+#ifndef NBTRI_H_SEEN
+#define NBTRI_H_SEEN
+
+
+#include "machdefs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+void HeapSort(int n,double *ra_int);
+void HeapSortF(int n,float *ra_int);
+void HeapSortF2(int n,float *ra_int,float *ra2_int);
+
+int_4 tri_double ( double *tab, int_4 *indx,int_4 N);
+int_4 tri_float ( float *tab, int_4 *indx,int_4 N);
+int_4 tri_entier ( int_4 *tab,int_4 *indx,int_4 N);
+
+int qSort_Float(const void *a1,const void *a2);
+int qSort_Dble(const void *a1,const void *a2);
+int qSort_Int(const void *a1,const void *a2);
+int qSort_Ushort(const void *a1,const void *a2);
+int qSort_Short(const void *a1,const void *a2);
+
+void IndexR4(int_4 n, float* arr_c, int_4* indx_c);
+void IndexR8(int_4 n, double* arr_c, int_4* indx_c);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Index: /tags/V_Dec2002/SophyaLib/NTools/ntools.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/ntools.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/ntools.h	(revision 2309)
@@ -0,0 +1,29 @@
+// This may look like C code, but it is really -*- C++ -*-
+//  All include files for module NTools
+
+#ifndef NTOOLS_SEEN
+#define NTOOLS_SEEN
+
+#include "ntoolsinit.h"
+
+#include "nbconst.h"
+#include "fmath.h"
+#include "nbrandom.h"
+#include "perandom.h"
+#include "nbtri.h"
+#include "linfit.h"
+#include "poly.h"
+#include "datatypes.h"
+
+#include "cimage.h"
+#include "dynccd.h"
+
+#include "generaldata.h"
+#include "generalfit.h"
+#include "fct1dfit.h"
+#include "fct2dfit.h"
+#include "objfitter.h"
+
+#include "fftpserver.h"
+
+#endif // NTOOLS_SEEN
Index: /tags/V_Dec2002/SophyaLib/NTools/ntoolsinit.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/ntoolsinit.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/ntoolsinit.cc	(revision 2309)
@@ -0,0 +1,74 @@
+// Classe d'initialisation du module NTools
+
+#include "machdefs.h"
+#include "ntoolsinit.h"
+
+#include "poly.h"
+#include "generaldata.h"
+#include "cimage.h"
+
+#include "tabmath.h"
+#include "dates.h"
+#include "datime.h"
+
+/*!
+   \defgroup NTools NTools module
+   This module contains various tools for Sophya.
+*/
+
+int NToolsInitiator::FgInit = 0;
+
+/*!
+  \class SOPHYA::NToolsInitiator
+  \ingroup NTools
+  Tools initiator
+*/
+NToolsInitiator::NToolsInitiator()
+  : TArrayInitiator()
+{
+  FgInit++;
+  if (FgInit > 1)  return;
+
+//   Enregistrement des classes PPersist du modules NTools
+
+  //  Objets Poly et Poly2  (pas encore a la norme Sophya::PPersist)
+  PPRegister(ObjFileIO<Poly>);
+  PPRegister(ObjFileIO<Poly2>);
+
+  // Classe GeneralFitData et son PPersist handler
+  PPRegister(ObjFileIO<GeneralFitData>);
+  DObjRegister(ObjFileIO<GeneralFitData>, GeneralFitData);
+
+  // Classes Image<T> et leurs  PPersist handler
+  PPRegister(FIO_Image<uint_2>);
+  DObjRegister(FIO_Image<uint_2>, Image<uint_2>);
+  PPRegister(FIO_Image<int_4>);
+  DObjRegister(FIO_Image<int_4>, Image<int_4>);
+  PPRegister(FIO_Image<int_8>);
+  DObjRegister(FIO_Image<int_8>, Image<int_8>);
+  PPRegister(FIO_Image<r_4>);
+  DObjRegister(FIO_Image<r_4>, Image<r_4>);
+  PPRegister(FIO_Image<r_8>);
+  DObjRegister(FIO_Image<r_8>, Image<r_8>);
+
+
+//  TSidSetupLaSilla();    Old-Eros
+
+  gTimeZone = new TimeZone;
+
+  ptabFExp = new TabFExp;
+
+}
+
+NToolsInitiator::~NToolsInitiator()
+{
+  FgInit--;
+}
+
+
+// On met un objet initiator en statique, pour les loaders qui savent 
+// appeler le constructeur des objets statiques   Reza 08/98
+#ifndef Darwin
+static NToolsInitiator ntoolsinit;
+#endif
+
Index: /tags/V_Dec2002/SophyaLib/NTools/ntoolsinit.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/ntoolsinit.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/ntoolsinit.h	(revision 2309)
@@ -0,0 +1,27 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe d'initialiseur du module NTools
+
+#ifndef NTOOLSINIT_H_SEEN
+#define NTOOLSINIT_H_SEEN
+
+// Classe d''initialisation pour le module de NTools
+#include "tarrinit.h"
+
+namespace SOPHYA {
+
+//! Tools initiator
+class NToolsInitiator : public TArrayInitiator {
+private:
+  static int FgInit;
+public:
+  			NToolsInitiator();
+  virtual		~NToolsInitiator();
+};
+
+#undef SophyaInit
+#define SophyaInit() NToolsInitiator ntoolsinitiator
+
+} // Fin du namespace
+
+#endif
+
Index: /tags/V_Dec2002/SophyaLib/NTools/objfitter.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/objfitter.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/objfitter.cc	(revision 2309)
@@ -0,0 +1,418 @@
+#include "objfitter.h"
+
+//===========================================================================
+//===========================================================================
+//=========================== ObjectFitter ==================================
+//===========================================================================
+//===========================================================================
+
+//============================= Matrix et Vector ============================
+TMatrix<int_4>
+ObjectFitter::FitResidus(TMatrix<int_4> const & mtx,GeneralFit& gfit,
+			 double xorg,double yorg,double dx,double dy)
+{return( ArrayFitter<int_4>::FitResidus(mtx,gfit,xorg,yorg,dx,dy) );}
+
+TMatrix<r_4>
+ObjectFitter::FitResidus(TMatrix<r_4> const & mtx,GeneralFit& gfit,
+			 double xorg,double yorg,double dx,double dy)
+{return( ArrayFitter<r_4>::FitResidus(mtx,gfit,xorg,yorg,dx,dy) );}
+
+TMatrix<r_8>
+ObjectFitter::FitResidus(TMatrix<r_8> const & mtx,GeneralFit& gfit,
+			 double xorg,double yorg,double dx,double dy)
+{return( ArrayFitter<r_8>::FitResidus(mtx,gfit,xorg,yorg,dx,dy) );}
+
+TMatrix<int_4>
+ObjectFitter::FitFunction(TMatrix<int_4> const & mtx,GeneralFit& gfit,
+			  double xorg,double yorg,double dx,double dy)
+{return( ArrayFitter<int_4>::FitFunction(mtx,gfit,xorg,yorg,dx,dy) );}
+
+TMatrix<r_4>
+ObjectFitter::FitFunction(TMatrix<r_4> const & mtx,GeneralFit& gfit,
+			  double xorg,double yorg,double dx,double dy)
+{return( ArrayFitter<r_4>::FitFunction(mtx,gfit,xorg,yorg,dx,dy) );}
+
+TMatrix<r_8>
+ObjectFitter::FitFunction(TMatrix<r_8> const & mtx,GeneralFit& gfit,
+			  double xorg,double yorg,double dx,double dy)
+{return( ArrayFitter<r_8>::FitFunction(mtx,gfit,xorg,yorg,dx,dy) );}
+
+TVector<int_4>
+ObjectFitter::FitResidus(TVector<int_4> const & vec,GeneralFit& gfit,
+			 double xorg,double dx)
+{return( ArrayFitter<int_4>::FitResidus(vec,gfit,xorg,dx) );}
+
+TVector<r_4>
+ObjectFitter::FitResidus(TVector<r_4> const & vec,GeneralFit& gfit,
+			 double xorg,double dx)
+{return( ArrayFitter<r_4>::FitResidus(vec,gfit,xorg,dx) );}
+
+TVector<r_8>
+ObjectFitter::FitResidus(TVector<r_8> const & vec,GeneralFit& gfit,
+			 double xorg,double dx)
+{return( ArrayFitter<r_8>::FitResidus(vec,gfit,xorg,dx) );}
+
+TVector<int_4>
+ObjectFitter::FitFunction(TVector<int_4> const & vec,GeneralFit& gfit,
+			  double xorg,double dx)
+{return( ArrayFitter<int_4>::FitFunction(vec,gfit,xorg,dx) );}
+
+TVector<r_4>
+ObjectFitter::FitFunction(TVector<r_4> const & vec,GeneralFit& gfit,
+			  double xorg,double dx)
+{return( ArrayFitter<r_4>::FitFunction(vec,gfit,xorg,dx) );}
+
+TVector<r_8>
+ObjectFitter::FitFunction(TVector<r_8> const & vec,GeneralFit& gfit,
+			  double xorg,double dx)
+{return( ArrayFitter<r_8>::FitFunction(vec,gfit,xorg,dx) );}
+
+//============================= Matrix et Vector ============================
+Image<uint_2> ObjectFitter::FitResidus(Image<uint_2> const & im,GeneralFit& gfit)
+{ return( ImageFitter<uint_2>::FitResidus(im,gfit) ); }
+Image<int_4> ObjectFitter::FitResidus(Image<int_4> const & im,GeneralFit& gfit)
+{ return( ImageFitter<int_4>::FitResidus(im,gfit) ); }
+Image<int_8> ObjectFitter::FitResidus(Image<int_8> const & im,GeneralFit& gfit)
+{ return( ImageFitter<int_8>::FitResidus(im,gfit) ); }
+Image<r_4> ObjectFitter::FitResidus(Image<r_4> const & im,GeneralFit& gfit)
+{ return( ImageFitter<r_4>::FitResidus(im,gfit) ); }
+Image<r_8> ObjectFitter::FitResidus(Image<r_8> const & im,GeneralFit& gfit)
+{ return( ImageFitter<r_8>::FitResidus(im,gfit) ); }
+
+Image<uint_2> ObjectFitter::FitFunction(Image<uint_2> const & im,GeneralFit& gfit)
+{ return( ImageFitter<uint_2>::FitFunction(im,gfit) ); }
+Image<int_4> ObjectFitter::FitFunction(Image<int_4> const & im,GeneralFit& gfit)
+{ return( ImageFitter<int_4>::FitFunction(im,gfit) ); }
+Image<int_8> ObjectFitter::FitFunction(Image<int_8> const & im,GeneralFit& gfit)
+{ return( ImageFitter<int_8>::FitFunction(im,gfit) ); }
+Image<r_4> ObjectFitter::FitFunction(Image<r_4> const & im,GeneralFit& gfit)
+{ return( ImageFitter<r_4>::FitFunction(im,gfit) ); }
+Image<r_8> ObjectFitter::FitFunction(Image<r_8> const & im,GeneralFit& gfit)
+{ return( ImageFitter<r_8>::FitFunction(im,gfit) ); }
+
+//=============================== Histo =====================================
+/*! Retourne une classe contenant les residus du fit ``gfit''. */
+Histo ObjectFitter::FitResidus(Histo const& hh, GeneralFit& gfit)
+{
+Histo h(hh);
+if(h.NBins()<=0)
+  throw(SzMismatchError("Histo::FitResidus: size mismatch\n"));
+GeneralFunction* f = gfit.GetFunction();
+if(f==NULL)
+  throw(NullPtrError("Histo::FitResidus: NULL pointer\n"));
+TVector<r_8> par = gfit.GetParm();
+for(int_4 i=0;i<h.NBins();i++) {
+  r_8 x =  h.BinCenter(i);
+  h(i) -=  f->Value(&x,par.Data());
+}
+return h;
+}
+
+/*! Retourne une classe contenant la fonction du fit ``gfit''. */
+Histo ObjectFitter::FitFunction(Histo const& hh, GeneralFit& gfit)
+{
+Histo h(hh);
+if(h.NBins()<=0)
+  throw(SzMismatchError("Histo::FitFunction: size mismatch\n"));
+GeneralFunction* f = gfit.GetFunction();
+if(f==NULL)
+  throw(NullPtrError("Histo::FitFunction: NULL pointer\n"));
+TVector<r_8> par = gfit.GetParm();
+for(int_4 i=0;i<h.NBins();i++) {
+  r_8 x =  h.BinCenter(i);
+  h(i) =  f->Value(&x,par.Data());
+}
+return h;
+}
+
+/*!
+  Fit de l'histogramme par ``gfit''.
+  \param errtype,errscale,errmin : pour definir les erreurs
+  \sa GeneralFitData::ComputeError(double,err,FitErrType,double,double,bool)
+*/
+int_4 ObjectFitter::Fit(Histo const& h, GeneralFit& gfit
+      ,GeneralFitData::FitErrType errtype,double errscale,double errmin)
+{
+if(h.NBins()<=0) return -1000;
+
+GeneralFitData mydata(1,h.NBins());
+
+for(int_4 i=0;i<h.NBins();i++) {
+  r_8 x =  h.BinCenter(i);
+  r_8 f =  h(i);
+  r_8 e = (h.HasErrors()) ? h.Error(i) : 1.;
+  e = GeneralFitData::ComputeError(f,e,errtype,errscale,errmin);
+  mydata.AddData1(x,f,e);
+}
+
+gfit.SetData(&mydata);
+
+return gfit.Fit();
+}
+
+//============================== Histo2D ====================================
+/*! Retourne une classe contenant les residus du fit ``gfit''. */
+Histo2D ObjectFitter::FitResidus(Histo2D const& hh, GeneralFit& gfit)
+{
+Histo2D h(hh);
+if(h.NBinX()<=0 || h.NBinY()<=0)
+  throw(SzMismatchError("Histo2D::FitResidus: size mismatch\n"));
+GeneralFunction* f = gfit.GetFunction();
+if(f==NULL)
+  throw(NullPtrError("Histo2D::FitResidus: NULL pointer\n"));
+TVector<r_8> par = gfit.GetParm();
+for(int_4 i=0;i<h.NBinX();i++) for(int_4 j=0;j<h.NBinY();j++) {
+  r_8 xc,yc;
+  h.BinCenter(i,j,xc,yc);
+  r_8 x[2] = {xc,yc};
+  h(i,j) -= f->Value(x,par.Data());
+}
+return h;
+}
+
+/*! Retourne une classe contenant la fonction du fit ``gfit''. */
+Histo2D ObjectFitter::FitFunction(Histo2D const& hh, GeneralFit& gfit)
+{
+Histo2D h(hh);
+if(h.NBinX()<=0 || h.NBinY()<=0)
+  throw(SzMismatchError("Histo2D::FitFunction: size mismatch\n"));
+GeneralFunction* f = gfit.GetFunction();
+if(f==NULL)
+  throw(NullPtrError("Histo2D::FitFunction: NULL pointer\n"));
+TVector<r_8> par = gfit.GetParm();
+for(int_4 i=0;i<h.NBinX();i++) for(int_4 j=0;j<h.NBinY();j++) {
+  r_8 xc,yc;
+  h.BinCenter(i,j,xc,yc);
+  r_8 x[2] = {xc,yc};
+  h(i,j) = f->Value(x,par.Data());
+}
+return h;
+}
+
+/*!
+  Fit de l'histogramme par ``gfit''.
+  \param errtype,errscale,errmin : pour definir les erreurs
+  \sa GeneralFitData::ComputeError(double,err,FitErrType,double,double,bool)
+*/
+int_4 ObjectFitter::Fit(Histo2D const & h, GeneralFit& gfit
+      ,GeneralFitData::FitErrType errtype,double errscale,double errmin)
+{
+if(h.NBinX()*h.NBinY()<=0) return -1000;
+
+GeneralFitData mydata(2,h.NBinX()*h.NBinY());
+
+for(int_4 i=0;i<h.NBinX();i++) for(int_4 j=0;j<h.NBinY();j++) {
+  r_8 x,y; h.BinCenter(i,j,x,y);
+  r_8 f = h(i,j);
+  r_8 e = (h.HasErrors()) ? h.Error(i,j) : 1.;
+  e = GeneralFitData::ComputeError(f,e,errtype,errscale,errmin);
+  mydata.AddData2(x,y,f,e);
+}
+
+gfit.SetData(&mydata);
+
+return gfit.Fit();
+}
+
+//===========================================================================
+//===========================================================================
+//========================== ArrayFitter<T> =================================
+//===========================================================================
+//===========================================================================
+
+/*! Retourne une classe contenant les residus du fit ``gfit''. */
+template <class T>
+TMatrix<T> 
+ArrayFitter<T>::FitResidus(TMatrix<T> const & mtx, GeneralFit& gfit,
+			   double xorg,double yorg,double dx,double dy)
+// Retourne une classe contenant les residus du fit ``gfit''.
+// On suppose que x=j (colonnes) et y=i (lignes) pour m(i,j).
+// Les coordonnees de l'element (i,j) sont :
+//    (i,j) -> x = xorg+j*dx , y = yorg+i*dy
+{
+if(mtx.NCols()<=0||mtx.NRows()<=0)
+  throw(SzMismatchError("ArrayFitter::FitResidus(TMatrix<T>...) size mismatch\n"));
+GeneralFunction* f = gfit.GetFunction();
+if(f==NULL)
+  throw(NullPtrError("ArrayFitter::FitResidus(TMatrix<T>...) GeneraFit==NULL\n"));
+int npar =  gfit.GetNPar();
+if(npar==0)
+  throw(SzMismatchError("ArrayFitter::FitResidus(TMatrix<T>...) GeneraFit 0 parametre\n"));
+double* par = new double[npar];
+{for(int i=0;i<npar;i++) par[i] = gfit.GetParm(i);}
+TMatrix<T> m(mtx,false);
+for(uint_4 i=0;i<mtx.NRows();i++) for(uint_4 j=0;j<mtx.NCols();j++) {
+  double x[2] = {xorg+j*dx,yorg+i*dy};
+  m(i,j) -= f->Value(x,par);
+}
+delete [] par;
+return m;
+}
+
+
+/*! Retourne une classe contenant la fonction du fit ``gfit''. */
+template <class T>
+TMatrix<T> 
+ArrayFitter<T>::FitFunction(TMatrix<T> const & mtx, GeneralFit& gfit,
+			    double xorg,double yorg,double dx,double dy)
+
+// Retourne une classe contenant la fonction du fit ``gfit''.
+// On suppose que x=j (colonnes) et y=i (lignes) pour m(i,j).
+// Les coordonnees de l'element (i,j) sont :
+//    (i,j) -> x = xorg + j*dx , y = yorg + i*dy
+
+{
+if(mtx.NCols()<=0||mtx.NRows()<=0)
+  throw(SzMismatchError("ArrayFitter::FitFunction(TMatrix<T>...) size mismatch\n"));
+GeneralFunction* f = gfit.GetFunction();
+if(f==NULL)
+  throw(NullPtrError("ArrayFitter::FitFunction(TMatrix<T>...) GeneraFit==NULL\n"));
+int npar =  gfit.GetNPar();
+if(npar==0)
+  throw(SzMismatchError("ArrayFitter::FitFunction(TMatrix<T>...) GeneraFit 0 parametre\n"));
+double* par = new double[npar];
+{for(int i=0;i<npar;i++) par[i] = gfit.GetParm(i);}
+TMatrix<T> m(mtx.NRows(), mtx.NCols());
+for(uint_4 i=0;i<mtx.NRows();i++) for(uint_4 j=0;j<mtx.NCols();j++) {
+  double x[2] = {xorg+j*dx,yorg+i*dy};
+  m(i,j) = f->Value(x,par);
+}
+delete [] par;
+return m;
+
+}
+
+/*! Retourne une classe contenant les residus du fit ``gfit''. */
+template <class T>
+TVector<T> 
+ArrayFitter<T>::FitResidus(TVector<T> const & vec, GeneralFit& gfit,
+			   double xorg,double dx)
+// Retourne une classe contenant la fonction fittee du fit ``gfit''.
+// La coordonnee de l'element (i) est -> x = xorg + i*dx
+{
+if(vec.NElts()<=0)
+  throw(SzMismatchError("ArrayFitter::FitResidus(TVector<T>...)  size mismatch\n"));
+GeneralFunction* f = gfit.GetFunction();
+if(f==NULL)
+  throw(NullPtrError("ArrayFitter::FitResidus(TVector<T>...) GeneraFit==NULL\n"));
+int npar =  gfit.GetNPar();
+if(npar==0)
+  throw(SzMismatchError("ArrayFitter::FitResidus(TVector<T>...) GeneraFit 0 parametre\n"));
+double* par = new double[npar];
+{for(int i=0;i<npar;i++) par[i] = gfit.GetParm(i);}
+TVector<T> v(vec,false);
+for(uint_4 i=0;i<vec.NElts();i++) {
+  double x = xorg+i*dx;
+  v(i) -= f->Value(&x,par);
+}
+delete [] par;
+return v;
+}
+
+/*! Retourne une classe contenant la fonction du fit ``gfit''. */
+template <class T>
+TVector<T> 
+ArrayFitter<T>::FitFunction(TVector<T> const & vec, GeneralFit& gfit,
+			    double xorg,double dx)
+// Retourne une classe contenant la function fittee du fit ``gfit''.
+// La coordonnee de l'element (i) est -> x = xorg + i*dx
+{
+if(vec.NElts()<=0)
+  throw(SzMismatchError("ArrayFitter::FitResidus(TVector<T>...)  size mismatch\n"));
+GeneralFunction* f = gfit.GetFunction();
+if(f==NULL)
+  throw(NullPtrError("ArrayFitter::FitResidus(TVector<T>...) GeneraFit==NULL\n"));
+int npar =  gfit.GetNPar();
+if(npar==0)
+  throw(SzMismatchError("ArrayFitter::FitResidus(TVector<T>...) GeneraFit 0 parametre\n"));
+double* par = new double[npar];
+{for(int i=0;i<npar;i++) par[i] = gfit.GetParm(i);}
+TVector<T> v(vec.NElts());
+for(uint_4 i=0;i<vec.NElts();i++) {
+  double x = xorg+i*dx;
+  v(i) = f->Value(&x,par);
+}
+delete [] par;
+return v;
+}
+
+//===========================================================================
+//===========================================================================
+//========================== ImageFitter<T> =================================
+//===========================================================================
+//===========================================================================
+
+/*! Retourne une classe contenant les residus du fit ``gfit''. */
+template <class T>
+Image<T> 
+ImageFitter<T>::FitResidus(Image<T> const & ima, GeneralFit& gfit)
+{
+if(ima.XSize()<=0||ima.YSize()<=0)
+  throw(SzMismatchError("ImageFitter::FitResidus(Image<T>...) size mismatch\n"));
+GeneralFunction* f = gfit.GetFunction();
+if(f==NULL)
+  throw(NullPtrError("ImageFitter::FitResidus(Image<T>...) GeneraFit==NULL\n"));
+int npar =  gfit.GetNPar();
+if(npar==0)
+  throw(SzMismatchError("ImageFitter::FitResidus(Image<T>...) GeneraFit 0 parametre\n"));
+double* par = new double[npar];
+{for(int i=0;i<npar;i++) par[i] = gfit.GetParm(i);}
+Image<T> im(ima,false);
+for(uint_4 i=0;i<ima.XSize();i++) for(uint_4 j=0;j<ima.YSize();j++) {
+  double x[2] = {ima.XPos(i),ima.YPos(j)};
+  im(i,j) -= f->Value(x,par);
+}
+delete [] par;
+return im;
+}
+
+/*! Retourne une classe contenant la function fittee du fit ``gfit''. */
+template <class T>
+Image<T> 
+ImageFitter<T>::FitFunction(Image<T> const & ima, GeneralFit& gfit)
+{
+if(ima.XSize()<=0||ima.YSize()<=0)
+  throw(SzMismatchError("ImageFitter::FitFunction(Image<T>...) size mismatch\n"));
+GeneralFunction* f = gfit.GetFunction();
+if(f==NULL)
+  throw(NullPtrError("ImageFitter::FitFunction(Image<T>...) GeneraFit==NULL\n"));
+int npar =  gfit.GetNPar();
+if(npar==0)
+  throw(SzMismatchError("ImageFitter::FitFunction(Image<T>...) GeneraFit 0 parametre\n"));
+double* par = new double[npar];
+{for(int i=0;i<npar;i++) par[i] = gfit.GetParm(i);}
+Image<T> im(ima.XSize(),ima.YSize());
+for(uint_4 i=0;i<ima.XSize();i++) for(uint_4 j=0;j<ima.YSize();j++) {
+  double x[2] = {ima.XPos(i),ima.YPos(j)};
+  im(i,j) = f->Value(x,par);
+}
+delete [] par;
+return im;
+}
+
+///////////////////////////////////////////////////////////////
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template ArrayFitter<int_4>
+#pragma define_template ArrayFitter<r_4>
+#pragma define_template ArrayFitter<r_8>
+#pragma define_template ArrayFitter< complex<r_4> >
+#pragma define_template ArrayFitter< complex<r_8> >
+#pragma define_template ImageFitter<uint_2>
+#pragma define_template ImageFitter<int_4>
+#pragma define_template ImageFitter<int_8>
+#pragma define_template ImageFitter<r_4>
+#pragma define_template ImageFitter<r_8>
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class ArrayFitter<int_4>;
+template class ArrayFitter<r_4>;
+template class ArrayFitter<r_8>;
+template class ArrayFitter< complex<r_4> >;
+template class ArrayFitter< complex<r_8> >;
+template class ImageFitter<uint_2>;
+template class ImageFitter<int_4>;
+template class ImageFitter<int_8>;
+template class ImageFitter<r_4>;
+template class ImageFitter<r_8>;
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/objfitter.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/objfitter.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/objfitter.h	(revision 2309)
@@ -0,0 +1,142 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Methode d'ajustement non-lineaire sur des objets 
+//                                   R. Ansari    02/2000
+
+#ifndef OBJFITTER_SEEN
+#define OBJFITTER_SEEN
+
+#include "machdefs.h"
+
+#include "tmatrix.h"
+#include "cimage.h"
+#include "tvector.h"
+#include "histos.h"
+#include "histos2.h"
+#include "hisprof.h"
+#include "generalfit.h"
+
+
+namespace SOPHYA {
+
+class  ObjectFitter {
+public:
+  // Residus et fonction fittees sur matrix
+  static TMatrix<int_4> FitResidus(TMatrix<int_4> const & mtx, GeneralFit& gfit,
+			       double xorg=0.,double yorg=0.,double dx=1.,double dy=1.);
+  static TMatrix<r_4> FitResidus(TMatrix<r_4> const & mtx, GeneralFit& gfit,
+			       double xorg=0.,double yorg=0.,double dx=1.,double dy=1.);
+  static TMatrix<r_8> FitResidus(TMatrix<r_8> const & mtx, GeneralFit& gfit,
+			       double xorg=0.,double yorg=0.,double dx=1.,double dy=1.);
+  static TMatrix< complex<r_4> > FitResidus(TMatrix< complex<r_4> > const & mtx, GeneralFit& gfit,
+			       double xorg=0.,double yorg=0.,double dx=1.,double dy=1.);
+  static TMatrix< complex<r_8> > FitResidus(TMatrix< complex<r_8> > const & mtx, GeneralFit& gfit,
+			       double xorg=0.,double yorg=0.,double dx=1.,double dy=1.);
+
+  static TMatrix<int_4> FitFunction(TMatrix<int_4> const & mtx, GeneralFit& gfit,
+			       double xorg=0.,double yorg=0.,double dx=1.,double dy=1.);
+  static TMatrix<r_4> FitFunction(TMatrix<r_4> const & mtx, GeneralFit& gfit,
+			       double xorg=0.,double yorg=0.,double dx=1.,double dy=1.);
+  static TMatrix<r_8> FitFunction(TMatrix<r_8> const & mtx, GeneralFit& gfit,
+			       double xorg=0.,double yorg=0.,double dx=1.,double dy=1.);
+  static TMatrix< complex<r_4> > FitFunction(TMatrix< complex<r_4> > const & mtx, GeneralFit& gfit,
+			       double xorg=0.,double yorg=0.,double dx=1.,double dy=1.);
+  static TMatrix< complex<r_8> > FitFunction(TMatrix< complex<r_8> > const & mtx, GeneralFit& gfit,
+			       double xorg=0.,double yorg=0.,double dx=1.,double dy=1.);
+
+  // Residus et fonction fittees sur vecteurs
+  static TVector<int_4> FitResidus(TVector<int_4> const & vec, GeneralFit& gfit,
+			       double xorg=0.,double dx=1.);
+  static TVector<r_4> FitResidus(TVector<r_4> const & vec, GeneralFit& gfit,
+			       double xorg=0.,double dx=1.);
+  static TVector<r_8> FitResidus(TVector<r_8> const & vec, GeneralFit& gfit,
+			       double xorg=0.,double dx=1.);
+  static TVector< complex<r_4> > FitResidus(TVector< complex<r_4> > const & vec, GeneralFit& gfit,
+			       double xorg=0.,double dx=1.);
+  static TVector< complex<r_8> > FitResidus(TVector< complex<r_8> > const & vec, GeneralFit& gfit,
+			       double xorg=0.,double dx=1.);
+
+  static TVector<int_4> FitFunction(TVector<int_4> const & vec, GeneralFit& gfit,
+				double xorg=0.,double dx=1.);
+  static TVector<r_4> FitFunction(TVector<r_4> const & vec, GeneralFit& gfit,
+				double xorg=0.,double dx=1.);
+  static TVector<r_8> FitFunction(TVector<r_8> const & vec, GeneralFit& gfit,
+				double xorg=0.,double dx=1.);
+  static TVector< complex<r_4> > FitFunction(TVector< complex<r_4> > const & vec, GeneralFit& gfit,
+				double xorg=0.,double dx=1.);
+  static TVector< complex<r_8> > FitFunction(TVector< complex<r_8> > const & vec, GeneralFit& gfit,
+				double xorg=0.,double dx=1.);
+
+  // Residus et fonction fittees sur Image
+  static Image<uint_2> FitResidus(Image<uint_2> const & im, GeneralFit& gfit);
+  static Image<int_4> FitResidus(Image<int_4> const & im, GeneralFit& gfit);
+  static Image<int_8> FitResidus(Image<int_8> const & im, GeneralFit& gfit);
+  static Image<r_4> FitResidus(Image<r_4> const & im, GeneralFit& gfit);
+  static Image<r_8> FitResidus(Image<r_8> const & im, GeneralFit& gfit);
+
+  static Image<uint_2> FitFunction(Image<uint_2> const & im, GeneralFit& gfit);
+  static Image<int_4> FitFunction(Image<int_4> const & im, GeneralFit& gfit);
+  static Image<int_8> FitFunction(Image<int_8> const & im, GeneralFit& gfit);
+  static Image<r_4> FitFunction(Image<r_4> const & im, GeneralFit& gfit);
+  static Image<r_8> FitFunction(Image<r_8> const & im, GeneralFit& gfit);
+
+  // Residus et fonction fittees sur Histo
+  static Histo FitResidus(Histo const& h, GeneralFit& gfit);
+  static Histo FitFunction(Histo const& h, GeneralFit& gfit);
+  static int_4 Fit(Histo const & h, GeneralFit& gfit
+          ,GeneralFitData::FitErrType errtype=GeneralFitData::DefaultError
+          ,double errscale=1.,double errmin=1.);
+
+  // Residus et fonction fittees sur Histo2D
+  static Histo2D FitResidus(Histo2D const& h, GeneralFit& gfit);
+  static Histo2D FitFunction(Histo2D const& h, GeneralFit& gfit);
+  static int_4 Fit(Histo2D const & h, GeneralFit& gfit
+          ,GeneralFitData::FitErrType errtype=GeneralFitData::DefaultError
+          ,double errscale=1.,double errmin=0.);
+
+  // Residus et fonction fittees sur HProf
+  static inline Histo FitResidus(HProf const& h, GeneralFit& gfit)
+         {h.UpdateHisto(); return FitResidus((Histo const&) h,gfit);}
+  static inline Histo FitFunction(HProf const& h, GeneralFit& gfit)
+         {h.UpdateHisto(); return FitFunction((Histo const&) h,gfit);}
+  static int_4 Fit(HProf const & h, GeneralFit& gfit
+          ,GeneralFitData::FitErrType errtype=GeneralFitData::DefaultError
+          ,double errscale=1.,double errmin=0.)
+          {h.UpdateHisto();
+           return Fit((Histo const&) h,gfit,errtype,errscale,errmin);}
+
+  // Residus et fonction fittees sur GeneralFitData
+  static inline GeneralFitData FitResidus(GeneralFitData const& g, GeneralFit& gfit)
+                            {return g.FitResidus(gfit);}
+  static inline GeneralFitData FitFunction(GeneralFitData const& g, GeneralFit& gfit)
+                            {return g.FitFunction(gfit);}
+};
+
+//  Classe template pour ajustement sur tableaux (Vecteurs, Matrices)
+template <class T>
+class  ArrayFitter {
+public:
+  // Residus et fonction fittees sur matrix
+  static TMatrix<T> FitResidus(TMatrix<T> const & mtx, GeneralFit& gfit,
+			       double xorg=0.,double yorg=0.,double dx=1.,double dy=1.);
+  static TMatrix<T> FitFunction(TMatrix<T> const & mtx, GeneralFit& gfit,
+				double xorg=0.,double yorg=0.,double dx=1.,double dy=1.);
+  // Residus et fonction fittees sur vecteurs
+  static TVector<T> FitResidus(TVector<T> const & vec, GeneralFit& gfit,
+			       double xorg=0.,double dx=1.);
+  static TVector<T> FitFunction(TVector<T> const & vec, GeneralFit& gfit,
+				double xorg=0.,double dx=1.);
+};
+
+//  Classe template pour ajustement sur images
+template <class T>
+class  ImageFitter {
+public:
+  static Image<T> FitResidus(Image<T> const & mtx, GeneralFit& gfit);
+  static Image<T> FitFunction(Image<T> const & mtx, GeneralFit& gfit);
+};
+
+}  // Fin du namespace
+
+
+#endif   // OBJFITTER_SEEN
Index: /tags/V_Dec2002/SophyaLib/NTools/objlist.list
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/objlist.list	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/objlist.list	(revision 2309)
@@ -0,0 +1,30 @@
+FSAppIrrSmpl.o
+cimage.o
+cspline.o
+datatypes.o
+dates.o
+datime.o
+difeq.o
+dynccd.o
+fct1dfit.o
+fct2dfit.o
+fftmayer_r4.o
+fftmayer_r8.o
+fftmserver.o
+fftpackc.o
+fftpserver.o
+fftservintf.o
+generaldata.o
+generalfit.o
+integ.o
+matxop.o
+median.o
+nbmath.o
+nbtri.o
+ntoolsinit.o
+objfitter.o
+perandom.o
+poly.o
+rk4cdifeq.o
+simplesort.o
+tabmath.o
Index: /tags/V_Dec2002/SophyaLib/NTools/pclassids.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/pclassids.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/pclassids.h	(revision 2309)
@@ -0,0 +1,55 @@
+// This may look like C code, but it is really -*- C++ -*-
+
+#ifndef PEIDA_CLASS_ID_H
+#define PEIDA_CLASS_ID_H
+
+// ClassIds pour Peida. Il est possible d'en definir d'autres, mais on regroupe
+// ici toutes les classIds pour eviter des collisions.
+//
+// ClassIds pour utilisateur >= 0x4000
+//
+
+enum PeidaClassIds {
+
+   ClassId_Unknown    = 0x0000,
+//  Module Outils++
+   ClassId_Poly1    = 0x0101,
+   ClassId_Poly2    = 0x0102,
+   ClassId_Matrix   = 0x0103,
+   ClassId_Vector   = 0x0104,
+   ClassId_DVList   = 0x0105,
+
+   ClassId_PMatrixF = 0x0110,
+   ClassId_PMatrixD = 0x0111,
+   ClassId_PVectorF = 0x0112,
+   ClassId_PVectorD = 0x0113,
+
+   ClassId_Histo1D  = 0x0201,
+   ClassId_Histo2D  = 0x0202,
+   ClassId_HProf    = 0x0203,
+   ClassId_NTuple   = 0x0210,
+   ClassId_XNTuple  = 0x0211,
+
+   ClassId_GeneralFitData  = 0x0290,
+
+//  Module Images++
+   ClassId_Image    = 0x0300,    // classId = 0x0300 + ImageType pour images types   
+   ClassId_ZFidu    = 0x0330,
+   ClassId_Voronoi  = 0x0340,
+   ClassId_RLEImage = 0x0350,
+
+//  Module StarReco++
+   ClassId_StarList = 0x0500,
+   ClassId_Transfo  = 0x0501,
+   ClassId_PSF      = 0x0510,
+   ClassId_Star     = 0x1000,     // Et ce qui suit, classId = 0x1000 + StarType
+
+//  Module Samba
+   ClassId_SphereTetaPhi  = 0x0611,
+   ClassId_SphereGorski   = 0x0612,
+   ClassId_LocalMap       = 0x0601,
+   ClassId_Scan           = 0x0631,
+   ClassId_MainLobe       = 0x0641
+};
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/peida.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/peida.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/peida.h	(revision 2309)
@@ -0,0 +1,17 @@
+// This may look like C code, but it is really -*- C++ -*-
+
+#ifndef PEIDA_SEEN
+#define PEIDA_SEEN
+
+#include "machdefs.h"
+#include "utils.h"
+#include "perrors.h"
+#include "pexceptions.h"
+#include "fmath.h"
+
+#ifdef __mac__
+#include "unixmac.h"
+#endif
+
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/pemath.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/pemath.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/pemath.h	(revision 2309)
@@ -0,0 +1,26 @@
+/* quelques fonctions mathematiques et constantes utiles */
+/*                                         cmv  23/06/94 */
+
+#ifndef PEMATH_SEEN
+#define PEMATH_SEEN
+
+#include "machdefs.h"
+
+#define  Pi     (double) (3.1415926535898)    /* c'est Pi */
+#define  DeuxPi (double) (6.2831853071796)    /* c'est 2*Pi */
+#define  SPi    (double) (1.772453850906)     /* c'est sqrt(Pi) */
+#define  S2Pi   (double) (2.506628274631)     /* c'est sqrt(2*Pi) */
+#define  Rac2   (double) (1.414213562373)     /* c'est sqrt(2) */
+#define  Log2   (double) (0.301029995664)     /* c'est log10(2) */
+#define  LnPi   (double) (1.14472988585)      /* c'est ln(Pi) */
+#define  LgPi   (double) (0.497149872694)     /* c'est log10(Pi) */
+#define  Ln10   (double) (2.302585092994)     /* c'est ln(10) */
+#define  DftoDm (double) (1.085736204758)     /* c'est 2.5/ln(10) */
+#define  Hln2pi (double) 0.918938533205       /* c'est Ln(2*pi)/2 */
+#define  JourSec (float) (86400.)       /* nombre de secondes dans 24H */
+#define  AnSec  (int) (31557600)   /* nombre de secondes dans 365.25 jours */
+#define  GRAND  (float) (1.e+35)
+#define  GRAND2 (double) (1.e+35)
+#define  IGRAND (int_4) (2147483647)
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/perandom.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/perandom.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/perandom.cc	(revision 2309)
@@ -0,0 +1,216 @@
+#include "machdefs.h"
+#include "pexceptions.h"
+#include "perandom.h"
+#include "pemath.h"
+#include <iostream.h>
+
+////////////////////////////////////////////////////////////////////////////
+//++
+// Class	FunRan
+// Lib  Outils++ 
+// include	perandom.h
+//
+//	Tirage aleatoire sur un histogramme 1D.
+//--
+
+//++
+FunRan::FunRan(FunRan::Func f, r_8 xMin, r_8 xMax, int_4 nBin)
+//
+//	Createur.
+//--
+: Histo(xMin, xMax, nBin)
+{
+  (*this)(0) = f(BinLowEdge(0));
+  for(int_4 i=1; i<nBin; i++)
+    (*this)(i) = (*this)(i-1) + f(BinLowEdge(i));
+    
+  for(int_4 j=0; j<nBin; j++)
+    (*this)(j) /= (*this)(nBin-1);
+  END_CONSTRUCTOR
+}
+
+//++
+FunRan::FunRan(r_8 *tab, int_4 nBin)
+//
+//	Createur.
+//--
+: Histo(0, (r_8)(nBin), nBin)
+{
+  (*this)(0) = tab[0];
+  for(int_4 i=1; i<nBin; i++)
+    (*this)(i) = (*this)(i-1) + tab[i];
+
+  if ((*this)(nBin-1) == 0) {
+    cerr << "FunRan::FunRan : sum(prob) = 0" << endl;
+    exit(-1);
+  }
+
+  for(int_4 j=0; j<nBin; j++)
+    (*this)(j) /= (*this)(nBin-1);
+  END_CONSTRUCTOR
+}
+
+FunRan::FunRan(r_8 *tab, int_4 nBin, r_8 xMin, r_8 xMax)
+: Histo(xMin, xMax, nBin)
+{
+  (*this)(0) = tab[0];
+  for(int_4 i=1; i<nBin; i++)
+    (*this)(i) = (*this)(i-1) + tab[i];
+
+  if ((*this)(nBin-1) == 0) {
+    cerr << "FunRan::FunRan : sum(prob) = 0" << endl;
+    exit(-1);
+  }
+
+  for(int_4 j=0; j<nBin; j++)
+    (*this)(j) /= (*this)(nBin-1);
+  END_CONSTRUCTOR
+}
+
+//++
+int_4 FunRan::BinRandom()
+//
+//	Tirage avec retour du numero de bin.
+//--
+{
+  r_8 z=drand01();
+  if (z <= 0) return 0;
+  if (z >= 1) return mBins-1;
+  
+  // recherche du premier bin plus grand que z
+  int_4 iBin = 0;
+  for (; iBin<mBins; iBin++)
+    if (z < (*this)(iBin)) break;
+
+  return iBin;
+}
+
+//++
+r_8 FunRan::Random()
+//
+//	Tirage avec retour abscisse du bin interpole.
+//--
+{
+  r_8 z=drand01();
+  if (z <= 0) return mMin;
+  if (z >= 1) return mMax;
+  // cas z <= tab[0] 
+  if (z <= (*this)(0)) {
+    r_8 t = mMin + binWidth/(*this)(0) * z;
+    return t;
+  }
+
+  // recherche du premier bin plus grand que z
+  int_4 iBin = 0;
+  for (; iBin<mBins; iBin++)
+    if (z < (*this)(iBin)) break;
+
+  // interpolation pour trouver la valeur du tirage aleatoire
+  r_8 t1 = (*this)(iBin-1);
+  r_8 x1 = BinLowEdge(iBin-1);
+  r_8 t2 = (*this)(iBin);
+  r_8 x2 = x1 + binWidth;
+  r_8 t = x1 + (x2-x1) / (t2-t1) * (z-t1);
+  if (t < mMin) t = mMin;
+  if (t > mMax) t = mMax;
+  return(t);
+}
+
+                   
+
+////////////////////////////////////////////////////////////////////////////
+//++
+// Class	FunRan2D
+// Lib  Outils++ 
+// include	perandom.h
+//
+//	Tirage aleatoire sur un histogramme 2D.
+//--
+
+//++
+FunRan2D::FunRan2D(r_8 *tab, int_4 nBinX, int_4 nBinY)
+//
+//	Createur.
+//--
+{
+  // Tirage en X, somme sur les Y.
+   r_8* tabX = new r_8[nBinX];
+   for (int_4 i=0; i<nBinX; i++) {
+     tabX[i] = 0;
+     for (int_4 j=0; j<nBinY; j++) {
+       tabX[i] += tab[i*nBinY +j];
+     }
+   }
+   ranX = new FunRan(tabX, nBinX);
+   delete[] tabX;
+   
+   ranY = new(FunRan*[nBinX]);
+   
+   for (int_4 k=0; k<nBinX; k++)
+      ranY[k] = new FunRan(tab + nBinY*k, nBinY);
+   
+   nx = nBinX;
+  END_CONSTRUCTOR
+}
+
+//++
+FunRan2D::FunRan2D(r_8 **tab, int_4 nBinX, int_4 nBinY)
+//
+//	Createur.
+//--
+{
+  // Tirage en X, somme sur les Y.
+   r_8* tabX = new r_8[nBinX];
+   for (int_4 i=0; i<nBinX; i++) {
+     tabX[i] = 0;
+     for (int_4 j=0; j<nBinY; j++) {
+       tabX[i] += tab[i][j];
+     }
+   }
+   ranX = new FunRan(tabX, nBinX);
+   
+   ranY = new(FunRan*[nBinX]);
+   
+   for (int_4 k=0; k<nBinX; k++)
+    if (tabX[k] != 0) 
+      ranY[k] = new FunRan(tab[k], nBinY);
+    else ranY[k] = NULL;
+   
+   delete[] tabX;
+   nx = nBinX;
+  END_CONSTRUCTOR
+}
+
+FunRan2D::~FunRan2D()
+{
+  for (int_4 i=nx-1; i>=0; i--)
+    delete ranY[i];
+    
+  delete[] ranY;
+  
+  delete ranX;
+}
+
+//++
+void FunRan2D::BinRandom(int_4& x, int_4& y)
+//
+//	Tirage avec retour du numeros de bin.
+//--
+{
+  x = ranX->BinRandom();
+  //  FAILNIL(ranY[x]);  Ne compile pas $CHECK$ Reza 22/04/99
+  y = ranY[x]->BinRandom();
+}
+
+//++
+void FunRan2D::Random(r_8& x, r_8& y)
+//
+//	Tirage avec retour abscisse et ordonnee
+//	du bin interpole.
+//--
+{
+  x = ranX->Random();
+  int_4 i = int_4(ceil(x));
+  //  FAILNIL(ranY[i]);  Ne compile pas $CHECK$ Reza 22/04/99
+  y = ranY[i]->Random();
+}
Index: /tags/V_Dec2002/SophyaLib/NTools/perandom.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/perandom.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/perandom.h	(revision 2309)
@@ -0,0 +1,45 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Nombres aleatoires pour Peida.
+//        C. Magneville   1996-2000
+// DAPNIA/SPP (Saclay) / CEA    LAL - IN2P3/CNRS  (Orsay)
+
+#ifndef PERANDOM_SEEN
+#define PERANDOM_SEEN
+
+#include "machdefs.h"
+#include <stdlib.h>
+#include "histos.h"
+#include "nbrandom.h"
+
+namespace SOPHYA {  
+
+class FunRan : public Histo {
+public:
+  typedef r_8 (*Func)(r_8);
+  FunRan(Func f, r_8 xMin=0.0, r_8 xMax=1.0, int_4 nBin=100);
+  FunRan(r_8 *tab, int_4 nBin);
+  FunRan(r_8 *tab, int_4 nBin, r_8 xMin, r_8 xMax);
+  void IFunRan(r_8 *tab, int_4 nBin);
+  r_8 Random(void);
+  int_4 BinRandom(void);
+};
+
+class FunRan2D  {
+public:
+//  typedef r_8 (*Func)(r_8, r_8);
+//  FunRan2D(Func f, r_8 xMin=0.0, r_8 xMax=1.0, int_4 nBinX=100,
+//                   r_8 yMin=0.0, r_8 yMax=1.0, int_4 nBinY=100);
+  FunRan2D(r_8 *tab, int_4 nBinX, int_4 nBinY);
+  FunRan2D(r_8 **tab, int_4 nBinX, int_4 nBinY);
+  ~FunRan2D();
+  void Random(r_8& x, r_8& y);
+  void BinRandom(int_4& x, int_4& y);
+private:
+  FunRan* ranX;
+  FunRan** ranY;
+  int_4 nx;
+};
+
+} // namespace SOPHYA
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/poly.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/poly.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/poly.cc	(revision 2309)
@@ -0,0 +1,795 @@
+#include "machdefs.h"
+#include "poly.h"
+#include "linfit.h"
+#include "fioarr.h"
+
+////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::Poly
+  \ingroup NTools
+  One dimensional polynomials class.
+*/
+
+//! Constructor
+/*! Create a 1D polynomial of degre \b degre */
+Poly::Poly(int degre)
+: TVector<r_8>(degre+1), dirty(0), deg(0)
+{
+  END_CONSTRUCTOR
+}
+
+//! Constructor by copy
+Poly::Poly(Poly const& a)
+:TVector<r_8>(a), dirty(a.dirty), deg(a.deg)
+{
+  END_CONSTRUCTOR
+}
+
+//! update degre
+/*! update degre (that could be changed after operations) */
+void Poly::UpdateDeg() const
+{
+  int i = NElts()-1;
+  while (Element(i) == 0 && i>0) i--;
+
+  (int&) deg = i;          // bientot mutable dans ANSI C++ 
+  (int&) dirty = 0;
+}
+
+//! compute value P(\b x)
+double Poly::operator()(double x) const
+{
+  UpdateDegIfDirty();
+  double res = Element(deg);
+  for (int i=deg-1; i>=0; i--) {
+    res *= x;
+    res += Element(i);
+  }
+  return res;
+}
+
+//! Replace p(x) by its derivate
+void Poly::Derivate()
+{
+  UpdateDegIfDirty();
+  if (deg == 0) { Element(0) = 0; return;}
+  for (int i=1; i<=deg; i++)
+    Element(i-1) = Element(i)*i;
+  Element(deg) = 0;
+  deg--;
+}
+
+
+//! Return the derivate in \b der(x)
+void Poly::Derivate(Poly& der) const
+{
+  UpdateDegIfDirty();
+  der.Realloc(deg);
+//  der.Zero();    // on sait que Realloc met a zero le reste.
+  for (int i=1; i<=deg; i++)
+    der.Element(i-1) = Element(i)*i;
+}
+
+
+//! Return the roots of the polynomial into \b roots
+/*!
+  This works until degre 2
+  \return the number of roots
+*/
+int Poly::Roots(TVector<r_8>& roots) const
+{
+  UpdateDegIfDirty();
+
+  switch (deg)
+    {
+    case 0 :           // degre 0
+      return 0;
+    case 1 :           // degre 1
+      roots.Realloc(1);
+      return Root1(roots(0));
+    case 2 :           // degre 2
+      roots.Realloc(2);
+      return Root2(roots(0),roots(1));
+    default :
+      THROW(parmErr);
+    }
+}
+
+
+//! Return root \b r for a degre 1 polynomial
+/*! \return return 1 if succes, 0 if not */
+int Poly::Root1(double& r) const
+{
+  UpdateDegIfDirty();
+  if (deg != 1) THROW(sizeMismatchErr);
+
+  if (Element(1) == 0) return 0;
+  r = -Element(0)/Element(1);
+  return 1;
+}
+
+//! Return roots \b r1 and \b r2 for a degre 2 polynomial
+/*! \return return the number of roots found */
+int Poly::Root2(double& r1, double& r2) const
+{
+  UpdateDegIfDirty();
+  if (deg != 2) THROW(sizeMismatchErr);
+
+  double delta = Element(1)*Element(1) - 4*Element(0)*Element(2);
+  if (delta < 0) return 0;
+  if (delta == 0) {
+    r1 = r2 = -Element(1)/2/Element(0);
+    return 1;
+  }
+  r1 = (-Element(1) - sqrt(delta))/2/Element(0);
+  r2 = (-Element(1) + sqrt(delta))/2/Element(0);
+  return 2;
+}
+
+//! Operator P(x) = a(x)
+Poly& Poly::operator = (Poly const& a)
+{
+  if (this == &a) return *this;
+  TVector<r_8>::operator=(a);
+
+  UpdateDeg();
+  return *this;
+}
+
+//! Perform P(x) += b(x)
+Poly& Poly::operator += (Poly const& b)
+{
+  UpdateDegIfDirty();
+  b.UpdateDegIfDirty();
+
+  if (b.deg > deg) Realloc(b.deg);
+
+  int n = (deg > b.deg) ? deg : b.deg;
+  for (int i=0; i<=n; i++) Element(i) += b.Element(i);
+
+  UpdateDeg();
+  return *this;
+}
+
+//! Perform P(x) -= b(x)
+Poly& Poly::operator -= (Poly const& b)
+{
+  UpdateDegIfDirty();
+  b.UpdateDegIfDirty();
+
+  if (b.deg > deg) Realloc(b.deg);
+
+  int n = (deg > b.deg) ? deg : b.deg;
+  for (int i=0; i<=n; i++) Element(i) -= b.Element(i);
+
+  UpdateDeg();
+  return *this;
+}
+
+//! Perform P(x) *= b(x)
+Poly& Poly::operator *= (double a)
+{
+  UpdateDegIfDirty();
+  for (int i=0; i<=deg; i++) Element(i) *= a;
+  return *this;
+}
+
+//! Return P(x) = *this(x) * b(x)
+Poly Poly::Mult(Poly const& b) const
+{
+Poly c(deg + b.deg);
+  UpdateDegIfDirty();
+  b.UpdateDegIfDirty();
+
+  c.deg = deg + b.deg;
+
+  for (int i=0; i<=c.deg; i++) {
+    c[i] = 0;
+    int kmin = (i <= deg) ? 0 : i - deg;
+    int kmax = (i <= deg) ? i : deg;
+    for (int k=kmin; k<=kmax; k++)
+      c[i] += (*this)[k] * b[i-k];
+  }
+return c;
+}
+
+//! Print on stream \b s
+void Poly::Print(ostream& s, sa_size_t , bool, bool ) const
+{
+  UpdateDegIfDirty();
+  int nz=0;
+  for (int i = deg; i>=0; i--) {
+    if ((*this)[i] != 0) {
+      nz = 1;
+      if (i < deg && (*this)[i] > 0) s << "+";
+      s << (*this)[i];
+      if (i == 1) s << "*X ";
+      if (i > 1) s << "*X^" << i << " ";
+    }
+  }
+  if (!nz) s << " 0 ";
+}
+
+//! Fit datas by a polynomial
+/*!
+  Fit y(x) by a polynimial P(x)
+  \param x : x datas
+  \param y : y datas
+  \param degre : degre of the polynomial P(x) to be fitted
+  \warning result is stored in the current object
+  \return return chisquare
+*/
+double Poly::Fit(TVector<r_8> const& x, TVector<r_8> const& y, int degre)
+{
+  int n = x.NElts();
+  if (n != (int)y.NElts()) THROW(sizeMismatchErr);
+
+  Realloc(degre);
+
+  TMatrix<r_8> a(degre+1, n);
+
+  for (int c=0; c<n; c++) {
+    double xpow = 1.0;
+    for (int l=0; l<=degre; l++) {
+      a(l,c) = xpow;
+      xpow *= x(c);
+    }
+  }
+
+  LinFitter<r_8> lf;
+  double rc = lf.LinFit(a,y,(TVector<r_8>&)*this);
+  UpdateDeg();
+  return rc;
+}
+
+//! Fit datas with errors by a polynomial
+/*!
+  Fit y(x) by a polynimial P(x)
+  \param x : x datas
+  \param y : y datas
+  \param erry2 : errors squared on y
+  \param degre : degre of the polynomial P(x) to be fitted
+  \warning result is stored in the current object
+  \return \b errcoeff : errors on the coefficients
+  \return return chisquare
+*/
+double Poly::Fit(TVector<r_8> const& x, TVector<r_8> const& y,
+       TVector<r_8> const& erry2, int degre,TVector<r_8>& errCoef)
+{
+  int n = x.NElts();
+  if (n != (int)y.NElts()) THROW(sizeMismatchErr);
+  if (n != (int)erry2.NElts()) THROW(sizeMismatchErr);
+
+  Realloc(degre);
+  errCoef.Realloc(degre+1);
+
+  TMatrix<r_8> a(degre+1, n);
+
+  for (int c=0; c<n; c++) {
+    double xpow = 1.0;
+    for (int l=0; l<=degre; l++) {
+      a(l,c) = xpow;
+      xpow *= x(c);
+    }
+  }
+
+  LinFitter<r_8> lf;
+  double rc = lf.LinFit(a,y,erry2,(TVector<r_8>&)*this,errCoef);
+  UpdateDeg();
+  return rc;
+}
+
+
+//! Return the polynomial at power \b n : ( \f$ P(x)^n \f$ )
+Poly Poly::power(int n) const // a accelerer !!!
+{
+  if (n < 0) THROW(rangeCheckErr);
+  if (n == 0) { Poly r(0); r[0] = 1; return r;}
+  if (n == 1) { return *this; }
+  return *this * power(n-1);
+}
+
+//! Substitue polynomial and return P\f$ (b(x)) \f$
+Poly Poly::operator() (Poly const& b) const
+{
+  Poly c(b.Degre()*Degre());
+  for (int i=0; i<= Degre(); i++)
+    c += (*this)[i] * b.power(i);
+  return c;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+//! For persistance management
+void ObjFileIO<Poly>::ReadSelf(PInPersist& is)
+{
+if(dobj==NULL) dobj=new Poly;
+int_4 dg;
+is >> dg;
+dobj->Realloc(dg,true);
+is >> *((TVector<r_8> *) dobj);
+dobj->UpdateDeg();
+}
+
+//! For persistance management
+void ObjFileIO<Poly>::WriteSelf(POutPersist& os) const
+{
+if(dobj == NULL) return;
+dobj->UpdateDegIfDirty();
+dobj->Realloc(dobj->deg,true);
+os << dobj->deg;
+os << *((TVector<r_8> *) dobj);
+}
+
+//////////////////////////////////////////////////////////////////////////
+/*! \ingroup NTools
+  \fn binomial(int,int)
+  Return the binomial coefficient \f$ {C_n}^p \f$.
+*/
+int binomial(int n, int p)
+{
+  int c = 1;
+  for (int i=n-p+1; i<=n; i++) c *= i;
+  for (int j=2; j<=p; j++) c /= j;
+  return c;
+}
+
+
+////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::Poly2
+  \ingroup NTools
+  Two dimensional polynomials class.
+*/
+
+//! Constructor of 2D polynomial of degres \b degreX \b degreY
+Poly2::Poly2(int degreX, int degreY)
+:TVector<r_8>((degreX+1)*(degreY+1)), dirty(0),
+ maxDegX(degreX), maxDegY(degreY), degX(0), degY(0), deg(0)
+{
+  END_CONSTRUCTOR
+}
+
+//! Constructor of 2D polynomial \f$ P(x,y) = px(x) * py(y) \f$
+Poly2::Poly2(Poly const& polX, Poly const& polY)
+:TVector<r_8>((polX.Degre()+1)*(polY.Degre()+1)), dirty(0),
+ maxDegX(polX.Degre()), maxDegY(polY.Degre()),
+ degX(polX.Degre()), degY(polY.Degre()), deg(degX+degY)
+{
+  for (int i=0; i<=degX; i++)
+    for (int j=0; j<=degY; j++)
+      Coef(i,j) = polX[i]*polY[j];
+  END_CONSTRUCTOR
+}
+
+//! Constructor by copy
+Poly2::Poly2(Poly2 const& a)
+:TVector<r_8>(a), dirty(a.dirty),
+ maxDegX(a.maxDegX), maxDegY(a.maxDegY),
+ degX(a.degX), degY(a.degY), deg(a.deg)
+{
+  END_CONSTRUCTOR
+}
+
+//! Operator P(x) = a(x)
+Poly2& Poly2::operator = (Poly2 const& a)
+{
+  if (this == &a) return *this;
+  if (maxDegX < a.DegX() || maxDegY < a.DegY())
+    Realloc(a.DegX(), a.DegY());
+
+
+  for (int i=0; i<= maxDegX; i++)
+    for (int j=0; j<= maxDegY; j++)
+      Coef(i,j) = a.Coef(i,j);
+
+  UpdateDeg();
+  return *this;
+}
+
+//! Re-allocate space for 2D polynomial with partial degres \b degreX \b degreY
+void Poly2::Realloc(int degreX, int degreY)
+{
+  UpdateDegIfDirty();
+  Poly2 tmp(*this);
+  TVector<r_8>::Realloc((degreX+1)*(degreY+1));
+  DataBlock().Reset();
+  maxDegX = degreX;
+  maxDegY = degreY;
+
+// Attention - Reza 30/09/99
+// il faut prendre le min en degre du polynome de depart et le nouveau
+  int cdegx = (tmp.degX < degreX) ? tmp.degX : degreX;
+  int cdegy = (tmp.degY < degreY) ? tmp.degY : degreY;
+  for (int i=0; i<= cdegx; i++)
+    for (int j=0; j<= cdegy; j++)
+      Coef(i,j) = tmp.Coef(i,j);
+}
+
+
+//! update degres
+/*! update degres (that could be changed after operations) */
+void Poly2::UpdateDeg() const
+{
+  (int&)degX=(int&)degY=(int&)deg=0;
+
+  for (int dx=0; dx<=maxDegX; dx++)
+    for (int dy=0; dy<=maxDegY; dy++)
+      if (Coef(dx,dy) != 0) {
+        if (dx > degX) (int&)degX = dx;
+        if (dy > degY) (int&)degY = dy;
+        if (dx+dy > deg) (int&)deg = dx+dy;
+      }
+
+  (int&)dirty = 0;
+}
+
+//! Return P(\b x, \b y)
+double Poly2::operator()(double x, double y) const
+{
+  UpdateDegIfDirty();
+  double res = 0;
+  double xPow = 1;
+  for (int dx=0; dx<=maxDegX; dx++) {
+    double yPow = 1;
+    for (int dy=0; dy<=maxDegY; dy++) {
+      res += Coef(dx,dy) * xPow * yPow;
+      yPow *= y;
+    }
+    xPow *= x;
+  }
+  return res;
+}
+
+//! Fit datas by a polynomial
+/*!
+  Fit z(x,y) by a polynimial P(x,y)
+  \param x : x datas
+  \param y : y datas
+  \param z : z datas
+  \param degreX : partial degre on X
+  \param degreY : partial degre on Y
+  \warning result is stored in the current object
+  \return return chisquare
+*/
+double Poly2::Fit(TVector<r_8> const& x, TVector<r_8> const& y,
+                 TVector<r_8> const& z, int degreX, int degreY)
+{
+  int n = x.NElts();
+  if (n != (int)y.NElts()) THROW(sizeMismatchErr);
+  if (n != (int)z.NElts()) THROW(sizeMismatchErr);
+
+  Realloc(degreX, degreY);
+
+  TMatrix<r_8> a((degreX+1)*(degreY+1), n);
+
+  for (int c=0; c<n; c++) {
+    double xPow = 1.0;
+    for (int dx = 0; dx <= degreX; dx++) {
+      double yPow = 1.0;
+      for (int dy = 0; dy <= degreY; dy++) {
+        a(IndCoef(dx,dy), c) = xPow*yPow;
+        yPow *= y(c);
+      }
+      xPow *= x(c);
+    }
+  }
+
+  LinFitter<r_8> lf;
+  double rc = lf.LinFit(a,z,(TVector<r_8>&)*this);
+  UpdateDeg();
+  return rc;
+}
+
+//! Fit datas with errors by a polynomial
+/*!
+  Fit z(x,y) by a polynimial P(x,y)
+  \param x : x datas
+  \param y : y datas
+  \param z : z datas
+  \param errz2 : errors squared on z
+  \param degreX : partial degre on X
+  \param degreY : partial degre on Y
+  \warning result is stored in the current object
+  \return \b errcoeff : errors on the coefficients
+  \return return chisquare
+*/
+double Poly2::Fit(TVector<r_8> const& x, TVector<r_8> const& y, TVector<r_8> const& z,
+                  TVector<r_8> const& errz2, int degreX, int degreY,
+                  TVector<r_8>& errCoef)
+{
+  int n = x.NElts();
+  if (n != (int)y.NElts()) THROW(sizeMismatchErr);
+  if (n != (int)z.NElts()) THROW(sizeMismatchErr);
+  if (n != (int)errz2.NElts()) THROW(sizeMismatchErr);
+
+  Realloc(degreX, degreY);
+  errCoef.Realloc((degreX+1)*(degreY+1));
+
+  TMatrix<r_8> a((degreX+1)*(degreY+1), n);
+
+  for (int c=0; c<n; c++) {
+    double xPow = 1.0;
+    for (int dx = 0; dx <= degreX; dx++) {
+      double yPow = 1.0;
+      for (int dy = 0; dy <= degreY; dy++) {
+        a(IndCoef(dx,dy), c) = xPow*yPow;
+        yPow *= y(c);
+      }
+      xPow *= x(c);
+    }
+  }
+
+  LinFitter<r_8> lf;
+  double rc = lf.LinFit(a,z,errz2,(TVector<r_8>&)*this,errCoef);
+  UpdateDeg();
+  return rc;
+}
+
+//! Fit datas by a polynomial
+/*!
+  Fit z(x,y) by a polynimial P(x,y)
+  \param x : x datas
+  \param y : y datas
+  \param z : z datas
+  \param degre : total degre
+  \warning result is stored in the current object
+  \return return chisquare
+*/
+double Poly2::Fit(TVector<r_8> const& x, TVector<r_8> const& y,
+                              TVector<r_8> const& z, int degre)
+{
+  int n = x.NElts();
+  if (n != (int)y.NElts()) THROW(sizeMismatchErr);
+  if (n != (int)z.NElts()) THROW(sizeMismatchErr);
+
+  Realloc(degre, degre);   // certains vaudront 0, impose.
+
+  TMatrix<r_8> a((degre+1)*(degre+2)/2, n);
+  TVector<r_8> cf((degre+1)*(degre+2)/2);
+#define C_INDEX(i,j) ((i) + (j)*(2*degre+3-(j))/2)
+
+  for (int c=0; c<n; c++) {
+    double xPow = 1.0;
+    for (int dx = 0; dx <= degre; dx++) {
+      double yPow = 1.0;
+      for (int dy = 0; dy <= degre; dy++) {
+        if (dy+dx <= degre)
+          a(C_INDEX(dx,dy), c) = xPow*yPow;
+        yPow *= y(c);
+      }
+      xPow *= x(c);
+    }
+  }
+
+  LinFitter<r_8> lf;
+  double rc = lf.LinFit(a,z,cf);
+
+  for (int dx = 0; dx <= degre; dx++)
+    for (int dy = 0; dy <= degre; dy++)
+      if (dx+dy <= degre)
+        Coef(dx,dy) = cf(C_INDEX(dx,dy));
+      else
+        Coef(dx,dy) = 0;
+
+  UpdateDeg();
+  return rc;
+}
+
+//! Fit datas with errors by a polynomial
+/*!
+  Fit z(x,y) by a polynimial P(x,y)
+  \param x : x datas
+  \param y : y datas
+  \param z : z datas
+  \param errz2 : errors squared on z
+  \param degre : total degre
+  \warning result is stored in the current object
+  \return \b errcoeff : errors on the coefficients
+  \return return chisquare
+*/
+double Poly2::Fit(TVector<r_8> const& x, TVector<r_8> const& y,
+               TVector<r_8> const& z,TVector<r_8> const& errz2,
+                              int degre, TVector<r_8>& errCoef)
+{
+  int n = x.NElts();
+  if (n != (int)y.NElts()) THROW(sizeMismatchErr);
+  if (n != (int)z.NElts()) THROW(sizeMismatchErr);
+  if (n != (int)errz2.NElts()) THROW(sizeMismatchErr);
+
+  Realloc(degre, degre);
+  errCoef.Realloc((degre+1)*(degre+1));
+#define C_INDEX(i,j) ((i) + (j)*(2*degre+3-(j))/2)
+
+  TMatrix<r_8> a((degre+1)*(degre+2)/2, n);
+  TVector<r_8> cf((degre+1)*(degre+2)/2);
+  TVector<r_8> ecf((degre+1)*(degre+2)/2);
+
+  for (int c=0; c<n; c++) {
+    double xPow = 1.0;
+    for (int dx = 0; dx <= degre; dx++) {
+      double yPow = 1.0;
+      for (int dy = 0; dy <= degre; dy++) {
+        if (dy+dx <= degre)
+          a(C_INDEX(dx,dy), c) = xPow*yPow;
+        yPow *= y(c);
+      }
+      xPow *= x(c);
+    }
+  }
+
+  LinFitter<r_8> lf;
+  double rc = lf.LinFit(a,z,errz2,cf,ecf);
+
+
+  for (int dx = 0; dx <= degre; dx++)
+    for (int dy = 0; dy <= degre; dy++)
+      if (dx+dy <= degre) {
+        Coef(dx,dy) = cf(C_INDEX(dx,dy));
+        errCoef(IndCoef(dx,dy)) = ecf(C_INDEX(dx,dy));
+      } else {
+        Coef(dx,dy) = 0;
+        errCoef(IndCoef(dx,dy)) = 0;
+      }
+  UpdateDeg();
+  return rc;
+}
+
+//! Print on stream \b s
+void Poly2::Print(ostream& s, sa_size_t , bool, bool ) const
+{
+  UpdateDegIfDirty();
+  int nz=0;
+  int notfirst=0;
+  for (int dx = degX; dx>=0; dx--)
+    for (int dy= degY; dy>=0; dy--) {
+      double c = Coef(dx,dy);
+      if (c != 0) {
+        nz = 1;
+        if (notfirst && c > 0) {
+          s << "+";
+          notfirst = 1;
+        }
+        s << c << " ";
+        if (dx == 1) s << "* X ";
+        if (dx > 1) s << "* X^" << dx << " ";
+        if (dy == 1) s << "* Y ";
+        if (dy > 1) s << "* Y^" << dy << " ";
+        s << endl;
+    }
+  }
+  if (!nz) s << " 0 ";
+}
+
+//! Operator: return P(x) = *this(x) + b(x)
+Poly2& Poly2::operator += (Poly2 const& b)
+{
+  if (maxDegX < b.DegX() || maxDegY < b.DegY())
+    Realloc(b.DegX(),b.DegY());
+
+  UpdateDegIfDirty();
+
+  int mx = b.DegX();
+  int my = b.DegY();
+  for (int i=0; i<= mx; i++)
+    for (int j=0; j<= my; j++)
+      Coef(i,j) += b.Coef(i,j);
+
+  UpdateDeg();
+  return *this;
+}
+
+//! Operator: return P(x) = *this(x) - b(x)
+Poly2& Poly2::operator -= (Poly2 const& b)
+{
+  if (maxDegX < b.DegX() || maxDegY < b.DegY())
+    Realloc(b.DegX(),b.DegY());
+
+  UpdateDegIfDirty();
+
+  int mx = b.DegX();
+  int my = b.DegY();
+  for (int i=0; i<= mx; i++)
+    for (int j=0; j<= my; j++)
+      Coef(i,j) -= b.Coef(i,j);
+
+  UpdateDeg();
+  return *this;
+}
+
+//! Operator: return P(x) = *this(x) * a
+Poly2& Poly2::operator *= (double a)
+{
+  for (uint_4 i=0; i<NElts(); i++) Element(i) *= a;
+  return *this;
+}
+
+//! Operator: return P(x) = *this(x) * b(x)
+Poly2 Poly2::Mult(Poly2 const& b) const
+{
+  Poly2 c(DegX() + b.DegX(), DegY() + b.DegY());
+  UpdateDegIfDirty();
+  b.UpdateDegIfDirty();
+
+  for (int i=0; i<=DegX(); i++)
+    for (int j=0; j<=DegY(); j++)
+      for (int k=0; k<=b.DegX(); k++)
+        for (int l=0; l<=b.DegY(); l++)
+          c.Coef(i+k,j+l) += Coef(i,j)*b.Coef(k,l);
+  return c;
+}
+
+//! Return \f$ P(x,y)^n \f$
+Poly2 Poly2::power(int n) const
+{
+  if (n < 0) THROW(rangeCheckErr);
+  if (n == 0) { Poly2 r(0); r.Coef(0,0) = 1; return r;}
+  if (n == 1) { return *this; }
+  return *this * power(n-1);
+}
+
+
+//! substitute and return \f$ P(a(x),b(x)) \f$
+Poly2 Poly2::operator() (Poly const& a, Poly const& b) const
+{
+  UpdateDegIfDirty();
+  Poly2 c(maxDegX*a.Degre(), maxDegY*b.Degre());
+
+  for (int i=0; i<= degX; i++)
+    for (int j=0; j<= degY; j++) {
+      Poly2 d(a.power(i), b.power(j));
+      c += Coef(i,j) * d;
+    }
+
+  return c;
+}
+
+//! substitute and return 2D polynomial \f$ P(a(x,y)) \f$, P is a 1D polynomial
+Poly2 Poly::operator() (Poly2 const& a) const
+{
+  Poly2 c(a.MaxDegX()*Degre(), a.MaxDegY()*Degre());
+
+  for (int i=0; i<= Degre(); i++)
+    c += (*this)[i] * a.power(i);
+  return c;
+}
+
+//////////////////////////////////////////////////////////////////////////
+//! For persistance management
+void ObjFileIO<Poly2>::ReadSelf(PInPersist& is)
+{
+if(dobj==NULL) dobj=new Poly2;
+int_4 dgx, dgy;
+is >> dgx >> dgy;
+dobj->Realloc(dgx,dgy);
+is >> *((TVector<r_8> *) dobj);
+dobj->UpdateDeg();
+}
+
+//! For persistance management
+void ObjFileIO<Poly2>::WriteSelf(POutPersist& os) const
+{
+if(dobj == NULL) return;
+os << dobj->maxDegX << dobj->maxDegY;
+os << *((TVector<r_8> *) dobj);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template ObjFileIO<Poly>
+#pragma define_template ObjFileIO<Poly2>
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class ObjFileIO<Poly>;
+template class ObjFileIO<Poly2>;
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/poly.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/poly.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/poly.h	(revision 2309)
@@ -0,0 +1,281 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// $Id: poly.h,v 1.10 2001-07-19 08:33:49 ansari Exp $
+//
+
+// Des polynomes avec des operations de bases et surtout des fits.
+
+#ifndef POLY_SEEN
+#define POLY_SEEN
+
+#include "objfio.h"
+#include <stdio.h>
+#include "peida.h"
+#include "tvector.h"
+#include "ppersist.h"
+#include "anydataobj.h"
+
+namespace SOPHYA {
+
+class Poly2;
+
+//////////////////////////////////////////////////////////////////////////
+//! Class of 1 dimension polynomials P(x)
+class Poly : public TVector<r_8> {
+  friend class ObjFileIO<Poly>;
+public:
+  Poly(int degre = 0);
+  Poly(Poly const& a);
+
+  //! Return degre of polynomials
+  inline int Degre() const {UpdateDegIfDirty(); return deg;}
+
+  //! Return space for a \b n degre polynomial
+  /*!
+    \param \b n : degre of new polynomial
+    \param \b force : force re-allocation if true,\
+                 if not allocation occurs only
+                 if space needed is greater than the old one
+  */
+  inline void Realloc(int n, bool force=false)
+                     {TVector<r_8>::Realloc(n+1,force);}
+
+  //  Pour compatibilite PEIDA  - Reza 03/2000
+  //! Return coefficient of degre \b i
+  inline double Element(int i) const { return Elem(i,0,0,0,0); } 
+  //! Return coefficient of degre \b i
+  inline double & Element(int i)  { return Elem(i,0,0,0,0); } 
+
+  //! Return coefficient of degre \b i
+  inline double operator[](int i) const {return Elem(i,0,0,0,0);}
+  //! Return coefficient of degre \b i
+  inline double& operator[](int i) {dirty = 1; return Elem(i,0,0,0,0);}
+  // Retourne le coefficient de degre i
+
+  double operator()(double x) const;
+  // Retourne la valeur prise en x.
+
+  void   Derivate();
+  // Derive le polynome en place
+
+  void   Derivate(Poly& der) const;
+  // Derive le polynome dans un autre
+
+  int    Roots(TVector<r_8>& roots) const;
+  // retourne les racines si on peut les calculer...
+
+  int    Root1(double& r) const;
+  // special degre 1
+
+  int    Root2(double& r1, double& r2) const;
+  // special degre 2
+
+  Poly& operator = (Poly const& b);
+  Poly& operator += (Poly const& b);
+  Poly& operator -= (Poly const& b);
+
+  Poly& operator *= (double a);
+
+  Poly Mult(Poly const& b) const;
+
+  Poly power(int n) const;
+  Poly operator() (Poly const& b) const;
+  Poly2 operator() (Poly2 const& b) const;
+
+  void Print(ostream& s, sa_size_t maxprt=-1, 
+	     bool si=false, bool ascd=false) const ;
+
+  double Fit(TVector<r_8> const& x, TVector<r_8> const& y, int degre);
+  // Fit d'un polynome de degre donne sur les x et y.
+
+  double Fit(TVector<r_8> const& x, TVector<r_8> const& y,
+         TVector<r_8> const& erry2, int degre, TVector<r_8>& errCoef);
+  // En plus, on fournit les carres des erreurs sur y et on a les erreurs
+  // sur les coefficients dans un vecteur.
+
+private:
+  int dirty;
+  int_4 deg;
+  void UpdateDeg() const;
+  void UpdateDegIfDirty() const {if (dirty) UpdateDeg();}
+};
+
+/*! \ingroup NTools \fn operator*(Poly const&,Poly const&)
+  \brief perform and return P(X) = a(x) * b(x) */
+inline Poly operator* (Poly const& a, Poly const& b)
+  { return a.Mult(b); }
+
+/*! \ingroup NTools \fn operator+(Poly const&,Poly const&)
+  \brief perform and return P(X) = a(x) + b(x) */
+inline Poly operator+ (Poly const& a, Poly const& b)
+ { Poly c((a.Degre() > b.Degre())?(a.Degre()+1):(b.Degre()+1));
+   c = a; c += b; return c; }
+
+/*! \ingroup NTools \fn operator-(Poly const&,Poly const&)
+  \brief perform and return P(X) = a(x) - b(x) */
+inline Poly operator- (Poly const& a, Poly const& b)
+  { Poly c((a.Degre() > b.Degre())?(a.Degre()+1):(b.Degre()+1));
+    c = a; c -= b; return c; }
+
+/*! \ingroup NTools \fn operator*(double,Poly const&)
+  \brief perform and return P(X) = a * b(x) */
+inline Poly operator* (double a, Poly const& b)
+  { Poly c(b); c *= a; return c; }
+
+/*! \ingroup NTools \fn operator<<(ostream&,const Poly&)
+  \brief Print a(x) on stream \b s */
+inline ostream& operator << (ostream& s, const Poly& a)
+  { a.Print(s); return s; }
+
+//////////////////////////////////////////////////////////////////////////
+/*! \ingroup NTools \fn operator<<(POutPersist&,Poly&)
+  \brief For persistance management */
+inline POutPersist& operator << (POutPersist& os, Poly & obj)
+  { ObjFileIO<Poly> fio(&obj);  fio.Write(os);  return(os); }
+/*! \ingroup NTools \fn operator<<(PInPersist&,,Poly&)
+  \brief For persistance management */
+inline PInPersist& operator >> (PInPersist& is, Poly & obj)
+  { ObjFileIO<Poly> fio(&obj);  fio.Read(is);  return(is); }
+// Classe pour la gestion de persistance
+// ObjFileIO<Poly>
+
+//////////////////////////////////////////////////////////////////////////
+int binomial(int n, int p);
+
+//////////////////////////////////////////////////////////////////////////
+//! Class of 2 dimensions polynomials P(x,y)
+class Poly2 : public TVector<r_8> {
+  friend class ObjFileIO<Poly2>;
+public:
+  Poly2(int degreX=0, int degreY=0);
+  // degres alloues.
+  Poly2(Poly const& polX, Poly const& polY);
+  Poly2(Poly2 const& a);
+
+  //! Return polynomial partial degre for X
+  inline int DegX() const {UpdateDegIfDirty(); return degX;}
+  //! Return polynomial partial degre for Y
+  inline int DegY() const {UpdateDegIfDirty(); return degY;}
+  //! Return polynomial maximum partial degre for X
+  inline int MaxDegX() const {return maxDegX;}
+  //! Return polynomial maximum partial degre for Y
+  inline int MaxDegY() const {return maxDegY;}
+  //! Return polynomial total degre for X
+  inline int Deg()  const {UpdateDegIfDirty(); return deg;}
+  // les degres partiels en x et y, et totaux.
+
+  //  Pour compatibilite PEIDA  - Reza 03/2000
+  //! Return coefficient of degre \b i
+  inline double Element(int i) const { return Elem(i,0,0,0,0); } 
+  //! Return coefficient of degre \b i
+  inline double & Element(int i)  { return Elem(i,0,0,0,0); } 
+
+  double operator()(double x, double y) const;
+  // retourne la valeur en (x,y)
+
+  //! Return index of coefficient of X^dx * Y^dy in the vector
+  inline int IndCoef(int dx, int dy) const {
+    if (dx>maxDegX || dy>maxDegY) THROW(rangeCheckErr);
+    return dx + (maxDegX+1)*dy;
+  }
+  // l'indice du coefficient dans le vecteur. Public uniquement parce
+  // que ca sert a recuperer les erreurs sur les coefficients lors
+  // d'un fit...
+
+  //! Return coefficient of X^dx * Y^dy
+  inline double Coef(int dx, int dy) const {
+    return (dx>maxDegX || dy>maxDegY) ? 0 : Element(IndCoef(dx,dy));
+  }
+  //! Return coefficient of X^dx * Y^dy
+  inline double& Coef(int dx, int dy) {
+    if (dx>maxDegX || dy>maxDegY) THROW(rangeCheckErr);
+    dirty = 1; return Element(IndCoef(dx,dy));
+  }
+  // retourne le coefficient de degre (dx,dy)
+
+  double Fit(TVector<r_8> const& x, TVector<r_8> const& y, TVector<r_8> const& z,
+             int degreX, int degreY);
+  double Fit(TVector<r_8> const& x, TVector<r_8> const& y, TVector<r_8> const& z,
+             TVector<r_8> const& errz2, int degreX, int degreY,
+             TVector<r_8>& errCoef);
+  // degres partiels imposes. cf Poly::Fit sinon
+
+
+  double Fit(TVector<r_8> const& x, TVector<r_8> const& y, TVector<r_8> const& z,
+             int degre);
+  double Fit(TVector<r_8> const& x, TVector<r_8> const& y, TVector<r_8> const& z,
+             TVector<r_8> const& errz2, int degre,
+             TVector<r_8>& errCoef);
+  // degre total impose. cf Poly::Fit sinon
+
+  Poly2& operator = (Poly2 const& b);
+
+  Poly2& operator += (Poly2 const& b);
+  Poly2& operator -= (Poly2 const& b);
+
+  Poly2& operator *= (double a);
+
+  Poly2 Mult(Poly2 const& b) const;
+
+  Poly2 power(int n) const;
+
+  Poly2 operator() (Poly const& px, Poly const& py) const;
+//  Poly2 operator() (Poly2 const& px, Poly2 const& py) const;
+
+  void Realloc(int degreX, int degreY);
+
+  void Print(ostream& s, sa_size_t maxprt=-1, 
+	     bool si=false, bool ascd=false) const ;
+
+private:
+  int dirty;
+  int_4 maxDegX;
+  int_4 maxDegY;
+  int degX;
+  int degY;
+  int deg;
+  void UpdateDeg() const;
+  void UpdateDegIfDirty() const {if (dirty) UpdateDeg();}
+};
+
+/*! \ingroup NTools \fn operator*(Poly2 const&,Poly2 const&)
+  \brief Perform P(x,y) = a(x,y) * b(x,y) */
+inline Poly2 operator* (Poly2 const& a, Poly2 const& b)
+  { return a.Mult(b); }
+
+/*! \ingroup NTools \fn operator+(Poly2 const&,Poly2 const&)
+  \brief Perform P(x,y) = a(x,y) + b(x,y) */
+inline Poly2 operator+ (Poly2 const& a, Poly2 const& b)
+  { Poly2 c(a); c += b; return c; }
+
+/*! \ingroup NTools \fn operator-(Poly2 const&,Poly2 const&)
+  \brief Perform P(x,y) = a(x,y) - b(x,y) */
+inline Poly2 operator- (Poly2 const& a, Poly2 const& b)
+  { Poly2 c(a); c -= b; return c; }
+
+/*! \ingroup NTools \fn operator-(double,Poly2 const&)
+  \brief Perform P(x,y) = a * b(x,y) */
+inline Poly2 operator * (double a, Poly2 const& b)
+  { Poly2 c(b); c *= a; return c; }
+
+/*! \ingroup NTools \fn operator<<(ostream&,const Poly2&)
+  \brief Print a(x,y) on stream \b s */
+inline ostream& operator << (ostream& s, const Poly2& a)
+  { a.Print(s); return s; }
+
+//////////////////////////////////////////////////////////////////////////
+/*! \ingroup NTools \fn operator<<(POutPersist&,Poly2&)
+  \brief For persistance management */
+inline POutPersist& operator << (POutPersist& os, Poly2 & obj)
+  { ObjFileIO<Poly2> fio(&obj);  fio.Write(os);  return(os); }
+/*! \ingroup NTools \fn operator<<(POutPersist&,Poly2&)
+  \brief For persistance management */
+inline PInPersist& operator >> (PInPersist& is, Poly2 & obj)
+  { ObjFileIO<Poly2> fio(&obj);  fio.Read(is);  return(is); }
+// Classe pour la gestion de persistance
+// ObjFileIO<Poly2>
+
+
+} // Fin du namespace
+
+#endif // POLY_SEEN
Index: /tags/V_Dec2002/SophyaLib/NTools/rk4cdifeq.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/rk4cdifeq.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/rk4cdifeq.cc	(revision 2309)
@@ -0,0 +1,193 @@
+#include "machdefs.h"
+#include "rk4cdifeq.h"
+#include "ctimer.h"
+#include <iostream.h>
+
+inline double max_dbl(double a, double b) { return ((a < b) ? b : a); } 
+
+//++
+// Class	RK4CDiffEq
+// Lib  	Outils++ 
+// include	rk4cdifeq.h
+//
+//	Classe de résolution d'équadif par la méthode de
+//	Runge-Kutta d'ordre 4 adaptatif.
+//	Voir DiffEqSolver et R4KDiffEq pour les méthodes.
+//
+//	On peut demander une précision relative ou absolue
+//	sur chacune des fonctions du système. Le pas d'intégration
+//	est adapté automatiquement pour fournir au moins 
+//	cette précision.
+//--
+
+//++
+// Links	Parents
+// RK4DiffEq
+// DiffEqSolver
+//--
+
+//++
+// Titre	Constructeurs
+//	Voir RK4DiffEq et DiffEqSolver
+//--
+
+//++
+RK4CDiffEq::RK4CDiffEq()
+//
+//--
+: RK4DiffEq(), eps(1.e-4), relAccuracy(true), accScale(10), yTemp(10), ySave(10)
+{}
+
+//++
+RK4CDiffEq::RK4CDiffEq(DiffEqFunction* f)
+//
+//--
+: RK4DiffEq(f), eps(1.e-4), relAccuracy(true), accScale(f->NFuncReal()), yTemp(f->NFuncReal()), ySave(f->NFuncReal())
+{}
+
+//++
+RK4CDiffEq::RK4CDiffEq(DIFEQFCN1 f)
+//
+//--
+: RK4DiffEq(f), eps(1.e-4), relAccuracy(true), accScale(1), yTemp(1), ySave(1)
+{}
+
+//++
+// Titre	Méthodes
+//--
+
+//++
+// RK4CDiffEq& RK4CDiffEq::Accuracy(double eps)
+//	Fixe la précision requise sur les fonctions. Cette précision
+//	est par défaut relative. Elle peut être absolue, auquel cas
+//	il faut fixer, pour chaque fonction, un facteur d'échelle, et
+//	la précision sur chaque fonction est alors scale[i]*eps.
+//--
+
+RK4CDiffEq& 
+RK4CDiffEq::Accuracy(double x)
+{
+  eps = x;
+  return *this;
+}
+
+//++
+RK4CDiffEq&  
+RK4CDiffEq::AbsAccuracy(Vector const& vScal)
+//
+//	On souhaite une précision absolue, et le vecteur vScal contient
+//	le facteur d'échelle pour chaque fonction (voir Accuracy).
+//--
+{
+  accScale = vScal;
+  relAccuracy = false;
+  return *this;
+}
+
+//++
+RK4CDiffEq&  
+RK4CDiffEq::AbsAccuracy(double scal)
+//
+//	On souhaite une précision absolue, et le vecteur scal contient
+//	le facteur d'échelle à appliquer à toutes les fonctions.
+//	La précision absolue souhaitée est alors eps*scal.
+//--
+{
+  for (int i=0; i<accScale.NElts(); i++)
+    accScale(i) = scal;
+  relAccuracy = false;
+  return *this;
+}
+
+//++
+RK4CDiffEq&  
+RK4CDiffEq::RelAccuracy()
+//
+//	On souhaite une précision relative. En quelque sorte, le facteur d'échelle 
+//	pour chaque fonction est alors la valeur de la fonction.
+//--
+{
+  relAccuracy = true;
+  return *this;
+}
+
+static const double pgrow   = -0.20;
+static const double pshrink = -0.25;
+static const double safety  = 0.9;
+static const double errcon = pow((4/safety),1/pgrow);
+
+void
+RK4CDiffEq::RKCStep(Vector& newY, Vector const& y0, Vector const& yScale, 
+	       double dttry, double& dtdone, double& dtnext)
+{
+  double err;
+  ySave = y0;
+  do {
+    // Deux petits pas
+    RKStep(yTemp, ySave, dttry/2.);
+    RKStep(newY, yTemp, dttry/2.);
+    
+    // Un grand pas
+    RKStep(yTemp, ySave, dttry);
+    
+    yTemp -= newY;   // l'erreur courante
+
+    err = 0;
+    for (int i=0; i<yTemp.NElts(); i++) 
+      err = max_dbl(fabs(yScale(i) ? (yTemp(i)/yScale(i)) : yTemp(i)), err);
+    
+    err /= eps;
+    if (err > 1) 
+      dttry *= safety*pow(err,pshrink);
+    else {
+      dtdone = dttry;
+      if (err > errcon)
+	dtnext = safety*dttry*pow(err,pgrow);
+      else
+	dtnext = dttry*4;
+    }
+  }  while (err > 1);
+  
+  // Et on corrige a l'ordre 5
+
+  newY += yTemp/15.;
+}
+
+void
+RK4CDiffEq::SolveArr(Matrix& y, double* t, double tf, int n)
+{
+  //TIMEF;
+  // Les intervalles a stocker dans la matrice des resultats
+
+  double dxres = (tf - mXStart)/n;
+
+  Vector yt(mYStart,false);
+  
+  k1.Realloc(mFunc->NFuncReal());
+  k2.Realloc(mFunc->NFuncReal());
+  k3.Realloc(mFunc->NFuncReal());
+  k4.Realloc(mFunc->NFuncReal());
+  yTemp.Realloc(mFunc->NFuncReal());
+  ySave.Realloc(mFunc->NFuncReal());
+
+  double x = mXStart;
+  double step = mStep;
+  double nstep;
+
+  for (int i=0; i<n; i++) {
+    double xEndStep = (i+1)*dxres + mXStart;
+    do {
+      if (relAccuracy) accScale = yt;
+      if ((x+step-xEndStep)*(x+step-mXStart)>0) step = xEndStep-x;
+      RKCStep(yt, yt, accScale, step, step, nstep);
+      x += step;
+      //cout << x << " " << step << endl;
+      step = nstep;
+    } while ((x-xEndStep)*(x-mXStart) < 0);
+    for (int j=0; j<mFunc->NFunc(); j++)
+      y(i,j) = yt(j);
+    t[i] = xEndStep;
+    //cout << "fin boucle "<<i<<"  "<<x<<"  "<<yt(0)<<endl;
+  }
+   
+}
Index: /tags/V_Dec2002/SophyaLib/NTools/rk4cdifeq.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/rk4cdifeq.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/rk4cdifeq.h	(revision 2309)
@@ -0,0 +1,46 @@
+// This may look like C code, but it is really -*- C++ -*-
+#ifndef RK4CDIFEQ_H_SEEN
+#define RK4CDIFEQ_H_SEEN
+
+#include "difeq.h"
+
+namespace SOPHYA {
+
+// <summary> Runge-Kutta ordre 4 adaptatif </summary>
+// Runge-Kutta ordre 4 adaptatif, avec correction du pas d'integration
+class RK4CDiffEq : public RK4DiffEq {
+public:
+  // Constructeurs. Voir <linkto class=DiffEqSolver>DiffEqSolver</linkto>
+  // <group>
+  RK4CDiffEq();
+  RK4CDiffEq(DiffEqFunction*);
+  RK4CDiffEq(DIFEQFCN1);
+  // </group>
+
+  // Precision souhaitee, en absolu ou relatif, independamment pour chaque
+  // fonction ou globalement
+  // <group>
+  RK4CDiffEq& Accuracy(double);
+  RK4CDiffEq& AbsAccuracy(Vector const& vScal);
+  RK4CDiffEq& AbsAccuracy(double scal);
+  RK4CDiffEq& RelAccuracy();
+  // </group>
+  
+  // Implementation RK4 adaptatif
+  virtual void SolveArr(Matrix& y, double* t, double tf, int n);
+
+protected:
+  // Un pas adaptatif
+  void RKCStep(Vector& newY, Vector const& y0, Vector const& yScale, 
+	       double dttry, double& dtdone, double& dtnext);
+
+  double eps;
+  bool   relAccuracy;
+  Vector accScale;
+  Vector yTemp; // Pour ne pas reallouer
+  Vector ySave;
+};
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/simplesort.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/simplesort.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/simplesort.cc	(revision 2309)
@@ -0,0 +1,60 @@
+//
+// $Id: simplesort.cc,v 1.2 1999-04-22 16:18:50 ansari Exp $
+//
+
+#include "machdefs.h"
+#include "simplesort.h"
+#include <stdlib.h>
+
+//++
+// Class	SimpleSort
+// Lib  	Outils++ 
+// include	simplesort.h
+//
+//	Classe pour trier. Utiliser plutôt la STL.
+//--
+
+
+SimpleSort::SimpleSort(int nElts)
+: numElts(nElts), index(new TRIPAIRE[nElts])
+{END_CONSTRUCTOR}
+			
+SimpleSort::~SimpleSort()
+{
+  delete[] index;
+}
+
+int SimpleSort::Compare(const void* tp1, const void* tp2)
+{ float x=((TRIPAIRE*)tp1)->value - ((TRIPAIRE*)tp2)->value;
+  if (x>0) return(1);
+  else if (x<0) return(-1);
+  else return(0);
+}
+
+#if !ARG_FUNC_CPP_C
+extern "C" int SimpleSortCompare(const void* tp1, const void* tp2);
+
+int SimpleSortCompare(const void* tp1, const void* tp2)
+{ return SimpleSort::Compare(tp1, tp2);
+}
+#endif
+
+void SimpleSort::Sort()
+{
+#if ARG_FUNC_CPP_C
+  qsort(index, numElts, sizeof(TRIPAIRE), SimpleSort::Compare);
+#else
+  qsort(index, numElts, sizeof(TRIPAIRE), SimpleSortCompare);
+#endif
+}
+
+int SimpleSort::Lookup(float val)
+{
+  int a = 0;
+  int b = numElts-1;
+  while (b>a+1) {
+    int c = (b+a)/2;
+    ((val >= index[c].value) ? a : b) = c;
+  }
+  return a;
+}
Index: /tags/V_Dec2002/SophyaLib/NTools/simplesort.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/simplesort.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/simplesort.h	(revision 2309)
@@ -0,0 +1,97 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// $Id: simplesort.h,v 1.5 2001-01-12 15:47:31 ansari Exp $
+//
+
+// Un tri tout bete sur des reels. On donne un tableau de reels,
+// et on recupere un index trie, et on peut faire des recherches.
+
+#ifndef SIMPLESORT_SEEN
+#define SIMPLESORT_SEEN
+
+#include "peida.h"
+
+// Pour la variante avec la STL, a preferer
+#include <functional>
+#include <algorithm>
+
+namespace SOPHYA {  
+
+class SimpleSort  {
+public:
+  SimpleSort(int nElts);
+  // On donne au constructeur le nombre d'elements a trier.
+  virtual ~SimpleSort();
+
+  void      Set(int i, float value);
+  // Donne la valeur de l'element i
+
+  void      Sort();
+  // Trie. A faire avant d'appeler la suite.
+
+  float    Value(int i) const {return index[i].value;}
+  // La valeur numero i une fois trie.
+
+  int       Num(int i) const   {return index[i].num;}
+  // L'ancien indice qui est le numero i une fois trie
+
+  int       Lookup(float val);
+  // L'indice - trie - le plus proche de val.
+  
+#if ARG_FUNC_CPP_C
+private:
+#endif
+  typedef struct {
+    int num;
+    float value;
+  } TRIPAIRE;
+
+  static int Compare(const void* tp1, const void* tp2);
+    
+  int numElts;
+  TRIPAIRE* index;
+};
+
+// ************ INLINES
+
+inline
+void SimpleSort::Set(int i, float value)   // Check range ?
+{
+  index[i].num = i;
+  index[i].value = value;
+}
+
+
+// ----- Une variante avec la STL, a preferer
+
+
+// On a un vecteur de donnees et un vecteur d'index, on trie les index
+// en comparant les donnees.
+// L'objet-fonction de type dataCompare doit comparer deux objets de type data.
+
+// Comparateur qui agit sur l'index en comparant les donnees avec dataCompare
+template <class data, class index, class dataCompare>
+struct IndexComp : public std::binary_function<index,index,bool>
+{
+  IndexComp(data* begin_data, index* begin_index, dataCompare comp)
+    : bdata(begin_data), bindex(begin_index), datacomp(comp) {}
+
+  bool operator()(index const& i1, index const& i2)
+    { return datacomp(*(bdata + (&i1 - bindex)), *(bdata + (&i2 - bindex)));}
+    
+  data* bdata;
+  index* bindex;
+  dataCompare datacomp;
+};
+
+// Fonction de tri qui trie un index en comparant des donnees avec dataComp
+template <class data, class index, class dataCompare>
+void TriIndex(data* begin_data, data* end_data, index* begin_index, dataCompare comp)
+{
+  sort(begin_index, begin_index + (end_data-begin_data),
+  	IndexComp<data, index, dataCompare>(begin_data, begin_index, comp));
+}  
+
+} // namespace SOPHYA
+
+#endif // SIMPLESORT_SEEN
Index: /tags/V_Dec2002/SophyaLib/NTools/simps2d.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/simps2d.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/simps2d.h	(revision 2309)
@@ -0,0 +1,40 @@
+#ifndef SIMPS2D_SEEN
+#define SIMPS2D_SEEN
+
+// Integration 2D domaine carre
+// Selon Abramowitz p892-893 formule 25.462, residu ordre 0.5**6
+// 0.387298=0.5*sqrt(3/5)  0.197531=16/81  0.123457=10/81  0.077160=25/324
+#if defined(SIMPSON9)
+  static int   nd2d = 9;
+  static float dx2d[9] = { 0.000000 ,  0.000000 ,  0.000000
+                         ,-0.387298 ,  0.387298 , -0.387298
+                         , 0.387298 , -0.387298 ,  0.387298 };
+  static float dy2d[9] = { 0.000000 , -0.387298 ,  0.387298
+                         , 0.000000 ,  0.000000 , -0.387298
+                         , 0.387298 ,  0.387298 , -0.387298 };
+  static float  w2d[9] = { 0.197531 ,  0.123457 ,  0.123457
+                         , 0.123457 ,  0.123457 ,  0.077157
+                         , 0.0771605,  0.0771605,  0.0771605};
+#elif defined(SIMPSON4)
+  static int   nd2d = 4;
+  static float dx2d[4] = { 0.288675, 0.288675,-0.288675,-0.288675 };
+  static float dy2d[4] = { 0.288675,-0.288675, 0.288675,-0.288675 };
+  static float  w2d[4] = { 0.250000, 0.250000, 0.250000, 0.250000 };
+#elif defined(INTEG5)
+  static int   nd2d = 5;
+  static float dx2d[5] = { 0. , -0.3, -0.3,  0.3, 0.3 };
+  static float dy2d[5] = { 0. , -0.3,  0.3, -0.3, 0.3 };
+  static float  w2d[5] = { 0.2,  0.2,  0.2,  0.2, 0.2 };
+#elif  defined(NOINTEG)
+  static int   nd2d = 1;
+  static float dx2d[1] = { 0. };
+  static float dy2d[1] = { 0. };
+  static float  w2d[1] = { 1. };
+#else
+  static int   nd2d = 0;
+  static float dx2d[1] = { 999999. };
+  static float dy2d[1] = { 999999. };
+  static float  w2d[1] = { 0. };
+#endif
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/slinparbuff.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/slinparbuff.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/slinparbuff.h	(revision 2309)
@@ -0,0 +1,397 @@
+#include "machdefs.h"
+#include <iostream.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <algorithm>
+#include "pexceptions.h"
+
+#ifndef SLINPARBUF_H_SEEN
+#define SLINPARBUF_H_SEEN
+
+namespace SOPHYA {
+
+//////////////////////////////////////////////////////////////////////////////////
+class SLinParBuff {
+public:
+  friend class SLinParBuffMerger;
+
+  //***************************************************************** 
+  SLinParBuff(uint_4 lenbuf,uint_4 nresynch=0
+             ,r_8 x0=0.,r_8 y0=0.,bool autoxy0=false)
+  // ---- Createur
+  {
+    if(lenbuf==0) throw RangeCheckError("SLinParBuff: lenbuf==0 !");
+    mLenBuf = lenbuf;
+    mNResynch = nresynch;
+    mX = new r_8[mLenBuf]; mY = new r_8[mLenBuf];
+    mX0 = x0; mY0 = y0; mAutoXY0 = autoxy0;
+    Reset();
+  }
+
+  SLinParBuff(SLinParBuff& slp)
+  // ---- Createur par copie
+  {
+    mLenBuf = slp.mLenBuf;
+    mNResynch = slp.mNResynch;
+
+    mX = mY = NULL;
+    if(mLenBuf) {
+      mX = new r_8[mLenBuf]; mY = new r_8[mLenBuf];
+      for(uint_4 i=0;i<mLenBuf;i++) {mX[i]=slp.mX[i]; mY[i]=slp.mY[i];}
+    }
+
+    mX0 = slp.mX0; mY0 = slp.mY0; mAutoXY0 = slp.mAutoXY0;
+    mNCur = slp.mNCur; mIDeb = slp.mIDeb; mIResynch = slp.mIResynch;
+    mNResynchEff = slp.mNResynchEff; mNPush = slp.mNPush; mNPop = slp.mNPop;
+
+    mSx = slp.mSx; mSy = slp.mSy;
+    mSx2 = slp.mSx2; mSy2 = slp.mSy2; mSxy = slp.mSxy;
+    mSx3 = slp.mSx3; mSx2y = slp.mSx2y;
+    mSx4 = slp.mSx4;
+  }
+
+  SLinParBuff(void)
+  // ---- Createur par defaut
+  {
+    mLenBuf = 0; mNResynch = 0;
+    mX = mY = NULL;
+    mX0 = mY0 = 0.; mAutoXY0 = false;
+    Reset();
+  }
+
+  virtual ~SLinParBuff()
+  // ---- Destructeur
+  {
+    if(mX) delete [] mX; if(mY) delete [] mY;
+  }
+
+  //***************************************************************** 
+  inline void GetX0Y0(r_8& x0,r_8& y0) {x0 = mX0; y0 = mY0;}
+  inline bool GetAutoX0Y0() {return mAutoXY0;}
+
+  inline void SetX0Y0(r_8 x0=0.,r_8 y0=0.)
+  // ---- Stabilite numerique, centrage des x,y en mX0,mY0
+  {
+    mX0 = x0; mY0 = y0; mAutoXY0 = false;
+    ReComputeSum();
+  }
+
+  inline void SetAutoX0Y0(bool autoxy0=false)
+  // ---- Stabilite numerique, centrage automatique a <x> et <y>
+  //      a chaque ReComputeSum
+  {
+    mAutoXY0 = autoxy0;
+    ReComputeSum();
+  }
+
+  inline void Reset(void)
+  // ---- Reset des sommes et des compteurs
+  {
+    mSx=mSy=mSx2=mSy2=mSxy=mSx3=mSx2y=mSx4=0.;
+    mNCur = mIDeb = mIResynch = mNResynchEff = mNPush = mNPop = 0;
+    //if(mX) for(uint_4 i=0;i<mLenBuf;i++) mX[i] = 0.;
+    //if(mY) for(uint_4 i=0;i<mLenBuf;i++) mY[i] = 0.;
+  }
+
+  //***************************************************************** 
+  inline uint_4 Pop(void)
+  // ---- Pour enlever la donnee la plus ancienne
+  {
+    if(mNCur==0) return mNCur;
+    r_8 x=mX[mIDeb]-mX0, y=mY[mIDeb]-mY0; r_8 x2 = x*x;
+    mSx  -= x;     mSy   -= y;
+    mSx2 -= x2;    mSy2  -= y*y;   mSxy -= x*y;
+    mSx3 -= x2*x;  mSx2y -= x2*y;
+    mSx4 -= x2*x2;
+    mNCur--; mNPop++;
+    if(mNCur==0) {Reset(); return mNCur;}
+    mIDeb++; if(mIDeb==mLenBuf) mIDeb=0;
+    return mNCur;
+  }
+
+  inline uint_4 Push(r_8 x,r_8 y)
+  // ---- Pour ajouter une donnee, la donnee la plus ancienne
+  //      est enlevee si le buffer est deja plein.
+  {
+    uint_4 ifill;
+    if(mNCur==mLenBuf) {
+      r_8 X=mX[mIDeb]-mX0, Y=mY[mIDeb]-mY0; r_8 X2 = X*X;
+      mSx  -= X;     mSy   -=Y;
+      mSx2 -= X2;    mSy2  -=Y*Y;   mSxy -= X*Y;
+      mSx3 -= X2*X;  mSx2y -=X*X*Y;
+      mSx4 -= X2*X2;
+      ifill = mIDeb;
+      mIDeb++; if(mIDeb==mLenBuf) mIDeb=0;
+    } else {
+      ifill = (mIDeb+mNCur)%mLenBuf;
+      mNCur++;
+    }
+    mX[ifill] = x; mY[ifill] = y;
+    x -= mX0; y -= mY0; r_8 x2 = x*x;
+    mSx += x; mSy += y;
+    mSx2 += x2; mSy2 += y*y; mSxy += x*y;
+    mSx3 += x2*x; mSx2y += x2*y;
+    mSx4 += x2*x2;
+    mNPush++;
+    // Il faut re-synchroniser pour eviter les derives numeriques
+    mIResynch++; if(mIResynch == mNResynch) ReComputeSum();
+    return mNCur;
+  }
+
+  //***************************************************************** 
+  inline uint_4 ReComputeSum(void)
+  // ---- Pour re-synchroniser (eviter les derives numeriques).
+  {
+    if(mNCur==0) return 0;
+    // Re-centrage automatique a la moyenne demande:
+    // Attention, mSx = sum(x-mX0) ==> nouvel mX0 = mSx/N + mX0(ancien)
+    if(mAutoXY0) {mX0 = mSx/(r_8)mNCur + mX0; mY0 = mSy/(r_8)mNCur + mY0;}
+    mSx=mSy=mSx2=mSy2=mSxy=mSx3=mSx2y=mSx4=0.;
+    for(uint_4 i=mIDeb;i<mIDeb+mNCur;i++) {
+      uint_4 ii = i%mLenBuf;
+      r_8 x=mX[ii]-mX0, y=mY[ii]-mY0; r_8 x2 = x*x;
+      mSx  += x;     mSy   += y;
+      mSx2 += x2;    mSy2  += y*y;   mSxy += x*y;
+      mSx3 += x2*x;  mSx2y += x2*y;
+      mSx4 += x2*x2;
+    }
+    mIResynch=0;
+    mNResynchEff++;
+    return mNCur;
+  }
+
+  //***************************************************************** 
+  // ---- Retourne le nombre de points
+  inline uint_4 NPoints(void) {return mNCur;}
+
+  inline r_8 Compute(r_8& mean,bool recomputeXi2=false)
+  // ---- Calcul <y>, Var(y)
+  //   recomputeXi2=true : recalcule le xi2 (sigma) avec la courbe et les points
+  {
+    mean=0.;
+    if(mNCur==0) return -1.;
+    // Moyenne
+    mean  = mSy/(r_8) mNCur;
+    // Sigma
+    r_8 sigma;
+    if(recomputeXi2) {
+      sigma=0.;
+      for(uint_4 i=mIDeb;i<mIDeb+mNCur;i++) {
+        uint_4 ii = i%mLenBuf;
+        r_8 s = mean - (mY[ii]-mY0);
+	sigma += s*s;
+      }
+      sigma /= (r_8) mNCur;
+    } else {
+      sigma = mSy2/(r_8) mNCur - mean*mean;
+    }
+    // gestion du decalage
+    mean += mY0;
+
+    if(sigma>0.) return sqrt(sigma);
+    if(sigma<0.) return -sqrt(-sigma);
+    return sigma;
+  }
+
+  inline r_8 Compute(r_8& a0,r_8 &a1,bool recomputeXi2=false)
+  // ---- Calcul y=a0+a1*x et slin=Var(y-(a0+a1*x))=sqrt(<dy^2>)
+  //   recomputeXi2=true : recalcule le xi2 avec la courbe et les points
+  {
+    a0=a1=0.;
+    if(mNCur==0) return -1.;
+    // Fit lineaire
+    r_8 w = mNCur*mSx2 - mSx*mSx;
+    if(w==0. || mNCur==1) return -2.;
+    a0 = (mSx2*mSy - mSx*mSxy)/w;
+    a1 = (mNCur*mSxy - mSx*mSy )/w;
+    // Sigma par rapport Fit lineaire 
+    // (On a XI2=mNCur*slin**2 dans notre cas ou les erreurs=1)
+    r_8 slin;
+    if(recomputeXi2) {
+      slin=0.;
+      for(uint_4 i=mIDeb;i<mIDeb+mNCur;i++) {
+        uint_4 ii = i%mLenBuf;
+        r_8 s = a0+a1*(mX[ii]-mX0) - (mY[ii]-mY0);
+	slin += s*s;
+      }
+      slin /= (r_8) mNCur;
+    } else {
+      slin = (mSy2 +a0*a0*mNCur +a1*a1*mSx2 -2.*a0*mSy -2.*a1*mSxy +2.*a0*a1*mSx)
+             / (r_8)mNCur;
+    }
+    // gestion du decalage y-y0 = a0 + a1*(x-x0)
+    a0 = mY0 + a0 - a1*mX0;
+
+    if(slin>0.) return sqrt(slin);
+    if(slin<0.) return -sqrt(-slin);
+    return slin;
+  }
+
+  inline r_8 Compute(r_8& a0,r_8 &a1,r_8 &a2,bool recomputeXi2=false)
+  // ---- Calcul y=a0+a1*x+a2*x^2 et spar=Var(y-(a0+a1*x+a2*x^2))=sqrt(<dy^2>)
+  //   recomputeXi2=true : recalcule le xi2 avec la courbe et les points
+  {
+    a0=a1=a2=0.;
+    if(mNCur==0) return -1.;
+    // Fit parabolique
+    r_8 w = mSx2*(mSx2*mSx2-mSx3*mSx) -mSx*(mSx3*mSx2-mSx4*mSx) +mNCur*(mSx3*mSx3-mSx4*mSx2);
+    if(w==0. || mNCur<=2) return -2.;
+    a2 =  (mSy*(mSx2*mSx2-mSx3*mSx)  - mSxy*(mSx*mSx2-mSx3*mNCur)  + mSx2y*(mSx*mSx-mSx2*mNCur) )/w;
+    a1 = -(mSy*(mSx3*mSx2-mSx4*mSx)  - mSxy*(mSx2*mSx2-mSx4*mNCur) + mSx2y*(mSx2*mSx-mSx3*mNCur))/w;
+    a0 =  (mSy*(mSx3*mSx3-mSx4*mSx2) - mSxy*(mSx2*mSx3-mSx4*mSx)   + mSx2y*(mSx2*mSx2-mSx3*mSx) )/w;
+    // Sigma par rapport Fit parabolique
+    // (On a XI2=mNCur*spar**2 dans notre cas ou les erreurs=1)
+    // Le calcul direct du Xi2 n'est pas precis
+    r_8 spar;
+    if(recomputeXi2) {
+      spar=0.;
+      for(uint_4 i=mIDeb;i<mIDeb+mNCur;i++) {
+        uint_4 ii = i%mLenBuf;
+        r_8 s = a0+(a1+a2*(mX[ii]-mX0))*(mX[ii]-mX0) - (mY[ii]-mY0);
+	spar += s*s;
+      }
+      spar /= (r_8) mNCur;
+    } else {
+      spar = (mSy2 +a0*a0*mNCur +a1*a1*mSx2 +a2*a2*mSx4 -2.*mSy*a0 -2.*a1*mSxy
+              -2.*a2*mSx2y +2.*a0*a1*mSx +2.*a0*a2*mSx2 +2.*a1*a2*mSx3)
+             / (r_8) mNCur;
+    }
+    // gestion du decalage y-y0 = a0 + a1*(x-x0) + a2*(x-x0)^2
+    a0 = mY0 + a0 - a1*mX0 + a2*mX0*mX0;
+    a1 = a1 - 2.*a2*mX0;
+
+    if(spar>0.) return sqrt(spar);
+    if(spar<0.) return -sqrt(-spar);
+    return spar;
+  }
+
+  //***************************************************************** 
+  void Print(int lp=0)
+  // ---- Print de l'etat de la classe
+  //      lp = 0 : parametres
+  //           1 :            + sommes
+  //           2 :                     + tableaux
+  {
+    cout<<"SLinParBuff(LenBuf="<<mLenBuf<<",NResynch="<<mNResynch
+        <<",auto_xy0="<<mAutoXY0
+        <<"): mX0="<<mX0<<" mY0="<<mY0<<" mNCur="<<mNCur<<endl
+        <<"           NPush="<<mNPush<<" NPop="<<mNPop
+        <<" NSynchro="<<mNResynchEff<<endl;
+    if(mNCur==0) return;
+    if(lp>=2) {
+      cout<<"X:";
+      if(mX) for(uint_4 i=0;i<mNCur;i++) {
+        uint_4 ii = (mIDeb+i)%mLenBuf;
+        cout<<" "<<mX[ii]; if(i%10==9 || i==mNCur-1) cout<<endl;
+      }
+      if(mY) cout<<"Y:";
+      for(uint_4 i=0;i<mNCur;i++) {
+        uint_4 ii = (mIDeb+i)%mLenBuf;
+        cout<<" "<<mY[ii]; if(i%10==9 || i==mNCur-1) cout<<endl;
+      }
+    }
+    if(lp>=1) {
+      cout<<"...IDeb="<<mIDeb<<" IResynch="<<mIResynch<<endl;
+      cout<<"   Sx="<<mSx<<" Sx2="<<mSx2<<" Sx3="<<mSx3<<" Sx4="<<mSx4<<endl
+          <<"   Sy="<<mSy<<" Sy2="<<mSy2<<" Sxy="<<mSxy<<" Sx2y="<<mSx2y<<endl;
+    }
+  }
+
+  void PrintCompute(int lp=0)
+  // ---- Print des valeurs numeriques calculees
+  //      lp = 0 : valeurs calculees
+  //           1 :             + sommes
+  {
+    bool recompute = (mX==NULL || mY==NULL) ? false: true;
+    r_8 mean;
+    r_8 sigma = Compute(mean,recompute), sigmar = Compute(mean,false);
+    cout<<"SLinParBuff: n="<<NPoints()<<" mean="<<mean
+        <<" sigma="<<sigma<<" (raw="<<sigmar<<")"<<endl;
+    r_8 a0,a1,a2;
+    r_8 slin  = Compute(a0,a1,recompute), slinr  = Compute(a0,a1,false);
+    cout<<"             a0="<<a0<<" a1="<<a1
+        <<" slin="<<slin<<" (raw="<<slinr<<")"<<endl;
+    r_8 spar = Compute(a0,a1,a2,recompute), sparr = Compute(a0,a1,a2,false);
+    cout<<"             a0="<<a0<<" a1="<<a1<<" a2="<<a2
+        <<" spar="<<spar<<" (raw="<<sparr<<")"<<endl;
+    if(lp<1) return;
+    cout<<"...Sx="<<mSx<<" Sx2="<<mSx2<<" Sx3="<<mSx3<<" Sx4="<<mSx4<<endl
+        <<"   Sy="<<mSy<<" Sy2="<<mSy2<<" Sxy="<<mSxy<<" Sx2y="<<mSx2y<<endl;
+  }
+
+protected:
+  uint_4 mLenBuf,mNResynch;
+  r_8 *mX,*mY, mX0, mY0;
+  bool mAutoXY0;
+  uint_4 mNCur,mIDeb,mIResynch;
+  r_8 mSx,mSy,mSx2,mSy2,mSxy, mSx3,mSx2y, mSx4;
+  uint_4 mNResynchEff, mNPush, mNPop;
+};
+
+///////////////////////////////////////////////////////////////////
+// That Class allows merging of SLinParBuff Class for computing  //
+// parameters.
+// ex:
+// SLinParBuff s1;  -> Fill s1
+// SLinParBuff s2;  -> Fill s2
+// SLinParBuff s3;  -> Fill s3
+// SLinParBuffMerger smerge(s1);
+//   sig = smerge.Compute(mean); -> same as sig = s1.Compute(mean);
+// smerge.Add(s2);
+//   sig = smerge.Compute(mean); -> sig and mean are those for
+class SLinParBuffMerger {
+public:
+  SLinParBuffMerger(void) {mFirst=true; mSlp.Reset();}
+  SLinParBuffMerger(SLinParBuff& s,bool recompute=false)
+                   {mFirst=true; mSlp.Reset(); Add(s,recompute);}
+  virtual ~SLinParBuffMerger(void) {}
+  inline uint_4  NPoints(void) {return mSlp.NPoints();}
+  inline void Reset(void) {mSlp.Reset(); mFirst=true;}
+  inline void Add(SLinParBuff& s,bool recompute=false)
+  {
+    bool changex0y0=false, AutoXY0_Save; r_8 X0_Save,Y0_Save;
+    if(mFirst) {
+      // Cas ou c'est le premier SLinParBuff additionne.
+      mSlp.mX0=s.mX0; mSlp.mY0=s.mY0; mFirst=false;
+    } else if(mSlp.mX0!=s.mX0 || mSlp.mY0!=s.mY0) {
+      // Attention: pour merger il faut avoir les memes mX0,mY0
+      changex0y0=true;
+      X0_Save=s.mX0; Y0_Save=s.mY0; AutoXY0_Save=s.mAutoXY0;
+      s.mX0=mSlp.mX0; s.mY0=mSlp.mY0; s.mAutoXY0=false;
+      recompute=true;
+    }
+    if(recompute) s.ReComputeSum();
+    mSlp.mNCur += s.mNCur;
+    mSlp.mSx   += s.mSx;
+    mSlp.mSy   += s.mSy;
+    mSlp.mSx2  += s.mSx2;
+    mSlp.mSy2  += s.mSy2;
+    mSlp.mSxy  += s.mSxy;
+    mSlp.mSx3  += s.mSx3;
+    mSlp.mSx2y += s.mSx2y;
+    mSlp.mSx4  += s.mSx4;
+    // Dans le cas ou on a change les X0,Y0, on remet en etat
+    if(changex0y0) {
+      s.mX0=X0_Save; s.mY0=Y0_Save;
+      s.ReComputeSum();
+      s.mAutoXY0=AutoXY0_Save;
+    }
+  }
+  inline r_8 Compute(r_8& mean)
+              {return mSlp.Compute(mean);}
+  inline r_8 Compute(r_8& a0,r_8 &a1)
+              {return mSlp.Compute(a0,a1);}
+  inline r_8 Compute(r_8& a0,r_8 &a1,r_8 &a2)
+              {return mSlp.Compute(a0,a1,a2);}
+  inline void Print(int lp=0) {mSlp.Print(lp);}
+  inline void PrintCompute(int lp=0) {mSlp.PrintCompute(lp);}
+
+protected:
+  bool mFirst;
+  SLinParBuff mSlp;
+};
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/swapbytes.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/swapbytes.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/swapbytes.h	(revision 2309)
@@ -0,0 +1,40 @@
+/*  Macro pour faire des bytes-swap        */
+/*                   CMV+Reza Fev 98       */
+
+#ifndef  SWAPBYTES_H_SEEN
+#define  SWAPBYTES_H_SEEN
+
+/*  Les arguments des define sont consideres comme pointeur */
+
+#define  Swap_Bytes8(_x8_)                                 \
+{                                                          \
+  uint_8 _tmp_ = *(uint_8*)(_x8_);                         \
+  *(uint_8*)(_x8_) = ((_tmp_ >> (7*8)) & 0x000000FF) |     \
+                     ((_tmp_ >> (5*8)) & 0x0000FF00) |     \
+                     ((_tmp_ >> (3*8)) & 0x00FF0000) |     \
+                     ((_tmp_ >> (1*8)) & 0xFF000000) |     \
+                     ((_tmp_ & 0xFF000000) << (1*8))  |    \
+                     ((_tmp_ & 0x00FF0000) << (3*8))  |    \
+                     ((_tmp_ & 0x0000FF00) << (5*8))  |    \
+                     ((_tmp_ & 0x000000FF) << (7*8));      \
+}
+
+
+#define  Swap_Bytes4(_x4_)                                 \
+{                                                          \
+  uint_4 _tmp_ = *(uint_4*)(_x4_);                         \
+  *(uint_4*)(_x4_) = ((_tmp_ >> 24) & 0x000000FF) |        \
+                     ((_tmp_ >> 8)  & 0x0000FF00) |        \
+                     ((_tmp_ & 0x0000FF00) << 8)  |        \
+                     ((_tmp_ & 0x000000FF) << 24);         \
+}
+
+
+#define  Swap_Bytes2(_x2_)                                 \
+{                                                          \
+  uint_2 _tmp_ = *(uint_2*)(_x2_);                         \
+  *(uint_2*)(_x2_) = ((_tmp_ >> 8) & 0x00FF) |             \
+                     ((_tmp_ & 0x00FF) << 8);              \
+}
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/tabmath.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/tabmath.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/tabmath.cc	(revision 2309)
@@ -0,0 +1,41 @@
+#include "machdefs.h"
+#include "tabmath.h"
+
+///////////////////////////////
+//  Exponentielles tabulees  //
+///////////////////////////////
+
+TabFExp::TabFExp()
+{
+  tab = new double[10000];
+
+  for(int i=0; i<10000; i++)
+    tab[i] = exp(-(double)i*0.001) ;
+}
+
+TabFExp::~TabFExp()
+{
+  delete[] tab;
+}
+
+TabFExp* SOPHYA::ptabFExp;
+
+////////////////////////////////////
+//    Sinus tabules (et Cosinus)  //
+////////////////////////////////////
+
+TabFSin::TabFSin(int n)
+{
+  if(n<=1) n=10000;
+  tab = new double[n];
+  delta = Pi/2. / (double) (n-1);
+  for(int i=0; i<n; i++)
+    tab[i] = sin((double)i* delta) ;
+}
+
+TabFSin::~TabFSin()
+{
+  delete[] tab;
+}
+
+TabFSin* SOPHYA::ptabFSin;
Index: /tags/V_Dec2002/SophyaLib/NTools/tabmath.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/tabmath.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/tabmath.h	(revision 2309)
@@ -0,0 +1,65 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Tabulated math functions
+//   E. Aubourg, C. Magneville  1996-2000
+// DAPNIA/SPP (Saclay) / CEA    LAL - IN2P3/CNRS  (Orsay)
+
+#ifndef TABMATH_H_SEEN
+#define TABMATH_H_SEEN
+
+#include <math.h>
+#include "peida.h"
+#include "nbconst.h"
+
+namespace SOPHYA {  
+
+///////////////////////////////
+//  Exponentielles tabulees  //
+///////////////////////////////
+
+class TabFExp  {
+public:
+  TabFExp();
+  ~TabFExp();
+  inline double operator()(double x)
+    { if (x > 0) return exp(x);
+      if (x <= -10) return 0;
+          return tab[int(-x*1000)];
+    }
+private:
+  double* tab;
+};
+
+extern TabFExp* ptabFExp;
+#define tabFExp(_x_) ((*ptabFExp)(_x_))
+
+
+////////////////////////////////////
+//    Sinus tabules (et Cosinus)  //
+////////////////////////////////////
+
+class TabFSin  {
+public:
+  TabFSin(int ntab = 0);
+  ~TabFSin();
+  inline double operator()(double x)
+    {
+    double s = 1.;
+    if(x<0.) {x *=-1.; s = -1.;}
+    x -= DeuxPi * int(x/DeuxPi);
+    if(x>Pi) {x -= Pi; s *= -1.;}
+    if(x>Pi/2.) x = Pi-x;
+    return s * tab[int(x/delta)];
+    }
+private:
+  int ntab;
+  double delta;
+  double* tab;
+};
+
+extern TabFSin* ptabFSin;
+#define tabFSin(_x_) ((*ptabFSin)(_x_))
+#define tabFCos(_x_) ((*ptabFSin)(_x_+Pis2))
+
+} // namespace SOPHYA
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/NTools/trigtbl.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/NTools/trigtbl.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/NTools/trigtbl.h	(revision 2309)
@@ -0,0 +1,169 @@
+#ifndef  TRIGTBL_H_SEEN
+#define  TRIGTBL_H_SEEN
+
+/*
+** Please only distribute this with it's associated FHT routine.
+** This algorithm is apparently patented(!) and the code copyrighted. 
+** See the comment with the fht routine for more info.
+**   -Thanks,
+**   Ron Mayer
+*/
+
+#ifdef REAL
+#else
+#define REAL double
+#endif
+
+#ifdef GOOD_TRIG
+#else
+#define FAST_TRIG
+#endif
+
+#if defined(GOOD_TRIG)
+#define FHT_SWAP(a,b,t) {(t)=(a);(a)=(b);(b)=(t);}
+#define TRIG_VARS					         \
+      int t_lam=0;
+#define TRIG_INIT(k,c,s)					 \
+     {								 \
+      int i;							 \
+      for (i=2 ; i<=k ; i++)					 \
+          {coswrk[i]=costab[i];sinwrk[i]=sintab[i];}		 \
+      t_lam = 0;					         \
+      c = 1;							 \
+      s = 0;							 \
+     }
+#define TRIG_NEXT(k,c,s)					 \
+     {								 \
+	 int i,j;	                                         \
+         (t_lam)++;	  					 \
+         for (i=0 ; !((1<<i)&t_lam) ; i++);			 \
+         i = k-i;						 \
+         s = sinwrk[i];						 \
+         c = coswrk[i];						 \
+         if (i>1)   						 \
+            {	    						 \
+             for (j=k-i+2 ; (1<<j)&t_lam ; j++);		 \
+             j	       = k - j;					 \
+             sinwrk[i] = halsec[i] * (sinwrk[i-1] + sinwrk[j]);  \
+             coswrk[i] = halsec[i] * (coswrk[i-1] + coswrk[j]);  \
+            }                                                    \
+     }
+#define TRIG_RESET(k,c,s)
+#endif
+
+#if defined(FAST_TRIG)
+#define TRIG_VARS					 \
+      REAL t_c,t_s;
+#define TRIG_INIT(k,c,s)				 \
+    {				        		 \
+     t_c  = costab[k];				         \
+     t_s  = sintab[k];				         \
+     c    = 1;				    		 \
+     s    = 0;				    		 \
+    }
+#define TRIG_NEXT(k,c,s)				 \
+    {                                                    \
+     REAL t = c;                                         \
+     c   = t*t_c - s*t_s;				 \
+     s   = t*t_s + s*t_c;				 \
+    }
+#define TRIG_RESET(k,c,s)
+#endif
+
+static REAL halsec[20]=
+    {
+     0,
+     0,
+     .54119610014619698439972320536638942006107206337801,
+     .50979557910415916894193980398784391368261849190893,
+     .50241928618815570551167011928012092247859337193963,
+     .50060299823519630134550410676638239611758632599591,
+     .50015063602065098821477101271097658495974913010340,
+     .50003765191554772296778139077905492847503165398345,
+     .50000941253588775676512870469186533538523133757983,
+     .50000235310628608051401267171204408939326297376426,
+     .50000058827484117879868526730916804925780637276181,
+     .50000014706860214875463798283871198206179118093251,
+     .50000003676714377807315864400643020315103490883972,
+     .50000000919178552207366560348853455333939112569380,
+     .50000000229794635411562887767906868558991922348920,
+     .50000000057448658687873302235147272458812263401372
+    };
+static REAL costab[20]=
+    {
+     .00000000000000000000000000000000000000000000000000,
+     .70710678118654752440084436210484903928483593768847,
+     .92387953251128675612818318939678828682241662586364,
+     .98078528040323044912618223613423903697393373089333,
+     .99518472667219688624483695310947992157547486872985,
+     .99879545620517239271477160475910069444320361470461,
+     .99969881869620422011576564966617219685006108125772,
+     .99992470183914454092164649119638322435060646880221,
+     .99998117528260114265699043772856771617391725094433,
+     .99999529380957617151158012570011989955298763362218,
+     .99999882345170190992902571017152601904826792288976,
+     .99999970586288221916022821773876567711626389934930,
+     .99999992646571785114473148070738785694820115568892,
+     .99999998161642929380834691540290971450507605124278,
+     .99999999540410731289097193313960614895889430318945,
+     .99999999885102682756267330779455410840053741619428
+    };
+static REAL sintab[20]=
+    {
+     1.0000000000000000000000000000000000000000000000000,
+     .70710678118654752440084436210484903928483593768846,
+     .38268343236508977172845998403039886676134456248561,
+     .19509032201612826784828486847702224092769161775195,
+     .09801714032956060199419556388864184586113667316749,
+     .04906767432741801425495497694268265831474536302574,
+     .02454122852291228803173452945928292506546611923944,
+     .01227153828571992607940826195100321214037231959176,
+     .00613588464915447535964023459037258091705788631738,
+     .00306795676296597627014536549091984251894461021344,
+     .00153398018628476561230369715026407907995486457522,
+     .00076699031874270452693856835794857664314091945205,
+     .00038349518757139558907246168118138126339502603495,
+     .00019174759731070330743990956198900093346887403385,
+     .00009587379909597734587051721097647635118706561284,
+     .00004793689960306688454900399049465887274686668768
+    };
+static REAL coswrk[20]=
+    {
+     .00000000000000000000000000000000000000000000000000,
+     .70710678118654752440084436210484903928483593768847,
+     .92387953251128675612818318939678828682241662586364,
+     .98078528040323044912618223613423903697393373089333,
+     .99518472667219688624483695310947992157547486872985,
+     .99879545620517239271477160475910069444320361470461,
+     .99969881869620422011576564966617219685006108125772,
+     .99992470183914454092164649119638322435060646880221,
+     .99998117528260114265699043772856771617391725094433,
+     .99999529380957617151158012570011989955298763362218,
+     .99999882345170190992902571017152601904826792288976,
+     .99999970586288221916022821773876567711626389934930,
+     .99999992646571785114473148070738785694820115568892,
+     .99999998161642929380834691540290971450507605124278,
+     .99999999540410731289097193313960614895889430318945,
+     .99999999885102682756267330779455410840053741619428
+    };
+static REAL sinwrk[20]=
+    {
+     1.0000000000000000000000000000000000000000000000000,
+     .70710678118654752440084436210484903928483593768846,
+     .38268343236508977172845998403039886676134456248561,
+     .19509032201612826784828486847702224092769161775195,
+     .09801714032956060199419556388864184586113667316749,
+     .04906767432741801425495497694268265831474536302574,
+     .02454122852291228803173452945928292506546611923944,
+     .01227153828571992607940826195100321214037231959176,
+     .00613588464915447535964023459037258091705788631738,
+     .00306795676296597627014536549091984251894461021344,
+     .00153398018628476561230369715026407907995486457522,
+     .00076699031874270452693856835794857664314091945205,
+     .00038349518757139558907246168118138126339502603495,
+     .00019174759731070330743990956198900093346887403385,
+     .00009587379909597734587051721097647635118706561284,
+     .00004793689960306688454900399049465887274686668768
+    };
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/SUtils/Makefile
===================================================================
--- /tags/V_Dec2002/SophyaLib/SUtils/Makefile	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SUtils/Makefile	(revision 2309)
@@ -0,0 +1,19 @@
+include ../Mgr/Makefile.h
+ 
+all: $(LIB)libSUtils.a
+clean:
+	rm -f $(OBJ)datacards.o $(OBJ)strutilxx.o $(OBJ)utils.o $(OBJ)strutil.o
+	rm -f $(LIB)libSUtils.a
+$(LIB)libSUtils.a : $(OBJ)datacards.o $(OBJ)strutil.o $(OBJ)strutilxx.o $(OBJ)utils.o
+	$(ARCXX) $(ARCXXFLAGS) $@ $($(ARARGS))
+ifeq ($(CXX),cxx)
+	$(CXX) $? $(CPPFLAGS) $(CXXFLAGS) -o $(OBJ)xx.x -Hf
+endif 
+ 
+$(OBJ)datacards.o: datacards.cc $(INC)machdefs.h \
+ datacards.h $(INC)pexceptions.h
+$(OBJ)strutilxx.o: strutilxx.cc $(INC)machdefs.h \
+ strutilxx.h
+$(OBJ)utils.o: utils.cc $(INC)machdefs.h utils.h \
+ $(INC)pexceptions.h
+$(OBJ)strutil.o: strutil.c strutil.h
Index: /tags/V_Dec2002/SophyaLib/SUtils/datacards.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SUtils/datacards.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SUtils/datacards.cc	(revision 2309)
@@ -0,0 +1,377 @@
+//
+// $Id: datacards.cc,v 1.8 2001-07-31 14:02:38 cmv Exp $
+//
+//
+// Eric Aubourg, R. Ansari 1995-2000
+//               PEIDA (EROS) - SOPHYA
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+
+#include "machdefs.h"
+#include "datacards.h"
+#include "pexceptions.h"
+#include <algorithm>
+#include <iostream.h>
+#include <iomanip.h>
+#include <stdio.h>
+
+//++
+// Class	DataCards
+// Lib		SUtils
+// include	datacards.h
+//
+//   	Cette classe permet la gestion des parametres d'un programme a partir 
+//   	de mot-cle (lecture d'un fichier par exemple)
+//--
+
+
+//++
+// Titre	Constructeurs
+//--
+//++
+//
+// DataCards()
+// DataCards(string const& fn)
+//    Createur avec lecture des parametres ds le fichier de nom "fn"
+//--
+
+/*! 
+    \class SOPHYA::DataCards
+    \ingroup SUtils
+    This class can be used for decoding program parameters from an ascii
+    file. Each line of the ascii contains a keyword starting with \b @ .
+    Lines with any other character in the first column are treated as comments.
+    Keywords can be followed by 0 or more parameters.
+    Processing functions (\b ProcCard) can automatically be called for
+    keywords matching a given pattern. (see \b AddProcF )
+*/ 
+
+/* Default constructor */
+DataCards::DataCards()
+{
+}
+
+/*! constructor with the specification of a parameter file */
+DataCards::DataCards(string const& fn)
+{
+  ReadFile(fn);
+}
+
+//++
+// Titre	Methodes
+//--
+//++
+// AddProcF(ProcCard f, string const& mtch="*")
+//	Ajoute une fonction de traitement a la liste pour les mots cle
+//      compatibles avec la chaine "mtch" ("mtch" peut contenir "*" en debut 
+//      fin de mot) 
+//
+// Clear()
+//	Supprime les cartes existantes
+//
+// ReadFile(string const& fn) 
+//      Lit le contenu du fichiers "fn" et ajoute les cartes a la liste
+//
+// AppendCard(string const& line)
+//	Rajoute la carte "line" a la liste
+//--
+
+/*! 
+    Adds a new processing function for all keywords matching the 
+    specified pattern.
+    \param mtch : The pattern - can contain * 
+*/
+void
+DataCards::AddProcF(ProcCard f, string const& mtch)
+{
+CrdPF mpf;
+if (f == NULL)  return;
+mpf.pf = f;
+if (mtch.length() <= 0)  mpf.patt = "*";
+else  mpf.patt = mtch;
+cpfs.push_back(mpf);
+
+// On applique cette nouvelle fonction aux cartes existantes
+CardList::iterator  ic;
+for(ic = cards.begin(); ic != cards.end(); ic ++)
+  {
+  vector<string>::iterator ik;
+  string tks;
+  for(ik = (*ic).tokens.begin(); ik != (*ic).tokens.end(); ik++)
+    tks = tks + " " + (*ik);
+  ApplyPF(mpf, (*ic).kw, tks);
+  }
+}
+
+/*! Resets the objects - Suppresses all cards  */
+void DataCards::Clear()
+{
+cards.erase(cards.begin(), cards.end());
+}
+
+/*! Reads the file named \b fn. if fn=="" the value of \b SOPHYA_DATACARDS is used */
+void
+DataCards::ReadFile(string const& fn)
+{
+  string file = fn;
+  if (file == "") {
+    char * efn = getenv("SOPHYA_DATACARDS");
+    if (efn != NULL)    file = efn;  
+  }
+  if (file == "")  return;
+
+  try {
+    DoReadFile(file);
+  } catch(...) {
+    char* wdp = getenv("SOPHYA_WORK");
+    if (wdp) {
+      cerr << "DataCards::ReadFile() Error reading file " << fn << " (Trying with SOPHYA_WORK) \n";
+      file = wdp + file;
+      DoReadFile(file);
+    }
+    else cerr << "DataCards::ReadFile() Error reading file " << fn << "\n";
+    throw IOExc("DataCards::ReadFile() Error");  
+  } 
+}
+
+/*! Appends a card, represented by the string \b crd to the list of cards */
+void
+DataCards::AppendCard(string const& crd)
+{
+Card c;
+size_t p = 1;
+size_t q = crd.find_first_of(" \t");
+size_t l = crd.length();
+
+string toks;
+if (l < 2)  return;
+if (crd[0] != '@')  return;
+
+if (q < l)
+  {  c.kw = crd.substr(p,q-p);  toks = crd.substr(q, l-q); }
+else { c.kw = crd.substr(p,l-p);  toks = ""; }
+//  On applique les ProcFunc's
+ApplyPFL(c.kw, toks);
+while (q < l) 
+  {
+  p = crd.find_first_not_of(" \t",q+1); // au debut d'un token
+  if (p>=l) break;
+  q = crd.find_first_of(" \t",p); // la fin du token;
+  string token = crd.substr(p,q-p);
+  c.tokens.push_back(token);
+  }
+// On supprime la carte de la liste, si elle existe deja ...
+RemoveCard(c.kw);
+cards.push_back(c);
+}
+
+
+//++
+// Titre	Acces aux parametres
+//--
+//++
+// int   NbCards()
+//	Renvoie le nombre de cartes data
+// bool	 HasKey(string const& key) 
+//	Indique l'existence d'une carte avec la cle "key"
+// int   NbParam(string const& key)
+//	Indique le nombre de parametre (separes par des espaces) pour la cle "key"
+// string  SParam(string const& key, int num = 0, string def="")
+//	Renvoie la valeur du parametre numero "num" ( 0..(NbParam()-1) ) sous forme de
+//	chaine de caracteres ("string")
+// long    IParam(string const& key, int numero = 0, long def = 0)
+//	Renvoie la valeur du parametre numero "num" ( 0..(NbParam()-1) ) convertie 
+//	en entier ("long")
+// double  DParam(string const& key, int numero = 0, double def = 0)
+//	Renvoie la valeur du parametre numero "num" ( 0..(NbParam()-1) ) convertie 
+//	en flottant ("double")
+//--
+
+
+/*! Returns true if \b key is present in the list */
+bool
+DataCards::HasKey(string const& key) const
+{
+  return (FindKeyC(key) != cards.end());
+}
+
+//! Returns the total number of cards 
+int 
+DataCards::NbCards() const
+{
+return(cards.size());
+}
+
+/*! Returns the number of parameters for card \b key. (-1) if \b key not present  */
+int 
+DataCards::NbParam(string const& key) const
+{
+  DataCards::CardList::const_iterator it = FindKeyC(key);
+  if (it == cards.end()) return(-1);
+  else return((*it).tokens.size());
+}
+
+/*! Returns the key for card number \b num. */ 
+string 
+DataCards::GetKey(int num) const
+{
+  if ((num < 0) || (num >= cards.size()) )  return("");
+  int k = 0;
+  CardList::const_iterator i;
+  for(i=cards.begin(); i != cards.end(); i++) {
+    if (k == num)  return((*i).kw);
+    else k++;
+  }
+  return("");
+}
+
+/*! Returns the list of parameters for card \b key. */ 
+string 
+DataCards::GetParams(string const& key) const
+{
+  string rs;
+  DataCards::CardList::const_iterator it = FindKeyC(key);
+  if (it == cards.end()) return(rs);
+  for (int k=0; k<(*it).tokens.size(); k++) {
+    rs += ' ';  rs += (*it).tokens[k];
+  }
+  return(rs);
+}
+
+/*! Returns the parameter number \b numero for card \b key */
+string
+DataCards::SParam(string const& key, int numero, string def) const
+{
+  DataCards::CardList::const_iterator it = FindKeyC(key);
+  if (it == cards.end()) return(def);
+  if ( (numero < 0) || (numero >= (*it).tokens.size()) )  return def;
+  return (*it).tokens[numero];
+}
+
+/*! Returns the parameter number \b numero for card \b key, converted to type long */
+long
+DataCards::IParam(string const& key, int numero, long def) const
+{
+  string p = SParam(key, numero, "");
+  if (p == "") return def;
+  long i;
+  //istrstream(p.c_str(), p.length()) >> i;
+  sscanf(p.c_str(),"%ld",&i);
+  return i;
+}
+
+/*! Returns the parameter number \b numero for card \b key, converted to type double */
+double
+DataCards::DParam(string const& key, int numero, double def) const
+{
+  string p = SParam(key, numero, "");
+  if (p == "") return def;
+  double i;
+  //istrstream(p.c_str(), p.length()) >> i;
+  sscanf(p.c_str(),"%lg",&i);
+  return i;
+}
+
+   
+/*! Prints the list of cards on the output stream \b s */
+void
+DataCards::Print(ostream& s) const
+{
+  for (CardList::const_iterator i = cards.begin(); i != cards.end(); i++) {
+    s << setw(10) << (*i).kw << " ";
+    for (vector<string>::const_iterator j = (*i).tokens.begin(); j != (*i).tokens.end(); j++)
+      s << (*j) << " ";
+    s << endl;
+  }
+}
+
+/*! Reads the file named \b fn. */
+void
+DataCards::DoReadFile(string const& fn)
+{
+  char line_buff[512];
+  FILE *fip;
+
+  if ( (fip = fopen(fn.c_str(),"r")) == NULL )  
+    throw IOExc("DataCards::DoReadFile() fopen Error ") ;
+  while (fgets(line_buff,511,fip) != NULL) {
+    line_buff[strlen(line_buff)-1] = '\0';   /*  LF/CR de la fin */
+    string line(line_buff);
+    AppendCard(line);
+  }
+  fclose(fip);
+  return;
+}
+
+int
+DataCards::ApplyPF(CrdPF & cpf, string const& key, string const& toks)
+{
+int l,lk;
+int rc = 0;
+// On verifie si le "pattern" correspond
+bool mtch = false;
+l = cpf.patt.length(); 
+if (cpf.patt == "*")  mtch = true;
+else if (cpf.patt[0] == '*')   
+  {
+  lk = key.length();
+  if (cpf.patt[l-1] != '*')
+    {
+    if (strcmp(key.c_str()+(lk-l+1), cpf.patt.c_str()+1) == 0)   mtch = true;
+    }
+  else if  (key.find(cpf.patt.substr(1,l-2)) < lk)  mtch = true;
+  }
+else if (cpf.patt[l-1] == '*')
+  {
+  if ( strncmp(key.c_str(), cpf.patt.c_str(),l-1) == 0)  mtch = true;
+  }
+else if (key == cpf.patt)  mtch = true;
+
+// Si oui, on appelle la fonction correspondante
+if (mtch)  rc = cpf.pf(key, toks); 
+
+return(rc);
+}
+
+
+int
+DataCards::ApplyPFL(string const& key, string const& toks)
+{
+int rc = 0;
+CrdPFList::iterator icf;
+for(icf = cpfs.begin(); icf != cpfs.end(); icf++)
+  rc += ApplyPF((*icf), key, toks);
+return(rc);
+}
+
+void  
+DataCards::RemoveCard(string const& key)
+{
+CardList::iterator i;
+for(i=cards.begin(); i != cards.end(); i++)
+  if ((*i).kw == key) { cards.erase(i);  break;  }
+}
+
+DataCards::Card *
+DataCards::FindKey(string const& key) 
+{
+/*
+  CardList::iterator i = find_if(cards.begin(), cards.end(), bind2nd(KeyEq(),key));
+  if (i == cards.end() ) return NULL;
+*/
+  CardList::iterator i;
+  for(i=cards.begin(); i != cards.end(); i++)
+    if ((*i).kw == key) return &(*i);
+
+  return NULL;
+}
+
+
+DataCards::CardList::const_iterator
+DataCards::FindKeyC(string const& key) const
+{
+  CardList::const_iterator i;
+  for(i=cards.begin(); i != cards.end(); i++)
+    if ((*i).kw == key) return i;
+  return cards.end();
+}
Index: /tags/V_Dec2002/SophyaLib/SUtils/datacards.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SUtils/datacards.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SUtils/datacards.h	(revision 2309)
@@ -0,0 +1,102 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// $Id: datacards.h,v 1.4 2000-10-24 17:35:04 ansari Exp $
+//
+// Datacards, acquisition EROS II
+//
+//
+// Eric Aubourg, Decembre 95
+// Reza Ansari, Aout 96
+//
+// DAPNIA/SPP (Saclay) / CEA    LAL - IN2P3/CNRS  (Orsay)
+
+#ifndef DATACARDS_SEEN
+#define DATACARDS_SEEN
+
+#include "machdefs.h"
+#include <string.h>
+#include <string>
+#include <functional>
+#include <list>
+#include <vector>
+
+
+namespace SOPHYA {  
+
+typedef int (*ProcCard)(string const& key, string const& toks);
+ 
+//! Class for decoding parameters from  an ascii file.
+    
+class DataCards  {
+public:
+
+   DataCards();                  
+   DataCards(string const& fn);
+
+           // nom dans variable d'environnement SOPHYA_DATACARDS
+           // par defaut, sophya.datacards                        
+           // Si pas chemin complet, on tente dans repertoire 
+           // en cours, puis dans SOPHYA_WORK
+
+   virtual ~DataCards() {}
+
+   void    AddProcF(ProcCard f, string const& mtch="*");
+
+   void    Clear();
+   void    ReadFile(string const& fn);
+   void    AppendCard(string const& line);
+
+   int     NbCards() const; 
+   bool    HasKey(string const& key) const;
+   int     NbParam(string const& key) const;
+   string  GetKey(int num) const;
+   string  GetParams(string const& key) const;
+   string  SParam(string const& key, int numero = 0, string def="") const;
+   long    IParam(string const& key, int numero = 0, long def = 0) const;
+   double  DParam(string const& key, int numero = 0, double def = 0) const;
+   
+   void    Print(ostream& s) const;
+
+protected:
+   struct Card {
+     string kw;
+     vector<string> tokens;
+     bool operator == (Card const & b) const { return(kw == b.kw); }
+     bool operator < (Card const & b) const { return(kw < b.kw); }
+   };
+   struct CrdPF {
+     ProcCard pf;
+     string  patt;
+     bool operator == (CrdPF const & b) const { return(pf == b.pf); }
+     bool operator < (CrdPF const & b) const { return(pf == b.pf); }
+   };
+
+   void  DoReadFile(string const& fn);
+
+   int   ApplyPF(CrdPF & cpf, string const& key, string const& toks);
+   int   ApplyPFL(string const& key, string const& toks);
+
+   void  RemoveCard(string const& key);
+   
+   Card* FindKey(string const& key) ;
+
+   typedef list<Card> CardList;
+   typedef list<CrdPF> CrdPFList;
+
+   CardList::const_iterator FindKeyC(string const& key) const;
+
+   CardList cards;
+   CrdPFList cpfs;
+
+   struct KeyEq : binary_function<Card, string, bool> {
+    bool operator()(const Card& x, const string& y) const { return x.kw == y; }
+   };
+};
+
+//! operator << overloading - calls Print()
+inline ostream& operator << (ostream& s, DataCards const & c)
+{ c.Print(s); return s; }
+
+} // namespace SOPHYA
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/SUtils/objlist.list
===================================================================
--- /tags/V_Dec2002/SophyaLib/SUtils/objlist.list	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SUtils/objlist.list	(revision 2309)
@@ -0,0 +1,4 @@
+datacards.o
+strutil.o
+strutilxx.o
+utils.o
Index: /tags/V_Dec2002/SophyaLib/SUtils/strutil.c
===================================================================
--- /tags/V_Dec2002/SophyaLib/SUtils/strutil.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SUtils/strutil.c	(revision 2309)
@@ -0,0 +1,534 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include "strutil.h"
+
+/* 
+++ 
+  Module	Strutil (C)
+  Lib	LibsUtil
+  include	strutil.h
+
+	Groupe de fonction de gestion et manipulation
+	des chaines de caracteres.
+--
+*/
+
+/*
+++
+  char* itoc(int in, char* s, int nDigits)
+	conversion entier-chaine de caracteres
+--
+*/
+/*
+++
+  ctoi(const char* cst, int *ipt)
+	convertit une chaine de caractere en entier
+--
+*/
+/*
+++
+  ctol(const char* cst, long int *lpt)
+	convertit une chaine de caractere en entier long
+--
+*/
+/*
+++
+  ctof(const char* cst, double *fpt)
+	convertit une chaine de caractere en flottant
+--
+*/
+/*
+++
+  posc(const char* cst, char sec)
+	trouve la position d'un caractere dans une chaine
+	(premier charactere rencontre)
+--
+*/
+/*
+++
+  poslc(const char* cst, char sec)
+	trouve la position d'un caractere dans une chaine
+	(dernier charactere rencontre)
+--
+*/
+/*
+++
+  strip(char cst[], char opt, char bc)
+	permet d'enlever les blancs au debut ou a la fin d'une
+	chaine de caractere
+--
+*/
+/*
+++
+  padstr(spo,lpa,bc)
+	Cette  fonction  rajoute  des blancs a la fin de la chaine `spo'
+	pour amener la longueur de la chaine a `lpa'. Les caracteres
+	rajoutes a la fin sont `bc'. La fonction retourne le nombre de
+	blancs (caracteres bc)  rajoutes a la fin.
+--
+*/
+/*
+++
+  tomaj(char *cbuff)
+	Changement en majuscule d'une chaine de caracteres
+--
+*/
+/*
+++
+  tomin(char *cbuff)
+	Changement en minuscule d'une chaine de caracteres
+--
+*/
+/*
+++
+  efface(char *cbuff,int lbuff,char c)
+	Remplace un caractere avec des blancs
+--
+*/
+/*
+++
+  csh_parse(const char* x, const char* yp)
+	Compare la chaine de caracteres `x' avec la chaine `yp'
+	comprenant des regles de substitution type c-shell
+	(asterisque et point d'interrogation).
+--
+*/
+/*
+  DecArgList()
+	Decoder une liste du type a,b,c-d,e,f-g,h...
+*/
+ 
+
+/*            Fonction  itoc()    */
+char* itoc(int in, char* s, int nDigits)
+{
+  int i,j,n;
+  n=abs(in);
+  for(i=0;i<nDigits;i++)
+    s[i]=' ';
+  s[nDigits-1]='\0';
+  j=nDigits-2;
+  for (i=j; i>=0; i--)
+   {
+    int x = n % 10;
+    n /= 10;
+    s[i] = '0' + x;
+    if(n==0) break;
+   }
+  if(in < 0 )
+   {
+    s[i-1]='-';
+   } 
+ return (s);
+ }
+ 
+/*            Fonction  ctoi()    */
+int ctoi(const char* cst, int *ipt)
+{
+int i,j,k,l,ls,isgn;
+ls = strlen(cst)-1;
+if (ls < 0)  return (-1);
+j = -1;
+isgn = l = 1;
+k = 0;
+if(cst[0] == '-')
+  {
+  j = 0;
+  isgn = -1;
+  }
+if(cst[0] == '+') j = 0;
+for(i=ls;i>j;i--)
+  {
+  if(isdigit(cst[i]) == 0)  return (-1);
+  k += (cst[i] - '0')*l;
+  l *= 10;
+  }
+*ipt = k*isgn;
+return (1);
+}
+/*                                                       */
+/*            Fonction  ctol()    */
+int ctol(const char* cst, long int *lpt)
+{
+int i,j,ls,isgn;
+long k,l;
+ls = strlen(cst)-1;
+if (ls < 0)  return (-1);
+j = -1;
+isgn = l = 1;
+k = 0;
+if(cst[0] == '-')
+  {
+  j = 0;
+  isgn = -1;
+  }
+if(cst[0] == '+') j = 0;
+for(i=ls;i>j;i--)
+  {
+  if(isdigit(cst[i]) == 0)  return (-1);
+  k += (cst[i] - '0')*l;
+  l *= 10;
+  }
+*lpt = k*isgn;
+return (1);
+}
+/*              Fonction  ctof()           */
+int ctof(const char* cst, double *fpt)
+{
+int i,jb,pv,ls,isgn;
+double v1,v2;
+ls = strlen(cst);
+if (ls < 0)  return (-1);
+jb = -1;
+isgn = 1;
+v1 = 0.;
+v2 = 1.;
+if (cst[0] == '-')
+  {
+  jb = 0;
+  isgn = -1;
+  }
+if (cst[0] == '+')  jb = 0;
+if ((pv=posc(cst,'.')) != -1)
+  {
+  v2 = 0.1;
+  for(i=pv+1;i<ls;i++)
+    {
+    if(isdigit(cst[i]) == 0)  return (-1);
+    v1 += (cst[i]-'0')*v2;
+    v2 /= 10.;
+    }
+  ls = pv;
+  v2 = 1.;
+  }
+for(i=ls-1;i>jb;i--)
+  {
+  if(isdigit(cst[i]) == 0)  return (-1);
+  v1 += (cst[i]-'0')*v2;
+  v2 *= 10.;
+  }
+*fpt = (isgn == 1)? v1 : -v1;
+return (1);
+}
+/*           Fonction  posc()        */
+int posc(const char* cst, char sec)
+{
+int i,ls;
+ls = strlen(cst);
+for(i=0;i<ls;i++)
+  {
+  if (cst[i] == sec)  return(i);
+  }
+return (-1);
+}
+
+/*           Fonction  poslc()        */
+int poslc(const char* cst, char sec)
+{
+int i,ls;
+ls = strlen(cst);
+for(i=ls-1;i>=0;i--)
+  {
+  if (cst[i] == sec)  return(i);
+  }
+return (-1);
+}
+
+/*                Fonction   strip()             */
+int strip(char cst[], char opt, char bc)
+{
+int i,j,ls;
+ls = strlen(cst);
+if (opt == 'L' || opt == 'B')
+  {
+  i = 0;
+  while(cst[i] == bc) i++;
+  if (i != 0)
+    {
+    for(j=i;j<ls;j++)  cst[j-i] = cst[j];
+    ls -= i;
+    cst[ls] = '\0';
+    }
+  }
+if ((opt == 'T' || opt == 'B') && ls > 0)
+  {
+  i = ls-1;
+  while(cst[i] == bc)  i--;
+  cst[i+1] = '\0';
+  }
+return (0);
+}
+
+/*                Fonction   padstr(spo,lpa,bc)                      */
+/*    Cette  fonction  rajoute  des blancs a la fin de la chaine spo */
+/*   pour amener la longueur de la chaine a lpa. les caracteres      */
+/*   rajoutes a la fin sont bc. La fonction retourne le nombre de    */ 
+/*   blancs (caracteres bc)  rajoutes a la fin.                      */
+
+int padstr(char spo[], int lpa, int bc)
+{
+int li,i;
+li = strlen(spo);
+for(i=li;i<lpa;i++)  spo[i] = bc;
+spo[lpa] = '\0';
+return(lpa-li);
+}
+
+/* Eric L. 11-03-94 */
+/* quelques fonctions utiles */
+
+void tomaj(char *cbuff)
+{
+register int i,l;
+
+l=strlen(cbuff);
+for(i=0; i< l;i++)
+  cbuff[i]=(char) toupper( (int) cbuff[i]);
+}
+
+void tomin(char *cbuff)
+{
+register int i,l;
+
+l=strlen(cbuff);
+for(i=0; i< l;i++)
+  cbuff[i]=(char) tolower( (int) cbuff[i]);
+}
+
+void efface(char *cbuff,int lbuff,char c)
+{
+register int i;
+
+for(i=0; i< lbuff;i++)
+  if(cbuff[i] == c)  cbuff[i] = ' ';
+}
+
+char* rep_char(const char *cbuff,char cin,char crep)
+{
+register int i,l;
+char* buff;
+buff=(char*) cbuff;
+l=strlen(buff);
+for(i=0; i< l;i++)
+  if(buff[i] == cin) buff[i] = crep;
+return(buff);
+}
+
+/* Eric L. 23-03-96 */
+
+int csh_parse(const char* x, const char* yp)
+{
+ int i,lenx,lenyp;
+ int ix,iyp;
+ int faux;
+ char cx, cyp;
+ 
+ lenx=strlen(x);
+ lenyp=strlen(yp);
+ if(!lenx || !lenyp) return(0);
+ faux=0;
+ ix=0;iyp=0;
+ while(ix < lenx && iyp < lenyp)
+  {
+   cx=x[ix];
+   cyp=yp[iyp];
+   if(cx == cyp) 
+    {
+     ix++; 
+     iyp++;
+    }
+   else
+    switch(cyp)
+     {
+       case '?':
+        ix++;
+        iyp++;
+        break;
+       case '*':
+        while((cyp=='*' || cyp=='?') && (iyp < lenyp))
+         {
+          iyp++;
+          if(iyp < lenyp) cyp=yp[iyp];
+         }
+        if(iyp < lenyp)
+         {
+          faux=1;
+          for(i = ix; i < lenx ; i++)
+           {
+            cx=x[i];
+            if(cx == cyp)
+             {
+              faux=0;
+              break;
+             }
+           }
+          ix=i+1;
+          if(ix < lenx) cx=x[ix];
+          iyp++; 
+          if(iyp < lenyp) cyp=yp[iyp];
+         }    
+        break;
+       default:
+        faux=1;
+     }
+    if(faux) return(0);
+  }
+ 
+ for( i= iyp; i < lenyp ; i++)
+  {
+   cyp=yp[i];
+   if( cyp != '*' && cyp != '?') return(0);
+  }
+ 
+ if(cyp == '*') return(1);
+ if((lenx-ix) == 1 && ( cyp == '?' || cx==cyp)) return(1);
+ for( i= ix; i < lenx ; i++)
+  {
+   cx=x[i];
+   if( cx != cyp)  return(0);
+  }
+ return(1);
+}
+ 
+/*-------------------------------------------------------------------*/
+
+/*
+++
+  int DecArgList(char *listin, int *Vec, int nVec)
+	Pour decoder une liste de numeros a,b,c-d,e,f-g,h...
+	avec a,b... entiers
+| Vec est rempli jusqu'a concurrence de nVec elts.
+|     Si Vec==NULL ou nVec<=0 le tableau n'est pas rempli
+|         et seul le nombre d'elements est compte
+| Return: nombre d'elements rempli
+--
+*/
+/*                            (cmv 7/8/97)      */
+int DecArgList(char *listin, int *Vec, int nVec)
+{
+int i,k, num, min, max;
+char *list = NULL, *listfin, *s;
+
+if(strlen(listin) <= 0) return(0);
+list = (char *) malloc(strlen(listin)+1);
+if(list==NULL) return(0);
+strcpy(list,listin); strip(list,'B',' ');
+if( (k=strlen(list)) <= 0 ) {free(list); return(0);}
+for(i=0; i<k; i++) if(list[i] == ',') list[i] = ' ';
+listfin = list + k; *listfin = '\0';
+
+s = list; num = 0; k = 0;
+while(s < listfin) {
+  if ( (k=posc(s,' ')) < 0)  k = strlen(s);
+  s[k] = '\0'; strip(s,'B',' ');
+  sscanf(s,"%d-%d",&min,&max);
+  max = min - 1;
+  sscanf(s,"%d-%d",&min,&max);
+  if(max<min) max = min;
+  for(i=min; i<=max; i++) {
+    if( Vec!=NULL && nVec>0 ) {
+      if( num >= nVec )
+        {printf("DecArgList_Erreur: pas assez de place dans le vecteur (%d)\n"
+               ,nVec); free(list); return(num);}
+      Vec[num] = i;
+    }
+    num++;
+  }
+  s = s+k+1;
+}
+
+free(list);
+return(num);
+}
+ 
+/*-------------------------------------------------------------------*/
+
+/*
+++
+  char *ExtName(char *cout,char *cin,char t)
+	Pour separer les composantes d'un nom de fichier de type unix.
+| cout   = chaine en sortie
+| cin    = chaine en entree
+| t      = type de racine a extraire
+| Return = *cout
+| - Remarque: pas de verification de longeur de la chaine cout!
+| - Exemple: /home/toto.cc  /home/ /home/.cc  .cc  toto.cc
+|    t='d' : /home          /home  /home      ""   ""
+|    t='n' : toto.cc        ""     .cc        .cc  toto.cc
+|    t='r' : toto           ""     ""         ""   toto
+|    t='t' : cc             ""     cc         cc   cc
+--
+*/
+/*                            (cmv 24/4/98)      */
+char *ExtName(char *cout,char *cin,char t)
+{
+int is=-1,ip=-1,i,j;
+int len = strlen(cin);
+/* cas ou le nom se termine par un / qui n'est pas au debut*/
+if(len>1) if(cin[len-1]=='/') len--;
+
+for(i=0;i<len;i++) {
+  if(cin[i]=='/') is=i;         /* position du dernier / */
+  if(cin[i]=='.' && ip<0) ip=i; /* position du 1er point */
+  cout[i]=cin[i];
+}
+cout[len]='\0';
+
+/* mauvais nom de fichier */
+if(is>=0&&ip>=0&&ip<=is) {cout[0]='\0'; return cout;}
+
+/* traitement des differents cas */
+switch(t) {
+  case 'd':
+    if(is==0) {                    /* cas /... */
+      if(ip<0) ip=len-1;             /* cas /home */
+      else ip=0;                     /* cas /toto.c */
+    } else if(is<0) {              /* cas toto.c */
+      is=ip=-1;
+    } else {                       /* cas /home/.../... */
+      ip=is-1; is=0;
+    }
+    break;
+  case 'n':
+    if(is==0) {                        /* cas /... */
+      if(ip<0) ip=is=-1;                 /* cas /home */
+      else {is=1; ip=len-1;}             /* cas /toto.c */
+    } else if(is>0) {                  /* cas /home/toto.c */
+      is++; ip=len-1;
+    } else {                           /* cas toto.c */
+      is=0; ip=len-1;
+    }
+    break;
+  case 'r':
+    if(is==0) {                          /* cas /... */
+      if(ip<0) ip=is=-1;                   /* cas /home */
+      else if(ip==1) is=ip=-1;             /* cas /.c */
+      else {is=1; ip--;}                   /* cas /toto.c */
+    } else if(is>0) {                    /* cas /home/... */
+      if(ip<0) {is++;ip=len-1;}            /* cas /home/toto */
+      else if(ip==is+1) is=ip=-1;          /* cas /home/.c */
+      else {is++; ip--;}                   /* cas /home/toto.c */
+    } else if(is<0) {                    /* cas toto.c */
+      if(ip<0) {is=0;ip=len-1;}            /* cas toto */
+      else if(ip==0) is=ip=-1;             /* cas .c */
+      else {is=0; ip--;}                   /* cas toto.c */
+    }
+    break;
+  case 't':
+    if(ip<0) is=ip=-1;             /* cas sans '.' dans le nom */
+    else {is=ip+1,ip=len-1;}       /* cas blablabla.c */
+    break;
+  default:
+    cout[0]='\0';
+    return cout;
+    break;
+}
+
+j=0;
+if(is>=0&&ip>=is) for(i=is,j=0;i<=ip;i++,j++) cout[j]=cin[i];
+cout[j]='\0';
+/* printf("........ is=%d ip=%d :%s:\n",is,ip,cout); */
+return cout;
+}
Index: /tags/V_Dec2002/SophyaLib/SUtils/strutil.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SUtils/strutil.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SUtils/strutil.h	(revision 2309)
@@ -0,0 +1,58 @@
+/*                                                                          */
+/*   Ce fichier contient quelques fonctions de manipulation de caracteres   */
+/*   et autres bricoles utiles                                              */
+/*     # char* itoc() : conversion entier-chaine de caracteres              */ 
+/*     # ctoi()   : convertit une chaine de caractere en entier             */
+/*     # ctol()   : convertit une chaine de caractere en entier long        */
+/*     # ctof()   : convertit une chaine de caractere en flottant           */
+/*     # posc()    : trouve la position d'un caractere dans une chaine      */
+/*     # strip()  : permet d'enlever les blancs au debut ou a la fin d'une  */
+/*                  chaine de caractere                                     */ 
+/*     # padstr() : permet d'ajouter des caracteres a la fin d'une chaine   */
+/*                  de caracteres pour amener la longueur de cette chaine   */
+/*                  a une valeur donnee.                                    */
+/*     # tomaj()  : Changement en majuscule d'une chaine de caracteres      */
+/*     # efface() : Remplace un caractere avec des blancs                   */
+/*     # rep_char() : Remplace un caractere par un autre                    */ 
+/*                                                                          */
+/* Derniere modif: csh_parse, E. Lesquoy, le 23-03-96                       */
+/* DecArgList: Decoder une liste du type a,b,c-d,e,f-g,h...(cmv 7/8/97)     */
+/* ExtName: eclatement des nom de fichiers unix (cmv 24/4/98)               */
+
+#ifndef STRUTIL_H_SEEN
+#define STRUTIL_H_SEEN
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*    Manipulation de chaines de caracteres     */
+/*                    Reza - 92/93              */
+char* itoc(int in, char* s,int nDigits);
+int ctoi(const char* cst, int *ipt);
+int ctol(const char* cst, long int *lpt);
+int ctof(const char* cst, double *fpt);
+/* retour ctox : 1: OK, -1 erreur */
+int posc(const char* cst, char sec);
+int poslc(const char* cst, char sec);
+int strip(char* cst, char opt, char bc);
+int padstr(char* spo, int lpa, int bc);
+
+/* Eric L. 11-03-94 */
+void tomaj(char *cbuff);
+void tomin(char *cbuff);
+void efface(char *cbuff,int lbuff,char c);
+/* Attention rep_char(const char *cbuff ...) c'est declare const cbuff, mais ca modifie cbuff - Reza 2/09/98  */
+char* rep_char(const char *cbuff,char cin,char crep);  
+/* Eric L. 23-03-96 */
+int csh_parse(const char* x, const char* yp);
+/* cmv 7/8/97 */
+int DecArgList(char *listin, int *Vec, int nVec);
+char *ExtName(char *cin,char *cout,char t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Index: /tags/V_Dec2002/SophyaLib/SUtils/strutilxx.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SUtils/strutilxx.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SUtils/strutilxx.cc	(revision 2309)
@@ -0,0 +1,42 @@
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream.h>
+
+#include "strutilxx.h"
+
+
+void FillVStringFrString(string s,vector<string>& vs,char sep)
+// Use string "s" to fill vector of strings "vs"
+// considering char "sep" as a separator.
+// Vector is filled from its end (no reset done).
+// Tp write a "sep" char, use \'sep'
+// Warning: separator "sep" could not be set to '\'
+// Ex: sep=' ': s="aaa   bbb cc d " -> vs=(aaa,bbb,cc,d)
+// Ex: sep=';': s="aaa   ;bbb; cc;d " -> vs=(aaa   ,bbb, cc,d )
+// Ex: sep=';': s=";aaa\;bbb;;;ccc;ddd" -> vs=(aaa;bbb,ccc,ddd)
+// Ex: sep=';': s=";aaa\;bbb;;;ccc;ddd\" -> vs=(aaa;bbb,ccc,ddd\)
+{
+uint_4 ls = s.size();
+if(ls<=0 || sep=='\\') return;
+s += sep; // add a separator at the end
+const char* str = s.c_str();
+ls = strlen(str); // str[ls-1]==sep cf ci-dessus
+string dum = "";
+for(uint_4 i=0; i<ls; i++) {
+  if(i==0 && str[i]==sep) {
+    continue;
+  } else if(str[i]=='\\') {
+    if(str[i+1]!=sep || i==ls-2) dum += str[i];
+  } else if(str[i]!=sep) {
+    dum += str[i];
+  } else {  // C'est un "sep" mais est-ce vraiment un separateur?
+    if(str[i-1]=='\\' && i!=ls-1) dum += str[i];
+    else {  // C'est un separateur, ne delimite t-il pas d'autres separateurs?
+      if(dum.size()<=0) continue;
+      vs.push_back(dum);
+      dum = "";
+    }
+  }
+}
+}
Index: /tags/V_Dec2002/SophyaLib/SUtils/strutilxx.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SUtils/strutilxx.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SUtils/strutilxx.h	(revision 2309)
@@ -0,0 +1,10 @@
+#ifndef STRUTILXX_H_SEEN
+#define STRUTILXX_H_SEEN
+
+#include "machdefs.h"
+#include <vector>
+#include <string>
+
+void FillVStringFrString(string s,vector<string>& vs,char sep = ' ');
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/SUtils/sutils.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SUtils/sutils.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SUtils/sutils.h	(revision 2309)
@@ -0,0 +1,15 @@
+#ifndef SUTILS_H
+#define SUTILS_H
+
+/*!
+   \defgroup SUtils SUtils module
+   This module contains general utility routines and classes
+   for datacards, string manipulation etc...
+*/
+
+#include "datacards.h"
+#include "strutil.h"
+#include "strutilxx.h"
+#include "utils.h"
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/SUtils/utils.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SUtils/utils.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SUtils/utils.cc	(revision 2309)
@@ -0,0 +1,112 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// $Id: utils.cc,v 1.1 2000-04-12 17:49:52 ansari Exp $
+//
+
+#include "machdefs.h"
+#include "utils.h"
+#include "pexceptions.h"
+#include <string.h>
+
+// MemCpy marche meme en cas de recouvrement.
+void* MemCpy(void* dest, const void* source, size_t n)
+{
+  int i;   // THINK C ne veut pas du int i dans chaque for...
+  if (dest < source)
+    for (i=0; i<n; i++)
+      ((char*)dest)[i] = ((char*)source)[i];
+  else 
+    for (i=n-1; i>=0; i--)
+      ((char*)dest)[i] = ((char*)source)[i];
+  
+  return dest;
+}
+
+// Dans parmst.cc
+//int PrtLevel = 0;
+//int DebugLevel = 0;
+
+char const* PeidaWorkPath()
+{
+  char const* envWP = getenv("PEIDAWORKPATH");
+  if (envWP) return envWP;
+  #ifdef __mac__
+  return "WORK";
+  #endif
+  return ".";
+}
+
+#ifndef __mac__
+void buildPath(char* dst, const char* dir, const char* file)
+{
+  strcpy(dst, dir);
+  char *p = dst; while (*p) p++; p--;
+  if (*dir && *p != '/') strcat(dst, "/");
+  strcat(dst, file);
+}
+
+void buildPath(string& dst, const string& dir, const string& file)
+{
+  dst = dir;
+  if (dir != "" && dir[dir.length()-1] != '/') dst += "/";
+  dst += file;
+}
+
+#else
+void buildPath(char* dst, const char* dir, const char* file)
+{
+  if (*dir) {
+    strcpy(dst, ":");
+    strcat(dst, dir);
+    char *p = dst; while (*p) p++; p--;
+    strcat(dst, ":");
+    strcat(dst, file);
+  } else
+    strcpy(dst, file);
+}
+
+void buildPath(string& dst, const string& dir, const string& file)
+{
+  if (dir != "") {
+    dst = ":" + dir + ":" + file;
+  } else
+    dst = file;
+}
+
+#endif
+
+
+void changeSuffix(char* file, const char* suffix)
+{
+  char *p = file;
+  while (*p) p++;
+  while (*p != '.' && p > file) p--;
+  if (*p != '.') 
+    strcat(file, suffix);
+  else
+    strcpy(p,suffix);
+}
+
+void changeSuffix(string& file, const string& suffix)
+{
+  size_t pos = file.rfind('.');
+  //  if (pos != NPOS) file.remove(pos);
+  if (pos != NPOS) file = file.substr(0,pos);
+  file += suffix;
+}
+
+string itos(int i)
+{
+  char s[20];
+  sprintf(s, "%d", i);
+  return s;
+}
+
+string ftos(double f)
+{
+  char s[20];
+  sprintf(s, "%g", f);
+  return s;
+}
+
+
Index: /tags/V_Dec2002/SophyaLib/SUtils/utils.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SUtils/utils.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SUtils/utils.h	(revision 2309)
@@ -0,0 +1,53 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// $Id: utils.h,v 1.1 2000-04-12 17:49:54 ansari Exp $
+//
+
+#ifndef UTILS_EA
+#define UTILS_EA
+
+#include "machdefs.h"
+#include <string.h>
+#include <string>
+#include <stdlib.h>
+#include <stdio.h>
+
+
+// MemCpy marche meme en cas de recouvrement.
+// #define memcpy MemCpy
+
+void* MemCpy(void* dest, const void* source, size_t n);
+
+char const* PeidaWorkPath();
+void buildPath(char* dst, const char* dir, const char* file);
+void buildPath(string& dst, const string& dir, const string& file);
+void changeSuffix(char* file, const char* suffix);
+void changeSuffix(string& file, const string& suffix);
+string itos(int);
+string ftos(double);
+
+inline void GetIntEnv(char const* s, int& v)
+{
+  char* pdeb = getenv(s);
+  if (pdeb) v = atoi(pdeb);
+}
+
+/* if defined(__DECCXX) || defined(__xlC) */
+#if defined(__xlC) || defined(__DECCXX)
+#define STRUCTCOMP(s)                        \
+  bool operator==(s const& b) const          \
+{ return memcmp(this, &b, sizeof(s)) == 0; } \
+  bool operator<(s const& b) const           \
+{ return memcmp(this, &b, sizeof(s)) < 0; } 
+  
+#define STRUCTCOMPF(s,f)                        \
+  bool operator==(s const& b) const          \
+{ return f == b.f; }                          \
+  bool operator<(s const& b) const           \
+{ return f < b.f; }
+#else
+#define STRUCTCOMP(s) 
+#define STRUCTCOMPF(s,f)
+#endif
+
+#endif // UTILS_EA
Index: /tags/V_Dec2002/SophyaLib/Samba/Makefile
===================================================================
--- /tags/V_Dec2002/SophyaLib/Samba/Makefile	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Samba/Makefile	(revision 2309)
@@ -0,0 +1,139 @@
+include ../Mgr/Makefile.h
+ 
+all: $(LIB)libSamba.a
+clean:
+	rm -f $(OBJ)alm.o $(OBJ)bruit.o $(OBJ)circle.o $(OBJ)datacirclefake.o $(OBJ)lambdaBuilder.o $(OBJ)mlobe.o $(OBJ)sambainit.o $(OBJ)scan.o $(OBJ)sphericaltransformserver.o
+	rm -f $(LIB)libSamba.a
+$(LIB)libSamba.a : $(OBJ)alm.o $(OBJ)bruit.o $(OBJ)circle.o $(OBJ)datacirclefake.o $(OBJ)lambdaBuilder.o $(OBJ)mlobe.o $(OBJ)sambainit.o $(OBJ)scan.o $(OBJ)sphericaltransformserver.o
+	$(ARCXX) $(ARCXXFLAGS) $@ $($(ARARGS))
+ifeq ($(CXX),cxx)
+	$(CXX) $? $(CPPFLAGS) $(CXXFLAGS) -o $(OBJ)xx.x -Hf
+endif 
+ 
+$(OBJ)alm.o: alm.cc alm.h $(INC)nbrandom.h \
+ $(INC)srandgen.h \
+ $(INC)machdefs.h \
+ $(INC)nbmath.h \
+ $(INC)smathconst.h \
+ $(INC)triangmtx.h \
+ $(INC)ndatablock.h \
+ $(INC)anydataobj.h \
+ $(INC)pexceptions.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)utilarr.h
+$(OBJ)bruit.o: bruit.cc $(INC)fmath.h bruit.h \
+ $(INC)nbrandom.h \
+ $(INC)srandgen.h \
+ $(INC)machdefs.h
+$(OBJ)circle.o: circle.cc circle.h $(INC)vector3d.h \
+ $(INC)longlat.h \
+ $(INC)machdefs.h \
+ $(INC)utilgeom.h \
+ $(INC)unitvector.h geometry.h
+$(OBJ)datacirclefake.o: datacirclefake.cc datacirclefake.h datacirclebase.h \
+ circle.h $(INC)vector3d.h \
+ $(INC)longlat.h \
+ $(INC)machdefs.h \
+ $(INC)utilgeom.h \
+ $(INC)unitvector.h geometry.h
+$(OBJ)lambdaBuilder.o: lambdaBuilder.cc lambdaBuilder.h \
+ $(INC)ndatablock.h \
+ $(INC)machdefs.h \
+ $(INC)anydataobj.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)utilarr.h alm.h \
+ $(INC)nbrandom.h \
+ $(INC)srandgen.h \
+ $(INC)nbmath.h \
+ $(INC)smathconst.h \
+ $(INC)triangmtx.h \
+ $(INC)nbconst.h
+$(OBJ)mlobe.o: mlobe.cc mlobe.h \
+ $(INC)sphericalmap.h \
+ $(INC)smathconst.h \
+ $(INC)machdefs.h \
+ $(INC)pixelmap.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)spherepos.h \
+ $(INC)unitvector.h \
+ $(INC)vector3d.h \
+ $(INC)longlat.h \
+ $(INC)utilgeom.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)timing.h
+$(OBJ)sambainit.o: sambainit.cc sambainit.h \
+ $(INC)skymapinit.h \
+ $(INC)sophyainit.h \
+ $(INC)machdefs.h \
+ $(INC)ntoolsinit.h \
+ $(INC)tarrinit.h
+$(OBJ)scan.o: scan.cc $(INC)machdefs.h scan.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)ndatablock.h \
+ $(INC)piocmplx.h \
+ $(INC)fiondblock.h \
+ $(INC)smathconst.h
+$(OBJ)sphericaltransformserver.o: sphericaltransformserver.cc \
+ $(INC)machdefs.h sphericaltransformserver.h \
+ $(INC)sphericalmap.h \
+ $(INC)smathconst.h \
+ $(INC)pixelmap.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)spherepos.h \
+ $(INC)unitvector.h \
+ $(INC)vector3d.h \
+ $(INC)longlat.h \
+ $(INC)utilgeom.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)fftservintf.h \
+ $(INC)fftpserver.h alm.h \
+ $(INC)nbrandom.h \
+ $(INC)srandgen.h \
+ $(INC)nbmath.h \
+ $(INC)triangmtx.h lambdaBuilder.h \
+ $(INC)timing.h
Index: /tags/V_Dec2002/SophyaLib/Samba/Makefile.am
===================================================================
--- /tags/V_Dec2002/SophyaLib/Samba/Makefile.am	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Samba/Makefile.am	(revision 2309)
@@ -0,0 +1,8 @@
+lib_LIBRARIES = libSamba.a
+
+libSamba_a_SOURCES = \
+alm.cc    circle.cc         mlobe.cc      scan.cc                      \
+bruit.cc  lambdaBuilder.cc  sambainit.cc  sphericaltransformserver.cc
+
+
+DEFS = -I.. -I../include
Index: /tags/V_Dec2002/SophyaLib/Samba/alm.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/Samba/alm.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Samba/alm.cc	(revision 2309)
@@ -0,0 +1,88 @@
+#include "alm.h"
+template <class T>
+Alm<T>::Alm(const TVector<T>& clin, const r_8 fwhm) 
+
+{
+
+
+  /*=======================================================================
+     creates the a_lm from the power spectrum, 
+     assuming they are gaussian  and complex 
+     with a variance given by C(l)
+
+     the input file should contain : l and C(l) with *consecutive* l's
+     (missing C(l) are put to 0.)
+
+     because the map is real we have : a_l-m = (-)^m conjug(a_lm)
+     so we actually compute them only for m >= 0
+
+=======================================================================*/
+  int_4 nlmax= clin.NElts()-1;
+
+  //alm.ReSize(nlmax);
+  ReSizeRow(nlmax+1);
+
+  r_8 sig_smooth = fwhm/sqrt(8.*log(2.))/(60.*180.)* M_PI;
+  int_4 n_l = nlmax+1;
+
+
+  //    --- smoothes the initial power spectrum ---
+  TVector<T> cl=clin;
+  int l;
+  for (l=0;l<n_l;l++)
+    {
+      r_8 gauss=exp(-l*(l+1.)*sig_smooth*sig_smooth);
+      cl(l)*=(T)gauss;
+    }
+  
+
+  //     --- generates randomly the alm according to their power spectrum ---
+  r_8 hsqrt2 = 1.0 / Rac2;
+
+  for (l=0;l<n_l;l++)
+    {
+      T rms=sqrt(cl(l));
+      //        ------ m = 0 ------
+      complex<T> zeta1(NorRand());
+      (*this)(l,0)   = zeta1 * rms;
+
+      //------ m > 0 ------
+      for (int m=1;m<=l;m++)
+	{
+	  complex<T> aux1(hsqrt2);
+	  complex<T> aux2(NorRand(),NorRand());
+	  zeta1=aux1*aux2;
+	  (*this)(l,m)=rms*zeta1;
+	}
+    }
+}
+
+
+template <class T>
+TVector<T> Alm<T>::powerSpectrum() const
+{
+  int_4 nlmax=Lmax();
+
+  TVector<T>  powsp(nlmax+1);
+
+  for (int l=0; l<=nlmax;l++)
+    {
+      powsp(l)=( (*this)(l,0) ).real()*( (*this)(l,0) ).real();
+      for (int m=1; m<=l; m++)
+	{
+	  powsp(l)+=2.*( (*this)(l,m).real()*(*this)(l,m).real()+
+	     (*this)(l,m).imag()*(*this)(l,m).imag() );
+	}
+      powsp(l)/=(2.*l+1.);
+    }
+  return powsp;
+}
+ 
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template Alm<r_8>
+#pragma define_template Alm<r_4>
+#endif
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class Alm<r_8>;
+template class Alm<r_4>;
+#endif
Index: /tags/V_Dec2002/SophyaLib/Samba/alm.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/Samba/alm.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Samba/alm.h	(revision 2309)
@@ -0,0 +1,92 @@
+//   Class for representing spherical harmonic coefficients
+//              G. Le Meur      2000
+// DAPNIA/SPP (Saclay) / CEA    LAL - IN2P3/CNRS  (Orsay)
+
+#ifndef ALM_SEEN
+#define ALM_SEEN
+
+#include "nbrandom.h"
+#include "nbmath.h"
+#include "triangmtx.h"
+#include "tvector.h"
+
+namespace SOPHYA {  
+
+/*! class for the coefficients \f$a_{lm}\f$ of the development of a function defined on a sphere, in spherical harmonics */
+template <class T>
+class Alm : public TriangularMatrix<complex<T> >
+  {
+    public :
+ 
+Alm() : TriangularMatrix<complex<T> >()  {;};
+    /* instanciate the class from the maximum value of the index \f$l\f$ in the sequence of the \f$a_{lm}\f$'s */
+Alm(int nlmax) : TriangularMatrix<complex<T> >(nlmax+1) {;}
+Alm(const Alm<T>& a,  bool share=false)  : TriangularMatrix<complex<T> >(a, share)  {;}
+
+Alm(const TVector<T>& clin, const r_8 fwhm) ;
+/*! resize with a new lmax */
+inline void ReSizeToLmax(int_4 nlmax) {ReSizeRow(nlmax+1);}
+inline int_4 Lmax() const {return rowNumber()-1;}
+TVector<T> powerSpectrum() const;
+
+inline  Alm<T>& SetComplexT(complex<T> a)
+   {
+     this->SetT(a);
+     return *this;
+   }
+ inline Alm<T>& operator = (complex<T> a)
+ {
+   return SetComplexT(a);
+ } 
+
+};
+/*! class for a vector with an index running from \f$-m_{max}\f$ to \f$+m_{max}\f$ (then the size of the vector will be actually \f$2m_{max}+1)\f$ */
+template <class T>
+class Bm
+  {
+    public :
+Bm(): nmmax_(0) {;};
+    /* instanciate from the maximum absolute value of the index */
+Bm(int mmax) : nmmax_((uint_4)mmax)   { bm_.ReSize( (uint_4)(2*mmax+1) );}
+ Bm(const Bm<T>& b,  bool share=false) : nmmax_(b.nmmax_), bm_(b.bm_, share) {;}
+ /*! resize with a new value of mmax */
+inline void ReSizeToMmax(int_4 mmax) 
+  {
+    nmmax_=(uint_4)l;
+    bm_.ReSize(2* nmmax_+1);
+  }
+//inline int_4 Size() const {return 2*nmmax_+1;};
+inline T& operator()(int m) {return bm_( adr_i(m));};
+inline T const& operator()(int m) const {return *(bm_.Begin()+ adr_i(m));};
+/*! return the current value of the maximum absolute value of the index */
+inline int_4 Mmax() const 
+   {
+     return (int_4)nmmax_;
+   }
+inline Bm<T>& operator = (const Bm<T>& b)
+ {
+   if (this != &b)
+     {
+       nmmax_= b.nmmax_;
+       bm_=  b.bm_;
+     }
+   return *this;
+ }
+
+  private:
+/*! return the address in the array representing the vector */
+inline uint_4 adr_i(int i) const 
+{
+  return(uint_4)(i+nmmax_);
+}
+
+
+
+ uint_4 nmmax_;
+ NDataBlock<T> bm_;
+
+  };
+
+} // namespace SOPHYA
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/Samba/bruit.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/Samba/bruit.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Samba/bruit.cc	(revision 2309)
@@ -0,0 +1,683 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+#ifdef __MWERKS__
+#include "unixmac.h"
+#endif
+
+
+#include "fmath.h"
+
+#include "bruit.h"
+#include "nbrandom.h"
+// #include "rancern.h"
+// #include "hbook.h"
+#ifdef OS_MACOSX
+#include <limits.h>
+#endif
+
+//  Le code des classes   NoiseGenerator  RWalkNoise
+
+//++ 
+// Class	NoiseGenerator
+//
+// include      bruit.h math.h fmath.h nbrandom.h
+//
+//--
+//++
+//
+// Links	Childs
+//
+//    RWalkNoise OOFNoise EXPNoise MemNoise  SumNoise
+//     
+//-- 
+//++
+// Titre	Constructors
+//--
+
+// Definition de fonctions pour float - a changer en utilisant cmath
+//                              Reza Juillet 2002
+inline float _myfabsf(float x) { return ((float)(fabs((double)x)) ); }
+inline float _mysqrtf(float x) { return ((float)(sqrt((double)x)) ); }
+ 
+/* --Methode-- */
+//++
+NoiseGenerator::NoiseGenerator(float sigma)
+//
+//--
+{
+if (sigma < 0.)  sigma = 1.;
+mNCoups = 0;
+mSigma = sigma;
+//printf("-- NoiseGenerator::NoiseGenerator(%g) (Constructeur) ---\n", sigma);
+}
+
+//++
+// Titre	Destructor
+//--
+/* --Methode-- */
+//++
+NoiseGenerator::~NoiseGenerator()
+//
+//--
+{
+    //printf("-- NoiseGenerator::~NoiseGenerator() (Destructeur) --- \n");
+}
+
+
+//++
+//
+// inline  unsigned long int  NoiseGenerator::NCoups() 
+//--
+//++
+// Titre	Public Methods
+//--
+
+/* --Methode-- */
+//++
+float NoiseGenerator::Noise()
+//
+//--
+{
+mNCoups++;
+return(NorRand()*mSigma);
+}
+//++
+// Class	RWalkNoise
+//
+// include      bruit.h math.h fmath.h nbrandom.h
+//
+//--
+//++
+//
+// Links	Parents
+//
+//    NoiseGenerator
+//     
+//-- 
+//++
+// Titre	Constructor
+//--
+
+/* --Methode-- */
+//++
+RWalkNoise::RWalkNoise(float sigma)
+    : NoiseGenerator(sigma)
+//
+//--
+{
+mState = 0.;
+//printf("--  RWalkNoise::RWalkNoise(%g) (Constructeur) ---\n", sigma);
+}
+
+
+//++
+// Titre	Destructor
+//--
+/* --Methode-- */
+//++
+RWalkNoise::~RWalkNoise()
+//
+//--
+{
+//printf("--  RWalkNoise::~RWalkNoise (Destructeur) ---\n");
+
+}
+
+//++
+// Titre	Public Methods
+//--
+/* --Methode-- */
+//++
+float RWalkNoise::Noise()
+//
+//--
+{
+mState += NoiseGenerator::Noise();
+return(mState);
+}
+
+//++
+// Class	OOFNoise
+//
+// include      bruit.h math.h fmath.h nbrandom.h
+//
+//--
+//++
+//
+// Links	Parents
+//
+//    NoiseGenerator
+//     
+//-- 
+//++
+// Titre	Constructor
+//--
+
+/* --Methode-- */
+//++
+OOFNoise::OOFNoise(float sigma, int typacf, int mem, float tau)
+    : NoiseGenerator(sigma)
+//
+//--
+{
+if (typacf != ACF_Exp)   typacf = ACF_Exp;
+// Fonction d'autocorrelation donnant un bruit en 1/f
+//                  
+mTypACF = typacf;
+if (mem < 1)  mem = 1;
+mMemL = mem;
+if (tau < 1.e-6)  tau = 1.e-6;
+mTau = tau;
+mState = new double[mem];
+mDyn = new double[mem];
+int i;
+mDyn[0]=1.;
+mState[0]=0.;
+for(i=1; i<mem; i++) {
+  mState[i] = 0.;   mDyn[i] = 1./sqrt((double)i);
+}
+//printf("--  OOFNoise::OOFNoise(%g,%d,%d,%g) (Constructeur) ---\n", 
+//       sigma, typacf, mem, tau);
+}
+
+
+//++
+// Titre	Destructor
+//--
+/* --Methode-- */
+//++
+OOFNoise::~OOFNoise()
+//
+//--
+{
+delete[] mState;
+delete[] mDyn;
+// printf("--  OOFNoise::~OOFNoise (Destructeur) ---\n");
+}
+
+
+//++
+// Titre	Public Methods
+//--
+/* --Methode-- */
+//++
+float OOFNoise::Noise()
+//
+//--
+{
+int i;
+double rn;
+
+for(i=(mMemL-1); i>0; i--)   mState[i] = mState[i-1];
+mState[0] = NoiseGenerator::Noise();
+rn = 0.;
+for(i=0; i< mMemL; i++)  rn += mDyn[i]*mState[i];
+return(rn);
+}
+
+/* --Methode-- */
+//++
+void OOFNoise::Print()
+//
+//--
+{
+int i,j;
+printf("OOFNoise::Print()  MemL=%d  Tau= %g \n", mMemL, mTau);
+printf("OOFNoise::Print() Vecteur de Dynamique / Etat : \n");
+for(i=0; i<mMemL-1; i+=2) 
+  printf("%d:   D=%g  S=%g   | %d:  D=%g  S=%g \n", i, 
+         mDyn[i], mState[i], i+1, mDyn[i], mState[i]);   
+return;
+}
+//++
+// Class	EXPNoise
+//
+// include      bruit.h math.h fmath.h nbrandom.h
+//
+//--
+//++
+//
+// Links	Parents
+//
+//    NoiseGenerator
+//     
+//-- 
+//++
+// Titre	Constructor
+//--
+
+/* --Methode-- */
+//++
+EXPNoise::EXPNoise(float sigma, int typacf, int mem, float tau)
+    : NoiseGenerator(sigma)
+//
+//--
+{
+if (typacf != ACF_Exp)   typacf = ACF_Exp;
+// Fonction d'autocorrelation exponentiel disponible uniquement
+//                  Reza , Juillet 97
+mTypACF = typacf;
+if (mem < 1)  mem = 1;
+mMemL = mem;
+if (tau < 1.e-6)  tau = 1.e-6;
+mTau = tau;
+mState = new double[mem];
+mDyn = new double[mem];
+int i;
+for(i=0; i<mem; i++) {
+  mState[i] = 0.;   mDyn[i] = exp(-(double)i/tau);
+}
+//printf("--  EXPNoise::EXPNoise(%g,%d,%d,%g) (Constructeur) ---\n", 
+//       sigma, typacf, mem, tau);
+}
+
+
+//++
+// Titre	Destructor
+//--
+/* --Methode-- */
+//++
+EXPNoise::~EXPNoise()
+//
+//--
+{
+delete[] mState;
+delete[] mDyn;
+//printf("--  EXPNoise::~EXPNoise (Destructeur) ---\n");
+}
+
+
+//++
+// Titre	Public Methods
+//--
+/* --Methode-- */
+//++
+float EXPNoise::Noise()
+//
+//--
+{
+int i;
+double rn;
+
+for(i=(mMemL-1); i>0; i--)   mState[i] = mState[i-1];
+mState[0] = NoiseGenerator::Noise();
+rn = 0.;
+for(i=0; i< mMemL; i++)  rn += mDyn[i]*mState[i];
+return(rn);
+}
+
+/* --Methode-- */
+//++
+void EXPNoise::Print()
+//
+//--
+{
+int i,j;
+printf("EXPNoise::Print()  MemL=%d  Tau= %g \n", mMemL, mTau);
+printf("EXPNoise::Print() Vecteur de Dynamique / Etat : \n");
+for(i=0; i<mMemL-1; i+=2) 
+  printf("%d:   D=%g  S=%g   | %d:  D=%g  S=%g \n", i, 
+         mDyn[i], mState[i], i+1, mDyn[i], mState[i]);   
+
+return;
+}
+
+//++
+// Class	MemNoise
+//
+// include      bruit.h math.h fmath.h nbrandom.h
+//
+//--
+//++
+//
+// Links	Parents
+//
+//    NoiseGenerator
+//     
+//-- 
+//++
+// Titre	Constructor
+//--
+
+
+// ----------------      $CHECK$   Reza 1/12/99   ------------
+// ----- MAJ MemNoise et SumNoise / version F. Couchot (~couchot/CoSa/Samba/bruit.cc  )
+// -----------------------------------------------------------
+
+/* --Methode-- */
+//++
+MemNoise::MemNoise(float sigma, int mem, float tau, int ava)
+    : NoiseGenerator(_mysqrtf(_myfabsf(tau))*sigma)
+//
+//--
+{
+/* on tire les instants des impulsions successives selon une
+loi de distance exponentielle de duree tau
+*/
+const int place = 1000;
+mTypACF = ACF_Exp;
+if (mem < 1)  mem = 1;
+mMemL = place;
+mCoupHaut=mem;
+if (tau < 1.)  tau = 1.;
+mTau = tau;
+mStPos = new float[place];
+mStNeg = new float[place];
+mTePos = new float[place];
+mTeNeg = new float[place];
+// printf("apres reservation\n");
+int i;
+for(i=0; i<place; i++)
+{
+mStNeg[i] = 0.; mStPos[i] = 0.;
+}
+// printf("apres initialisation tableaux \n");
+
+mNappel=0;
+mNtirage=1;
+mNappLast=0;
+mMemPos=1;
+mMemNeg=1;
+mduree=0.;
+mTePos[0]=0.;
+mTeNeg[0]=0.;
+mTdernier=0.;
+
+Avance(ava);
+// printf("fin du createur MemNoise \n");
+//printf("--  EXPNoise::EXPNoise(%g,%d,%d,%g) (Constructeur) ---\n", 
+//       sigma, typacf, mem, tau);
+}
+
+
+//++
+// Titre	Destructor
+//--
+/* --Methode-- */
+//++
+MemNoise::~MemNoise()
+//
+//--
+{
+delete[] mStPos;
+delete[] mStNeg;
+delete[] mTePos;
+delete[] mTeNeg;
+//printf("--  EXPNoise::~EXPNoise (Destructeur) ---\n");
+}
+
+//++
+// Titre	Public Methods
+//--
+/* --Methode-- */
+//++
+float MemNoise::Noise()
+//
+//--
+{
+return(Avance(0));
+}
+
+/* --Methode-- */
+//++
+float MemNoise::Avance(long Asauter)
+//
+//--
+{
+int i,j;
+float boum;
+float rn = 0;
+float Somme,SbaryT,Poids,BaryT,Approx,Erreur;
+int nReduit;
+const float epsilon=.05;
+// printf("entree dans methode Noise de MemNoise \n");
+long mNsaut;
+for (mNsaut = Asauter ; mNsaut >= 0 ; mNsaut--)
+    {  // debut mNsaut
+	// printf("mNsaut = %ld\n",mNsaut);
+mNappel++;
+mTdernier += 1.;
+for(i=0; i<mMemPos; i++) mTePos[i] += 1.;
+for(i=0; i<mMemNeg; i++) mTeNeg[i] += 1.;
+
+if (mduree < mTdernier)
+    {
+	/* la duree depuis le dernier tirage est maintenant ecoulee
+	   on commence par remettre a jour le temps ecoule entre la derniere
+	   impulsion (celle qu'on va tirer maintenant) et l'instant present  */
+	   
+	   mTdernier = mTdernier - mduree;
+        
+	/* puis on tire une nouvelle impulsion de bruit */
+
+	   boum =  NoiseGenerator::Noise();
+
+        /* on decale la memoire d'une case vers le passe 
+	   puis on met a jour la case [0] */
+
+if(boum>0)
+    {
+	for(i=mMemPos; i>0; i--)
+	    {
+		mStPos[i] = mStPos[i-1];
+		mTePos[i] = mTePos[i-1];
+	    }
+	mTePos[0] = mTdernier;
+	mStPos[0] = boum;
+	if (mMemPos<mMemL) mMemPos++;
+/* a chaque tirage, on regroupe les impulsions precedentes */
+for(i=mMemPos-2 ; i>0 ; i--)
+    {
+	if(mStPos[i]==0.)continue;
+	//	printf("i,temps,bruit %d,%g,%g \n",i,mTePos[i],mStPos[i]);
+	Somme = mStPos[i]/_mysqrtf(mTePos[i]);
+	    SbaryT = mStPos[i] * mTePos[i];
+	    Poids = mStPos[i];
+	    for(j=i-1 ; j>=0 ; j--)
+		{
+		    //		printf("  j,temps,bruit %d,%g,%g \n",j,mTePos[j],mStPos[j]);
+		Somme += mStPos[j]/_mysqrtf(mTePos[j]);
+		    Poids += mStPos[j];
+		    SbaryT += mStPos[j] * mTePos[j];
+		    BaryT = SbaryT / Poids;
+		    Approx = Poids / _mysqrtf(BaryT);
+		    Erreur = (Approx - Somme) / Somme;
+		    //		    		    printf("i,j = %d %d Approx = %g \n",i,j,_myfabsf(Erreur));
+		    //		    printf("Temps,Bruit = %g %g \n",BaryT,Poids);
+		    if(_myfabsf(Erreur)<epsilon)
+			{
+			    mStPos[i]=Poids;
+			    mTePos[i]=BaryT;
+			    mStPos[j]=0.;
+			}
+		    else break;
+		}
+    }
+nReduit=0;
+for(i=0; i<mMemPos-1 ; i++)
+    {
+	if(mStPos[i]!=0)
+	    {
+		mStPos[nReduit]=mStPos[i];
+		mTePos[nReduit]=mTePos[i];
+		nReduit++;
+	    }
+    }
+mMemPos=nReduit+1;
+
+    }
+else
+    {
+	for(i=mMemNeg; i>0; i--)
+	    {
+		mStNeg[i] = mStNeg[i-1];
+		mTeNeg[i] = mTeNeg[i-1];
+	    }
+	mTeNeg[0] = mTdernier;
+	mStNeg[0] = boum;
+	if (mMemNeg<mMemL) mMemNeg++;
+    
+
+/* idem pour negatifs */
+for(i=mMemNeg-2 ; i>0 ; i--)
+    {
+	if(mStNeg[i]==0.)continue;
+	//	printf("i,temps,bruit %d,%g,%g \n",i,mTeNeg[i],mStNeg[i]);
+	Somme = mStNeg[i]/_mysqrtf(mTeNeg[i]);
+	    SbaryT = mStNeg[i] * mTeNeg[i];
+	    Poids = mStNeg[i];
+	    for(j=i-1 ; j>=0 ; j--)
+		{
+		    //		printf("  j,temps,bruit %d,%g,%g \n",j,mTeNeg[j],mStNeg[j]);
+		Somme += mStNeg[j]/_mysqrtf(mTeNeg[j]);
+		    Poids += mStNeg[j];
+		    SbaryT += mStNeg[j] * mTeNeg[j];
+		    BaryT = SbaryT / Poids;
+		    Approx = Poids / _mysqrtf(BaryT);
+		    Erreur = (Approx - Somme) / Somme;
+		    //		    printf("i,j = %d %d Approx = %g \n",i,j,Erreur);
+		    //		    printf("Temps,Bruit = %g %g \n",BaryT,Poids);
+		    if(_myfabsf(Erreur)<epsilon)
+			{
+			    mStNeg[i]=Poids;
+			    mTeNeg[i]=BaryT;
+			    mStNeg[j]=0.;
+			}
+		    else break;
+		}
+    }
+nReduit=0;
+for(i=0; i<mMemNeg-1 ; i++)
+    {
+	if(mStNeg[i]!=0)
+	    {
+		mStNeg[nReduit]=mStNeg[i];
+		mTeNeg[nReduit]=mTeNeg[i];
+		nReduit++;
+	    }
+    }
+mMemNeg=nReduit+1;
+    }
+/* on tire la duree a attendre avant la prochaine impulsion de bruit */
+// $CHECK$ avec Francois - rndm() remplace par Reza 10/01/99 
+//  passage en drand le 1/12/99
+mduree = -mTau*log(drand01());  
+
+// if(mNtirage<mMemL) mNtirage++;
+mNtirage++;
+/*
+int idn=1;
+float pds=1.;
+float nul=0.;
+hfill_(&idn,&mduree,&nul,&pds);
+*/
+// printf("Ntirage %d,mMemPos,Neg %d,%d, Suppress = %d \n",mNtirage,mMemPos,mMemNeg, Suppress);
+    }
+/* On calcule le bruit total */
+
+//printf("mMemPos,Neg,%d %d\n",mMemPos,mMemNeg);
+//for(i=0;i<mMemPos;i++) printf("mTePos %g \n",mTePos);
+//for(i=0;i<mMemNeg;i++) printf("mTeNeg %g \n",mTeNeg);
+if(mNsaut == 0)
+    {
+	// printf("coucou\n");
+rn = 0.;
+int indlim=0;
+for(i=0; i < mMemPos-1; i++) 
+{
+if(mTePos[i] > 1.) break; 		// Modif F.C et D.Y. 03/2000
+rn += mStPos[i];
+indlim++;
+}
+// float ajout=0.;
+for(i=indlim; i < mMemPos-1; i++)  rn += mStPos[i]/_mysqrtf(mTePos[i]);
+indlim=0;
+for(i=0; i < mMemNeg-1; i++) 
+{
+if(mTeNeg[i] > 1.) break;		// Modif F.C et D.Y. 03/2000
+rn += mStNeg[i];
+indlim++;
+}
+for(i=indlim; i < mMemNeg-1; i++) rn += mStNeg[i]/_mysqrtf(mTeNeg[i]);
+}
+}
+return(rn);
+}
+/* --Methode-- */
+//++
+int MemNoise::Print()
+//
+//--
+{
+int i,j,rc=0;
+printf("MemNoise::Print()  MemL=%d  Tau= %g \n", mMemL, mTau);
+printf("mNtirage= %d , mMemPos= %d , mMemNeg= %d \n",mNtirage,mMemPos,mMemNeg);
+// printf("MemNoise::Print() Vecteur de Dynamique / Etat : \n");
+/* for(i=0; i<mMemL-1; i+=2) 
+  printf("%d:   D=%g  S=%g   | %d:  D=%g  S=%g \n", i, 
+         mDyn[i], mState[i], i+1, mDyn[i], mState[i]);   
+	 */
+return(rc);
+}
+
+//++
+// Class	SumNoise
+//
+// include      bruit.h math.h fmath.h nbrandom.h
+//
+//    Generateur de bruit blanc + 1/f avec fknee
+
+//--
+//++
+//
+// Links	Parents
+//
+//    NoiseGenerator
+//     
+//-- 
+//++
+// Titre	Constructor
+//--
+// Generateur de bruit blanc + 1/f avec fknee
+
+
+/* --Methode-- */
+//++
+SumNoise::SumNoise(float fknee, float sig, int mem, float tau)
+    : NoiseGenerator(sig)
+//
+//--
+{
+// Reza 27/01/98 :
+// Je calcule les sigma du MemNoise d'apres la formule de Francois 
+// mn = new MemNoise(sig*fknee);  
+// mn = new MemNoise(1.4142*sig*_mysqrtf(fknee),1,10.,1000000); // modif appel FC 13 mai 98.  
+mn = new MemNoise(1.4142*sig*sqrt((double)fknee),mem,tau,12000); // FC 13 mai 98. -> Reza 1/12/99 
+}
+
+
+//++
+// Titre	Destructor
+//--
+/* --Methode-- */
+//++
+SumNoise::~SumNoise()
+//
+//--
+{
+delete mn;
+}
+
+//++
+// Titre	Public Methods
+//--
+/* --Methode-- */
+//++
+float SumNoise::Noise()
+//
+//--
+{
+return(NoiseGenerator::Noise() + mn->Noise());
+}
Index: /tags/V_Dec2002/SophyaLib/Samba/bruit.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/Samba/bruit.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Samba/bruit.h	(revision 2309)
@@ -0,0 +1,115 @@
+// Noise generators
+//        R. Ansari , F. Couchot   1998
+// DAPNIA/SPP (Saclay) / CEA    LAL - IN2P3/CNRS  (Orsay)
+
+#ifndef BRUIT_H_SEEN
+#define BRUIT_H_SEEN
+
+namespace SOPHYA {  
+
+class NoiseGenerator {
+public :
+			NoiseGenerator(float sigma=1.); 
+  virtual		~NoiseGenerator();
+  virtual float		Noise();
+  inline  unsigned long int           NCoups() { return(mNCoups); }
+
+protected :
+unsigned long  int mNCoups;
+  float mSigma;
+};
+
+class  RWalkNoise : public NoiseGenerator {
+public :
+			RWalkNoise(float sigma=1.);
+  virtual		~RWalkNoise();
+  virtual float		Noise();
+
+protected:
+  float mState;
+};
+
+class OOFNoise : public NoiseGenerator {
+public :
+  enum {
+     ACF_Def = 0,
+     ACF_Exp = 1
+  };
+			OOFNoise(float sigma=1., int typacf=ACF_Exp, 
+                                 int mem=128, float tau=1.);
+  virtual		~OOFNoise();
+  virtual float         Noise();
+  void                  Print();
+
+protected:
+  int mTypACF;
+  int mMemL;
+  float mTau; 
+  double* mState;
+  double* mDyn;
+};
+
+class EXPNoise : public NoiseGenerator {
+public :
+  enum {
+     ACF_Def = 0,
+     ACF_Exp = 1
+  };
+			EXPNoise(float sigma=1., int typacf=ACF_Exp, 
+                                 int mem=128, float tau=1.);
+  virtual		~EXPNoise();
+  virtual float         Noise();
+  void                  Print();
+
+protected:
+  int mTypACF;
+long  int mMemL;
+  float mTau; 
+  double* mState;
+  double* mDyn;
+};
+
+class MemNoise : public NoiseGenerator {
+public :
+  enum {
+     ACF_Def = 0,
+     ACF_Exp = 1
+  };
+			MemNoise(float sigma=1., int mem=128, float tau=1., int ava=4096);
+  virtual		~MemNoise();
+  virtual float         Noise();
+  virtual float         Avance(long Asauter);
+  int                   Print();
+ 
+protected:
+  int mTypACF;
+  int mMemL; int mCoupHaut;
+unsigned long   mNappel;
+unsigned long   mNappLast;
+  float mTeappel;
+  float mTau;
+  float mduree;
+  float mTdernier;
+  int mNtirage;
+  int mMemPos;
+  int mMemNeg;
+  float* mStPos;
+  float* mTePos;
+  float* mStNeg;
+  float* mTeNeg;
+};
+
+class  SumNoise : public NoiseGenerator {
+public :
+			SumNoise(float fknee, float sig=1., int mem=32, float tau=10.);
+  virtual		~SumNoise();
+  virtual float		Noise();
+
+protected:
+  MemNoise* mn;
+};
+
+} // namespace SOPHYA
+
+#endif
+
Index: /tags/V_Dec2002/SophyaLib/Samba/circle.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/Samba/circle.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Samba/circle.cc	(revision 2309)
@@ -0,0 +1,310 @@
+#include <math.h>
+#include "circle.h"
+//++ 
+// Class	Circle
+//
+// include      circle.h math.h
+//--
+//++
+//
+// Links	Parents
+//
+//    Geometry
+//    
+//-- 
+//++
+// Titre	Constructors
+//--
+//++
+Circle::Circle() 
+//
+//--
+{
+  UnitVector temp;
+  SetCircle(temp,M_PI/2.);
+}
+//++
+Circle::Circle(double theta, double phi, double aperture) 
+//
+//--
+{
+  UnitVector temp(theta,phi);
+  SetCircle(temp,aperture);
+}
+//++
+Circle::Circle(double x, double y, double z, double aperture) 
+//
+//--
+{
+  UnitVector temp(x,y,z);
+  SetCircle(temp,aperture);
+}
+//++
+Circle::Circle(const Vector3d& v, double aperture) 
+//
+//--
+{
+  UnitVector temp=v;
+  SetCircle(temp,aperture);
+}
+//++
+Circle::Circle(const Circle& c) 
+//
+//    copy constructor
+//--
+{
+  UnitVector temp= c.Omega();
+  SetCircle(temp,c._angouv);
+}
+//++
+// Titre	Public Methods
+//--
+//++
+void Circle::SetCircle(const UnitVector& temp, double aperture) 
+//
+//--
+{
+  _spinunitaxis= temp;
+
+  _angouv = aperture;
+  _cangouv= cos(_angouv);
+  _sangouv= sin(_angouv);
+
+  _spinaxis=_spinunitaxis*fabs(_cangouv);
+
+  _theta =_spinunitaxis.Theta();
+  _ctheta= cos(_theta);
+  _stheta= sin(_theta);
+
+  _phi =_spinunitaxis.Phi();
+  _cphi= cos(_phi);
+  _sphi= sin(_phi);
+
+  _x= _spinunitaxis.X();
+  _y= _spinunitaxis.Y();
+  _z= _spinunitaxis.Z();
+}
+//++
+void Circle::SetSpinAxis(double theta, double phi)
+//
+//--
+{ 
+  UnitVector temp(theta,phi);
+  SetCircle(temp,_angouv);
+}
+//++
+void Circle::SetSpinAxis(const Vector3d& u) 
+//
+//--
+{
+  UnitVector temp=u;
+  SetCircle(temp,_angouv);
+}
+//++
+void Circle::SetSpinAxis(double x, double y, double z) 
+//
+//--
+{
+  UnitVector temp(x,y,z);
+  SetCircle(temp,_angouv);
+}
+//++
+void Circle::SetApertureAngle(double aperture) 
+//
+//--
+{ 
+  SetCircle(_spinunitaxis,aperture);
+}
+//++
+void Circle::SetApertureAngle(const Circle& c) 
+//
+//--
+{
+  SetCircle(_spinunitaxis,c._angouv);
+}
+
+//++
+UnitVector Circle::ConvToSphere(double psi) const 
+//
+//    Return UnitVector corresponding to a given position donnee on the circle
+//--
+{
+  psi=mod(psi,pi2);
+  double xout, yout, zout;
+  double cosa=cos(_angouv);
+  double sina=sin(_angouv);
+  double cost=cos(_theta);
+  double sint=sin(_theta);
+  double cosphi=cos(_phi);
+  double sinphi=sin(_phi);
+  double cosp=cos(psi);
+  double sinp=sin(psi);
+  xout = cosa*sint*cosphi+sina*(sinphi*sinp-cost*cosphi*cosp);
+  yout = cosa*sint*sinphi-sina*(cosphi*sinp+cost*sinphi*cosp);
+  zout = cosa*cost+sina*sint*cosp;
+  return UnitVector(xout,yout,zout);
+}
+//++
+UnitVector Circle::TanOnCircle(double psi) const 
+//
+//    Return UnitVector corresponding to the tangent to the circle 
+//    at given position on the circle.
+//--
+{
+  psi=mod(psi,pi2);
+  double xout, yout, zout;
+  double cost=cos(_theta);
+  double sint=sin(_theta);
+  double cosphi=cos(_phi);
+  double sinphi=sin(_phi);
+  double cosp=cos(psi);
+  double sinp=sin(psi);
+  xout = cosp*sinphi+sinp*sint*cosphi;
+  yout = -cosp*cosphi+sinp*sint*sinphi;
+  zout = -sinp*cost;
+  return UnitVector(xout,yout,zout);
+}
+//++
+UnitVector Circle::EPhi(double psi) const 
+//
+//    Return the  vector  tangent to the sphere in the plane (xy) 
+//    at a given position on the circle.
+//--
+{
+  psi=mod(psi,pi2);
+  return ConvToSphere(psi).EPhi();
+}
+//++
+UnitVector Circle::ETheta(double psi) const 
+//
+//    Return the other tangent  vector( orthogonal to EPhi)-- 
+//    see previous method
+//--
+{
+  psi=mod(psi,pi2);
+  return ConvToSphere(psi).ETheta();
+}
+//++
+double Circle::SepAngleTanEPhi02PI(double psi) const
+//
+//    Return separation angle in [0,2Pi] at a given position on the 
+//    circle and EPhi
+//--
+{
+  psi=mod(psi,pi2);
+  UnitVector pol=this->TanOnCircle(psi);
+  UnitVector ephi=this->EPhi(psi);
+  double angle=pol.SepAngle(ephi);
+  if( pol.Z() <= 0 ) angle=pi2-angle;
+  return angle;
+}
+//++
+void Circle::Print(ostream& os) const 
+//
+//--
+{
+  os << "1 - Circle - Axe de Spin Unitaire : " << _spinunitaxis << endl;
+  os << "1 - Circle - Axe de Spin : " << _spinaxis << endl;
+  os << "2 - Circle - Angle d'ouverture : " << _angouv << endl;
+  os << "3 - Circle - Theta,Phi : " << _theta << "," << _phi << endl;
+  os << "4 - Circle - x,y,z : " << _x << "," << _y << "," << _z << endl;
+}
+//++
+//
+// inline double Theta() const
+// inline double Phi() const 
+// inline double ApertureAngle() const 
+// inline Vector3d Omega() const 
+//--
+//++
+// Titre	Operators
+//--
+
+Circle& Circle::operator=(const Circle& c) 
+{
+  if( this != &c ) 
+    {
+      UnitVector temp(c.Omega());
+      SetCircle(temp,c.ApertureAngle());
+    } 
+  return *this;
+}
+//++
+bool Circle::operator==(const Circle& c) const 
+//
+//--
+{
+  bool flag;
+  if( this == &c ) flag=true;
+  else flag=false;
+  return flag;
+}
+//++
+bool Circle::operator!=(const Circle& c) const 
+//
+//--
+{
+  return (bool)(1-(this->operator==(c)));
+}
+//
+bool Circle::Intersection(const Circle& c) const
+{
+  double alphak= _angouv;
+  double alphal= c._angouv;
+  Vector3d ok= _spinaxis;
+  Vector3d ol= c._spinaxis;
+  double gamma= ok.SepAngle(ol);
+
+  if(fabs(alphak-alphal) < gamma && gamma <= (alphak+alphal) && this != &c) {
+    return true;
+  } else {
+    return false;
+  }
+}
+//
+bool Circle::Intersection(const Circle& c, double* psi) const
+{
+  double alphak= _angouv;
+  double alphal= c._angouv;
+  Vector3d ok= _spinaxis;
+  Vector3d ol= c._spinaxis;
+  double gamma= ok.SepAngle(ol);
+
+  if(fabs(alphak-alphal) < gamma && gamma <= (alphak+alphal) && this != &c) {
+
+    double sgamma= sin(gamma); 
+    double cgamma= cos(gamma);
+
+    double sdphi= _sphi*c._cphi - _cphi*c._sphi; 
+    double cdphi= _cphi*c._cphi + _sphi*c._sphi;
+
+    double ssk= c._stheta*sdphi/sgamma;
+    double csk= (c._ctheta*_stheta-c._stheta*_ctheta*cdphi)/sgamma;
+
+    double ssl= -_stheta*sdphi/sgamma;
+    double csl= (_ctheta*c._stheta-_stheta*c._ctheta*cdphi)/sgamma;
+
+    double ak= atan2(ssk,csk);
+    double al= atan2(ssl,csl);
+    double omegak= acos((c._cangouv-_cangouv*cgamma)/sgamma/_sangouv);
+    double omegal= acos((_cangouv-c._cangouv*cgamma)/sgamma/c._sangouv);
+
+    psi[0]= fmod(ak-omegak+pi2,pi2);
+    psi[1]= fmod(ak+omegak+pi2,pi2);
+    psi[2]= fmod(al-omegal+pi2,pi2);
+    psi[3]= fmod(al+omegal+pi2,pi2);
+
+    if(psi[0] > psi[1]) {
+      swap(psi[0],psi[1]); 
+      swap(psi[2],psi[3]); 
+    }                      
+    return true;
+    
+  } else {
+    psi[0] = -1.;
+    psi[1] = -1.;
+    psi[2] = -1.;
+    psi[3] = -1.;
+    return false;
+  }
+}
Index: /tags/V_Dec2002/SophyaLib/Samba/circle.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/Samba/circle.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Samba/circle.h	(revision 2309)
@@ -0,0 +1,110 @@
+//   Geometry handling class 
+//        R. Ansari , G. Le Meur   2000
+// DAPNIA/SPP (Saclay) / CEA    LAL - IN2P3/CNRS  (Orsay)
+
+#ifndef CIRCLE_H_SEEN
+#define CIRCLE_H_SEEN
+
+#include <math.h>
+#include <iostream.h>
+#include "vector3d.h"
+#include "unitvector.h"
+#include "utilgeom.h"
+#include "geometry.h"
+
+namespace SOPHYA {  
+
+class Circle : public Geometry
+{
+  
+ public:
+
+  Circle();
+  Circle(double theta, double phi, double aperture);
+  Circle(double x, double y, double z, double aperture);
+  Circle(const Vector3d& v, double aperture=M_PI/2.);
+  Circle(const Circle& c);
+  virtual ~Circle() {}
+
+  void SetCircle(const UnitVector&, double);
+  void SetSpinAxis(double theta, double phi);
+  void SetSpinAxis(const Vector3d&);
+  void SetSpinAxis(double x, double y, double z);
+  void SetApertureAngle(double aperture);
+  void SetApertureAngle(const Circle&);
+  
+  // psi contient les 4 valeurs des angles d intersection. -1 si les cercles ne se coupent pas
+  // voir la numerotation dans le .cc
+  /*   psi contains  4 values of the intersection  angles. 
+    -1 if  circles do not intersect
+    psi[0]=psi(i,j,0)
+    psi[1]=psi(i,j,1)
+    psi[2]=psi(j,i,0)
+    psi[3]=psi(j,i,1)
+  */
+
+  bool Intersection(const Circle&, double*) const;
+  bool Intersection(const Circle&) const;
+
+  // donne le UnitVector correspondant a une position donnee sur le cercle
+  /*!    Return UnitVector corresponding to a given position donnee on the circle
+   */
+  UnitVector ConvToSphere(double psi) const;
+
+  // donne le UnitVector correspondant la tangente au cercle en une position donnee sur le cercle
+  /*!    Return UnitVector corresponding to the tangent to the circle */
+//    at given position on the circle.
+  UnitVector TanOnCircle(double psi) const;
+
+  // donne le vecteur tangent dans le plan (xy) a la sphere en une position donnee sur le cercle
+  /*!    Return the  vector  tangent to the sphere in the plane (xy) 
+    at a given position on the circle.
+  */
+  UnitVector EPhi(double psi) const;
+
+  // donne l autre vecteur tangent (orthogonal a EPhi)
+  /*!    Return the other tangent  vector( orthogonal to EPhi)-- 
+    see previous method
+  */
+  UnitVector ETheta(double psi) const;
+
+   // donne l angle de separation dans [0,2Pi] en une position donnee sur le cercle et EPhi
+  /*!   Return separation angle in [0,2Pi] at a given position on the 
+    circle and EPhi
+  */
+  double SepAngleTanEPhi02PI(double psi) const;
+
+  double Theta() const {return _spinaxis.Theta();}
+  double Phi() const {return _spinaxis.Phi();}
+  double ApertureAngle() const {return _angouv;}
+  Vector3d Omega() const {return _spinaxis;}
+  virtual void Print(ostream&) const;
+  Circle& operator=(const Circle&);
+  bool operator==(const Circle&) const;
+  bool operator!=(const Circle&) const;
+
+ private:
+
+  Vector3d _spinaxis;
+  UnitVector _spinunitaxis;
+  double _angouv;
+  double _theta,_phi;
+  double _x,_y,_z;
+
+  double _cangouv;
+  double _sangouv;
+  double _ctheta;
+  double _stheta;
+  double _cphi;
+  double _sphi;
+};
+
+inline ostream& operator<<(ostream& s, const Circle& c) 
+{  
+  c.Print(s);  
+  return s;  
+}
+
+} // namespace SOPHYA
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/Samba/datacirclebase.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/Samba/datacirclebase.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Samba/datacirclebase.h	(revision 2309)
@@ -0,0 +1,35 @@
+#ifndef DATACIRCLEBASE_H_SEEN
+#define DATACIRCLEBASE_H_SEEN
+
+#include "circle.h"
+
+static long l_ft_nint(double x) {
+  return ( (x < 0.) ? (long)(x-0.5) : (long)(x+0.5) ) ;
+}
+
+class DataCircleBase : public Circle {
+
+ public:
+
+  DataCircleBase() {;}
+  DataCircleBase(double theta,double phi,double aperture) : Circle(theta,phi,aperture) {;}
+
+  virtual ~DataCircleBase() {;}
+
+  virtual int NMeasurements() const = 0;
+  virtual double getData(double) const = 0;
+  virtual double getTMeasure(double) const = 0;
+
+  virtual void print(ostream&) const= 0;
+
+  // Pour compatibilite avec les autres classes  
+  inline void Print(ostream& s) const { print(s); }
+};
+
+inline ostream& operator<<(ostream& s, const DataCircleBase& c)
+{
+  c.Print(s);
+  return s;
+}
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/Samba/datacirclefake.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/Samba/datacirclefake.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Samba/datacirclefake.cc	(revision 2309)
@@ -0,0 +1,49 @@
+#include <iostream.h>
+#include "datacirclefake.h"
+
+DataCircleFake::DataCircleFake() : _NMeasurements(0), _mesures(NULL) 
+{;}
+
+DataCircleFake::DataCircleFake(double theta,double phi,double aperture,int NEch,double tl) : DataCircleBase(theta,phi,aperture), _NMeasurements(NEch), _mesures(NULL)
+{
+  _mesures= new double[NEch];
+  int i;
+  for(i = 0; i < NEch; i++) {
+    _mesures[i]= tl;
+  }
+}
+
+DataCircleFake::~DataCircleFake()
+{
+  if(_mesures != NULL) delete [] _mesures;
+}
+
+double DataCircleFake::getData(double psi) const {
+
+  int ibin= l_ft_nint(psi*_NMeasurements/(2.*M_PI));
+  //cout << "bin= " << ibin << ", " << _mesures[ibin] << endl;
+  return _mesures[ibin];
+}
+
+int DataCircleFake::NMeasurements() const { 
+
+  return _NMeasurements;
+}
+
+void DataCircleFake::print(ostream& out) const {
+
+  out << " Circle:: ApertureAngle= " << ApertureAngle() << ", Theta= " 
+      << Theta() << ", Phi= " << Phi() << ", NSamples= " 
+      << NMeasurements() << endl;
+}
+
+double DataCircleFake::getTMeasure(double psi) const {
+
+  if(_mesures == NULL) {
+    cout << "  DataCircleFake::getTMeasure data must be stored"
+	 << " in an array... " << endl;
+    exit(0);
+  }
+  int ibin= l_ft_nint(psi*_NMeasurements/(2.*M_PI));
+  return _mesures[ibin];
+}
Index: /tags/V_Dec2002/SophyaLib/Samba/datacirclefake.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/Samba/datacirclefake.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Samba/datacirclefake.h	(revision 2309)
@@ -0,0 +1,24 @@
+#ifndef DATACIRCLEFAKE_H_SEEN
+#define DATACIRCLEFAKE_H_SEEN
+
+#include "datacirclebase.h"
+
+class DataCircleFake : public DataCircleBase {
+
+ public:
+
+  DataCircleFake();
+  DataCircleFake(double,double,double,int,double);
+  virtual ~DataCircleFake();
+
+  virtual int NMeasurements() const;
+  virtual double getData(double) const;
+  virtual double getTMeasure(double) const;
+  virtual void print(ostream&) const;
+
+ private:
+
+  int _NMeasurements;
+  double* _mesures;
+};
+#endif
Index: /tags/V_Dec2002/SophyaLib/Samba/exclude
===================================================================
--- /tags/V_Dec2002/SophyaLib/Samba/exclude	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Samba/exclude	(revision 2309)
@@ -0,0 +1,2 @@
+anagen.cc
+syngen.cc
Index: /tags/V_Dec2002/SophyaLib/Samba/geometry.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/Samba/geometry.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Samba/geometry.h	(revision 2309)
@@ -0,0 +1,30 @@
+//   Geometry handling class 
+//        R. Ansari , G. Le Meur   2000
+// DAPNIA/SPP (Saclay) / CEA    LAL - IN2P3/CNRS  (Orsay)
+
+#ifndef GEOMETRY_SEEN
+#define GEOMETRY_SEEN
+
+
+#include "unitvector.h"
+
+namespace SOPHYA {  
+
+/*!
+  \class SOPHYA::Geometry
+  \ingroup Samba
+  Base class (pure virtual) for geometry handling and coordinate
+  system transforms
+*/
+
+class Geometry
+{
+public: 
+Geometry() {;}
+virtual ~Geometry() {;}
+virtual UnitVector  ConvToSphere(double psi) const = 0;
+};
+
+} // namespace SOPHYA
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/Samba/lambdaBuilder.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/Samba/lambdaBuilder.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Samba/lambdaBuilder.cc	(revision 2309)
@@ -0,0 +1,332 @@
+#include "lambdaBuilder.h"
+#include "nbconst.h"
+
+
+/*!
+  \class SOPHYA::Legendre
+generate Legendre polynomials : use in two steps : 
+
+a) instanciate Legendre(\f$x\f$, \f$lmax\f$) ; \f$x\f$ is the value for wich Legendre polynomials will be required (usually equal to \f$\cos \theta\f$) and \f$lmax\f$ is the MAXIMUM value of the order of polynomials wich will be required in the following code (all polynomials, from \f$l=0 to lmax\f$, are computed once for all by an iterative formula).
+
+b) get the value of Legendre polynomial for a particular value of \f$l\f$ by calling the method getPl.
+
+*/
+
+
+Legendre::Legendre(r_8 x, int_4 lmax) 
+{
+  if (fabs(x) > 1. ) 
+    {
+      throw RangeCheckError("variable for Legendre polynomials must have modules inferior to 1" );
+    }
+  x_ = x;
+  array_init(lmax);
+}
+   
+/*! \fn void SOPHYA::Legendre::array_init(int_4 lmax)
+
+compute all \f$P_l(x,l_{max})\f$ for \f$l=1,l_{max}\f$ 
+*/
+void Legendre::array_init(int_4 lmax)
+{
+  lmax_ = lmax;
+  Pl_.ReSize(lmax_+1);
+  Pl_(0)=1.;
+  if (lmax>0) Pl_(1)=x_;
+  for (int k=2; k<Pl_.NElts(); k++)
+    {
+      Pl_(k) = ( (2.*k-1)*x_*Pl_(k-1)-(k-1)*Pl_(k-2) )/k;
+    }
+}
+
+TriangularMatrix<r_8> LambdaLMBuilder::a_recurrence_ = TriangularMatrix<r_8>();
+TriangularMatrix<r_8> LambdaLMBuilder::lam_fact_     = TriangularMatrix<r_8>();
+TVector<r_8>* LambdaLMBuilder::normal_l_     = NULL;
+
+
+
+/*! \class SOPHYA::LambdaLMBuilder
+
+
+This class generate the coefficients :
+\f[
+            \lambda_l^m=\sqrt{\frac{2l+1}{4\pi}\frac{(l-m)!}{(l+m)!}}
+	    P_l^m(\cos{\theta})
+\f]
+where \f$P_l^m\f$ are the associated Legendre polynomials.  The above coefficients contain the theta-dependance of spheric harmonics : 
+\f[
+            Y_{lm}(\cos{\theta})=\lambda_l^m(\cos{\theta}) e^{im\phi}.
+\f]
+
+Each object has a fixed theta (radians), and maximum l and m to be calculated
+(lmax and mmax).
+ use the class in two steps : 
+a) instanciate  LambdaLMBuilder(\f$\theta\f$, \f$lmax\f$, \f$mmax\f$) ;  \f$lmax\f$ and \f$mmax\f$ are  MAXIMUM values for which \f$\lambda_l^m\f$ will be required in the following code (all coefficients, from \f$l=0 to lmax\f$, are computed once for all by an iterative formula).
+b) get the values of coefficients for  particular values of \f$l\f$ and \f$m\f$ by calling the method lamlm.
+*/
+
+
+LambdaLMBuilder::LambdaLMBuilder(r_8 theta,int_4 lmax, int_4 mmax)
+    {
+      cth_=cos(theta);
+      sth_=sin(theta);
+      array_init(lmax, mmax);
+    }
+LambdaLMBuilder::LambdaLMBuilder(r_8 costet, r_8 sintet,int_4 lmax, int_4 mmax)
+    {
+      cth_=costet;
+      sth_=sintet;
+      array_init(lmax, mmax);
+    }
+void LambdaLMBuilder::array_init(int lmax, int mmax)
+   {
+     if (a_recurrence_.Size() == 0)
+       {
+	 //	 a_recurrence_ = new TriangularMatrix<r_8>;
+	 updateArrayRecurrence(lmax);
+       }
+     else
+       if ( lmax > (a_recurrence_).rowNumber()-1     )
+	 {
+	   cout << " WARNING : The classes LambdaXXBuilder will be more efficient if instanciated with parameter lmax = maximum value of l index which will be needed in the whole application (arrays not recomputed) " << endl;
+	   cout << "lmax= " << lmax << " previous instanciation with lmax= " <<  (a_recurrence_).rowNumber() << endl;
+	 updateArrayRecurrence(lmax);
+	 }
+     lmax_=lmax;
+     mmax_=mmax;
+     r_8 bignorm2 = 1.e268; // = 1e-20*1.d288
+
+     lambda_.ReSizeRow(lmax_+1);
+
+     r_8 lam_mm = 1. / sqrt(4.*Pi) *bignorm2;
+	  
+     for (int m=0; m<=mmax_;m++)
+       {
+
+
+	 lambda_(m,m)= lam_mm / bignorm2; 
+
+	 r_8 lam_0=0.;
+	 r_8 lam_1=1. /bignorm2 ;
+	 //	 r_8 a_rec = LWK->a_recurr(m,m);
+	 r_8 a_rec = a_recurrence_(m,m);
+	 r_8 b_rec = 0.;
+	 for (int l=m+1; l<=lmax_; l++)
+	 {
+	   r_8 lam_2 = (cth_*lam_1-b_rec*lam_0)*a_rec;
+	   lambda_(l,m) = lam_2*lam_mm;
+	   b_rec=1./a_rec;
+	   //	   a_rec= LWK->a_recurr(l,m);
+	   a_rec= a_recurrence_(l,m);
+	   lam_0 = lam_1;
+	   lam_1 = lam_2;
+	 }
+
+	 lam_mm = -lam_mm*sth_* sqrt( (2.*m+3.)/ (2.*m+2.) );
+
+       }
+   }
+
+
+/*! \fn void  SOPHYA::LambdaLMBuilder::updateArrayRecurrence(int_4 lmax)
+
+ compute a static array of coefficients independant from theta (common to all instances of the LambdaBuilder Class 
+*/
+void  LambdaLMBuilder::updateArrayRecurrence(int_4 lmax)
+   {
+     a_recurrence_.ReSizeRow(lmax+1);
+     for (int m=0; m<=lmax;m++)
+     {
+       a_recurrence_(m,m) = sqrt( 2.*m +3.);
+       for (int l=m+1; l<=lmax; l++)
+	 {
+	   r_8 fl2 = (l+1.)*(l+1.);
+	   a_recurrence_(l,m)=sqrt( (4.*fl2-1.)/(fl2-m*m) );
+	 }
+     }
+   }
+
+/*! \fn void  SOPHYA::LambdaLMBuilder::updateArrayLamNorm()
+
+ compute  static arrays of coefficients independant from theta (common to all instances of the derived  classes 
+*/
+void  LambdaLMBuilder::updateArrayLamNorm()
+     {
+       lam_fact_.ReSizeRow(lmax_+1);
+       for(int m = 0;m<= lmax_; m++)
+	 {
+	   for (int l=m; l<=lmax_; l++)
+	     {
+	       lam_fact_(l,m) =2.*(r_8)sqrt( (2.*l+1)*(l+m)*(l-m)/(2.*l-1)  );
+	     }
+	 }
+       (*normal_l_).ReSize(lmax_+1);
+       (*normal_l_)(0)=0.;
+       (*normal_l_)(1)=0.;
+       for (int l=2; l< (*normal_l_).NElts(); l++)
+	 {
+	   (*normal_l_)(l) =(r_8)sqrt( 2./( (l+2)*(l+1)*l*(l-1) ) );	
+	 }
+     }
+
+
+/*! \class SOPHYA::LambdaWXBuilder
+
+This class generates the coefficients :
+\f[
+            _{w}\lambda_l^m=-2\sqrt{\frac{2(l-2)!}{(l+2)!}\frac{(2l+1)}{4\pi}\frac{(l-m)!}{(l+m)!}} G^+_{lm}
+\f]
+\f[
+            _{x}\lambda_l^m=-2\sqrt{\frac{2(l-2)!}{(l+2)!}\frac{(2l+1)}{4\pi}\frac{(l-m)!}{(l+m)!}}G^-_{lm}
+\f]
+where
+\f[G^+_{lm}(\cos{\theta})=-\left( \frac{l-m^2}{\sin^2{\theta}}+\frac{1}{2}l\left(l-1\right)\right)P_l^m(\cos{\theta})+\left(l+m\right)\frac{\cos{\theta}}{\sin^2{\theta}}P^m_{l-1}(\cos{\theta})
+\f]
+and
+\f[G^-_{lm}(\cos{\theta})=\frac{m}{\sin^2{\theta}}\left(\left(l-1\right)\cos{\theta}P^m_l(\cos{\theta})-\left(l+m\right)P^m_{l-1}(\cos{\theta})\right)
+\f]
+ \f$P_l^m\f$ are the associated Legendre polynomials.
+
+The coefficients express the theta-dependance of the \f$W_{lm}(\cos{\theta})\f$ and \f$X_{lm}(\cos{\theta})\f$ functions :
+\f[W_{lm}(\cos{\theta}) = \sqrt{\frac{(l+2)!}{2(l-2)!}}_w\lambda_l^m(\cos{\theta})e^{im\phi}
+\f]
+\f[X_{lm}(\cos{\theta}) = -i\sqrt{\frac{(l+2)!}{2(l-2)!}}_x\lambda_l^m(\cos{\theta})e^{im\phi}
+\f]
+ where \f$W_{lm}(\cos{\theta})\f$ and \f$X_{lm}(\cos{\theta})\f$ are defined as :
+
+\f[
+W_{lm}(\cos{\theta})=-\frac{1}{2}\sqrt{\frac{(l+2)!}{(l-2)!}}\left(
+_{+2}Y_l^m(\cos{\theta})+_{-2}Y_l^m(\cos{\theta})\right)
+\f]
+\f[X_{lm}(\cos{\theta})=-\frac{i}{2}\sqrt{\frac{(l+2)!}{(l-2)!}}\left(
+_{+2}Y_l^m(\cos{\theta})-_{-2}Y_l^m(\cos{\theta})\right)
+\f]
+
+*/
+
+
+LambdaWXBuilder::LambdaWXBuilder(r_8 theta, int_4 lmax, int_4 mmax) : LambdaLMBuilder(theta, lmax, mmax)
+  {
+    array_init();
+  }
+
+
+void LambdaWXBuilder::array_init()
+   {
+     if (lam_fact_.Size() < 1 || normal_l_ == NULL)
+       {
+	 //	 lam_fact_ = new  TriangularMatrix<r_8>;
+	 normal_l_ = new TVector<r_8>;
+	 updateArrayLamNorm();
+       }
+     else
+       if ( lmax_ > lam_fact_.rowNumber()-1  || lmax_ >  (*normal_l_).NElts()-1 )
+	 {
+	   updateArrayLamNorm();
+	 }
+
+     r_8 one_on_s2  = 1. / (sth_*sth_) ;    // 1/sin^2
+     r_8 c_on_s2    = cth_*one_on_s2;
+     lamWlm_.ReSizeRow(lmax_+1);
+     lamXlm_.ReSizeRow(lmax_+1);
+
+     // calcul des lambda
+     for(int m = 0;m<= mmax_; m++)
+       {
+	 for (int l=m; l<=lmax_; l++)
+	   {
+	     lamWlm_(l,m) =  0.;
+	     lamXlm_(l,m) =  0.;	  	
+	   }
+       }
+     for(int l = 2;l<= lmax_; l++)
+       {
+	 r_8 normal_l =  (*normal_l_)(l);	
+	 for (int m=0; m<=l; m++)
+	{
+	  r_8 lam_lm1m = LambdaLMBuilder::lamlm(l-1,m);
+	  r_8 lam_lm = LambdaLMBuilder::lamlm(l,m);
+	  r_8 lam_fact_l_m = lam_fact_(l,m);
+	  r_8  a_w =  2. * (l - m*m) * one_on_s2 + l*(l-1.);
+	  r_8  b_w =  c_on_s2 * lam_fact_l_m;
+	  r_8  a_x =  2. * cth_ * (l-1.);
+	  lamWlm_(l,m) =   normal_l * ( a_w * lam_lm - b_w * lam_lm1m );
+	  lamXlm_(l,m) = - normal_l * m* one_on_s2* ( a_x * lam_lm - lam_fact_l_m * lam_lm1m );
+	}
+       }
+
+   }
+
+/*!   \class SOPHYA::LambdaPMBuilder
+
+This class generates the coefficients
+\f[
+            _{\pm}\lambda_l^m=2\sqrt{\frac{(l-2)!}{(l+2)!}\frac{(2l+1)}{4\pi}\frac{(l-m)!}{(l+m)!}}\left( G^+_{lm} \mp G^-_{lm}\right)
+\f]
+where
+\f[G^+_{lm}(\cos{\theta})=-\left( \frac{l-m^2}{\sin^2{\theta}}+\frac{1}{2}l\left(l-1\right)\right)P_l^m(\cos{\theta})+\left(l+m\right)\frac{\cos{\theta}}{\sin^2{\theta}}P^m_{l-1}(\cos{\theta})
+\f]
+and
+\f[G^-_{lm}(\cos{\theta})=\frac{m}{\sin^2{\theta}}\left(\left(l-1\right)\cos{\theta}P^m_l(\cos{\theta})-\left(l+m\right)P^m_{l-1}(\cos{\theta})\right)
+\f]
+and \f$P_l^m\f$ are the associated Legendre polynomials.
+The coefficients express the theta-dependance of the  spin-2 spherical harmonics :
+\f[_{\pm2}Y_l^m(\cos{\theta})=_\pm\lambda_l^m(\cos{\theta})e^{im\phi}
+\f]
+*/
+
+LambdaPMBuilder::LambdaPMBuilder(r_8 theta, int_4 lmax, int_4 mmax) : LambdaLMBuilder(theta, lmax, mmax)
+  {
+    array_init();
+  }
+
+
+void LambdaPMBuilder::array_init()
+   {
+     if (lam_fact_.Size() < 1 || normal_l_ == NULL)
+       {
+	 //	 lam_fact_ = new  TriangularMatrix<r_8>;
+	 normal_l_ = new TVector<r_8>;
+	 updateArrayLamNorm();
+       }
+     else
+       if ( lmax_ > lam_fact_.rowNumber()-1  || lmax_ >  (*normal_l_).NElts()-1 )
+	 {
+	   updateArrayLamNorm();
+	 }
+
+     r_8 one_on_s2 = 1. / (sth_*sth_) ;
+     r_8 c_on_s2 = cth_*one_on_s2;
+     lamPlm_.ReSizeRow(lmax_+1);
+     lamMlm_.ReSizeRow(lmax_+1);
+
+     // calcul des lambda
+     for(int m = 0;m<= mmax_; m++)
+       {
+	 for (int l=m; l<=lmax_; l++)
+	   {
+	     lamPlm_(l,m) =  0.;
+	     lamMlm_(l,m) =  0.;	  	
+	   }
+       }
+
+     for(int l = 2;l<= lmax_; l++)
+       {
+	 r_8 normal_l =  (*normal_l_)(l);	
+	 for (int m=0; m<=l; m++)
+	   {
+	     r_8 lam_lm1m = LambdaLMBuilder::lamlm(l-1,m);
+	     r_8 lam_lm = LambdaLMBuilder::lamlm(l,m);
+	     r_8 lam_fact_l_m = lam_fact_(l,m);
+	     r_8  a_w =  2. * (l - m*m) * one_on_s2 + l*(l-1.);
+	     r_8 f_w =  lam_fact_l_m/(sth_*sth_);
+	     r_8  c_w =  2*m*(l-1.) * c_on_s2;
+
+	     lamPlm_(l,m)  = normal_l * ( -(a_w+c_w) * lam_lm + f_w*( cth_ + m) * lam_lm1m )/Rac2;
+	     lamMlm_(l,m) = normal_l * ( -(a_w-c_w) * lam_lm + f_w*( cth_ - m) * lam_lm1m )/Rac2;
+	   }
+       }
+
+   }
+
+
Index: /tags/V_Dec2002/SophyaLib/Samba/lambdaBuilder.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/Samba/lambdaBuilder.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Samba/lambdaBuilder.h	(revision 2309)
@@ -0,0 +1,151 @@
+#ifndef LAMBDABUILDER_SEEN
+#define LAMBDABUILDER_SEEN
+
+#include <math.h>
+#include "ndatablock.h"
+#include "tvector.h" 
+#include "alm.h"
+
+
+namespace SOPHYA {
+
+/*!  classe pour les polynomes de legendre*/
+class Legendre {
+
+ public :
+Legendre(r_8 x, int_4 lmax);
+
+inline r_8 getPl(int_4 l) const
+{
+  if (l>lmax_) 
+    {
+      throw (" illegal call of Legendre::getPl with index greater than lmax, which Legendre Class was instanciated with : instanciate Legendre with a greater lmax... ");
+    }
+return Pl_(l);
+}
+
+
+ private : 
+
+Legendre() {;}
+
+void array_init(int_4 lmax);
+
+  r_8 x_;
+  int_4 lmax_;
+  TVector<r_8> Pl_;
+};
+
+
+
+ class LambdaLMBuilder {
+
+ public:
+
+LambdaLMBuilder() {}
+LambdaLMBuilder(r_8 theta,int_4 lmax, int_4 mmax);
+LambdaLMBuilder(r_8 ct, r_8 st,int_4 lmax, int_4 mmax);
+virtual ~LambdaLMBuilder() {};
+
+ /*! return the value of the coefficient \f$  \lambda_l^m \f$ */
+inline double lamlm(int l, int m) const 
+  {
+    lambda_.CheckRelativeIndices(l,m);
+    return lambda_(l,m); 
+  }
+
+inline double lamlm(int index) const {
+ return lambda_(index); 
+}
+
+
+  //Return pointer to first element address of the alm's
+//inline r_8* Data()  {return lambda_.Data();}
+
+
+ private:
+ void updateArrayRecurrence(int_4 lmax);
+
+ void array_init(int lmax, int mmax);
+
+
+ // static TriangularMatrix<r_8>* a_recurrence_;
+ static TriangularMatrix<r_8> a_recurrence_;
+ TriangularMatrix<r_8> lambda_;
+
+ protected :
+
+ void updateArrayLamNorm();
+
+ // static  TriangularMatrix<r_8>* lam_fact_;
+ static  TriangularMatrix<r_8> lam_fact_;
+ static  TVector<r_8>*  normal_l_;
+ int_4 lmax_;
+ int_4 mmax_;
+ r_8 cth_;
+ r_8 sth_;
+ 
+ };
+
+
+
+class LambdaWXBuilder : public LambdaLMBuilder
+{
+ public:
+
+
+LambdaWXBuilder() {}
+
+LambdaWXBuilder(r_8 theta, int_4 lmax, int_4 mmax);
+ 
+ /*! return the value of the coefficients \f$ _{w}\lambda_l^m\f$ and \f$_{x}\lambda_l^m\f$ */
+inline void lam_wx(int l, int m, r_8& w, r_8& x) const
+   {
+  if (m > l ) 
+    {
+      throw RangeCheckError("LambdaWXBuilder::lam_wx : l < m !" );
+    }
+     w=lamWlm_(l,m);
+     x=lamXlm_(l,m);
+   }
+
+ private:
+
+ void array_init();
+
+
+  TriangularMatrix<r_8> lamWlm_;
+  TriangularMatrix<r_8> lamXlm_;
+  
+
+};
+
+class LambdaPMBuilder : public LambdaLMBuilder
+{
+ public:
+
+LambdaPMBuilder() {}
+
+ LambdaPMBuilder(r_8 theta, int_4 lmax, int_4 mmax);
+ /*! return the value of the coefficients \f$ _{+}\lambda_l^m\f$ and \f$_{-}\lambda_l^m\f$ */
+inline void lam_pm(int l, int m, r_8& lambda_plus, r_8& lambda_moins) const
+   {
+  if (m > l ) 
+    {
+      throw RangeCheckError("LambdaPMBuilder::lam_pm : l < m !" );
+    }
+      lambda_plus = lamPlm_(l,m);
+     lambda_moins = lamMlm_(l,m);
+   }
+
+ private:
+ void array_init();
+
+  TriangularMatrix<r_8> lamPlm_;
+  TriangularMatrix<r_8> lamMlm_;
+
+};
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/Samba/misstime.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/Samba/misstime.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Samba/misstime.h	(revision 2309)
@@ -0,0 +1,12 @@
+// This may look like C code, but it is really -*- C++ -*-
+#ifndef MISSIONTIME_H_SEEN
+#define MISSIONTIME_H_SEEN
+
+#include "machdefs.h"
+
+namespace SOPHYA {
+// Just a double for the moment, would be converted to a class later
+typedef r_8 MissionTime;
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/Samba/mlobe.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/Samba/mlobe.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Samba/mlobe.cc	(revision 2309)
@@ -0,0 +1,241 @@
+#include "mlobe.h"
+#include "unitvector.h"
+
+#include "timing.h"
+
+/*!
+  \class SOPHYA::MainLobe
+  \ingroup Samba
+  Class for computation of main lobe.
+  The lobe values are computed in pixels laying on nc slices 
+  with hexagonal  pavement around theta=0 , phi=0. The lobe is 
+  gaussian with sigma=sig. The slices are built every 
+  dels*sigma. all angles and the sigma are specified in radians.
+*/
+
+// #include "nbrandom.h"
+//++ 
+// Class	MainLobe
+//
+// include      mlobe.h sphericalmap.h unitvector.h math.h
+//
+//    Class for computation of main lobe.
+//
+//     The lobe values are computed in pixels laying on "nc" slices 
+//     with hexagonal  pavement around theta=0 , phi=0. The lobe is 
+//     gaussian with sigma="sig". The slices are built every 
+//     "dels"*sigma. 
+// 
+//--
+//++
+// Titre	Constructor
+//--
+/* --Methode-- */
+//++
+MainLobe::MainLobe(float sig, float dels, int nc)
+//
+//--
+{
+if (sig < 1.e-9)  sig = M_PI/100.;   // Sigma du lobe gaussien (radians)
+mSigma = sig;
+mDels = (dels < 1.e-5) ?  0.5 : dels;   // Epaisseur de chaque couche en unite de sigma
+mNC =  (nc < 1) ? 1 : nc;
+mNpix = 1;    // Nb total de pixels du lobe
+
+int i,j,k;
+for(i=1; i<=mNC; i++)  mNpix += 6*i;
+//  mT0 , mP0  Teta et Phi des pixels, Pixel 0 oriente vers (0, 0)
+mT0 = new float[mNpix];
+mP0 = new float[mNpix];
+//  mTC , mPC  Teta et Phi des pixels, Pixel 0 oriente vers (Teta, phi)
+mTC = new float[mNpix];
+mPC = new float[mNpix];
+mDx = new float[mNpix];
+mDy = new float[mNpix];
+mDr = new float[mNpix];
+// Valeurs des pixels 
+mVal = new double[mNpix];
+
+
+double teta,phi,dphi;
+double val;
+mT0[0] = mP0[0] = mTC[0] = mPC[0] = 0.;
+mVal[0] = 1.;  mDx[0] = mDy[0] = 0.;
+k = 1;  mTotVal = 1.;
+for(i=1; i<=mNC; i++) {
+  teta = (double)i*mDels;
+  val = exp(-teta*teta);
+  teta *= mSigma;
+  if (i%2)  phi = M_PI/6.;
+  else phi = 0.;
+  dphi = M_PI/(3.*i);
+  for(j=0; j<6*i; j++) {
+    mT0[k] = mTC[k] = teta;
+    phi += dphi;
+    mP0[k] = mPC[k] = phi;
+    mVal[k] = val;
+    mTotVal += val;
+    mDx[k] = teta*cos(phi);
+    mDy[k] = teta*sin(phi);
+    mDr[k] = teta;
+    k++;
+    }
+  }
+mDirTet = mDirPhi = 0.;
+return;
+}
+
+
+//++
+// Titre	Constructor
+//--
+/* --Methode-- */
+//++
+MainLobe::~MainLobe()
+//
+//--
+{
+delete mT0;
+delete mP0;
+delete mTC;
+delete mPC;
+delete mDx;
+delete mDy;
+delete mDr;
+delete mVal;
+}
+//++
+// Titre	Public Methods
+//--
+//++
+//
+// inline int      NPix() 
+//    Return the total number of pixels of the lobe            
+// inline float    Sigma()             
+// inline double   Integral()            
+//--
+/* --Methode-- */
+//++
+void MainLobe::SetDirection(float teta, float phi)
+//
+//    orientate  the lobe  toward the direction  (theta, phi)
+//--
+{
+int k;
+
+mDirTet = teta;
+mDirPhi = phi;
+
+if (teta < 0.1*mDels*mSigma) {
+  for(k=0; k<mNpix; k++) {
+    mTC[k] = mT0[k]; mPC[k] = mP0[k]; 
+    }
+  return;
+  }
+
+
+/*
+if (teta > 10.*mSigma*mDels*mNC) {   // On utilise des formules approchees
+  float stet = sin((double)teta);
+  float ctet = cos((double)teta);
+  for(k=0; k<mNpix; k++) {
+    mTC[k] = teta - mDy[k]*stet - mDr[k]*ctet;
+    mPC[k] = phi + mDx[k];
+    }
+  return;
+  }
+  */
+
+// Formules compliquees 
+
+double dx,dy,dz;
+double sphi = sin((double)phi);
+double cphi = cos((double)phi);
+double stet = sin((double)teta);
+double ctet = cos((double)teta);
+
+UnitVector pd((double)teta, (double)phi);
+UnitVector vc;
+for(k=0; k<mNpix; k++) {
+  dz = mDy[k]*stet;
+  dx = -(mDx[k]*sphi+mDy[k]*ctet*cphi);
+  dy = mDx[k]*cphi-mDy[k]*ctet*sphi;
+  vc.Setxyz(pd.X()+dx, pd.Y()+dy, pd.Z()+dz);
+  mTC[k] = vc.Theta();
+  mPC[k] = vc.Phi();
+  if (mTC[k] < 0.)  printf("ERREUR !!!! mTC[%d] = %g \n", k, mTC[k]);
+  if (mPC[k] < 0.) mPC[k] += M_PI*2.;
+  if (mPC[k] >= M_PI*2.) mPC[k] -= M_PI*2.;
+  }
+return;  
+}
+
+/* --Methode-- */
+//++
+double MainLobe::Value(int kpx, float& teta, float& phi)
+//
+//    return the value of the lobe as also the (theta, phi) of the
+//    pixel "kpx"  
+//--
+{
+if ( (kpx < 0) || (kpx >= mNpix) ) { teta = phi = 0.; return(0.); }
+teta = mTC[kpx];
+phi = mPC[kpx];
+return(mVal[kpx]);
+}
+
+/* --Methode-- */
+//++
+double MainLobe::Convol(SphericalMap<double>& sph)
+//
+//    return the value of the lobe convolved with the sky (sphere) "sph"
+//--
+{
+double ret=0.;
+int k;
+for(k=0; k<mNpix; k++)  ret += mVal[k]*sph(mTC[k], mPC[k]);
+/*
+if( (dbg > 0) && (k%dbg) ) 
+  printf("MainLobe::Convol k= %d T,P= %g %g , Lobe=%g Sph= %g  Ret=%g\n", 
+         k, mTC[k], mPC[k], mVal[k], sph(mTC[k], mPC[k]), ret );
+*/
+return(ret/mTotVal);
+}
+
+//++
+//
+// inline void     Print()  
+//--
+
+//++
+// Titre	Operators
+//--
+
+/* --Methode-- */
+//++
+ostream& operator << (ostream& s, MainLobe const& lob)
+//
+//--
+{
+s << "MainLobe_Info() : Sigma= " << lob.mSigma << " Dels= " << lob.mDels << " NC= " 
+  << lob.mNC << " NTotPix= " << lob.mNpix << " Integ= " << lob.mTotVal << endl;
+
+int i,j,k;
+cout << " Direction Teta,Phi = " << lob.mDirTet << " , " << lob.mDirPhi << endl;      
+cout << " Pixel 0 , Teta= " << lob.mT0[0] << " Phi= " << lob.mP0[0] 
+     << " Val= " << lob.mVal[0] << endl;
+k = 1;
+for(i=1; i<lob.mNC; i++) {
+  cout << " Couche # " << i << " NPix= " << i*6 << endl;
+  for(j=0;j<6*i;j++) {
+    cout << "K= " << k << "Teta,Phi= "  << lob.mTC[k] << ", " << lob.mPC[k] 
+         << " (" << lob.mT0[k] << ", " << lob.mP0[k] << ") "
+         << " Val= " << lob.mVal[k] << endl; 
+    k++;
+    }
+  }
+
+
+return s;
+}
+
Index: /tags/V_Dec2002/SophyaLib/Samba/mlobe.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/Samba/mlobe.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Samba/mlobe.h	(revision 2309)
@@ -0,0 +1,56 @@
+// Class for representing the main antenna lobe
+//        R. Ansari            1998-2000
+// DAPNIA/SPP (Saclay) / CEA    LAL - IN2P3/CNRS  (Orsay)
+
+#ifndef MLOBE_H_SEEN
+#define MLOBE_H_SEEN
+
+#include <math.h>
+#include <iostream.h>
+
+#include "sphericalmap.h"
+
+
+namespace SOPHYA {  
+
+// Classe MainLobe
+// Classe pour calcul du lobe principal
+// Les valeurs du lobe sont calcules dans des pixels
+// disposes sur "nc" couches avec pavage hexagonal autour de Teta=0, Phi=0
+// Le lobe est gaussien, de sigma = "sig" - Les couches sont construites 
+// toutes les "dels" * sigma 
+// NPix() renvoie le nombre total de pixels du lobe 
+// SetDirection() permet d orienter le lobe dans la direction "teta, phi"
+// Value() renvoie la valeur du lobe, ainsi que les teta,phi du pixel "kpx"
+// Convol() renvoie la valeur lobe convolue avec le ciel (sphere) "sph"
+
+class MainLobe {
+public:
+			MainLobe(float sig, float dels=0.5, int nc=3);
+			~MainLobe();
+        inline int      NPix() {return mNpix; }            
+        inline float    Sigma() {return mSigma; }            
+        inline double   Integral() {return mTotVal; }            
+               void     SetDirection(float teta, float phi);
+	       double   Value(int kpx, float& teta, float& phi);
+               double   Convol(SphericalMap<double>& sph);
+        friend ostream& operator << (ostream& s, MainLobe const& lob);
+	inline void     Print() { cout << (*this); } 
+
+float mSigma, mDels;
+int mNpix, mNC;
+double mTotVal;
+float mDirTet, mDirPhi;
+float* mT0; 
+float* mP0; 
+float* mTC; 
+float* mPC; 
+float* mDx;
+float* mDy;
+float* mDr;
+double* mVal;
+};
+
+} // namespace SOPHYA
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/Samba/objlist.list
===================================================================
--- /tags/V_Dec2002/SophyaLib/Samba/objlist.list	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Samba/objlist.list	(revision 2309)
@@ -0,0 +1,9 @@
+alm.o
+bruit.o
+circle.o
+datacirclefake.o
+lambdaBuilder.o
+mlobe.o
+sambainit.o
+scan.o
+sphericaltransformserver.o
Index: /tags/V_Dec2002/SophyaLib/Samba/prefcount.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/Samba/prefcount.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Samba/prefcount.h	(revision 2309)
@@ -0,0 +1,65 @@
+#ifndef PREFCOUNT_H
+#define PREFCOUNT_H
+
+// Classe d'objet avec comptage de référence.
+// Le nombre de référence est incrémenté lors de la création et lors d'un Attach
+// (inutile d'appeler Attach si on crée l'objet).
+// Si on cree l'objet avec isTmp = true, alors le possesseur est temporaire,
+// et en tout cas, possede le PRefCount en lecture seule.
+// Par exemple, une fonction qui retourne un objet de type PRefCounted le créera
+// en mode temporaire. Un constructeur par copie appelé derrière ne dupliquera pas
+// les données.
+// HasTmpOnly retourne true si un objet n'est référencé que de façon temporaire.
+
+#ifdef TRACE_REFCOUNT
+#define DBG_DESTROY cerr << "PRefCounted destroyed" << endl;
+#define DBG_ATTACH  cerr << "PRefCounted attached" << endl;
+#define DBG_DETACH  cerr << "PRefCounted detached" << endl;
+#else
+#define DBG_DESTROY 
+#define DBG_ATTACH
+#define DBG_DETACH
+#endif
+
+
+class PRefCounted {
+public:
+                               PRefCounted(bool isTmp=false) 
+                                                        :refcount(1), tmpcount(isTmp?1:0) {}
+  virtual                      ~PRefCounted()           {DBG_DESTROY}
+  
+  void                         Attach(bool isTemp=false) 
+                                                        {if (isTemp && HasTmpOnly()) tmpcount++;
+                                                         DBG_ATTACH
+                                                         refcount++;}
+  void                         Detach()                 {refcount--;
+                                                         DBG_DETACH
+                                                         if (!refcount) delete this;}
+  
+  int                          RefCount() const         {return refcount;}
+  bool                         HasTmpOnly() const       {return tmpcount == refcount;}
+  
+private:
+  int refcount;
+  int tmpcount;
+};
+
+// Macro pour les constructeurs par copie d'objets référençant des PRefCounted
+// Il faut que le PRefCounted ait une méthode T* Clone(bool isTmp);
+
+template <class refcount>
+void PRefCountCopy(refcount*& dest, refcount const* src, bool isTmp=false) {
+  if (dest) dest->Detach();
+  if (!src) {
+    dest=0;
+  } else if (src->HasTmpOnly()) {
+    dest = const_cast<refcount*>(src);
+    dest->Attach(isTmp);
+  } else {
+    dest = src->Clone(isTmp);
+  }
+}
+
+
+#endif
+
Index: /tags/V_Dec2002/SophyaLib/Samba/samba.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/Samba/samba.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Samba/samba.h	(revision 2309)
@@ -0,0 +1,19 @@
+// This may look like C code, but it is really -*- C++ -*-
+// All include files for module Samba
+
+#ifndef SAMBA_H_SEEN
+#define SAMBA_H_SEEN
+
+#include "alm.h"
+#include "bruit.h"
+#include "circle.h"
+#include "geometry.h"
+#include "lambdaBuilder.h"
+#include "misstime.h"
+#include "mlobe.h"
+#include "prefcount.h"
+#include "scan.h"
+#include "sphericaltransformserver.h"
+#include "tod.h"
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/Samba/sambainit.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/Samba/sambainit.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Samba/sambainit.cc	(revision 2309)
@@ -0,0 +1,37 @@
+// Classe d'initialisation du module Samba 
+
+#include "sambainit.h"
+
+/*!
+   \defgroup Samba Samba module
+   This module contains various classes for CMB analysis, such as
+   spherical harmonic decomposition and synthesis
+*/
+
+/*!
+  \class SOPHYA::SambaInitiator
+  \ingroup Samba
+  Array Matrices and Vector initiator
+*/
+
+int SambaInitiator::FgInit = 0;
+
+SambaInitiator::SambaInitiator()
+  : SkyMapInitiator()
+{
+  SambaInitiator::FgInit++;
+  if (SambaInitiator::FgInit > 1)  return;
+  ntinit = new NToolsInitiator;
+}
+
+SambaInitiator::~SambaInitiator()
+{
+  SambaInitiator::FgInit--;
+  if (FgInit < 1)  delete ntinit;
+}
+
+
+// On met un objet initiator en statique, pour les loaders qui savent 
+// appeler le constructeur des objets statiques   Reza 08/98
+static SambaInitiator s_sambainit_;
+
Index: /tags/V_Dec2002/SophyaLib/Samba/sambainit.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/Samba/sambainit.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Samba/sambainit.h	(revision 2309)
@@ -0,0 +1,29 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe d'initialiseur du module Outils++
+
+#ifndef SAMBAINIT_H_SEEN
+#define SAMBAINIT_H_SEEN
+
+
+// Classe d''initialisation pour les modules de PEIDA++
+#include "skymapinit.h"
+#include "ntoolsinit.h"
+
+namespace SOPHYA {  
+
+class SambaInitiator : public SkyMapInitiator {
+private:
+  static int FgInit;
+  NToolsInitiator * ntinit; 
+public:
+  			SambaInitiator();
+  virtual		~SambaInitiator();
+};
+
+#undef SophyaInit
+#define SophyaInit() SambaInitiator sambainitiator
+
+} // namespace SOPHYA
+
+#endif
+
Index: /tags/V_Dec2002/SophyaLib/Samba/scan.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/Samba/scan.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Samba/scan.cc	(revision 2309)
@@ -0,0 +1,443 @@
+#include "machdefs.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+#include "scan.h"
+#include <complex>
+#include "piocmplx.h"
+#include "fiondblock.h"
+
+// valeurs de Pi, 2*Pi, etc                                              
+#include "smathconst.h"
+
+
+//
+//++
+// Class	Scan
+//
+// include      scan.h  dvlist.h math.h nbmath.h 
+//
+//    Storage and treatment of data for a scanning of a part of the sky
+//    with a set of given values for parameters (see constructor)
+//--
+//++
+Scan::Scan(float Ouv,float* Omega,float Fech,float T, 
+	   float t0=0., float phi0=0.)
+
+//  
+//    * Ouv      = aperture angle (rad)
+//    * Omega[3] = direction of rotation axis of the satellite (teta,phi)
+//    and rotation velocity (rad/s)
+//    * Fech     = sampling frequency  (Hz)
+//    * T        = total time of data acquistion (s)
+//    * t0       = starting time (s)
+//    * phi0     = offset of antenna (rad)
+//--
+{
+  mInfo_=NULL;
+  // On memorise les arguments d'appel
+  Ouverture_= Ouv;
+  OmegaTeta_= Omega[0];
+  //
+  // je ne comprends pas ce qui se passe ci-apres (GLM)
+  if( (Omega[0]== 0.0) || (Omega[0]==(float)Pi) ) 
+    OmegaPhi_ = Omega[1];
+  else
+    OmegaPhi_ = Omega[1]+(float)Pi/2.;
+  OmegaRad_ = Omega[2];
+  FrequenceEch_  = Fech;
+  TempsFinal_    = T;
+  TempsInitial_  = t0;
+  PhiZero_ = phi0;
+
+  float aux= 0.0;
+  // Nombre total de points
+  aux= (TempsFinal_-TempsInitial_)*FrequenceEch_;
+  NmaxPts_= (int_4)(aux);
+
+  // Nombre total de tours
+  aux= OmegaRad_*(TempsFinal_-TempsInitial_)/(2.*Pi);
+  NmaxTrs_= (int_4)(aux);
+
+  // Nombre de points par tour
+  aux= 2.*Pi*FrequenceEch_/OmegaRad_;
+  NPts1Tr_= (int_4)(aux);
+
+  // Creation et initialisation du vecteur des mesures aux points
+  //  sPix_ = new r_8[NmaxPts_];
+  sPix_.ReSize(NmaxPts_);
+  sPix_.Reset();
+  //  for( int_4 i=0; i<NmaxPts_; i++ )  sPix_[i]= 0.;
+    for( int_4 i=0; i<NmaxPts_; i++ )  sPix_(i)= 0.;
+
+  // matrice de passage du systeme lie au satellite au systeme fixe
+
+  Rota_[0]=  cos((double)OmegaPhi_);
+  Rota_[1]= -sin((double)OmegaPhi_)*cos((double)OmegaTeta_);
+  Rota_[2]=  sin((double)OmegaPhi_)*sin((double)OmegaTeta_);
+  Rota_[3]=  sin((double)OmegaPhi_);
+  Rota_[4]=  cos((double)OmegaPhi_)*cos((double)OmegaTeta_);
+  Rota_[5]= -cos((double)OmegaPhi_)*sin((double)OmegaTeta_);
+  Rota_[6]=  0.0;
+  Rota_[7]=  sin((double)OmegaTeta_);
+  Rota_[8]=  cos((double)OmegaTeta_);
+
+
+  // printf("%f  %f  %f \n",Rota_[0],Rota_[1],Rota_[2]);
+  // printf("%f  %f  %f \n",Rota_[3],Rota_[4],Rota_[5]);
+  // printf("%f  %f  %f \n",Rota_[6],Rota_[7],Rota_[8]);
+
+}
+
+
+//++
+Scan::Scan(const Scan& s,  bool share) :  sPix_(s.sPix_ , share)
+
+//    copy  constructor
+//--
+{
+  NmaxPts_      = s.NmaxPts_;
+  Ouverture_    = s.Ouverture_;
+  OmegaTeta_    = s.OmegaTeta_;
+  OmegaPhi_     = s.OmegaPhi_;
+  OmegaRad_     = s.OmegaRad_;
+  FrequenceEch_ = s.FrequenceEch_;
+  TempsFinal_   = s.TempsFinal_;
+  TempsInitial_ = s.TempsInitial_;
+  PhiZero_      = s.PhiZero_;
+  for (int k=0; k<9; k++) Rota_[k]=s. Rota_[k];
+}
+//++
+// Titre	Destructor
+//--
+//++
+Scan::~Scan()
+
+//     
+//--
+{
+  // delete[] sPix_ ;
+}
+
+
+//++
+// Titre	Public Methods
+//--
+
+//++
+int_4 Scan::NbPoints() const
+
+//    Return the number of points in the scan
+//--
+{
+  return(NmaxPts_);
+}
+
+/* --Methode-- */
+//++
+int_4 Scan::NbTours() const
+
+//    Return total nomber of turns
+//--
+{
+  return(NmaxTrs_);
+}
+
+/* --Methode-- */
+//++
+int_4 Scan::NbPts1Tr() const
+
+//    Return  nomber of points for 1 turn
+//--
+{
+  return(NPts1Tr_);
+}
+
+/* --Methode-- */
+//++
+int_4 Scan::ValueIndex(float t) const
+
+//    Return index of pixel associated to time t
+//--
+{
+  int_4 k;
+  float eps= 1.0E-06;
+
+  // verification si t est dans [TempsInitial_,TempsFinal_]
+  if( (t< TempsInitial_) || (t> TempsFinal_) ) {
+    printf("\n ValueIndex:: probleme sur le temps t= %f",t);
+    return(-1);
+  }
+
+  k= (int_4)((t-TempsInitial_)*FrequenceEch_+eps);
+  if ( (k< 0) || (k >= NmaxPts_) ) {
+    printf("\n ValueIndex:: probleme sur l'indice du point k= %d",k); 
+    return(-1);
+  }
+  return(k);
+}
+
+/* --Methode-- */
+//++
+void Scan::Direction(float t, float&  teta , float&  phi)
+
+//    Return  (teta,phi) coordinate of pixel related to time t
+//--
+{
+  r_8 alfa,xs,ys,zs,x,y,z;
+
+  // coordonnees dans le systeme du satellite
+  alfa= OmegaRad_*(t-TempsInitial_)+PhiZero_;
+  xs = sin((double)Ouverture_)*cos(alfa);
+  ys = sin((double)Ouverture_)*sin(alfa);
+  zs = cos((double)Ouverture_);
+
+  // coordonnees dans le systeme fixe
+  x = Rota_[0]*xs+Rota_[1]*ys+Rota_[2]*zs;
+  y = Rota_[3]*xs+Rota_[4]*ys+Rota_[5]*zs;
+  z = Rota_[6]*xs+Rota_[7]*ys+Rota_[8]*zs;
+
+  // angles teta,phi
+  teta = acos(z);
+  phi  = atan2(y,x);
+  if( phi< 0. ) phi= DeuxPi+phi;
+}
+
+/* --Methode-- */
+//++
+void Scan::DirectionIndex(int_4 k, float&  teta, float&  phi)
+
+//    Return  (teta,phi) coordinates of  pixel with index k
+//--
+{
+  float t;
+
+  //recupere le temps associe a l'indice k du pixel
+  t= TempsInitial_+(float)k/FrequenceEch_;
+
+  // angles teta,phi 
+  Direction(t, teta, phi);
+}
+
+static r_8 dummy_pixel = 0;
+/* --Methode-- */
+//++
+r_8 const& Scan::PixelValue(int_4 k) const
+
+//    Retourne la valeur du contenu du pixel d'indice k
+//--
+{
+  if ( (k<0) || (k >=  NmaxPts_) ) {
+    printf("\n ValueIndex::indice du pixel errone k= %d",k); 
+    return(dummy_pixel);
+  }
+  //  return(sPix_[k]);
+  //return(sPix_(k));
+  return *(sPix_.Data()+k);
+}
+//++
+r_8 & Scan::PixelValue(int_4 k) 
+
+//    Retourne la valeur du contenu du pixel d'indice k
+//--
+{
+  if ( (k<0) || (k >=  NmaxPts_) ) {
+    printf("\n ValueIndex::indice du pixel errone k= %d",k); 
+    return(dummy_pixel);
+  }
+  //  return(sPix_[k]);
+  //return(sPix_(k));
+  return *(sPix_.Data()+k);
+}
+
+//void Scan::Clear() {
+//  if (sPix_)  delete[] sPix_;
+//}         
+void Scan::InitNull() {
+  //  sPix_=NULL;
+  //  sPix_.Reset(); pas de reset (pour le cas de share)
+  mInfo_=NULL;
+}         
+Scan&  Scan::operator = (const Scan& s)
+{
+  NmaxPts_      = s.NmaxPts_;
+  Ouverture_    = s.Ouverture_;
+  OmegaTeta_    = s.OmegaTeta_;
+  OmegaPhi_     = s.OmegaPhi_;
+  OmegaRad_     = s.OmegaRad_;
+  FrequenceEch_ = s.FrequenceEch_;
+  TempsFinal_   = s.TempsFinal_;
+  TempsInitial_ = s.TempsInitial_;
+  PhiZero_      = s.PhiZero_;
+  sPix_=s.sPix_;
+  for (int k=0; k<9; k++) Rota_[k]=s. Rota_[k];
+  return *this;
+}
+
+
+//++
+// Titre	Operators
+//--
+//++
+// Links	double&        operator()(int_4 k)
+//--
+//++
+//    fill and/or return value of the pixel with index k
+//--
+
+
+
+
+
+//++
+// Titre	class FIO_Scan
+//    Delegated objects for persitance management
+//--
+
+//*******************************************************************
+// class FIO_Scan
+//  Les objets delegues pour la gestion de persistance 
+//*******************************************************************
+
+//++
+FIO_Scan::FIO_Scan()
+//
+//--
+{
+  dobj= new Scan;
+  ownobj= true;
+}
+//++
+FIO_Scan::FIO_Scan(string const& filename)
+//
+//--
+{
+  dobj= new Scan;
+  ownobj= true;
+  Read(filename);
+}
+//++
+FIO_Scan::FIO_Scan(const Scan& obj)
+//
+//--
+{
+  dobj= new Scan(obj);
+  ownobj= true;
+}
+FIO_Scan::FIO_Scan(Scan* obj)
+{
+  dobj= obj;
+  ownobj= false;
+}
+//++
+FIO_Scan::~FIO_Scan()
+//
+//--
+{
+  if (ownobj && dobj) delete dobj;
+}
+//++
+AnyDataObj* FIO_Scan::DataObj()
+//
+//--
+{
+  return(dobj);
+}
+
+//++
+void FIO_Scan::ReadSelf(PInPersist& is)
+//
+//--
+{
+
+  int_4 NmaxPts, NmaxTrs, NPts1Tr;
+  r_4 Ouverture, OmegaTeta, OmegaPhi, OmegaRad, FrequenceEch; 
+  r_4 TempsFinal,  TempsInitial, PhiZero; 
+  r_8 Rota[9];
+
+  if(dobj == NULL) 
+    {
+      dobj= new Scan;
+    }
+
+  // Pour savoir s'il y avait un DVList Info associe
+  char strg[256];
+  is.GetLine(strg, 255);
+  bool hadinfo= false;
+  if (strncmp(strg+strlen(strg)-7, "HasInfo", 7) == 0)  hadinfo = true;
+  if(hadinfo) 
+    {    // Lecture eventuelle du DVList Info
+      is >> dobj->Info(); 
+    }
+
+
+  is.GetI4(NmaxPts);
+  is.GetI4(NmaxTrs);
+  is.GetI4(NPts1Tr);
+  dobj->SetIntParams(NmaxPts,NmaxTrs,NPts1Tr);
+
+  is.GetR4(Ouverture);
+  is.GetR4(OmegaTeta);
+  is.GetR4(OmegaPhi);
+  is.GetR4(OmegaRad);
+  is.GetR4(FrequenceEch);
+  is.GetR4(TempsFinal);
+  is.GetR4(TempsInitial);
+  is.GetR4(PhiZero);
+  is.GetR8s(Rota, 9);
+  dobj->SetFloatParams(Ouverture,OmegaTeta,OmegaPhi,OmegaRad,
+		       FrequenceEch,TempsFinal,TempsInitial,PhiZero,Rota);
+// On lit le DataBlock;
+  FIO_NDataBlock<r_8> fio_nd(&dobj->DataBlock());
+  fio_nd.Read(is);
+}
+//++
+void FIO_Scan::WriteSelf(POutPersist& os) const
+//
+//--
+{
+  r_4 Ouverture, OmegaTeta, OmegaPhi, OmegaRad, FrequenceEch; 
+  r_4 TempsFinal,  TempsInitial, PhiZero; 
+  r_8 Rota[9];
+  char strg[256];
+
+  if(dobj == NULL) 
+    {
+      cout << " FIO_Scan::WriteSelf:: dobj= null " << endl;
+      return;
+    }
+  dobj->GetFloatParams(Ouverture,OmegaTeta,OmegaPhi,OmegaRad,
+		       FrequenceEch,TempsFinal,TempsInitial,PhiZero,Rota);
+  if (dobj->ptrInfo()) 
+    {sprintf(strg, "Scan: Theta=%9f Phi=%9f omega=%9f HasInfo", 
+	     (float)OmegaTeta, (float)OmegaPhi, (float)OmegaRad);
+    os.PutLine(strg);
+    os << dobj->Info();
+    }
+  else 
+    {
+      sprintf(strg, "Scan: Theta=%9f Phi=%9f omega=%9f ", 
+	      (float)OmegaTeta, (float)OmegaPhi, (float)OmegaRad); 
+      os.PutLine(strg);
+    }
+
+  os.PutI4(dobj->NbPoints());
+  os.PutI4(dobj->NbTours());
+  os.PutI4(dobj->NbPts1Tr());
+
+  os.PutR4(Ouverture);
+  os.PutR4(OmegaTeta);
+  os.PutR4(OmegaPhi);
+  os.PutR4(OmegaRad);
+  os.PutR4(FrequenceEch);
+  os.PutR4(TempsFinal);
+  os.PutR4(TempsInitial);
+  os.PutR4(PhiZero);
+  os.PutR8s(Rota, 9);
+
+// On ecrit le dataBlock 
+  FIO_NDataBlock<r_8> fio_nd(&dobj->DataBlock());
+  fio_nd.Write(os);
+
+}
Index: /tags/V_Dec2002/SophyaLib/Samba/scan.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/Samba/scan.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Samba/scan.h	(revision 2309)
@@ -0,0 +1,197 @@
+//   Class for managing sky scanning
+//        R. Ansari , G. Le Meur   1998-2000
+// DAPNIA/SPP (Saclay) / CEA    LAL - IN2P3/CNRS  (Orsay)
+
+#ifndef SCAN_H_SEEN
+#define SCAN_H_SEEN
+
+
+#include "ppersist.h"
+#include <iostream.h>
+#include "dvlist.h"
+#include "ndatablock.h"
+
+namespace SOPHYA {  
+
+class FIO_Scan;
+
+//!   Storage and treatment of data for a scanning of a part of the sky with a set of given values for parameters (see constructor)
+
+class Scan :  public AnyDataObj  {
+    friend class FIO_Scan;
+  public  :
+    /* 
+arguments du constructeur : 
+  . ouverture (radians), 
+  . un tableau de 3 reels (deux angles-en radians- definissant la direction de 
+                      l'axe de rotation du satellite + vitesse de rotation 
+                      en radians/s),
+  . frequence d'echantillonnage (Hz), 
+  . instant final de prise de donnees (s),
+deux arguments optionnels :
+  . instant initial pour la prise de donnees
+  . offset d'antenne en angle phi
+  */
+
+    /*!
+\verbatim
+    * Ouv      = aperture angle (rad)
+    * Omega[3] = direction of rotation axis of the satellite (teta,phi)
+                 and rotation velocity (rad/s)
+    * Fech     = sampling frequency  (Hz)
+    * T        = total time of data acquistion (s)
+    * t0       = starting time (s)
+    * phi0     = offset of antenna (rad)
+\endverbatim
+    */
+Scan(float,float*,float,float,float,float);
+Scan(const Scan&,  bool share=false );
+Scan() { 
+  InitNull();
+}
+~Scan();
+
+// ------------ Persistence handling
+
+//     enum {classId = 0xF003 };
+//int_4                  ClassId() const        { return classId; }
+
+//virtual void           WriteSelf(POutPersist&) const;
+//virtual void           ReadSelf(PInPersist&);
+
+/*!   Return the number of points in the scan */
+int_4     NbPoints() const;
+/*!    Return total nomber of turns */
+int_4     NbTours() const;
+/*!    Return  nomber of points for 1 turn */
+int_4     NbPts1Tr() const; 
+/*!    Return index of pixel associated to time t */
+int_4     ValueIndex(float) const;
+/*!    Return  (teta,phi) coordinate of pixel related to time t */
+void    Direction(float, float& ,float& );
+/*!    Return  (teta,phi) coordinates of  pixel with index k */
+void    DirectionIndex(int_4,float& ,float& );
+/*!    Return value of pixel with index k */
+r_8  & PixelValue(int_4 k) ;
+/*!    const version of previous method */
+r_8 const & PixelValue(int_4 k) const;
+
+/* Surcharge de la parenthese a un indice entier : remplit ou/et renvoie */
+/* la valeur du contenu du pixel d'indice k                              */ 
+  
+  inline  r_8&    operator()(int_4 k)
+                                      { return(PixelValue(k)) ; } ;
+  inline  r_8 const &    operator()(int_4 k) const
+                                      { return(PixelValue(k)) ; } ;
+  Scan& operator = (const Scan& s);
+//++
+DVList&  Info()
+//
+//      Renvoie une reference sur l'objet DVList Associe
+//--
+{  
+if (mInfo_ == NULL)  mInfo_ = new DVList;
+return(*mInfo_);
+}
+
+const DVList*  ptrInfo() const
+  {
+    return mInfo_;
+  }
+
+
+
+
+
+  private :
+    
+    //void          Clear();
+void          InitNull();
+
+/*  Acces to the DataBlock  */
+inline       NDataBlock<r_8>& DataBlock()       {return sPix_;}
+inline const NDataBlock<r_8>& DataBlock() const {return sPix_;}
+
+inline  void  SetIntParams(int_4 NmaxPts, int_4 NmaxTrs, int_4 NPts1Tr)
+  {
+    NmaxPts_=NmaxPts;
+    NmaxTrs_=NmaxTrs;
+    NPts1Tr_=NPts1Tr;
+  }
+ inline void SetFloatParams(r_4 Ouverture, r_4 OmegaTeta, r_4 OmegaPhi, 
+			    r_4 OmegaRad, r_4 FrequenceEch, r_4 TempsFinal, 
+			    r_4 TempsInitial, r_4 PhiZero, r_8* Rota)
+   {
+     Ouverture_    = Ouverture;
+     OmegaTeta_    = OmegaTeta;
+     OmegaPhi_     = OmegaPhi;
+     OmegaRad_     = OmegaRad;
+     FrequenceEch_ = FrequenceEch;
+     TempsFinal_   = TempsFinal;
+     TempsInitial_ = TempsInitial;
+     PhiZero_      = PhiZero;
+     for (int k=0; k<9;k++) Rota_[k]=Rota[k];
+   }
+
+ inline void GetFloatParams(r_4& Ouverture, r_4& OmegaTeta, r_4& OmegaPhi, 
+			    r_4& OmegaRad, r_4& FrequenceEch, r_4& TempsFinal, 
+			    r_4& TempsInitial, r_4& PhiZero, r_8* Rota) const
+   {
+     Ouverture    = Ouverture_;
+     OmegaTeta    = OmegaTeta_;
+     OmegaPhi     = OmegaPhi_;
+     OmegaRad     = OmegaRad_;
+     FrequenceEch = FrequenceEch_;
+     TempsFinal   = TempsFinal_;
+     TempsInitial = TempsInitial_;
+     PhiZero      = PhiZero_;
+     for (int k=0; k<9;k++) Rota[k]=Rota_[k];
+   }
+
+
+ int_4 NmaxPts_;
+ int_4 NmaxTrs_;
+ int_4 NPts1Tr_;
+ r_4   Ouverture_;
+ r_4   OmegaTeta_;     /* direction de l'axe de rotation du satellite */
+ r_4   OmegaPhi_;      /* (radians)                                   */
+ r_4   OmegaRad_;      /* vitesse de rotation du satellite (radians/s) */
+ r_4   FrequenceEch_;  /* frequence d'echantillonnage (Hz)*/
+ r_4   TempsFinal_;
+ r_4   TempsInitial_;
+ r_4   PhiZero_;           /* Offset antenne (radians)  */
+ NDataBlock<r_8>  sPix_;   /* valeurs contenues dans chaque pixel */ 
+ //r_8*  sPix_;            /* valeurs contenues dans chaque pixel */ 
+ r_8   Rota_[9];       /* matrice de passage : [Xf]=[Rota][Xs] */
+                      /* Xs : coordonnees dans un systeme lie au satellite*/ 
+                      /* Xf : coordonnees dans un repere "fixe"           */ 
+ DVList* mInfo_;        // Infos (variables) attachees 
+};
+
+// ------------- Classe pour la gestion de persistance --
+//!    Delegated objects for persitance management
+
+class FIO_Scan : public PPersist  
+{
+
+public:
+
+FIO_Scan(); 
+FIO_Scan(string const & filename); 
+FIO_Scan(const Scan& obj);
+FIO_Scan(Scan* obj);
+virtual ~FIO_Scan();
+virtual AnyDataObj* DataObj();
+inline operator Scan() {return(*dobj); }
+
+protected :
+
+virtual void ReadSelf(PInPersist&);           
+virtual void WriteSelf(POutPersist&) const;  
+Scan* dobj;
+bool ownobj;
+};
+
+} // namespace SOPHYA
+
+#endif /* SCAN_H_SEEN */
Index: /tags/V_Dec2002/SophyaLib/Samba/sphericaltransformserver.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/Samba/sphericaltransformserver.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Samba/sphericaltransformserver.cc	(revision 2309)
@@ -0,0 +1,1347 @@
+#include "machdefs.h"
+#include <iostream.h>
+#include <math.h>
+#include <complex>
+#include "sphericaltransformserver.h"
+#include "tvector.h"
+#include "nbrandom.h"
+#include "nbmath.h"
+#include "timing.h"
+//#include "spherehealpix.h"
+
+
+/*! \class SOPHYA::SphericalTransformServer
+
+ Class for performing analysis and synthesis of sky maps using spin-0 or spin-2 spherical harmonics.
+
+Maps must be SOPHYA SphericalMaps (SphereGorski or SphereThetaPhi).
+
+Temperature and polarization (Stokes parameters) can be developped on spherical harmonics : 
+\f[
+\frac{\Delta T}{T}(\hat{n})=\sum_{lm}a_{lm}^TY_l^m(\hat{n})
+\f]
+\f[
+Q(\hat{n})=\frac{1}{\sqrt{2}}\sum_{lm}N_l\left(a_{lm}^EW_{lm}(\hat{n})+a_{lm}^BX_{lm}(\hat{n})\right)
+\f]
+\f[
+U(\hat{n})=-\frac{1}{\sqrt{2}}\sum_{lm}N_l\left(a_{lm}^EX_{lm}(\hat{n})-a_{lm}^BW_{lm}(\hat{n})\right)
+\f]
+\f[
+\left(Q \pm iU\right)(\hat{n})=\sum_{lm}a_{\pm 2lm}\, _{\pm 2}Y_l^m(\hat{n})
+\f]
+
+\f[
+Y_l^m(\hat{n})=\lambda_l^m(\theta)e^{im\phi}
+\f]
+\f[
+_{\pm}Y_l^m(\hat{n})=_{\pm}\lambda_l^m(\theta)e^{im\phi}
+\f]
+\f[
+W_{lm}(\hat{n})=\frac{1}{N_l}\,_{w}\lambda_l^m(\theta)e^{im\phi}
+\f]
+\f[
+X_{lm}(\hat{n})=\frac{-i}{N_l}\,_{x}\lambda_l^m(\theta)e^{im\phi}
+\f]
+
+(see LambdaLMBuilder, LambdaPMBuilder, LambdaWXBuilder classes)
+
+power spectra : 
+
+\f[
+C_l^T=\frac{1}{2l+1}\sum_{m=0}^{+ \infty }\left|a_{lm}^T\right|^2=\langle\left|a_{lm}^T\right|^2\rangle 
+\f]
+\f[
+C_l^E=\frac{1}{2l+1}\sum_{m=0}^{+\infty}\left|a_{lm}^E\right|^2=\langle\left|a_{lm}^E\right|^2\rangle 
+\f]
+\f[
+C_l^B=\frac{1}{2l+1}\sum_{m=0}^{+\infty}\left|a_{lm}^B\right|^2=\langle\left|a_{lm}^B\right|^2\rangle 
+\f]
+
+\arg
+\b Synthesis : Get temperature and polarization maps  from \f$a_{lm}\f$ coefficients or from power spectra, (methods GenerateFrom...).
+
+\b Temperature:
+\f[
+\frac{\Delta T}{T}(\hat{n})=\sum_{lm}a_{lm}^TY_l^m(\hat{n}) = \sum_{-\infty}^{+\infty}b_m(\theta)e^{im\phi}
+\f]
+
+with 
+\f[
+b_m(\theta)=\sum_{l=\left|m\right|}^{+\infty}a_{lm}^T\lambda_l^m(\theta)
+\f]
+
+\b Polarisation
+\f[
+Q \pm iU = \sum_{-\infty}^{+\infty}b_m^{\pm}(\theta)e^{im\phi}
+\f]
+
+where :
+\f[
+b_m^{\pm}(\theta) = \sum_{l=\left|m\right|}^{+\infty}a_{\pm 2lm}\,_{\pm}\lambda_l^m(\theta)
+\f]
+
+or :
+\f[
+Q  = \sum_{-\infty}^{+\infty}b_m^{Q}(\theta)e^{im\phi}
+\f]
+\f[
+U  = \sum_{-\infty}^{+\infty}b_m^{U}(\theta)e^{im\phi}
+\f]
+
+where: 
+\f[
+b_m^{Q}(\theta) = \frac{1}{\sqrt{2}}\sum_{l=\left|m\right|}^{+\infty}\left(a_{lm}^E\,_{w}\lambda_l^m(\theta)-ia_{lm}^B\,_{x}\lambda_l^m(\theta)\right)
+\f]
+\f[
+b_m^{U}(\theta) = \frac{1}{\sqrt{2}}\sum_{l=\left|m\right|}^{+\infty}\left(ia_{lm}^E\,_{x}\lambda_l^m(\theta)+a_{lm}^B\,_{w}\lambda_l^m(\theta)\right)
+\f]
+
+Since the pixelization provides "slices" with constant \f$\theta\f$ and \f$\phi\f$ equally distributed  on \f$2\pi\f$  \f$\frac{\Delta T}{T}\f$, \f$Q\f$,\f$U\f$  can be computed by FFT.
+
+
+\arg
+\b Analysis :  Get \f$a_{lm}\f$ coefficients or  power spectra from temperature and polarization maps   (methods DecomposeTo...). 
+
+\b Temperature:
+\f[
+a_{lm}^T=\int\frac{\Delta T}{T}(\hat{n})Y_l^{m*}(\hat{n})d\hat{n}
+\f]
+
+approximated as : 
+\f[
+a_{lm}^T=\sum_{\theta_k}\omega_kC_m(\theta_k)\lambda_l^m(\theta_k)
+\f]
+where :
+\f[
+C_m (\theta _k)=\sum_{\phi _{k\prime}}\frac{\Delta T}{T}(\theta _k,\phi_{k\prime})e^{-im\phi _{k\prime}}
+\f]
+Since the pixelization provides "slices" with constant \f$\theta\f$ and \f$\phi\f$ equally distributed  on \f$2\pi\f$ (\f$\omega_k\f$ is the solid angle of each pixel of the slice \f$\theta_k\f$) \f$C_m\f$ can be computed by FFT.
+
+\b polarisation:
+
+\f[
+a_{\pm 2lm}=\sum_{\theta_k}\omega_kC_m^{\pm}(\theta_k)\,_{\pm}\lambda_l^m(\theta_k)
+\f]
+where :
+\f[
+C_m^{\pm} (\theta _k)=\sum_{\phi _{k\prime}}\left(Q \pm iU\right)(\theta _k,\phi_{k\prime})e^{-im\phi _{k\prime}}
+\f]
+or :
+
+\f[
+a_{lm}^E=\frac{1}{\sqrt{2}}\sum_{\theta_k}\omega_k\left(C_m^{Q}(\theta_k)\,_{w}\lambda_l^m(\theta_k)-iC_m^{U}(\theta_k)\,_{x}\lambda_l^m(\theta_k)\right)
+\f]
+\f[
+a_{lm}^B=\frac{1}{\sqrt{2}}\sum_{\theta_k}\omega_k\left(iC_m^{Q}(\theta_k)\,_{x}\lambda_l^m(\theta_k)+C_m^{U}(\theta_k)\,_{w}\lambda_l^m(\theta_k)\right)
+\f]
+
+where : 
+\f[
+C_m^{Q} (\theta _k)=\sum_{\phi _{k\prime}}Q(\theta _k,\phi_{k\prime})e^{-im\phi _{k\prime}}
+\f]
+\f[
+C_m^{U} (\theta _k)=\sum_{\phi _{k\prime}}U(\theta _k,\phi_{k\prime})e^{-im\phi _{k\prime}}
+\f]
+
+ */
+
+ /*! \fn void SOPHYA::SphericalTransformServer::GenerateFromAlm( SphericalMap<T>& map, int_4 pixelSizeIndex, const Alm<T>& alm) const
+
+ synthesis of a temperature  map from  Alm coefficients 
+*/
+template<class T>
+void SphericalTransformServer<T>::GenerateFromAlm( SphericalMap<T>& map, int_4 pixelSizeIndex, const Alm<T>& alm) const
+{
+  /*=======================================================================
+    computes a map from its alm for the HEALPIX pixelisation
+    map(theta,phi) = sum_l_m a_lm Y_lm(theta,phi)
+    = sum_m {e^(i*m*phi) sum_l a_lm*lambda_lm(theta)}
+    
+    where Y_lm(theta,phi) = lambda(theta) * e^(i*m*phi)
+    
+    * the recurrence of Ylm is the standard one (cf Num Rec)
+    * the sum over m is done by FFT
+    
+    =======================================================================*/
+  int_4 nlmax=alm.Lmax();
+  int_4 nmmax=nlmax;
+  int_4 nsmax=0;
+  // le Resize est suppose mettre a zero
+  map.Resize(pixelSizeIndex);
+  string sphere_type=map.TypeOfMap();
+      int premiereTranche = 0;
+      int derniereTranche = map.NbThetaSlices()-1;
+  if (sphere_type.substr(0,4) == "RING")
+  {
+    nsmax=map.SizeIndex();
+  }
+  else
+  {
+    // pour une sphere Gorski le nombre de pixels est 12*nsmax**2
+    // on calcule une quantite equivalente a nsmax pour la sphere-theta-phi
+    // en vue de l'application du critere Healpix : nlmax<=3*nsmax-1
+    // c'est approximatif ; a raffiner.
+    if (sphere_type.substr(0,6) == "TETAFI")
+    {
+      nsmax=(int_4)sqrt(map.NbPixels()/12.);
+      premiereTranche++;
+      derniereTranche--;
+    }
+    else
+    {
+      cout << " unknown type of sphere : " << sphere_type << endl;
+      throw IOExc(" unknown type of sphere: " + (string)sphere_type );
+    }
+  //  cout << "GenerateFromAlm: the sphere is of type : " << sphere_type << endl;
+  //  cout << "GenerateFromAlm: size index (nside) of the sphere= " << nsmax << endl;
+  //  cout << "GenerateFromAlm: nlmax (from Alm) = " << nlmax << endl;
+  //  if (nlmax>3*nsmax-1) 
+  //  {
+      //     cout << "GenerateFromAlm: nlmax should be <= 3*nside-1" << endl;
+  //   if (strncmp(sphere_type,"TETAFI",6) == 0)
+  //	{
+  //	  cout << "GenerateFromAlm: nlmax should be <= 3*nside-1" << endl;
+  //	  cout << " (for this criterium, nsmax is computed as sqrt(nbPixels/12))" << endl;
+  //	}
+  //}
+  }
+  Bm<complex<T> > b_m_theta(nmmax);
+
+  //  map.Resize(nsmax);
+
+
+  // pour chaque tranche en theta
+  for (int_4 ith = premiereTranche; ith <= derniereTranche;ith++)
+    {
+      int_4 nph;
+      r_8 phi0;
+      r_8 theta;
+      TVector<int_4> pixNumber; 
+      TVector<T> datan;
+      
+      map.GetThetaSlice(ith,theta,phi0, pixNumber,datan);
+      nph = pixNumber.NElts();
+
+      //       -----------------------------------------------------
+      //	      for each theta, and each m, computes
+      //	      b(m,theta) = sum_over_l>m (lambda_l_m(theta) * a_l_m) 
+      //	      ------------------------------------------------------
+      LambdaLMBuilder lb(theta,nlmax,nmmax);
+      //  somme sur m de 0 a l'infini
+      int m;
+      for (m = 0; m <= nmmax; m++)
+	{
+	  b_m_theta(m) = (T)( lb.lamlm(m,m) ) * alm(m,m);
+	  for (int l = m+1; l<= nlmax; l++)
+	    {
+	       b_m_theta(m) += (T)( lb.lamlm(l,m) ) * alm(l,m);
+	    }
+	}
+    //        obtains the negative m of b(m,theta) (= complex conjugate)
+
+      for (m=1;m<=nmmax;m++)
+	{
+	  b_m_theta(-m) = conj(b_m_theta(m));
+	}
+      // ---------------------------------------------------------------
+      //    sum_m  b(m,theta)*exp(i*m*phi)   -> f(phi,theta)
+      // ---------------------------------------------------------------*/
+      TVector<T> Temp = RfourierSynthesisFromB(b_m_theta,nph,phi0);
+      for (int i=0;i< nph;i++)
+	{
+	  map(pixNumber(i))=Temp(i);
+	}
+    }
+}
+
+
+
+  /*! \fn TVector< complex<T> >  SOPHYA::SphericalTransformServer::fourierSynthesisFromB(const Bm<complex<T> >& b_m,  int_4 nph, r_8 phi0) const
+
+\return a vector with nph elements  which are  sums :\f$\sum_{m=-mmax}^{mmax}b_m(\theta)e^{im\varphi}\f$ for nph values of \f$\varphi\f$ regularly distributed in \f$[0,\pi]\f$ ( calculated by FFT)
+
+  The object b_m (\f$b_m\f$) of the class Bm is a special vector which index goes from -mmax to mmax. 
+  */
+template<class T>
+TVector< complex<T> >  SphericalTransformServer<T>::fourierSynthesisFromB(const Bm<complex<T> >& b_m,  int_4 nph, r_8 phi0) const
+{
+  /*=======================================================================
+     dataout(j) = sum_m datain(m) * exp(i*m*phi(j)) 
+     with phi(j) = j*2pi/nph + kphi0*pi/nph and kphi0 =0 or 1
+
+     as the set of frequencies {m} is larger than nph, 
+     we wrap frequencies within {0..nph-1}
+     ie  m = k*nph + m' with m' in {0..nph-1}
+     then
+     noting bw(m') = exp(i*m'*phi0) 
+                   * sum_k (datain(k*nph+m') exp(i*k*pi*kphi0))
+        with bw(nph-m') = CONJ(bw(m')) (if datain(-m) = CONJ(datain(m)))
+     dataout(j) = sum_m' [ bw(m') exp (i*j*m'*2pi/nph) ]
+                = Fourier Transform of bw
+        is real
+
+         NB nph is not necessarily a power of 2
+
+=======================================================================*/
+  //**********************************************************************
+  // pour une valeur de phi (indexee par j) la temperature est la transformee 
+  // de Fourier de bm (somme sur m de -nmax a +nmmax de bm*exp(i*m*phi)).
+  // on demande nph (nombre de pixels sur la tranche) valeurs de transformees, pour nph valeurs de phi, regulierement reparties sur 2*pi. On a:
+  //      DT/T(j) = sum_m b(m) * exp(i*m*phi(j)) 
+  // sommation de -infini a +infini, en fait limitee a -nmamx, +nmmax
+  // On pose m=k*nph + m', avec m' compris entre 0 et nph-1. Alors :
+  // DT/T(j) = somme_k somme_m'  b(k*nph + m')*exp(i*(k*nph + m')*phi(j))
+  // somme_k : de -infini a +infini
+  // somme_m' : de 0 a nph-1
+  // On echange les sommations :
+  // DT/T(j) = somme_k (exp(i*m'*phi(j)) somme_m' b(k*nph + m')*exp(i*(k*nph*phi(j))
+  // mais phi(j) est un multiple entier de 2*pi/nph, la seconde exponentielle 
+  // vaut 1.
+  // Il reste a calculer les transformees de Fourier de somme_m' b(k*nph + m')
+  // si phi0 n'est pas nul, il y a juste un decalage a faire.
+  //**********************************************************************
+
+  TVector< complex<T> > bw(nph);
+  TVector< complex<T> > dataout(nph);
+  TVector< complex<T> > data(nph);
+
+
+  for (int kk=0; kk<bw.NElts(); kk++) bw(kk)=(T)0.;
+  int m;
+  for (m=-b_m.Mmax();m<=-1;m++)
+    {
+      int maux=m;
+      while (maux<0) maux+=nph;
+      int iw=maux%nph;
+      double aux=(m-iw)*phi0;
+      bw(iw) += b_m(m) * complex<T>( (T)cos(aux),(T)sin(aux) )  ;
+    }
+  for (m=0;m<=b_m.Mmax();m++)
+    {
+      //      int iw=((m % nph) +nph) % nph; //between 0 and nph = m'
+      int iw=m%nph;
+      double aux=(m-iw)*phi0;
+      bw(iw)+=b_m(m) * complex<T>( (T)cos(aux),(T)sin(aux) );
+    }
+
+  //     applies the shift in position <-> phase factor in Fourier space
+  for (int mprime=0; mprime < nph; mprime++)
+    {
+      complex<double> aux(cos(mprime*phi0),sin(mprime*phi0));
+      data(mprime)=bw(mprime)*
+	               (complex<T>)(complex<double>(cos(mprime*phi0),sin(mprime*phi0)));
+    }
+
+  //sortie.ReSize(nph);
+  TVector< complex<T> > sortie(nph);
+
+  fftIntfPtr_-> FFTBackward(data, sortie);
+  
+  return sortie;
+}
+
+//********************************************
+/*! \fn TVector<T>  SOPHYA::SphericalTransformServer::RfourierSynthesisFromB(const Bm<complex<T> >& b_m,  int_4 nph, r_8 phi0) const
+
+same as fourierSynthesisFromB, but return a real vector, taking into account the fact that b(-m) is conjugate of b(m) */
+template<class T>
+TVector<T>  SphericalTransformServer<T>::RfourierSynthesisFromB(const Bm<complex<T> >& b_m,  int_4 nph, r_8 phi0) const
+{
+  /*=======================================================================
+     dataout(j) = sum_m datain(m) * exp(i*m*phi(j)) 
+     with phi(j) = j*2pi/nph + kphi0*pi/nph and kphi0 =0 or 1
+
+     as the set of frequencies {m} is larger than nph, 
+     we wrap frequencies within {0..nph-1}
+     ie  m = k*nph + m' with m' in {0..nph-1}
+     then
+     noting bw(m') = exp(i*m'*phi0) 
+                   * sum_k (datain(k*nph+m') exp(i*k*pi*kphi0))
+        with bw(nph-m') = CONJ(bw(m')) (if datain(-m) = CONJ(datain(m)))
+     dataout(j) = sum_m' [ bw(m') exp (i*j*m'*2pi/nph) ]
+                = Fourier Transform of bw
+        is real
+
+         NB nph is not necessarily a power of 2
+
+=======================================================================*/
+  //**********************************************************************
+  // pour une valeur de phi (indexee par j) la temperature est la transformee 
+  // de Fourier de bm (somme sur m de -nmax a +nmmax de bm*exp(i*m*phi)).
+  // on demande nph (nombre de pixels sur la tranche) valeurs de transformees, pour nph valeurs de phi, regulierement reparties sur 2*pi. On a:
+  //      DT/T(j) = sum_m b(m) * exp(i*m*phi(j)) 
+  // sommation de -infini a +infini, en fait limitee a -nmamx, +nmmax
+  // On pose m=k*nph + m', avec m' compris entre 0 et nph-1. Alors :
+  // DT/T(j) = somme_k somme_m'  b(k*nph + m')*exp(i*(k*nph + m')*phi(j))
+  // somme_k : de -infini a +infini
+  // somme_m' : de 0 a nph-1
+  // On echange les sommations :
+  // DT/T(j) = somme_k (exp(i*m'*phi(j)) somme_m' b(k*nph + m')*exp(i*(k*nph*phi(j))
+  // mais phi(j) est un multiple entier de 2*pi/nph, la seconde exponentielle 
+  // vaut 1.
+  // Il reste a calculer les transformees de Fourier de somme_m' b(k*nph + m')
+  // si phi0 n'est pas nul, il y a juste un decalage a faire.
+  //**********************************************************************
+  TVector< complex<T> > bw(nph);
+  TVector< complex<T> > dataout(nph);
+  TVector< complex<T> > data(nph/2+1);
+
+
+  for (int kk=0; kk<bw.NElts(); kk++) bw(kk)=(T)0.;
+  int m;
+  for (m=-b_m.Mmax();m<=-1;m++)
+    {
+      int maux=m;
+      while (maux<0) maux+=nph;
+      int iw=maux%nph;
+      double aux=(m-iw)*phi0;
+      bw(iw) += b_m(m) * complex<T>( (T)cos(aux),(T)sin(aux) )  ;
+    }
+  for (m=0;m<=b_m.Mmax();m++)
+    {
+      //      int iw=((m % nph) +nph) % nph; //between 0 and nph = m'
+      int iw=m%nph;
+      double aux=(m-iw)*phi0;
+      bw(iw)+=b_m(m) * complex<T>( (T)cos(aux),(T)sin(aux) );
+    }
+
+  //     applies the shift in position <-> phase factor in Fourier space
+  for (int mprime=0; mprime <= nph/2; mprime++)
+    {
+      complex<double> aux(cos(mprime*phi0),sin(mprime*phi0));
+      data(mprime)=bw(mprime)*
+	               (complex<T>)(complex<double>(cos(mprime*phi0),sin(mprime*phi0)));
+    }
+
+  TVector<T> sortie;
+  fftIntfPtr_-> FFTBackward(data, sortie);
+  
+  return sortie;
+}
+//*******************************************
+
+ /*! \fn  Alm<T> SOPHYA::SphericalTransformServer::DecomposeToAlm(const SphericalMap<T>& map, int_4 nlmax, r_8 cos_theta_cut) const
+
+\return the Alm coefficients from analysis of a temperature map. 
+
+    \param<nlmax> : maximum value of the l index
+
+     \param<cos_theta_cut> : cosinus of the symmetric cut EULER angle theta : cos_theta_cut=0 means no cut ; cos_theta_cut=1 all the sphere is cut.
+
+ */ 
+template<class T>
+void SphericalTransformServer<T>::DecomposeToAlm(const SphericalMap<T>& map, Alm<T>& alm, int_4 nlmax, r_8 cos_theta_cut) const
+{
+  DecomposeToAlm(const_cast< SphericalMap<T>& >(map), alm, nlmax, cos_theta_cut, 0);
+}
+//*******************************************
+
+ /*! \fn  Alm<T> SOPHYA::SphericalTransformServer::DecomposeToAlm(const SphericalMap<T>& map, int_4 nlmax, r_8 cos_theta_cut, int iterationOrder) const
+
+\return the Alm coefficients from analysis of a temperature map. THE MAP CAN BE MODIFIED (if iterationOrder >0)
+
+    \param<nlmax> : maximum value of the l index
+
+     \param<cos_theta_cut> : cosinus of the symmetric cut EULER angle theta : cos_theta_cut=0 means no cut ; cos_theta_cut=1 all the sphere is cut.
+
+\param<iterationOrder> : 1,2,3,4.... order of an iterative analysis. (Default : 0 -> standard analysis). If iterationOrder is not null, the method works with SphereHEALPix but NOT WITH SphereThetaPhi maps !  */ 
+template<class T>
+void SphericalTransformServer<T>::DecomposeToAlm(SphericalMap<T>& map, Alm<T>& alm, int_4 nlmax, r_8 cos_theta_cut, int iterationOrder) const
+{
+  int_4  nmmax = nlmax;
+  //  PrtTim("appel  carteVersAlm");
+  carteVersAlm(map, nlmax, cos_theta_cut, alm);
+  //  PrtTim("retour  carteVersAlm");
+  if (iterationOrder > 0)
+    {
+      TVector<int_4> fact(iterationOrder+2);
+      fact(0) = 1;
+      int k;
+      for (k=1; k <= iterationOrder+1; k++)
+	{
+	  fact(k) = fact(k-1)*k;
+	}
+      Alm<T> alm2(alm);
+      T Tzero = (T)0.;
+      complex<T> complexZero = complex<T>(Tzero, Tzero);
+      alm = complexZero;
+      int signe = 1;
+      int nbIteration = iterationOrder+1;
+      for (k=1; k <= nbIteration; k++)
+	{
+	  T facMult = (T)(0.5*signe*fact(iterationOrder)*(2*nbIteration-k)/(fact(k)*fact(nbIteration-k)));
+	  for (int m = 0; m <= nmmax; m++)
+	    {
+	      for (int l = m; l<= nlmax; l++)
+		{
+		  alm(l,m) += facMult*alm2(l,m); 
+		}
+	    }
+	  if (k == nbIteration) break;
+	  signe = -signe;
+	  for (int k=0; k< map.NbPixels(); k++) map(k) = (T)0.;
+	  //        synthetize a map from the estimated alm
+	  //	  PrtTim("appel  GenerateFromAlm");
+	  GenerateFromAlm( map, map.SizeIndex(), alm2);
+	  //	  PrtTim("retour  GenerateFromAlm");
+	  alm2 = complexZero;
+	  //        analyse the new map
+	  //	  PrtTim("appel  carteVersAlm");
+	  carteVersAlm(map, nlmax, cos_theta_cut, alm2);
+	  //	  PrtTim("retour  carteVersAlm");
+	}
+    }
+}
+
+template<class T>
+ void SphericalTransformServer<T>::carteVersAlm(const SphericalMap<T>& map, int_4 nlmax, r_8 cos_theta_cut, Alm<T>& alm) const
+{
+  
+  /*-----------------------------------------------------------------------
+    computes the integral in phi : phas_m(theta)
+    for each parallele from north to south pole
+    -----------------------------------------------------------------------*/
+  TVector<T> data;
+  TVector<int_4> pixNumber;
+  int_4  nmmax = nlmax;
+  TVector< complex<T> > phase(nmmax+1);
+  
+  alm.ReSizeToLmax(nlmax);
+  for (int_4 ith = 0; ith < map.NbThetaSlices(); ith++)
+    {
+      r_8 phi0;
+      r_8 theta;
+      //  PrtTim("debut 1ere tranche ");
+      map.GetThetaSlice(ith,theta,phi0,pixNumber ,data);
+      phase = complex<T>((T)0.,(T)0.);
+      double cth = cos(theta);
+      
+      //part of the sky out of the symetric cut
+      bool keep_it = (fabs(cth) >= cos_theta_cut); 
+
+      //    PrtTim("fin 1ere tranche ");
+  
+      if (keep_it)
+	{
+	  //	  phase = CFromFourierAnalysis(nmmax,data,phi0);
+	  // 	  PrtTim("avant Fourier ");
+	  CFromFourierAnalysis(nmmax,data,phase, phi0);
+	  // 	  PrtTim("apres Fourier ");
+
+	}
+      
+//      ---------------------------------------------------------------------
+//	computes the a_lm by integrating over theta
+//	lambda_lm(theta) * phas_m(theta)
+//	for each m and l
+//	-----------------------------------------------------------------------
+      //        PrtTim("avant instanciation LM ");
+      LambdaLMBuilder lb(theta,nlmax,nmmax);
+      //        PrtTim("apres instanciation LM ");
+      r_8 domega=map.PixSolAngle(map.PixIndexSph(theta,phi0));
+
+      //   PrtTim("avant mise a jour Alm ");
+      complex<T> fi;
+      T facteur;
+      int index;
+      for (int m = 0; m <= nmmax; m++)
+	{
+	  fi = phase(m);
+	  for (int l = m; l<= nlmax; l++)
+	    {
+	         index = alm.indexOfElement(l,m);
+		 //  facteur = (T)(lb.lamlm(l,m) * domega);
+		    facteur = (T)(lb.lamlm(index) * domega);
+		  // alm(l,m) += facteur * fi ; 
+		      alm(index) += facteur * fi ; 
+	    }
+	}
+      
+
+      
+      //
+      //
+      //       PrtTim("apres mise a jour Alm ");
+    }
+}
+  /*! \fn TVector< complex<T> > SOPHYA::SphericalTransformServer::CFromFourierAnalysis(int_4 nmmax, const TVector<complex<T> >datain, r_8 phi0) const
+
+\return a vector with mmax elements  which are  sums :
+\f$\sum_{k=0}^{nphi}datain(\theta,\varphi_k)e^{im\varphi_k}\f$ for (mmax+1) values of \f$m\f$ from 0 to mmax.
+   */
+template<class T>
+TVector< complex<T> > SphericalTransformServer<T>::CFromFourierAnalysis(int_4 nmmax, const TVector<complex<T> >datain, r_8 phi0) const
+{
+  /*=======================================================================
+    integrates (data * phi-dependence-of-Ylm) over phi
+    --> function of m can be computed by FFT
+    
+    datain est modifie
+    =======================================================================*/
+  int_4 nph=datain.NElts();
+  if (nph <= 0) 
+    {
+      throw PException("bizarre : vecteur datain de longueur nulle (CFromFourierAnalysis)");
+    }
+  TVector<complex<T> > transformedData(nph);
+  fftIntfPtr_-> FFTForward(datain, transformedData);
+
+  TVector< complex<T> > dataout(nmmax+1);
+
+  int im_max=min(nph,nmmax+1);
+  int i;
+  dataout = complex<T>((T)0.,(T)0.);
+  //  for (i=0;i< dataout.NElts();i++) dataout(i)=complex<T>((T)0.,(T)0.);
+  for (i=0;i<im_max;i++) dataout(i)=transformedData(i);
+
+
+  for (int kk=nph; kk<dataout.NElts(); kk++) dataout(kk)=dataout(kk%nph);
+  for (i = 0;i <dataout.NElts();i++){
+    dataout(i)*= (complex<T>)(complex<double>(cos(-i*phi0),sin(-i*phi0)));
+  }
+  return dataout;
+}
+
+//&&&&&&&&& nouvelle version
+/* \fn TVector< complex<T> > SOPHYA::SphericalTransformServer::CFromFourierAnalysis(int_4 nmmax, const TVector<T> datain, r_8 phi0) const
+
+same as previous one, but with a "datain" which is real (not complex) */
+template<class T>
+void SphericalTransformServer<T>::CFromFourierAnalysis(int_4 nmmax, const TVector<T> datain, TVector< complex<T> >& dataout, r_8 phi0) const
+{
+  //=======================================================================
+  //    integrates (data * phi-dependence-of-Ylm) over phi
+  //    --> function of m can be computed by FFT
+  //   !     with  0<= m <= npoints/2 (: Nyquist)
+  //   !     because the data is real the negative m are the conjugate of the 
+  //   !     positive ones
+    
+  //    datain est modifie
+  //    
+  //    =======================================================================
+  int_4 nph=datain.NElts();
+  if (nph <= 0) 
+    {
+      throw PException("bizarre : vecteur datain de longueur nulle (CFromFourierAnalysis)");
+    }
+  // if (nph%2 != 0 )
+  //  {
+      //  throw PException("SphericalTransformServer<T>::CFromFourierAnalysis : longueur de datain impair ?");
+  //  }
+  TVector<complex<T> > transformedData;
+
+  // la taille du vecteur complexe retourne est nph/2+1 (si la taille 
+  // du vecteur reel entre est nph)
+  //   cout << " longueur de datain  = " << nph << endl;
+  fftIntfPtr_-> FFTForward(datain, transformedData);
+  //  cout <<  " taille de la transformee " << transformedData.Size() << endl;
+  //  TVector< complex<T> > dataout(nmmax+1);
+  dataout.ReSize(nmmax+1);
+
+  // on transfere le resultat de la fft dans dataout.
+
+  int maxFreqAccessiblesParFFT = min(nph/2,nmmax);
+  int i;
+  for (i=0;i<=maxFreqAccessiblesParFFT;i++) dataout(i)=transformedData(i);
+
+
+  // si dataout n'est pas plein, on complete jusqu'a  nph+1 valeurs (a moins 
+  // que dataout ne soit plein avant d'atteindre nph)
+  if (maxFreqAccessiblesParFFT != nmmax )
+    {
+      int maxMfft = min(nph,nmmax);
+      for (i=maxFreqAccessiblesParFFT+1; i<=maxMfft; i++)
+	{
+	  dataout(i) = conj(dataout(nph-i) );
+	}
+      // on conplete, si necessaire, par periodicite
+      if ( maxMfft != nmmax )
+	{
+	  for (int kk=nph+1; kk <= nmmax; kk++) 
+	    {
+	      dataout(kk)=dataout(kk%nph);
+	    }
+	}
+    }
+  for (i = 0;i <dataout.NElts();i++)
+    {
+      dataout(i)*= (complex<T>)(complex<double>(cos(-i*phi0),sin(-i*phi0)));
+    }
+  //  return dataout;
+}
+
+ /*! \fn void SOPHYA::SphericalTransformServer::GenerateFromAlm(SphericalMap<T>& mapq,
+					       SphericalMap<T>& mapu, 
+					       int_4 pixelSizeIndex,
+					       const Alm<T>& alme,
+					       const Alm<T>& almb) const
+
+synthesis of a polarization map from  Alm coefficients. The spheres mapq and mapu contain respectively the Stokes parameters. */
+template<class T>
+void SphericalTransformServer<T>::GenerateFromAlm(SphericalMap<T>& mapq,
+					       SphericalMap<T>& mapu, 
+					       int_4 pixelSizeIndex,
+					       const Alm<T>& alme,
+					       const Alm<T>& almb) const
+{
+  /*=======================================================================
+    computes a map form its alm for the HEALPIX pixelisation
+    map(theta,phi) = sum_l_m a_lm Y_lm(theta,phi)
+    = sum_m {e^(i*m*phi) sum_l a_lm*lambda_lm(theta)}
+    
+    where Y_lm(theta,phi) = lambda(theta) * e^(i*m*phi)
+    
+    * the recurrence of Ylm is the standard one (cf Num Rec)
+    * the sum over m is done by FFT
+    
+    =======================================================================*/
+  int_4 nlmax=alme.Lmax();
+  if (nlmax != almb.Lmax())
+    {
+      cout << " SphericalTransformServer: les deux tableaux alm n'ont pas la meme taille" << endl;
+      throw SzMismatchError("SphericalTransformServer: les deux tableaux alm n'ont pas la meme taille");
+    }
+  int_4 nmmax=nlmax;
+  int_4 nsmax=0;
+  mapq.Resize(pixelSizeIndex);
+  mapu.Resize(pixelSizeIndex);
+  string sphere_type=mapq.TypeOfMap();
+  if (sphere_type != mapu.TypeOfMap())
+    {
+      cout <<  " SphericalTransformServer: les deux spheres ne sont pas de meme type" << endl;
+      cout << " type 1 " << sphere_type << endl;
+      cout << " type 2 " << mapu.TypeOfMap() << endl;
+      throw SzMismatchError("SphericalTransformServer: les deux spheres ne sont pas de meme type");
+      
+    }
+  if (sphere_type.substr(0,4) == "RING")
+    {
+      nsmax=mapq.SizeIndex();
+    }
+  else
+    // pour une sphere Gorski le nombre de pixels est 12*nsmax**2
+    // on calcule une quantite equivalente a nsmax pour la sphere-theta-phi
+    // en vue de l'application du critere Healpix : nlmax<=3*nsmax-1
+    // c'est approximatif ; a raffiner.
+    if (sphere_type.substr(0,6) == "TETAFI")
+      {
+	nsmax=(int_4)sqrt(mapq.NbPixels()/12.);
+      }
+    else
+      {
+	cout << " unknown type of sphere : " << sphere_type << endl;
+	throw IOExc(" unknown type of sphere ");
+      }
+  cout << "GenerateFromAlm: the spheres are of type : " << sphere_type << endl;
+  cout << "GenerateFromAlm: size indices (nside) of  spheres= " << nsmax << endl;
+  cout << "GenerateFromAlm: nlmax (from Alm) = " << nlmax << endl;
+  if (nlmax>3*nsmax-1) 
+    {
+      cout << "GenerateFromAlm: nlmax should be <= 3*nside-1" << endl;
+      if (sphere_type.substr(0,6) == "TETAFI")
+	{
+	  cout << " (for this criterium, nsmax is computed as sqrt(nbPixels/12))" << endl;
+	}
+    }
+  if (alme.Lmax()!=almb.Lmax())
+    {
+      cout << "GenerateFromAlm: arrays Alme and Almb have not the same size ? " << endl; 
+      throw SzMismatchError("SphericalTransformServer: arrays Alme and Almb have not the same size ?  ");
+    }
+    mapFromWX(nlmax, nmmax, mapq, mapu, alme, almb);
+    // mapFromPM(nlmax, nmmax, mapq, mapu, alme, almb);
+}
+ /*! \fn void SOPHYA::SphericalTransformServer::DecomposeToAlm(const SphericalMap<T>& mapq,
+					      const SphericalMap<T>& mapu,
+					      Alm<T>& alme,
+					      Alm<T>& almb,
+					      int_4 nlmax,
+					      r_8 cos_theta_cut) const
+
+analysis of a polarization map into Alm coefficients.
+
+ The spheres \c mapq and \c mapu contain respectively the Stokes parameters. 
+
+ \c a2lme and \c a2lmb will receive respectively electric and magnetic Alm's
+    nlmax : maximum value of the l index
+
+ \c cos_theta_cut : cosinus of the symmetric cut EULER angle theta : cos_theta_cut=0 means no cut ; cos_theta_cut=1 all the sphere is cut.
+
+
+ */ 
+template<class T>
+void SphericalTransformServer<T>::DecomposeToAlm(const SphericalMap<T>& mapq,
+					      const SphericalMap<T>& mapu,
+					      Alm<T>& alme,
+					      Alm<T>& almb,
+					      int_4 nlmax,
+					      r_8 cos_theta_cut) const
+{
+  DecomposeToAlm(const_cast< SphericalMap<T>& >(mapq), const_cast< SphericalMap<T>& >(mapu), alme, almb, nlmax, cos_theta_cut);
+}
+
+ /*! \fn void SOPHYA::SphericalTransformServer::DecomposeToAlm(const SphericalMap<T>& mapq,
+					      const SphericalMap<T>& mapu,
+					      Alm<T>& alme,
+					      Alm<T>& almb,
+					      int_4 nlmax,
+					      r_8 cos_theta_cut,
+					      int iterationOrder) const
+
+analysis of a polarization map into Alm coefficients.
+
+ The spheres \c mapq and \c mapu contain respectively the Stokes parameters. 
+
+ \c a2lme and \c a2lmb will receive respectively electric and magnetic Alm's
+    nlmax : maximum value of the l index
+
+ \c cos_theta_cut : cosinus of the symmetric cut EULER angle theta : cos_theta_cut=0 means no cut ; cos_theta_cut=1 all the sphere is cut.
+
+\param<iterationOrder> : 1,2,3,4.... order of an iterative analysis. (Default : 0 -> standard analysis). If iterationOrder is not null, the method works with SphereHEALPix but NOT WITH SphereThetaPhi maps !
+
+THE INPUT MAPS CAN BE MODIFIED (only if iterationOrder >0)
+
+ */ 
+template<class T>
+void SphericalTransformServer<T>::DecomposeToAlm(SphericalMap<T>& mapq,
+					      SphericalMap<T>& mapu,
+					      Alm<T>& alme,
+					      Alm<T>& almb,
+					      int_4 nlmax,
+					      r_8 cos_theta_cut, 
+					      int iterationOrder) const
+{
+  int_4  nmmax = nlmax;
+  carteVersAlm(mapq, mapu, alme, almb, nlmax, cos_theta_cut);
+  if (iterationOrder > 0)
+    {
+      TVector<int_4> fact(iterationOrder+2);
+      fact(0) = 1;
+      int k;
+      for (k=1; k <= iterationOrder+1; k++)
+	{
+	  fact(k) = fact(k-1)*k;
+	}
+      Alm<T> alme2(alme);
+      Alm<T> almb2(almb);
+      T Tzero = (T)0.;
+      complex<T> complexZero = complex<T>(Tzero, Tzero);
+      alme = complexZero;
+      almb = complexZero;
+      int signe = 1;
+      int nbIteration = iterationOrder+1;
+      for (k=1; k <= nbIteration; k++)
+	{
+	  T facMult = (T)(0.5*signe*fact(iterationOrder)*(2*nbIteration-k)/(fact(k)*fact(nbIteration-k)));
+	  for (int m = 0; m <= nmmax; m++)
+	    {
+	      for (int l = m; l<= nlmax; l++)
+		{
+		  alme(l,m) += facMult*alme2(l,m); 
+		  almb(l,m) += facMult*almb2(l,m); 
+		}
+	    }
+	  if (k == nbIteration) break;
+	  signe = -signe;
+	  for (int k=0; k< mapq.NbPixels(); k++)
+	    {
+	      mapq(k) = (T)0.;
+	      mapu(k) = (T)0.;
+	    }
+	  //        synthetize a map from the estimated alm
+	  GenerateFromAlm(mapq,mapu,mapq.SizeIndex(),alme2,almb2); 
+	  alme2 = complexZero;
+	  almb2 = complexZero;
+	  //        analyse the new map
+	  carteVersAlm(mapq, mapu, alme2, almb2, nlmax, cos_theta_cut);
+	}
+    }
+}
+
+template<class T>
+void SphericalTransformServer<T>::carteVersAlm(const SphericalMap<T>& mapq,
+					      const SphericalMap<T>& mapu,
+					      Alm<T>& alme,
+					      Alm<T>& almb,
+					      int_4 nlmax,
+					      r_8 cos_theta_cut) const
+{
+  int_4  nmmax = nlmax;
+  // resize et remise a zero
+  alme.ReSizeToLmax(nlmax);
+  almb.ReSizeToLmax(nlmax);
+
+  
+  TVector<T> dataq;
+  TVector<T> datau;
+  TVector<int_4> pixNumber;
+
+  string sphere_type=mapq.TypeOfMap();
+  if (sphere_type != mapu.TypeOfMap())
+    {
+      cout <<  " SphericalTransformServer: les deux spheres ne sont pas de meme type" << endl;
+      cout << " type 1 " << sphere_type << endl;
+      cout << " type 2 " << mapu.TypeOfMap() << endl;
+      throw SzMismatchError("SphericalTransformServer: les deux spheres ne sont pas de meme type");
+      
+    }
+  if (mapq.NbPixels()!=mapu.NbPixels())
+    {
+      cout << " DecomposeToAlm: map Q and map U have not same size ?" << endl;
+      throw SzMismatchError("SphericalTransformServer::DecomposeToAlm: map Q and map U have not same size ");
+    }
+  for (int_4 ith = 0; ith < mapq.NbThetaSlices(); ith++)
+    {
+      r_8 phi0;
+      r_8 theta;
+      mapq.GetThetaSlice(ith,theta,phi0, pixNumber,dataq);
+      mapu.GetThetaSlice(ith,theta,phi0, pixNumber,datau);
+      if (dataq.NElts() != datau.NElts() ) 
+	{
+	  throw  SzMismatchError("the spheres have not the same pixelization");
+	}
+      r_8 domega=mapq.PixSolAngle(mapq.PixIndexSph(theta,phi0));
+      double cth = cos(theta);
+      //part of the sky out of the symetric cut
+      bool keep_it = (fabs(cth) >= cos_theta_cut); 
+      if (keep_it)
+	{
+	  //  almFromPM(pixNumber.NElts(), nlmax, nmmax, phi0, domega, theta, dataq, datau, alme, almb); 
+	  almFromWX(nlmax, nmmax, phi0, domega, theta, dataq, datau, alme, almb); 
+	}
+    }
+}
+
+
+ /*! \fn void SOPHYA::SphericalTransformServer::almFromWX(int_4 nlmax, int_4 nmmax,
+					 r_8 phi0, r_8 domega, 
+					 r_8 theta, 
+					 const TVector<T>& dataq, 
+					 const TVector<T>& datau,
+					 Alm<T>& alme,
+					 Alm<T>& almb) const
+
+Compute polarized Alm's as : 
+\f[
+a_{lm}^E=\frac{1}{\sqrt{2}}\sum_{slices}{\omega_{pix}\left(\,_{w}\lambda_l^m\tilde{Q}-i\,_{x}\lambda_l^m\tilde{U}\right)}
+\f]
+\f[
+a_{lm}^B=\frac{1}{\sqrt{2}}\sum_{slices}{\omega_{pix}\left(i\,_{x}\lambda_l^m\tilde{Q}+\,_{w}\lambda_l^m\tilde{U}\right)}
+\f]
+
+where \f$\tilde{Q}\f$ and \f$\tilde{U}\f$ are C-coefficients computed by FFT (method CFromFourierAnalysis, called by present method) from the Stokes parameters.
+
+\f$\omega_{pix}\f$ are solid angle of each pixel.
+
+dataq, datau : Stokes parameters.
+
+  */
+template<class T>
+void SphericalTransformServer<T>::almFromWX(int_4 nlmax, int_4 nmmax,
+					 r_8 phi0, r_8 domega, 
+					 r_8 theta, 
+					 const TVector<T>& dataq, 
+					 const TVector<T>& datau,
+					 Alm<T>& alme,
+					 Alm<T>& almb) const
+{
+  TVector< complex<T> > phaseq(nmmax+1);
+  TVector< complex<T> > phaseu(nmmax+1);
+  //  TVector<complex<T> > datain(nph);
+  for (int i=0;i< nmmax+1;i++)
+    {
+      phaseq(i)=0; 
+      phaseu(i)=0; 
+    }
+  //  for(int kk=0; kk<nph; kk++) datain(kk)=complex<T>(dataq(kk),0.);
+
+  //  phaseq = CFromFourierAnalysis(nmmax,dataq,phi0); 
+  CFromFourierAnalysis(nmmax,dataq,phaseq, phi0); 
+
+  //  phaseu=  CFromFourierAnalysis(nmmax,datau,phi0); 
+  CFromFourierAnalysis(nmmax,datau,phaseu, phi0); 
+
+  LambdaWXBuilder lwxb(theta,nlmax,nmmax);
+
+  r_8 sqr2inv=1/Rac2;
+  for (int m = 0; m <= nmmax; m++)
+    {
+      r_8 lambda_w=0.;
+      r_8 lambda_x=0.;
+      lwxb.lam_wx(m, m, lambda_w, lambda_x);
+      complex<T>  zi_lam_x((T)0., (T)lambda_x);
+      alme(m,m) +=  ( (T)(lambda_w)*phaseq(m)-zi_lam_x*phaseu(m) )*(T)(domega*sqr2inv);
+      almb(m,m) +=  ( (T)(lambda_w)*phaseu(m)+zi_lam_x*phaseq(m) )*(T)(domega*sqr2inv);
+      
+      for (int l = m+1; l<= nlmax; l++)
+	{
+	  lwxb.lam_wx(l, m, lambda_w, lambda_x);
+	  zi_lam_x = complex<T>((T)0., (T)lambda_x);
+	  alme(l,m) +=  ( (T)(lambda_w)*phaseq(m)-zi_lam_x*phaseu(m) )*(T)(domega*sqr2inv);
+	  almb(l,m) +=  ( (T)(lambda_w)*phaseu(m)+zi_lam_x*phaseq(m) )*(T)(domega*sqr2inv);
+	}
+    }
+}
+
+
+ /*! \fn void SOPHYA::SphericalTransformServer::almFromPM(int_4 nph, int_4 nlmax, 
+                                         int_4 nmmax,
+					 r_8 phi0, r_8 domega,  
+					 r_8 theta, 
+					 const TVector<T>& dataq, 
+					 const TVector<T>& datau,
+					 Alm<T>& alme,
+					 Alm<T>& almb) const
+
+Compute polarized Alm's as : 
+\f[
+a_{lm}^E=-\frac{1}{2}\sum_{slices}{\omega_{pix}\left(\,_{+}\lambda_l^m\tilde{P^+}+\,_{-}\lambda_l^m\tilde{P^-}\right)}
+\f]
+\f[
+a_{lm}^B=\frac{i}{2}\sum_{slices}{\omega_{pix}\left(\,_{+}\lambda_l^m\tilde{P^+}-\,_{-}\lambda_l^m\tilde{P^-}\right)}
+\f]
+
+where \f$\tilde{P^{\pm}}=\tilde{Q}\pm\tilde{U}\f$  computed by FFT (method CFromFourierAnalysis, called by present method) from the Stokes parameters,\f$Q\f$ and \f$U\f$ .
+
+\f$\omega_{pix}\f$ are solid angle of each pixel.
+
+dataq, datau : Stokes parameters.
+
+  */
+template<class T>
+void SphericalTransformServer<T>::almFromPM(int_4 nph, int_4 nlmax, 
+                                         int_4 nmmax,
+					 r_8 phi0, r_8 domega,  
+					 r_8 theta, 
+					 const TVector<T>& dataq, 
+					 const TVector<T>& datau,
+					 Alm<T>& alme,
+					 Alm<T>& almb) const
+{
+  TVector< complex<T> > phasep(nmmax+1);
+  TVector< complex<T> > phasem(nmmax+1);
+  TVector<complex<T> > datain(nph);
+  for (int i=0;i< nmmax+1;i++)
+    {
+      phasep(i)=0; 
+      phasem(i)=0; 
+    }
+  int kk;
+  for(kk=0; kk<nph; kk++) datain(kk)=complex<T>(dataq(kk),datau(kk));
+
+  phasep = CFromFourierAnalysis(nmmax,datain,phi0); 
+
+  for(kk=0; kk<nph; kk++) datain(kk)=complex<T>(dataq(kk),-datau(kk));
+  phasem = CFromFourierAnalysis(nmmax,datain,phi0); 
+  LambdaPMBuilder lpmb(theta,nlmax,nmmax);
+	  
+  for (int m = 0; m <= nmmax; m++)
+    {
+      r_8 lambda_p=0.;
+      r_8 lambda_m=0.;
+      complex<T> im((T)0.,(T)1.);
+      lpmb.lam_pm(m, m, lambda_p, lambda_m);
+	      
+      alme(m,m) +=   -( (T)(lambda_p)*phasep(m) + (T)(lambda_m)*phasem(m)  )*(T)(domega*0.5);
+      almb(m,m) +=  im*( (T)(lambda_p)*phasep(m) - (T)(lambda_m)*phasem(m) )*(T)(domega*0.5);
+      for (int l = m+1; l<= nlmax; l++)
+	{
+	  lpmb.lam_pm(l, m, lambda_p, lambda_m);
+	  alme(l,m) +=  -( (T)(lambda_p)*phasep(m) + (T)(lambda_m)*phasem(m)  )*(T)(domega*0.5);
+	  almb(l,m) += im* ( (T)(lambda_p)*phasep(m) - (T)(lambda_m)*phasem(m) )*(T)(domega*0.5);
+	}
+    }
+}
+
+
+/*! \fn void SOPHYA::SphericalTransformServer::mapFromWX(int_4 nlmax, int_4 nmmax,
+					 SphericalMap<T>& mapq,
+					 SphericalMap<T>& mapu, 
+					 const Alm<T>& alme,
+					 const Alm<T>& almb) const
+
+synthesis of Stokes parameters following formulae : 
+
+\f[
+Q=\sum_{m=-mmax}^{mmax}b_m^qe^{im\varphi}
+\f]
+\f[
+U=\sum_{m=-mmax}^{mmax}b_m^ue^{im\varphi}
+\f]
+
+computed by FFT (method fourierSynthesisFromB called by the present one)
+
+with :
+
+\f[
+b_m^q=-\frac{1}{\sqrt{2}}\sum_{l=|m|}^{lmax}{\left(\,_{w}\lambda_l^ma_{lm}^E-i\,_{x}\lambda_l^ma_{lm}^B\right) }
+\f]
+\f[
+b_m^u=\frac{1}{\sqrt{2}}\sum_{l=|m|}^{lmax}{\left(i\,_{x}\lambda_l^ma_{lm}^E+\,_{w}\lambda_l^ma_{lm}^B\right) }
+\f]
+ */
+template<class T>
+void SphericalTransformServer<T>::mapFromWX(int_4 nlmax, int_4 nmmax,
+					 SphericalMap<T>& mapq,
+					 SphericalMap<T>& mapu, 
+					 const Alm<T>& alme,
+					 const Alm<T>& almb) const
+{
+  Bm<complex<T> > b_m_theta_q(nmmax);
+  Bm<complex<T> > b_m_theta_u(nmmax);
+
+  for (int_4 ith = 0; ith < mapq.NbThetaSlices();ith++)
+    {
+      int_4 nph;
+      r_8 phi0;
+      r_8 theta;
+      TVector<int_4>  pixNumber; 
+      TVector<T> datan;
+      
+      mapq.GetThetaSlice(ith,theta,phi0, pixNumber,datan);
+      nph =  pixNumber.NElts();
+      //       -----------------------------------------------------
+      //	      for each theta, and each m, computes
+      //	      b(m,theta) = sum_over_l>m (lambda_l_m(theta) * a_l_m) 
+      //	      ------------------------------------------------------
+      LambdaWXBuilder lwxb(theta,nlmax,nmmax);
+      //      LambdaPMBuilder lpmb(theta,nlmax,nmmax);
+      r_8 sqr2inv=1/Rac2;
+      int m;
+      for (m = 0; m <= nmmax; m++)
+	{
+	  r_8 lambda_w=0.;
+	  r_8 lambda_x=0.;
+	  lwxb.lam_wx(m, m, lambda_w, lambda_x);
+	  complex<T>  zi_lam_x((T)0., (T)lambda_x);
+	  
+	  b_m_theta_q(m) =  ( (T)(lambda_w) * alme(m,m) - zi_lam_x * almb(m,m))*(T)sqr2inv ;
+	  b_m_theta_u(m) =  ( (T)(lambda_w) * almb(m,m) + zi_lam_x * alme(m,m))*(T)sqr2inv;
+	  
+	  
+	  for (int l = m+1; l<= nlmax; l++)
+	    {
+	      
+	      lwxb.lam_wx(l, m, lambda_w, lambda_x);
+	      zi_lam_x= complex<T>((T)0., (T)lambda_x);
+	      
+	      b_m_theta_q(m) += ((T)(lambda_w)*alme(l,m)-zi_lam_x *almb(l,m))*(T)sqr2inv;
+	      b_m_theta_u(m) += ((T)(lambda_w)*almb(l,m)+zi_lam_x *alme(l,m))*(T)sqr2inv;
+	      
+	    } 
+	}
+      //        obtains the negative m of b(m,theta) (= complex conjugate)
+      for (m=1;m<=nmmax;m++)
+	{
+	  b_m_theta_q(-m) = conj(b_m_theta_q(m));
+	  b_m_theta_u(-m) = conj(b_m_theta_u(m));
+	}
+
+      //    TVector<complex<T> > Tempq = fourierSynthesisFromB(b_m_theta_q,nph,phi0);  
+      //     TVector<complex<T> > Tempu = fourierSynthesisFromB(b_m_theta_u,nph,phi0); 
+      TVector<T> Tempq = RfourierSynthesisFromB(b_m_theta_q,nph,phi0);  
+      TVector<T> Tempu = RfourierSynthesisFromB(b_m_theta_u,nph,phi0); 
+      for (int i=0;i< nph;i++)
+	{
+	  //	  mapq(pixNumber(i))=Tempq(i).real();
+	  //	  mapu(pixNumber(i))=Tempu(i).real();
+	  mapq(pixNumber(i))=Tempq(i);
+	  mapu(pixNumber(i))=Tempu(i);
+	  
+	}
+    } 
+}
+/*! \fn void SOPHYA::SphericalTransformServer::mapFromPM(int_4 nlmax, int_4 nmmax,
+					 SphericalMap<T>& mapq,
+					 SphericalMap<T>& mapu, 
+					 const Alm<T>& alme,
+					 const Alm<T>& almb) const
+
+synthesis of polarizations following formulae : 
+
+\f[
+P^+ = \sum_{m=-mmax}^{mmax} {b_m^+e^{im\varphi} }
+\f]
+\f[
+P^- = \sum_{m=-mmax}^{mmax} {b_m^-e^{im\varphi} }
+\f]
+
+computed by FFT (method fourierSynthesisFromB called by the present one)
+
+with :
+
+\f[
+b_m^+=-\sum_{l=|m|}^{lmax}{\,_{+}\lambda_l^m \left( a_{lm}^E+ia_{lm}^B \right) }
+\f]
+\f[
+b_m^-=-\sum_{l=|m|}^{lmax}{\,_{+}\lambda_l^m \left( a_{lm}^E-ia_{lm}^B \right) }
+\f]
+ */
+template<class T>
+void SphericalTransformServer<T>::mapFromPM(int_4 nlmax, int_4 nmmax,
+					 SphericalMap<T>& mapq,
+					 SphericalMap<T>& mapu, 
+					 const Alm<T>& alme,
+					 const Alm<T>& almb) const
+{
+  Bm<complex<T> > b_m_theta_p(nmmax);
+  Bm<complex<T> > b_m_theta_m(nmmax);
+  for (int_4 ith = 0; ith < mapq.NbThetaSlices();ith++)
+    {
+      int_4 nph;
+      r_8 phi0;
+      r_8 theta;
+      TVector<int_4> pixNumber; 
+      TVector<T> datan;
+      
+      mapq.GetThetaSlice(ith,theta,phi0, pixNumber,datan);
+      nph =  pixNumber.NElts();
+
+      //       -----------------------------------------------------
+      //	      for each theta, and each m, computes
+      //	      b(m,theta) = sum_over_l>m (lambda_l_m(theta) * a_l_m) 
+      //------------------------------------------------------
+
+      LambdaPMBuilder lpmb(theta,nlmax,nmmax);
+      int m;
+      for (m = 0; m <= nmmax; m++)
+	{
+	  r_8 lambda_p=0.;
+	  r_8 lambda_m=0.;
+	  lpmb.lam_pm(m, m, lambda_p, lambda_m);
+	  complex<T> im((T)0.,(T)1.);
+	  
+	  b_m_theta_p(m) =  (T)(lambda_p )* (-alme(m,m) - im * almb(m,m));
+	  b_m_theta_m(m) =  (T)(lambda_m) * (-alme(m,m) + im * almb(m,m));
+	  
+	  
+	  for (int l = m+1; l<= nlmax; l++)
+	    {
+	      lpmb.lam_pm(l, m, lambda_p, lambda_m);
+	      b_m_theta_p(m) +=  (T)(lambda_p)*(-alme(l,m)-im *almb(l,m));
+	      b_m_theta_m(m) +=  (T)(lambda_m)*(-alme(l,m)+im *almb(l,m));
+	    }
+	}
+      
+      //        obtains the negative m of b(m,theta) (= complex conjugate)
+      for (m=1;m<=nmmax;m++)
+	{
+	  b_m_theta_p(-m) = conj(b_m_theta_m(m));
+	  b_m_theta_m(-m) = conj(b_m_theta_p(m));
+	}
+
+      TVector<complex<T> > Tempp = fourierSynthesisFromB(b_m_theta_p,nph,phi0);  
+      TVector<complex<T> > Tempm = fourierSynthesisFromB(b_m_theta_m,nph,phi0); 
+
+      for (int i=0;i< nph;i++)
+	{
+	  	  mapq(pixNumber(i))=0.5*(Tempp(i)+Tempm(i)).real();
+	  	  mapu(pixNumber(i))=0.5*(Tempp(i)-Tempm(i)).imag();
+	}
+    }
+}
+
+
+  /*! \fn void SOPHYA::SphericalTransformServer::GenerateFromCl(SphericalMap<T>& sphq, 
+					      SphericalMap<T>& sphu, 
+					      int_4 pixelSizeIndex,
+					      const TVector<T>& Cle, 
+					      const TVector<T>& Clb, 
+					      const r_8 fwhm) const
+
+synthesis of a polarization  map from  power spectra electric-Cl and magnetic-Cl (Alm's are generated randomly, following a gaussian distribution). 
+  \param fwhm FWHM in arcmin for random generation of Alm's (eg. 5) 
+*/
+template<class T>
+void SphericalTransformServer<T>::GenerateFromCl(SphericalMap<T>& sphq, 
+					      SphericalMap<T>& sphu, 
+					      int_4 pixelSizeIndex,
+					      const TVector<T>& Cle, 
+					      const TVector<T>& Clb, 
+					      const r_8 fwhm) const
+{
+  if (Cle.NElts() != Clb.NElts())
+    {
+      cout << " SphericalTransformServer: les deux tableaux Cl n'ont pas la meme taille" << endl;
+      throw SzMismatchError("SphericalTransformServer::GenerateFromCl :  two Cl arrays have not same size");
+    }
+
+  //  Alm<T> a2lme,a2lmb;
+  //  almFromCl(a2lme, Cle, fwhm); 
+  //  almFromCl(a2lmb, Clb, fwhm); 
+  //  Alm<T> a2lme = almFromCl(Cle, fwhm);
+  // Alm<T> a2lmb = almFromCl(Clb, fwhm);
+  Alm<T> a2lme(Cle, fwhm);
+  Alm<T> a2lmb(Clb, fwhm);
+
+  GenerateFromAlm(sphq,sphu,pixelSizeIndex,a2lme,a2lmb); 
+}
+ /*! \fn void SOPHYA::SphericalTransformServer::GenerateFromCl(SphericalMap<T>& sph,
+						 int_4 pixelSizeIndex, 
+					      const TVector<T>& Cl, 
+						 const r_8 fwhm)  const
+
+synthesis of a temperature  map from  power spectrum Cl (Alm's are generated randomly, following a gaussian distribution). */
+template<class T>
+void SphericalTransformServer<T>::GenerateFromCl(SphericalMap<T>& sph,
+						 int_4 pixelSizeIndex, 
+					      const TVector<T>& Cl, 
+						 const r_8 fwhm)  const
+{
+
+  Alm<T> alm(Cl, fwhm);
+  GenerateFromAlm(sph,pixelSizeIndex, alm ); 
+}
+
+
+
+/*! \fn TVector<T>  SOPHYA::SphericalTransformServer::DecomposeToCl(SphericalMap<T>& sph, int_4 nlmax, r_8 cos_theta_cut, int iterationOrder) const
+
+\return power spectrum from analysis of a temperature map. THE MAP CAN BE MODIFIED (if iterationOrder >0) 
+
+     \param<nlmax> : maximum value of the l index
+
+     \param<cos_theta_cut> : cosinus of the symmetric cut EULER angle theta : cos_theta_cut=0 means no cut ; cos_theta_cut=1 all the sphere is cut.
+
+\param<iterationOrder> : 1,2,3,4.... order of an iterative analysis. If iterationOrder is not null, the method works with SphereHEALPix but NOT WITH SphereThetaPhi maps !
+
+  */ 
+template <class T>
+TVector<T>  SphericalTransformServer<T>::DecomposeToCl(SphericalMap<T>& sph, int_4 nlmax, r_8 cos_theta_cut, int iterationOrder) const
+{
+  Alm<T> alm;
+  DecomposeToAlm( sph, alm, nlmax, cos_theta_cut, iterationOrder);
+  // power spectrum
+     return  alm.powerSpectrum();
+}
+
+
+/*! \fn TVector<T>  SOPHYA::SphericalTransformServer::DecomposeToCl(const SphericalMap<T>& sph, int_4 nlmax, r_8 cos_theta_cut) const
+
+\return power spectrum from analysis of a temperature map. 
+
+     \param<nlmax> : maximum value of the l index
+
+     \param<cos_theta_cut> : cosinus of the symmetric cut EULER angle theta : cos_theta_cut=0 means no cut ; cos_theta_cut=1 all the sphere is cut.
+
+
+  */ 
+
+
+template <class T>
+TVector<T>  SphericalTransformServer<T>::DecomposeToCl(const SphericalMap<T>& sph, int_4 nlmax, r_8 cos_theta_cut) const
+{
+  Alm<T> alm;
+  DecomposeToAlm( sph, alm, nlmax, cos_theta_cut);
+  // power spectrum
+     return  alm.powerSpectrum();
+}
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template SphericalTransformServer<r_8>
+#pragma define_template SphericalTransformServer<r_4>
+#endif
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class SphericalTransformServer<r_8>;
+template class SphericalTransformServer<r_4>;
+#endif
Index: /tags/V_Dec2002/SophyaLib/Samba/sphericaltransformserver.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/Samba/sphericaltransformserver.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Samba/sphericaltransformserver.h	(revision 2309)
@@ -0,0 +1,124 @@
+#ifndef SPHERICALTRANFORMSERVER_SEEN
+#define SPHERICALTRANFORMSERVER_SEEN
+
+#include "sphericalmap.h"
+#include "fftservintf.h"
+#include "fftpserver.h"
+#include "alm.h"
+#include "lambdaBuilder.h"
+
+
+namespace SOPHYA {
+
+
+template <class T>
+class SphericalTransformServer
+{
+
+ public:
+
+  SphericalTransformServer()  
+    {
+      fftIntfPtr_=new FFTPackServer;
+      fftIntfPtr_->setNormalize(false);
+    };
+  ~SphericalTransformServer(){ if (fftIntfPtr_!=NULL) delete fftIntfPtr_;};
+  
+ /*!
+ Set a fft server. The constructor sets a default fft server (fft-pack). So it is not necessary to call this method for a standard use.
+*/
+  void SetFFTServer(FFTServerInterface* srv=NULL) 
+    {
+      if (fftIntfPtr_!=NULL) delete fftIntfPtr_;
+      fftIntfPtr_=srv;
+      fftIntfPtr_->setNormalize(false);
+    }
+
+  void GenerateFromAlm( SphericalMap<T>& map, int_4 pixelSizeIndex, const Alm<T>& alm) const; 
+  void GenerateFromAlm(SphericalMap<T>& mapq, SphericalMap<T>& mapu, int_4 pixelSizeIndex, const Alm<T>& alme,    const Alm<T>& almb) const;
+
+  void GenerateFromCl(SphericalMap<T>& sph, int_4 pixelSizeIndex,
+		     const TVector<T>& Cl, const r_8 fwhm) const; 
+  void GenerateFromCl(SphericalMap<T>& sphq, SphericalMap<T>& sphu, 
+		     int_4 pixelSizeIndex,
+		     const TVector<T>& Cle, const TVector<T>& Clb, 
+		    const r_8 fwhm) const; 
+
+
+void DecomposeToAlm(SphericalMap<T>& map, Alm<T>& alm, int_4 nlmax, r_8 cos_theta_cut, int iterationOrder) const;
+void DecomposeToAlm(const SphericalMap<T>& map, Alm<T>& alm, int_4 nlmax, r_8 cos_theta_cut) const;
+
+void DecomposeToAlm(SphericalMap<T>& mapq,
+		    SphericalMap<T>& mapu,
+		    Alm<T>& alme,
+		    Alm<T>& almb,
+		    int_4 nlmax,
+		    r_8 cos_theta_cut, 
+		    int iterationOrder) const;
+void DecomposeToAlm(const SphericalMap<T>& mapq,
+		    const SphericalMap<T>& mapu,
+		    Alm<T>& alme,
+		    Alm<T>& almb,
+		    int_4 nlmax,
+		    r_8 cos_theta_cut) const;
+
+TVector<T>  DecomposeToCl(SphericalMap<T>& sph,  
+			   int_4 nlmax, r_8 cos_theta_cut, int iterationOrder) const;
+
+TVector<T>  DecomposeToCl(const SphericalMap<T>& sph,  
+			   int_4 nlmax, r_8 cos_theta_cut) const;
+
+
+ private:
+
+void carteVersAlm(const SphericalMap<T>& map, int_4 nlmax, r_8 cos_theta_cut, Alm<T>& alm) const;
+
+void carteVersAlm(const SphericalMap<T>& mapq,
+		  const SphericalMap<T>& mapu,
+		  Alm<T>& alme,
+		  Alm<T>& almb,
+		  int_4 nlmax,
+		  r_8 cos_theta_cut) const;
+
+
+TVector< complex<T> >  fourierSynthesisFromB(const Bm<complex<T> >& b_m,  
+				  int_4 nph, r_8 phi0) const;
+TVector<T>  RfourierSynthesisFromB(const Bm<complex<T> >& b_m,  
+				  int_4 nph, r_8 phi0) const;
+TVector< complex<T> > CFromFourierAnalysis(int_4 mmax, 
+				  const TVector<complex<T> > datain,
+				  r_8 phi0) const;
+  //  TVector< complex<T> > CFromFourierAnalysis(int_4 mmax, 
+  //			 const TVector<T> datain,  
+  //				  r_8 phi0) const;
+  void CFromFourierAnalysis(int_4 mmax, const TVector<T> datain,
+			    TVector< complex<T> >& dataout,
+			    r_8 phi0) const;
+
+  void almFromWX(int_4 nlmax, int_4 nmmax, r_8 phi0, 
+	       r_8 domega, r_8 theta, 
+	       const TVector<T>& dataq, const TVector<T>& datau,
+	       Alm<T>& alme, Alm<T>& almb) const;
+  void almFromPM(int_4 nph, int_4 nlmax, int_4 nmmax, 
+	       r_8 phi0, r_8 domega, r_8 theta, 
+	       const TVector<T>& dataq, const TVector<T>& datau,
+	       Alm<T>& alme, Alm<T>& almb) const;
+
+  void mapFromWX(int_4 nlmax, int_4 nmmax,
+	       SphericalMap<T>& mapq, SphericalMap<T>& mapu, 
+	       const Alm<T>& alme, const Alm<T>& almb) const;
+
+
+  void mapFromPM(int_4 nlmax, int_4 nmmax,
+	       SphericalMap<T>& mapq, SphericalMap<T>& mapu, 
+	       const Alm<T>& alme, const Alm<T>& almb) const;
+
+
+
+ FFTServerInterface* fftIntfPtr_;
+
+};
+} // Fin du namespace
+
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/Samba/tod.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/Samba/tod.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/Samba/tod.h	(revision 2309)
@@ -0,0 +1,56 @@
+// This may look like C code, but it is really -*- C++ -*-
+#ifndef TOD_H_SEEN
+#define TOD_H_SEEN
+
+#include "machdefs.h"
+#include "spherepos.h"
+#include "misstime.h"
+
+namespace SOPHYA {
+template<class T>
+class TOD 
+{
+public:
+		TOD(SphereCoordSys* cs = NULL)
+                    { if (cs) cs_ = cs; else cs = new SphereCoordSys; }
+  virtual 	~TOD()
+                    { if (cs_) delete cs_; }
+
+// Set/Change/Get the coordinate system
+  virtual void  SetCoordSys(SphereCoordSys* cs)
+                    { if (cs) { delete cs_;  cs_ = cs; } }
+  inline SphereCoordSys* GetCoordSys() const { return(cs_); }
+
+// Return the size / number of sample
+  virtual int_8 size() const = 0; 
+  inline  int_8 NbSample() const { return(size()); }
+
+// Start/End time
+  virtual MissionTime StartTime();
+  virtual MissionTime EndTime();
+
+// Sample time 
+  virtual const MissionTime& SampleTime(int k) const = 0;
+  virtual MissionTime& SampleTime(int k) = 0;
+
+// Time to sample number - return the closest sample to time t
+  virtual int_8 IndexFromTime(MissionTime const & t) const = 0;
+
+// Sample value
+  virtual const T& SampleValue(int_8 k) const = 0;
+  virtual T& SampleValue(int_8 k) = 0;
+  virtual const T& ValueAtTime(MissionTime const & t) const 
+		{ return SampleValue(IndexFromTime(t)); }
+
+// Sample direction
+  virtual const UnitVector& SamplePointing(int_8 k) const = 0;
+  virtual UnitVector& SamplePointing(int_8 k) = 0;
+// Pointing at time t
+  virtual const UnitVector& PointingAtTime(MissionTime const & t ) const 
+		{ return SamplePointing(IndexFromTime(t)); }
+
+};
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyMap/HEALPixUtils.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/HEALPixUtils.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/HEALPixUtils.cc	(revision 2309)
@@ -0,0 +1,687 @@
+// utilitaires de pixelisation HEALPix
+#include "HEALPixUtils.h"
+#include <iostream.h>
+#include <math.h>
+//#include <complex>
+#include "tvector.h"
+#include "smathconst.h"
+extern "C" 
+{
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+}
+
+using namespace SOPHYA;
+
+//////////////////////////////////////////////////////////////////////////
+//
+// ------------- Classe PIXELS_XY -----------------------
+//
+class PIXELS_XY
+{
+
+public :
+
+static PIXELS_XY& instance();
+
+NDataBlock<int_4> pix2x_;
+NDataBlock<int_4> pix2y_;
+NDataBlock<int_4> x2pix_;
+NDataBlock<int_4> y2pix_;
+
+private :
+
+PIXELS_XY();
+void mk_pix2xy();
+void mk_xy2pix();
+};
+
+
+
+//*******************************************************************
+// Class PIXELS_XY 
+// Construction des tableaux necessaires a la traduction des indices RING en 
+// indices NESTED (ou l'inverse)
+//*******************************************************************
+
+PIXELS_XY::PIXELS_XY()
+{
+  pix2x_.ReSize(1024);
+  pix2x_.Reset();
+  pix2y_.ReSize(1024);
+  pix2y_.Reset();
+  x2pix_.ReSize(128);
+  x2pix_.Reset();
+  y2pix_.ReSize(128);
+  y2pix_.Reset();
+  mk_pix2xy(); 
+  mk_xy2pix(); 
+}
+
+// Instance unique de la classe PIXELS_XY 
+static PIXELS_XY * _singleton = NULL;
+
+PIXELS_XY& PIXELS_XY::instance()
+{
+  if (_singleton == NULL) _singleton = new PIXELS_XY ;
+  return (*_singleton);
+}
+
+void PIXELS_XY::mk_pix2xy() 
+{
+  /*
+    ==================================================
+    subroutine mk_pix2xy
+    ==================================================
+    c     constructs the array giving x and y in the face from pixel number
+    c     for the nested (quad-cube like) ordering of pixels
+    c
+    c     the bits corresponding to x and y are interleaved in the pixel number
+    c     one breaks up the pixel number by even and odd bits
+    ==================================================
+  */
+  // tranlated from FORTRAN (Gorski) to C, by B. Revenu, revised Guy Le Meur
+  //  (16/12/98)
+
+  int kpix, jpix, IX, IY, IP, ID;
+  
+  for(kpix = 0; kpix < 1024; kpix++) 
+    {
+      jpix = kpix;
+      IX = 0;
+      IY = 0;
+      IP = 1 ;//  ! bit position (in x and y)
+      while( jpix!=0 )
+	{ // ! go through all the bits
+	  ID=jpix%2;//  ! bit value (in kpix), goes in ix
+	  jpix = jpix/2;
+	  IX = ID*IP+IX;
+      
+	  ID=jpix%2;//  ! bit value (in kpix), goes in iy
+	  jpix = jpix/2;
+	  IY = ID*IP+IY;
+     
+	  IP = 2*IP;//        ! next bit (in x and y)
+	}
+      pix2x_(kpix) = IX;//     ! in 0,31
+      pix2y_(kpix) = IY;//     ! in 0,31
+    }
+}
+
+void PIXELS_XY::mk_xy2pix() 
+{
+  /*
+    =================================================
+    subroutine mk_xy2pix
+    =================================================
+    c     sets the array giving the number of the pixel lying in (x,y)
+    c     x and y are in {1,128}
+    c     the pixel number is in {0,128**2-1}
+    c
+    c     if  i-1 = sum_p=0  b_p * 2^p
+    c     then ix = sum_p=0  b_p * 4^p
+    c          iy = 2*ix
+    c     ix + iy in {0, 128**2 -1}
+    =================================================
+  */
+  // tranlated from FORTRAN (Gorski) to C, by B. Revenu, revised Guy Le Meur
+  //  (16/12/98)
+
+  int K,IP,I,J,ID;
+  for(I = 1; I <= 128; I++) 
+    {
+      J  = I-1;//            !pixel numbers
+      K  = 0;//
+      IP = 1;//
+      truc : if( J==0 ) 
+	{
+	  x2pix_(I-1) = K;
+	  y2pix_(I-1) = 2*K;
+	}
+      else 
+	{
+	  ID = J%2;  //RzModFloor (int)fmod(J,2);
+	  J  = J/2;
+	  K  = IP*ID+K;
+	  IP = IP*4;
+	  goto truc;
+	}
+    }     
+}
+
+
+
+int_4 HEALPix::nest2ring(int_4 nside, int_4 ipnest) 
+{
+  /*
+    ====================================================
+    subroutine nest2ring(nside, ipnest, ipring)
+    ====================================================
+    c     conversion from NESTED to RING pixel number
+    ====================================================
+  */
+  // tranlated from FORTRAN (Gorski) to C, by B. Revenu, revised Guy Le Meur
+  //  (16/12/98)
+  
+    const PIXELS_XY& PXY= PIXELS_XY::instance();
+
+  int npix, npface, face_num, ncap, n_before;
+  int ipf, ip_low, ip_trunc, ip_med, ip_hi;
+  int ix, iy, jrt, jr, nr, jpt, jp, kshift, nl4;
+  int ns_max=8192;
+  int jrll[12]={2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4};
+  int jpll[12]={1, 3, 5, 7, 0, 2, 4, 6, 1, 3, 5, 7};
+  
+  if(  nside<1 ||  nside>ns_max ) {
+    char buff[64];
+    sprintf(buff,"HEALPix::nest2ring nside(=%d) out of range ", nside);
+    throw RangeCheckError(PExcLongMessage(buff));
+  }
+  npix = 12 *  nside* nside;
+  if( ipnest<0 || ipnest>npix-1 ) {
+    char buff[64];
+    sprintf(buff,"HEALPix::nest2ring ipnest(=%d) out of range ", ipnest);
+    throw RangeCheckError(PExcLongMessage(buff));
+  }
+
+  ncap  = 2* nside*( nside-1);// ! number of points in the North Polar cap
+  nl4   = 4* nside;
+  
+  //c     finds the face, and the number in the face
+  npface =  nside* nside;
+  //cccccc      ip = ipnest - 1         ! in {0,npix-1}
+  
+  face_num = ipnest/npface;//  ! face number in {0,11}
+  ipf =ipnest%npface;//  ! pixel number in the face {0,npface-1}
+  //c     finds the x,y on the face (starting from the lowest corner)
+  //c     from the pixel number
+  ip_low=ipf%1024;                //   ! content of the last 10 bits
+  ip_trunc =   ipf/1024;         //    ! truncation of the last 10 bits
+  ip_med=ip_trunc%1024;         //     ! content of the next 10 bits
+  ip_hi  =     ip_trunc/1024;//   ! content of the high weight 10 bits
+  
+  ix = 1024*PXY.pix2x_(ip_hi)+32*PXY.pix2x_(ip_med)+PXY.pix2x_(ip_low);
+  iy = 1024*PXY.pix2y_(ip_hi)+32*PXY.pix2y_(ip_med)+PXY.pix2y_(ip_low);
+  
+  //c     transforms this in (horizontal, vertical) coordinates
+  jrt = ix + iy;//  ! 'vertical' in {0,2*(nside-1)}
+  jpt = ix - iy;//  ! 'horizontal' in {-nside+1,nside-1}
+  
+  //c     computes the z coordinate on the sphere
+  //      jr =  jrll[face_num+1]*nside - jrt - 1;//   ! ring number in {1,4*nside-1}
+  jr =  jrll[face_num]*nside - jrt - 1;
+  nr = nside;//                  ! equatorial region (the most frequent)
+  n_before = ncap + nl4 * (jr - nside);
+  kshift=(jr - nside)%2;
+  if( jr<nside ) {//then     ! north pole region
+    nr = jr;
+    n_before = 2 * nr * (nr - 1);
+    kshift = 0;
+  }
+  else if( jr>3*nside ) {//then ! south pole region
+    nr = nl4 - jr;
+    n_before = npix - 2 * (nr + 1) * nr;
+    kshift = 0;
+  }
+  
+  //c     computes the phi coordinate on the sphere, in [0,2Pi]
+  jp = (jpll[face_num]*nr + jpt + 1 + kshift)/2;//  ! 'phi' number in the ring in {1,4*nr}
+  
+  if( jp>nl4 ) jp = jp - nl4;
+  if( jp<1 )   jp = jp + nl4;
+  
+  //RzDel int aux=n_before + jp - 1;
+  return (n_before + jp - 1);// ! in {0, npix-1}
+}
+
+
+int_4 HEALPix::ring2nest(int_4 nside, int_4 ipring)  
+{
+  /*
+    ==================================================
+    subroutine ring2nest(nside, ipring, ipnest)
+    ==================================================
+    c     conversion from RING to NESTED pixel number
+    ==================================================
+  */
+  // tranlated from FORTRAN (Gorski) to C, by B. Revenu, revised Guy Le Meur
+  //  (16/12/98)
+
+    const PIXELS_XY& PXY= PIXELS_XY::instance();
+
+  double fihip, hip;
+  int npix, nl2, nl4, ncap, ip, iphi, ipt, ipring1;
+  int     kshift, face_num, nr;
+  int irn, ire, irm, irs, irt, ifm , ifp;
+  int ix, iy, ix_low, ix_hi, iy_low, iy_hi, ipf;
+  int ns_max(8192);
+  
+  // coordinate of the lowest corner of each face
+  int jrll[12]={2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4};// ! in unit of nside
+  int jpll[12]={1, 3, 5, 7, 0, 2, 4, 6, 1, 3, 5, 7};//! in unit of nside/2
+  
+  if( nside<1 || nside>ns_max ) {
+    char buff[64];
+    sprintf(buff,"HEALPix::ring2nest nside(=%d) out of range ", nside);
+    throw RangeCheckError(PExcLongMessage(buff));
+  }
+  npix = 12 * nside*nside;
+  if( ipring<0 || ipring>npix-1 ) {
+    char buff[64];
+    sprintf(buff,"HEALPix::ring2nest ipring(=%d) out of range ", ipring);
+    throw RangeCheckError(PExcLongMessage(buff));
+  }
+  
+  nl2 = 2*nside;
+  nl4 = 4*nside;
+  npix = 12*nside*nside;//      ! total number of points
+  ncap = 2*nside*(nside-1);// ! points in each polar cap, =0 for nside =1
+  ipring1 = ipring + 1;
+  
+  //c     finds the ring number, the position of the ring and the face number
+  if( ipring1<=ncap ) {//then
+    
+    hip   = ipring1/2.;
+    fihip = floor ( hip );
+    irn   = (int)floor( sqrt( hip - sqrt(fihip) ) ) + 1;// ! counted from North pole
+    iphi  = ipring1 - 2*irn*(irn - 1);
+    
+    kshift = 0;
+    nr = irn   ;//               ! 1/4 of the number of points on the current ring
+    face_num = (iphi-1) / irn;// ! in {0,3}
+  }
+  else if( ipring1<=nl2*(5*nside+1) ) {//then
+    
+    ip    = ipring1 - ncap - 1;
+    irn   = ip / nl4 + nside; //RzModFloor (int)floor( ip / nl4 ) + nside;   ! counted from North pole
+    iphi  = ip%nl4 + 1;  //RzModFloor (int)fmod(ip,nl4) + 1;
+    
+    kshift  = (irn+nside)%2; //RzModFloor (int)fmod(irn+nside,2);  ! 1 if irn+nside is odd, 0 otherwise
+    nr = nside;
+    ire =  irn - nside + 1;// ! in {1, 2*nside +1}
+    irm =  nl2 + 2 - ire;
+    ifm = (iphi - ire/2 + nside -1) / nside;// ! face boundary
+    ifp = (iphi - irm/2 + nside -1) / nside;
+    if( ifp==ifm ) {//then          ! faces 4 to 7
+      face_num = ifp%4+4; // RzModFloor (int)fmod(ifp,4) + 4;
+    }
+    else if( ifp + 1==ifm ) {//then ! (half-)faces 0 to 3
+      face_num = ifp;
+    }
+    else if( ifp - 1==ifm ) {//then ! (half-)faces 8 to 11
+      face_num = ifp + 7;
+    }
+  }
+  else {
+    
+    ip    = npix - ipring1 + 1;
+    hip   = ip/2.;
+    fihip = floor ( hip );
+    irs   = (int)floor( sqrt( hip - sqrt(fihip) ) ) + 1;//  ! counted from South pole
+    iphi  = 4*irs + 1 - (ip - 2*irs*(irs-1));
+    
+    kshift = 0;
+    nr = irs;
+    irn   = nl4 - irs;
+    face_num = (iphi-1) / irs + 8;// ! in {8,11}
+  }
+  
+  //c     finds the (x,y) on the face
+  irt =   irn  - jrll[face_num]*nside + 1;//       ! in {-nside+1,0}
+  ipt = 2*iphi - jpll[face_num]*nr - kshift - 1;// ! in {-nside+1,nside-1}
+
+
+  if( ipt>=nl2 ) ipt = ipt - 8*nside;// ! for the face #4
+  
+  ix =  (ipt - irt ) / 2;
+  iy = -(ipt + irt ) / 2;
+  
+  ix_low = ix%128; //RzModFloor (int)fmod(ix,128);
+  ix_hi  = ix/128;
+  iy_low = iy%128; //RzModFloor (int)fmod(iy,128); 
+  iy_hi  = iy/128;
+  ipf=(PXY.x2pix_(ix_hi)+PXY.y2pix_(iy_hi))*(128*128)+(PXY.x2pix_(ix_low)+PXY.y2pix_(iy_low));
+
+  return (ipf + face_num* nside *nside);//   ! in {0, 12*nside**2 - 1}
+}
+
+int_4 HEALPix::ang2pix_ring(int_4 nside, double theta, double phi)  
+{
+  /*
+    ==================================================
+    c     gives the pixel number ipix (RING) 
+    c     corresponding to angles theta and phi
+    c==================================================
+  */
+  // tranlated from FORTRAN (Gorski) to C, by B. Revenu, revised Guy Le Meur
+  //  (16/12/98)
+
+  int nl2, nl4, ncap, npix, jp, jm, ipix1;
+  double  z, za, tt, tp, tmp;
+  int ir, ip, kshift;
+
+  double piover2(Pi/2.);
+  double twopi(2.*Pi);
+  double z0(2./3.);
+  int ns_max(8192);
+
+  if( nside<1 || nside>ns_max ) {
+    char buff[64];
+    sprintf(buff,"HEALPix::ang2pix_ring nside(=%d) out of range ", nside);
+    throw RangeCheckError(PExcLongMessage(buff));
+  }
+
+  if( theta<0. || theta>Pi) {
+    char buff[64];
+    sprintf(buff,"HEALPix::ang2pix_ring theta(=%g) out of range ", theta);
+    throw RangeCheckError(PExcLongMessage(buff));
+  }
+
+  z = cos(theta);
+  za = fabs(z);
+  if( phi >= twopi)  phi = phi - twopi;
+  if (phi < 0.)     phi = phi + twopi;
+  tt = phi / piover2;//  ! in [0,4)
+
+  nl2 = 2*nside;
+  nl4 = 4*nside;
+  ncap  = nl2*(nside-1);// ! number of pixels in the north polar cap
+  npix  = 12*nside*nside;
+
+  if( za <= z0 ) {
+    
+    jp = (int)floor(nside*(0.5 + tt - z*0.75));// ! index of  ascending edge line 
+    jm = (int)floor(nside*(0.5 + tt + z*0.75));// ! index of descending edge line
+
+    ir = nside + 1 + jp - jm;// ! in {1,2n+1} (ring number counted from z=2/3)
+    kshift = 0;
+    //RzModFloor if (fmod(ir,2)==0.) kshift = 1; ! kshift=1 if ir even, 0 otherwise
+    if ((ir%2)==0) kshift = 1;// ! kshift=1 if ir even, 0 otherwise
+    
+    //RzModFloor ip = (int)floor( ( jp+jm - nside + kshift + 1 ) / 2 ) + 1; ! in {1,4n}
+    ip = ( jp+jm - nside + kshift + 1 )/2  + 1;  
+    if( ip>nl4 ) ip = ip - nl4;
+    
+    ipix1 = ncap + nl4*(ir-1) + ip ;
+  }
+  else {
+
+    tp = tt - floor(tt);//      !MOD(tt,1.d0)
+    tmp = sqrt( 3.*(1. - za) );
+
+    jp = (int)floor( nside * tp * tmp );// ! increasing edge line index
+    jm = (int)floor( nside * (1. - tp) * tmp );// ! decreasing edge line index
+
+    ir = jp + jm + 1;//        ! ring number counted from the closest pole
+    ip = (int)floor( tt * ir ) + 1;// ! in {1,4*ir}
+    if( ip>4*ir ) ip = ip - 4*ir;
+      
+    ipix1 = 2*ir*(ir-1) + ip;
+      if( z<=0. ) {
+	ipix1 = npix - 2*ir*(ir+1) + ip;
+      }
+  }
+    return (ipix1 - 1);// ! in {0, npix-1}
+}
+
+int_4 HEALPix::ang2pix_nest(int_4 nside, double theta, double phi) 
+{
+  /*
+    ==================================================
+    subroutine ang2pix_nest(nside, theta, phi, ipix)
+    ==================================================
+    c     gives the pixel number ipix (NESTED) 
+    c     corresponding to angles theta and phi
+    c
+    c     the computation is made to the highest resolution available (nside=8192)
+    c     and then degraded to that required (by integer division)
+    c     this doesn't cost more, and it makes sure 
+    c     that the treatement of round-off will be consistent 
+    c     for every resolution
+    ==================================================
+  */
+  // tranlated from FORTRAN (Gorski) to C, by B. Revenu, revised Guy Le Meur
+  //  (16/12/98)
+  
+    const PIXELS_XY& PXY= PIXELS_XY::instance();
+
+  double    z, za, z0, tt, tp, tmp;
+  int face_num,jp,jm;
+  int ifp, ifm;
+  int  ix, iy, ix_low, ix_hi, iy_low, iy_hi, ipf, ntt;
+  double piover2(Pi/2.), twopi(2.*Pi);
+  int ns_max(8192);
+  
+  if( nside<1 || nside>ns_max ) {
+    char buff[64];
+    sprintf(buff,"HEALPix:::ang2pix_nest nside(=%d) out of range ", nside);
+    throw RangeCheckError(PExcLongMessage(buff));
+  }
+  if( theta<0 || theta>Pi ) {
+    char buff[64];
+    sprintf(buff,"HEALPix:::ang2pix_nest theta(=%g) out of range ", theta);
+    throw RangeCheckError(PExcLongMessage(buff));
+  }
+  z  = cos(theta);
+  za = fabs(z);
+  z0 = 2./3.;
+  if( phi>=twopi ) phi = phi - twopi;
+  if( phi<0. )    phi = phi + twopi;
+  tt = phi / piover2;// ! in [0,4[
+  if( za<=z0 ) { // then ! equatorial region
+    
+    //(the index of edge lines increase when the longitude=phi goes up)
+    jp = (int)floor(ns_max*(0.5 + tt - z*0.75));// !  ascending edge line index
+    jm = (int)floor(ns_max*(0.5 + tt + z*0.75));// ! descending edge line index
+    
+    //c        finds the face
+    ifp = jp / ns_max;//  ! in {0,4}
+    ifm = jm / ns_max;
+    if( ifp==ifm ) face_num = (ifp%4)+4; //RzModFloor (int)fmod(ifp,4) + 4; then  ! faces 4 to 7
+    else if( ifp<ifm ) face_num = ifp%4; //RzModFloor (int)fmod(ifp,4); (half-)faces 0 to 3
+    else face_num = (ifm%4) + 8; //RzModFloor (int)fmod(ifm,4) + 8;! (half-)faces 8 to 11
+    
+    ix = jm%ns_max; //RzModFloor (int)fmod(jm, ns_max);
+    iy = ns_max - (jp%ns_max) - 1;//RzModFloor  ns_max - (int)fmod(jp, ns_max) - 1;
+  }
+  else { //! polar region, za > 2/3
+    
+    ntt = (int)floor(tt);
+    if( ntt>=4 ) ntt = 3;
+    tp = tt - ntt;
+    tmp = sqrt( 3.*(1. - za) );//  ! in ]0,1]
+    
+    //(the index of edge lines increase when distance from the closest pole goes up)
+    jp = (int)floor(ns_max*tp*tmp); // ! line going toward the pole as phi increases
+    jm = (int)floor(ns_max*(1.-tp)*tmp); // ! that one goes away of the closest pole
+    jp = (int)min(ns_max-1, jp);// ! for points too close to the boundary
+    jm = (int)min(ns_max-1, jm);
+    
+    // finds the face and pixel's (x,y)
+    if( z>=0 ) {
+      face_num = ntt;//  ! in {0,3}
+      ix = ns_max - jm - 1;
+      iy = ns_max - jp - 1;
+    }
+    else {
+      face_num = ntt + 8;// ! in {8,11}
+      ix =  jp;
+      iy =  jm;
+    }
+  }
+  
+  ix_low = (ix%128); //RzModFloor (int)fmod(ix,128);
+  ix_hi  =     ix/128;
+  iy_low = (iy%128); //RzModFloor ((int)fmod(iy,128);
+  iy_hi  =     iy/128;
+  ipf= (PXY.x2pix_(ix_hi)+PXY.y2pix_(iy_hi))*(128*128)+(PXY.x2pix_(ix_low)+PXY.y2pix_(iy_low));
+  //  ipf = ipf / pow(ns_max/nside,2.);//  ! in {0, nside**2 - 1}
+  //  return ( ipf + face_num*pow(nside,2));//    ! in {0, 12*nside**2 - 1}
+  // $CHECK$  Reza 25/10/99 , pow remplace par *
+  ipf = ipf / ((ns_max/nside)*(ns_max/nside));
+  return (ipf + face_num*nside*nside);
+}
+
+void HEALPix::pix2ang_ring(int_4 nside,int_4 ipix,double& theta,double& phi)  
+{
+  /*
+    ===================================================
+    c     gives theta and phi corresponding to pixel ipix (RING) 
+    c     for a parameter nside
+    ===================================================
+  */
+  // tranlated from FORTRAN (Gorski) to C, by B. Revenu, revised Guy Le Meur
+  //  (16/12/98)
+  
+  int nl2, nl4, npix, ncap, iring, iphi, ip, ipix1;
+  double  fact1, fact2, fodd, hip, fihip;
+  
+  int ns_max(8192);
+  
+  if( nside<1 || nside>ns_max ) {
+    char buff[64];
+    sprintf(buff,"HEALPix::pix2ang_ring nside(=%d) out of range ", nside);
+    throw RangeCheckError(PExcLongMessage(buff));
+  }
+  npix = 12*nside*nside;      // ! total number of points
+  if( ipix<0 || ipix>npix-1 ) {
+    char buff[64];
+    sprintf(buff,"HEALPix::pix2ang_ring ipix(=%d) out of range ", ipix);
+    throw RangeCheckError(PExcLongMessage(buff));
+  }
+  
+  ipix1 = ipix + 1; // in {1, npix}
+  nl2 = 2*nside;
+  nl4 = 4*nside;
+  ncap = 2*nside*(nside-1);// ! points in each polar cap, =0 for nside =1
+  fact1 = 1.5*nside;
+  fact2 = 3.0*nside*nside;
+  
+  if( ipix1 <= ncap ) {  //! North Polar cap -------------
+    
+    hip   = ipix1/2.;
+    fihip = floor(hip);
+    iring = (int)floor( sqrt( hip - sqrt(fihip) ) ) + 1;// ! counted from North pole
+    iphi  = ipix1 - 2*iring*(iring - 1);
+    
+    theta = acos( 1. - iring*iring / fact2 );
+    phi   = ((double)iphi - 0.5) * Pi/(2.*iring);
+    //    cout << theta << " " << phi << endl;
+  }
+  else if( ipix1 <= nl2*(5*nside+1) ) {//then ! Equatorial region ------
+    
+    ip    = ipix1 - ncap - 1;
+    iring = ip/nl4  + nside; //RzModFloor (int)floor( ip / nl4 ) + nside; ! counted from North pole
+    iphi  = ip%nl4 + 1;
+    
+    fodd  = 0.5 * (1 + (iring+nside)%2 );//  ! 1 if iring+nside is odd, 1/2 otherwise
+    theta = acos( (nl2 - iring) / fact1 );
+    phi   = ((double)iphi - fodd) * Pi /(2.*nside);
+  }
+  else {//! South Polar cap -----------------------------------
+    
+    ip    = npix - ipix1 + 1;
+    hip   = ip/2.;
+    fihip = floor(hip);
+    iring = (int)floor( sqrt( hip - sqrt(fihip) ) ) + 1;//     ! counted from South pole
+    iphi  = (int)(4.*iring + 1 - (ip - 2.*iring*(iring-1)));
+    
+    theta = acos( -1. + iring*iring / fact2 );
+    phi   = ((double)iphi - 0.5) * Pi/(2.*iring);
+    //    cout << theta << " " << phi << endl;
+  }
+}
+
+void HEALPix::pix2ang_nest(int_4 nside,int_4 ipix,double& theta,double& phi)  
+{
+  /*
+    ==================================================
+    subroutine pix2ang_nest(nside, ipix, theta, phi)
+    ==================================================
+    c     gives theta and phi corresponding to pixel ipix (NESTED) 
+    c     for a parameter nside
+    ==================================================
+  */
+  // tranlated from FORTRAN (Gorski) to C, by B. Revenu, revised Guy Le Meur
+  //  (16/12/98)
+
+    const PIXELS_XY& PXY= PIXELS_XY::instance();
+    
+  int npix, npface, face_num;
+  int ipf, ip_low, ip_trunc, ip_med, ip_hi;
+  int ix, iy, jrt, jr, nr, jpt, jp, kshift, nl4;
+  double z, fn, fact1, fact2;
+  double piover2(Pi/2.);
+  int ns_max(8192);
+          
+  // ! coordinate of the lowest corner of each face
+  int jrll[12]={2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4};//! in unit of nside
+  int jpll[12]={1, 3, 5, 7, 0, 2, 4, 6, 1, 3, 5, 7};// ! in unit of nside/2
+  
+  if( nside<1 || nside>ns_max ) {
+    char buff[64];
+    sprintf(buff,"HEALPix::pix2ang_nest nside(=%d) out of range ", nside);
+    throw RangeCheckError(PExcLongMessage(buff));
+  }
+  npix = 12 * nside*nside;
+  if( ipix<0 || ipix>npix-1 ) {
+    char buff[64];
+    sprintf(buff,"HEALPix::pix2ang_nest ipix(=%d) out of range ", ipix);
+    throw RangeCheckError(PExcLongMessage(buff));
+  }
+  
+  fn = 1.*nside;
+  fact1 = 1./(3.*fn*fn);
+  fact2 = 2./(3.*fn);
+  nl4   = 4*nside;
+
+  //c     finds the face, and the number in the face
+  npface = nside*nside;
+  
+  face_num = ipix/npface;//  ! face number in {0,11}
+  ipf = ipix%npface; //RzModFloor (int)fmod(ipix,npface);  ! pixel number in the face {0,npface-1}
+  
+  //c     finds the x,y on the face (starting from the lowest corner)
+  //c     from the pixel number
+  ip_low = ipf%1024; //RzModFloor  (int)fmod(ipf,1024);      ! content of the last 10 bits
+  ip_trunc =   ipf/1024 ;//       ! truncation of the last 10 bits
+  ip_med = ip_trunc%1024;  //RzModFloor  (int)fmod(ip_trunc,1024);  ! content of the next 10 bits
+  ip_hi  =     ip_trunc/1024   ;//! content of the high weight 10 bits
+  
+  ix = 1024*PXY.pix2x_(ip_hi)+32*PXY.pix2x_(ip_med)+PXY.pix2x_(ip_low);
+  iy = 1024*PXY.pix2y_(ip_hi)+32*PXY.pix2y_(ip_med)+PXY.pix2y_(ip_low);
+  
+  //c     transforms this in (horizontal, vertical) coordinates
+  jrt = ix + iy;//  ! 'vertical' in {0,2*(nside-1)}
+  jpt = ix - iy;//  ! 'horizontal' in {-nside+1,nside-1}
+  
+  //c     computes the z coordinate on the sphere
+  //      jr =  jrll[face_num+1]*nside - jrt - 1;//   ! ring number in {1,4*nside-1}
+  jr =  jrll[face_num]*nside - jrt - 1;
+  nr = nside;//                  ! equatorial region (the most frequent)
+  z  = (2*nside-jr)*fact2;
+  kshift = (jr-nside) % 2; //RzModFloor (int)fmod(jr - nside, 2);
+  if( jr<nside ) { //then     ! north pole region
+    nr = jr;
+    z = 1. - nr*nr*fact1;
+    kshift = 0;
+  }
+  else {
+    if( jr>3*nside ) {// then ! south pole region
+      nr = nl4 - jr;
+      z = - 1. + nr*nr*fact1;
+      kshift = 0;
+    }
+  }
+  theta = acos(z);
+  
+  //c     computes the phi coordinate on the sphere, in [0,2Pi]
+  //      jp = (jpll[face_num+1]*nr + jpt + 1 + kshift)/2;//  ! 'phi' number in the ring in {1,4*nr}
+  jp = (jpll[face_num]*nr + jpt + 1 + kshift)/2;
+  if( jp>nl4 ) jp = jp - nl4;
+  if( jp<1 )   jp = jp + nl4;
+  phi = (jp - (kshift+1)*0.5) * (piover2 / nr);
+}
+
+ 
Index: /tags/V_Dec2002/SophyaLib/SkyMap/HEALPixUtils.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/HEALPixUtils.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/HEALPixUtils.h	(revision 2309)
@@ -0,0 +1,29 @@
+#ifndef HEALPixUtils_SEEN
+#define HEALPixUtils_SEEN
+#include "machdefs.h"
+#include "ndatablock.h"
+
+// utilitaires de pixelisation HEALPix
+
+
+namespace SOPHYA {
+
+  // Utility class to compute index to/from angle conversion in HEALPix 
+  // spherical map pixelisation
+
+class HEALPix {
+public :
+  static int_4  nest2ring(int_4 nside,int_4 ipnest) ;
+  static int_4  ring2nest(int_4 nside,int_4 ipring) ;
+
+  static int_4  ang2pix_ring(int_4 nside,double theta,double phi) ;
+  static int_4  ang2pix_nest(int_4 nside,double theta,double phi) ;
+  static void   pix2ang_ring(int_4 nside,int_4 ipix,double& theta,double& phi) ;
+  static void   pix2ang_nest(int_4 nside,int_4 ipix,double& theta,double& phi) ;
+};
+
+
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyMap/Makefile
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/Makefile	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/Makefile	(revision 2309)
@@ -0,0 +1,184 @@
+include ../Mgr/Makefile.h
+ 
+all: $(LIB)libSkyMap.a
+clean:
+	rm -f $(OBJ)HEALPixUtils.o $(OBJ)fiolocalmap.o $(OBJ)fiospherehealpix.o $(OBJ)fiospherethetaphi.o $(OBJ)localmap.o $(OBJ)longlat.o $(OBJ)mapoperation.o $(OBJ)skymapinit.o $(OBJ)spherehealpix.o $(OBJ)spherepos.o $(OBJ)spherethetaphi.o $(OBJ)unitvector.o $(OBJ)utilgeom.o $(OBJ)vector3d.o
+	rm -f $(LIB)libSkyMap.a
+$(LIB)libSkyMap.a : $(OBJ)HEALPixUtils.o $(OBJ)fiolocalmap.o $(OBJ)fiospherehealpix.o $(OBJ)fiospherethetaphi.o $(OBJ)localmap.o $(OBJ)longlat.o $(OBJ)mapoperation.o $(OBJ)skymapinit.o $(OBJ)spherehealpix.o $(OBJ)spherepos.o $(OBJ)spherethetaphi.o $(OBJ)unitvector.o $(OBJ)utilgeom.o $(OBJ)vector3d.o
+	$(ARCXX) $(ARCXXFLAGS) $@ $($(ARARGS))
+ifeq ($(CXX),cxx)
+	$(CXX) $? $(CPPFLAGS) $(CXXFLAGS) -o $(OBJ)xx.x -Hf
+endif 
+ 
+$(OBJ)HEALPixUtils.o: HEALPixUtils.cc HEALPixUtils.h \
+ $(INC)machdefs.h \
+ $(INC)ndatablock.h \
+ $(INC)anydataobj.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)utilarr.h \
+ $(INC)smathconst.h
+$(OBJ)fiolocalmap.o: fiolocalmap.cc fiolocalmap.h sphericalmap.h \
+ $(INC)smathconst.h \
+ $(INC)machdefs.h pixelmap.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h spherepos.h unitvector.h \
+ vector3d.h longlat.h utilgeom.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h localmap.h \
+ $(INC)fiondblock.h
+$(OBJ)fiospherehealpix.o: fiospherehealpix.cc fiospherehealpix.h \
+ sphericalmap.h $(INC)smathconst.h \
+ $(INC)machdefs.h pixelmap.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h spherepos.h unitvector.h \
+ vector3d.h longlat.h utilgeom.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h spherehealpix.h \
+ HEALPixUtils.h $(INC)fiondblock.h
+$(OBJ)fiospherethetaphi.o: fiospherethetaphi.cc fiospherethetaphi.h \
+ sphericalmap.h $(INC)smathconst.h \
+ $(INC)machdefs.h pixelmap.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h spherepos.h unitvector.h \
+ vector3d.h longlat.h utilgeom.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h spherethetaphi.h \
+ $(INC)fiondblock.h
+$(OBJ)localmap.o: localmap.cc localmap.h pixelmap.h \
+ $(INC)ppersist.h \
+ $(INC)machdefs.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h spherepos.h unitvector.h \
+ vector3d.h longlat.h utilgeom.h sphericalmap.h \
+ $(INC)smathconst.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)piocmplx.h \
+ $(INC)fiondblock.h
+$(OBJ)longlat.o: longlat.cc longlat.h \
+ $(INC)machdefs.h utilgeom.h
+$(OBJ)mapoperation.o: mapoperation.cc \
+ $(INC)machdefs.h mapoperation.h \
+ $(INC)ndatablock.h \
+ $(INC)anydataobj.h pixelmap.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)mutyv.h spherepos.h unitvector.h \
+ vector3d.h longlat.h utilgeom.h
+$(OBJ)skymapinit.o: skymapinit.cc $(INC)machdefs.h \
+ skymapinit.h $(INC)sophyainit.h \
+ spherethetaphi.h sphericalmap.h \
+ $(INC)smathconst.h pixelmap.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h spherepos.h unitvector.h \
+ vector3d.h longlat.h utilgeom.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h fiospherehealpix.h \
+ spherehealpix.h HEALPixUtils.h fiospherethetaphi.h fiolocalmap.h \
+ localmap.h
+$(OBJ)spherehealpix.o: spherehealpix.cc \
+ $(INC)machdefs.h \
+ $(INC)pexceptions.h \
+ $(INC)fiondblock.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)anydataobj.h spherehealpix.h \
+ sphericalmap.h $(INC)smathconst.h pixelmap.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)mutyv.h spherepos.h unitvector.h \
+ vector3d.h longlat.h utilgeom.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)utilarr.h HEALPixUtils.h \
+ $(INC)strutil.h
+$(OBJ)spherepos.o: spherepos.cc spherepos.h \
+ $(INC)machdefs.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h unitvector.h vector3d.h \
+ longlat.h utilgeom.h $(INC)anydataobj.h
+$(OBJ)spherethetaphi.o: spherethetaphi.cc spherethetaphi.h sphericalmap.h \
+ $(INC)smathconst.h \
+ $(INC)machdefs.h pixelmap.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h spherepos.h unitvector.h \
+ vector3d.h longlat.h utilgeom.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)piocmplx.h \
+ $(INC)fiondblock.h
+$(OBJ)unitvector.o: unitvector.cc unitvector.h vector3d.h longlat.h \
+ $(INC)machdefs.h utilgeom.h
+$(OBJ)utilgeom.o: utilgeom.cc utilgeom.h
+$(OBJ)vector3d.o: vector3d.cc $(INC)machdefs.h \
+ $(INC)pexceptions.h vector3d.h longlat.h \
+ utilgeom.h
Index: /tags/V_Dec2002/SophyaLib/SkyMap/Makefile.am
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/Makefile.am	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/Makefile.am	(revision 2309)
@@ -0,0 +1,9 @@
+lib_LIBRARIES = libSkyMap.a
+
+libSkyMap_a_SOURCES = \
+HEALPixUtils.cc      fiospherethetaphi.cc  mapoperation.cc   spherepos.cc       utilgeom.cc \
+fiolocalmap.cc       localmap.cc           skymapinit.cc     spherethetaphi.cc  vector3d.cc \
+fiospherehealpix.cc  longlat.cc            spherehealpix.cc  unitvector.cc
+
+
+DEFS = -I.. -I../include
Index: /tags/V_Dec2002/SophyaLib/SkyMap/fiolocalmap.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/fiolocalmap.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/fiolocalmap.cc	(revision 2309)
@@ -0,0 +1,233 @@
+// G. Le Meur 04/2000
+
+#include "fiolocalmap.h"
+#include "fioarr.h"
+#include "pexceptions.h"
+#include "fiondblock.h"
+#include "datatype.h"
+#include <typeinfo>
+
+//*******************************************************************
+// class FIO_LocalMap<T>
+//  Les objets delegues pour la gestion de persistance 
+//*******************************************************************
+
+//++
+template <class T>
+FIO_LocalMap<T>::FIO_LocalMap()
+//
+//--
+{
+  dobj= new LocalMap<T>;
+  ownobj= true;
+}
+//++
+template <class T>
+FIO_LocalMap<T>::FIO_LocalMap(string const& filename)
+//
+//--
+{
+  dobj= new LocalMap<T>;
+  ownobj= true;
+  Read(filename);
+}
+
+//++
+template <class T>
+FIO_LocalMap<T>::FIO_LocalMap(const LocalMap<T>& obj)
+//
+//--
+{
+  dobj= new LocalMap<T>(obj, true);
+  ownobj= true;
+}
+
+template <class T>
+FIO_LocalMap<T>::FIO_LocalMap(LocalMap<T>* obj)
+{
+  dobj= obj;
+  ownobj= false;
+}
+
+//++
+template <class T>
+FIO_LocalMap<T>::~FIO_LocalMap()
+//
+//--
+{
+  if (ownobj && dobj) delete dobj;
+}
+
+//++
+template <class T>
+AnyDataObj* FIO_LocalMap<T>::DataObj()
+//
+//--
+{
+  return(dobj);
+}
+
+//++
+template <class T>
+void FIO_LocalMap<T>::SetDataObj(AnyDataObj & o)
+//
+//--
+{
+  LocalMap<T> * po = dynamic_cast< LocalMap<T> * >(&o);
+  if (po == NULL) {
+    char buff[160];
+    sprintf(buff,"FIO_LocalMap<%s>::SetDataObj(%s) - Object type  error ! ",
+	    DataTypeInfo<T>::getTypeName().c_str(), typeid(o).name());
+    throw TypeMismatchExc(PExcLongMessage(buff));    
+  }
+  if (ownobj && dobj) delete dobj;
+  dobj = po; ownobj = false;
+} 
+
+//++
+template <class T>
+void FIO_LocalMap<T>::ReadSelf(PInPersist& is)
+//
+//--
+{
+
+  if(dobj == NULL) 
+    {
+      dobj= new LocalMap<T>;
+      ownobj= true;
+    }
+
+  // Pour savoir s'il y avait un DVList Info associe
+  char strg[256];
+  is.GetLine(strg, 255);
+  bool hadinfo= false;
+  if(strncmp(strg+strlen(strg)-7, "HasInfo", 7) == 0)  hadinfo= true;
+  if(hadinfo) 
+    {    // Lecture eventuelle du DVList Info
+      is >> dobj->Info(); 
+    }
+
+  int_4 nSzX;
+  is.GetI4(nSzX);
+  //  dobj->setSize_x(nSzX);
+
+  int_4 nSzY;
+  is.GetI4(nSzY);
+  //  dobj->setSize_y(nSzY);
+
+  // int_4 nPix;
+  // is.GetI4(nPix);
+  //  dobj->setNbPixels(nPix);
+  dobj->ReSize(nSzX, nSzY); 
+  string ss("local mapping is done");
+  string sso;
+  is.GetStr(sso);
+  if(sso == ss)
+    {
+      //   cout<<" ReadSelf:: local mapping"<<endl;
+
+      double angleX, angleY;
+      is.GetR8(angleX);
+      is.GetR8(angleY);
+      dobj->SetSize(angleX, angleY);
+
+
+      int_4 x0, y0;
+      double theta, phi, angle;
+      is.GetR8(theta);
+      is.GetR8(phi);
+      is.GetI4(x0);
+      is.GetI4(y0);
+      is.GetR8(angle);
+      dobj->SetOrigin(theta, phi, x0, y0, angle);
+
+    }
+  
+// On lit le DataBlock;
+      //  FIO_NDataBlock<T> fio_nd(&dobj->DataBlock());
+// On lit la matrice;
+  FIO_TArray<T> fio_nd(&dobj->Matrix());
+  fio_nd.Read(is);
+}
+
+//++
+template <class T>
+void FIO_LocalMap<T>::WriteSelf(POutPersist& os) const
+//
+//--
+{
+  if(dobj == NULL) 
+    {
+      cout << " FIO_LocalMap::WriteSelf:: dobj= null " << endl;
+      return;
+    }
+
+  char strg[256];
+  int_4 nSzX= dobj->Size_x();
+  int_4 nSzY= dobj->Size_y();
+  int_4 nPix= dobj->NbPixels();
+ 
+  if(dobj->ptrInfo()) 
+    {
+      sprintf(strg,"LocalMap: NPixX=%6d  NPixY=%9d HasInfo",nSzX,nSzY);
+      os.PutLine(strg);
+      os << dobj->Info();
+    }
+  else 
+    { 
+      sprintf(strg,"LocalMap: NPixX=%6d  NPixY=%9d ",nSzX,nSzY);
+      os.PutLine(strg);  
+    }
+
+  os.PutI4(nSzX);
+  os.PutI4(nSzY);
+  //  os.PutI4(nPix);
+
+  if(dobj->LocalMap_isDone())
+    {
+      string ss("local mapping is done");
+      os.PutStr(ss);
+
+      double angleX, angleY;
+      dobj->Aperture(angleX, angleY);
+      os.PutR8(angleX);
+      os.PutR8(angleY);
+
+
+      int_4 x0, y0;
+      double theta, phi, angle;
+      dobj->Origin(theta, phi, x0, y0, angle);
+      os.PutR8(theta);
+      os.PutR8(phi);
+      os.PutI4(x0);
+      os.PutI4(y0);
+      os.PutR8(angle);
+
+    }
+  else
+    {
+      string ss("no local mapping");
+      os.PutStr(ss);
+    }
+
+// On ecrit le dataBlock 
+      //  FIO_NDataBlock<T> fio_nd(&dobj->DataBlock());
+// On ecrit la matrice 
+  FIO_TArray<T> fio_nd(&dobj->Matrix());
+  fio_nd.Write(os);
+}
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template FIO_LocalMap<int_4>
+#pragma define_template FIO_LocalMap<r_4>
+#pragma define_template FIO_LocalMap<r_8>
+#pragma define_template FIO_LocalMap< complex<r_4> >
+#pragma define_template FIO_LocalMap< complex<r_8> >
+#endif
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class FIO_LocalMap<int_4>;
+template class FIO_LocalMap<r_4>;
+template class FIO_LocalMap<r_8>;
+template class FIO_LocalMap< complex<r_4> >;
+template class FIO_LocalMap< complex<r_8> >;
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyMap/fiolocalmap.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/fiolocalmap.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/fiolocalmap.h	(revision 2309)
@@ -0,0 +1,59 @@
+// G. Le Meur 04/2000
+
+#ifndef FIOLOCALMAP_SEEN
+#define FIOLOCALMAP_SEEN
+#include "sphericalmap.h"
+#include "localmap.h"
+#include "tvector.h"
+#include "ndatablock.h"
+
+#include "anydataobj.h"
+#include "ppersist.h"
+
+
+//
+// ------------- Classes pour la gestion de persistance --
+//
+
+namespace SOPHYA {
+
+//!    Delegated objects for persitance management
+template <class T>
+class FIO_LocalMap : public PPersist  
+{
+
+public:
+
+FIO_LocalMap();
+FIO_LocalMap(string const & filename); 
+FIO_LocalMap(const LocalMap<T>& obj);
+FIO_LocalMap(LocalMap<T>* obj);
+virtual ~FIO_LocalMap();
+virtual AnyDataObj* DataObj();
+virtual void        SetDataObj(AnyDataObj & o);
+inline operator LocalMap<T>() { return(*dobj); }
+
+protected :
+
+virtual void ReadSelf(PInPersist&);           
+virtual void WriteSelf(POutPersist&) const;  
+LocalMap<T>* dobj;
+bool ownobj;
+};
+
+/*! \ingroup SkyMap \fn operator<<(POutPersist&,LocalMap<T>&)
+  \brief Write LocalMap \b obj into POutPersist stream \b os */
+template <class T>
+inline POutPersist& operator << (POutPersist& os, LocalMap<T> & obj)
+{ FIO_LocalMap<T> fio(&obj);  fio.Write(os);  return(os); }
+
+/*! \ingroup SkyMap \fn operator>>(PInPersist&,LocalMap<T>&)
+  \brief Read LocalMap \b obj from PInPersist stream \b os */
+template <class T>
+inline PInPersist& operator >> (PInPersist& is, LocalMap<T> & obj)
+{ FIO_LocalMap<T> fio(&obj);  fio.Read(is);  return(is); }
+
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyMap/fiospherehealpix.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/fiospherehealpix.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/fiospherehealpix.cc	(revision 2309)
@@ -0,0 +1,177 @@
+// G. Le Meur 04/2000
+
+#include "fiospherehealpix.h"
+#include "pexceptions.h"
+#include "fiondblock.h"
+#include "datatype.h"
+#include <typeinfo>
+
+//*******************************************************************
+// Class FIO_SphereHEALPix<T>
+//  Les objets delegues pour la gestion de persistance 
+//*******************************************************************
+
+template <class T>
+FIO_SphereHEALPix<T>::FIO_SphereHEALPix()
+{
+  dobj_= new SphereHEALPix<T>;
+  ownobj= true;
+}
+
+template <class T>
+FIO_SphereHEALPix<T>::FIO_SphereHEALPix(string const& filename)
+{
+  dobj_= new SphereHEALPix<T>;
+  ownobj= true;
+  Read(filename);
+}
+
+template <class T>
+FIO_SphereHEALPix<T>::FIO_SphereHEALPix(const SphereHEALPix<T>& obj)
+{
+  dobj_= new SphereHEALPix<T>(obj, true);
+  ownobj= true;
+}
+
+template <class T>
+FIO_SphereHEALPix<T>::FIO_SphereHEALPix(SphereHEALPix<T>* obj)
+{
+  dobj_= obj;
+  ownobj= false;
+}
+
+template <class T>
+FIO_SphereHEALPix<T>::~FIO_SphereHEALPix()
+{
+  if (ownobj && dobj_) delete dobj_;
+}
+
+template <class T>
+AnyDataObj* FIO_SphereHEALPix<T>::DataObj()
+{
+  return(dobj_);
+}
+
+template <class T>
+void FIO_SphereHEALPix<T>::SetDataObj(AnyDataObj & o)
+{
+  SphereHEALPix<T> * po = dynamic_cast< SphereHEALPix<T> * >(&o);
+  if (po == NULL) { 
+    char buff[160];
+    sprintf(buff,"FIO_SphereHEALPix<%s>::SetDataObj(%s) - Object type error ! ",
+	    DataTypeInfo<T>::getTypeName().c_str(), typeid(o).name());
+    throw TypeMismatchExc(PExcLongMessage(buff));
+  }
+  if (ownobj && dobj_) delete dobj_;
+  dobj_ = po; ownobj = false;
+} 
+
+template <class T>
+void FIO_SphereHEALPix<T>::ReadSelf(PInPersist& is)
+{
+
+  if(dobj_ == NULL) 
+    {
+      dobj_= new SphereHEALPix<T>;
+      ownobj= true;      
+    }
+
+// On lit les 3 premiers uint_8
+uint_8 itab[3];
+is.Get(itab, 3);
+// Let's Read the SphereCoordSys object  -- ATTENTIOn - $CHECK$
+  FIO_SphereCoordSys fio_scs( dobj_->GetCoordSys());
+  fio_scs.Read(is);
+  // Pour savoir s'il y avait un DVList Infodobj->Info();  associe
+  char strg[256];
+  is.GetLine(strg, 255);
+  bool hadinfo= false;
+  if(strncmp(strg+strlen(strg)-7, "HasInfo", 7) == 0)  hadinfo= true;
+  if(hadinfo) 
+    {    // Lecture eventuelle du DVList Info
+      is >> dobj_->Info(); 
+    }
+
+  int_4 nSide;
+  is.GetI4(nSide);
+  int_4 nPix;
+  is.GetI4(nPix);
+  double Omega;
+  is.GetR8(Omega);
+  dobj_->setParameters(nSide,nPix, Omega);
+
+// On lit les DataBlocks;
+  FIO_NDataBlock<T> fio_nd(&dobj_->pixels_);
+  fio_nd.Read(is);
+  FIO_NDataBlock<int_4> fio_ndi1(&dobj_->sliceBeginIndex_);
+  fio_ndi1.Read(is);
+  FIO_NDataBlock<int_4> fio_ndi2(&dobj_->sliceLenght_);
+  fio_ndi2.Read(is);
+
+
+}
+ 
+template <class T>
+void FIO_SphereHEALPix<T>::WriteSelf(POutPersist& os) const
+{
+  if(dobj_ == NULL) 
+    {
+      cout << " WriteSelf:: dobj_= null " << endl;
+      return;
+    }
+
+//  On ecrit 3 uint_8 
+//  0 : Numero de version,  1 : Size index,  2  reserve a l
+uint_8 itab[3];
+itab[0] = 1;
+itab[1] = dobj_->SizeIndex();
+itab[2] = 0;
+os.Put(itab, 3);
+// Let's write the SphereCoordSys object
+  FIO_SphereCoordSys fio_scs( dobj_->GetCoordSys());
+  fio_scs.Write(os);
+
+  char strg[256];
+  int_4 nSide= dobj_->SizeIndex();
+  int_4 nPix = dobj_->NbPixels();
+ 
+  if(dobj_->ptrInfo()) 
+    {
+      sprintf(strg,"SphereHEALPix: NSide=%6d  NPix=%9d HasInfo",nSide,nPix);
+      os.PutLine(strg);
+      os << dobj_->Info();
+    }
+  else 
+    { 
+      sprintf(strg,"SphereHEALPix: NSide=%6d  NPix=%9d ",nSide,nPix);
+      os.PutLine(strg);  
+    }
+
+  os.PutI4(nSide);
+  os.PutI4(nPix);
+  os.PutR8(dobj_->PixSolAngle());
+// On ecrit les dataBlocks 
+  FIO_NDataBlock<T> fio_nd(&dobj_->pixels_);
+  fio_nd.Write(os);
+  FIO_NDataBlock<int_4> fio_ndi1(&dobj_->sliceBeginIndex_);
+  fio_ndi1.Write(os);
+  FIO_NDataBlock<int_4> fio_ndi2(&dobj_->sliceLenght_);
+  fio_ndi2.Write(os);
+}
+
+//*******************************************************************
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template FIO_SphereHEALPix<int_4>
+#pragma define_template FIO_SphereHEALPix<r_8>
+#pragma define_template FIO_SphereHEALPix<r_4>
+#pragma define_template FIO_SphereHEALPix< complex<r_4> >
+#pragma define_template FIO_SphereHEALPix< complex<r_8> >
+#endif
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class FIO_SphereHEALPix<int_4>;
+template class FIO_SphereHEALPix<r_8>;
+template class FIO_SphereHEALPix<r_4>;
+template class FIO_SphereHEALPix< complex<r_4> >;
+template class FIO_SphereHEALPix< complex<r_8> >;
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyMap/fiospherehealpix.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/fiospherehealpix.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/fiospherehealpix.h	(revision 2309)
@@ -0,0 +1,57 @@
+// G. Le Meur 04/2000
+
+#ifndef FIOSPHEREHEALPIX_SEEN
+#define FIOSPHEREHEALPIX_SEEN
+#include "sphericalmap.h"
+#include "tvector.h"
+#include "ndatablock.h"
+#include "spherehealpix.h"
+
+#include "anydataobj.h"
+#include "ppersist.h"
+
+
+//
+// ------------- Classes pour la gestion de persistance --
+//
+
+namespace SOPHYA {
+
+
+template <class T>
+class FIO_SphereHEALPix : public PPersist  
+{
+public:
+
+FIO_SphereHEALPix();
+FIO_SphereHEALPix(string const & filename); 
+FIO_SphereHEALPix(const SphereHEALPix<T>& obj);
+FIO_SphereHEALPix(SphereHEALPix<T>* obj);
+virtual ~FIO_SphereHEALPix();
+virtual AnyDataObj* DataObj();
+virtual void SetDataObj(AnyDataObj & o);
+inline operator SphereHEALPix<T>() { return(*dobj_); }
+
+protected :
+
+virtual void ReadSelf(PInPersist&);           
+virtual void WriteSelf(POutPersist&) const;  
+SphereHEALPix<T>* dobj_;
+bool ownobj;
+};
+
+/*! \ingroup SkyMap \fn operator<<(POutPersist&,SphereHEALPix<T>&)
+  \brief Write SphereHEALPix \b obj into POutPersist stream \b os */
+template <class T>
+inline POutPersist& operator << (POutPersist& os, SphereHEALPix<T> & obj)
+{ FIO_SphereHEALPix<T> fio(&obj);  fio.Write(os);  return(os); }
+
+/*! \ingroup SkyMap \fn operator>>(PInPersist&,SphereHEALPix<T>&)
+  \brief Read SphereHEALPix \b obj from PInPersist stream \b os */
+template <class T>
+inline PInPersist& operator >> (PInPersist& is, SphereHEALPix<T> & obj)
+{ FIO_SphereHEALPix<T> fio(&obj);  fio.Read(is);  return(is); }
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyMap/fiospherethetaphi.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/fiospherethetaphi.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/fiospherethetaphi.cc	(revision 2309)
@@ -0,0 +1,195 @@
+// G. Le Meur 04/2000
+
+#include "fiospherethetaphi.h"
+#include "pexceptions.h"
+#include "fiondblock.h"
+#include "datatype.h"
+#include <typeinfo>
+
+///////////////////////////////////////////////////////////
+// --------------------------------------------------------
+//   Les objets delegues pour la gestion de persistance 
+// --------------------------------------------------------
+//////////////////////////////////////////////////////////
+
+template <class T>
+FIO_SphereThetaPhi<T>::FIO_SphereThetaPhi()
+{
+  dobj= new SphereThetaPhi<T>;
+  ownobj= true;
+}
+
+template <class T>
+FIO_SphereThetaPhi<T>::FIO_SphereThetaPhi(string const& filename)
+{
+  dobj= new SphereThetaPhi<T>;
+  ownobj= true;
+  Read(filename);
+}
+
+template <class T>
+FIO_SphereThetaPhi<T>::FIO_SphereThetaPhi(const SphereThetaPhi<T>& obj)
+{
+  dobj= new SphereThetaPhi<T>(obj, true);
+  ownobj= true;
+}
+
+template <class T>
+FIO_SphereThetaPhi<T>::FIO_SphereThetaPhi(SphereThetaPhi<T>* obj)
+{
+  dobj= obj;
+  ownobj= false;
+}
+
+template <class T>
+FIO_SphereThetaPhi<T>::~FIO_SphereThetaPhi()
+{
+  if (ownobj && dobj) delete dobj;
+}
+
+template <class T>
+AnyDataObj* FIO_SphereThetaPhi<T>::DataObj()
+{
+  return(dobj);
+}
+
+
+template <class T>
+void FIO_SphereThetaPhi<T>::SetDataObj(AnyDataObj & o)
+{
+  SphereThetaPhi<T> * po = dynamic_cast< SphereThetaPhi<T> * >(&o);
+  if (po == NULL) {
+    char buff[160];
+    sprintf(buff,"FIO_SphereThetaPhi<%s>::SetDataObj(%s) - Object type  error ! ",
+	    DataTypeInfo<T>::getTypeName().c_str(), typeid(o).name());
+    throw TypeMismatchExc(PExcLongMessage(buff));    
+  }
+
+  if (ownobj && dobj) delete dobj;
+  dobj = po; ownobj = false;
+} 
+
+template <class T>
+void FIO_SphereThetaPhi<T>::ReadSelf(PInPersist& is)
+{
+
+  if(dobj == NULL) 
+    {
+      dobj= new SphereThetaPhi<T>;
+      ownobj= true;      
+    }
+
+  // On lit les 3 premiers uint_8
+  uint_8 itab[3];
+  is.Get(itab, 3);
+// Let's Read the SphereCoordSys object  -- ATTENTIOn - $CHECK$
+  FIO_SphereCoordSys fio_scs( dobj->GetCoordSys());
+  fio_scs.Read(is);
+
+  // Pour savoir s'il y avait un DVList Info associe
+  char strg[256];
+  is.GetLine(strg, 255);
+  bool hadinfo= false;
+  if(strncmp(strg+strlen(strg)-7, "HasInfo", 7) == 0)  hadinfo= true;
+  if(hadinfo) 
+    {    // Lecture eventuelle du DVList Info
+      is >> dobj->Info(); 
+    }
+
+  int_4 mNTheta;
+  is.GetI4(mNTheta);  
+  int_4 mNPix;
+  is.GetI4(mNPix);
+  double mOmeg;
+  is.GetR8(mOmeg);
+  dobj->setParameters( mNTheta, mNPix, mOmeg); 
+  
+  //  FIO_NDataBlock<int_4> fio_nd_nphi( &dobj->NPhi_);	
+  //  fio_nd_nphi.Read(is);
+  //  FIO_NDataBlock<int_4> fio_nd_Tnphi(&dobj->TNphi_);
+  //  fio_nd_Tnphi.Read(is);
+  //  FIO_NDataBlock<r_8> fio_nd_Theta( &dobj->Theta_);
+  //  fio_nd_Theta.Read(is);
+  //  FIO_NDataBlock<T> fio_nd(&dobj->pixels_);
+  //  fio_nd.Read(is);
+
+  //  Reza 30/8/2000 , - Methode de lecture plus facile  
+
+  is >> dobj->NPhi_ ;    
+  is >> dobj->TNphi_ ;   
+  is >> dobj->Theta_;
+  is >> dobj->pixels_;
+}
+
+template <class T>
+void FIO_SphereThetaPhi<T>::WriteSelf(POutPersist& os) const
+{
+
+  if(dobj == NULL) 
+    {
+      cout << " WriteSelf:: dobj= null " << endl;
+      return;
+    }
+
+//  On ecrit 3 uint_8 
+//  0 : Numero de version,  1 : Size index,  2  reserve a l
+uint_8 itab[3];
+itab[0] = 1;
+itab[1] = dobj->SizeIndex();
+itab[2] = 0;
+os.Put(itab, 3);
+// Let's write the SphereCoordSys object
+  FIO_SphereCoordSys fio_scs( dobj->GetCoordSys());
+  fio_scs.Write(os);
+  
+  char strg[256];
+  int_4 mNTheta= dobj->SizeIndex();
+  int_4 mNPix  = dobj->NbPixels();
+ 
+  if(dobj->ptrInfo()) 
+    {
+      sprintf(strg,"SphereThetaPhi: NSlices=%6d  NPix=%9d HasInfo",mNTheta,mNPix);
+      os.PutLine(strg);
+      os << dobj->Info();
+    }
+  else 
+    { 
+      sprintf(strg,"SphereThetaPhi: NSlices=%6d  NPix=%9d ",mNTheta,mNPix);
+      os.PutLine(strg);  
+    }
+
+  os.PutI4(mNTheta);  
+  os.PutI4(mNPix);
+  os.PutR8(dobj->PixSolAngle());
+  
+  //  FIO_NDataBlock<int_4> fio_nd_nphi(&dobj->NPhi_);	
+  //  fio_nd_nphi.Write(os);
+  //  FIO_NDataBlock<int_4> fio_nd_Tnphi(&dobj->TNphi_);
+  //  fio_nd_Tnphi.Write(os);
+  //  FIO_NDataBlock<r_8> fio_nd_Theta(&dobj->Theta_);
+  //  fio_nd_Theta.Write(os);
+  //  FIO_NDataBlock<T> fio_nd(&dobj->pixels_);
+  //  fio_nd.Write(os);
+
+  //  Reza 30/8/2000 , - Methode d'ecriture plus facile  
+
+  os << dobj->NPhi_;
+  os << dobj->TNphi_;
+  os << dobj->Theta_;
+  os << dobj->pixels_;
+}
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template FIO_SphereThetaPhi<int_4>
+#pragma define_template FIO_SphereThetaPhi<r_8>
+#pragma define_template FIO_SphereThetaPhi<r_4>
+#pragma define_template FIO_SphereThetaPhi< complex<r_4> >
+#pragma define_template FIO_SphereThetaPhi< complex<r_8> >
+#endif
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class FIO_SphereThetaPhi<int_4>;
+template class FIO_SphereThetaPhi<r_8>;
+template class FIO_SphereThetaPhi<r_4>;
+template class FIO_SphereThetaPhi< complex<r_4> >;
+template class FIO_SphereThetaPhi< complex<r_8> >;
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyMap/fiospherethetaphi.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/fiospherethetaphi.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/fiospherethetaphi.h	(revision 2309)
@@ -0,0 +1,59 @@
+// G. Le Meur 04/2000
+
+
+
+#ifndef FIOSPHERETHETAPHI_SEEN
+#define FIOSPHERETHETAPHI_SEEN
+#include "sphericalmap.h"
+#include "tvector.h"
+#include "ndatablock.h"
+#include "spherethetaphi.h"
+
+#include "anydataobj.h"
+#include "ppersist.h"
+
+
+//
+// ------------- Classes pour la gestion de persistance --
+//
+
+namespace SOPHYA {
+
+template <class T>
+class FIO_SphereThetaPhi : public PPersist  
+{
+public:
+
+FIO_SphereThetaPhi();
+FIO_SphereThetaPhi(string const & filename); 
+FIO_SphereThetaPhi(const SphereThetaPhi<T>& obj);
+FIO_SphereThetaPhi(SphereThetaPhi<T>* obj);
+virtual ~FIO_SphereThetaPhi();
+virtual AnyDataObj* DataObj();
+void SetDataObj(AnyDataObj & o);
+inline operator SphereThetaPhi<T>() { return(*dobj); }
+
+protected :
+
+virtual void ReadSelf(PInPersist&);           
+virtual void WriteSelf(POutPersist&) const;  
+SphereThetaPhi<T>* dobj;
+bool ownobj;
+};
+
+/*! \ingroup SkyMap \fn operator<<(POutPersist&,SphereThetaPhi<T>&)
+  \brief Write SphereThetaPhi \b obj into POutPersist stream \b os */
+template <class T>
+inline POutPersist& operator << (POutPersist& os, SphereThetaPhi<T> & obj)
+{ FIO_SphereThetaPhi<T> fio(&obj);  fio.Write(os);  return(os); }
+
+/*! \ingroup SkyMap \fn operator>>(PInPersist&,SphereThetaPhi<T>&)
+  \brief Read SphereThetaPhi \b obj from PInPersist stream \b os */
+template <class T>
+inline PInPersist& operator >> (PInPersist& is, SphereThetaPhi<T> & obj)
+{ FIO_SphereThetaPhi<T> fio(&obj);  fio.Read(is);  return(is); }
+
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyMap/healpix.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/healpix.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/healpix.h	(revision 2309)
@@ -0,0 +1,13 @@
+// This may look like C code, but it is really -*- C++ -*-
+//       To make life easier  - R. Ansari 04/2000
+
+#ifndef HEALPix_H_SEEN
+#define HEALPix_H_SEEN
+
+#include "spherehealpix.h"
+
+#define SphereGorski SphereHEALPix
+#define SphereHealpix SphereHEALPix
+
+#endif
+
Index: /tags/V_Dec2002/SophyaLib/SkyMap/localmap.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/localmap.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/localmap.cc	(revision 2309)
@@ -0,0 +1,967 @@
+#include "localmap.h"
+#include "smathconst.h"
+#include <complex>
+#include "piocmplx.h"
+#include "fiondblock.h"
+
+#include <string.h>
+#include <iostream.h>
+#include "timing.h"
+
+
+/*!
+  \class SOPHYA::LocalMap
+  \ingroup SkyMap
+  A local map is a 2 dimensional matrix, with ny rows and nx columns.
+  The local map has a spatial origin with spherical coordinates (theta0, phi0), mapped to pixel(x0, y0). Default value of (x0, y0) is middle of the map, center of pixel(nx/2, ny/2).
+
+ Each pixel(ip, it) is defined by its "phi-like" index ip (column 
+ index in the matrix) and its "theta-like" index it (row index in 
+ the matrix). Index ip is associated with x-axis in a map-coordinate 
+ system ; index it is associated with y-axis in the same map-coordinate system.
+  
+    The map is supposed to lie in a plan tangent to the celestial sphere 
+    at its origin, with spherical coordinates (theta0, phi0), whose pixel 
+    numbers  are (x0,y0) in the local map as indicated above. The aperture of the map is defined by two values of angles, angleX and angleY, covered respectively by all the pixels in x direction and all the pixels in y direction.
+
+    Each pixel has angleX/nx and angleY/ny, as angle extensions. So, in
+    map-coordinate system the pixel (i,j) has following coordinates : 
+
+    x = (i-x0)*angleX/nx
+ 
+    y = (j-y0)*angleY/ny 
+    
+    (angles in radians)
+
+    The projection (method : ProjectionToSphere() ) of the map onto a 
+    sphere is made by the following procedure : 
+
+    the sphere is supposed to have radius=1. The map is 
+    considered to be tangent to the sphere, at a point with (theta0, phi0)
+    spherical coodinates. A reference coordinate system (plane-coordinate
+    system) , is chosen with respect to the plane of the map  with reference axes : 
+
+    x-axis : vector tangent to a parallel at (theta0, phi0) on the sphere
+    (components in "3-dim cartesian system : -sin(phi0) ; cos(phi0) ; 0)
+
+    z-axis : vector-radius with 3-dim cartesian cordinates : 
+             sin(theta0)*cos(phi0) ; sin(theta0*sin(phi0) ; cos(theta0)
+
+    y-axis : z-axis^x-axis : tangent to the meridian at (theta0, phi0)
+
+
+    note that the map-coordinate system may be rotated with respect to
+    plane-coordinate system (parameter "angle" below).
+    
+    the projection of a map pixel is defined as the intersection of 
+    the vector-radius, from sphere center to the pixel defined by
+    his coordinates  in the plane-coordinate system (computed from x,y 
+    above, with eventual rotation), with the sphere.
+
+   In order to make an instance of this class  available, the user must either use the standard constructor LocalMap() (as well as the "full" constructor LocalMap() ) or use the "partial" constructor LocalMap() followed by call to SetSize() and SetOrigin() (for fixing links between the map and the celestial sphere.
+
+Example : 
+
+\verbatim 
+  LocalMap<r_4>    lcm(300, 600, 10.,20., 90.,0.); // full cstr.
+\endverbatim
+
+defining a local map 300X600 pixels, representing a sphere portion of angular apertures 10 degres x 20 degres, with map center located on the equator, is equivalent to :
+
+\verbatim 
+  LocalMap<r_4>    lcm(300, 600); // partial cstr.
+  lcm.SetSize(10., 20.);
+  lcm.SetOrigin(90., 0.);
+\endverbatim
+
+as well as : 
+
+
+\verbatim 
+  LocalMap<r_4>    lcm(300, 600, 10.,20., 90.,0., 0, 0); // full cstr.
+\endverbatim
+
+(same map, but with origin of coordinates at pixel (0,0) instead of (150, 300) as it was implicit above) 
+
+is equivalent to : 
+
+\verbatim 
+  LocalMap<r_4>    lcm(300, 600); 
+  lcm.SetSize(10., 20.);
+lcm.SetOrigin(90., 0., 0,0);
+\endverbatim
+
+
+*/
+template<class T>
+LocalMap<T>::LocalMap() :  pixels_()
+{
+  InitNul();
+}
+
+//! partial constructor of the local map
+/*! \fn void SOPHYA::LocalMap::LocalMap(int_4 nx, int_4 ny)
+  \param nx : number of pixels in x direction
+  \param ny : number of pixels in y direction
+
+must be followed by calls to the methods  SetSize() and SetOrigin() in order the object become usable
+
+ */
+template<class T>
+LocalMap<T>::LocalMap(int_4 nx, int_4 ny)  
+{
+  InitNul();
+  ReSize(nx, ny);
+  //  nSzX_ = nx;
+  //  nSzY_ = ny;
+  //  nPix_= nx*ny;
+  //  pixels_.ReSize(ny,nx);
+}
+
+//! full constructor of the local map
+/*! \fn void SOPHYA::LocalMap:::LocalMap(int_4 nx, int_4 ny, double angleX,double angleY, double theta0,double phi0,int_4 x0,int_4 y0,double angle)
+  \param nx : number of pixels in x direction
+  \param ny : number of pixels in y direction
+  \param angleX : total angle aperture in x direction (degrees)
+  \param angleY : total angle aperture in y direction (degrees)
+  \param theta0,phi0 : spherical coordinates of reference point at which 
+                       the map is considered to be tangent to the sphere 
+  \param x0, y0 : coordinates (in pixels) of the reference point just defined
+  \param angle : angle (degrees) of the rotation between x-axis of 
+                 map-coordinate system) and the tangent to parallel on 
+                 the sphere (default : 0.).
+ */
+template<class T>
+LocalMap<T>::LocalMap(int_4 nx, int_4 ny, double angleX,double angleY, double theta0,double phi0,int_4 x0,int_4 y0,double angle)  
+{
+  InitNul();
+  //  nSzX_ = nx;
+  // nSzY_ = ny;
+  // nPix_= nx*ny;
+  // pixels_.ReSize(ny,nx);
+  ReSize(nx, ny);
+  SetSize(angleX, angleY);
+  SetOrigin(theta0, phi0, x0, y0, angle);
+}
+
+// void SOPHYA::LocalMap::LocalMap(int_4 nx, int_4 ny, double angleX,double angleY, double theta0,double phi0, double angle)
+
+//! standard constructor of the local map
+/*! \fn void SOPHYA::LocalMap::LocalMap(int_4 nx, int_4 ny, double angleX,double angleY, double theta0,double phi0, double angle)
+  \param nx : number of pixels in x direction
+  \param ny : number of pixels in y direction
+  \param angleX : total angle aperture in x direction (degrees)
+  \param angleY : total angle aperture in y direction (degrees)
+  \param theta0,phi0 : spherical coordinates of reference point at which 
+                       the map is considered to be tangent to the sphere 
+  \param angle : angle (degrees) of the rotation between x-axis of 
+                 map-coordinate system) and the tangent to parallel on 
+                 the sphere (default : 0.).
+ */
+template<class T>
+LocalMap<T>::LocalMap(int_4 nx, int_4 ny, double angleX,double angleY, double theta0,double phi0, double angle) 
+{
+  InitNul();
+  //  nSzX_ = nx;
+  //  nSzY_ = ny;
+  // nPix_= nx*ny;
+  //  pixels_.ReSize(ny,nx);
+  ReSize(nx, ny);
+  SetSize(angleX, angleY);
+  SetOrigin(theta0, phi0, angle);
+}
+
+//! copy constructor 
+/*! \fn void SOPHYA::LocalMap::LocalMap(const LocalMap<T>& lm, bool share)
+  \param share : if true, share data. If false copy data
+ */
+template<class T>
+LocalMap<T>::LocalMap(const LocalMap<T>& lm, bool share)
+  : pixels_(lm.pixels_, share)
+{
+
+  if(lm.mInfo_) mInfo_= new DVList(*lm.mInfo_);
+  recopierVariablesSimples(lm);
+}
+
+//! copy constructor 
+/*! \fn void SOPHYA::LocalMap::LocalMap(const LocalMap<T>& lm)
+  \warning datas are \b SHARED with \b lm.
+  \sa TMatrix::TMatrix(const TMatrix<T>&)
+*/
+template<class T>
+LocalMap<T>::LocalMap(const LocalMap<T>& lm)
+  : pixels_(lm.pixels_)
+
+{
+
+  if(lm.mInfo_) mInfo_= new DVList(*lm.mInfo_);
+  recopierVariablesSimples(lm);
+}
+
+//! destructor
+/*! \fn void SOPHYA::LocalMap::~LocalMap()
+ 
+ */ 
+template<class T>
+LocalMap<T>::~LocalMap() {;}
+
+
+
+/*!  \fn void SOPHYA::LocalMap::ReSize(int_4 nx, int_4 ny) 
+
+  Resize storage area for pixels 
+\param nx 
+\param ny  new pixel numbers
+*/
+template<class T>
+void LocalMap<T>::ReSize(int_4 nx, int_4 ny) 
+{
+    // angles par pixel,  en radians 
+  deltaPhi_   *=  nSzX_/nx;   
+  deltaTheta_ *=  nSzY_/ny;
+
+  nSzX_ = nx;
+  nSzY_ = ny;
+  nPix_= nx*ny;
+  pixels_.ReSize(ny,nx);
+  pixelSized_ = true;
+}
+
+////////////////////////// methodes de copie/share
+
+template<class T>
+void LocalMap<T>::CloneOrShare(const LocalMap<T>& a)
+{
+      recopierVariablesSimples(a);     
+      pixels_.CloneOrShare(a.pixels_);
+      if (mInfo_) {delete mInfo_; mInfo_ = NULL;}
+      if (a.mInfo_) mInfo_ = new DVList(*(a.mInfo_));
+}
+template<class T>
+void LocalMap<T>::Share(const LocalMap<T>& a)
+{
+      recopierVariablesSimples(a);     
+      pixels_.Share(a.pixels_);
+      if (mInfo_) {delete mInfo_; mInfo_ = NULL;}
+      if (a.mInfo_) mInfo_ = new DVList(*(a.mInfo_));
+}
+
+template<class T>
+LocalMap<T>& LocalMap<T>::CopyElt(const LocalMap<T>& a)
+{
+  if (NbPixels() < 1) 
+    throw RangeCheckError("LocalMap<T>::CopyElt(const LocalMap<T>& )  - Not Allocated Array ! ");
+  if (NbPixels() != a.NbPixels()) 
+    throw(SzMismatchError("LocalMap<T>::CopyElt(const LocalMap<T>&) SizeMismatch")) ;
+      recopierVariablesSimples(a);     
+  int k;
+  pixels_ = a.pixels_;
+  return(*this);
+
+}
+
+template<class T>
+LocalMap<T>& LocalMap<T>::Set(const LocalMap<T>& a)
+   {
+  if (this != &a) 
+    { 
+      if (a.NbPixels() < 1) 
+	throw RangeCheckError("LocalMap<T>::Set(a ) - Array a not allocated ! ");
+      if (NbPixels() < 1) CloneOrShare(a);
+      else CopyElt(a);
+      if (mInfo_) delete mInfo_;
+      mInfo_ = NULL;
+      if (a.mInfo_) mInfo_ = new DVList(*(a.mInfo_));
+    }
+  return(*this);
+   }
+
+
+/*! \fn int_4 SOPHYA::LocalMap::NbPixels() const
+
+   \return number of pixels 
+*/
+template<class T>
+int_4 LocalMap<T>::NbPixels() const
+{
+  return(nPix_);
+}
+
+/*! \fn T& SOPHYA::LocalMap::PixVal(int_4 k)
+
+   \return value of pixel with index k 
+*/
+template<class T>
+T& LocalMap<T>::PixVal(int_4 k)
+{
+  if((k < 0) || (k >= nPix_)) 
+    {
+    throw RangeCheckError("LocalMap::PIxVal Pixel index out of range ");
+    }
+  //
+  int_4 i,j;
+  Getij(k,i,j);
+  return(pixels_(j,i));
+
+  //
+}
+
+/*! \fn T const& SOPHYA::LocalMap::PixVal(int_4 k) const
+  const version of previous method 
+*/
+template<class T>
+T const& LocalMap<T>::PixVal(int_4 k) const
+{
+  if((k < 0) || (k >= nPix_)) 
+    {
+    throw RangeCheckError("LocalMap::PIxVal Pixel index out of range ");
+    } 
+  //
+  int_4 i,j;
+  Getij(k,i,j);
+  return(pixels_(j,i));
+}
+
+/*! \fn bool SOPHYA::LocalMap::ContainsSph(double theta, double phi) const
+ \return true if teta,phi in map  
+ <b> Not yet implemented </b>
+*/
+template<class T>
+bool LocalMap<T>::ContainsSph(double theta, double phi) const
+{
+// $CHECK$  Reza 11/11/99 - A modifier
+  throw NotAvailableOperation("LocalMap<T>::ContainsSph() - Not yet implemented !");
+  return(true);
+}
+
+/*!  \fn int_4 SOPHYA::LocalMap::PixIndexSph(double theta,double phi) const
+
+   angles in radians
+  \return index of the pixel with spherical coordinates (theta,phi) 
+*/
+template<class T>
+int_4 LocalMap<T>::PixIndexSph(double theta,double phi) const
+{
+  int_4 i,j;
+
+  if (! LocalMap_isDone()) initializationError();
+  double csTheta = cos(theta);
+  double snTheta = sin(theta);
+  double csPhi   = cos(phi);
+  double snPhi   = sin(phi); 
+  double csPhiMPhiC = cos (phi - phiC_);
+  double snPhiMPhiC = sin (phi - phiC_);
+  // le point sur la sphere est note M. 
+  // intersection P de OM avec le plan de la carte (tangent en C)
+  double denom = snTheta*snthC_*csPhiMPhiC + csTheta*csthC_;
+  if ( denom == 0.) 
+    {
+    }
+  double lambda = 1./denom;
+  // coordonnes du point d'intersection P dans le repere lie au plan
+
+  double XP = lambda*snTheta*snPhiMPhiC;
+  double YP = lambda*snTheta*csthC_*csPhiMPhiC;
+
+  // coordonnees dans le repere lie a la carte (eventuellement tourne par
+  // rapport au precedent.
+
+  double X = XP*cosAngle_ + YP*sinAngle_;
+  double Y = -XP*sinAngle_ + YP*cosAngle_;
+
+  // en unites de pixels 
+
+  X /= deltaPhi_;
+  Y /= deltaTheta_;
+
+
+  double xmin= -x0_-0.5;
+  double xmax= xmin+nSzX_;
+  if((X > xmax) || (X < xmin)) { 
+    if (exc_outofmap_) throw RangeCheckError("LocalMap<T>::PixIndexSph() - Out of Map Theta/Phi (X) ");
+    else return(-1);
+  }
+  double xcurrent= xmin;
+  for(i = 0; i < nSzX_; i++ ) 
+    {
+      xcurrent += 1.;
+      if( X < xcurrent ) break;
+    }
+  double ymin= -y0_-0.5;
+  double ymax= ymin+nSzY_;
+  if((Y >  ymax) || (Y < ymin)) { 
+    if (exc_outofmap_) throw RangeCheckError("LocalMap<T>::PixIndexSph() - Out of Map Theta/Phi (Y) ");
+    else return(-1);
+  }
+  double ycurrent= ymin;
+  for(j = 0; j < nSzY_; j++ ) 
+    {
+      ycurrent += 1.;
+      if( Y < ycurrent ) break;
+    }
+  return (j*nSzX_+i);
+}
+
+/*! \fn void SOPHYA::LocalMap::PixThetaPhi(int_4 k,double& theta,double& phi) const
+
+   \return (theta, phi) coordinates of pixel with index k 
+*/
+
+
+template<class T>
+void LocalMap<T>::PixThetaPhi(int_4 k,double& theta,double& phi) const
+{
+
+  int_4 i,j;
+  Getij(k,i,j);
+
+  PixThetaPhi(i,j, theta, phi);
+
+}
+
+/*! \fn void SOPHYA::LocalMap::PixThetaPhi(int_4 ip,int_4 it, double& theta,double& phi) const
+
+
+   \return (theta, phi) coordinates of pixel of map with indices (ip,it) corresponding to x and y directions
+
+ \param ip  phi-like index
+ \param it  theta-like index
+*/
+
+template<class T>
+void LocalMap<T>::PixThetaPhi(int_4 ip,int_4 it, double& theta,double& phi) const
+{
+  double XP, YP, ZP;
+  PixToSphereC(ip,it,XP,YP,ZP);
+
+  theta = acos(ZP);
+  phi = atan2(YP, XP);
+  while (phi < 0.)  phi += 2.*Pi;
+
+}
+
+
+
+
+/*! \fn T SOPHYA::LocalMap::SetPixels(T v)
+
+Set all pixels to value v 
+*/
+template <class T>
+T LocalMap<T>::SetPixels(T v)
+{
+pixels_ = v;
+return(v);
+}
+ 
+/*! \fn double SOPHYA::LocalMap::PixSolAngle(int_4 k) const
+   Pixel Solid angle  of pixel k (steradians). 
+   For the moment, all the pixels are considered to have  the same size in (theta, phi). So the parameter k is dummy.
+      
+*/  
+template<class T>
+double LocalMap<T>::PixSolAngle(int_4 k) const
+{
+  double XP, YP, ZP;
+  int_4 i,j;
+  Getij(k,i,j);
+  PixToSphereC(i,j,XP,YP,ZP);
+
+  double theta = acos(ZP);
+
+  
+
+  // angle solide
+
+  double sol= 2.* deltaPhi_*sin(theta)*sin(0.5*deltaTheta_);
+  return sol;
+}
+
+/*! \fn void SOPHYA::LocalMap::PixToSphereC(int_4 ip, int_4 it, double& XP, double& YP, double& ZP) const
+
+projection of a pixel of map, onto the unity sphere ; result in cartesian coordinates.
+*/
+
+template<class T>
+void LocalMap<T>::PixToSphereC(int_4 ip, int_4 it, double& XP, double& YP, double& ZP) const
+{
+  if (! LocalMap_isDone()) initializationError();
+  double X= double(ip-x0_)* deltaPhi_;
+  double Y= double(it-y0_)*deltaTheta_; 
+
+    // situation dans le plan de reference tangent
+  double dx= X*cosAngle_-Y*sinAngle_;
+  double dy= X*sinAngle_+Y*cosAngle_;
+
+  XP = XC_ - dx*snphC_ - dy*csthC_*csphC_;
+  YP = YC_ + dx*csphC_ - dy*csthC_*snphC_;
+  ZP = ZC_ + dy*snthC_;
+
+  // on renormalise pour eviter les probleme de precision lors
+  // de la prise ulterieure de lignes trigonometriques
+  double norme = sqrt(XP*XP + YP*YP + ZP*ZP);
+  XP /= norme;
+  YP /= norme;
+  ZP /= norme;
+}
+
+/*! \fn void SOPHYA::LocalMap::SetOrigin(double theta0,double phi0,double angle)
+   set the referential of the map (angles in degrees)
+
+    \param theta0
+    \param phi0 celestial coordinates attributed to center pixel:  x0=siz_x/2,  y0=siz_y/2 
+\param angle  angle between map referential and plane-coordinate system (see class description)
+*/
+template<class T>
+void LocalMap<T>::SetOrigin(double theta0,double phi0,double angle)
+{
+  SetOrigin(theta0, phi0,  nSzX_/2,  nSzY_/2, angle);
+}
+ 
+/*!  \fn void SOPHYA::LocalMap::SetOrigin(double theta0,double phi0,int_4 x0,int_4 y0,double angle)
+   set the referential of the map (angles in degrees)
+
+    \param theta0
+    \param phi0 celestial coordinates attributed to center pixel: (x0,y0) 
+\param angle  angle between map referential and plane-coordinate system (see class description)
+
+*/
+template<class T>
+void LocalMap<T>::SetOrigin(double theta0,double phi0,int_4 x0,int_4 y0,double angle)
+{
+
+  if ( theta0 < 0. || theta0 > 180. || phi0 < 0. || phi0 > 360. || angle < -90. || angle > 90.)
+    {
+      throw ParmError("LocalMap::SetOrigin  angle out of range"); 
+    }
+  SetCoorC(theta0,phi0);
+  angleDegres_ = angle; 
+  // en radians 
+  angle_ = angle*Pi/180.;
+  x0_= x0;
+  y0_= y0;
+  cosAngle_= cos(angle_);
+  sinAngle_= sin(angle_);
+
+   if (originSet_)
+     {
+       cout << " WARNING:  LocalMap<T>::SetOrigin() : reset origine of a local map which had already an origin " << endl;
+     }
+   originSet_ = true;
+} 
+
+template<class T>
+void LocalMap<T>::SetCoorC(double theta0, double phi0)
+{
+
+  thetaDegresC_ = theta0;
+  phiDegresC_ = phi0;
+
+  // passage en radians
+  thetaC_= theta0*Pi/180.;
+  phiC_  = phi0*Pi/180.;
+  csthC_ = cos(thetaC_);
+  snthC_ = sin(thetaC_);
+  csphC_ = cos(phiC_);
+  snphC_ = sin(phiC_);
+  XC_ = snthC_*csphC_;
+  YC_ = snthC_*snphC_;
+  ZC_ = csthC_;
+}
+
+
+// angles en RADIANS
+template<class T>
+TMatrix<double> LocalMap<T>::CalculMatricePassage()
+{
+  cout << " calcul matrice de passage " << endl;
+  if (! LocalMap_isDone()) initializationError();
+  TMatrix<double> passage(3,3);
+  double cos_th_axeZ;
+  double sin_th_axeZ;
+  double cos_phi_axeZ;
+  double sin_phi_axeZ;
+
+  double cth,sth, cdeltaPhi, phi, cphi, sphi;
+
+  if ( snthC_ <= 0.) // carte centree au pole 
+    {
+      cos_th_axeZ = 1.;
+      sin_th_axeZ = 0.;
+      cos_phi_axeZ = 1.;
+      sin_phi_axeZ = 0.;
+      
+    }
+  else
+    {
+      cth = cosAngle_*snthC_;
+      double arg = 1.-cth*cth;
+      if (arg <= 0. ) // carte centree sur l'equateur, sans rotation
+	{
+	  cos_th_axeZ = 1.;
+	  sin_th_axeZ = 0.;
+	  cos_phi_axeZ = csphC_;
+	  sin_phi_axeZ = snphC_;
+	}
+      else
+	{
+	  sth = sqrt(arg);
+	  cdeltaPhi = -csthC_*cth/(snthC_*sth);
+	  if (cdeltaPhi < -1. ) cdeltaPhi = -1.;
+	  if (cdeltaPhi > 1. ) cdeltaPhi = 1.;
+	  phi = phiC_ + acos( cdeltaPhi );
+
+	  cos_th_axeZ = cth;
+	  sin_th_axeZ = sth;
+	  cos_phi_axeZ = cos(phi);
+	  sin_phi_axeZ = sin(phi);
+	}
+    }
+  passage(0,0) = snthC_*csphC_;
+  passage(1,0) = snthC_*snphC_;
+  passage(2,0) = csthC_;
+
+  passage(0,2) = sin_th_axeZ*cos_phi_axeZ;
+  passage(1,2) = sin_th_axeZ*sin_phi_axeZ;
+  passage(2,2) = cos_th_axeZ;
+
+  passage(0,1) = passage(1,2)*passage(2,0) - passage(2,2)*passage(1,0);
+  passage(1,1) = passage(2,2)*passage(0,0) - passage(0,2)*passage(2,0); 
+  passage(2,1) = passage(0,2)*passage(1,0) - passage(1,2)*passage(0,0);
+
+  //  passage.Print(cout);
+  // cout << " fin calcul passage " << endl;
+
+  return passage;
+
+
+}
+
+/*! \fn void SOPHYA::LocalMap::SetSize(double angleX,double angleY)
+
+   angle range of tthe map (angles in degrees) 
+\param angleX phi-like angle
+\param angleX theta-like angle
+*/
+template<class T>
+void LocalMap<T>::SetSize(double angleX,double angleY)
+{
+  if (!pixelSized_) initializationError();
+
+  if ( angleX <= 0. || angleX > 180. || angleY <= 0. || angleY > 180.)
+    {
+      throw ParmError("LocalMap::SetSize extension angle out of range"); 
+    }
+
+  angleDegresX_ = angleX;
+  angleDegresY_ = angleY;
+  // angles par pixel,  en radians 
+  cout << " taille x " << nSzX_ <<"  taille y " << nSzY_ << endl;
+  deltaPhi_   = angleX*Pi/(180.*nSzX_);
+  deltaTheta_ = angleY*Pi/(180.*nSzY_);
+ 
+  if (angleSized_)
+     {
+       cout << " WARNING LocalMap::SetSize  ; angle resizing of an already sized local map " << endl;
+     }
+  angleSized_  = true;
+
+}
+
+
+
+/*! \fn void SOPHYA::LocalMap::ProjectionToSphere(SphericalMap<T>& sphere) const
+
+Projection to a spherical map 
+*/
+template<class T>
+void LocalMap<T>::ProjectionToSphere(SphericalMap<T>& sphere) const
+{
+   double theta, phi;
+  int it, ip;
+   for (it = 0; it < nSzY_; it++)
+    {
+      for (ip = 0; ip < nSzX_; ip++) 
+	{
+	  PixThetaPhi(ip,it, theta, phi);
+	  sphere(theta,phi)= pixels_(it, ip);
+	}
+    }
+}
+
+
+
+// Titre	Private Methods
+//++
+template<class T>
+void LocalMap<T>::InitNul()
+//
+//    set attributes to zero
+//--
+{ 
+
+  pixelSized_  = false;
+  angleSized_  = false;
+  originSet_ = false;
+
+  nSzX_ = 0;
+  nSzY_ = 0;
+  angleDegresX_ = 0.;
+  angleDegresY_ = 0.;
+  thetaDegresC_ = 0.;
+  phiDegresC_   = 0.;
+  x0_ = 0;
+  y0_ = 0;
+  angleDegres_ = 0.;
+
+
+
+  nPix_ = 0;
+
+  thetaC_ = 0.;
+  phiC_   = 0.;
+  csthC_  = 1.;
+  snthC_  = 0.;
+  csphC_  = 1.;
+  snphC_  = 0.;
+  XC_     = 0.;
+  YC_     = 0.;
+  ZC_     = 1.;
+
+  angle_      = 0.;
+  cosAngle_   = 1.;
+  sinAngle_   = 0.;
+  deltaPhi_   = 0.;
+  deltaTheta_ =0.;
+  SetThrowExceptionWhenOutofMapFlag(false); // Genere des exceptions si theta-phi out of range 
+}
+
+
+/*!   \fn void SOPHYA::LocalMap::Getij(int_4 k,int_4& i,int_4& j) const
+
+ \return 2 indices corresponding to the pixel number k 
+*/
+template<class T>
+void LocalMap<T>::Getij(int_4 k,int_4& i,int_4& j) const
+{
+  i= (k+1)%nSzX_-1;
+  if(i == -1) i= nSzX_-1;
+  j= (k-i+2)/nSzX_;
+}
+
+
+
+
+
+
+template<class T>
+void LocalMap<T>::print(ostream& os) const
+{
+  os<<" SzX= "<<nSzX_<<", SzY= "<<nSzY_<<", NPix= "<<nPix_<<endl;
+      os<<" theta0= "<<thetaC_*180./Pi <<", phi0= "<<phiC_*180./Pi <<", angle= "<<angle_*180./Pi<<endl;
+      os<<" x0= "<<x0_<<", y0= "<<y0_<<endl;
+      os<<" cos= "<< cosAngle_ <<", & sin= "<<sinAngle_<<endl;
+      os<<"  deltaPhi_= "<<  deltaPhi_ <<", deltaTheta = "<< deltaTheta_ <<endl;
+      os <<endl;
+
+  os << " contenu de pixels : ";
+  for(int i=0; i < nPix_; i++)
+    {
+      if(i%5 == 0) os << endl;
+  int_4 ik,jk;
+  Getij(i,ik,jk);
+      os <<  pixels_(jk,ik) <<", ";
+    }
+  os << endl;
+}
+
+
+template<class T>
+void LocalMap<T>::recopierVariablesSimples(const LocalMap<T>& lm)
+{
+
+  pixelSized_ = lm.pixelSized_;
+  angleSized_ = lm.angleSized_;
+  originSet_  = lm.originSet_ ;
+
+
+  nSzX_ = lm.nSzX_;
+  nSzY_ = lm.nSzY_;
+  nPix_ = lm.nPix_;
+  x0_   = lm.x0_;
+  y0_   = lm.y0_;
+
+  thetaC_ = lm.thetaC_;
+  phiC_   = lm.phiC_;
+  csthC_  = lm.csthC_;
+  snthC_  = lm.snthC_;
+  csphC_  = lm.csphC_;
+  snphC_  = lm.snphC_;
+  XC_     = lm.XC_;
+  YC_     = lm.YC_;
+  ZC_     = lm.ZC_;
+
+  angle_= lm.angle_;
+  cosAngle_  = lm.cosAngle_;
+  sinAngle_  = lm.sinAngle_;
+  deltaPhi_  = lm. deltaPhi_;
+  deltaTheta_ = lm.deltaTheta_;
+}
+
+template<class T>
+void LocalMap<T>::initializationError() const
+{
+  cout << endl;
+  if (!pixelSized_) cout << " LocalMap::initializationError() ; pixel sizing is missing " << endl;
+  if (!angleSized_ ) cout << " LocalMap::initializationError() ; angle sizing is missing " << endl;
+  if (!originSet_ ) cout << " LocalMap::initializationError() ; origin of map is not set " << endl;
+      throw PException("LocalMap::initializationError() : bad initialization of the local map ");
+
+
+}
+
+
+//   ...... Operations de calcul  ......
+
+
+/*!  \fn void SOPHYA::LocalMap::SetT(T a)
+ Fill a LocalMap with a constant value \b a
+ */
+template <class T>
+LocalMap<T>& LocalMap<T>::SetT(T a) 
+{
+  if (NbPixels() < 1) 
+    throw RangeCheckError("LocalMap<T>::SetT(T )  - LocalMap not dimensionned ! ");
+  pixels_ = a;
+  return (*this);
+}
+
+/*!  \fn void SOPHYA::LocalMap::Add(T a)
+Add a constant value \b x to a LocalMap 
+ */
+template <class T>
+LocalMap<T>& LocalMap<T>::Add(T a)
+ {
+  if (NbPixels()< 1) 
+    throw RangeCheckError("LocalMap<T>::Add(T )  - LocalMap not dimensionned ! ");
+  pixels_ += a; 
+  return (*this);
+}
+
+/*!  \fn void SOPHYA::LocalMap::Sub(T a,bool fginv)
+
+Substract a constant value \b a to a LocalMap 
+
+*/
+template <class T>
+LocalMap<T>& LocalMap<T>::Sub(T a,bool fginv) 
+{
+  if (NbPixels()< 1) 
+    throw RangeCheckError("LocalMap<T>::Sub(T )  - LocalMap not dimensionned ! ");
+  pixels_.Sub(a,fginv); 
+  return (*this);
+} 
+
+/*! \fn void SOPHYA::LocalMap::Mul(T a)
+mutiply a LocalMap by a constant value \b a 
+*/
+template <class T>
+LocalMap<T>& LocalMap<T>::Mul(T a) 
+{
+  if (NbPixels()< 1) 
+    throw RangeCheckError("LocalMap<T>::Mul(T )  - LocalMap not dimensionned ! ");
+  pixels_ *= a; 
+  return (*this);
+}
+
+/*! \fn void SOPHYA::LocalMap::Div(T a)
+divide a LocalMap by a constant value \b a 
+*/
+template <class T>
+LocalMap<T>& LocalMap<T>::Div(T a) 
+{
+  if (NbPixels()< 1) 
+    throw RangeCheckError("LocalMap<T>::Div(T )  - LocalMap not dimensionned ! ");
+  pixels_ /= a; 
+  return (*this);
+} 
+
+//  >>>> Operations avec 2nd membre de type LocalMap
+/*! \fn void SOPHYA::LocalMap::AddElt(const LocalMap<T>& a)
+Add two LocalMap
+ */
+template <class T>
+LocalMap<T>& LocalMap<T>::AddElt(const LocalMap<T>& a)
+{
+  if (nSzX_ != a.nSzX_ || nSzY_ != a.nSzY_)
+    {
+    throw(SzMismatchError("LocalMap<T>::AddElt(const LocalMap<T>&) SizeMismatch")) ;
+    }
+  pixels_ += a.pixels_;
+  return (*this);
+}
+
+/*! \fn void SOPHYA::LocalMap::SubElt(const LocalMap<T>& a)
+Substract two LocalMap
+ */
+template <class T>
+LocalMap<T>& LocalMap<T>::SubElt(const LocalMap<T>& a)
+{
+  if (nSzX_ != a.nSzX_ || nSzY_ != a.nSzY_)
+    {
+    throw(SzMismatchError("LocalMap<T>::SubElt(const LocalMap<T>&) SizeMismatch")) ;
+    }
+  pixels_ -= a.pixels_;
+  return (*this);
+}
+
+/*! \fn void SOPHYA::LocalMap::MulElt(const LocalMap<T>& a)
+Multiply two LocalMap (elements by elements)
+ */
+template <class T>
+LocalMap<T>& LocalMap<T>::MulElt(const LocalMap<T>& a)
+{
+  if (nSzX_ != a.nSzX_ || nSzY_ != a.nSzY_)
+    {
+    throw(SzMismatchError("LocalMap<T>::MulElt(const LocalMap<T>&) SizeMismatch")) ;
+    }
+  //  pixels_ *= a.pixels_;
+  pixels_.DataBlock() *= a.pixels_.DataBlock();
+  return (*this);
+}
+
+/*! \fn void SOPHYA::LocalMap::DivElt(const LocalMap<T>& a)
+Divide two LocalMaps (elements by elements) - No protection for divide by 0
+*/
+template <class T>
+LocalMap<T>& LocalMap<T>::DivElt(const LocalMap<T>& a)
+{
+  if (nSzX_ != a.nSzX_ || nSzY_ != a.nSzY_)
+    {
+    throw(SzMismatchError("LocalMap<T>::DivElt(const LocalMap<T>&) SizeMismatch")) ;
+    }
+  //  pixels_ /= a.pixels_;
+  pixels_.DataBlock() /= a.pixels_.DataBlock();
+  return (*this);
+}
+
+
+
+
+
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template LocalMap<int_4>
+#pragma define_template LocalMap<r_8>
+#pragma define_template LocalMap<r_4>
+#pragma define_template LocalMap< complex<r_8> >
+#pragma define_template LocalMap< complex<r_4> >
+#endif
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class LocalMap<int_4>;
+template class LocalMap<r_8>;
+template class LocalMap<r_4>;
+template class LocalMap< complex<r_8> >;
+template class LocalMap< complex<r_4> >;
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyMap/localmap.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/localmap.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/localmap.h	(revision 2309)
@@ -0,0 +1,358 @@
+// This may look like C code, but it is really -*- C++ -*-
+#ifndef LOCALMAP_SEEN
+#define LOCALMAP_SEEN
+
+#include "pixelmap.h"
+#include "sphericalmap.h"
+#include "ndatablock.h"
+
+#include "anydataobj.h"
+#include "ppersist.h"
+
+
+
+// ***************** Class LocalMap *****************************
+
+
+
+namespace SOPHYA {
+
+
+template <class T>
+class FIO_LocalMap;
+
+template<class T>
+class FITS_LocalMap;
+
+/* Class LocalMap */
+
+
+template<class T>
+class LocalMap : public PixelMap<T>
+{
+
+ // friend declaration for classes which handle persistence and FITS IO
+  friend class FIO_LocalMap<T>; 
+  friend class FITS_LocalMap<T>; 
+
+public:
+
+LocalMap();
+LocalMap(int_4 nx, int_4 ny);
+LocalMap(int_4 nx, int_4 ny, double angleX,double angleY, double theta0,double phi0,int_4 x0,int_4 y0,double angle=0.);
+LocalMap(int_4 nx, int_4 ny, double angleX,double angleY, double theta0,double phi0, double angle=0.);
+LocalMap(const LocalMap<T>& lm, bool share);
+LocalMap(const LocalMap<T>& lm);
+virtual ~LocalMap();
+
+inline virtual bool IsTemp(void) const { return pixels_.IsTemp();}
+
+/*! Setting blockdata to temporary (see ndatablock documentation) */
+inline virtual void SetTemp(bool temp=false) const {pixels_.SetTemp(temp);};
+
+
+// ---------- Overloading of () to access pixel number k ----
+
+inline T& operator()(int_4 k) {return(PixVal(k));}
+inline T const& operator()(int_4 k) const {return(PixVal(k));}
+inline T& operator()(int_4 ix, int_4 iy) {return PixVal(iy*nSzX_+ix);};
+inline T const& operator()(int_4 ix, int_4 iy) const {return PixVal(iy*nSzX_+ix);};
+
+// Acces a un pixel 
+inline T& operator()(double theta,double phi) {return(PixValSph(theta,phi));};
+inline T  const& operator()(double theta,double phi) const {return(PixValSph(theta,phi));};
+   
+// ---------- Definition of PixelMap abstract methods -------
+
+virtual int_4 NbPixels() const;   // D.Y. int change en int_4 rationalisation Mac
+  
+virtual T& PixVal(int_4 k);
+virtual T const& PixVal(int_4 k) const;
+  //! if fg = true, will generate  exceptions , when theta-phi out of range
+inline  void SetThrowExceptionWhenOutofMapFlag(bool fg = false) { exc_outofmap_ = fg; }
+
+//! true --> exceptions wil be active when theta-phi out of range 
+inline  bool GetThrowExceptionWhenOutofMapFlag() { return exc_outofmap_; }
+
+virtual bool ContainsSph(double theta, double phi) const;
+//! return pixel number correspoinding to (theta,phi)
+virtual int_4 PixIndexSph(double theta,double phi) const;
+   
+//! return (theta,phi) correspoinding to pixel number k
+virtual void PixThetaPhi(int_4 k,double& theta,double& phi) const;
+
+//! set all pixel values equal to v
+virtual T SetPixels(T v);
+
+// return the solid angle covered by pixel k (steradians)
+virtual double PixSolAngle(int_4 k) const; 
+
+// ---------- Specific methods ------------------------------
+
+void ReSize(int_4 nx, int_4 ny);
+
+void SetOrigin(double theta=90.,double phi=0.,double angle=0.);
+void SetOrigin(double theta,double phi,int_4 x0,int_4 y0,double angle=0.);
+void SetSize(double angleX,double angleY);
+
+  /*! \fn TypeOfMap()
+ return the string "LOCAL"
+  */ 
+inline virtual string TypeOfMap() const {return string("LOCAL");};
+ 
+
+/*! Check to see if the local mapping is done */
+inline bool LocalMap_isDone() const {return( originSet_ && angleSized_ && pixelSized_);};
+
+void PixThetaPhi(int_4 ip,int_4 it, double& theta,double& phi) const;
+
+
+void ProjectionToSphere(SphericalMap<T>&) const;
+  
+/* There should be a more complex algorithm somewhere to combine *several* local maps to a full sphere.
+      -> static method, or separate class */
+  
+/*! provides a integer characterizing the pixelization refinement  (here : number of pixels) */
+inline virtual int_4 SizeIndex() const {return(nPix_);}
+inline int_4 Size_x() const {return nSzX_;}
+inline int_4 Size_y() const {return nSzY_;}
+
+/* Je rajoute ces 2 fonctions inlines pour compatibilite d'interface 
+   avec TArray  -   Reza 30/8/2000                                   */
+inline int_4 SizeX() const {return nSzX_;}
+inline int_4 SizeY() const {return nSzY_;}
+
+inline void Origin(double& theta,double& phi,int_4& x0,int_4& y0,double& angle) const {theta= thetaDegresC_; phi= phiDegresC_; x0= x0_; y0= y0_;angle= angleDegres_;}
+
+/*! total aperture in theta and phi, in degrees ( from SetSize() ) */
+inline void Aperture(double& anglex,double& angley) const {anglex= angleDegresX_; angley= angleDegresY_;}
+
+
+/*  Acces to the DataBlock  */
+inline       NDataBlock<T>& DataBlock()       {return pixels_.DataBlock();}
+inline const NDataBlock<T>& DataBlock() const {return pixels_.DataBlock();}
+
+/*  Acces to the matrix  */
+//! access to matrix 
+/*!
+  \warning : a pixel is defined by the pair of a phi-like index 
+   (x-axis) and a theta-like index (y-axis). The phi-like index denotes
+   the column number in the matrix ; the theta-like index denotes the
+   row number.
+*/
+inline       TMatrix<T>& Matrix()       {return pixels_;}
+inline const TMatrix<T>& Matrix() const {return pixels_;}
+
+/* impression */ 
+void print(ostream& os) const;
+
+// Operations diverses  = , +=, ...
+
+
+virtual LocalMap<T>& Set(const LocalMap<T>& a);
+inline  LocalMap<T>& operator = (const LocalMap<T>& a) {return Set(a);}
+
+// A += -= *= /= x (ajoute, soustrait, ... x a tous les elements)
+
+  //! Fill LocalMap with all elements equal to \b x
+virtual LocalMap<T>& SetT(T a); 
+inline  LocalMap<T>& operator = (T a) {return SetT(a);}
+
+// Add \b x to all elements
+virtual LocalMap<T>& Add(T a); 
+inline  LocalMap<T>&  operator += (T x)  { return Add(x); }
+// Substract \b x to all elements
+virtual LocalMap<T>& Sub(T a,bool fginv=false); 
+inline   LocalMap<T>&  operator -= (T x)  { return Sub(x); }
+// Multiply all elements by \b x
+virtual LocalMap<T>& Mul(T a); 
+inline  LocalMap<T>&  operator *= (T x)  { return Mul(x); }
+// Divide all elements by \b x
+virtual LocalMap<T>& Div(T a); 
+inline  LocalMap<T>&  operator /= (T x)  { return Div(x); }
+
+// A += -=  (ajoute, soustrait element par element les deux spheres )
+  //! Operator LocalMap += LocalMap
+  virtual LocalMap<T>&  AddElt(const LocalMap<T>& a);
+  inline  LocalMap<T>&  operator += (const LocalMap<T>& a)  { return AddElt(a); }
+
+
+
+  virtual LocalMap<T>&  SubElt(const LocalMap<T>& a);
+  //! Operator LocalMap -= LocalMap
+  inline  LocalMap<T>&  operator -= (const LocalMap<T>& a)  { return SubElt(a); }
+// Multiplication, division element par element les deux LocalMap 
+  virtual LocalMap<T>&  MulElt(const LocalMap<T>& a);
+  inline  LocalMap<T>&  operator *= (const LocalMap<T>& a)  { return MulElt(a); }
+  virtual LocalMap<T>&  DivElt(const LocalMap<T>& a);
+  inline  LocalMap<T>&  operator /= (const LocalMap<T>& a)  { return DivElt(a); }
+
+
+void CloneOrShare(const LocalMap<T>& a);
+void Share(const LocalMap<T>& a);
+LocalMap<T>& CopyElt(const LocalMap<T>& a);
+
+
+// ---------- Méthodes internes -----------------------------
+          
+private :
+
+void InitNul();
+void SetCoorC(double theta0, double phi0);
+TMatrix<double> CalculMatricePassage();
+void Getij(int_4 k,int_4& i,int_4& j) const;
+  void PixToSphereC(int_4 ip, int_4 it, double& XP, double& YP, double& ZP) const;
+
+void recopierVariablesSimples(const LocalMap<T>& lm);
+
+void initializationError() const;
+
+// ---------- Variables internes ----------------------------
+
+
+  // variables suffisantes pour reconstruire l'objet
+
+  bool pixelSized_;
+  bool angleSized_;
+  bool originSet_;
+
+  int_4 nSzX_;
+  int_4 nSzY_;
+  double angleDegresX_;
+  double angleDegresY_;
+  double thetaDegresC_;
+  double phiDegresC_;
+  int_4 x0_;
+  int_4 y0_;
+  double angleDegres_;
+
+
+  //  NDataBlock<T> pixels_;
+  TMatrix<T> pixels_;
+
+
+  // variables derivees (redondantes, precalculees pour ameliorer 
+  // les performances)
+
+  int_4 nPix_;
+
+
+  double thetaC_;
+  double phiC_;
+  double csthC_;
+  double snthC_;
+  double csphC_;
+  double snphC_;
+  double XC_;
+  double YC_;
+  double ZC_;
+
+
+  double angle_;
+  double cosAngle_;
+  double sinAngle_;
+  double deltaPhi_;
+  double deltaTheta_;
+
+  bool exc_outofmap_;
+
+
+};
+
+////////////////////////////////////////////////////////////////
+// Surcharge d'operateurs A (+,-,*,/) (T) x
+/*! \ingroup SkyMap \fn operator+(const LocalMap<T>&,T)
+  \brief Operator LocalMap = LocalMap + constant */
+template <class T> inline LocalMap<T> operator + (const LocalMap<T>& a, T b)
+    {LocalMap<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Add(b); return result;}
+/*! \ingroup SkyMap \fn operator+(T,const LocalMap<T>&)
+  \brief Operator LocalMap = constant + LocalMap */
+template <class T> inline LocalMap<T> operator + (T b,const LocalMap<T>& a)
+    {LocalMap<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Add(b); return result;}
+
+
+/*! \ingroup SkyMap\fn operator-(const LocalMap<T>&,T)
+  \brief Operator LocalMap = LocalMap - constant */
+template <class T> inline LocalMap<T> operator - (const LocalMap<T>& a, T b)
+    {LocalMap<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Sub(b); return result;}
+
+/*! \ingroup  \fn operator-(T,const LocalMap<T>&)
+  \brief Operator LocalMap = constant - LocalMap */
+template <class T> inline LocalMap<T> operator - (T b,const LocalMap<T>& a)
+    {LocalMap<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Sub(b,true); return result;}
+
+/*! \ingroup SkyMap \fn operator*(const LocalMap<T>&,T)
+  \brief Operator LocalMap = LocalMap * constant */
+template <class T> inline LocalMap<T> operator * (const LocalMap<T>& a, T b)
+    {LocalMap<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Mul(b); return result;}
+
+/*! \ingroup SkyMap \fn operator*(T,const LocalMap<T>&)
+  \brief Operator LocalMap = constant * LocalMap */
+template <class T> inline LocalMap<T> operator * (T b,const LocalMap<T>& a)
+    {LocalMap<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Mul(b); return result;}
+
+/*! \ingroup SkyMap \fn operator/(const LocalMap<T>&,T)
+  \brief Operator LocalMap = LocalMap / constant */
+template <class T> inline LocalMap<T> operator / (const LocalMap<T>& a, T b)
+    {LocalMap<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Div(b); return result;}
+
+/*! \ingroup SkyMap \fn operator/(T,const LocalMap<T>&)
+  \brief Operator LocalMap = constant / LocalMap  */
+template <class T> inline LocalMap<T> operator / (T b, const LocalMap<T>& a)
+    {LocalMap<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Div(b, true); return result;}
+
+////////////////////////////////////////////////////////////////
+// Surcharge d'operateurs C = A (+,-) B
+
+/*! \ingroup SkyMap \fn operator+(const LocalMap<T>&,const LocalMap<T>&)
+  \brief Operator LocalMap = LocalMap + LocalMap */
+template <class T>
+inline LocalMap<T> operator + (const LocalMap<T>& a,const LocalMap<T>& b)
+    { LocalMap<T> result; result.SetTemp(true); 
+    if (b.IsTemp())  { result.Share(b); result.AddElt(a); }
+    else { result.CloneOrShare(a); result.AddElt(b); }
+    return result; }
+
+/*! \ingroup SkyMap \fn operator-(const LocalMap<T>&,const LocalMap<T>&)
+  \brief Operator LocalMap = LocalMap - LocalMap */
+template <class T>
+inline LocalMap<T> operator - (const LocalMap<T>& a,const LocalMap<T>& b)
+    { LocalMap<T> result; result.SetTemp(true); 
+    if (b.IsTemp())  { result.Share(b); result.SubElt(a); }
+    else { result.CloneOrShare(a); result.SubElt(b); }
+    return result; }
+
+////////////////////////////////////////////////////////////////
+// Surcharge d'operateurs C = A (*,/) B
+
+/*! \ingroup SkyMap \fn operator*(const LocalMap<T>&,const LocalMap<T>&)
+  \brief Operator LocalMap = LocalMap * LocalMap (pixel by pixel multiply)*/
+template <class T>
+inline LocalMap<T> operator * (const LocalMap<T>& a,const LocalMap<T>& b)
+    { LocalMap<T> result; result.SetTemp(true); 
+    if (b.IsTemp())  { result.Share(b); result.MulElt(a); }
+    else { result.CloneOrShare(a); result.MulElt(b); }
+    return result; }
+
+/*! \ingroup SkyMap \fn operator/(const LocalMap<T>&,const LocalMap<T>&)
+  \brief Operator LocalMap = LocalMap / LocalMap (pixel by pixel divide)*/
+template <class T>
+inline LocalMap<T> operator / (const LocalMap<T>& a,const LocalMap<T>& b)
+    { LocalMap<T> result; result.SetTemp(true); 
+    if (b.IsTemp())  { result.Share(b); result.DivElt(a); }
+    else { result.CloneOrShare(a); result.DivElt(b); }
+    return result; }
+
+
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyMap/longlat.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/longlat.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/longlat.cc	(revision 2309)
@@ -0,0 +1,82 @@
+#include "longlat.h"
+//++ 
+// Class	LongLat
+//
+// include      longlat.h
+//
+//    translation from  coordinates (longitude, latitude) 
+//    to theta,phi
+//
+//    longitude=phi
+//
+//    latitude=Pi/2-theta
+//
+//--
+//++
+// Titre	Constructors
+//--
+//++
+LongLat::LongLat()
+//
+//--
+{
+  _lon=0.;
+  _lat=0.;
+}
+//++
+LongLat::LongLat(double longitude, double latitude)
+//
+//--
+{
+  _lon=mod(longitude,pi2);
+  if( latitude == pi_over_2 ) _lat=latitude;
+  else _lat=mod(latitude+pi_over_2,M_PI)-pi_over_2; // dans [-Pi/2,Pi/2]
+}
+//++
+LongLat::LongLat(double x, double y, double z)
+//
+//--
+{
+  double norm=sqrt(x*x+y*y+z*z);
+  double theta;
+  if( norm != 0. ) 
+    {
+      theta=acos(z/norm); // dans [0,Pi]
+      if( mod(theta,M_PI) == 0. ) _lon=0.; // on est sur +-Oz, le vecteur z est en phi=0
+      //      else _lon=acos(x/sin(theta)/norm)+M_PI*(y<0);
+      else _lon=scangle(y/sin(theta)/norm,x/sin(theta)/norm);
+    }
+  else // vecteur nul
+    {
+      theta=0.;
+      _lon=0.;
+    }
+  _lat=pi_over_2-theta;
+}
+//++
+// Titre	Public Methods
+//--
+//++
+void LongLat::Set(double longitude, double latitude)
+//
+//--
+{
+  _lon=mod(longitude,pi2);
+  if( latitude == pi_over_2 ) _lat=latitude;
+  else _lat=mod(latitude+pi_over_2,M_PI)-pi_over_2; // dans [-Pi/2,Pi/2]
+}
+//++
+void LongLat::Print(ostream& os) const
+//
+//--
+{
+  os << "LongLat : longitude = " << _lon << " phi   = " << this->Phi() << endl;
+  os << "LongLat : latitude    = " << _lat << " theta = " << this->Theta() << endl;
+}
+//++
+//
+//  double Longitude() const 
+//  double Phi() const 
+//  double Latitude() 
+//  double Theta() const 
+//--
Index: /tags/V_Dec2002/SophyaLib/SkyMap/longlat.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/longlat.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/longlat.h	(revision 2309)
@@ -0,0 +1,56 @@
+//   Geometry handling class 
+//       B. Revenu, R. Ansari , G. Le Meur   2000
+// DAPNIA/SPP (Saclay) / CEA    LAL - IN2P3/CNRS  (Orsay)
+
+#ifndef LONGLAT_H_SEEN
+#define LONGLAT_H_SEEN
+
+#include "machdefs.h"
+#include <math.h>
+#include <iostream.h>
+#include <stdio.h>
+#include <string.h>
+#include "utilgeom.h"
+
+/*
+  passage des coordonnees longitude, latitude en theta,phi
+  longitude=phi
+  latitude=Pi/2-theta
+*/
+
+namespace SOPHYA {  
+
+class LongLat
+{
+  
+ public:
+  
+  LongLat();
+  LongLat(double longitude, double latitude);
+  LongLat(double x, double y, double z);
+  LongLat(const LongLat&);
+  
+  void Set(double longitude, double latitude);
+  double Longitude() const {return _lon;}
+  double Phi() const {return _lon;}
+  double Latitude() const {return _lat;}
+  double Theta() const {return pi_over_2-_lat;}
+
+  void Print(ostream& os) const;
+  
+ private:
+  
+  double _lon; // lambda
+  double _lat; // beta
+  
+};
+
+inline ostream& operator<<(ostream& s, const LongLat& ll) 
+{  
+  ll.Print(s);  
+  return s;  
+}
+
+} // namespace SOPHYA
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyMap/mapoperation.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/mapoperation.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/mapoperation.cc	(revision 2309)
@@ -0,0 +1,84 @@
+// This may look like C code, but it is really -*- C++ -*-
+//--------------------------------------------------------------------------
+// File and Version Information:
+//        Simple Operations on Maps 
+// Description:
+//
+// History (add to end):
+//      Sophie   April, 2000  - creation
+//        code from Reza
+//------------------------------------------------------------------------
+#include "machdefs.h"
+#include <math.h>
+#include "mapoperation.h"
+/*!
+ * \class SOPHYA::MapOperations
+ * This class is for simple operations on maps
+ */
+
+template <class T>
+void MapOperations<T>::sphTosph(PixelMap<T>& in, PixelMap<T>& out)
+  // Cette fonction remplit la sphere out a partir de la sphere in
+  // Les spheres peuvent etre de type et de pixelisations differentes
+{
+  int kin,kout;
+  double teta,phi;
+  
+  int* cnt = new int[out.NbPixels()+1];
+  for(kout=0; kout<out.NbPixels(); kout++)
+    { cnt[kout] = 0; out(kout) = 0.; }
+  
+  for(kin=0; kin<in.NbPixels(); kin++) {
+    in.PixThetaPhi(kin, teta, phi);
+    kout = out.PixIndexSph(teta, phi);
+    if (kout < 0) continue;
+    out(kout) += in(kin);
+    cnt[kout] ++;
+  }
+  
+  double moy, sig, dcn;
+  moy = 0.; sig = 0.;
+  for(kout=0; kout<out.NbPixels(); kout++) {
+    dcn = cnt[kout];  moy += dcn;	 sig += (dcn*dcn);
+    if (cnt[kout] > 0)  out(kout) /= dcn;
+    else {
+      out.PixThetaPhi(kout, teta, phi);
+      int pixel = in.PixIndexSph(teta,phi);
+      out(kout) = in.PixVal(pixel);
+    }
+  }
+  
+  moy /= out.NbPixels();
+  sig = sig/out.NbPixels() - moy*moy;
+  if (sig >= 0.)	sig = sqrt(sig);
+  
+  delete[] cnt;
+  
+}
+
+template <class T>
+void  MapOperations<T>::meanSig(NDataBlock<T> const & dbl, double& gmoy, double& gsig)
+{
+  gmoy=0.;
+  gsig = 0.; 
+  double valok;
+  for(int k=0; k<(int)dbl.Size(); k++) {
+    valok = dbl(k);
+    gmoy += valok;  gsig += valok*valok; 
+  }
+  gmoy /= (double)dbl.Size();
+  gsig = gsig/(double)dbl.Size() - gmoy*gmoy;
+  if (gsig >= 0.) gsig = sqrt(gsig);
+}
+
+///////////////////////////////////////////////////////////////
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template MapOperations<r_4>
+#pragma define_template MapOperations<r_8>
+#endif
+  
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class MapOperations<r_4>;
+template class MapOperations<r_8>;
+#endif
+   
Index: /tags/V_Dec2002/SophyaLib/SkyMap/mapoperation.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/mapoperation.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/mapoperation.h	(revision 2309)
@@ -0,0 +1,44 @@
+// This may look like C code, but it is really -*- C++ -*-
+//--------------------------------------------------------------------------
+// File and Version Information:
+//        Simple Operations on Maps 
+// Description:
+//
+// History (add to end):
+//      Sophie   April, 2000  - creation
+//        code from Reza
+//------------------------------------------------------------------------
+
+#ifndef MapOperation_SEEN
+#define MapOperation_SEEN
+
+#include "machdefs.h"
+#include <math.h>
+#include "ndatablock.h"
+#include "pixelmap.h"
+
+namespace SOPHYA {
+  
+  //! Class for simple mathematical operation on maps
+  
+template <class T>
+  class MapOperations {
+  public:
+  void meanSig(NDataBlock<T> const & dbl, double& gmoy, double& gsig);
+  void sphTosph(PixelMap<T>& in, PixelMap<T>& out);
+  
+  void Sph2Sph(PixelMap<T>& in, PixelMap<T>& out);
+  void MeanSig(NDataBlock<T> const & dbl, double& gmoy, double& gsig);
+};
+ 
+template <class T>
+  inline void Sph2Sph(PixelMap<T>& in, PixelMap<T>& out)
+  { MapOperations<T> a; a.sphTosph(in,out); }
+ 
+template <class T>
+  inline void MeanSig(NDataBlock<T> const & dbl, double& gmoy, double& gsig)
+  { MapOperations<T> a; a.meanSig(dbl,gmoy,gsig); } 
+
+}  // namespace SOPHYA
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyMap/objlist.list
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/objlist.list	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/objlist.list	(revision 2309)
@@ -0,0 +1,14 @@
+HEALPixUtils.o
+fiolocalmap.o
+fiospherehealpix.o
+fiospherethetaphi.o
+localmap.o
+longlat.o
+mapoperation.o
+skymapinit.o
+spherehealpix.o
+spherepos.o
+spherethetaphi.o
+unitvector.o
+utilgeom.o
+vector3d.o
Index: /tags/V_Dec2002/SophyaLib/SkyMap/pixelmap.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/pixelmap.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/pixelmap.h	(revision 2309)
@@ -0,0 +1,156 @@
+// This may look like C code, but it is really -*- C++ -*-
+#ifndef PIXELMAP_SEEN
+#define PIXELMAP_SEEN
+
+#include "ppersist.h" 
+#include "dvlist.h"
+#include "spherepos.h"
+#include <iostream.h>
+
+namespace SOPHYA {
+
+/*!
+ \class PixelMap
+ \ingroup SkyMap
+ General map of pixels on part of sphere or whole sphere.
+
+ Class hierarchy :
+\verbatim
+   PixelMap
+     SphericalMap
+         SphereThetaPhi
+         SphereHEALPix
+         SphereIco
+      LocalMap
+\endverbatim
+*/
+
+template<class T>
+class PixelMap  : public AnyDataObj 
+{
+public:
+  
+              PixelMap(SphereCoordSys* cs = NULL) : mInfo_(NULL) 
+                    { if (cs) cs_ = cs; else cs_ = new SphereCoordSys; }
+virtual       ~PixelMap() 
+                    { if (mInfo_) delete mInfo_; if (cs_) delete cs_; }
+
+// Set/Change/Get the coordinate system
+virtual void  SetCoordSys(SphereCoordSys* cs)
+                    { if (cs) { delete cs_;  cs_ = cs; } }
+inline SphereCoordSys* GetCoordSys() const { return(cs_); }
+
+/*! Number of pixels */
+virtual int_4 NbPixels() const=0;
+   
+/*! Value of pixel number k */
+virtual T& PixVal(int_4 k)=0;
+virtual T const& PixVal(int_4 k) const=0;
+
+// Map s coverage
+virtual bool ContainsSph(double theta, double phi) const=0;
+virtual bool Contains(const SpherePosition& spos) const;
+
+/*! Index of pixel at (theta,phi) */
+virtual int_4 PixIndexSph(double theta, double phi) const=0;
+// Index of pixel at a sky-position 
+virtual int_4 PixIndex(const SpherePosition& spos);
+
+/*! Value of pixel number at (theta,phi) */
+virtual T& PixValSph(double theta, double phi)
+                           {return PixVal(PixIndexSph(theta,phi));}
+virtual T const& PixValSph(double theta, double phi) const
+                           {return PixVal(PixIndexSph(theta,phi));}
+
+/*! Spherical coordinates of center of pixel number k */
+virtual void PixThetaPhi(int_4 k, double& theta, double& phi) const=0;
+
+/*! provides a integer characterizing the pixelization refinement 
+ (depending of the type of the map) 
+*/             
+virtual int_4 SizeIndex() const=0;
+virtual string TypeOfMap() const =0;
+
+/*! Pixel  (steradians) */
+virtual double PixSolAngle(int_4 k) const =0; 
+
+/*! Setting blockdata to temporary (see ndatablock documentation) */
+virtual void SetTemp(bool temp=false) const =0;
+
+
+/*! Overloading of () to access pixel number k. */
+inline T& operator()(int_4 k) {return(PixVal(k));}
+inline T const& operator()(int_4 k) const {return(PixVal(k));}
+
+// Overloading of () to access pixel at a sky position .
+inline T& operator()(const SpherePosition& spos) 
+                     { return(PixVal(PixIndex(spos))); }
+inline T const& operator()(const SpherePosition& spos) const 
+                     { return(PixVal(PixIndex(spos))); }
+
+
+// Note : no overloading of (double,double) to access pixel (theta,phi).
+// overloading of (double,double) in SphericalMap
+// overloading of (int,int)     in CartesianMap
+
+/*! Setting pixel values to a constant */
+virtual T SetPixels(T v);
+PixelMap<T>& SetT(T v);
+  //inline T operator = (T v) { return(SetPixels(v)); }
+inline PixelMap<T>& operator = (T v) { return(SetT(v)); }
+
+
+                     
+//++
+DVList& Info()
+//
+// Renvoie une reference sur l''objet DVList Associe
+//--
+  {
+    if (mInfo_ == NULL)  mInfo_ = new DVList;
+    return(*mInfo_);
+  }
+
+const DVList*  ptrInfo() const
+  {
+    return mInfo_;
+  }
+
+protected :
+    SphereCoordSys *cs_;   // Coordinate system used in the map
+    DVList* mInfo_;        // Infos (variables) attachees 
+};
+
+
+template <class T>
+int_4 PixelMap<T>::PixIndex(const SpherePosition& spos)
+{
+UnitVector v = spos.Transform(*cs_);
+return(PixIndexSph(v.Theta(), v.Phi()));
+}
+
+template <class T>
+bool PixelMap<T>::Contains(const SpherePosition& spos) const
+{
+UnitVector v = spos.Transform(*cs_);
+return(ContainsSph(v.Theta(), v.Phi()));
+}
+template <class T>
+T PixelMap<T>::SetPixels(T v)
+{
+int k;
+for(k=0; k<NbPixels(); k++) PixVal(k) = v;
+return(v);
+}
+template <class T>
+PixelMap<T>& PixelMap<T>::SetT(T v)
+{
+int k;
+for(k=0; k<NbPixels(); k++) PixVal(k) = v;
+return(*this);
+}
+
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyMap/skymap.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/skymap.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/skymap.h	(revision 2309)
@@ -0,0 +1,15 @@
+// This may look like C code, but it is really -*- C++ -*-
+//  All the include files for skymap 
+//                     R. Ansari, G. Le Meur   04/2000
+
+#ifndef ALLSKYMAP_H_SEEN
+#define ALLSKYMAP_H_SEEN
+
+#include "spherethetaphi.h"
+#include "spherehealpix.h"
+#include "localmap.h"
+#include "fiospherethetaphi.h"
+#include "fiospherehealpix.h"
+#include "fiolocalmap.h"
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyMap/skymapinit.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/skymapinit.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/skymapinit.cc	(revision 2309)
@@ -0,0 +1,100 @@
+// Classe d'initialisation du module Outils++ 
+#include "machdefs.h"
+#include "skymapinit.h" 
+
+#include <unistd.h>
+#include "spherethetaphi.h"
+#include "fiospherehealpix.h"
+#include "fiospherethetaphi.h"
+#include "fiolocalmap.h"
+#include "localmap.h"
+ 
+/*!
+   \defgroup SkyMap SkyMap module
+   This module contains classes for handling partial and full sky (spherical) maps
+*/
+
+/*!
+  \class SOPHYA::SkyMapInitiator
+  \ingroup SkyMap
+  Class handling initialization for module SkyMap
+*/
+
+int SkyMapInitiator::FgInit = 0;
+
+SkyMapInitiator::SkyMapInitiator()
+  : SophyaInitiator()
+{
+  FgInit++;
+  if (FgInit > 1)  return;
+
+//   Enregistrement des classes PPersist du module SkyMap
+  
+  // ---------- Les SphereThetaPhi ---------
+
+  PPRegister(FIO_SphereCoordSys);
+  DObjRegister(FIO_SphereCoordSys, SphereCoordSys);
+
+  PPRegister(FIO_SphereThetaPhi<int_4>);
+  DObjRegister(FIO_SphereThetaPhi<int_4>, SphereThetaPhi<int_4>);
+
+  PPRegister(FIO_SphereThetaPhi<r_4>);
+  DObjRegister(FIO_SphereThetaPhi<r_4>, SphereThetaPhi<r_4>);
+
+  PPRegister(FIO_SphereThetaPhi<r_8>);
+  DObjRegister(FIO_SphereThetaPhi<r_8>, SphereThetaPhi<r_8>);
+
+  PPRegister(FIO_SphereThetaPhi< complex<r_4> >);
+  DObjRegister(FIO_SphereThetaPhi< complex<r_4> >, SphereThetaPhi< complex<r_4> >);
+
+  PPRegister(FIO_SphereThetaPhi< complex<r_8> >);
+  DObjRegister(FIO_SphereThetaPhi< complex<r_8> >, SphereThetaPhi< complex<r_8> >);
+
+
+  // ---------- Les SphereHEALPix ---------
+
+  PPRegister(FIO_SphereHEALPix<int_4>);  
+  DObjRegister(FIO_SphereHEALPix<int_4>, SphereHEALPix<int_4>);
+
+  PPRegister(FIO_SphereHEALPix<r_4>);  
+  DObjRegister(FIO_SphereHEALPix<r_4>, SphereHEALPix<r_4>);
+
+  PPRegister(FIO_SphereHEALPix<r_8>);
+  DObjRegister(FIO_SphereHEALPix<r_8>, SphereHEALPix<r_8>);
+
+  PPRegister(FIO_SphereHEALPix< complex<r_4> >);
+  DObjRegister(FIO_SphereHEALPix< complex<r_4> >, SphereHEALPix< complex<r_4> >);
+
+  PPRegister(FIO_SphereHEALPix< complex<r_8> >);
+  DObjRegister(FIO_SphereHEALPix< complex<r_8> >, SphereHEALPix< complex<r_8> >);
+
+  // ------------ Les LocalMap ---------
+  PPRegister(FIO_LocalMap<int_4>);
+  DObjRegister(FIO_LocalMap<int_4>, LocalMap<int_4>);
+
+  PPRegister(FIO_LocalMap<r_4>);
+  DObjRegister(FIO_LocalMap<r_4>, LocalMap<r_4>);
+
+  PPRegister(FIO_LocalMap<r_8>);
+  DObjRegister(FIO_LocalMap<r_8>, LocalMap<r_8>);
+
+  PPRegister(FIO_LocalMap< complex<r_4> >);
+  DObjRegister(FIO_LocalMap< complex<r_4> >, LocalMap< complex<r_4> >);
+
+  PPRegister(FIO_LocalMap< complex<r_8> >);
+  DObjRegister(FIO_LocalMap< complex<r_8> >, LocalMap< complex<r_8> >);
+
+
+}
+
+SkyMapInitiator::~SkyMapInitiator()
+{
+  FgInit--;
+}
+
+
+// On met un objet initiator en statique, pour les loaders qui savent 
+// appeler le constructeur des objets statiques   Reza 08/98
+static SkyMapInitiator s_sskymapinit_;
+
+ 
Index: /tags/V_Dec2002/SophyaLib/SkyMap/skymapinit.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/skymapinit.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/skymapinit.h	(revision 2309)
@@ -0,0 +1,27 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe d'initialiseur du module SkyMap
+
+#ifndef SKYMAPINIT_H_SEEN
+#define SKYMAPINIT_H_SEEN
+
+
+// Classe d''initialisation pour le modules SkyMap
+#include "sophyainit.h"
+
+namespace SOPHYA {
+
+class SkyMapInitiator : public SophyaInitiator {
+private:
+  static int FgInit;
+public:
+  			SkyMapInitiator();
+  virtual		~SkyMapInitiator();
+};
+
+#undef SophyaInit
+#define SophyaInit() SkyMapInitiator skymapinitiator
+
+} // Fin du namespace
+
+#endif
+
Index: /tags/V_Dec2002/SophyaLib/SkyMap/spherehealpix.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/spherehealpix.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/spherehealpix.cc	(revision 2309)
@@ -0,0 +1,710 @@
+#include "machdefs.h"
+#include <math.h>
+#include <complex>
+
+#include "pexceptions.h"
+#include "fiondblock.h"
+#include "spherehealpix.h"
+#include "strutil.h"
+
+extern "C" 
+{
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+}
+      
+using namespace SOPHYA;
+
+/*!
+  \class SOPHYA::SphereHEALPix
+  \ingroup SkyMap
+  Class implementing spherical maps, in the HEALPix pixelisation scheme, 
+  with template data types (double, float, complex, ...)
+
+
+\verbatim
+
+    -----------------------------------------------------------------------
+     version 0.8.2  Aug97 TAC  Eric Hivon, Kris Gorski
+    -----------------------------------------------------------------------
+
+    the sphere is split in 12 diamond-faces containing nside**2 pixels each
+    the numbering of the pixels (in the nested scheme) is similar to
+    quad-cube
+    In each face the first pixel is in the lowest corner of the diamond
+    the faces are                    (x,y) coordinate on each face
+
+        .   .   .   .   <--- North Pole
+       / \ / \ / \ / \                          ^        ^     
+      . 0 . 1 . 2 . 3 . <--- z = 2/3             \      / 
+       \ / \ / \ / \ /                        y   \    /  x  
+      4 . 5 . 6 . 7 . 4 <--- equator               \  /      
+       / \ / \ / \ / \                              \/      
+      . 8 . 9 .10 .11 . <--- z = -2/3              (0,0) : lowest corner 
+       \ / \ / \ / \ /      
+        .   .   .   .   <--- South Pole
+\endverbatim
+    phi:0               2Pi                                 
+
+   in the ring scheme pixels are numbered along the parallels
+   the first parallel is the one closest to the north pole and so on  
+   on each parallel, pixels are numbered starting from the one closest
+    to phi = 0
+
+    nside MUST be a power of 2 (<= 8192)
+
+*/
+
+/* --Methode-- */
+
+template<class T>
+SphereHEALPix<T>::SphereHEALPix() : pixels_(), sliceBeginIndex_(), 
+                                                sliceLenght_()
+
+
+{
+  InitNul();
+}
+
+/*! \fn   SOPHYA::SphereHEALPix::SphereHEALPix(int_4 m)
+ 
+  \param <m> : "nside" of the Healpix algorithm
+
+  The total number of pixels will be Npix =  12*nside**2
+
+  nside MUST be a power of 2 (<= 8192)
+*/
+
+template<class T>
+SphereHEALPix<T>::SphereHEALPix(int_4 m)
+
+{
+
+  if(m <= 0 || m > 8192) 
+    {
+      cout << "SphereHEALPix : m hors bornes [0,8192], m= " << m << endl;
+      throw RangeCheckError("SphereHEALPix<T>::SphereHEALPix() - Out of bound nside (< 8192)!");
+    }
+  // verifier que m est une puissance de deux 
+  int x= m;
+  while(x%2 == 0) x/=2;
+  if(x != 1) 
+    {  
+      cout<<"SphereHEALPix: m doit etre une puissance de deux, m= "<<m<<endl;
+      throw ParmError("SphereHEALPix<T>::SphereHEALPix() - nside != 2^n !");
+    }
+  InitNul();
+  Pixelize(m);
+  SetThetaSlices();
+}
+//++
+template<class T>
+SphereHEALPix<T>::SphereHEALPix(const SphereHEALPix<T>& s, bool share)
+  : pixels_(s.pixels_, share), sliceBeginIndex_(s.sliceBeginIndex_, share), 
+				sliceLenght_(s.sliceLenght_, share)
+//    copy constructor
+//--
+{
+  nSide_= s.nSide_;
+  nPix_ = s.nPix_;
+  omeg_ = s.omeg_;
+  if(s.mInfo_) mInfo_= new DVList(*s.mInfo_);
+}
+//++
+template<class T>
+SphereHEALPix<T>::SphereHEALPix(const SphereHEALPix<T>& s)
+  : pixels_(s.pixels_), sliceBeginIndex_(s.sliceBeginIndex_), 
+				sliceLenght_(s.sliceLenght_)
+//    copy constructor
+//--
+{
+  nSide_= s.nSide_;
+  nPix_ = s.nPix_;
+  omeg_ = s.omeg_;
+  if(s.mInfo_) mInfo_= new DVList(*s.mInfo_);
+  //  CloneOrShare(s);
+}
+
+//! Clone if \b a is not temporary, share if temporary
+/*! \sa NDataBlock::CloneOrShare(const NDataBlock<T>&) */
+template<class T>
+void SphereHEALPix<T>::CloneOrShare(const SphereHEALPix<T>& a)
+{
+  nSide_= a.nSide_;
+  nPix_ = a.nPix_;
+  omeg_ = a.omeg_;
+  pixels_.CloneOrShare(a.pixels_);
+  sliceBeginIndex_.CloneOrShare(a.sliceBeginIndex_);
+  sliceLenght_.CloneOrShare(a.sliceLenght_);
+  if (mInfo_) {delete mInfo_; mInfo_ = NULL;}
+  if (a.mInfo_) mInfo_ = new DVList(*(a.mInfo_));
+}
+
+//! Share data with a
+template<class T>
+void SphereHEALPix<T>::Share(const SphereHEALPix<T>& a)
+{
+  nSide_= a.nSide_;
+  nPix_ = a.nPix_;
+  omeg_ = a.omeg_;
+  pixels_.Share(a.pixels_);
+  sliceBeginIndex_.Share(a.sliceBeginIndex_);
+  sliceLenght_.Share(a.sliceLenght_);
+  if (mInfo_) {delete mInfo_; mInfo_ = NULL;}
+  if (a.mInfo_) mInfo_ = new DVList(*(a.mInfo_));
+}
+
+////////////////////////// methodes de copie/share
+template<class T>
+SphereHEALPix<T>& SphereHEALPix<T>::Set(const SphereHEALPix<T>& a)
+{
+  if (this != &a) 
+    { 
+      
+      if (a.NbPixels() < 1) 
+	throw RangeCheckError("SphereHEALPix<T>::Set(a ) - SphereHEALPix a not allocated ! ");
+      if (NbPixels() < 1) CloneOrShare(a);
+      else CopyElt(a);
+      
+      
+      if (mInfo_) delete mInfo_;
+      mInfo_ = NULL;
+      if (a.mInfo_) mInfo_ = new DVList(*(a.mInfo_));
+    }
+  return(*this);
+}
+
+template<class T>
+SphereHEALPix<T>& SphereHEALPix<T>::CopyElt(const SphereHEALPix<T>& a)
+{
+  if (NbPixels() < 1) 
+    throw RangeCheckError("SphereHEALPix<T>::CopyElt(const SphereHEALPix<T>& )  - Not Allocated SphereHEALPix ! ");
+  if (NbPixels() != a.NbPixels()) 
+    throw(SzMismatchError("SphereHEALPix<T>::CopyElt(const SphereHEALPix<T>&) SizeMismatch")) ;
+  nSide_= a.nSide_;
+  nPix_ = a.nPix_;
+  omeg_ = a.omeg_;
+  int k;
+  for (k=0; k< nPix_; k++) pixels_(k) = a.pixels_(k);
+  for (k=0; k< a.sliceBeginIndex_.Size(); k++) sliceBeginIndex_(k) = a.sliceBeginIndex_(k);
+  for (k=0; k< a.sliceLenght_.Size(); k++) sliceLenght_(k) = a.sliceLenght_(k);
+  return(*this);
+}
+
+
+
+//++
+// Titre	Destructor
+//--
+//++
+template<class T>
+SphereHEALPix<T>::~SphereHEALPix()
+
+//--
+{
+}
+
+//++
+// Titre	Public Methods
+//--
+
+/*!  \fn   void SOPHYA::SphereHEALPix::Resize(int_4 m)
+  \param <m>   "nside" of the Gorski algorithm
+
+  The total number of pixels will be Npix =  12*nside**2
+
+  nside MUST be a power of 2 (<= 8192)
+*/
+template<class T>
+void SphereHEALPix<T>::Resize(int_4 m)
+
+
+{
+  if (m<=0 || m> 8192) {
+    cout << "SphereHEALPix : m hors bornes [0,8192], m= " << m << endl;
+    exit(1);
+  }
+  // verifier que m est une puissance de deux 
+  int x= m;
+  while (x%2==0) x/=2;
+  if(x != 1) 
+    {  
+      cout<<"SphereHEALPix: m doit etre une puissance de deux, m= "<<m<<endl;
+      exit(1);
+    }
+  InitNul();
+  Pixelize(m);
+  SetThetaSlices();
+}
+
+template<class T>
+void  SphereHEALPix<T>::Pixelize( int_4 m) 
+
+//    prépare la pixelisation Gorski (m a la même signification 
+//    que pour le constructeur)
+//
+//    
+{
+  // On memorise les arguments d'appel
+  nSide_= m;  
+
+  // Nombre total de pixels sur la sphere entiere
+  nPix_= 12*nSide_*nSide_;
+
+  // pour le moment les tableaux qui suivent seront ranges dans l'ordre 
+  // de l'indexation GORSKY "RING"
+  // on pourra ulterieurement changer de strategie et tirer profit
+  // de la dualite d'indexation GORSKY (RING et NEST) : tout dependra 
+  // de pourquoi c'est faire
+
+  // Creation et initialisation du vecteur des contenus des pixels 
+  pixels_.ReSize(nPix_);
+  pixels_.Reset();
+
+  // solid angle per pixel   
+  omeg_= 4.0*Pi/nPix_;
+}
+
+template<class T>
+void SphereHEALPix<T>::InitNul()
+//
+//    initialise à zéro les variables de classe 
+{
+  nSide_= 0;
+  nPix_ = 0;
+  omeg_ = 0.;
+//  pixels_.Reset();  -  Il ne faut pas mettre les pixels a zero si share !
+}
+
+/* --Methode-- */
+/* Nombre de pixels du decoupage */
+/*! \fn int_4 SOPHYA::SphereHEALPix::NbPixels() const
+
+   Return number of  pixels of the  splitting 
+*/
+template<class T>
+int_4 SphereHEALPix<T>::NbPixels() const
+{  
+  return(nPix_);
+}
+
+
+/*! \fn uint_4 SOPHYA::SphereHEALPix::NbThetaSlices() const
+
+   \return number of slices in theta direction on the  sphere 
+*/
+template<class T>
+uint_4 SphereHEALPix<T>::NbThetaSlices() const 
+{
+  uint_4 nbslices = uint_4(4*nSide_-1);
+  if (nSide_<=0) 
+    {
+      nbslices = 0;
+      throw PException(" sphere not pixelized, NbSlice=0 ");
+    }
+  return nbslices;
+}
+
+/*!  \fn void SOPHYA::SphereHEALPix::GetThetaSlice(int_4 index,r_8& theta,TVector<r_8>& phi,TVector<T>& value) const 
+
+ For a theta-slice with index 'index', return :
+ 
+   the corresponding "theta" 
+
+   a vector containing the phi's of the pixels of the slice
+
+   a vector containing the corresponding values of pixels 
+*/
+template<class T>
+void SphereHEALPix<T>::GetThetaSlice(int_4 index,r_8& theta,TVector<r_8>& phi,TVector<T>& value) const 
+
+{
+
+  if (index<0 || index >= NbThetaSlices()) 
+    {
+      cout << " SphereHEALPix::GetThetaSlice : Pixel index out of range" <<endl;
+      throw RangeCheckError(" SphereHEALPix::GetThetaSlice : Pixel index out of range");
+    }
+
+
+  int_4 iring= sliceBeginIndex_(index);
+  int_4 lring  =  sliceLenght_(index);
+
+   phi.ReSize(lring);
+   value.ReSize(lring);
+
+  double TH= 0.;
+  double FI= 0.;
+  for(int_4 kk = 0; kk < lring;kk++) 
+    {
+      PixThetaPhi(kk+iring,TH,FI);
+      phi(kk)= FI;
+      value(kk)= PixVal(kk+iring);
+    }
+  theta= TH;
+}
+/*! \fn void SOPHYA::SphereHEALPix::GetThetaSlice(int_4 sliceIndex,r_8& theta, r_8& phi0, TVector<int_4>& pixelIndices,TVector<T>& value) const
+
+   For a theta-slice with index 'index', return : 
+
+   the corresponding "theta" 
+
+   the corresponding "phi" for first pixel of the slice 
+
+    a vector containing indices of the pixels of the slice
+
+   (equally distributed in phi)
+
+    a vector containing the corresponding values of pixels 
+*/
+
+template<class T>
+void SphereHEALPix<T>::GetThetaSlice(int_4 sliceIndex,r_8& theta, r_8& phi0, TVector<int_4>& pixelIndices,TVector<T>& value) const 
+
+{
+
+  if (sliceIndex<0 || sliceIndex >= NbThetaSlices()) 
+    {
+      cout << " SphereHEALPix::GetThetaSlice : Pixel index out of range" <<endl;
+      throw RangeCheckError(" SphereHEALPix::GetThetaSlice : Pixel index out of range");
+    }
+  int_4 iring= sliceBeginIndex_(sliceIndex);
+  int_4 lring  =  sliceLenght_(sliceIndex);
+  pixelIndices.ReSize(lring);
+  value.ReSize(lring);
+
+  for(int_4 kk = 0; kk < lring;kk++) 
+    {
+      pixelIndices(kk)= kk+iring;
+      value(kk)= PixVal(kk+iring);
+    }
+  PixThetaPhi(iring, theta, phi0);
+}
+
+template<class T>
+void SphereHEALPix<T>::SetThetaSlices()  
+{
+  sliceBeginIndex_.ReSize(4*nSide_-1);
+  sliceLenght_.ReSize(4*nSide_-1);
+  int sliceIndex;
+  for (sliceIndex=0; sliceIndex<  nSide_-1; sliceIndex++)
+    {
+      sliceBeginIndex_(sliceIndex)  = 2*sliceIndex*(sliceIndex+1);
+      sliceLenght_(sliceIndex) = 4*(sliceIndex+1);
+    }
+  for (sliceIndex= nSide_-1; sliceIndex<  3*nSide_; sliceIndex++)
+    {
+      sliceBeginIndex_(sliceIndex)  = 2*nSide_*(2*sliceIndex-nSide_+1);
+      sliceLenght_(sliceIndex) = 4*nSide_;
+    }
+  for (sliceIndex= 3*nSide_; sliceIndex< 4*nSide_-1; sliceIndex++)
+    {
+      int_4 nc= 4*nSide_-1-sliceIndex;
+      sliceBeginIndex_(sliceIndex)  = nPix_-2*nc*(nc+1); 
+      sliceLenght_(sliceIndex) = 4*nc;
+    }
+}
+
+
+/*! \fn T& SOPHYA::SphereHEALPix::PixVal(int_4 k)
+
+   \return value of  pixel with "RING" index k 
+*/
+template<class T>
+T& SphereHEALPix<T>::PixVal(int_4 k)
+
+{
+  if((k < 0) || (k >= nPix_)) 
+    {
+      throw RangeCheckError("SphereHEALPix::PIxVal Pixel index out of range");
+    }
+  return pixels_(k);
+}
+
+/*! \fn T const& SOPHYA::SphereHEALPix::PixVal(int_4 k) const
+
+   \return value of  pixel with "RING" index k 
+*/
+template<class T>
+T const& SphereHEALPix<T>::PixVal(int_4 k) const
+
+{
+  if((k < 0) || (k >= nPix_)) 
+    {
+      throw RangeCheckError("SphereHEALPix::PIxVal Pixel index out of range");
+    }
+  return *(pixels_.Data()+k);
+}
+
+/*! \fn T& SOPHYA::SphereHEALPix::PixValNest(int_4 k)
+
+   \return value of  pixel with "NESTED" index k 
+*/
+template<class T>
+T& SphereHEALPix<T>::PixValNest(int_4 k)
+
+//--
+{
+  if((k < 0) || (k >= nPix_)) 
+    { 
+      throw RangeCheckError("SphereHEALPix::PIxValNest Pixel index out of range");
+    }
+  return pixels_(nest2ring(nSide_,k));
+}
+
+/*!  \fn T const& SOPHYA::SphereHEALPix::PixValNest(int_4 k) const
+
+  \return value of  pixel with "NESTED" index k 
+*/
+
+template<class T>
+T const& SphereHEALPix<T>::PixValNest(int_4 k) const
+
+{
+  if((k < 0) || (k >= nPix_)) 
+    { 
+      throw RangeCheckError("SphereHEALPix::PIxValNest Pixel index out of range");
+  }
+  int_4 pix= nest2ring(nSide_,k);
+  return *(pixels_.Data()+pix);
+}
+
+/*! \fn bool SOPHYA::SphereHEALPix::ContainsSph(double theta, double phi) const
+
+\return true if teta,phi in map 
+*/
+template<class T>
+bool SphereHEALPix<T>::ContainsSph(double theta, double phi) const
+{
+return(true);
+}
+
+/*! \fn int_4 SOPHYA::SphereHEALPix::PixIndexSph(double theta,double phi) const
+
+ \return "RING" index of the pixel corresponding to direction (theta, phi).
+ */
+template<class T>
+int_4 SphereHEALPix<T>::PixIndexSph(double theta,double phi) const
+
+{
+  return ang2pix_ring(nSide_,theta,phi);
+}
+
+/*! \fn int_4 SOPHYA::SphereHEALPix::PixIndexSphNest(double theta,double phi) const
+
+ \return "NESTED" index of the pixel corresponding to direction (theta, phi).
+ */
+template<class T>
+int_4 SphereHEALPix<T>::PixIndexSphNest(double theta,double  phi) const
+
+{
+  return ang2pix_nest(nSide_,theta,phi);
+}
+
+
+/* --Methode-- */
+/*! \fn void SOPHYA::SphereHEALPix::PixThetaPhi(int_4 k,double& theta,double& phi) const
+ \return (theta,phi) coordinates of middle of  pixel with "RING" index k
+ */
+template<class T>
+void SphereHEALPix<T>::PixThetaPhi(int_4 k,double& theta,double& phi) const
+{
+  pix2ang_ring(nSide_,k,theta,phi);
+}
+
+/*! \fn T SOPHYA::SphereHEALPix::SetPixels(T v)
+
+Set all pixels to value v 
+*/
+template <class T>
+T SphereHEALPix<T>::SetPixels(T v)
+{
+pixels_.Reset(v);
+return(v);
+}
+
+
+
+/*! \fn void SOPHYA::SphereHEALPix::PixThetaPhiNest(int_4 k,double& theta,double& phi) const
+
+  \return (theta,phi) coordinates of middle of  pixel with "NESTED" index k
+ */
+template<class T>
+void SphereHEALPix<T>::PixThetaPhiNest(int_4 k,double& theta,double& phi) const
+
+{   
+  pix2ang_nest(nSide_,k,theta,phi);
+}
+
+
+/*! \fn int_4 SOPHYA::SphereHEALPix::NestToRing(int_4 k) const
+
+   translation from NESTED index  into RING index 
+*/
+template<class T>
+int_4 SphereHEALPix<T>::NestToRing(int_4 k) const
+
+{
+  return  nest2ring(nSide_,k);
+}
+
+
+/*!  \fn  int_4 SOPHYA::SphereHEALPix::RingToNest(int_4 k) const
+
+ translation from  RING index  into NESTED index 
+*/
+template<class T>
+int_4 SphereHEALPix<T>::RingToNest(int_4 k) const
+{
+  return  ring2nest(nSide_,k);
+}
+
+//   ...... Operations de calcul  ......
+
+//! Fill a SphereHEALPix with a constant value \b a
+template <class T>
+SphereHEALPix<T>& SphereHEALPix<T>::SetT(T a) 
+{
+  if (NbPixels() < 1) 
+    throw RangeCheckError("SphereHEALPix<T>::SetT(T )  - SphereHEALPix not dimensionned ! ");
+  pixels_ = a;
+  return (*this);
+}
+
+/*! Add a constant value \b x to a SphereHEALPix */
+template <class T>
+SphereHEALPix<T>& SphereHEALPix<T>::Add(T a)
+ {
+   cout << " c'est mon Add " << endl;
+  if (NbPixels() < 1) 
+    throw RangeCheckError("SphereHEALPix<T>::Add(T )  - SphereHEALPix not dimensionned ! ");
+  //   pixels_ += a; 
+   pixels_.Add(a); 
+  return (*this);
+}
+
+/*! Substract a constant value \b a to a SphereHEALPix */
+template <class T>
+SphereHEALPix<T>& SphereHEALPix<T>::Sub(T a,bool fginv) 
+{
+  if (NbPixels() < 1) 
+    throw RangeCheckError("SphereHEALPix<T>::Sub(T )  - SphereHEALPix not dimensionned ! ");
+  pixels_.Sub(a,fginv); 
+  return (*this);
+} 
+
+/*! multiply a SphereHEALPix by a constant value \b a */
+template <class T>
+SphereHEALPix<T>& SphereHEALPix<T>::Mul(T a) 
+{
+  if (NbPixels() < 1) 
+    throw RangeCheckError("SphereHEALPix<T>::Mul(T )  - SphereHEALPix not dimensionned ! ");
+  pixels_ *= a; 
+  return (*this);
+}
+
+/*! divide a SphereHEALPix by a constant value \b a */
+template <class T>
+SphereHEALPix<T>& SphereHEALPix<T>::Div(T a) 
+{
+  if (NbPixels() < 1) 
+    throw RangeCheckError("SphereHEALPix<T>::Div(T )  - SphereHEALPix not dimensionned ! ");
+  pixels_ /= a; 
+  return (*this);
+} 
+
+//  >>>> Operations avec 2nd membre de type SphereHEALPix
+//! Add two SphereHEALPix
+
+template <class T>
+SphereHEALPix<T>& SphereHEALPix<T>::AddElt(const SphereHEALPix<T>& a)
+{
+  if (NbPixels() != a.NbPixels() )
+    {
+    throw(SzMismatchError("SphereHEALPix<T>::AddElt(const SphereHEALPix<T>&) SizeMismatch")) ;
+    }
+  pixels_ += a.pixels_;
+  return (*this);
+}
+
+//! Substract two SphereHEALPix
+template <class T>
+SphereHEALPix<T>& SphereHEALPix<T>::SubElt(const SphereHEALPix<T>& a)
+{
+  if (NbPixels() != a.NbPixels() )
+    {
+    throw(SzMismatchError("SphereHEALPix<T>::SubElt(const SphereHEALPix<T>&) SizeMismatch")) ;
+    }
+  pixels_ -= a.pixels_;
+  return (*this);
+}
+
+//! Multiply two SphereHEALPix (elements by elements)
+template <class T>
+SphereHEALPix<T>& SphereHEALPix<T>::MulElt(const SphereHEALPix<T>& a)
+{
+  if (NbPixels() != a.NbPixels() )
+    {
+    throw(SzMismatchError("SphereHEALPix<T>::MulElt(const SphereHEALPix<T>&) SizeMismatch")) ;
+    }
+  pixels_ *= a.pixels_;
+  return (*this);
+}
+
+//! Divide two SphereHEALPix (elements by elements) - No protection for divide by 0
+template <class T>
+SphereHEALPix<T>& SphereHEALPix<T>::DivElt(const SphereHEALPix<T>& a)
+{
+  if (NbPixels() != a.NbPixels() )
+    {
+    throw(SzMismatchError("SphereHEALPix<T>::DivElt(const SphereHEALPix<T>&) SizeMismatch")) ;
+    }
+  pixels_ /= a.pixels_;
+  return (*this);
+}
+
+
+
+
+template <class T>
+void SphereHEALPix<T>::print(ostream& os) const
+{
+  if(mInfo_) os << "  DVList Info= " << *mInfo_ << endl;
+  //
+  os << " nSide_ = " << nSide_  << endl;
+  os << " nPix_   = " << nPix_   << endl;
+  os << " omeg_ = " << omeg_   << endl;
+
+  os << " content of pixels : ";
+  for(int i=0; i < nPix_; i++)
+    {
+      if(i%5 == 0) os << endl;
+      os <<  pixels_(i) <<", ";
+    }
+  os << endl;
+
+
+}
+
+
+
+//*******************************************************************
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template SphereHEALPix<uint_2>
+#pragma define_template SphereHEALPix<int_4>
+#pragma define_template SphereHEALPix<r_8>
+#pragma define_template SphereHEALPix<r_4>
+#pragma define_template SphereHEALPix< complex<r_4> >
+#pragma define_template SphereHEALPix< complex<r_8> >
+#endif
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class SphereHEALPix<uint_2>;
+template class SphereHEALPix<int_4>;
+template class SphereHEALPix<r_8>;
+template class SphereHEALPix<r_4>;
+template class SphereHEALPix< complex<r_4> >;
+template class SphereHEALPix< complex<r_8> >;
+#endif
+
Index: /tags/V_Dec2002/SophyaLib/SkyMap/spherehealpix.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/spherehealpix.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/spherehealpix.h	(revision 2309)
@@ -0,0 +1,305 @@
+#ifndef SPHEREHEALPIX_SEEN
+#define SPHEREHEALPIX_SEEN
+
+#include "sphericalmap.h"
+#include "tvector.h"
+#include "ndatablock.h"
+
+#include "anydataobj.h"
+#include "ppersist.h"
+
+#include "HEALPixUtils.h"
+
+namespace SOPHYA {
+
+
+// ***************** CLASSE SphereHEALPix *****************************
+
+  /*! Class SphereHEALPix */
+
+
+template<class T>
+class FIO_SphereHEALPix;
+
+template<class T>
+class FITS_SphereHEALPix;
+
+template<class T>
+class SphereHEALPix : public SphericalMap<T>
+{
+public :
+// Static Methods to ease the use of HEALPix index <> angle conversion methods
+
+  static inline int_4  nest2ring(int_4 nside,int_4 ipnest) 
+         { return HEALPix::nest2ring(nside, ipnest); }
+  static inline int_4  ring2nest(int_4 nside,int_4 ipring) 
+         { return HEALPix::ring2nest(nside, ipring); }
+  static inline int_4  ang2pix_ring(int_4 nside,double theta,double phi) 
+         { return HEALPix::ang2pix_ring(nside, theta, phi); }
+  static inline int_4  ang2pix_nest(int_4 nside,double theta,double phi) 
+         { return HEALPix::ang2pix_nest(nside, theta, phi); }
+  static inline void   pix2ang_ring(int_4 nside,int_4 ipix,double& theta,double& phi) 
+         { HEALPix::pix2ang_ring(nside, ipix, theta, phi); }
+  static inline void   pix2ang_nest(int_4 nside,int_4 ipix,double& theta,double& phi) 
+         { HEALPix::pix2ang_nest(nside, ipix, theta, phi); }
+
+SphereHEALPix();
+SphereHEALPix(int_4 m);
+SphereHEALPix(const SphereHEALPix<T>& s, bool share);
+SphereHEALPix(const SphereHEALPix<T>& s);
+virtual ~SphereHEALPix();
+
+inline virtual bool   IsTemp(void) const {
+
+    if (sliceBeginIndex_.IsTemp() != pixels_.IsTemp() || sliceLenght_.IsTemp() != pixels_.IsTemp() )
+      throw PException(" l'etat 'temporaire' de la spherehealpix est incoherent"); 
+    return pixels_.IsTemp();
+}
+
+inline virtual void SetTemp(bool temp=false) const 
+  {
+    pixels_.SetTemp(temp);
+    sliceBeginIndex_.SetTemp(temp);
+    sliceLenght_.SetTemp(temp);
+  };
+// ------------------ Definition of PixelMap abstract methods
+
+virtual int_4 NbPixels() const;
+
+virtual T& PixVal(int_4 k);
+virtual T const& PixVal(int_4 k) const;
+
+uint_4 NbThetaSlices() const;
+virtual void GetThetaSlice(int_4 index,r_8& theta,TVector<r_8>& phi,TVector<T>& value) const;
+virtual void GetThetaSlice(int_4 sliceIndex,r_8& theta, r_8& phi0, TVector<int_4>& pixelIndices,TVector<T>& value) const ;
+
+virtual bool ContainsSph(double theta, double phi) const;
+virtual int_4 PixIndexSph(double theta,double phi) const;
+
+virtual void PixThetaPhi(int_4 k,double& theta,double& phi) const;
+
+virtual T SetPixels(T v);
+
+/*! Pixel Solid angle  (steradians)
+
+    All the pixels have the same solid angle. The dummy argument is
+    for compatibility with eventual pixelizations which would not 
+   fulfil this requirement.
+*/
+inline virtual double PixSolAngle(int_4 dummy=0) const {return omeg_;}
+
+/*  Acces to the DataBlock  */
+inline       NDataBlock<T>& DataBlock()       {return pixels_;}
+inline const NDataBlock<T>& DataBlock() const {return pixels_;}
+
+// --------------- Specific methods 
+
+virtual void Resize(int_4 m);
+
+/*! 
+
+\return type of storage of the map : RING or NESTED
+
+at the moment, always RING
+*/
+inline virtual string TypeOfMap() const {return string("RING");};
+
+
+virtual T& PixValNest(int_4 k);
+virtual T const& PixValNest(int_4 k) const;
+
+virtual int_4 PixIndexSphNest(double theta,double phi) const;
+
+virtual void PixThetaPhiNest(int_4 k,double& theta,double& phi) const;
+
+void Pixelize(int_4); 
+
+int_4 NestToRing(int_4) const;
+
+int_4 RingToNest(int_4) const;
+
+
+/*! \return value of healpix nside */
+inline virtual int_4 SizeIndex() const {return(nSide_);}
+
+void print(ostream& os) const;
+
+
+
+
+ 
+
+
+
+// Operations diverses  = , +=, ...
+
+
+SphereHEALPix<T>& Set(const SphereHEALPix<T>& a);
+inline  SphereHEALPix<T>& operator = (const SphereHEALPix<T>& a) 
+                                                        {return Set(a);}
+
+// A += -= *= /= x (ajoute, soustrait, ... x a tous les elements)
+
+  //! Fill SphereHEALPix with all elements equal to \b x
+virtual SphereHEALPix<T>& SetT(T a); 
+inline  SphereHEALPix<T>& operator = (T a) {return SetT(a);}
+
+//! Add \b x to all elements
+virtual SphereHEALPix<T>& Add(T a); 
+inline  SphereHEALPix<T>&  operator += (T x)  { pixels_ += x; return *this; }
+//! Substract \b x to all elements
+virtual SphereHEALPix<T>& Sub(T a,bool fginv=false); 
+inline   SphereHEALPix<T>&  operator -= (T x)  { pixels_ -= x; return *this; }
+//! Multiply all elements by \b x
+virtual SphereHEALPix<T>& Mul(T a); 
+inline  SphereHEALPix<T>&  operator *= (T x)  {pixels_ *= x; return *this; }
+//! Divide all elements by \b x
+virtual SphereHEALPix<T>& Div(T a); 
+inline  SphereHEALPix<T>&  operator /= (T x)  {pixels_ /= x; return *this; }
+
+// A += -=  (ajoute, soustrait element par element les deux spheres )
+  //! Operator SphereHEALPix += SphereHEALPix
+  virtual SphereHEALPix<T>&  AddElt(const SphereHEALPix<T>& a);
+  inline  SphereHEALPix<T>&  operator += (const SphereHEALPix<T>& a)  { return AddElt(a); }
+
+
+
+  virtual SphereHEALPix<T>&  SubElt(const SphereHEALPix<T>& a);
+  //! Operator SphereHEALPix -= SphereHEALPix
+  inline  SphereHEALPix<T>&  operator -= (const SphereHEALPix<T>& a)  { return SubElt(a); }
+// Multiplication, division element par element les deux SphereHEALPix 
+  virtual SphereHEALPix<T>&  MulElt(const SphereHEALPix<T>& a);
+  inline  SphereHEALPix<T>&  operator *= (const SphereHEALPix<T>& a)  { return MulElt(a); }
+  virtual SphereHEALPix<T>&  DivElt(const SphereHEALPix<T>& a);
+  inline  SphereHEALPix<T>&  operator /= (const SphereHEALPix<T>& a)  { return DivElt(a); }
+
+
+ void CloneOrShare(const SphereHEALPix<T>& a);
+ void Share(const SphereHEALPix<T>& a);
+ SphereHEALPix<T>& CopyElt(const SphereHEALPix<T>& a);
+
+
+ // friend declaration for classes which handle persistence and FITS IO
+ friend class FIO_SphereHEALPix<T>;
+ friend class FITS_SphereHEALPix<T>;
+       
+protected :
+
+// ------------- méthodes internes ----------------------
+void InitNul();
+void SetThetaSlices(); 
+
+inline void setParameters(int_4 nside, int_4 nbpixels, double solangle) 
+  {
+    nSide_= nside;
+    nPix_= nbpixels;
+    omeg_= solangle;
+  }
+
+// ------------- variables internes -----------------------
+
+int_4 nSide_;
+int_4 nPix_;
+double omeg_;
+
+NDataBlock<T> pixels_;
+NDataBlock<int_4> sliceBeginIndex_;	    // Rationalisation Mac. D.Y.
+NDataBlock<int_4> sliceLenght_;
+
+};
+
+////////////////////////////////////////////////////////////////
+// Surcharge d'operateurs A (+,-,*,/) (T) x
+/*! \ingroup SkyMap \fn operator+(const SphereHEALPix<T>&,T)
+  \brief Operator SphereHEALPix = SphereHEALPix + constant */
+template <class T> inline SphereHEALPix<T> operator + (const SphereHEALPix<T>& a, T b)
+    {SphereHEALPix<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Add(b); return result;}
+/*! \ingroup SkyMap \fn operator+(T,const SphereHEALPix<T>&)
+  \brief Operator SphereHEALPix = constant + SphereHEALPix */
+template <class T> inline SphereHEALPix<T> operator + (T b,const SphereHEALPix<T>& a)
+    {SphereHEALPix<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Add(b); return result;}
+
+
+/*! \ingroup SphereHEALPix\fn operator-(const SphereHEALPix<T>&,T)
+  \brief Operator SphereHEALPix = SphereHEALPix - constant */
+template <class T> inline SphereHEALPix<T> operator - (const SphereHEALPix<T>& a, T b)
+    {SphereHEALPix<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Sub(b); return result;}
+
+/*! \ingroup  \fn operator-(T,const SphereHEALPix<T>&)
+  \brief Operator SphereHEALPix = constant - SphereHEALPix */
+template <class T> inline SphereHEALPix<T> operator - (T b,const SphereHEALPix<T>& a)
+    {SphereHEALPix<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Sub(b,true); return result;}
+
+/*! \ingroup SkyMap \fn operator*(const SphereHEALPix<T>&,T)
+  \brief Operator SphereHEALPix = SphereHEALPix * constant */
+template <class T> inline SphereHEALPix<T> operator * (const SphereHEALPix<T>& a, T b)
+    {SphereHEALPix<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Mul(b); return result;}
+
+/*! \ingroup SkyMap \fn operator*(T,const SphereHEALPix<T>&)
+  \brief Operator SphereHEALPix = constant * SphereHEALPix */
+template <class T> inline SphereHEALPix<T> operator * (T b,const SphereHEALPix<T>& a)
+    {SphereHEALPix<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Mul(b); return result;}
+
+/*! \ingroup SkyMap \fn operator/(const SphereHEALPix<T>&,T)
+  \brief Operator SphereHEALPix = SphereHEALPix / constant */
+template <class T> inline SphereHEALPix<T> operator / (const SphereHEALPix<T>& a, T b)
+    {SphereHEALPix<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Div(b); return result;}
+
+/*! \ingroup SkyMap \fn operator/(T,const SphereHEALPix<T>&)
+  \brief Operator SphereHEALPix = constant / SphereHEALPix  */
+template <class T> inline SphereHEALPix<T> operator / (T b, const SphereHEALPix<T>& a)
+    {SphereHEALPix<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Div(b, true); return result;}
+
+////////////////////////////////////////////////////////////////
+// Surcharge d'operateurs C = A (+,-) B
+
+/*! \ingroup SkyMap \fn operator+(const SphereHEALPix<T>&,const SphereHEALPix<T>&)
+  \brief Operator SphereHEALPix = SphereHEALPix + SphereHEALPix */
+template <class T>
+inline SphereHEALPix<T> operator + (const SphereHEALPix<T>& a,const SphereHEALPix<T>& b)
+    { SphereHEALPix<T> result; result.SetTemp(true); 
+    if (b.IsTemp())  { result.Share(b); result.AddElt(a); }
+    else { result.CloneOrShare(a); result.AddElt(b); }
+    return result; }
+
+/*! \ingroup SkyMap \fn operator-(const SphereHEALPix<T>&,const SphereHEALPix<T>&)
+  \brief Operator SphereHEALPix = SphereHEALPix - SphereHEALPix */
+template <class T>
+inline SphereHEALPix<T> operator - (const SphereHEALPix<T>& a,const SphereHEALPix<T>& b)
+    { SphereHEALPix<T> result; result.SetTemp(true); 
+    if (b.IsTemp())  { result.Share(b); result.SubElt(a); }
+    else { result.CloneOrShare(a); result.SubElt(b); }
+    return result; }
+
+////////////////////////////////////////////////////////////////
+// Surcharge d'operateurs C = A (*,/) B
+
+/*! \ingroup SkyMap \fn operator*(const SphereHEALPix<T>&,const SphereHEALPix<T>&)
+  \brief Operator SphereHEALPix = SphereHEALPix * SphereHEALPix (pixel by pixel multiply) */
+template <class T>
+inline SphereHEALPix<T> operator * (const SphereHEALPix<T>& a,const SphereHEALPix<T>& b)
+    { SphereHEALPix<T> result; result.SetTemp(true); 
+    if (b.IsTemp())  { result.Share(b); result.MulElt(a); }
+    else { result.CloneOrShare(a); result.MulElt(b); }
+    return result; }
+
+/*! \ingroup SkyMap \fn operator/(const SphereHEALPix<T>&,const SphereHEALPix<T>&)
+  \brief Operator SphereHEALPix = SphereHEALPix / SphereHEALPix (pixel by pixel divide) */
+template <class T>
+inline SphereHEALPix<T> operator / (const SphereHEALPix<T>& a,const SphereHEALPix<T>& b)
+    { SphereHEALPix<T> result; result.SetTemp(true); 
+    if (b.IsTemp())  { result.Share(b); result.DivElt(a); }
+    else { result.CloneOrShare(a); result.DivElt(b); }
+    return result; }
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyMap/spherepos.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/spherepos.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/spherepos.cc	(revision 2309)
@@ -0,0 +1,147 @@
+// 04/01/00 : implantation de la persistance par classe deleguee - Guy Le Meur
+
+#include "spherepos.h"
+#include "datatype.h"
+#include <typeinfo>
+
+static char *head_spherepos_cc_ = "$Header: /Users/garnier/temp/CVSSophya/SophyaLib/SkyMap/spherepos.cc,v 1.2 2002-04-26 16:48:22 ansari Exp $";
+
+
+//................. SphereCoordSys class .................
+
+SphereCoordSys::SphereCoordSys(){
+  id_ = SphereCoordSys_NEUTRAL;
+  description_ = "NEUTRAL SphereCoordSystem";
+}
+SphereCoordSys::SphereCoordSys(const SphereCoordSys& a )
+{
+  id_ = a.id_;
+  description_ = a.description_;
+}
+
+SphereCoordSys::SphereCoordSys(int id, const string& description){
+  id_ = id;
+  description_ = description;
+}
+
+SphereCoordSys::~SphereCoordSys()
+{
+}
+SphereCoordSys& SphereCoordSys::operator = (const SphereCoordSys& a)
+{
+  id_ = a.id_;
+  description_ = a.description_;
+  return *this;
+}
+
+
+////////////////////////////////////////////////////////////////
+// -------------------------------------------------------------------------
+//   Les objets delegues pour la gestion de persistance 
+// -------------------------------------------------------------------------
+
+FIO_SphereCoordSys::FIO_SphereCoordSys()
+  {
+    dobj=new SphereCoordSys;
+    ownobj=true;
+  }
+FIO_SphereCoordSys::FIO_SphereCoordSys(string const & filename)
+  {
+    dobj=new SphereCoordSys;
+    ownobj=true; 
+    Read(filename);
+  }
+FIO_SphereCoordSys::FIO_SphereCoordSys(const SphereCoordSys & obj)
+  {
+    dobj = new SphereCoordSys(obj);
+    ownobj=true; 
+  }
+FIO_SphereCoordSys::FIO_SphereCoordSys(SphereCoordSys * obj)
+  {
+    dobj = obj;
+    ownobj=false; 
+  }
+FIO_SphereCoordSys::~FIO_SphereCoordSys()
+  {
+    if (ownobj && dobj) delete dobj;
+  }
+AnyDataObj* FIO_SphereCoordSys::DataObj()
+  {
+    return(dobj);
+  }
+
+void  FIO_SphereCoordSys::SetDataObj(AnyDataObj & o) 
+{
+  SphereCoordSys * po = dynamic_cast<SphereCoordSys *>(&o);
+  if (po == NULL) {
+    char buff[160];
+    sprintf(buff,"FIO_SphereCoordSys::SetDataObj(%s) - Object type  error ! ",
+	    typeid(o).name());
+    throw TypeMismatchExc(PExcLongMessage(buff));    
+  }
+
+  if (ownobj && dobj) delete dobj;  
+  dobj = po; ownobj = false;
+}
+
+
+void  FIO_SphereCoordSys::ReadSelf(PInPersist& is)
+  {
+uint_8 itab[3];
+ string description;
+is.Get(itab, 3);
+is.GetStr(description);
+if (dobj == NULL) dobj = new SphereCoordSys(itab[1], description);
+ else *dobj= SphereCoordSys(itab[1], description);
+  }           
+void       FIO_SphereCoordSys::WriteSelf(POutPersist& os) const
+{
+if (dobj == NULL)   return;  // Attention - $CHECK$ Guy 04/01/00
+//  On ecrit 3 uint_8 
+//  0 : Numero de version,  1 : Id,  2  reserve a l
+uint_8 itab[3];
+itab[0] = 1;
+itab[1] = dobj->Id();
+itab[2] = 0;
+os.Put(itab, 3);
+os.PutStr(dobj->description());
+} 
+
+
+
+//................. SpherePosition class .................
+
+SpherePosition::SpherePosition() 
+        : UnitVector()
+{
+  cs_ = new SphereCoordSys;
+}
+
+SpherePosition::SpherePosition(double theta, double phi, SphereCoordSys* cs)
+        : UnitVector(theta, phi)
+{
+if (cs == NULL) cs_ = new SphereCoordSys;
+else cs_ = cs;
+}
+
+SpherePosition::SpherePosition(double x, double y, double z, SphereCoordSys* cs)
+        : UnitVector(x, y, z)
+{
+if (cs == NULL) cs_ = new SphereCoordSys;
+else cs_ = cs;
+}
+
+SpherePosition::~SpherePosition()
+{
+if (cs_) delete cs_;
+}
+
+UnitVector SpherePosition::Transform(const SphereCoordSys& /*cs*/) const
+{
+return(*this);
+}
+
+double SpherePosition::Separation(const SpherePosition& gamma) const 
+{
+return(this->SepAngle(gamma));
+}
Index: /tags/V_Dec2002/SophyaLib/SkyMap/spherepos.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/spherepos.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/spherepos.h	(revision 2309)
@@ -0,0 +1,83 @@
+// This may look like C code, but it is really -*- C++ -*-
+#ifndef SPHEREPOS_H_SEEN
+#define SPHEREPOS_H_SEEN
+
+#include "machdefs.h"
+#include "ppersist.h"
+#include <string>
+#include "unitvector.h"
+#include "anydataobj.h"
+
+static char *head_spherepos_h_ = "$Header: /Users/garnier/temp/CVSSophya/SophyaLib/SkyMap/spherepos.h,v 1.1.1.1 2000-03-02 17:05:39 ansari Exp $";
+
+namespace SOPHYA {
+
+enum SphereCoordSysIds { SphereCoordSys_NEUTRAL =0, 
+                         SphereCoordSys_ROTATION =1,
+                         SphereCoordSys_OTHER = 0xFFFF
+};
+
+ 
+class SphereCoordSys : public  AnyDataObj {
+public:
+  
+  SphereCoordSys();
+  SphereCoordSys(const SphereCoordSys& a);
+                 SphereCoordSys(int id, const string& description);
+  virtual        ~SphereCoordSys();
+
+  virtual int    Id() const {return id_; }
+  virtual string description() const {return description_; }
+  SphereCoordSys& operator = (const SphereCoordSys& a);
+
+
+private:
+  int id_;
+  string description_;
+};
+
+// Classe pour la gestion de persistance
+
+class FIO_SphereCoordSys : public  PPersist  {
+public:
+  FIO_SphereCoordSys();
+  FIO_SphereCoordSys(string const & filename);
+  FIO_SphereCoordSys(const SphereCoordSys & obj);
+  FIO_SphereCoordSys(SphereCoordSys * obj);
+  virtual ~FIO_SphereCoordSys();
+  virtual AnyDataObj* DataObj();
+  virtual   void        SetDataObj(AnyDataObj & o);
+  inline operator SphereCoordSys() { return(*dobj); }
+protected :
+  virtual void       ReadSelf(PInPersist&);
+  virtual void       WriteSelf(POutPersist&) const;  
+  SphereCoordSys * dobj;
+  bool ownobj;
+};
+
+
+class SpherePosition : public UnitVector {
+public:
+  
+                 SpherePosition();
+// cs should be created by new SphereCoordSys...
+// It will be deleted by the destructor
+                 SpherePosition(double theta, double phi, SphereCoordSys* cs = NULL);
+                 SpherePosition(double x, double y, double z, SphereCoordSys* cs = NULL);
+                 SpherePosition(const UnitVector& v, SphereCoordSys* cs = NULL);
+  virtual        ~SpherePosition();
+
+  inline double  phi() const {return Phi(); }
+  inline double  theta() const { return(Theta()); }
+  inline SphereCoordSys *   GetCoordSys() const { return(cs_); } 
+  virtual UnitVector Transform(const SphereCoordSys& cs) const ;
+
+  virtual double     Separation(const SpherePosition& gamma) const;
+
+protected:
+  SphereCoordSys* cs_;
+};
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyMap/spherethetaphi.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/spherethetaphi.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/spherethetaphi.cc	(revision 2309)
@@ -0,0 +1,853 @@
+#include "spherethetaphi.h"
+#include "smathconst.h"
+#include <complex>
+#include "piocmplx.h"
+#include "fiondblock.h"
+#include <iostream.h>
+
+
+/*!
+  \class SOPHYA::SphereThetaPhi
+  \ingroup SkyMap
+  Class implementing spherical maps, with equal latitude (iso-theta) rings 
+  pixelisation scheme - with template data types (double, float, complex, ...)
+
+    sphere splitted with respect to theta, phi : each hemisphere is 
+    splitted into (m-1) parallels (equator does not enter into account).
+    This operation defines m slices, each of which is splitted into 
+    equidistant meridians. This splitting is realized in such a way that 
+    all pixels have the same area and are as square as possible.
+
+    One begins with the hemisphere with positive z, starting from the pole
+    toward the equator. The first pixel is the polar cap ; it is circular
+    and centered on theta=0. 
+*/
+
+//***************************************************************
+//++ 
+// Class	SphereThetaPhi
+// 
+//
+// include      spherethetaphi.h 
+//--
+//++
+//
+// Links	Parents
+//
+//    SphericalMap 
+//-- 
+
+/* --Methode-- */
+//++
+// Titre	Constructors
+//--
+//++
+
+template <class T>
+SphereThetaPhi<T>::SphereThetaPhi()
+  : NPhi_(), TNphi_(), Theta_(), pixels_() 
+
+//--
+{
+  InitNul();
+}
+
+
+/* --Methode-- */
+
+//++
+template <class T>
+SphereThetaPhi<T>::SphereThetaPhi(int_4 m)
+
+//    m is the number of slices in theta on an hemisphere (the polar cap
+//    forms the first slice).
+//--
+{
+  InitNul();
+  Pixelize(m);
+}
+
+template <class T>
+SphereThetaPhi<T>::SphereThetaPhi(const SphereThetaPhi<T>& s, bool share)
+  : NPhi_(s.NPhi_, share), TNphi_(s.TNphi_, share), Theta_(s.Theta_, share),
+    pixels_(s.pixels_ , share) 
+{
+
+  NTheta_= s.NTheta_;
+  NPix_  = s.NPix_;
+  Omega_ = s.Omega_;
+  if(s.mInfo_) mInfo_= new DVList(*s.mInfo_);
+}
+
+template <class T>
+SphereThetaPhi<T>::SphereThetaPhi(const SphereThetaPhi<T>& s)
+  : NPhi_(s.NPhi_), TNphi_(s.TNphi_), Theta_(s.Theta_), pixels_(s.pixels_) 
+{
+
+  NTheta_= s.NTheta_;
+  NPix_  = s.NPix_;
+  Omega_ = s.Omega_;
+  if(s.mInfo_) mInfo_= new DVList(*s.mInfo_);
+}
+
+//++
+// Titre	Destructor
+//--
+//++
+template <class T>
+SphereThetaPhi<T>::~SphereThetaPhi()
+
+//--
+{}
+
+//++
+// Titre	Public Méthods
+//--
+template <class T>
+void SphereThetaPhi<T>::InitNul()
+//
+{
+  NTheta_= 0;
+  NPix_  = 0;
+//  pixels_.Reset();  Pas de reset par InitNul (en cas de share) - Reza 20/11/99 $CHECK$
+}
+
+
+//++
+template <class T>
+void SphereThetaPhi<T>::Resize(int_4 m)
+//   re-pixelize the sphere
+//--
+{
+  InitNul();
+  Pixelize(m);
+}
+
+template<class T>
+void  SphereThetaPhi<T>::CloneOrShare(const  SphereThetaPhi<T>& a)
+{
+
+  NTheta_= a.NTheta_;
+  NPix_  = a.NPix_;
+  Omega_ = a.Omega_;
+  NPhi_.CloneOrShare(a.NPhi_);
+  TNphi_.CloneOrShare(a.TNphi_);
+  Theta_.CloneOrShare(a.Theta_);
+  pixels_.CloneOrShare(a.pixels_);
+  if (mInfo_) {delete mInfo_; mInfo_ = NULL;}
+  if (a.mInfo_) mInfo_ = new DVList(*(a.mInfo_));
+}
+template<class T>
+void  SphereThetaPhi<T>::Share(const  SphereThetaPhi<T>& a)
+{
+
+  NTheta_= a.NTheta_;
+  NPix_  = a.NPix_;
+  Omega_ = a.Omega_;
+  NPhi_.Share(a.NPhi_);
+  TNphi_.Share(a.TNphi_);
+  Theta_.Share(a.Theta_);
+  pixels_.Share(a.pixels_);
+  if (mInfo_) {delete mInfo_; mInfo_ = NULL;}
+  if (a.mInfo_) mInfo_ = new DVList(*(a.mInfo_));
+}
+
+////////////////////////// methodes de copie/share
+template<class T>
+SphereThetaPhi<T>& SphereThetaPhi<T>::Set(const SphereThetaPhi<T>& a)
+{
+  if (this != &a) 
+    { 
+      
+      
+      if (a.NbPixels() < 1) 
+	throw RangeCheckError("SphereThetaPhi<T>::Set(a ) - Array a not allocated ! ");
+      if (NbPixels() < 1) CloneOrShare(a);
+      else CopyElt(a);
+      if (mInfo_) delete mInfo_;
+      mInfo_ = NULL;
+      if (a.mInfo_) mInfo_ = new DVList(*(a.mInfo_));
+    }
+  return(*this);
+}
+
+template<class T>
+SphereThetaPhi<T>& SphereThetaPhi<T>::CopyElt(const SphereThetaPhi<T>& a)
+{
+  if (NbPixels() < 1) 
+    throw RangeCheckError("SphereThetaPhi<T>::CopyElt(const SphereThetaPhi<T>& )  - Not Allocated Array ! ");
+  if (NbPixels() != a.NbPixels()) 
+    throw(SzMismatchError("SphereThetaPhi<T>::CopyElt(const SphereThetaPhi<T>&) SizeMismatch")) ;
+
+  NTheta_= a.NTheta_;
+  NPix_  = a.NPix_;
+  Omega_ = a.Omega_;
+  int k;
+  for (k=0; k< NPix_; k++) pixels_(k) = a.pixels_(k);
+  for (k=0; k< a.NPhi_.Size(); k++) NPhi_(k) = a.NPhi_(k);
+  for (k=0; k< a.TNphi_.Size(); k++) TNphi_(k) = a.TNphi_(k);
+  for (k=0; k< a.Theta_.Size(); k++) Theta_(k) = a.Theta_(k);
+  return(*this);
+
+}
+
+/* --Methode-- */
+//++
+template <class T>
+int_4 SphereThetaPhi<T>::NbPixels() const
+
+//    Return total number of pixels 
+//--
+{
+  return(NPix_);
+}
+
+/* --Methode-- */
+//++
+template <class T>
+T& SphereThetaPhi<T>::PixVal(int_4 k)
+
+//    Return value of pixel with index k
+//--
+{
+  if((k < 0) || (k >= NPix_)) 
+    {
+      throw RangeCheckError("SphereThetaPhi::PIxVal Pixel index out of range");
+    }
+  return pixels_(k);
+}
+
+//++
+template <class T>
+T const& SphereThetaPhi<T>::PixVal(int_4 k) const
+
+//    Return value of pixel with index k
+//--
+{
+  if((k < 0) || (k >= NPix_)) 
+    {
+       throw RangeCheckError("SphereThetaPhi::PIxVal Pixel index out of range");
+    } 
+  return *(pixels_.Data()+k);
+}
+
+/* --Methode-- */
+//++
+template <class T>
+bool SphereThetaPhi<T>::ContainsSph(double /*theta*/, double /*phi*/) const
+//--
+{
+  return(true);
+}
+
+/* --Methode-- */
+//++
+template <class T>
+int_4 SphereThetaPhi<T>::PixIndexSph(double theta, double phi) const
+
+//    Return index of the pixel corresponding to 
+//    direction (theta, phi).
+//--
+{
+  double dphi;
+  int i,k;
+  bool fgzn = false;
+
+  if((theta > Pi) || (theta < 0.)) return(-1);
+  if((phi < 0.) || (phi > DeuxPi)) return(-1);
+  if(theta > Pi*0.5) {fgzn = true; theta = Pi-theta;}
+  
+  // La bande d'indice kt est limitée par les valeurs de theta contenues dans
+  // Theta_[kt] et Theta_[kt+1]
+  for( i=1; i< NTheta_; i++ ) 
+    if( theta < Theta_(i) ) break;
+  
+  dphi= DeuxPi/(double)NPhi_(i-1);
+  
+  if (fgzn)  k= NPix_-TNphi_(i)+(int_4)(phi/dphi);
+  else k= TNphi_(i-1)+(int_4)(phi/dphi); 
+  return(k);
+}
+
+/* --Methode-- */
+//++
+template <class T>
+void SphereThetaPhi<T>::PixThetaPhi(int_4 k,double& theta,double& phi) const
+
+//   Return (theta,phi) coordinates of middle of  pixel with  index k
+//--
+{
+  int i; 
+  bool fgzn = false;
+  
+  if((k < 0) || (k >= NPix_)) {theta = -99999.; phi = -99999.; return; }
+  if( k >= NPix_/2)  {fgzn = true; k = NPix_-1-k;}
+
+  // recupère l'indice i de la tranche qui contient le pixel k
+  for( i=0; i< NTheta_; i++ ) 
+    if( k < TNphi_(i+1) ) break;
+
+  // angle theta
+  theta= 0.5*(Theta_(i)+Theta_(i+1));
+  if (fgzn) theta= Pi-theta;
+  
+  // angle phi
+  k -= TNphi_(i);
+  phi= DeuxPi/(double)NPhi_(i)*(double)(k+.5);
+  if (fgzn) phi= DeuxPi-phi;
+}
+
+template <class T>
+T SphereThetaPhi<T>::SetPixels(T v)
+{
+pixels_.Reset(v);
+return(v);
+}
+
+//++
+template <class T>
+double SphereThetaPhi<T>::PixSolAngle(int_4 /*dummy*/) const
+
+//    Pixel Solid angle  (steradians)
+//    All the pixels have the same solid angle. The dummy argument is
+//    for compatibility with eventual pixelizations which would not 
+//    fulfil this requirement.
+//--
+{
+  return Omega_;
+}
+
+/* --Methode-- */
+//++
+template <class T>
+void SphereThetaPhi<T>::Limits(int_4 k,double& tetMin,double& tetMax,double& phiMin,double& phiMax) 
+
+//   Return values of theta,phi which limit the pixel with  index k
+//--
+  {
+  int j;
+  double dphi;
+  bool fgzn= false;
+  
+  if((k < 0) || (k >= NPix_)) {
+    tetMin= -99999.; 
+    phiMin= -99999.;  
+    tetMax= -99999.; 
+    phiMax= -99999.;  
+    return;
+  }
+  
+  // si on se trouve dans l'hémisphère Sud
+  if(k >= NPix_/2) { 
+    fgzn= true; 
+    k= NPix_-1-k; 
+  }
+  
+  // on recupere l'indice i de la tranche qui contient le pixel k
+  int i;
+  for( i=0; i< NTheta_; i++ ) 
+    if(k < TNphi_(i+1)) break;
+  
+  // valeurs limites de theta dans l'hemisphere Nord
+  tetMin= Theta_(i);
+  tetMax= Theta_(i+1);
+  // valeurs limites de theta dans l'hemisphere Sud
+  if (fgzn) {
+    tetMin= Pi - Theta_(i+1);
+    tetMax= Pi - Theta_(i);
+  }
+  
+  // pixel correspondant dans l'hemisphere Nord
+  if (fgzn) k= TNphi_(i+1)-k+TNphi_(i)-1;
+  
+  // indice j de discretisation ( phi= j*dphi )
+  j= k-TNphi_(i);
+  dphi= DeuxPi/(double)NPhi_(i);
+  
+  // valeurs limites de phi 
+  phiMin= dphi*(double)(j);
+  phiMax= dphi*(double)(j+1);
+  return;
+}
+
+/* --Methode-- */
+//++
+template <class T>
+uint_4 SphereThetaPhi<T>::NbThetaSlices() const
+
+//    Return number of theta-slices on the sphere
+//--
+{
+  if (NTheta_<=0) 
+    {
+      throw PException(" sphere not pixelized, NbSlice=0 ");
+    }
+  return( 2*NTheta_);
+}
+
+/* --Methode-- */
+//++
+template <class T>
+int_4 SphereThetaPhi<T>::NPhi(int_4 kt) const
+
+//    Return number of pixels in phi-direction of the kt-th slice
+//-- 
+{
+  int nbpix;  
+  // verification
+  if((kt < 0) || (kt >= 2*NTheta_)) return(-1);
+  
+  // si on se trouve dans l'hemisphere Sud
+  if(kt >= NTheta_) {
+    kt= 2*NTheta_-1-kt; 
+  }
+  
+  // nombre de pixels
+  nbpix= NPhi_(kt);
+  return(nbpix);
+}
+
+
+/* --Methode-- */
+//++
+template <class T>
+void SphereThetaPhi<T>::Theta(int_4 kt,double& tetMin,double& tetMax) 
+
+//    Return  theta values which limit the slice kt
+//--
+{
+  bool fgzn= false;
+  // verification
+  if( (kt< 0) || (kt>= 2*NTheta_) ) {
+    tetMin= -99999.; 
+    tetMax= -99999.; 
+    return;
+  }
+
+  // si on se trouve dans l'hemisphere Sud
+  if( kt >= NTheta_ ) {
+    fgzn= true;
+    kt= 2*NTheta_-1-kt; 
+  }
+  
+  // valeurs limites de theta dans l'hemisphere Nord
+  tetMin= Theta_(kt);
+  tetMax= Theta_(kt+1);
+  // valeurs limites de theta dans l'hemisphere Sud
+  if (fgzn) {
+    tetMin= Pi - Theta_(kt+1);
+    tetMax= Pi - Theta_(kt);
+  }  
+}
+
+/* --Methode-- */
+//++
+template <class T>
+void SphereThetaPhi<T>::Phi(int_4 kt,int_4 jp,double& phiMin,double& phiMax) 
+
+//   Return values of phi which limit the jp-th pixel of the kt-th slice
+//--
+{
+  // verification
+  if((kt < 0) || (kt >= 2*NTheta_)) {
+    phiMin= -99999.; 
+    phiMax= -99999.; 
+    return;
+  }
+  
+  // si on se trouve dans l'hemisphere Sud
+  if(kt >= NTheta_) kt= 2*NTheta_-1-kt;
+  
+  // verifie si la tranche kt contient au moins jp pixels
+  if( (jp< 0) || (jp >= NPhi_(kt)) ) {
+    phiMin= -88888.; 
+    phiMax= -88888.; 
+    return;
+  }
+  
+  double dphi= DeuxPi/(double)NPhi_(kt);
+  phiMin= dphi*(double)(jp);
+  phiMax= dphi*(double)(jp+1);
+  return;
+}
+
+/* --Methode-- */
+//++
+template <class T>
+int_4 SphereThetaPhi<T>::Index(int_4 kt,int_4 jp) const
+
+//    Return pixel index  with sequence index jp in the slice kt 
+//--
+{
+  int k;
+  bool fgzn= false;
+  
+  // si on se trouve dans l'hemisphere Sud
+  if(kt >= NTheta_) {
+    fgzn= true; 
+    kt= 2*NTheta_-1-kt;
+  }
+  
+  // si la tranche kt contient au moins i pixels
+  if( (jp>=0) && (jp<NPhi_(kt)) ) 
+    {
+      // dans l'hemisphere Sud
+      if (fgzn) k= NPix_-TNphi_(kt+1)+jp;
+      // dans l'hemisphere Nord
+      else k= TNphi_(kt)+jp;
+    }
+  else
+    {
+      k= 9999;
+      printf("\n la tranche %d ne contient pas un pixel de rang %d",kt,jp);
+    }
+  return(k);
+}
+
+/* --Methode-- */
+//++
+template <class T>
+void SphereThetaPhi<T>::ThetaPhiIndex(int_4 k,int_4& kt,int_4& jp) 
+
+//    Return indices kt (theta) and jp (phi) of  pixel with index k
+//--
+{
+  bool fgzn= false;  
+  // si on se trouve dans l'hemisphere Sud
+  if(k >= NPix_/2) 
+    { 
+      fgzn= true; 
+      k= NPix_-1-k; 
+    }
+  
+  // on recupere l'indice kt de la tranche qui contient le pixel k
+  int i;
+  for(i = 0; i < NTheta_; i++) 
+    if(k < TNphi_(i+1)) break;
+  
+  // indice  kt de tranche
+  if (fgzn) kt= 2*NTheta_-1-i;
+  else kt= i;
+  
+  // indice jp de pixel
+  if (fgzn) jp= TNphi_(i+1)-k-1;
+  else jp= k-TNphi_(i);  
+}
+//++
+template <class T>
+void  SphereThetaPhi<T>::Pixelize(int_4 m) 
+
+//    achieve the splitting into pixels (m has the same signification 
+//    as for the constructor)
+//
+//    Each theta-slice of the north hemisphere will be spitted starting f
+//    from  phi=0 ...
+//
+//    South hemisphere is scanned in the same direction according to phi
+//    and from equator to the pole (the pixel following the last one of
+//    the slice closest to the equator with z>0, is the pixel with lowest 
+//    phi of the slice closest of the equator with z<0).
+//--
+{
+  int ntotpix,j;
+  
+  // Decodage et controle des arguments d'appel :
+  // au moins 2 et au plus 16384 bandes d'un hemisphere en theta
+  if (m < 2) m = 2;
+  if (m > 16384) m = 16384;
+  
+  // On memorise les arguments d'appel
+  NTheta_ = m;  
+  
+  // On commence par decouper l'hemisphere z>0.
+  // Creation des vecteurs contenant :
+  // Les valeurs limites de theta (une valeur de plus que le nombre de bandes...)
+  //  Theta_= new double[m+1];
+  Theta_.ReSize(m+1);
+  
+  // Le nombre de pixels en phi de chacune des bandes en theta
+  //  NPhi_ = new int_4[m];
+  // une taille de m suffit, mais je mets m+1 pour que les 3 tableaux aient 
+  // la meme taille pour une manipulation plus faciles par la librairie 
+  // cfitsio -- GLM (13-04-00)
+  NPhi_.ReSize(m+1);
+  
+  // Le nombre/Deuxpi total des pixels contenus dans les bandes de z superieur a une
+  // bande donnee (mTPphi[m] contient le nombre de pixels total de l'hemisphere)
+  //  TNphi_= new int_4[m+1];
+    TNphi_.ReSize(m+1);
+  
+  // Calcul du nombre total de pixels dans chaque bande pour optimiser
+  // le rapport largeur/hauteur des pixels 
+  
+  //calotte polaire
+  TNphi_(0)= 0;
+  NPhi_(0) = 1;
+  
+  //bandes jusqu'a l'equateur
+  for(j = 1; j < m; j++) 
+    {
+      TNphi_(j)= TNphi_(j-1)+NPhi_(j-1);
+      NPhi_(j) = (int_4)(.5+4.*(double)(m-.5)*sin(Pi*(double)j/(double)(2.*m-1.))) ;
+    }
+  
+  // Nombre total de pixels sur l'hemisphere
+  ntotpix  = TNphi_(m-1)+NPhi_(m-1);
+  TNphi_(m)= ntotpix;
+  // et sur la sphere entiere
+  NPix_= 2*ntotpix;
+  
+  // Creation et initialisation du vecteur des contenus des pixels 
+  pixels_.ReSize(NPix_);
+  pixels_.Reset();
+
+  // Determination des limites des bandes en theta :
+  // omeg est l'angle solide couvert par chaque pixel,
+  // une bande donnee kt couvre un angle solide NPhi_[kt]*omeg
+  // egal a 2* Pi*(cos Theta_[kt]-cos Theta_[kt+1]). De meme, l'angle solide 
+  //de la
+  // calotte allant du pole a la limite haute de la bande kt vaut
+  // 2* Pi*(1.-cos Theta_[kt+1])= TNphi_[kt]*omeg...
+  
+  double omeg2pi= 1./(double)ntotpix;
+  Omega_ = omeg2pi*DeuxPi;
+  
+  for(j=0; j <= m; j++) 
+    {
+      Theta_(j)= acos(1.-(double)TNphi_(j)*omeg2pi);
+    }
+}
+
+//++
+template <class T>
+void SphereThetaPhi<T>::GetThetaSlice(int_4 index,r_8& theta, TVector<r_8>& phi, TVector<T>& value) const 
+
+//    For a theta-slice with index 'index', return : 
+//    the corresponding "theta" 
+//    a vector containing the phi's of the pixels of the slice
+//    a vector containing the corresponding values of pixels 
+//--
+
+{
+
+  if(index < 0 || index >= NbThetaSlices()) 
+    {
+       throw RangeCheckError("SphereThetaPhi::PIxVal Pixel index out of range"); 
+    }
+
+  int iring= Index(index,0);
+  int lring  = NPhi(index);
+
+  phi.ReSize(lring);
+  value.ReSize(lring);
+  double Te= 0.;
+  double Fi= 0.;
+  for(int kk = 0; kk < lring; kk++) 
+    {
+      PixThetaPhi(kk+iring,Te,Fi);
+      phi(kk)= Fi;
+      value(kk)= PixVal(kk+iring);
+    }
+  theta= Te;
+}
+
+//++
+template <class T>
+void SphereThetaPhi<T>::GetThetaSlice(int_4 index,r_8& theta, r_8& phi0,TVector<int_4>& pixelIndices, TVector<T>& value) const 
+
+//    For a theta-slice with index 'index', return : 
+//    the corresponding "theta" 
+//    the corresponding "phi" for first pixel of the slice 
+//    a vector containing the indices of the pixels of the slice
+//    (equally distributed in phi)
+//    a vector containing the corresponding values of pixels 
+//--
+
+{
+
+  if(index < 0 || index >= NbThetaSlices()) 
+    {
+       throw RangeCheckError("SphereThetaPhi::PIxVal Pixel index out of range"); 
+ 
+    }
+
+  int iring= Index(index,0);
+  int lring  = NPhi(index);
+
+  pixelIndices.ReSize(lring);
+  value.ReSize(lring);
+  double Te= 0.;
+  double Fi= 0.;
+  for(int kk = 0; kk < lring; kk++) 
+    {
+      pixelIndices(kk)=kk+iring ;
+      value(kk)= PixVal(kk+iring);
+    }
+      PixThetaPhi(iring,theta,phi0);
+}
+
+
+
+
+template <class T>
+void SphereThetaPhi<T>::print(ostream& os) const
+{
+  if(mInfo_) os << "  DVList Info= " << *mInfo_ << endl;
+  //
+  os << " NTheta_= " << NTheta_ << endl;
+  os << " NPix_    = " << NPix_   << endl;
+  os << " Omega_  =  " << Omega_   << endl;
+
+  os << " contenu de NPhi_ : ";
+  int i;
+  for(i=0; i < NTheta_; i++)
+    {
+      if(i%5 == 0) os << endl;
+      os << NPhi_(i) <<", ";
+    }
+  os << endl;
+
+  os << " contenu de Theta_ : ";
+  for(i=0; i < NTheta_+1; i++)
+    {
+      if(i%5 == 0) os << endl;
+      os << Theta_(i) <<", ";
+    }
+  os << endl;
+
+  os << " contenu de TNphi_ : ";
+  for(i=0; i < NTheta_+1; i++)
+    {
+      if(i%5 == 0) os << endl;
+      os << TNphi_(i) <<", ";
+    }
+  os << endl;
+
+  os << " contenu de pixels : ";
+  for(i=0; i < NPix_; i++)
+    {
+      if(i%5 == 0) os << endl;
+      os <<  pixels_(i) <<", ";
+    }
+  os << endl;
+}
+
+//   ...... Operations de calcul  ......
+
+
+//! Fill a SphereThetaPhi with a constant value \b a
+template <class T>
+SphereThetaPhi<T>& SphereThetaPhi<T>::SetT(T a) 
+{
+  if (NbPixels() < 1) 
+    throw RangeCheckError("SphereThetaPhi<T>::SetT(T )  - SphereThetaPhi not dimensionned ! ");
+  pixels_ = a;
+  return (*this);
+}
+
+/*! Add a constant value \b x to a SphereThetaPhi */
+template <class T>
+SphereThetaPhi<T>& SphereThetaPhi<T>::Add(T a)
+ {
+  if (NbPixels()< 1) 
+    throw RangeCheckError("SphereThetaPhi<T>::Add(T )  - SphereThetaPhi not dimensionned ! ");
+  pixels_ += a; 
+  return (*this);
+}
+
+/*! Substract a constant value \b a to a SphereThetaPhi */
+template <class T>
+SphereThetaPhi<T>& SphereThetaPhi<T>::Sub(T a,bool fginv) 
+{
+  if (NbPixels()< 1) 
+    throw RangeCheckError("SphereThetaPhi<T>::Sub(T )  - SphereThetaPhi not dimensionned ! ");
+  pixels_.Sub(a,fginv); 
+  return (*this);
+} 
+
+/*! multiply a SphereThetaPhi by a constant value \b a */
+template <class T>
+SphereThetaPhi<T>& SphereThetaPhi<T>::Mul(T a) 
+{
+  if (NbPixels()< 1) 
+    throw RangeCheckError("SphereThetaPhi<T>::Mul(T )  - SphereThetaPhi not dimensionned ! ");
+  pixels_ *= a; 
+  return (*this);
+}
+
+/*! divide a SphereThetaPhi by a constant value \b a */
+template <class T>
+SphereThetaPhi<T>& SphereThetaPhi<T>::Div(T a) 
+{
+  if (NbPixels()< 1) 
+    throw RangeCheckError("SphereThetaPhi<T>::Div(T )  - SphereThetaPhi not dimensionned ! ");
+  pixels_ /= a; 
+  return (*this);
+} 
+
+//  >>>> Operations avec 2nd membre de type SphereThetaPhi
+//! Add two SphereThetaPhi
+
+template <class T>
+SphereThetaPhi<T>& SphereThetaPhi<T>::AddElt(const SphereThetaPhi<T>& a)
+{
+  if (NbPixels()!= a.NbPixels())
+    {
+    throw(SzMismatchError("SphereThetaPhi<T>::AddElt(const SphereThetaPhi<T>&) SizeMismatch")) ;
+    }
+  pixels_ += a.pixels_;
+  return (*this);
+}
+
+//! Substract two SphereThetaPhi
+template <class T>
+SphereThetaPhi<T>& SphereThetaPhi<T>::SubElt(const SphereThetaPhi<T>& a)
+{
+  if (NbPixels()!= a.NbPixels())
+    {
+    throw(SzMismatchError("SphereThetaPhi<T>::SubElt(const SphereThetaPhi<T>&) SizeMismatch")) ;
+    }
+  pixels_ -= a.pixels_;
+  return (*this);
+}
+
+//! Multiply two SphereThetaPhi (elements by elements)
+template <class T>
+SphereThetaPhi<T>& SphereThetaPhi<T>::MulElt(const SphereThetaPhi<T>& a)
+{
+  if (NbPixels()!= a.NbPixels())
+    {
+    throw(SzMismatchError("SphereThetaPhi<T>::MulElt(const SphereThetaPhi<T>&) SizeMismatch")) ;
+    }
+  pixels_ *= a.pixels_;
+  return (*this);
+}
+
+//! Divide two SphereThetaPhi (elements by elements) - No protection for divide by 0
+template <class T>
+SphereThetaPhi<T>& SphereThetaPhi<T>::DivElt(const SphereThetaPhi<T>& a)
+{
+  if (NbPixels()!= a.NbPixels())
+    {
+    throw(SzMismatchError("SphereThetaPhi<T>::DivElt(const SphereThetaPhi<T>&) SizeMismatch")) ;
+    }
+  pixels_ /= a.pixels_;
+  return (*this);
+}
+
+
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template SphereThetaPhi<int_4>
+#pragma define_template SphereThetaPhi<r_8>
+#pragma define_template SphereThetaPhi<r_4>
+#pragma define_template SphereThetaPhi< complex<r_4> >
+#pragma define_template SphereThetaPhi< complex<r_8> >
+#endif
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class SphereThetaPhi<int_4>;
+template class SphereThetaPhi<r_8>;
+template class SphereThetaPhi<r_4>;
+template class SphereThetaPhi< complex<r_4> >;
+template class SphereThetaPhi< complex<r_8> >;
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyMap/spherethetaphi.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/spherethetaphi.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/spherethetaphi.h	(revision 2309)
@@ -0,0 +1,361 @@
+#ifndef SPHERETHETAPHI_SEEN
+#define SPHERETHETAPHI_SEEN
+
+#include "sphericalmap.h"
+#include "ndatablock.h"
+#include "tvector.h"
+
+#include "anydataobj.h"
+#include "ppersist.h"
+
+namespace SOPHYA {
+
+
+
+template <class T>
+class FIO_SphereThetaPhi;  
+
+template<class T>
+class FITS_SphereThetaPhi;
+
+
+// ***************** Class SphereThetaPhi *****************************
+/*!    sphere splitted with respect to theta, phi : each hemisphere is 
+    splitted into (m-1) parallels (equator does not enter into account).
+   This operation defines m slices, each of which is splitted into 
+    equidistant meridians. This splitting is realized in such a way that 
+    all pixels have the same area and are as square as possible.
+
+    One begins with the hemisphere with positive z, starting from the pole
+    toward the equator. The first pixel is the polar cap ; it is circular
+    and centered on theta=0. 
+*/
+template <class T>
+class SphereThetaPhi : public SphericalMap<T>
+{
+
+public :
+
+SphereThetaPhi();
+/*!    m is the number of slices in theta on an hemisphere (the polar cap
+   forms the first slice).
+    pet is a dummy parameter at the moment. 
+*/
+SphereThetaPhi(int_4 m);
+SphereThetaPhi(const SphereThetaPhi<T>& s, bool share);
+SphereThetaPhi(const SphereThetaPhi<T>& s);
+virtual ~SphereThetaPhi();
+
+  // Temporaire?
+inline virtual bool IsTemp(void) const {
+
+    if (  NPhi_.IsTemp()  != pixels_.IsTemp() || 
+	  TNphi_.IsTemp() != pixels_.IsTemp()|| 
+	  Theta_.IsTemp() != pixels_.IsTemp()    )
+      throw PException(" l'etat 'temporaire' de la spherethetaphi est incoherent"); 
+    return pixels_.IsTemp();
+}
+/*! Setting blockdata to temporary (see ndatablock documentation) */
+inline virtual void SetTemp(bool temp=false) const 
+  {
+    NPhi_.SetTemp(temp);
+    TNphi_.SetTemp(temp);
+    Theta_.SetTemp(temp);
+    pixels_.SetTemp(temp);
+  };
+
+// ------------ Definition of PixelMap abstract methods -
+
+/* retourne le nombre de pixels */ 
+/*!    Return total number of pixels  */
+virtual int_4 NbPixels() const;
+
+/* retourne la valeur du pixel d'indice k */ 
+/*!    Return value of pixel with index k */
+virtual T&       PixVal(int_4 k);
+virtual T const& PixVal(int_4 k) const;
+
+/* Return true if teta,phi in map  */
+virtual bool ContainsSph(double theta, double phi) const;
+/* retourne l'indice du pixel a (theta,phi) */ 
+/*    Return index of the pixel corresponding to direction (theta, phi). */
+virtual int_4 PixIndexSph(double theta, double phi) const;
+
+/* retourne les coordonnees Spheriques du centre du pixel d'indice k */ 
+/*!   Return (theta,phi) coordinates of middle of  pixel with  index k */
+virtual void PixThetaPhi(int_4 k, double& theta, double& phi) const;
+
+/*! Setting pixel values to a constant */
+virtual T SetPixels(T v);
+
+/* retourne/fixe l'angle Solide de Pixel   (steradians) */ 
+/*!   Pixel Solid angle  (steradians)
+
+    All the pixels have the same solid angle. The dummy argument is
+   for compatibility with eventual pixelizations which would not 
+    fulfil this requirement.
+*/
+virtual double PixSolAngle(int_4 dummy=0) const;
+ 
+/* retourne/fixe la valeur du parametre de decoupage m */ 
+inline virtual int_4 SizeIndex() const { return( NTheta_); }
+
+/*  Acces to the DataBlock  */
+inline       NDataBlock<T>& DataBlock()       {return pixels_;}
+inline const NDataBlock<T>& DataBlock() const {return pixels_;}
+
+// ------------- Specific methods  ----------------------
+
+/*!   re-pixelize the sphere */
+virtual void Resize(int_4 m);
+
+inline virtual string TypeOfMap() const {return string("TETAFI");};
+
+/* Valeurs de theta des paralleles et phi des meridiens limitant le pixel d'indice k */
+/*   Return values of theta,phi which limit the pixel with  index k */
+virtual void Limits(int_4 k,double& th1,double& th2,double& phi1,double& phi2);
+
+/* Nombre de tranches en theta */ 
+/*!    Return number of theta-slices on the sphere */
+uint_4 NbThetaSlices() const;
+
+/* Nombre de pixels en phi de la tranche d'indice kt */ 
+int_4 NPhi(int_4 kt) const;
+
+/* Renvoie dans t1,t2 les valeurs respectives de theta min et theta max  */
+/* de la tranche d'indice kt  */ 
+/*!    Return  theta values which limit the slice kt */
+void Theta(int_4 kt, double& t1, double& t2);
+
+/* Renvoie dans p1,p2 les valeurs phimin et phimax du pixel d'indice jp  */
+/* dans la tranche d'indice kt  */ 
+/*!   Return values of phi which limit the jp-th pixel of the kt-th slice */
+void Phi(int_4 kt, int_4 jp, double& p1, double& p2);
+
+/* Renvoie l'indice k du pixel d'indice jp dans la tranche d'indice kt   */
+/*!   Return pixel index  with sequence index jp in the slice kt */
+int_4 Index(int_4 kt, int_4 jp) const;
+
+/* Indice kt de la tranche et indice jp du pixel d'indice k  */ 
+/*!    Return indices kt (theta) and jp (phi) of  pixel with index k */
+void ThetaPhiIndex(int_4 k,int_4& kt,int_4& jp);
+
+/*!    achieve the splitting into pixels (m has the same signification 
+    as for the constructor)
+
+    Each theta-slice of the north hemisphere will be spitted starting f
+    from  phi=0 ...
+
+    South hemisphere is scanned in the same direction according to phi
+    and from equator to the pole (the pixel following the last one of
+    the slice closest to the equator with z>0, is the pixel with lowest 
+    phi of the slice closest of the equator with z<0).
+*/
+void Pixelize(int_4); 
+
+/*!   For a theta-slice with index 'index', return : 
+
+   the corresponding "theta" 
+
+    a vector containing the phi's of the pixels of the slice
+
+    a vector containing the corresponding values of pixels 
+*/
+virtual void GetThetaSlice(int_4 index,r_8& theta,TVector<r_8>& phi,TVector<T>& value) const; 
+
+/*!   For a theta-slice with index 'index', return : 
+
+   the corresponding "theta" 
+
+   the corresponding "phi" for first pixel of the slice 
+
+    a vector containing indices of the pixels of the slice
+
+   (equally distributed in phi)
+
+    a vector containing the corresponding values of pixels 
+*/
+virtual void GetThetaSlice(int_4 index, r_8& theta, r_8& phi0,TVector<int_4>& pixelIndices, TVector<T>& value) const ;
+
+
+/* impression */ 
+void print(ostream& os) const;
+
+
+
+// Operations diverses  = , +=, ...
+
+
+SphereThetaPhi<T>& Set(const SphereThetaPhi<T>& a);
+inline  SphereThetaPhi<T>& operator = (const SphereThetaPhi<T>& a) 
+                                                        {return Set(a);}
+
+// A += -= *= /= x (ajoute, soustrait, ... x a tous les elements)
+
+  //! Fill SphereThetaPhi with all elements equal to \b x
+virtual SphereThetaPhi<T>& SetT(T a); 
+inline  SphereThetaPhi<T>& operator = (T a) {return SetT(a);}
+
+//! Add \b x to all elements
+virtual SphereThetaPhi<T>& Add(T a); 
+inline  SphereThetaPhi<T>&  operator += (T x)  { return Add(x); }
+//! Substract \b x to all elements
+virtual SphereThetaPhi<T>& Sub(T a,bool fginv=false); 
+inline   SphereThetaPhi<T>&  operator -= (T x)  { return Sub(x); }
+//! Multiply all elements by \b x
+virtual SphereThetaPhi<T>& Mul(T a); 
+inline  SphereThetaPhi<T>&  operator *= (T x)  { return Mul(x); }
+//! Divide all elements by \b x
+virtual SphereThetaPhi<T>& Div(T a); 
+inline  SphereThetaPhi<T>&  operator /= (T x)  { return Div(x); }
+
+// A += -=  (ajoute, soustrait element par element les deux spheres )
+  //! Operator SphereThetaPhi += SphereThetaPhi
+  virtual SphereThetaPhi<T>&  AddElt(const SphereThetaPhi<T>& a);
+  inline  SphereThetaPhi<T>&  operator += (const SphereThetaPhi<T>& a)  { return AddElt(a); }
+
+
+
+  virtual SphereThetaPhi<T>&  SubElt(const SphereThetaPhi<T>& a);
+  //! Operator SphereThetaPhi -= SphereThetaPhi
+  inline  SphereThetaPhi<T>&  operator -= (const SphereThetaPhi<T>& a)  { return SubElt(a); }
+// Multiplication, division element par element les deux SphereThetaPhi 
+  virtual SphereThetaPhi<T>&  MulElt(const SphereThetaPhi<T>& a);
+  inline  SphereThetaPhi<T>&  operator *= (const SphereThetaPhi<T>& a)  { return MulElt(a); }
+  virtual SphereThetaPhi<T>&  DivElt(const SphereThetaPhi<T>& a);
+  inline  SphereThetaPhi<T>&  operator /= (const SphereThetaPhi<T>& a)  { return DivElt(a); }
+
+
+  void CloneOrShare(const SphereThetaPhi<T>& a);
+  void Share(const SphereThetaPhi<T>& a);
+
+  SphereThetaPhi<T>& CopyElt(const SphereThetaPhi<T>& a);
+
+
+
+
+
+
+ // friend declaration for classes which handle persistence and FITS IO
+  friend class FIO_SphereThetaPhi<T>;
+  friend class FITS_SphereThetaPhi<T>;
+
+protected :
+
+// ------------- méthodes internes ----------------------          
+void InitNul();
+inline void setParameters( int nbThetaIndex, int nbpix, double omega) 
+  {
+    NPix_= nbpix;
+    Omega_= omega;
+    NTheta_= nbThetaIndex;
+  }
+
+// ------------- variables internes ---------------------
+ int_4 NTheta_;   // nombre de tranches en theta, pour une demi-sphere
+ int_4 NPix_;     // nombre total de pixels
+ double Omega_; // angle solide constant pour chaque pixel
+ NDataBlock<int_4>  NPhi_;  // tableau donnant, pour chaque bande en theta, 
+                         //le nombre de pixels selon phi
+ NDataBlock<int_4> TNphi_; // tableau donnant ke nombre de pixels cumule,
+                           // jusqu'au debut de chaque tranche
+ NDataBlock<r_8> Theta_;
+ NDataBlock<T> pixels_;
+};
+
+////////////////////////////////////////////////////////////////
+// Surcharge d'operateurs A (+,-,*,/) (T) x
+/*! \ingroup SkyMap \fn operator+(const SphereThetaPhi<T>&,T)
+  \brief Operator SphereThetaPhi = SphereThetaPhi + constant */
+template <class T> inline SphereThetaPhi<T> operator + (const SphereThetaPhi<T>& a, T b)
+    {SphereThetaPhi<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Add(b); return result;}
+/*! \ingroup SkyMap \fn operator+(T,const SphereThetaPhi<T>&)
+  \brief Operator SphereThetaPhi = constant + SphereThetaPhi */
+template <class T> inline SphereThetaPhi<T> operator + (T b,const SphereThetaPhi<T>& a)
+    {SphereThetaPhi<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Add(b); return result;}
+
+
+/*! \ingroup SphereThetaPhi\fn operator-(const SphereThetaPhi<T>&,T)
+  \brief Operator SphereThetaPhi = SphereThetaPhi - constant */
+template <class T> inline SphereThetaPhi<T> operator - (const SphereThetaPhi<T>& a, T b)
+    {SphereThetaPhi<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Sub(b); return result;}
+
+/*! \ingroup  \fn operator-(T,const SphereThetaPhi<T>&)
+  \brief Operator SphereThetaPhi = constant - SphereThetaPhi */
+template <class T> inline SphereThetaPhi<T> operator - (T b,const SphereThetaPhi<T>& a)
+    {SphereThetaPhi<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Sub(b,true); return result;}
+
+/*! \ingroup SkyMap \fn operator*(const SphereThetaPhi<T>&,T)
+  \brief Operator SphereThetaPhi = SphereThetaPhi * constant */
+template <class T> inline SphereThetaPhi<T> operator * (const SphereThetaPhi<T>& a, T b)
+    {SphereThetaPhi<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Mul(b); return result;}
+
+/*! \ingroup SkyMap \fn operator*(T,const SphereThetaPhi<T>&)
+  \brief Operator SphereThetaPhi = constant * SphereThetaPhi */
+template <class T> inline SphereThetaPhi<T> operator * (T b,const SphereThetaPhi<T>& a)
+    {SphereThetaPhi<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Mul(b); return result;}
+
+/*! \ingroup SkyMap \fn operator/(const SphereThetaPhi<T>&,T)
+  \brief Operator SphereThetaPhi = SphereThetaPhi / constant */
+template <class T> inline SphereThetaPhi<T> operator / (const SphereThetaPhi<T>& a, T b)
+    {SphereThetaPhi<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Div(b); return result;}
+
+/*! \ingroup SkyMap \fn operator/(T,const SphereThetaPhi<T>&)
+  \brief Operator SphereThetaPhi = constant / SphereThetaPhi  */
+template <class T> inline SphereThetaPhi<T> operator / (T b, const SphereThetaPhi<T>& a)
+    {SphereThetaPhi<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Div(b, true); return result;}
+
+////////////////////////////////////////////////////////////////
+// Surcharge d'operateurs C = A (+,-) B
+
+/*! \ingroup SkyMap \fn operator+(const SphereThetaPhi<T>&,const SphereThetaPhi<T>&)
+  \brief Operator SphereThetaPhi = SphereThetaPhi + SphereThetaPhi */
+template <class T>
+inline SphereThetaPhi<T> operator + (const SphereThetaPhi<T>& a,const SphereThetaPhi<T>& b)
+    { SphereThetaPhi<T> result; result.SetTemp(true); 
+    if (b.IsTemp())  { result.Share(b); result.AddElt(a); }
+    else { result.CloneOrShare(a); result.AddElt(b); }
+    return result; }
+
+/*! \ingroup SkyMap \fn operator-(const SphereThetaPhi<T>&,const SphereThetaPhi<T>&)
+  \brief Operator SphereThetaPhi = SphereThetaPhi - SphereThetaPhi */
+template <class T>
+inline SphereThetaPhi<T> operator - (const SphereThetaPhi<T>& a,const SphereThetaPhi<T>& b)
+    { SphereThetaPhi<T> result; result.SetTemp(true); 
+    if (b.IsTemp())  { result.Share(b); result.SubElt(a, true); }
+    else { result.CloneOrShare(a); result.SubElt(b); }
+    return result; }
+
+////////////////////////////////////////////////////////////////
+// Surcharge d'operateurs C = A (*,/) B
+
+/*! \ingroup SkyMap \fn operator*(const SphereThetaPhi<T>&,const SphereThetaPhi<T>&)
+  \brief Operator SphereThetaPhi = SphereThetaPhi * SphereThetaPhi (pixel by pixel multiply)*/
+template <class T>
+inline SphereThetaPhi<T> operator * (const SphereThetaPhi<T>& a,const SphereThetaPhi<T>& b)
+    { SphereThetaPhi<T> result; result.SetTemp(true); 
+    if (b.IsTemp())  { result.Share(b); result.MulElt(a); }
+    else { result.CloneOrShare(a); result.MulElt(b); }
+    return result; }
+
+/*! \ingroup SkyMap \fn operator/(const SphereThetaPhi<T>&,const SphereThetaPhi<T>&)
+  \brief Operator SphereThetaPhi = SphereThetaPhi / SphereThetaPhi (pixel by pixel divide) */
+template <class T>
+inline SphereThetaPhi<T> operator / (const SphereThetaPhi<T>& a,const SphereThetaPhi<T>& b)
+    { SphereThetaPhi<T> result; result.SetTemp(true); 
+    if (b.IsTemp())  { result.Share(b); result.DivElt(a, true); }
+    else { result.CloneOrShare(a); result.DivElt(b); }
+    return result; }
+
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyMap/sphericalmap.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/sphericalmap.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/sphericalmap.h	(revision 2309)
@@ -0,0 +1,65 @@
+#ifndef SPHERICALMAP_SEEN
+#define SPHERICALMAP_SEEN
+
+// valeurs de Pi, 2*Pi, etc                                              
+#include "smathconst.h"
+#include <math.h>
+#include "pixelmap.h"
+#include "tvector.h" 
+
+// Map of pixels on a whole sphere.
+// Class hierarchy :
+//   PixelMap
+//      SphericalMap
+//         SphereThetaPhi
+//         SphereGorski
+//         SphereIco
+//      LocalMap
+
+
+
+
+namespace SOPHYA {
+
+/*!
+  \class SphericalMap
+  \ingroup SkyMap
+  Base class (pure virtual) for 4Pi spherical maps
+*/
+
+template<class T>
+class SphericalMap : public PixelMap<T> 
+{
+  
+public :
+
+SphericalMap() {};
+virtual	 ~SphericalMap() {};
+
+// Overloading of () to access pixel number k.
+inline T& operator()(int k) {return(PixVal(k));}
+inline T  const& operator()(int k) const {return(PixVal(k));}
+inline T& operator()(double theta,double phi) {return(PixValSph(theta,phi));};
+inline T  const& operator()(double theta,double phi) const {return(PixValSph(theta,phi));};
+
+// index characterizing the size pixelization : m for SphereThetaPhi
+// nside for Gorski sphere...
+virtual void Resize(int_4 m)=0;
+virtual uint_4 NbThetaSlices() const=0;
+virtual void GetThetaSlice(int_4 index,r_8& theta, TVector<r_8>& phi, TVector<T>& value) const=0; 
+virtual void GetThetaSlice(int_4 sliceIndex, r_8& theta, r_8& phi0, TVector<int_4>& pixelIndices,TVector<T>& value) const=0 ;
+};
+
+
+} // Fin du namespace
+
+
+
+
+#endif
+
+
+
+
+
+
Index: /tags/V_Dec2002/SophyaLib/SkyMap/unitvector.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/unitvector.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/unitvector.cc	(revision 2309)
@@ -0,0 +1,102 @@
+#include <math.h>
+#include "unitvector.h"
+//*****************************************************************************
+//++ 
+// Class	UnitVector
+//
+// include      unitvector.h vector3d.h math.h
+//--
+//++
+//
+// Links	Parents
+//
+//    Vector3d
+//    
+//-- 
+//++
+// Titre	Constructors
+//--
+//++
+UnitVector::UnitVector() : Vector3d(1.,0.,0.) 
+//
+//--
+{
+}
+//++
+UnitVector::UnitVector(double x, double y, double z) : Vector3d(x,y,z) 
+//
+//--
+{
+  this->Normalize();
+}
+//++
+UnitVector::UnitVector(double theta, double phi) : Vector3d(theta,phi) 
+//
+//--
+{
+  this->Normalize();
+}
+//++
+UnitVector::UnitVector(const Vector3d& v) : Vector3d(v) 
+//
+//--
+{
+  this->Normalize();
+}
+//++
+// Titre	Public Method
+//--
+//++
+void UnitVector::Print(ostream& os) const 
+//
+//--
+{
+  os << "UnitVector : (X,Y,Z)= (" << _x << ", " << _y << ", " << _z 
+     << ") Theta,Phi= " << _theta << ", " << _phi << "\n"
+     << "norme =" << this->Norm() << endl;
+}
+//++
+// Titre	Operators
+//--
+//++
+Vector3d& UnitVector::operator = (const Vector3d& v)
+//
+//--
+
+{
+  Setxyz(v.X(),v.Y(),v.Z());
+  this->Normalize();
+  return *this;
+}
+//++
+Vector3d& UnitVector::operator += (const Vector3d& v)
+//
+//--
+{
+  Setxyz(_x+v.X(),_y+v.Y(),_z+v.Z());
+  this->Normalize();
+  return *this;
+}
+//++
+Vector3d& UnitVector::operator -= (const Vector3d& v)
+//
+//--
+{
+  Setxyz(_x-v.X(),_y-v.Y(),_z-v.Z());
+  this->Normalize();
+  return *this;
+}
+//++
+Vector3d UnitVector::operator + (const Vector3d& v) const
+//
+//--
+{
+  return UnitVector(_x+v.X(),_y+v.Y(),_z+v.Z());
+}
+//++
+Vector3d UnitVector::operator - (const Vector3d& v) const
+//
+//--
+{
+  return UnitVector(_x-v.X(),_y-v.Y(),_z-v.Z());
+}
Index: /tags/V_Dec2002/SophyaLib/SkyMap/unitvector.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/unitvector.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/unitvector.h	(revision 2309)
@@ -0,0 +1,43 @@
+//   3-D Geometry 
+//        B. Revenu, G. Le Meur   2000
+// DAPNIA/SPP (Saclay) / CEA    LAL - IN2P3/CNRS  (Orsay)
+
+#ifndef UNITVECTOR_H_SEEN
+#define UNITVECTOR_H_SEEN
+
+#include <iostream.h>
+#include <stdio.h>
+#include <string.h>
+#include "vector3d.h"
+
+namespace SOPHYA { 
+
+class UnitVector : public Vector3d 
+{
+  
+ public:
+  
+  UnitVector();
+  UnitVector(double x, double y, double z);
+  UnitVector(double theta, double phi=0);
+  UnitVector(const Vector3d&);
+  
+  /*virtual*/ Vector3d& operator=(const Vector3d&);  //$CHECK$ EA 101299 operator = non virtual
+  virtual Vector3d& operator+=(const Vector3d&);
+  virtual Vector3d& operator-=(const Vector3d&);
+  virtual Vector3d operator+(const Vector3d&) const;
+  virtual Vector3d operator-(const Vector3d&) const;
+
+  virtual Vector3d& operator+=(double d) { return Vector3d::operator+= (d); }
+  virtual Vector3d operator+(double d) const { return Vector3d::operator+ (d); }
+  virtual Vector3d operator-(double d) const { return Vector3d::operator- (d); }
+
+  void Print(ostream& os) const;
+  
+};
+
+} // namespace SOPHYA
+
+#endif
+
+
Index: /tags/V_Dec2002/SophyaLib/SkyMap/utilgeom.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/utilgeom.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/utilgeom.cc	(revision 2309)
@@ -0,0 +1,125 @@
+#include <math.h>
+#include <iostream.h>
+#include "utilgeom.h"
+//++
+// Titre	Some utilitary functions for geometry (utilgeom.h)...
+//--
+//++
+int sign(double d) 
+//
+//--
+{
+  return (d >= 0) - (d < 0);
+}
+//++
+double absd(double d) 
+//
+//--
+{
+  return sqrt(d*d);
+}
+//++
+double mod(double d, double periode) 
+//
+//--
+{
+  if( d >= 0 ) return d-floor(d/periode)*periode;
+  else return d-ceil(d/periode)*periode+periode;
+}
+//++
+void swap(double& d1, double& d2) 
+//
+//--
+{
+  double temp;
+  temp=d2;
+  d2=d1;
+  d1=temp;
+}
+//++
+double min(double d1, double d2) 
+//
+//--
+{
+  if( d1 >= d2 ) return d2;
+  else return d1;
+}
+//++
+double max(double d1, double d2) 
+//
+//--
+{
+  return -min(-d1,-d2);
+}
+//++
+int arrondi(double d) 
+//
+//--
+{
+  return (int)(((d-floor(d)) >= 0.5)*ceil(d)+((d-floor(d)) < 0.5)*floor(d));
+}
+//++
+long rangijd(int nc, int i, int j, int d) 
+//
+//--
+{
+  if( i < j ) return 2*i*(2*nc-i-1)+4*(j-i-1)+d;
+  if( i > j ) return 2*j*(2*nc-j-1)+4*(i-j-1)+d+2;
+  if( i == j ) 
+    {
+      cout << "pas d'intersection entre le cercle " << i 
+	   << " et le cercle " << j << "." << endl;
+      return -1;
+    }
+  else return -1;
+}
+//++
+long rangdiff(int nc, int i, int j, int d) 
+//
+//--
+{
+  if( i == j ) 
+    {
+      cout << "diff n'est pas defini entre le cercle " << i 
+	   << " et le cercle " << j << "." << endl;
+      return 0;
+    }
+  int indm=(int)min(i,j);
+  int indM=(int)max(i,j);
+  return indm*(2*nc-indm-1)+2*(indM-indm-1)+d;
+}
+//++
+long rangik(int NtotEch, int i, int k)
+//
+//--
+{
+  return NtotEch*i+k;
+}
+//++
+long ranghk(int NtotEch, int h, int k) 
+//
+//--
+{
+  return NtotEch*h+k;
+}
+//++
+double scangle(double sinus, double cosinus) 
+//
+//--
+{	// Modifie par D. Y. pour eviter des plantages aux petis angles
+	double eps=1.e-10;
+	if( fabs(1.-sinus*sinus-cosinus*cosinus) > eps) 
+    {	   // On renormalise D.Y.
+	  // cerr << "angle non valide: "<< "sinus = " << sinus << " cosinus = " << cosinus << '\n'; // BUGGG
+      double norm= cosinus*cosinus+sinus*sinus;
+      cosinus=cosinus/norm;
+      sinus=sinus/norm;     
+    }
+  if( fabs(cosinus) >1. ) cosinus=1.*copysign(1.,cosinus);
+  if( fabs(sinus) >1. ) sinus=1.*copysign(1.,sinus);
+/*  if( fabs(sinus) == 0. ) sinus=0.;
+    if( fabs(cosinus) == 0. ) cosinus=0.;
+*/
+  return acos(cosinus)*copysign(1,sinus);
+}
+
Index: /tags/V_Dec2002/SophyaLib/SkyMap/utilgeom.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/utilgeom.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/utilgeom.h	(revision 2309)
@@ -0,0 +1,22 @@
+#ifndef UTILGEOM_H_SEEN
+#define UTILGEOM_H_SEEN
+#include <math.h>
+#ifdef __MWERKS__
+	#include "unixmac.h"
+#endif
+#include <vector>
+
+const double pi2=2.*M_PI;
+const double dtor=M_PI/180.;
+const double pi_over_2=M_PI/2.;
+
+int sign(double);
+double absd(double);
+double mod(double, double=0);
+void swap(double&, double&);
+double min(double, double);
+double max(double, double);
+int arrondi(double);
+double scangle(double sinus, double cosinus);
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyMap/vector3d.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/vector3d.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/vector3d.cc	(revision 2309)
@@ -0,0 +1,418 @@
+#include "machdefs.h"
+#include <math.h>
+#include "pexceptions.h"
+#include "vector3d.h"
+#include "utilgeom.h"
+//++ 
+// Class	Vector3d
+//
+// include      vector3d.h utilgeom.h  longlat.h math.h
+//
+//
+//    3-D geometry. 
+//    All computations are made with angles in radians and with spherical
+//    coordinates theta, phi.
+//
+//    Concerning Euler's angles, the reference is :
+// 
+//    "Classical Mechanics" 2nd edition, H. Goldstein, Addison Wesley
+//--
+//++
+// Titre	Constructors
+//--
+//++
+Vector3d::Vector3d()
+//
+//-- 
+{
+  Setxyz(1.,0.,0.);
+}
+//++
+Vector3d::Vector3d(double x, double y, double z) 
+//
+//-- 
+{
+  _x=x;
+  _y=y;
+  _z=z;
+  xyz2ThetaPhi();
+}
+//++
+Vector3d::Vector3d(double theta, double phi) 
+//
+//-- 
+{
+ // _theta=mod(theta,M_PI); // dans [0;pi]
+ // Version precedente fausse: _theta=M_PI est valide. Or mod(M_PI,M_PI)=0!
+ // De plus theta>pi ou <0 n'a pas de sens. Dominique Yvon
+	if( (theta<0.) || (theta>M_PI) )
+	{	string exmsg = "Wrong initialisation of theta in Vector3d::Vector3d(double theta, double phi)";
+		throw( ParmError(exmsg) );
+	}
+  _theta=theta; // dans [0;pi]
+  _phi=mod(phi,pi2); // dans [0;2pi]
+  ThetaPhi2xyz();
+}
+//++
+Vector3d::Vector3d(const LongLat& ll)
+//
+//-- 
+{
+  _theta=ll.Theta(); // dans [0;pi]
+  _phi=ll.Phi(); // dans [0;2pi]
+  ThetaPhi2xyz();
+}
+//++
+Vector3d::Vector3d(const Vector3d& v) 
+//
+//-- 
+{
+  _x=v._x;
+  _y=v._y;
+  _z=v._z;
+  _theta=v._theta;
+  _phi=v._phi;
+}
+//++
+// Titre	Public methods
+//--
+//++
+void Vector3d::SetThetaPhi(double theta, double phi)
+//
+//-- 
+{
+  _theta=mod(theta,M_PI);
+  _phi=mod(phi,pi2);
+  ThetaPhi2xyz();
+}
+//++
+void Vector3d::Setxyz(double x, double y, double z) 
+//
+//-- 
+{
+  _x=x;
+  _y=y;
+  _z=z;
+  xyz2ThetaPhi();
+}
+//++
+void Vector3d::ThetaPhi2xyz()
+//
+//-- 
+{
+  _x=sin(_theta)*cos(_phi);
+  _y=sin(_theta)*sin(_phi);
+  _z=cos(_theta);
+}
+//++
+void Vector3d::xyz2ThetaPhi()
+//
+//-- 
+{
+  double norm=this->Norm();
+  if( norm != 0. ) 
+    {
+      _theta=acos(_z/norm); // dans [0,Pi]
+      if( mod(_theta,M_PI) == 0. ) _phi=0.; // on est sur +-Oz, le vecteur z est en phi=0
+      //      else _phi=acos(_x/sin(_theta)/norm)+M_PI*(_y<0);
+      else _phi=scangle(_y/sin(_theta)/norm,_x/sin(_theta)/norm);
+    }
+  else // vecteur nul
+    {
+      _theta=0.;
+      _phi=0.;
+    }
+}
+//++
+Vector3d& Vector3d::Normalize() 
+//
+//-- 
+{
+  double norm=this->Norm();
+  if( norm != 0. )  (*this)/=norm;
+  else cerr << "Division par zero" << endl;
+  return *this;
+} 
+//++
+double Vector3d::Norm() const 
+//
+//-- 
+{
+  return sqrt(_x*_x+_y*_y+_z*_z);
+}
+//++
+double Vector3d::Psc(const Vector3d& v) const 
+//
+//    dot product
+//-- 
+{
+  return _x*v._x+_y*v._y+_z*v._z;
+}
+//++
+double Vector3d::SepAngle(const Vector3d& v) const 
+//
+//    angular gap between 2 vectors in [0,Pi]
+//-- 
+{
+  double n1=this->Norm();
+  double n2=v.Norm();
+  double ret;
+  if( n1!=0. && n2!=0. ) ret=acos((this->Psc(v))/n1/n2);
+  else 
+    {
+      cerr << "Division par zero" << endl;
+      ret=0.;
+    }
+  return ret;
+}
+//++
+Vector3d Vector3d::Vect(const Vector3d& v) const 
+//
+//    vector product
+//-- 
+{
+  double xo=_y*v._z-_z*v._y;
+  double yo=_z*v._x-_x*v._z;
+  double zo=_x*v._y-_y*v._x;
+  return Vector3d(xo,yo,zo);
+}
+//++
+Vector3d Vector3d::VperpPhi() const 
+//
+//    perpendicular vector, with equal phi
+//-- 
+{
+  double theta;
+  if( _theta != pi_over_2 ) theta=_theta+(0.5-(_theta>pi_over_2))*M_PI; // on tourne theta de +-pi/2
+  else theta=0.;
+  return Vector3d(theta,_phi);
+}
+//++
+Vector3d Vector3d::VperpTheta() const 
+//
+//    perpendicular vector with equal theta
+//-- 
+{ cerr<< " Erreur in Vector3d::VperpTheta()"<<endl;
+  throw PError("Vector3d::VperpTheta() - Logic Error DY/Reza 20/02/2000"); 
+  // Bug ??? (D. Yvon, Fevrier 2000)
+  //  double phi=mod(_phi+pi_over_2,pi2); // on tourne phi de pi/2
+  //  return Vector3d(_theta,phi);
+}
+
+Vector3d Vector3d::EPhi() const 
+{
+  Vector3d temp;
+  if ( fabs(_z) == 1. ) // si on est en +- Oz
+    {
+      temp=Vector3d(1.,0.,0.);
+    }
+  else 
+    {
+      Vector3d k(0,0,-1);
+      temp=this->Vect(k);
+      temp.Normalize();
+    }
+  return temp;
+}
+//++
+Vector3d Vector3d::ETheta() const 
+//
+//-- 
+{
+  Vector3d temp=this->Vect(EPhi());
+  temp.Normalize();
+  return temp;
+}
+
+//++
+Vector3d Vector3d::Euler(double phi, double theta, double psi) const 
+//
+//    Euler's rotations
+//-- 
+{
+  double cpsi=cos(psi);
+  double ctheta=cos(theta);
+  double cphi=cos(phi);
+  double spsi=sin(psi);
+  double stheta=sin(theta);
+  double sphi=sin(phi);
+  double xnew=(cpsi*cphi-ctheta*sphi*spsi)*_x
+    +(cpsi*sphi+ctheta*cphi*spsi)*_y
+    +spsi*stheta*_z;
+  double ynew=(-spsi*cphi-ctheta*sphi*cpsi)*_x
+    +(-spsi*sphi+ctheta*cphi*cpsi)*_y
+    +cpsi*stheta*_z;
+  double znew=stheta*sphi*_x-stheta*cphi*_y+ctheta*_z;
+  return Vector3d(xnew,ynew,znew);
+}
+//++
+Vector3d Vector3d::InvEuler(double phi, double theta, double psi) const 
+//
+//    inverse rotation
+//-- 
+{
+  double cpsi=cos(psi);
+  double ctheta=cos(theta);
+  double cphi=cos(phi);
+  double spsi=sin(psi);
+  double stheta=sin(theta);
+  double sphi=sin(phi);
+  double xnew=(cpsi*cphi-ctheta*sphi*spsi)*_x
+    -(spsi*cphi+ctheta*sphi*cpsi)*_y
+    +sphi*stheta*_z;
+  double ynew=(cpsi*sphi+ctheta*cphi*spsi)*_x
+    +(-spsi*sphi+ctheta*cphi*cpsi)*_y
+    -cphi*stheta*_z;
+  double znew=stheta*spsi*_x+stheta*cpsi*_y+ctheta*_z;
+  return Vector3d(xnew,ynew,znew);
+}
+//++
+Vector3d Vector3d::Rotate(const Vector3d& omega, double phi) const
+//
+//    rotation of angle phi around an axis omega (Maxwell's rule)
+//-- 
+{
+  Vector3d rotationaxis=omega;
+  rotationaxis.Normalize();
+  double n=this->Psc(rotationaxis);
+  Vector3d myself=*this;
+  Vector3d rotate=n*rotationaxis+(myself-n*rotationaxis)*cos(phi)-(myself^rotationaxis)*sin(phi);
+  return rotate;
+} 
+//++  
+void Vector3d::Print(ostream& os) const 
+//
+//--
+{
+  os << "Vector3: (X,Y,Z)= (" << _x << ", " << _y << ", " << _z 
+     << ") --- Theta,Phi= " << _theta << ", " << _phi << "\n"
+     << "Norme = " << this->Norm() << endl;
+}
+//++
+// Titre	Operators
+//--
+//++
+Vector3d& Vector3d::operator += (const Vector3d& v) 
+//
+//-- 
+{
+  *this=*this+v;
+  return *this;
+}
+//++
+Vector3d& Vector3d::operator -= (const Vector3d& v) 
+//
+//-- 
+{
+  *this=*this-v;
+  return *this;
+}
+//++
+Vector3d& Vector3d::operator += (double d) 
+//
+//-- 
+{
+  Setxyz(_x+d,_y+d,_z+d);
+  return *this;
+}
+//++
+Vector3d& Vector3d::operator /= (double d) 
+//
+//-- 
+{
+  if( d != 0. ) Setxyz(_x/d,_y/d,_z/d);
+  else cerr << "Division par zero." << endl;
+  return *this;
+}
+//++
+Vector3d& Vector3d::operator *= (double d) 
+//
+//-- 
+{
+  Setxyz(_x*d,_y*d,_z*d);
+  return *this;
+}
+//++
+Vector3d Vector3d::operator ^ (const Vector3d& v) const 
+//
+//    vector product
+//-- 
+{
+  return this->Vect(v);
+}
+//++
+Vector3d Vector3d::operator + (double d) const 
+//
+//-- 
+{
+  return Vector3d(_x+d,_y+d,_z+d);
+}
+//++
+Vector3d Vector3d::operator + (const Vector3d& v) const 
+//
+//-- 
+{
+  return Vector3d(_x+v._x,_y+v._y,_z+v._z);
+}
+//++
+Vector3d Vector3d::operator - (double d) const 
+//
+//-- 
+{
+  return *this+(-d);
+}
+//++
+Vector3d Vector3d::operator - (const Vector3d& v) const 
+//
+//-- 
+{
+  return *this+(v*(-1.));
+}
+//++
+Vector3d Vector3d::operator * (double d) const 
+//
+//-- 
+{
+  return Vector3d(d*_x,d*_y,d*_z);
+}
+//++
+double Vector3d::operator * (const Vector3d& v) const 
+//
+//    dot product
+//-- 
+{
+  return this->Psc(v);
+}
+//++
+Vector3d Vector3d::operator / (double d) const 
+//
+//-- 
+{
+  Vector3d ret=*this;
+  if( d != 0. ) ret/=d;
+  else  cerr << "Division par zero." << endl;
+  return ret;
+}
+//++
+Vector3d& Vector3d::operator = (const Vector3d& v) 
+//
+//-- 
+{
+  if( this != &v ) 
+    {
+      _x=v._x; 
+      _y=v._y; 
+      _z=v._z; 
+      _theta=v._theta; 
+      _phi=v._phi;
+    }
+  return *this;
+}
+//++
+bool Vector3d::operator == (const Vector3d& v) 
+//
+//-- 
+{
+  return (this==&v);
+}
+
Index: /tags/V_Dec2002/SophyaLib/SkyMap/vector3d.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyMap/vector3d.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyMap/vector3d.h	(revision 2309)
@@ -0,0 +1,154 @@
+//   3-D Geometry 
+//        B. Revenu, G. Le Meur   2000
+// DAPNIA/SPP (Saclay) / CEA    LAL - IN2P3/CNRS  (Orsay)
+
+#ifndef VECTOR3D_H_SEEN
+#define VECTOR3D_H_SEEN
+
+#include <math.h>
+#include <iostream.h>
+#include <stdio.h>
+#include <string.h>
+#ifdef __MWERKS__
+#include "unixmac.h"
+#endif
+#include "longlat.h"
+
+/*
+  Geometrie en dimension 3. 
+  Tous les calculs sont faits en radians 
+  et en coordonnees spheriques theta,phi
+  pour les rotations (angles d'Euler) ma source est 
+  "Classical Mechanics" 2nd edition, H. Goldstein, Addison Wesley
+*/
+/*!    3-D geometry. 
+
+    All computations are made with angles in radians and with spherical
+    coordinates theta, phi.
+
+    Concerning Euler's angles, the reference is :
+ 
+    "Classical Mechanics" 2nd edition, H. Goldstein, Addison Wesley
+*/
+
+namespace SOPHYA { 
+ 
+class Vector3d 
+{
+
+ public:
+  
+  Vector3d();
+  Vector3d(double x, double y, double z);
+  Vector3d(double theta, double phi);
+  Vector3d(const LongLat&);
+  Vector3d(const Vector3d&);
+
+//   To manipulate the vector
+  virtual void Setxyz(double x, double y, double z);
+  virtual void SetThetaPhi(double theta,  double phi);
+  virtual void ThetaPhi2xyz();
+  virtual void xyz2ThetaPhi();
+
+// Acces to coordinates
+  inline double Theta() const {return _theta;}
+  inline double Phi() const {return _phi;}
+  inline double X() const {return _x;}
+  inline double Y() const {return _y;}
+  inline double Z() const {return _z;}
+
+  virtual Vector3d& Normalize();
+  virtual double Norm() const;
+
+  // produit scalaire
+  virtual double Psc(const Vector3d&) const;
+
+  // ecart angulaire entre 2 vecteurs dans [0,Pi]
+  /*!   angular gap between 2 vectors in [0,Pi] */
+  virtual double SepAngle(const Vector3d&) const;
+
+  // produit vectoriel
+  /*!    vector product */
+  virtual Vector3d Vect(const Vector3d&) const;
+
+  // vecteur perpendiculaire de meme phi
+  /*!    perpendicular vector, with equal phi */
+  virtual Vector3d VperpPhi() const;
+
+  // vecteur perpendiculaire de meme theta
+  /*!    perpendicular vector with equal theta */
+  virtual Vector3d VperpTheta() const;
+
+  virtual Vector3d ETheta() const;
+  virtual Vector3d EPhi() const;
+
+  // rotations d'Euler
+  /*!    Euler's rotations */
+  // rotations d Euler
+  virtual Vector3d Euler(double, double, double) const;
+
+  // rotation inverse
+  /*!    inverse rotation */
+  Vector3d InvEuler(double, double, double) const;
+
+  // rotation d'angle phi autour d'un axe omega (regle du tire-bouchon)
+  /*!    rotation of angle phi around an axis omega (Maxwell's rule) */
+  Vector3d Rotate(const Vector3d& omega,double phi) const;
+
+  /*virtual*/ Vector3d& operator=(const Vector3d&); // $CHECK$ EA 101299
+  virtual Vector3d& operator+=(const Vector3d&);
+  virtual Vector3d& operator-=(const Vector3d&);
+  virtual Vector3d operator+(const Vector3d&) const;
+  virtual Vector3d operator-(const Vector3d&) const;
+
+  virtual Vector3d& operator+=(double);
+  virtual Vector3d& operator/=(double);
+  virtual Vector3d& operator*=(double);
+
+  virtual Vector3d operator+(double) const;
+  virtual Vector3d operator-(double) const;
+  virtual Vector3d operator*(double) const;
+  virtual Vector3d operator/(double) const;
+
+  /*!    vector product */
+  virtual Vector3d operator^(const Vector3d&) const; // produit vectoriel
+  /*!    dot product */
+  virtual double operator*(const Vector3d&) const; // produit scalaire
+
+  bool operator==(const Vector3d&);
+  
+  virtual void Print(ostream& os) const;
+
+ protected:
+
+  double _x;
+  double _y;
+  double _z;
+  double _theta;
+  double _phi;
+
+};
+
+inline ostream& operator<<(ostream& s, const Vector3d& v) 
+{  
+  v.Print(s);  
+  return s;  
+}
+
+// fonctions globales
+
+inline Vector3d operator*(double d, const Vector3d& v) 
+{
+  return v*d;
+}
+
+inline Vector3d operator+(double d, const Vector3d& v) 
+{
+  return v+d;
+}
+
+} // namespace SOPHYA
+
+#endif
+
+
Index: /tags/V_Dec2002/SophyaLib/SkyT/Makefile
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyT/Makefile	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyT/Makefile	(revision 2309)
@@ -0,0 +1,118 @@
+include ../Mgr/Makefile.h
+ 
+all: $(LIB)libSkyT.a
+clean:
+	rm -f $(OBJ)blackbody.o $(OBJ)convtools.o $(OBJ)derivblackbody.o $(OBJ)gaussfilt.o $(OBJ)nupower.o $(OBJ)radspec.o $(OBJ)radspecvector.o $(OBJ)skyinit.o $(OBJ)specresp.o $(OBJ)specrespvector.o $(OBJ)squarefilt.o $(OBJ)trianglefilt.o
+	rm -f $(LIB)libSkyT.a
+$(LIB)libSkyT.a : $(OBJ)blackbody.o $(OBJ)convtools.o $(OBJ)derivblackbody.o $(OBJ)gaussfilt.o $(OBJ)nupower.o $(OBJ)radspec.o $(OBJ)radspecvector.o $(OBJ)skyinit.o $(OBJ)specresp.o $(OBJ)specrespvector.o $(OBJ)squarefilt.o $(OBJ)trianglefilt.o
+	$(ARCXX) $(ARCXXFLAGS) $@ $($(ARARGS))
+ifeq ($(CXX),cxx)
+	$(CXX) $? $(CPPFLAGS) $(CXXFLAGS) -o $(OBJ)xx.x -Hf
+endif 
+ 
+$(OBJ)blackbody.o: blackbody.cc $(INC)machdefs.h \
+ blackbody.h radspec.h specresp.h \
+ $(INC)anydataobj.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h convtools.h
+$(OBJ)convtools.o: convtools.cc convtools.h \
+ $(INC)machdefs.h
+$(OBJ)derivblackbody.o: derivblackbody.cc \
+ $(INC)machdefs.h derivblackbody.h radspec.h \
+ specresp.h $(INC)anydataobj.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h convtools.h
+$(OBJ)gaussfilt.o: gaussfilt.cc $(INC)machdefs.h \
+ gaussfilt.h specresp.h $(INC)anydataobj.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h
+$(OBJ)nupower.o: nupower.cc $(INC)machdefs.h \
+ nupower.h radspec.h specresp.h \
+ $(INC)anydataobj.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h convtools.h
+$(OBJ)radspec.o: radspec.cc $(INC)machdefs.h \
+ radspec.h specresp.h $(INC)anydataobj.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)integ.h
+$(OBJ)radspecvector.o: radspecvector.cc \
+ $(INC)machdefs.h radspecvector.h radspec.h \
+ specresp.h $(INC)anydataobj.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h
+$(OBJ)skyinit.o: skyinit.cc skyinit.h \
+ $(INC)ntoolsinit.h \
+ $(INC)tarrinit.h \
+ $(INC)sophyainit.h \
+ $(INC)machdefs.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h specrespvector.h \
+ specresp.h $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h gaussfilt.h
+$(OBJ)specresp.o: specresp.cc specresp.h \
+ $(INC)machdefs.h \
+ $(INC)anydataobj.h \
+ $(INC)integ.h \
+ $(INC)pexceptions.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h
+$(OBJ)specrespvector.o: specrespvector.cc \
+ $(INC)machdefs.h specrespvector.h specresp.h \
+ $(INC)anydataobj.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)fioarr.h
+$(OBJ)squarefilt.o: squarefilt.cc $(INC)machdefs.h \
+ squarefilt.h specresp.h $(INC)anydataobj.h
+$(OBJ)trianglefilt.o: trianglefilt.cc \
+ $(INC)machdefs.h trianglefilt.h specresp.h \
+ $(INC)anydataobj.h
Index: /tags/V_Dec2002/SophyaLib/SkyT/Makefile.am
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyT/Makefile.am	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyT/Makefile.am	(revision 2309)
@@ -0,0 +1,8 @@
+lib_LIBRARIES = libSkyT.a
+
+libSkyT_a_SOURCES = \
+blackbody.cc  derivblackbody.cc  nupower.cc  radspecvector.cc  specresp.cc        squarefilt.cc \
+convtools.cc  gaussfilt.cc       radspec.cc  skyinit.cc        specrespvector.cc  trianglefilt.cc
+
+
+DEFS = -I.. -I../include
Index: /tags/V_Dec2002/SophyaLib/SkyT/blackbody.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyT/blackbody.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyT/blackbody.cc	(revision 2309)
@@ -0,0 +1,99 @@
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: blackbody.cc,v 1.7 2002-07-31 10:25:34 ansari Exp $
+//
+// Description:
+//      Aim of the class: To give the energy density for a blackbody
+//                        The unity used here is W/m^2/Hz/sr
+//
+// History (add to end):
+//      Sophie   Oct, 1999  - creation
+//
+//------------------------------------------------------------------------
+
+//---------------
+// C++ Headers --
+//---------------
+#include "machdefs.h"
+#include <iostream.h>
+#include <math.h>
+#include "blackbody.h"
+
+/*! 
+ * \class SOPHYA::BlackBody 
+ \ingroup SkyT
+ This class corresponds to the emission spectrum of a
+ blackbody radiation.
+ */
+//----------------
+// Constructor --
+//----------------
+/*! Constructor: needs a temperature. Otherwise set to ConvTools::tcmb */
+BlackBody::BlackBody(double temperature)
+  : RadSpectra(10., 10000.)
+{
+  _temperature = temperature;
+}
+
+
+BlackBody::~BlackBody()
+{
+}
+/*! Black Body Flux Function:
+  \f[
+  I_\nu = {2 h_{pl} (1.10^9*\nu)^3 \over c^2 (e^{{h_{pl}(1.10^9*\nu) \over kT}} -1)}
+  \f]
+*/
+double
+BlackBody::flux(double nu) const
+{
+  if(nu < -1.e99) nu = -1.e99;
+  if(nu > 1.e99) nu = 1.e99;
+  double temperature = getTemperature();
+  if(nu==0.) return 0.;
+  double hpl = ConvTools::hpl;
+  double cel = ConvTools::cel;
+  double kb  = ConvTools::kb;
+  double puiss1 = nu*pow(10.,9);
+  if(puiss1 >  1.e99)   puiss1=1.e99;
+  if(puiss1 < -1.e99)   puiss1=-1.e99;
+  double puiss2 = hpl*nu*pow(10.,9)/(kb*temperature);
+  if(puiss2 >  1.e99)   puiss2=1.e99;
+  if(puiss2 < -1.e99)   puiss2=-1.e99;
+  
+  double result=
+   (2*hpl* pow( puiss1 ,3))/( pow(cel,2)*(exp(puiss2)-1));
+  return result;
+}
+
+
+void
+BlackBody::Print(ostream& os) const
+{
+  os << "BlackBody::Print Temp= " << getTemperature() 
+     << " - Fmin,Fmax= " << minFreq() << "," << maxFreq() << endl;
+  os << "MeanFreq= " << meanFreq() << "  Emission= " << flux(meanFreq()) << endl;
+  os << "PeakFreq= " << peakFreq() << "  Emission= " << flux(peakFreq()) << endl;
+
+}
+
+/*
+void 
+BlackBody::WriteSelf(POutPersist& s)  
+{
+  s.PutR8(this->getTemperature());
+  s.PutR8(this->minFreq());
+  s.PutR8(this->maxFreq());
+}
+
+void
+BlackBody::ReadSelf(PInPersist& s)  
+{
+  s.GetR8(_temperature);
+  s.GetR8(_numin);
+  s.GetR8(_numax);
+  cout << " Temperature - minFreq - maxFreq " << endl; 
+  cout << _temperature << "-" << _numin << "-" << _numax << endl;
+}
+
+*/
Index: /tags/V_Dec2002/SophyaLib/SkyT/blackbody.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyT/blackbody.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyT/blackbody.h	(revision 2309)
@@ -0,0 +1,43 @@
+// This may look like C code, but it is really -*- C++ -*-
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: blackbody.h,v 1.5 2000-04-13 08:17:02 ansari Exp $
+//
+// Description:
+//
+// History (add to end):
+//      Sophie   Oct, 1999  - creation
+//
+//------------------------------------------------------------------------
+
+#ifndef BLACKBODY_H_SEEN
+#define BLACKBODY_H_SEEN
+
+#include "radspec.h"
+#include "convtools.h"
+namespace SOPHYA {
+class BlackBody : public RadSpectra
+{
+public:   //Constructor
+  //Constructor
+  BlackBody (double temp = ConvTools::tcmb);
+
+  virtual ~BlackBody();
+
+  virtual double flux(double nu) const;
+
+  // returns the value of the temperature
+  inline double getTemperature() const {return _temperature;} 
+
+  // reset the value of the temperature with a new value
+  inline void setTemperature(double newtemp) { _temperature = newtemp; }
+
+  // Redefintion of the Print function
+  virtual void      Print(ostream& os)  const;
+
+protected:
+  double _temperature;
+
+};
+}
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyT/convtools.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyT/convtools.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyT/convtools.cc	(revision 2309)
@@ -0,0 +1,28 @@
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: convtools.cc,v 1.3 2000-04-14 07:28:12 ansari Exp $
+//
+// Description:
+//
+// History (add to end):
+//      Sophie   Oct, 1999  - creation
+//
+//------------------------------------------------------------------------
+
+#include "convtools.h"
+
+/*! \class SOPHYA::ConvTools
+ * \ingroup SkyT
+ * Definition of usual usefull constants
+ */
+// Boltzman constant  J/K
+double ConvTools::kb =  1.380662e-23;     
+// Mean value of the cmb temperature (K)
+double ConvTools::tcmb=2.728;
+// Planck constant in  Js
+double ConvTools::hpl=6.626176e-34;   
+// Light speed  PDG 1992 m/s
+double ConvTools::cel=299792458.; 
+
+
+
Index: /tags/V_Dec2002/SophyaLib/SkyT/convtools.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyT/convtools.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyT/convtools.h	(revision 2309)
@@ -0,0 +1,31 @@
+// This may look like C code, but it is really -*- C++ -*-
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: convtools.h,v 1.4 2000-04-13 10:46:14 ansari Exp $
+//
+// Description:
+//      Definition of general constant and some convertion functions
+//
+// History (add to end):
+//      Sophie   Oct, 1999  - creation
+//
+//------------------------------------------------------------------------
+
+#ifndef CONV_TOOLS_H_SEEN
+#define CONV_TOOLS_H_SEEN
+
+#include "machdefs.h"
+
+namespace SOPHYA {
+class ConvTools
+{
+public:
+ static double kb;
+ static double tcmb;
+ static double hpl;
+ static double cel;
+
+};
+}  // End of namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyT/derivblackbody.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyT/derivblackbody.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyT/derivblackbody.cc	(revision 2309)
@@ -0,0 +1,106 @@
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: derivblackbody.cc,v 1.5 2002-07-31 10:25:34 ansari Exp $
+//
+// Description:
+//      Aim of the class: To give the derivative spectrum
+//                        The unity used here is W/m^2/Hz/sr
+//
+// History (add to end):
+//      Sophie   Oct, 1999  - creation
+//
+//------------------------------------------------------------------------
+
+//---------------
+// C++ Headers --
+//---------------
+#include "machdefs.h"
+#include <iostream.h>
+#include <math.h>
+#include "derivblackbody.h"
+
+
+
+/*! \class SOPHYA::DerivBlackBody 
+  \ingroup SkyT
+ * This class corresponds to the emission spectrum of a
+ * dipole (since its emission spectrum is the derivation
+ * of a blackbody spectrum wrt the temperature).
+ */
+
+/*! Constructor: needs a temperature. Otherwise set to ConvTools::tcmb */
+DerivBlackBody::DerivBlackBody(double temperature)
+  : RadSpectra(10., 10000.)
+{
+  _temperature = temperature;
+}
+
+
+DerivBlackBody::~DerivBlackBody()
+{
+}
+
+/*!
+  The flux function is the derivation of the BlackBody
+  flux function wrt the temperature (used e.g. for a Dipole)
+  \f[
+  I_\nu = {2 h_{pl} (1.10^9*\nu)^3  {h_{pl}1.10^9*\nu \over k T^2}
+        {e^{{h_{pl}(1.10^9*\nu) \over kT}}\over c^2 (e^{{h_{pl}(1.10^9*\nu) \over kT}} -1)^2}}
+  \f]
+*/
+double
+DerivBlackBody::flux(double nu) const
+{
+  if(nu < -1.e99) nu = -1.e99;
+  if(nu > 1.e99) nu = 1.e99;
+  double temperature = getTemperature();
+  if(nu==0.) return 0.;
+  double hpl = ConvTools::hpl;
+  double cel = ConvTools::cel;
+  double kb  = ConvTools::kb;
+  double puiss1 = nu*pow(10.,9);
+  if(puiss1 >  1.e99)   puiss1=1.e99;
+  if(puiss1 < -1.e99)   puiss1=-1.e99;
+  double puiss2 = hpl*nu*pow(10.,9)/(kb*temperature);
+  if(puiss2 >  1.e99)   puiss2=1.e99;
+  if(puiss2 < -1.e99)   puiss2=-1.e99;
+  
+  double result=
+   (2*hpl* pow( puiss1 ,3))*(hpl*puiss1/kb)*(1/(temperature*temperature))
+    *exp(puiss2)
+    /(pow(cel,2)*pow(( (exp(puiss2)-1)),2));
+  //  result = 1500e3*result/400e6;
+  return result;
+}
+
+
+void
+DerivBlackBody::Print(ostream& os) const
+{
+  os << "DerivBlackBody::Print Temp= " << getTemperature() 
+     << " - Fmin,Fmax= " << minFreq() << "," << maxFreq() << endl;
+  os << "MeanFreq= " << meanFreq() << "  Emission= " << flux(meanFreq()) << endl;
+  os << "PeakFreq= " << peakFreq() << "  Emission= " << flux(peakFreq()) << endl;
+
+}
+
+/*
+void 
+DerivBlackBody::WriteSelf(POutPersist& s)  
+{
+  s.PutR8(this->getTemperature());
+  s.PutR8(this->minFreq());
+  s.PutR8(this->maxFreq());
+}
+
+void
+DerivBlackBody::ReadSelf(PInPersist& s)  
+{
+  s.GetR8(_temperature);
+  s.GetR8(_numin);
+  s.GetR8(_numax);
+  cout << " Temperature - minFreq - maxFreq " << endl; 
+  cout << _temperature << "-" << _numin << "-" << _numax << endl;
+}
+
+*/
Index: /tags/V_Dec2002/SophyaLib/SkyT/derivblackbody.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyT/derivblackbody.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyT/derivblackbody.h	(revision 2309)
@@ -0,0 +1,43 @@
+// This may look like C code, but it is really -*- C++ -*-
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: derivblackbody.h,v 1.2 2000-04-13 08:17:03 ansari Exp $
+//
+// Description:
+//
+// History (add to end):
+//      Sophie   Oct, 1999  - creation
+//
+//------------------------------------------------------------------------
+
+#ifndef DERIVBLACKBODY_H_SEEN
+#define DERIVBLACKBODY_H_SEEN
+
+#include "radspec.h"
+#include "convtools.h"
+namespace SOPHYA {
+class DerivBlackBody : public RadSpectra
+{
+public:   //Constructor
+  //Constructor
+  DerivBlackBody (double temp = ConvTools::tcmb);
+
+  virtual ~DerivBlackBody();
+
+  virtual double flux(double nu) const;
+
+  // returns the value of the temperature
+  inline double getTemperature() const {return _temperature;} 
+
+  // reset the value of the temperature with a new value
+  inline void setTemperature(double newtemp) { _temperature = newtemp; }
+
+  // Redefintion of the Print function
+  virtual void      Print(ostream& os)  const;
+
+protected:
+  double _temperature;
+
+};
+}
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyT/gaussfilt.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyT/gaussfilt.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyT/gaussfilt.cc	(revision 2309)
@@ -0,0 +1,161 @@
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: gaussfilt.cc,v 1.6 2000-04-14 07:28:12 ansari Exp $
+//
+// Description:
+//
+// History (add to end):
+//      Sophie   Oct, 1999  - creation
+//
+//------------------------------------------------------------------------
+
+//---------------
+// C++ Headers --
+//---------------
+#include "machdefs.h"
+#include <iostream.h>
+#include <math.h>
+
+#include "gaussfilt.h"
+
+/*! 
+ * \class SOPHYA::GaussianFilter
+ * \ingroup SkyT
+ * Gaussian detector response
+ */
+GaussianFilter::GaussianFilter()
+  : SpectralResponse()
+{
+  setParams(100, 10., 1.);
+}
+
+/*! Constructor: the parameters correspond to the function defined in the 
+  <a href="#gausseq"> equation </a> below 
+*/
+GaussianFilter::GaussianFilter(double nu0, double s, double a, double numin, double numax)
+  : SpectralResponse(numin, numax)
+{
+  setParams(nu0, s, a);
+}
+
+
+//--------------
+// Destructor --
+//--------------
+GaussianFilter::~GaussianFilter()
+{
+}
+
+//              ---------------------------
+//              --  Function Definitions --
+//              ---------------------------
+
+/*! The transmission function is the wel known gaussian:
+  <a name="gausseq"> </a>
+  \f[
+  \hbox{transmission}= A  e^{-{({\nu-\nu_0\over s})^2}};
+  \f]
+*/
+
+double 
+GaussianFilter::transmission(double nu) const
+{
+  if ((nu < _numin) || (nu > _numax)) return(0.);
+  else { 
+    double tmp = (nu-_nu0)/_s;
+    return(_a * exp(-tmp*tmp));
+  }
+}
+
+double 
+GaussianFilter::peakFreq()  const
+{
+return(_nu0);
+}
+
+double 
+GaussianFilter::peakTransmission() const
+{
+return(_a);
+}
+
+
+
+void 
+GaussianFilter::setParams(double nu0, double s, double a)
+{
+  if (s < 1.e-19) s = 1.e-19;
+  _s = s;
+  _nu0 = nu0;
+  _a = a;
+}
+
+
+
+void 
+GaussianFilter::Print(ostream& os)  const
+{ 
+  os << "GaussianFilter::Print - Fmin,Fmax= " << minFreq() << "," << maxFreq() << endl;
+  os << " T = A * Exp(-((nu-nu0)/s)^2) : " << " nu0= " << _nu0 << " sig= " 
+     << _s << "  A= " << _a << endl;  
+  os << "PeakFreq= " << peakFreq() << "  Transmission= " << transmission(peakFreq()) << endl;
+
+
+}
+
+void
+ObjFileIO<GaussianFilter>::WriteSelf(POutPersist& s) const
+{
+  if(dobj == NULL)
+    {
+      cout << " ObjFileIO<GaussianFilter>::WriteSelf:: dobj= null " << endl;
+      return;
+    }
+  int_4 version, nothing;
+  version = 1;
+  nothing = 0;   // Reserved for future use 
+  s.PutI4(version);
+  s.PutI4(nothing);
+
+  s.PutR8(dobj->minFreq());
+  s.PutR8(dobj->maxFreq());
+  s.PutR8(dobj->giveNorm());
+  s.PutR8(dobj->giveNu0());
+  s.PutR8(dobj->giveDNu());
+}
+
+void
+ObjFileIO<GaussianFilter>::ReadSelf(PInPersist& s)  
+{
+  int_4 version, nothing;
+  version = 1;
+  nothing = 0;   // Reserved for future use 
+  s.GetI4(version);
+  s.GetI4(nothing);
+
+  if(dobj == NULL)
+    {
+      dobj= new GaussianFilter();
+      ownobj= true;
+    }
+
+  r_8 a, nu0, dnu, numin, numax;
+  s.GetR8(numin);
+  s.GetR8(numax);
+  s.GetR8(a);
+  s.GetR8(nu0);
+  s.GetR8(dnu);
+  dobj->setMinMaxFreq(numin, numax);
+  dobj->setParams(nu0, dnu, a);
+  //  cout << " Norm - Nu0 - DNu - minFreq - maxFreq " << endl; 
+  // cout << _a << "-" << _nu0  << "-" << _s << "-" << _numin << "-" << _numax << endl;
+}
+
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template ObjFileIO<GaussianFilter>
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class ObjFileIO<GaussianFilter>;
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyT/gaussfilt.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyT/gaussfilt.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyT/gaussfilt.h	(revision 2309)
@@ -0,0 +1,74 @@
+// This may look like C code, but it is really -*- C++ -*-
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: gaussfilt.h,v 1.5 2000-04-06 17:09:39 ansari Exp $
+//
+// Description:
+//
+// History (add to end):
+//      Sophie   Oct, 1999  - creation
+//
+//------------------------------------------------------------------------
+
+#ifndef GAUSSFILT_H_SEEN
+#define GAUSSFILT_H_SEEN
+
+//----------------------
+// Base Class Headers --
+//----------------------
+#include "specresp.h"
+#include "objfio.h"
+
+//------------------------------------
+// Collaborating Class Declarations --
+//------------------------------------
+
+//              ---------------------
+//              -- Class Interface --
+//              ---------------------
+
+// Spectral response in the form  A Exp(-((nu-nu0)/s)^2) 
+
+namespace SOPHYA {
+
+class GaussianFilter:public SpectralResponse
+{
+public:
+  //Constructors
+  GaussianFilter ();
+  GaussianFilter (double nu0, double s, double a=1., double numin=0., double numax= 9.e49); 
+  
+
+  // destructor
+  virtual ~GaussianFilter();
+
+  //
+  //  Function members
+  //
+
+  virtual double transmission(double) const;
+  virtual double peakFreq() const;
+  virtual double peakTransmission() const;
+
+  virtual void   Print(ostream& os)  const;
+
+  virtual inline double giveNorm() const {return _a;};
+  virtual inline double giveNu0() const {return _nu0;};
+  virtual inline double giveDNu() const {return _s;};
+  virtual void setParams(double nu0, double s, double a=1.);
+  
+protected:
+  double _a, _s, _nu0;
+};
+
+
+  // ObjFileIO<SpecRespVec> pour les PPersist 
+  inline POutPersist& operator << (POutPersist& os, GaussianFilter & obj)
+    { ObjFileIO<GaussianFilter> fio(&obj); fio.Write(os); return(os);}
+  
+  inline PInPersist& operator >> (PInPersist& os, GaussianFilter & obj)
+    { ObjFileIO<GaussianFilter> fio(&obj); fio.Read(os); return(os);}
+
+}  // End of namespace 
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyT/nupower.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyT/nupower.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyT/nupower.cc	(revision 2309)
@@ -0,0 +1,102 @@
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: nupower.cc,v 1.7 2000-04-14 07:28:12 ansari Exp $
+//
+// Description:
+//      Aim of the class: To give the energy density for a nupower
+//                        The unity used here is W/m^2/Hz/sr
+//
+// History (add to end):
+//      Sophie   Oct, 1999  - creation
+//
+//------------------------------------------------------------------------
+
+//---------------
+// C++ Headers --
+//---------------
+#include "machdefs.h"
+#include <iostream.h>
+#include <math.h>
+
+#include "nupower.h"
+
+
+/*! 
+ * \class SOPHYA::PowerLawSpectra 
+ \ingroup SkyT
+ * This class corresponds to a power law radiation spectrum.
+*/
+PowerLawSpectra::PowerLawSpectra()
+{
+}
+/*! Constructor: The arguments corresponds to the Power Law Spectrum
+  equation:
+<a name="psldef"> </a>
+\f[
+\hbox{flux}(\nu) = A ({\nu-\nu_0\over \delta\nu})^B
+\f]
+*/
+PowerLawSpectra::PowerLawSpectra(double A, double B, double nu0, double dnu, double numin, double numax)
+  : RadSpectra(numin, numax)
+{
+  _a = A;
+  _b = B;
+  _nu0 = nu0;
+  _dnu = (dnu > 1.e-19) ? dnu : 1.;
+}
+
+
+PowerLawSpectra::~PowerLawSpectra()
+{
+}
+/*! Flux function according to the <a href="#psldef"> above </a>
+ equation */
+double
+PowerLawSpectra::flux(double nu) const
+{
+  if ((nu< _numin) || (nu > _numax)) return(0.);
+  double tmp = (nu-_nu0)/_dnu;
+  if (tmp <= 0.)  return(0.); 
+  else return(  _a * pow(tmp, _b) );
+}
+
+
+
+void
+PowerLawSpectra::Print(ostream& os) const
+{
+  os << "PowerLawSpectra::Print f = a ((nu-nu0)/dnu)^b " << _a << "((nu-" << _nu0 
+     << ") / " << _dnu << ") ^ " << _b << endl;
+  os << " - Fmin,Fmax= " << minFreq() << "," << maxFreq() << endl;
+  os << "MeanFreq= " << meanFreq() << "  Emission= " << flux(meanFreq()) << endl;
+  os << "PeakFreq= " << peakFreq() << "  Emission= " << flux(peakFreq()) << endl;
+
+}
+
+
+/*
+void 
+PowerLawSpectra::WriteSelf(POutPersist& s)  
+{
+  s.PutR8(this->giveNorm());
+  s.PutR8(this->giveNu0());
+  s.PutR8(this->giveDNu());
+  s.PutR8(this->giveExp());
+  s.PutR8(this->minFreq());
+  s.PutR8(this->maxFreq());
+}
+
+void
+PowerLawSpectra::ReadSelf(PInPersist& s)  
+{
+  s.GetR8(_a);
+  s.GetR8(_nu0);
+  s.GetR8(_dnu);
+  s.GetR8(_b);
+  s.GetR8(_numin);
+  s.GetR8(_numax);
+  cout << " Norm - Nu0 - DNu - Exp - minFreq - maxFreq " << endl; 
+  cout << _a << "-" << _nu0  << "-" << _dnu << "-" << _b << "-" << _numin << "-" << _numax << endl;
+}
+
+*/
Index: /tags/V_Dec2002/SophyaLib/SkyT/nupower.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyT/nupower.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyT/nupower.h	(revision 2309)
@@ -0,0 +1,50 @@
+// This may look like C code, but it is really -*- C++ -*-
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: nupower.h,v 1.7 2000-04-13 08:20:00 ansari Exp $
+//
+// Description:
+//
+// History (add to end):
+//      Sophie   Oct, 1999  - creation
+//
+//------------------------------------------------------------------------
+
+#ifndef NUPOWER_H_SEEN
+#define NUPOWER_H_SEEN
+
+#include "radspec.h"
+#include "convtools.h"
+namespace SOPHYA {
+// Power law spectra  f = a ((nu-nu0)/dnu)^b   
+class PowerLawSpectra : public RadSpectra
+{
+public:   //Constructor
+  
+  PowerLawSpectra();
+  PowerLawSpectra(double a, double b, double nu0, double dnu, double numin=0., double numax=9.e49);
+
+  virtual ~PowerLawSpectra();
+
+  virtual double flux(double nu) const;
+
+  // Redefintion of the Print function
+  virtual void      Print(ostream& os)  const;
+
+  virtual inline double giveNorm() const {return _a;};
+  virtual inline double giveNu0() const {return _nu0;};
+  virtual inline double giveDNu() const {return _dnu;};
+  virtual inline double giveExp() const {return _b;};
+  
+  virtual inline void setNorm(double a) {_a=a;};
+  virtual inline void setNu0(double nu0) {_nu0=nu0;};
+  virtual inline void setDNu(double dnu) {_dnu=dnu;};
+  virtual inline void setExp(double b) {_b=b;};
+  
+  
+
+protected:
+  double _a, _b, _nu0, _dnu;
+};
+}
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyT/objlist.list
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyT/objlist.list	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyT/objlist.list	(revision 2309)
@@ -0,0 +1,12 @@
+blackbody.o
+convtools.o
+derivblackbody.o
+gaussfilt.o
+nupower.o
+radspec.o
+radspecvector.o
+skyinit.o
+specresp.o
+specrespvector.o
+squarefilt.o
+trianglefilt.o
Index: /tags/V_Dec2002/SophyaLib/SkyT/radspec.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyT/radspec.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyT/radspec.cc	(revision 2309)
@@ -0,0 +1,308 @@
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: radspec.cc,v 1.6 2002-07-31 10:25:34 ansari Exp $
+//
+// Description:
+//      Aim of the class: To give the energy density
+//                        The unity used here is W/m^2/Hz/sr
+//
+// History (add to end):
+//      Sophie   Oct, 1999  - creation
+//
+//------------------------------------------------------------------------
+
+//---------------
+// C++ Headers --
+//---------------
+#include "machdefs.h"
+#include <iostream.h>
+#include <typeinfo>
+#include <math.h>
+
+#include "radspec.h"
+#include "integ.h"
+/*!
+   \defgroup SkyT SkyT module
+   This module contains classes and functions which define 
+   several radiation spectra and filter responses
+*/
+
+/*! 
+ * \class SOPHYA::RadSpectra
+ * \ingroup SkyT
+ * This class is an abstract base class for radiation emission spectra. The flux() function returns the value of the flux (the spectral      <BR>
+ * energy distribution) as a function of the frequency.  As in the SpectralResponse class, the () operator has been redefined <BR>
+ * at this level, so that the user can access the flux value, either by  calling the function or directly by using this operator. <BR>
+ * For all the sub-classes, \nu is given in units of Hz and
+ * the flux is returned in units of W/m^2/sr/Hz.
+*/
+
+
+//----------------
+// Constructor --
+//----------------
+/*! Default constructor */
+/*!
+  The constructor takes as an argument the minimum
+  and the maximum frequency of the spectrum, if any. <BR>
+  In the case the user does not want to specify these
+  values, there are set respectively to 0. and 9.E49
+  by default.
+*/
+RadSpectra::RadSpectra(double numin, double numax)
+{
+  _numin = numin;
+  _numax = numax;
+}
+
+
+//--------------
+// Destructor --
+//--------------
+RadSpectra::~RadSpectra()
+{
+}
+
+//              ---------------------------
+//              --  Function Definitions --
+//              ---------------------------
+
+double 
+RadSpectra::minFreq()  const
+{
+  return _numin;
+}
+
+double 
+RadSpectra::maxFreq()  const
+{
+  return _numax;
+}
+
+double 
+RadSpectra::meanFreq()  const
+{
+  double result = (_numax+_numin)/2.;
+  return result;
+}
+
+
+/* 
+   The peakFreq() function returns the value of the 
+   frequency for the maximum value of the flux
+*/
+double 
+RadSpectra::peakFreq()  const
+{
+  double maxAnswer = -1.e99;
+  double maxNu = -10;
+  double nu;
+  for (int i=1; i<1000;i++)
+    {
+      nu=(_numax-_numin)*i/1000.+_numin;
+      double lookForMax = flux(nu);
+      if(maxAnswer <= lookForMax) {
+	maxAnswer= lookForMax;
+	maxNu    = nu;
+      }
+    }
+  return maxNu;  
+}
+
+void
+RadSpectra::setMinMaxFreq(double numin, double numax)
+{
+  _numin = numin;
+  _numax = numax;
+}
+
+// the RadSpectra_fluxFunction function is used to call TrpzInteg double(double) 
+// (integration over a range of frequencies)
+static RadSpectra* _raypourfinteg = NULL;
+static double RadSpectra_fluxFunction(double nu)
+{
+   return(_raypourfinteg->flux(nu));   
+}
+/*! 
+  The integratedFlux() function performs the integration
+  of the flux function in a frequency range <BR> defined by
+  f1 and f2.
+*/
+double 
+RadSpectra::integratedFlux(double f1, double f2)  const
+{
+  if(f1 < this->minFreq()) f1 = this->minFreq();
+  if(f2 > this->maxFreq()) f2 = this->maxFreq();
+  _raypourfinteg = const_cast<RadSpectra *>(this);
+  TrpzInteg I(RadSpectra_fluxFunction , f1, f2);  
+  double val = (double)I;
+  _raypourfinteg = NULL;  // On ne peut pas faire ca avant la destruction de I
+  return(val);        
+}
+
+/*!
+  Same than integratedFlux() over the frequency range 
+  of definition of the flux function
+ */
+double 
+RadSpectra::integratedFlux()  const
+{
+  return integratedFlux(this->minFreq(),this->maxFreq());
+}
+
+// integration using the logarithm !!
+// Carefull!! Base 10....
+static RadSpectra* _rayIntLog = NULL;
+
+static double RadSpectra_logFluxFunction(double tau)
+{
+  double value = _rayIntLog->flux(pow(10.,tau))*pow(10.,tau);
+  return(value);   
+}
+
+/*! 
+  The logIntegratedFlux() function performs the integration
+  of the flux function in a frequency range <BR> defined by
+  f1 and f2. The integration is here performed
+  on the logarithm of the flux function. 
+*/
+double 
+RadSpectra::logIntegratedFlux(double f1, double f2)  const
+{
+  if(f1 < this->minFreq()) f1 = this->minFreq();
+  if(f2 > this->maxFreq()) f2 = this->maxFreq();
+
+  double f1Log = log10(f1);
+  double f2Log = log10(f2);
+  if(f1Log < -1.e99) f1Log = -1.e99;
+  if(f2Log > 1.e99)  f2Log = 1.e99;
+  _rayIntLog = const_cast<RadSpectra *>(this);
+  TrpzInteg I(RadSpectra_logFluxFunction,f1Log,f2Log);
+  double value = (double)I * log(10.);
+  _rayIntLog = NULL;
+  return(value);        
+}
+
+/*!
+  same than logIntegratedFlux over the frequency range
+  of definition of the flux function
+ */
+double 
+RadSpectra::logIntegratedFlux()  const
+{
+  return logIntegratedFlux(_numin,_numax);
+}
+
+// the RadSpectra_filteredFlux function is used to call TrpzInteg double(double) 
+// (integration over a range of frequencies with a filter)
+static SpectralResponse* _filter = NULL ;
+static double RadSpectra_filteredFlux(double nu) 
+{
+  double flux = _raypourfinteg->flux(nu);
+  return(flux * _filter->transmission(nu));
+}
+
+/*! 
+  The filteredIntegratedFlux() function performs the integration
+  of the flux function in a frequency range <BR> defined by
+  f1 and f2 convolved by a SpectralResponse filter.
+*/
+double 
+RadSpectra::filteredIntegratedFlux(SpectralResponse const& filter, double f1, double f2) const
+{
+  _raypourfinteg = const_cast<RadSpectra *>(this);
+  _filter = const_cast<SpectralResponse *>(&filter);
+   if(f1 < this->minFreq()) f1 = this->minFreq();
+   if(f2 > this->maxFreq()) f2 = this->maxFreq();
+
+  TrpzInteg I(RadSpectra_filteredFlux,f1,f2);
+  double val = (double)I;
+  _raypourfinteg = NULL;
+  _filter = NULL;
+  return(val);        
+}
+
+/*!
+  Same than filteredIntegratedFlux() over the frequency range
+  defined as: <BR>
+   min_freq = MAX(minfreq_flux, minfreq_filter), <BR>
+   max_freq = MIN(maxfreq_flux, maxfreq_filter), <BR>
+  where:
+<UL>  
+<LI>   minfreq_flux   is the minimum frequency of the flux definition
+<LI>   maxfreq_flux   is the maximum frequency of the flux definition
+<LI>   minfreq_filter is the minimum frequency of the filter definition
+<LI>   maxfreq_filter is the maximum frequency of the filter definition
+  </UL>
+ */
+double 
+RadSpectra::filteredIntegratedFlux(SpectralResponse const& filter)
+{
+  double minOfMin = filter.minFreq();
+  double maxOfMax = filter.maxFreq();
+  if(minOfMin < this->minFreq()) minOfMin = this->minFreq();
+  if(maxOfMax > this->maxFreq()) maxOfMax = this->maxFreq();  
+  return(filteredIntegratedFlux(filter, minOfMin, maxOfMax ) );
+}
+
+
+// the RadSpectraVec_filteredFlux function is used to call TrpzInteg double(double) 
+// (integration over a range of frequencies with a filter)
+static double RadSpectra_logFilteredFlux(double tau) 
+{
+  double nu = pow(10.,tau);
+  double flux = _raypourfinteg->flux(nu)*nu;
+  double result = flux * _filter->transmission(nu);
+  return(result);
+}
+
+
+/*! 
+ *  The filteredIntegratedFlux() function performs the integration
+ * of the flux function in a frequency range <BR> defined by
+ * f1 and f2 convolved by a SpectralResponse filter (using the
+ * logarithm of the function).
+ */
+double 
+RadSpectra::filteredLogIntFlux(SpectralResponse const& filter, double f1, double f2) const
+{
+  
+   _raypourfinteg = NULL;
+   _filter = NULL;
+   if(f1 < this->minFreq()) f1 = this->minFreq();
+   if(f2 > this->maxFreq()) f2 = this->maxFreq();
+   
+   double f1Log = log10(f1);
+   double f2Log = log10(f2);
+   if(f1Log < -1.e99) f1Log = -1.e99;
+   if(f2Log > 1.e99)  f2Log = 1.e99;
+   _raypourfinteg = const_cast<RadSpectra *>(this);
+   _filter = const_cast<SpectralResponse *>(&filter);
+   TrpzInteg I(RadSpectra_logFilteredFlux,f1Log,f2Log);  
+   double val = (double)I;
+   _raypourfinteg = NULL;
+   _filter = NULL;
+   return(val* log(10.));        
+}
+
+double 
+RadSpectra::filteredLogIntFlux(SpectralResponse const& filter)
+{
+  return(filteredLogIntFlux(filter, filter.minFreq(), filter.maxFreq() ) );
+}
+
+
+
+
+void
+RadSpectra::Print(ostream& os) const
+{
+  //  os << "RadSpectra::Print (" << typeid(*this).name() 
+  //     << ") - Fmin,Fmax= " << minFreq() << "," << maxFreq() << endl;
+  os << "RadSpectra::Print  - Fmin,Fmax= " << minFreq() << "," << maxFreq() << endl;
+  os << "MeanFreq= " << meanFreq() << "  Emission= " << flux(meanFreq()) << endl;
+  os << "PeakFreq= " << peakFreq() << "  Emission= " << flux(peakFreq()) << endl;
+
+}
+
+
Index: /tags/V_Dec2002/SophyaLib/SkyT/radspec.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyT/radspec.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyT/radspec.h	(revision 2309)
@@ -0,0 +1,89 @@
+// This may look like C code, but it is really -*- C++ -*-
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: radspec.h,v 1.5 2000-04-13 08:17:03 ansari Exp $
+//
+// Description:
+//
+// History (add to end):
+//      Sophie   Oct, 1999  - creation
+//
+//------------------------------------------------------------------------
+
+#ifndef RADSPEC_H_SEEN
+#define RADSPEC_H_SEEN
+
+#include "machdefs.h"
+#include <iostream.h>
+
+#include "specresp.h"
+#include "objfio.h"
+//              ---------------------
+//              -- Class Interface --
+//              ---------------------
+
+// ***IMPORTANT*** All frequencies are expressed in GHz  (10^9 Hz)
+//                 and flux in Watt/m^2/sr
+namespace SOPHYA {
+class RadSpectra
+{
+
+public:
+  //Constructor
+  RadSpectra (double numin=0., double numax=9.e49);
+
+  // destructor
+  virtual ~RadSpectra();
+
+  //
+  //  Member Functions
+  //
+
+  //  The flux() function is virtual: 
+  //  It computes the flux per units of W/m^2/Hz/st
+  // implemented in the subclasses
+  virtual double flux(double nu) const =0;
+  inline double operator() (double nu) const { return(flux(nu)); }
+
+  virtual double minFreq() const;
+  virtual double maxFreq() const;
+  virtual double meanFreq() const;
+  virtual double peakFreq() const;
+
+  // For changing the min/max frequency
+  virtual void	 setMinMaxFreq(double numin, double numax);
+
+  // The IntegratedFlux() function
+  // integrates the flux function between two frequencies: 
+  // numin and numax (in GHz)
+  virtual double integratedFlux( double numin, double numax) const ;
+  virtual double logIntegratedFlux( double numin, double numax) const ;
+
+  // same but integrated over the full spectrum of frequencies
+  virtual  double integratedFlux() const ;
+  virtual  double logIntegratedFlux() const ;
+  
+  // filteredIntegratedFlux integrates the flux function while
+  // taking into account the spectralResponse of a filter
+  virtual double filteredIntegratedFlux(SpectralResponse const & filter, 
+					double numin, double numax) const ;
+  virtual double filteredLogIntFlux(SpectralResponse const & filter, 
+					double numin, double numax) const ;
+
+  // same but integrates over the filter's frequency band
+  virtual double filteredIntegratedFlux(SpectralResponse const & filter);
+  virtual double filteredLogIntFlux(SpectralResponse const & filter);
+
+  virtual void      Print(ostream& os)  const;
+
+protected:
+  double _numin;
+  double _numax;
+};
+
+// Definition de l'operateur <<
+inline ostream& operator << (ostream& s,  RadSpectra const & rs)
+  {  rs.Print(s);  return(s);  }
+}
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyT/radspecvector.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyT/radspecvector.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyT/radspecvector.cc	(revision 2309)
@@ -0,0 +1,146 @@
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: radspecvector.cc,v 1.7 2000-04-14 07:28:13 ansari Exp $
+//
+// Description:
+//      Aim of the class: To give the energy density
+//                        The unity used here is W/m^2/Hz/sr
+//
+// History (add to end):
+//      Sophie   Oct, 1999  - creation
+//
+//------------------------------------------------------------------------
+
+//---------------
+// C++ Headers --
+//---------------
+#include "machdefs.h"
+#include <iostream.h>
+#include <math.h>
+// #include <typeinfo>
+
+#include "radspecvector.h"
+#include "pexceptions.h"
+
+//----------------
+// Constructor --
+//----------------
+
+/*! 
+ * \class SOPHYA::RadSpectraVec 
+ \ingroup SkyT
+ * One may define the radiation
+ * spectrum with two vectors: <BR> one for the frequencies and the second for the
+ * value of the flux function. <BR>
+ * In that case, the class to use is RadSpectraVec !
+ */
+
+RadSpectraVec::RadSpectraVec()
+{
+}
+/*! Constructor:
+  \param nu is the frequency vector <BR>
+  \param fdenu is the corresponding flux values (stored in a vector as well)
+ */
+RadSpectraVec::RadSpectraVec(Vector const & nu, Vector const & fdenu, double numin, double numax)
+        : RadSpectra(numin, numax)
+{
+  if(nu.NElts() != fdenu.NElts())  
+    throw SzMismatchError("RadSpectraVec::RadSpectraVec() - Non equal vector sizes");
+  _vecOfNu = nu;
+  _vecOfFDeNu = fdenu;
+  _numin = nu(0);
+  _numax = nu(nu.NElts()-1);
+}
+
+
+//--------------
+// Destructor --
+//--------------
+RadSpectraVec::~RadSpectraVec()
+{
+}
+
+//              ---------------------------
+//              --  Function Definitions --
+//              ---------------------------
+
+
+
+/*! The flux function extrapolates the flux values for the 
+  frequencies that are not present in the nu vector <BR>
+  given at the instanciation of the class.
+ */
+double 
+RadSpectraVec::flux(double nu) const
+{
+  if ( (nu < _numin) || (nu > _numax) ) return(0.);
+  double value = 0.;
+  int sizeVecOfNu = _vecOfNu.NElts();
+  if(nu <=  _vecOfNu(0)) return _vecOfFDeNu(0);
+  if(nu >=  _vecOfNu(sizeVecOfNu-1)) return _vecOfFDeNu(sizeVecOfNu-1);
+  
+  for (int i=1; i<sizeVecOfNu; i++)
+    {
+      if(nu < _vecOfNu(i))
+	{
+	  double up = _vecOfFDeNu(i) ;
+	  double down = _vecOfFDeNu(i-1);
+	  double xmin = _vecOfNu(i-1);
+	  double xmax = _vecOfNu(i);
+	  double a = ((up-down)/(xmax-xmin));
+	  value = a*nu+(up-a*xmax);
+	  return value;
+	}
+    }
+  return _vecOfFDeNu(sizeVecOfNu-1);
+}
+
+
+
+void
+RadSpectraVec::Print(ostream& os) const
+{
+  //  os << "RadSpectraVec::Print (" << typeid(*this).name() 
+  //     << ") - Fmin,Fmax= " << minFreq() << "," << maxFreq() << endl;
+  os << "RadSpectraVec::Print  - Fmin,Fmax= " << minFreq() << "," << maxFreq() << endl;
+  os << "MeanFreq= " << meanFreq() << "  Emission= " << flux(meanFreq()) << endl;
+  os << "PeakFreq= " << peakFreq() << "  Emission= " << flux(peakFreq()) << endl;
+
+}
+
+/*
+void
+RadSpectraVec::WriteSelf(POutPersist& s) 
+{
+  s.PutI4(this->NbElts());
+  for (int i=0; i< this->NbElts(); i++)
+    {
+      s.PutR8(this->getNuVec(i));
+      s.PutR8(this->getFNuVec(i));
+    }
+  s.PutR8(this->minFreq());
+  s.PutR8(this->maxFreq());
+ 
+}
+
+void
+RadSpectraVec::ReadSelf(PInPersist& s) 
+{
+  s.GetI4(_size);
+
+  _vecOfNu.ReSize(_size);
+  _vecOfFDeNu.ReSize(_size);
+  for (int i=0; i< _size; i++)
+    {
+      s.GetR8(_vecOfNu(i));
+      s.GetR8(_vecOfFDeNu(i));
+    } 
+  s.GetR8(_numin);
+  s.GetR8(_numax);
+  cout << "minFreq - maxFreq"<< endl; 
+  cout <<    _numin<< "-" <<  _numax << endl;
+}
+*/
+
+
Index: /tags/V_Dec2002/SophyaLib/SkyT/radspecvector.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyT/radspecvector.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyT/radspecvector.h	(revision 2309)
@@ -0,0 +1,60 @@
+// This may look like C code, but it is really -*- C++ -*-
+//--------------------------------------------------------------------------
+// File and Version Information:
+//
+// Description:
+//
+// History (add to end):
+//      Sophie   Oct, 1999  - creation
+//
+//------------------------------------------------------------------------
+
+#ifndef RADSPECTRAVEC_H_SEEN
+#define RADSPECTRAVEC_H_SEEN
+#include "machdefs.h"
+#include <iostream.h>
+
+#include "radspec.h"
+#include "tvector.h"
+
+//              ---------------------
+//              -- Class Interface --
+//              ---------------------
+
+// ***IMPORTANT*** All frequencies are expressed in GHz  (10^9 Hz)
+//                 and flux in Watt/m^2/sr
+namespace SOPHYA {
+class RadSpectraVec : public RadSpectra
+{
+
+public:
+  //Constructor
+  RadSpectraVec ();
+  RadSpectraVec (Vector const & nu, Vector const & fdenu, double numin=0., double numax=9.e49);
+
+  // destructor
+  virtual ~RadSpectraVec();
+
+  //
+  //  Member Functions
+  //
+
+  //  The flux() function is virtual: 
+  //  It computes the flux per units of W/m^2/Hz/st
+  // implemented in the subclasses
+  virtual double flux(double nu) const;
+
+  // Acces to Nu and F(nu) vectors 
+  inline Vector& getNuVec() { return _vecOfNu; }
+  inline Vector& getFNuVec() { return _vecOfFDeNu; }
+  inline double getNuVec(int i) const { return _vecOfNu(i); }
+  inline double getFNuVec(int i) const { return _vecOfFDeNu(i); }
+
+  virtual void   Print(ostream& os)  const;
+
+protected:
+  Vector _vecOfNu;
+  Vector _vecOfFDeNu;
+};
+}
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyT/skyinit.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyT/skyinit.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyT/skyinit.cc	(revision 2309)
@@ -0,0 +1,37 @@
+// Classe d'initialisation du module Outils++ 
+#include <unistd.h>
+
+#include "skyinit.h"
+#include "ppersist.h"
+#include "objfio.h"
+#include "specrespvector.h"
+#include "gaussfilt.h"
+
+/*! \class SOPHYA::SkyTInitiator
+ *  \ingroup SkyT
+ */
+int SkyTInitiator::FgInit = 0;
+
+SkyTInitiator::SkyTInitiator()
+  : NToolsInitiator()
+{
+  SkyTInitiator::FgInit++;
+  if (SkyTInitiator::FgInit > 1)  return;
+
+//   Enregistrement des classes PPersist du modules SkyT
+  
+  PPRegister(ObjFileIO<SpecRespVec>);
+  PPRegister(ObjFileIO<GaussianFilter>);
+
+}
+
+SkyTInitiator::~SkyTInitiator()
+{
+  SkyTInitiator::FgInit--;
+}
+
+
+// On met un objet initiator en statique, pour les loaders qui savent 
+// appeler le constructeur des objets statiques   Reza 08/98
+static SkyTInitiator s_skytinit_;
+
Index: /tags/V_Dec2002/SophyaLib/SkyT/skyinit.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyT/skyinit.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyT/skyinit.h	(revision 2309)
@@ -0,0 +1,27 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe d'initialiseur du module Outils++
+
+#ifndef SKYTINIT_H_SEEN
+#define SKYTINIT_H_SEEN
+
+
+// Classe d''initialisation pour les modules de PEIDA++
+#include "ntoolsinit.h"
+
+namespace SOPHYA {  
+
+class SkyTInitiator : public NToolsInitiator {
+private:
+  static int FgInit;
+public:
+  			SkyTInitiator();
+  virtual		~SkyTInitiator();
+};
+
+#undef PeidaInit
+#define PeidaInit() SkyTInitiator _skytinitiator_
+
+} // namespace SOPHYA
+
+#endif
+
Index: /tags/V_Dec2002/SophyaLib/SkyT/skyt.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyT/skyt.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyT/skyt.h	(revision 2309)
@@ -0,0 +1,20 @@
+// This may look like C code, but it is really -*- C++ -*-
+// All include files for module SkyT
+
+#ifndef SKYT_H_SEEN
+#define SKYT_H_SEEN
+
+#include "convtools.h"
+#include "radspecvector.h"
+#include "radspec.h"
+#include "blackbody.h"
+#include "derivblackbody.h"
+#include "nupower.h"
+
+#include "specresp.h"
+#include "specrespvector.h"
+#include "squarefilt.h"
+#include "trianglefilt.h"
+#include "gaussfilt.h"
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyT/specresp.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyT/specresp.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyT/specresp.cc	(revision 2309)
@@ -0,0 +1,204 @@
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: specresp.cc,v 1.6 2002-07-31 10:25:34 ansari Exp $
+//
+// Description:
+//      Aim of the class: To give the energy density
+//                        The unity used here is W/m^2/Hz/sr
+//
+// History (add to end):
+//      Sophie   Oct, 1999  - creation
+//
+//------------------------------------------------------------------------
+
+//---------------
+// C++ Headers --
+//---------------
+#include <typeinfo>
+#include <math.h>
+#include "specresp.h"
+#include "integ.h"
+#include "tvector.h"
+
+/*! 
+ * \class SOPHYA::SpectralResponse 
+ \ingroup SkyT
+ SpectralResponse corresponds to a detector filter's
+ response as a function of the frequency.
+ The SpectralResponse class is an abstract class.
+ The virtual constructor takes as arguments the
+ minimum and maximum values of the frequency range on
+ which the detector response is defined
+ */
+//----------------
+// Constructor --
+//----------------
+SpectralResponse::SpectralResponse(double numin, double numax)
+{
+  _numin = numin;
+  _numax = numax;
+}
+
+
+//--------------
+// Destructor --
+//--------------
+SpectralResponse::~SpectralResponse()
+{
+}
+
+//              ---------------------------
+//              --  Function Definitions --
+//              ---------------------------
+
+
+double 
+SpectralResponse::minFreq()  const 
+{
+  return _numin;
+}
+
+double 
+SpectralResponse::maxFreq()  const
+{
+  return _numax;
+}
+
+double 
+SpectralResponse::meanFreq()  const
+{
+  return (_numax+_numin)/2.;
+}
+
+ 
+// To change min-max frequency
+void
+SpectralResponse::setMinMaxFreq(double numin, double numax)
+{
+  _numin = numin;
+  _numax = numax;
+}
+ 
+
+// peakFreq returns the value of the frequency for the
+// peak of the spectrum. 
+double 
+SpectralResponse::peakFreq()  const
+{
+  double maxAnswer = -1.e99;
+  double maxNu = -10;
+  double nu;
+  for (int i=1; i<1000;i++)
+    {
+      nu=(_numax-_numin)*i/1000.+_numin;
+      double lookForMax =transmission(nu);
+      if(maxAnswer <= lookForMax) {
+	maxAnswer= lookForMax;
+	maxNu    = nu;
+      }
+    }
+  return maxNu;    
+}
+
+
+double 
+SpectralResponse::peakTransmission()  const
+{
+  double nuPeak = this->peakFreq();
+  return transmission(nuPeak);
+}
+
+static SpectralResponse* _mySpecResp = NULL;
+
+static double SpectralResponse_transmission(double nu)
+{
+   return(_mySpecResp->transmission(nu));   
+}
+
+
+/*! 
+  This function performs the integration
+  of the transmission function in its frequency range 
+  (defined when instanciating an object of on of the
+  subclasses)
+*/
+double 
+SpectralResponse::IntegratedSpect()  const
+{
+  double value = this->IntegratedSpect(_numin, _numax);
+  return value;
+}
+
+/*! 
+  The IntegratedSpect function performs the integration
+  of the transmission function in a frequency range <BR> defined by
+  numin and numax.
+*/
+double 
+SpectralResponse::IntegratedSpect(double numin, double numax) const 
+{
+  if(numin < this->minFreq()) numin = this->minFreq();
+  if(numax > this->maxFreq()) numax = this->maxFreq();
+
+  
+  _mySpecResp = const_cast<SpectralResponse *>(this);
+  TrpzInteg I(SpectralResponse_transmission , numin, numax);  
+  double val = (double)I;
+  _mySpecResp= NULL;
+  return(val);
+}
+
+
+static SpectralResponse* _myLogSpecResp = NULL;
+
+static double SpectralResponse_logTransmission(double tau)
+{
+  double value =  _myLogSpecResp->transmission(pow(10.,tau))*pow(10.,tau);
+  return(value);   
+}
+
+/*! 
+  The logIntegratedSpect function performs the integration
+  of the logarithm of the transmission function in a frequency range <BR> defined by
+  numin and numax.
+*/
+double 
+SpectralResponse::logIntegratedSpect(double numin, double numax) const 
+{
+  if(numin <= this->minFreq()) numin = this->minFreq();
+  if(numax >= this->maxFreq()) numax = this->maxFreq();
+  if(numin == 0) numin = 1.e-99;
+  double f1Log = log10(numin);
+  double f2Log = log10(numax);
+  if(f1Log < -1.e99) f1Log = -1.e99;
+  if(f2Log > 1.e99)  f2Log = 1.e99;
+  _myLogSpecResp = const_cast<SpectralResponse *>(this); 
+  TrpzInteg I(SpectralResponse_logTransmission ,f1Log,f2Log); 
+  double val = (double)I;
+  _myLogSpecResp= NULL;
+  return(val*log(10.));
+}
+
+/*! 
+  Same than IntegratedSpect(numin,numax) over its
+  frequency range defined at the initialisation
+*/
+double 
+SpectralResponse::logIntegratedSpect()  const
+{
+  double value = this->logIntegratedSpect(_numin, _numax);
+  return value;
+}
+
+
+void
+SpectralResponse::Print(ostream& os) const 
+{
+
+  //   os << "SpectralResponse::Print (" << typeid(*this).name() 
+  //<< ") - Fmin,Fmax= " << minFreq() << "," << maxFreq() << endl;
+  os << "SpectralResponse::Print - Fmin,Fmax= " << minFreq() << "," << maxFreq() << endl;
+  os << "MeanFreq= " << meanFreq() << "  Transmission= " << transmission(meanFreq()) << endl;
+  os << "PeakFreq= " << peakFreq() << "  Transmission= " << transmission(peakFreq()) << endl;
+
+}
Index: /tags/V_Dec2002/SophyaLib/SkyT/specresp.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyT/specresp.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyT/specresp.h	(revision 2309)
@@ -0,0 +1,82 @@
+// This may look like C code, but it is really -*- C++ -*-
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: specresp.h,v 1.4 2000-04-06 17:10:51 ansari Exp $
+//
+// Description:
+//
+// History (add to end):
+//      Sophie   Oct, 1999  - creation
+//
+//------------------------------------------------------------------------
+#ifndef SPECRESP_H_SEEN
+#define SPECRESP_H_SEEN
+
+#include "machdefs.h"
+#include "anydataobj.h"
+#include <iostream.h>
+//------------------------------------
+// Collaborating Class Declarations --
+//------------------------------------
+
+//              ---------------------
+//              -- Class Interface --
+//              ---------------------
+
+// ***IMPORTANT*** All frequencies are expressed in GHz  (10^9 Hz)
+namespace SOPHYA {
+  
+  class SpectralResponse : public AnyDataObj
+  {
+    
+  public:
+    //Constructor
+    SpectralResponse(double numin=0., double numax=1.);
+    
+    // destructor
+    virtual ~SpectralResponse();
+    
+    //
+    //  Member Functions
+    //
+    
+    //  The transmission() function is virtual: 
+    virtual double transmission(double nu) const =0 ; 
+    
+    inline double operator() (double nu) const { return(transmission(nu)); }
+    
+    virtual void      Print(ostream& os)  const;
+    
+    virtual double minFreq() const;
+    virtual double maxFreq() const;
+    virtual double meanFreq() const;
+    virtual double peakFreq() const;
+    virtual double peakTransmission() const;
+
+    // For changing the min/max frequency
+    virtual void   setMinMaxFreq(double numin, double numax);
+
+    virtual double IntegratedSpect(double numin, double numax) const ;
+    virtual double logIntegratedSpect(double numin, double numax) const ;
+    virtual double IntegratedSpect() const ;
+    virtual double logIntegratedSpect() const ;
+    
+  protected:
+    double _numin;
+    double _numax;
+  };
+  
+  
+  // definition of the << operator
+  inline ostream& operator << (ostream& s,  SpectralResponse const & sr)
+    {  sr.Print(s);  return(s);  }
+  
+  
+  
+}
+
+#endif
+
+
+
+
Index: /tags/V_Dec2002/SophyaLib/SkyT/specrespvector.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyT/specrespvector.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyT/specrespvector.cc	(revision 2309)
@@ -0,0 +1,186 @@
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: specrespvector.cc,v 1.8 2000-04-14 07:28:14 ansari Exp $
+//
+// Description:
+//      Aim of the class: To give the energy density
+//                        The unity used here is W/m^2/Hz/sr
+//
+// History (add to end):
+//      Sophie   Oct, 1999  - creation
+//
+//------------------------------------------------------------------------
+
+//---------------
+// C++ Headers --
+//---------------
+#include "machdefs.h"
+#include <iostream.h>
+#include <math.h>
+// #include <typeinfo>
+
+#include "specrespvector.h"
+#include "pexceptions.h"
+#include "fioarr.h"
+//----------------
+// Constructor --
+//----------------
+/*! 
+ * \class SOPHYA::SpecRespVec
+ \ingroup SkyT
+ One may also want to defined the filter of a detector by two vectors:
+ one for the frequencies and one for the corresponding transmission values.
+ In this case on should use the SpecRespVec class !
+*/
+SpecRespVec::SpecRespVec()
+        : SpectralResponse()
+{
+}
+
+/*! Constructor: 
+  \param nu  vector of the frequencies
+  \param fdenu  vector of the corresponding transmission values of the filter
+*/
+SpecRespVec::SpecRespVec(Vector const & nu, Vector const & fdenu, double numin, double numax)
+        : SpectralResponse(numin, numax)
+{
+  if(nu.NElts() != fdenu.NElts())  
+    throw SzMismatchError("SpecRespVec::SpecRespVec() - Non equal vector sizes");
+  _vecOfNu = nu;
+  _vecOfFDeNu = fdenu;
+  _size = nu.NElts();
+  if(_vecOfNu.NElts() != _vecOfFDeNu.NElts()) cout << "vectors are not compatible" << exit;
+}
+
+SpecRespVec::SpecRespVec(Vector const & nu, Vector const & fdenu)
+        : SpectralResponse()
+{
+  if(nu.NElts() != fdenu.NElts())  
+    throw SzMismatchError("SpecRespVec::SpecRespVec() - Non equal vector sizes");
+  _vecOfNu = nu;
+  _vecOfFDeNu = fdenu;
+  _numin = nu(0);
+  _numax = nu(nu.NElts()-1);
+  _size = nu.NElts();
+  if(_vecOfNu.NElts() != _vecOfFDeNu.NElts()) cout << "vectors are not compatible" << exit;
+}
+
+
+//--------------
+// Destructor --
+//--------------
+SpecRespVec::~SpecRespVec()
+{
+}
+
+//              ---------------------------
+//              --  Function Definitions --
+//              ---------------------------
+
+
+
+/*! The transmission function extrapolates the transmission values for the 
+  frequencies that are not present in the nu vector <BR>
+  given at the instanciation of the class.
+*/
+double 
+SpecRespVec::transmission(double nu)  const 
+{
+  if ( (nu < _numin) || (nu > _numax) ) return(0.);
+  double value = 0.;
+  int sizeVecOfNu = _vecOfNu.NElts();
+  if(nu <=  _vecOfNu(0)) return _vecOfFDeNu(0);
+  if(nu >=  _vecOfNu(sizeVecOfNu-1)) return _vecOfFDeNu(sizeVecOfNu-1);
+
+  for (int i=1; i<sizeVecOfNu; i++)
+    {
+      if(nu < _vecOfNu(i))
+	{
+	  double up = _vecOfFDeNu(i) ;
+	  double down = _vecOfFDeNu(i-1);
+	  double xmin = _vecOfNu(i-1);
+	  double xmax = _vecOfNu(i);
+	  double a = ((up-down)/(xmax-xmin));
+	  value = a*nu+(up-a*xmax);
+	  return value;
+	}
+    }
+  return value;
+}
+
+
+
+void
+SpecRespVec::Print(ostream& os) const 
+{
+
+  //   os << "SpecRespVec::Print (" << typeid(*this).name() 
+  //<< ") - Fmin,Fmax= " << minFreq() << "," << maxFreq() << endl;
+  os << "SpecRespVec ::Print - Fmin,Fmax= " << minFreq() << "," << maxFreq() << endl;
+  os << "MeanFreq= " << meanFreq() << "  Transmission= " << transmission(meanFreq()) << endl;
+  os << "PeakFreq= " << peakFreq() << "  Transmission= " << transmission(peakFreq()) << endl;
+
+}
+
+
+void
+ObjFileIO<SpecRespVec>::WriteSelf(POutPersist& s) const
+{
+  if(dobj == NULL)
+    {
+      cout << " ObjFileIO<SpecRespVec>::WriteSelf:: dobj= null " << endl;
+      return;
+    }
+
+  int_4 version, nothing;
+  version = 1;
+  nothing = 0;   // Reserved for future use 
+  s.PutI4(version);
+  s.PutI4(nothing);
+
+  s.PutR8(dobj->minFreq());
+  s.PutR8(dobj->maxFreq());
+
+  // TVector<T> has Persistence Manager
+  s << dobj->getNuVec();
+  {
+  Vector& xv2 = dobj->getTNuVec();
+  cout << xv2 ;
+  FIO_TArray<double> vio2(&xv2);
+  vio2.Write(s);
+  }
+}
+
+void 
+ObjFileIO<SpecRespVec>::ReadSelf(PInPersist& s) 
+{
+  int_4 version, nothing;
+  version = 1;
+  nothing = 0;   // Reserved for future use 
+  s.GetI4(version);
+  s.GetI4(nothing);
+
+  if(dobj == NULL)
+    {
+    dobj= new SpecRespVec();
+    ownobj= true;
+    }
+  r_8 minf, maxf;
+  s.GetR8(minf);
+  s.GetR8(maxf);
+  dobj->setMinMaxFreq(minf, maxf);
+  // TVector<T> has Persistence Manager 
+  FIO_TArray<double> vio(&(dobj->getNuVec()));
+  vio.Read(s);
+  FIO_TArray<double> vio2(&(dobj->getTNuVec()));
+  vio2.Read(s);
+}
+
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template ObjFileIO<SpecRespVec>
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class ObjFileIO<SpecRespVec>;
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyT/specrespvector.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyT/specrespvector.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyT/specrespvector.h	(revision 2309)
@@ -0,0 +1,76 @@
+// This may look like C code, but it is really -*- C++ -*-
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: specrespvector.h,v 1.5 2000-04-06 17:11:03 ansari Exp $
+//
+// Description:
+//
+// History (add to end):
+//      Sophie   Oct, 1999  - creation
+//
+//------------------------------------------------------------------------
+#ifndef SPECRESPVEC_H_SEEN
+#define SPECRESPVEC_H_SEEN
+
+#include "machdefs.h"
+#include <iostream.h>
+
+#include "specresp.h"
+#include "tvector.h"
+#include "objfio.h"
+
+//------------------------------------
+// Collaborating Class Declarations --
+//------------------------------------
+
+//              ---------------------
+//              -- Class Interface --
+//              ---------------------
+
+// ***IMPORTANT*** All frequencies are expressed in GHz  (10^9 Hz)
+
+namespace SOPHYA {
+  
+  class SpecRespVec :  public SpectralResponse
+  {
+
+public:
+  //Constructor
+  SpecRespVec();
+  SpecRespVec(Vector const & nu, Vector const & fdenu, double numin, double numax);
+  SpecRespVec(Vector const & nu, Vector const & fdenu);
+
+  // destructor
+  virtual ~SpecRespVec();
+
+  //
+  //  Member Functions
+  //
+
+  //  The transmission() function is virtual: 
+  virtual double transmission(double nu) const; 
+
+  // Acces to Nu and T(nu) vectors 
+  inline Vector&  getNuVec()  { return _vecOfNu; } ;
+  inline Vector& getTNuVec()  { return _vecOfFDeNu; }
+  inline double getNuVec(int i) const { return _vecOfNu(i); }
+  inline double getTNuVec(int i) const { return _vecOfFDeNu(i); }
+  inline int NbElts() const { return _size;}
+  
+  virtual void      Print(ostream& os)  const;
+
+protected:
+  Vector _vecOfNu;
+  Vector _vecOfFDeNu;
+  int _size;
+};
+
+  // ObjFileIO<SpecRespVec> pour les PPersist 
+  inline POutPersist& operator << (POutPersist& os, SpecRespVec & obj)
+    { ObjFileIO<SpecRespVec> fio(&obj); fio.Write(os); return(os);}
+  
+  inline PInPersist& operator >> (PInPersist& os, SpecRespVec & obj)
+    { ObjFileIO<SpecRespVec> fio(&obj); fio.Read(os); return(os);}
+
+}  // End of namespace 
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyT/squarefilt.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyT/squarefilt.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyT/squarefilt.cc	(revision 2309)
@@ -0,0 +1,94 @@
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: squarefilt.cc,v 1.6 2000-04-14 07:28:14 ansari Exp $
+//
+// Description:
+//
+// History (add to end):
+//      Sophie   Oct, 1999  - creation
+//
+//------------------------------------------------------------------------
+
+//---------------
+// C++ Headers --
+//---------------
+#include "machdefs.h"
+#include <iostream.h>
+
+#include "squarefilt.h"
+
+/*! 
+ * \class SOPHYA::SquareFilter
+ \ingroup SkyT
+ * Square detector response
+ */
+
+//----------------
+// Constructor --
+//----------------
+SquareFilter::SquareFilter()
+  : SpectralResponse()
+{
+}
+
+SquareFilter::SquareFilter(double numin, double numax)
+  : SpectralResponse(numin, numax)
+{
+  _nuPeak = (numin+numax)/2.;
+  _peakTransmission = transmission(_nuPeak);
+}
+
+
+//--------------
+// Destructor --
+//--------------
+SquareFilter::~SquareFilter()
+{
+}
+
+//              ---------------------------
+//              --  Function Definitions --
+//              ---------------------------
+
+
+/*! The transmission returns 1. for frequencies in the [numin,numax] range
+  and 0. outside */ 
+double 
+SquareFilter::transmission(double nu) const
+{
+  if(nu < -1.e99) nu = -1.e99;
+  if(nu > 1.e99) nu = 1.e99;
+  
+  if(nu>=_numin && nu<=_numax) return 1.;
+  return 0.;
+}
+
+double 
+SquareFilter::peakFreq() const 
+{
+return _nuPeak;
+}
+
+double 
+SquareFilter::peakTransmission() const 
+{
+  return _peakTransmission;
+}
+
+/*
+void 
+SquareFilter::WriteSelf(POutPersist& s) 
+{
+  s.PutR8(this->minFreq());
+  s.PutR8(this->maxFreq());
+}
+
+void 
+SquareFilter::ReadSelf(PInPersist& s) 
+{
+  double minFreq, maxFreq;
+  s.GetR8(_numin);
+  s.GetR8(_numax);
+  cout << "minFreq - maxFreq " <<  _numin << "-" << _numax  << endl;
+}
+*/
Index: /tags/V_Dec2002/SophyaLib/SkyT/squarefilt.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyT/squarefilt.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyT/squarefilt.h	(revision 2309)
@@ -0,0 +1,56 @@
+// This may look like C code, but it is really -*- C++ -*-
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: squarefilt.h,v 1.5 2000-04-13 08:17:03 ansari Exp $
+//
+// Description:
+//
+// History (add to end):
+//      Sophie   Oct, 1999  - creation
+//
+//------------------------------------------------------------------------
+
+#ifndef SQUAREFIL_H_SEEN
+#define SQUAREFIL_H_SEEN
+
+//----------------------
+// Base Class Headers --
+//----------------------
+#include "specresp.h"
+
+//------------------------------------
+// Collaborating Class Declarations --
+//------------------------------------
+
+//              ---------------------
+//              -- Class Interface --
+//              ---------------------
+namespace SOPHYA {
+class SquareFilter:public SpectralResponse
+{
+
+public:
+  //Constructors
+  SquareFilter (); 
+  SquareFilter (double numin, double numax); 
+  
+
+  // destructor
+  virtual ~SquareFilter();
+
+  //
+  //  Function members
+  //
+
+  virtual double transmission(double) const;
+  virtual double peakFreq() const;
+  virtual double peakTransmission() const;
+  
+
+protected:
+  double _peakTransmission;
+  double _nuPeak;
+};
+
+}
+#endif
Index: /tags/V_Dec2002/SophyaLib/SkyT/trianglefilt.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyT/trianglefilt.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyT/trianglefilt.cc	(revision 2309)
@@ -0,0 +1,103 @@
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: trianglefilt.cc,v 1.6 2000-04-14 07:28:14 ansari Exp $
+//
+// Description:
+//
+// History (add to end):
+//      Sophie   Oct, 1999  - creation
+//
+//------------------------------------------------------------------------
+
+//---------------
+// C++ Headers --
+//---------------
+#include "machdefs.h"
+#include <iostream.h>
+
+#include "trianglefilt.h"
+
+//----------------
+// Constructor --
+//----------------
+/*! 
+ * \class SOPHYA::TriangleFilter
+ \ingroup SkyT
+ * triangle detector response
+ */
+TriangleFilter::TriangleFilter()
+   : SpectralResponse()
+{
+}
+/*! Constructor: nupeak is the frequency value at the hat of the triangle and
+  valueatpeak is the corresponding transmission value. */
+TriangleFilter::TriangleFilter(double numin, double numax,double nupeak, double valueatpeak)
+   : SpectralResponse(numin, numax)
+{
+  _nuPeak = nupeak ;
+  _peakTransmission = valueatpeak;
+}
+
+//--------------
+// Destructor --
+//--------------
+TriangleFilter::~TriangleFilter()
+{
+}
+
+//              ---------------------------
+//              --  Function Definitions --
+//              ---------------------------
+
+/*! The transmission function is a triangle defined in the constructor
+by numin and numax (for which the transmission goes to 0.) and
+the hat of the triangle (defined by a peak frequency and the corresponding
+transmission value. */
+double 
+TriangleFilter::transmission(double nu) const
+{
+  if(nu < -1.e99) nu = -1.e99;
+  if(nu > 1.e99) nu = 1.e99;
+  
+  if(nu>_numin && nu<_nuPeak) return (_peakTransmission*nu/_nuPeak);
+  if(nu>=_nuPeak && nu<_numax) return (_peakTransmission*nu/(_nuPeak-_numax)+_peakTransmission-_peakTransmission*_nuPeak/(_nuPeak-_numax));
+  return 0.;
+}
+
+double 
+TriangleFilter::peakFreq() const 
+{
+return _nuPeak;
+}
+
+double 
+TriangleFilter::peakTransmission() const 
+{
+  return _peakTransmission;
+}
+
+/*
+void
+TriangleFilter::WriteSelf(POutPersist& s) 
+{
+  s.PutR8(this->peakFreq());
+  s.PutR8(this->peakTransmission());
+  s.PutR8(this->minFreq());
+  s.PutR8(this->maxFreq());
+  
+}
+
+void
+TriangleFilter::ReadSelf(PInPersist& s)   
+{
+  //  double peakFreq, peakTransmission, minFreq,  maxFreq;
+  s.GetR8(_nuPeak);
+  s.GetR8(_peakTransmission);
+  s.GetR8(_numin);
+  s.GetR8(_numax);
+  cout << "peakFreq - peakTransmission - minFreq - maxFreq " << endl; 
+  cout <<  _nuPeak << "-" <<  _peakTransmission<< "-" <<  _numin << "-" <<  _numax << endl;
+
+}
+
+*/
Index: /tags/V_Dec2002/SophyaLib/SkyT/trianglefilt.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SkyT/trianglefilt.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SkyT/trianglefilt.h	(revision 2309)
@@ -0,0 +1,53 @@
+// This may look like C code, but it is really -*- C++ -*-
+//--------------------------------------------------------------------------
+// File and Version Information:
+//      $Id: trianglefilt.h,v 1.5 2000-04-13 08:17:04 ansari Exp $
+//
+// Description:
+//
+// History (add to end):
+//      Sophie   Oct, 1999  - creation
+//
+//------------------------------------------------------------------------
+#ifndef TRIANGLEFIL_H_SEEN
+#define TRIANGLEFIL_H_SEEN
+
+//----------------------
+// Base Class Headers --
+//----------------------
+#include "specresp.h"
+
+//------------------------------------
+// Collaborating Class Declarations --
+//------------------------------------
+
+//              ---------------------
+//              -- Class Interface --
+//              ---------------------
+namespace SOPHYA {
+class TriangleFilter:public SpectralResponse
+{
+public:
+  //Constructors
+  TriangleFilter (double numin, double numax,double nupeak, double valueatpeak); 
+  TriangleFilter ();
+
+  // destructor
+  ~TriangleFilter();
+
+  //
+  //  Function members
+  //
+
+  virtual double transmission(double) const;  
+  virtual double peakFreq() const; 
+  virtual double peakTransmission() const;
+
+protected:
+  double _peakTransmission;
+  double _nuPeak;
+};
+
+}
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/SysSpec/Makefile
===================================================================
--- /tags/V_Dec2002/SophyaLib/SysSpec/Makefile	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SysSpec/Makefile	(revision 2309)
@@ -0,0 +1,18 @@
+include ../Mgr/Makefile.h
+ 
+all: $(LIB)libSysSpec.a
+
+clean: 
+	rm -f $(OBJ)sysspecdummy.o $(OBJ)seed48.o $(OBJ)srand48.o $(OBJ)drand48-iter.o 
+	rm -f $(OBJ)sysspecdummy.o $(OBJ)rand48.o $(OBJ)seed48_r.o $(OBJ)srand48_r.o 
+	rm -f $(OBJ)complex_missing.o
+
+ifeq ($(MACHEROS),Darwin)
+#  SSOBJ :=  $(OBJ)sysspecdummy.o $(OBJ)seed48.o $(OBJ)srand48.o $(OBJ)drand48-iter.o
+  SSOBJ :=  $(OBJ)sysspecdummy.o $(OBJ)rand48.o $(OBJ)seed48_r.o $(OBJ)srand48_r.o $(OBJ)complex_missing.o
+else
+  SSOBJ :=  $(OBJ)sysspecdummy.o
+endif
+
+$(LIB)libSysSpec.a: $(SSOBJ)
+	$(ARCXX) $(ARCXXFLAGS) $@ $?
Index: /tags/V_Dec2002/SophyaLib/SysSpec/SysSpec.o.list
===================================================================
--- /tags/V_Dec2002/SophyaLib/SysSpec/SysSpec.o.list	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SysSpec/SysSpec.o.list	(revision 2309)
@@ -0,0 +1,3 @@
+rand48.o
+seed48_r.o
+srand48_r.o
Index: /tags/V_Dec2002/SophyaLib/SysSpec/complex_missing.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SysSpec/complex_missing.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SysSpec/complex_missing.cc	(revision 2309)
@@ -0,0 +1,6 @@
+#include <complex>
+#include <iostream>
+#include "complext.cc"
+template ostream & operator << <double>(ostream &, complex<double> const &);
+template ostream & operator << <float>(ostream &, complex<float> const &);
+
Index: /tags/V_Dec2002/SophyaLib/SysSpec/objlist.list
===================================================================
--- /tags/V_Dec2002/SophyaLib/SysSpec/objlist.list	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SysSpec/objlist.list	(revision 2309)
@@ -0,0 +1,3 @@
+rand48.o
+seed48_r.o
+srand48_r.o
Index: /tags/V_Dec2002/SophyaLib/SysSpec/rand48.c
===================================================================
--- /tags/V_Dec2002/SophyaLib/SysSpec/rand48.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SysSpec/rand48.c	(revision 2309)
@@ -0,0 +1,131 @@
+/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include "rand48.h"
+
+/* Global state for non-reentrant functions.  */
+static struct drand48_data __libc_drand48_data;
+
+
+int
+__drand48_iterate (xsubi, buffer)
+     unsigned short int xsubi[3];
+     struct drand48_data *buffer;
+{
+  u_int64_t X, a, result;
+
+  /* Initialize buffer, if not yet done.  */
+  if (!buffer->init)
+    {
+#if (USHRT_MAX == 0xffffU)
+      buffer->a[2] = 0x5;
+      buffer->a[1] = 0xdeec;
+      buffer->a[0] = 0xe66d;
+#else
+      buffer->a[2] = 0x5deecUL;
+      buffer->a[1] = 0xe66d0000UL;
+      buffer->a[0] = 0;
+#endif
+      buffer->c = 0xb;
+      buffer->init = 1;
+    }
+
+  /* Do the real work.  We choose a data type which contains at least
+     48 bits.  Because we compute the modulus it does not care how
+     many bits really are computed.  */
+
+  if (sizeof (unsigned short int) == 2)
+    {
+      X = (u_int64_t)xsubi[2] << 32 | (u_int64_t)xsubi[1] << 16 | xsubi[0];
+      a = ((u_int64_t)buffer->a[2] << 32 | (u_int64_t)buffer->a[1] << 16
+	   | buffer->a[0]);
+
+      result = X * a + buffer->c;
+
+      xsubi[0] = result & 0xffff;
+      xsubi[1] = (result >> 16) & 0xffff;
+      xsubi[2] = (result >> 32) & 0xffff;
+    }
+  else
+    {
+      X = (u_int64_t)xsubi[2] << 16 | xsubi[1] >> 16;
+      a = (u_int64_t)buffer->a[2] << 16 | buffer->a[1] >> 16;
+
+      result = X * a + buffer->c;
+
+      xsubi[0] = result >> 16 & 0xffffffffl;
+      xsubi[1] = result << 16 & 0xffff0000l;
+    }
+
+  return 0;
+}
+/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+
+unsigned short int *
+seed48 (seed16v)
+     unsigned short int seed16v[3];
+{
+  (void) seed48_r (seed16v, &__libc_drand48_data);
+
+  return __libc_drand48_data.old_X;
+}
+/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+
+void
+srand48 (seedval)
+     long seedval;
+{
+  (void) srand48_r (seedval, &__libc_drand48_data);
+}
Index: /tags/V_Dec2002/SophyaLib/SysSpec/rand48.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SysSpec/rand48.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SysSpec/rand48.h	(revision 2309)
@@ -0,0 +1,14 @@
+#ifndef RAND48_H
+#define RAND48_H
+
+struct drand48_data {
+  unsigned short  X[3];           /* 48 bit integer value */
+  unsigned short  a[3];           /* mutiplier value */
+  unsigned short  c;              /* addend value */
+  unsigned short  old_X[3];       /* previous value of Xi */
+  int             init;           /* initialize ? */
+};
+
+typedef unsigned long long u_int64_t;
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/SysSpec/seed48_r.c
===================================================================
--- /tags/V_Dec2002/SophyaLib/SysSpec/seed48_r.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SysSpec/seed48_r.c	(revision 2309)
@@ -0,0 +1,55 @@
+/* Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include "rand48.h"
+
+int
+seed48_r (seed16v, buffer)
+     unsigned short int seed16v[3];
+     struct drand48_data *buffer;
+{
+  /* Save old value at a private place to be used as return value.  */
+  memcpy (buffer->old_X, buffer->X, sizeof (buffer->X));
+
+  /* Install new state.  */
+#if USHRT_MAX == 0xffffU
+  buffer->X[2] = seed16v[2];
+  buffer->X[1] = seed16v[1];
+  buffer->X[0] = seed16v[0];
+
+  buffer->a[2] = 0x5;
+  buffer->a[1] = 0xdeec;
+  buffer->a[0] = 0xe66d;
+#else
+  buffer->X[2] = (seed16v[2] << 16) | seed16v[1];
+  buffer->X[1] = seed16v[0] << 16;
+  buffer->X[0] = 0;
+
+  buffer->a[2] = 0x5deecUL;
+  buffer->a[1] = 0xe66d0000UL;
+  buffer->a[0] = 0;
+#endif
+  buffer->c = 0xb;
+  buffer->init = 1;
+
+  return 0;
+}
Index: /tags/V_Dec2002/SophyaLib/SysSpec/srand48_r.c
===================================================================
--- /tags/V_Dec2002/SophyaLib/SysSpec/srand48_r.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SysSpec/srand48_r.c	(revision 2309)
@@ -0,0 +1,53 @@
+/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <limits.h>
+#include "rand48.h"
+
+int
+srand48_r (seedval, buffer)
+     long int seedval;
+     struct drand48_data *buffer;
+{
+  /* The standards say we only have 32 bits.  */
+  if (sizeof (long int) > 4)
+    seedval &= 0xffffffffl;
+
+#if USHRT_MAX == 0xffffU
+  buffer->X[2] = seedval >> 16;
+  buffer->X[1] = seedval & 0xffffl;
+  buffer->X[0] = 0x330e;
+
+  buffer->a[2] = 0x5;
+  buffer->a[1] = 0xdeec;
+  buffer->a[0] = 0xe66d;
+#else
+  buffer->X[2] = seedval;
+  buffer->X[1] = 0x330e0000UL;
+  buffer->X[0] = 0;
+
+  buffer->a[2] = 0x5deecUL;
+  buffer->a[1] = 0xe66d0000UL;
+  buffer->a[0] = 0;
+#endif
+  buffer->c = 0xb;
+  buffer->init = 1;
+
+  return 0;
+}
Index: /tags/V_Dec2002/SophyaLib/SysSpec/sysspecdummy.c
===================================================================
--- /tags/V_Dec2002/SophyaLib/SysSpec/sysspecdummy.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SysSpec/sysspecdummy.c	(revision 2309)
@@ -0,0 +1,2 @@
+void sysspecdummy() {}
+
Index: /tags/V_Dec2002/SophyaLib/SysTools/Makefile
===================================================================
--- /tags/V_Dec2002/SophyaLib/SysTools/Makefile	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SysTools/Makefile	(revision 2309)
@@ -0,0 +1,27 @@
+include ../Mgr/Makefile.h
+ 
+all: $(LIB)libSysTools.a
+clean:
+	rm -f $(OBJ)ctimer.o $(OBJ)cxxcmplnk.o $(OBJ)pdlmgr.o $(OBJ)periodic.o $(OBJ)psighand.o $(OBJ)resusage.o $(OBJ)zthread.o $(OBJ)timing.o
+	rm -f $(LIB)libSysTools.a
+$(LIB)libSysTools.a : $(OBJ)ctimer.o $(OBJ)cxxcmplnk.o $(OBJ)pdlmgr.o $(OBJ)periodic.o $(OBJ)psighand.o $(OBJ)resusage.o $(OBJ)timing.o $(OBJ)zthread.o
+	$(ARCXX) $(ARCXXFLAGS) $@ $($(ARARGS))
+ifeq ($(CXX),cxx)
+	$(CXX) $? $(CPPFLAGS) $(CXXFLAGS) -o $(OBJ)xx.x -Hf
+endif 
+ 
+$(OBJ)ctimer.o: ctimer.cc $(INC)machdefs.h ctimer.h
+$(OBJ)cxxcmplnk.o: cxxcmplnk.cc cxxcmplnk.h \
+ $(INC)machdefs.h
+$(OBJ)pdlmgr.o: pdlmgr.cc pdlmgr.h
+$(OBJ)periodic.o: periodic.cc $(INC)machdefs.h \
+ periodic.h
+$(OBJ)psighand.o: psighand.cc psighand.h \
+ $(INC)machdefs.h \
+ $(INC)pexceptions.h
+$(OBJ)resusage.o: resusage.cc resusage.h \
+ $(INC)machdefs.h
+$(OBJ)zthread.o: zthread.cc zthread.h \
+ $(INC)machdefs.h \
+ $(INC)pexceptions.h
+$(OBJ)timing.o: timing.c timing.h
Index: /tags/V_Dec2002/SophyaLib/SysTools/ctimer.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SysTools/ctimer.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SysTools/ctimer.cc	(revision 2309)
@@ -0,0 +1,108 @@
+//
+// $Id: ctimer.cc,v 1.4 2000-04-13 15:58:37 ansari Exp $
+//
+
+#include "machdefs.h"
+#include "ctimer.h"
+
+//++
+// Class	Timer
+// Lib  	SysTools
+// include	ctimer.h
+//
+//	Chronométrage de programmes. Le constructeur mémorise l'heure et
+//      le temps CPU, ainsi qu'un message éventuel.
+//
+//	Split affiche le temps partiel.
+//
+//	Le destructeur affiche le temps total (CPU, et écoulé).
+//    
+//      Des macros permettent une utilisation simplifiée :
+//      * TIMEF   crée un objet de type Timer, avec le nom de la function 
+//	courante comme message. Le temps écoulé sera affiché à la sortie 
+//	de la function.
+//      * SPLITTIME affiche le temps partiel du compteur crée par TIMEF
+//      * TIMEN(nom) permet de donner un autre nom que le nom de la fonction.
+//--
+
+
+//++
+// Titre	Constructeurs
+//--
+
+//++
+// Timer::Timer(const char* name)
+//	Crée un objet qui mémorise l'heure et le temps CPU du process courant.
+//	Le destructeur affiche les temps écoulé et CPU utilisé.
+//--
+
+/*!
+  \class SOPHYA::Timer
+  \ingroup SysTools
+  This class implements a simple chronometer which can be used for
+  measuring the CPU and elapsed time in functions. The constructor
+  keeps the start time (and CPU time) and an optional message. 
+  The \b Split method displays the partial time, and destructor 
+  displays the total CPU and elapsed time since timer creation.
+  The macro \b  TIMEF create a timer object with the function name.
+  The macro \b  SPLITTIME calls the split methode for the timer created
+  by TIMEF. A named timer can be created using the macro \b TIMEN(nom)
+*/
+
+/*! Constructor with the specification of a optional name or message */
+Timer::Timer(const char* name)
+: timerName(name)
+{
+  cpu0 = cpuSplit = clock();
+  elapse0 = elapseSplit = time(0);
+}
+
+//++
+// Titre	Méthodes
+//--
+
+//++
+// Timer::Split(const char* comm)
+//	Affiche le temps partiel.
+//--
+
+/*! Method which displays the partial CPU and elapsed time
+    An optional message can be passed to be used instead of the
+    timer name
+*/
+void Timer::Split(const char* comm)
+{
+  time_t elapse = time(0);
+  clock_t cpu   = clock();
+
+  float cpuSecT = ((float)cpu - (float)cpu0) / (float)(CLOCKS_PER_SEC);
+  float cpuSecP = ((float)cpu - (float)cpuSplit) / (float)(CLOCKS_PER_SEC);
+  
+  int etm  = elapse - elapseSplit;
+  int etmt = elapse - elapse0;
+
+  cout << "***Timing " << (comm ? comm : timerName.c_str()) << endl;
+
+// Pour des formats comme ca, la syntaxe printf est plus agreable.
+// Pour ne pas melanger stdio/iostream (pb de desynchronisation sur
+// autres C++ que GNU), on fait un cout << chaine.
+
+  char out[200];
+  sprintf(out,"CPU     Time: Total= %g (Partial= %g) Sec.",
+	  cpuSecT, cpuSecP);
+  cout << out << endl;
+
+  sprintf(out,"Elapsed Time: Total= %02d:%02d:%02d (Partial=%02d:%02d:%02d)",
+	  etmt/3600, (etmt%3600)/60, etmt%60, 
+	  etm/3600,  (etm%3600)/60,  etm%60);
+
+  cout << out << endl;
+
+  elapseSplit = elapse;
+  cpuSplit    = cpu;
+}
+
+Timer::~Timer()
+{
+  Split();
+}
Index: /tags/V_Dec2002/SophyaLib/SysTools/ctimer.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SysTools/ctimer.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SysTools/ctimer.h	(revision 2309)
@@ -0,0 +1,56 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// $Id: ctimer.h,v 1.3 2000-04-12 17:49:41 ansari Exp $
+//
+
+
+#ifndef CTIMER_SEEN
+#define CTIMER_SEEN
+
+#include "machdefs.h"
+#include <sys/types.h>
+#include <time.h>
+#include <iostream.h>
+#include <stdio.h>
+#include <string>
+
+// <summary> Permet de chronometrer des fonctions. </summary>
+// La macro TIMEF cree un objet de class Timer qui memorise
+// l'heure de sa creation, et le temps CPU.
+
+// A la fin du bloc ou de la procedure, l'objet est detruit,
+// et son destructeur affiche le temps ecoule.
+
+// La macro SPLITTIME lui permet d'afficher des temps partiels.
+namespace SOPHYA {
+
+//! Simple chronometer class
+class Timer  {
+public:
+  // L'objet memorise le temps CPU et l'heure, et le nom donne
+  Timer(const char* name=0);
+
+  // Le destructeur appelle split sans parametre.
+  virtual ~Timer();
+
+  // Affiche le temps ecoule total/partiel, avec le nom eventuel.
+  // Si pas de parametre affiche le nom donne a la creation.
+  void Split(const char* comm=0);
+
+  // Sert a eviter que GNU ne pretende qu'on utilise pas l'objet...
+  /*! To avoid not used object compiler warnings */
+  void Nop() {}
+
+private:
+  clock_t cpu0, cpuSplit;
+  time_t  elapse0, elapseSplit;
+  string timerName;
+};
+
+} // namespace SOPHYA
+
+#define TIMEN(x)  Timer timer(x); timer.Nop();
+#define TIMEF     Timer timer(__PRETTY_FUNCTION__); timer.Nop();
+#define SPLITTIME timer.Split();
+
+#endif // CTIMER_SEEN
Index: /tags/V_Dec2002/SophyaLib/SysTools/cxxcmplnk.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SysTools/cxxcmplnk.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SysTools/cxxcmplnk.cc	(revision 2309)
@@ -0,0 +1,209 @@
+// Gestionnaire de compilation-linker C++ - R. Ansari 10/2000
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "cxxcmplnk.h"
+#include <iostream.h>
+
+/*!
+  \class SOPHYA::CxxCompilerLinker
+  \ingroup SysTools
+  This classes handles the compilation of a C++ source code and 
+  building of a shared library.
+  The present version has been adapted for different compilers:
+  g++ , Compaq/Digital cxx , SGI CC , KCC .
+  \sa SOPHYA::PDynLinkMgr
+  \code
+  #include "cxxcmplnk.h"
+  CxxCompilerLinker cxx;
+  string name = "toto.cc";
+  string oname = "toto.o";
+  string soname = "toto.so";
+  int rc;
+  // compiling file 
+  rc = cxx.Compile(name, oname);
+  // linking and building the shared object 
+  rc = cxx.BuildSO(oname, soname);
+  \endcode
+*/
+
+static char * gcxx_opt = 
+"-O -Wall -Wpointer-arith -Wmissing-prototypes -Wsynth -fdollars-in-identifiers";
+static char * KCC_opt = 
+"-O --exceptions --rtti  --auto_instantiation --one_instantiation_per_object -D__KCC__";
+static char * cxx_opt = 
+"-O -no_implicit_include ";
+static char * SGICC_opt =  "-O -prelink -D__SGICC__ ";
+
+/* --Methode-- */
+/*!
+  Constructor
+  \param fglibsophya : if \c true libsophya.so is used when linking
+  \param fglibextsophya : if \c true libextsophya.so is used when linking
+  \param fglibpi : if \c true libPI.so is used when linking
+*/
+CxxCompilerLinker::CxxCompilerLinker(bool fglibsophya, bool fglibextsophya, bool fglibpi)
+  : verbose(false)
+{
+  
+  string syscomp = "";
+
+#if defined(OSF1) 
+  cppFlags += "-DOSF1" ; 
+  syscomp = "OSF1-";
+#elif defined(Linux)
+  cppFlags += "-DLinux" ;
+  syscomp = "Linux-"; 
+#elif defined(SunOS)
+  cppFlags += "-DSunOS" ;
+  syscomp = "SunOS-";  
+#elif defined(IRIX64)
+  cppFlags += "-DIRIX64" ;
+  syscomp = "IRIX64-";  
+#elif defined(AIX)
+  cppFlags += "-DAIX" ;
+  syscomp = "AIX-";  
+#elif defined(HPUX)
+  cppFlags += "-DHPUX" ;
+  syscomp = "HPUX-";  
+#elif defined(Darwin)
+  cppFlags += "-DDarwin";
+  syscomp = "Darwin-";
+#endif
+
+
+#if defined( __GNUG__ )
+  compCmd = "g++ ";
+  compOptions = gcxx_opt;
+  linkOptions = "-O -shared";
+  syscomp += "g++/"; 
+#elif defined( __DECCXX )
+  compCmd = "cxx ";
+  compOptions = cxx_opt;
+  linkOptions = compOptions + "-shared";
+  syscomp += "cxx/"; 
+#elif defined( __KCC__ )
+  compCmd = "KCC ";
+  compOptions = KCC_opt;
+  linkOptions = KCC_opt;
+  syscomp += "KCC/";  
+#elif defined( __SGICC__ )
+  compCmd = "CC ";
+  compOptions = SGICC_opt;
+  linkOptions = "-shared -O ";
+  syscomp += "CC/";  
+#ifdef SGI_ARCH64
+  compOptions += " -64 -DSGI_ARCH64 ";
+  linkOptions += " -64 "; 
+#endif
+#endif
+
+#ifndef Darwin
+  linkCmd = compCmd;
+#else
+  linkCmd = "cc -bundle -flat_namespace -undefined suppress ";
+  linkOptions = "-L/usr/lib/gcc/darwin/default -lstdc++ -lcc_dynamic -lpthread ";
+#endif
+
+  cppFlags += " -I. ";
+  compOptions += " -c ";
+
+  string dpcbase;
+  char* varenv=NULL;
+  varenv=getenv("DPCBASEREP");
+  if (varenv) {
+    dpcbase = varenv; 
+    if (dpcbase[dpcbase.length()-1] != '/')  dpcbase += '/';
+    cppFlags += ( " -I" + dpcbase + "Include/ ");
+    linkOptions += " -L" + dpcbase + syscomp + "ShLibs/";
+    if (fglibsophya) linkOptions += " -lsophya ";
+    if (fglibextsophya) linkOptions += " -lextsophya ";
+    if (fglibpi) linkOptions += " -lPI ";
+  }
+  linkOptions += " -lm ";
+
+  string extlib;
+  varenv=getenv("EXTLIBDIR");
+  if (varenv) {
+    extlib = varenv; 
+    if (extlib[extlib.length()-1] != '/')  extlib += '/';
+    cppFlags += ( " -I" + extlib +"Include/ ");
+  }
+
+  if ( (varenv=getenv("TMPDIR")) != NULL )  { 
+    tmpDir = varenv; 
+    if (tmpDir[tmpDir.length()-1] != '/') tmpDir += '/';
+  }
+}
+
+/* --Methode-- */
+CxxCompilerLinker::~CxxCompilerLinker()
+{
+}
+
+/* --Methode-- */
+/*!
+  Compiles the file \c name using the C++ compiler driver and produces 
+  the output object file \c oname. If no output name is specified,
+  a default output file name is made from the input name, with the 
+  suffix .o , the in temporary directory.
+  \param name : input C++ source file
+  \param oname : output object file 
+*/
+int CxxCompilerLinker::Compile(string const & name, string & oname)
+{
+  if (oname.length() < 1) {
+    size_t l,p,q;
+    l = name.length();
+    p = name.rfind('/');
+    if (p >= l)  p = 0;
+    else p++;
+    q = name.rfind('.');
+    if ((q < l) && (q > p))  oname = tmpDir + name.substr(p, q-p) + ".o";
+    else oname = tmpDir + name.substr(p) + ".o";
+  }
+  string cmd;
+  cmd = compCmd + cppFlags + compOptions + "-o " + oname + " " + name ; 
+  if (verbose)
+    cout << "CxxCompilerLinker::Compile() - Executing \n" << cmd << endl; 
+  int rc = system(cmd.c_str());
+  if (rc != 0)   
+    cerr << "CxxCompilerLinker::Compile() Error Rc(" << cmd <<")= "<< rc << endl; 
+  
+  return(rc);
+}
+
+/* --Methode-- */
+/*!
+  Creates a shared library from the object file \c oname.
+  If no output name \c soname is specified,
+  a default output file name is made from the object name, with the 
+  suffix .so , in the temporary directory.
+  \param oname : input object file 
+  \param soname : shared library name
+*/
+int CxxCompilerLinker::BuildSO(string const & oname, string & soname)
+{
+  //  char * soext = ".dylib"; if defined(Darwin) - pas necessaire Reza 02/2002
+  char * soext = ".so";
+
+  if (soname.length() < 1) {
+    size_t l,p,q;
+    l = oname.length();
+    p = oname.rfind('/');
+    if (p >= l)  p = 0;
+    else p++;
+    q = oname.rfind('.');
+    if ((q < l) && (q > p))  soname = tmpDir + oname.substr(p, q-p) + soext;
+    else soname = tmpDir + oname.substr(p) + soext;
+  }
+  string cmd;
+  cmd = linkCmd + " " + oname + " " + linkOptions + " -o " + soname + " " ; 
+  if (verbose)
+    cout << "CxxCompilerLinker::BuildSO() - Executing \n" << cmd << endl; 
+  int rc = system(cmd.c_str());
+  if (rc != 0)   
+    cerr << "CxxCompilerLinker::BuildSO() Error Rc(" << cmd <<")= "<< rc << endl; 
+  
+  return(rc);
+}
+
Index: /tags/V_Dec2002/SophyaLib/SysTools/cxxcmplnk.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SysTools/cxxcmplnk.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SysTools/cxxcmplnk.h	(revision 2309)
@@ -0,0 +1,68 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Gestionnaire de compilation-linker C++ - R. Ansari 10/2000
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef CXXCOMPILERLINKER_SEEN
+#define CXXCOMPILERLINKER_SEEN
+
+#include "machdefs.h"
+#include <string>
+
+
+namespace SOPHYA {
+
+//! C++ compiler - linker
+ 
+class CxxCompilerLinker {
+public:
+  CxxCompilerLinker(bool fglibsophya=true, bool fglibextsophya=true, 
+					  bool fglibpi=false);  
+  virtual		~CxxCompilerLinker();
+
+  virtual int           Compile(string const & name, string & oname);
+  virtual int           BuildSO(string const & oname, string & soname);
+
+  //! Adds compilation options \c opt . Appended to the present option string.
+  inline void           AddCompileOptions(string const & opt)
+  { compOptions += " " + opt; }
+  //! Sets the compilation options.
+  inline void           SetCompileOptions(string const & opt = "")
+  { compOptions = opt; }
+  //! Returns the currently defined compilation options.
+  inline string         GetCompileOptions()
+  { return compOptions; }
+
+  //! Adds link options \c opt . Appended to the present option string.
+  inline void           AddLinkOptions(string const & opt)
+  { linkOptions += " " + opt; }
+  //! Sets the link options.
+  inline void           SetLinkOptions(string const & opt = "")
+  { linkOptions = opt; }
+  inline string         GetLinkOptions()
+  //! Returns the currently defined link options.
+  { return linkOptions; }
+
+  //! Sets the temporary directory path.
+  inline void        	SetTmpDir(string const & tmpdir)
+  { tmpDir = tmpdir; }
+  //! returns the currently defined temporary directory path.
+  inline string        	GetTmpDir()
+  { return tmpDir; }
+  
+  //! Activate (or deactivate) the verbose mode.
+  inline void           SetVerbose(bool fg=false)
+  { verbose = fg; }
+
+protected :
+  string  tmpDir;
+  string  compCmd;
+  string  linkCmd;
+  string  compOptions;
+  string  linkOptions;
+  string  cppFlags;  
+  bool    verbose;
+};
+
+} // namespace SOPHYA
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/SysTools/objlist.list
===================================================================
--- /tags/V_Dec2002/SophyaLib/SysTools/objlist.list	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SysTools/objlist.list	(revision 2309)
@@ -0,0 +1,8 @@
+ctimer.o
+cxxcmplnk.o
+pdlmgr.o
+periodic.o
+psighand.o
+resusage.o
+timing.o
+zthread.o
Index: /tags/V_Dec2002/SophyaLib/SysTools/pdlmgr.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SysTools/pdlmgr.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SysTools/pdlmgr.cc	(revision 2309)
@@ -0,0 +1,287 @@
+//
+// Gestionnaire de lien dynamique   -   R. Ansari 12/98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+//
+#include <machdefs.h>
+
+#include "pdlmgr.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <iostream.h>
+
+
+// Extension de noms de fichiers Shared libs
+static const char* sofext = ".so";
+static const char* sofext_HPUX = ".sl";
+// static const char* sofext_Darwin = ".dylib"; pas necessaire - Reza 02/2002
+
+// Variables et methodes static
+int PDynLinkMgr::numSO = 0;
+string*  PDynLinkMgr::tmpDir = NULL;
+
+/*!
+  \class SOPHYA::PDynLinkMgr
+  \ingroup SysTools
+  This classes handles the run-time operations related to using shared
+  libraries. The present version has been adapted for different Unix 
+  flavours (Linux, Compaq/Digital Unix, SGI IRIX, IBM AIX, Sun Solaris,
+  MacOS X/Darwin).
+  The example here shows the linking of shared library named "mylib.so" 
+  containing a function \c double \c myfunction(double x). 
+  \code
+  #include "pdlmgr.h"
+  typedef double (* AFunctionOfX) (double x);
+  {
+  // ...
+  string soname = "mylib.so";
+  string funcname = "myfunction";
+  PDynLinkMgr dyl(son);
+  AFunctionOfX f = (AFunctionOfX)dyl.GetFunction(funcname);
+  double x = 3.1425;
+  if (f != NULL) 
+    cout << " X= " << x << " myfunction(x)=" << f(x) << endl;
+  // ...
+  }
+  \endcode
+*/
+
+/* --Methode-Static-- */
+/*! Sets the path for a temporary space where shared libraries are copied.
+    The path is appended to \b LD_LIBRARY_PATH
+*/
+void PDynLinkMgr::SetTmpDir(string const & path)
+{
+if ( (path.length() > 0) && (path[path.length()-1] != '/')  ) GetTmpDir() = path + '/';
+else GetTmpDir() = path;
+#if defined(OSF1) || defined(Linux) || defined(SunOS) || defined(IRIX64)
+  char* varenv=NULL;
+#if !defined(IRIX64)
+  string cmd = "LD_LIBRARY_PATH=";
+  varenv=getenv("LD_LIBRARY_PATH");
+#else
+#ifdef SGI_ARCH64
+  string cmd = "LD_LIBRARYN32_PATH=";
+  varenv=getenv("LD_LIBRARYN32_PATH");
+#else
+  string cmd = "LD_LIBRARYN64_PATH=";
+  varenv=getenv("LD_LIBRARYN64_PATH");
+#endif
+#endif
+
+  if (varenv == NULL) { 
+    cmd += '.';  
+    if (path.length() > 0)  cmd += ':' + path; 
+    }
+  else { 
+    if (varenv[0] != '.') cmd += ".:";
+    if (path.length() > 0)  cmd += path + ':';
+    cmd += varenv;
+    putenv(const_cast<char *>(cmd.c_str()));
+    }
+#elif defined(AIX)
+  string cmd = "LIBPATH=";
+  char* varenv=NULL;
+  varenv=getenv("LIBPATH");
+  if (varenv == NULL) { 
+    cmd += '.';  
+    if (path.length() > 0)  cmd += ':' + path; 
+    cmd += ":/usr/lib:/lib";
+    }
+  else { 
+    if (varenv[0] != '.') cmd += ".:";
+    if (path.length() > 0)  cmd += path + ':';
+    cmd += varenv;
+    putenv(const_cast<char *>(cmd.c_str()));
+    }
+
+#endif
+return;
+}
+
+/* --Methode-Static-- */
+/*! Returns the temporary space path */
+string& PDynLinkMgr::GetTmpDir()
+{
+if (tmpDir == NULL) { 
+  tmpDir = new string("");
+  char* varenv;
+  if ( (varenv=getenv("TMPDIR")) != NULL )  { 
+    *tmpDir = varenv; 
+    if ((*tmpDir)[tmpDir->length()-1] != '/') (*tmpDir) += '/';
+  }
+}
+return(*tmpDir);
+}
+
+/* --Methode-Static-- */
+/*! Compiles the C source file named \b fname and creates the 
+    corresponding shared library linking against the standard 
+    C library (-lc) and the math library (-lm).
+    Returns a pointer to the created PDynLinkMgr object (by new).
+    Returns the NULL pointer in case of errors. 
+*/
+PDynLinkMgr* PDynLinkMgr::BuildFromCFile(string const & fname)
+{
+size_t l = fname.length();
+if (l < 1)  return(NULL);
+string fnameobj = GetTmpDir()+"tmp_pdl.o";
+
+string cmd;
+int rc;
+
+// Compilation du fichier
+#ifndef __mac__
+#ifdef SGI_ARCH64
+cmd = "cc -64 -c -o " + fnameobj + " " + fname;
+#else
+cmd = "cc -c -o " + fnameobj + " " + fname;
+#endif
+#else 
+cmd = "Il faut compiler !!!" + fnameobj + " " + fname;
+#endif
+rc = system(cmd.c_str());
+if (rc != 0)  { 
+  cerr << "PDynLinkMgr::BuildFromCFile() Error Rc(" << cmd <<")= "<< rc << endl; 
+  return(NULL);
+  }
+
+char buff[32];
+numSO++;
+#ifndef HPUX
+sprintf(buff,"pdlmgr%d%s", numSO,sofext);
+#endif
+string fnameso = GetTmpDir()+buff;
+
+// Creation du shared-lib
+#if defined(OSF1) 
+  cmd = "ld -shared -o " + fnameso + " -all " + fnameobj + " -none -lm -lc";
+#elif defined(Linux)
+  cmd = "ld -shared -o " + fnameso + " " + fnameobj + " -lm -lc";
+#elif defined(SunOS)
+  cmd = "ld -G -o " + fnameso + " " + fnameobj + " -lm -lc";
+#elif defined(IRIX64)
+#ifdef SGI_ARCH64
+  cmd = "ld -64 -shared -o " + fnameso + " " + fnameobj + " -lm -lc";
+#else
+  cmd = "ld -shared -o " + fnameso + " " + fnameobj + " -lm -lc";
+#endif
+#elif defined(AIX)
+  cmd = "ld -G -bnogc -bexpall -bM:1L -o " + fnameso + " " + fnameobj;
+#elif defined(HPUX)
+  cmd = "ld -b -o " + fnameso + " " + fnameobj + " -lm -lc";
+#elif defined(Darwin)
+  cmd = "cc -bundle -flat_namespace -undefined suppress -o " + fnameso + " " + fnameobj + " -lm  -lcc_dynamic -lSystem ";
+#else 
+  cmd = "ld -o " + fnameso + " " + fnameobj + " -lm -lc";
+#endif
+rc = system(cmd.c_str());
+if (rc != 0)  { 
+  cerr << "PDynLinkMgr::BuildFromCFile() Error Rc(" << cmd <<")= "<< rc << endl; 
+  return(NULL);
+  }
+PDynLinkMgr* rdyn = new PDynLinkMgr(fnameso, false);
+rdyn->copy = true;
+return(rdyn);
+
+}
+
+/* --Methode-- */
+/*! The constructor. 
+    \param soname : Name of the shared library. ".so" is appended
+    to the name if no dot "." is found in the name.
+    \param cp : if true, copies the shared library in the temporary space.
+*/ 
+PDynLinkMgr::PDynLinkMgr(string& soname, bool cp)
+{
+#ifndef Darwin
+dlhandle = NULL;
+#endif
+soName = "";
+
+if (soname.find_last_of(".") > soname.length())  
+#ifdef HPUX
+  soname += sofext_HPUX;
+#else
+  soname += sofext;
+#endif
+
+string fnameso;
+if (cp) {
+  numSO++;
+  char buff[32];
+#ifndef HPUX
+  sprintf(buff,"pdlmgr%d%s", numSO,sofext);
+#elif defined(Darwin)
+  sprintf(buff,"pdlmgr%d%s", numSO,sofext_Darwin);
+#else
+  sprintf(buff,"pdlmgr%d%s", numSO,sofext_HPUX);
+#endif
+  fnameso = GetTmpDir()+buff;
+  string cmd = "cp " + soname + " " + fnameso;
+  int rc = system(cmd.c_str());
+  if (rc != 0)  { 
+    cerr << "PDynLinkMgr::PDynLinkMgr() Error Rc(" << cmd <<")= "<< rc << endl; 
+    return;
+    }
+  } 
+else fnameso = soname;
+copy = cp;
+soName = fnameso;
+
+#if defined(HPUX)
+dlhandle = NULL;
+cerr << "PDynLinkMgr::PDynLinkMgr() Not yet available on HP-UX " << endl;
+return;
+#else
+dlhandle =  dlopen(fnameso.c_str(), RTLD_NOW);
+if (dlhandle == NULL) { 
+  cerr << "PDynLinkMgr::PDynLinkMgr(): Error opening SO " << fnameso 
+       << " (" << soname << ")" << endl; 
+  string sn = dlerror();
+  cerr << "Loader Error (dlerror()) :" << sn << endl;
+  return; 
+  }
+#endif
+}
+
+/* --Methode-- */
+/*! Destructor. Closes the shared library. Removes the file if it had been
+    copied in the temporary space, or generated by \b BuildFromCFile */
+PDynLinkMgr::~PDynLinkMgr()
+{
+#if defined(HPUX)
+cerr << "PDynLinkMgr::~PDynLinkMgr() Not yet available on HP-UX " << endl;
+return;
+#else
+if (dlhandle) dlclose(dlhandle);    dlhandle = NULL;
+if (copy) {
+  string cmd = "rm -f " + soName;
+  system(cmd.c_str());
+  }
+#endif
+}
+
+/* --Methode-- */
+/*! Returns a handle to the function named \b funcname.
+    Returns the NULL pointer in case of error          */
+DlFunction PDynLinkMgr::GetFunction(string const & funcname)
+{
+DlFunction f = NULL;
+#if defined(HPUX)
+cerr << "PDynLinkMgr::GetFunction() Not yet available on HP-UX " << endl;
+return f;
+#else 
+#if defined(Darwin)
+string funame = "_" + funcname;
+#else 
+string const & funame = funcname;
+#endif
+if (dlhandle != NULL)  
+  f = (DlFunction)dlsym(dlhandle, funame.c_str());
+if (f == NULL) cerr << "PDynLinkMgr::GetFunction(): Error linking " << funcname << endl;
+return(f);
+#endif
+}
+
+
Index: /tags/V_Dec2002/SophyaLib/SysTools/pdlmgr.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SysTools/pdlmgr.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SysTools/pdlmgr.h	(revision 2309)
@@ -0,0 +1,54 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Gestionnaire de lien dynamique   -   R. Ansari 12/98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PDYNLINKMGR_SEEN
+#define PDYNLINKMGR_SEEN
+
+#include "machdefs.h"
+#include <string>
+
+
+#if defined(HPUX)
+#include <dl.h>
+#elif defined(Darwin)
+#include </sw/include/dlfcn.h>
+#else
+#include <dlfcn.h>
+#endif
+
+namespace SOPHYA {
+
+typedef void (* DlFunction) (void);
+
+//! Dynamic Link Manager. 
+class PDynLinkMgr {
+public:
+  // ---- Methodes globales (static)
+  static PDynLinkMgr*   BuildFromCFile(string const & fname);  // Compil+link fichier C
+  static void		SetTmpDir(string const & path);        // Repertoire des fichiers temporaires
+
+  // ---- Constructeur et methodes 
+  // Constructeur a partir d'un shared lib - copie en zone temporaire si cp==true
+			PDynLinkMgr(string& soname, bool cp=true);  
+  virtual		~PDynLinkMgr();
+
+  virtual DlFunction	GetFunction(string const & funcname);              
+
+protected :
+  static string&	GetTmpDir();
+  static int	  numSO;
+  static string*  tmpDir;
+
+#if defined(HPUX)
+  shl_t dlhandle;
+#else 
+  void * dlhandle;
+#endif
+  string soName;
+  bool copy;
+};
+
+} // namespace SOPHYA
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/SysTools/periodic.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SysTools/periodic.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SysTools/periodic.cc	(revision 2309)
@@ -0,0 +1,158 @@
+/* Classe d'objets avec une methode (DoPeriodic()) appelee periodiquement */
+/*                                  Eric Aubourg     04/96                */
+/*                                  Reza Ansari      06/96                */
+/*                      LAL/IN2P3 (Orsay)  DAPNIA/CEA (Saclay)            */
+
+#include "machdefs.h"
+#include <signal.h>
+#include <unistd.h>
+
+#include "periodic.h"
+/*!
+  \class SOPHYA::Periodic
+  \ingroup SysTools
+  This class provide the service of calling a given function at 
+  regular intervals. It can also be subclassed with the method 
+  \b DoPeriodic redefined to perform a periodic action.
+*/
+
+//++
+// Class	Periodic
+// Lib		SysTools
+// include	periodic.h
+//
+//	Classe d'objets avec une méthode "DoPeriodic()" appelée périodiquement
+//	à intervalle régulier.
+//--
+
+//++
+// Titre	Constructeur, méthodes
+//--
+//++
+//  Periodic(int dt, UsPeriodicAction act=NULL, void * usp=NULL)
+//	Constructeur avec un intervalle de temps en secondes "dt".
+//	Il est possible de spécifier une fonction "UsPeriodicAction" avec
+//	un argument "usp" qui sera appelée régulierement.
+//|	typedef void (* UsPeriodicAction) (void *);
+//--
+
+//++
+//  void  Start(int dt=-1)
+//	Activation de l'objet périodique. 
+//	On peut spécifier l'intervalle en temps (en secondes) si "dt > 0".
+//  void  Stop()
+//	Désactivation de l'objet périodique.
+//  void  DoPeriodic()
+//	Méthode virtuelle qui peut être surchargée dans les classes dérivées.
+//	Elle est appelée lorsque l'intervalle de temps est écoulé. Par défaut,
+//	elle appelle la fonction "UsPeriodicAction" associée si "!= NULL"
+//--
+
+
+/* --Methode-- */
+/*! Constructor with the definition of the interval (in seconds)
+  and an optional user action */
+Periodic::Periodic(int dt, UsPeriodicAction act, void * usp)
+{
+mDt = dt;
+mAct = act;
+mUsp = usp;
+if (mDt < 1)  mDt = 5;
+mDtms = 1000*mDt;
+mFgact = false;
+it = -1;
+}
+
+/* --Methode-- */
+Periodic::~Periodic()
+{
+if (mFgact) Stop();
+}
+
+/* --Methode-- */
+/*! Sets the user action function and its data \c usp */
+void Periodic::SetAction(UsPeriodicAction act, void * usp)
+{
+mAct = act;
+mUsp = usp;
+}
+
+/* --Methode-- */
+/*! Changes the interval \c dt specified in seconds */
+void Periodic::SetInterval(int dt)
+{
+mDt = dt;
+if (mDt < 1)  mDt = 5;
+mDtms = 1000*mDt;
+}
+
+/* --Methode-- */
+/*! Changes the interval \c dtms specified in milli-seconds */
+void Periodic::SetIntervalms(int dtms)
+{
+if (dtms < 1) dtms = 5;
+mDtms = dtms;
+mDt = mDtms/1000;
+if (mDt < 1)  mDt = 1;
+}
+
+/* --Methode-- */
+/*! Activate the object */
+void Periodic::Start(int dt)
+{
+if (mFgact)  return;
+if (dt > 0)  { mDt = dt;  mDtms = dt*1000; }
+if (!actifs) actifs = new PeriodicList;
+it = 0;
+if (actifs->size() == 0) {
+  signal(SIGALRM, CallBack);
+  alarm(1);
+  }
+actifs->push_back(this);
+mFgact = true;
+return;
+}
+
+/* --Methode-- */
+/*! Deactivate the object */
+void Periodic::Stop()
+{
+if (!mFgact)  return;
+
+//remove(actifs->begin(), actifs->end(), this);  // $CHECK$ - Reza
+actifs->remove(this);    // $CHECK$ 
+if (actifs->size() == 0) {
+  signal(SIGALRM, SIG_IGN);
+  alarm(0);
+  delete actifs;
+  actifs = NULL;
+  }
+it = -1;  mFgact = false;
+return;
+}
+
+/* --Methode-- */
+/*! This method should be redefined for sub-classes of Periodic 
+  The default implementation calls the user action function */
+void Periodic::DoPeriodic()
+{
+if (mAct)   mAct(mUsp);
+}
+
+PeriodicList* Periodic::actifs = NULL;
+
+void Periodic::CallBack(int)
+{
+  if (!actifs) return;
+
+  for (PeriodicList::iterator i = actifs->begin(); i != actifs->end(); i++) {
+    Periodic* p = (Periodic*) *i;
+    p->it ++;
+    if (p->it >= p->mDt) {
+      p->it = 0;
+      p->DoPeriodic();
+    }
+  }
+  alarm(1);
+}
+
Index: /tags/V_Dec2002/SophyaLib/SysTools/periodic.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SysTools/periodic.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SysTools/periodic.h	(revision 2309)
@@ -0,0 +1,50 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe d'objets avec une methode (DoPeriodic()) appelee periodiquement 
+#ifndef PERIODIC_H
+#define PERIODIC_H
+
+#include "machdefs.h"
+#include <list>
+
+namespace SOPHYA {
+
+class Periodic;
+typedef list<Periodic*> PeriodicList;
+
+typedef void (* UsPeriodicAction) (void *);
+
+//! Class for the execution of a periodic action
+class Periodic 
+{
+public:
+  Periodic(int dt, UsPeriodicAction act=NULL, void * usp=NULL);
+  virtual ~Periodic();
+
+  void SetAction(UsPeriodicAction act, void * usp=NULL);
+
+  virtual void SetInterval(int dt);
+  virtual void SetIntervalms(int dtms);
+
+/*! Returns the time interval in seconds >= 1 sec */
+  inline int Interval() { return(mDt); }
+/*! Returns the time interval in milli-second */
+  inline int Intervalms() { return(mDtms); }
+
+  virtual void Start(int dt=-1);
+  virtual void Stop();
+
+  virtual void DoPeriodic();
+
+  static PeriodicList* actifs;
+  static void CallBack(int);
+
+protected:
+  int mDt, mDtms, it;
+  UsPeriodicAction mAct;
+  void * mUsp;
+  bool mFgact;
+};
+
+} // namespace SOPHYA
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/SysTools/psighand.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SysTools/psighand.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SysTools/psighand.cc	(revision 2309)
@@ -0,0 +1,154 @@
+//  Pour la gestion des signaux a travers des exceptions
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include "psighand.h"
+#include "pexceptions.h"
+
+static bool sigprstate[6] = {false, false, false, false, false, false};
+
+void SophyaProcessSignal(int s);
+
+/* Nouvelle-Fonction */
+/*!\ingroup  SysTools 
+   Configures signal handling. When the flag is true, an exception 
+   \b CaughtSignalExc is thrown with the excpetion id set to the 
+   signal id. With the flag is false, the default signal handling
+   is restored.
+   \param cfpe : Floating point exception \c SIGFPE
+   \param csegv : Segmentation fault \c SIGSEGV
+   \param cint : Interrupt signal \c SIGINT
+   \param cquit : Quit signal \c SIGINT
+   \param cusr1 : User signal 1 \c SIGUSR1
+   \param cusr2 : User signal 1 \c SIGUSR2
+*/
+void SOPHYA::SophyaConfigureSignalhandling(bool cfpe, bool csegv, bool cint, bool cquit, bool cusr1, bool cusr2) 
+{
+  struct sigaction ae, ad;
+
+  ae.sa_handler = SophyaProcessSignal;
+  ad.sa_handler = SIG_DFL;
+  memset( &(ae.sa_mask), 0, sizeof(sigset_t) ); 
+  ae.sa_flags = 0;
+  memset( &(ad.sa_mask), 0, sizeof(sigset_t) ); 
+  ad.sa_flags = 0;
+#ifdef  OSF1
+  ae.sa_flags = SA_RESTART;
+  ad.sa_mask = 0;
+#endif
+
+// SIGFPE 
+  if (sigprstate[0] != cfpe) {
+    if (cfpe)   { 
+      sigaction(SIGFPE, &ae, NULL);
+      puts("SophyaConfigureSignalhandling(): Activating SIGFPE handling (-> throw) ...");
+      }
+    else  { 
+      sigaction(SIGFPE, &ad, NULL);
+      puts("SophyaConfigureSignalhandling(): Back to default SIGFPE handling ...");
+      }
+    sigprstate[0] = cfpe;
+    }
+// SIGSEGV 
+  if (sigprstate[1] != csegv) {
+    if (csegv)   { 
+      sigaction(SIGSEGV, &ae, NULL);
+      puts("SophyaConfigureSignalhandling(): Activating SIGSEGV handling (-> throw) ...");
+      }
+    else  { 
+      sigaction(SIGSEGV, &ad, NULL);
+      puts("SophyaConfigureSignalhandling(): Back to default SIGSEGV handling ...");
+      }
+    sigprstate[1] = csegv;
+    }
+
+// SIGINT
+  if (sigprstate[2] != cint) {
+    if (cint)   { 
+      sigaction(SIGINT, &ae, NULL);
+      puts("SophyaConfigureSignalhandling(): Activating SIGINT handling (-> throw) ...");
+      }
+    else  { 
+      sigaction(SIGINT, &ad, NULL);
+      puts("SophyaConfigureSignalhandling(): Back to default SIGINT handling ...");
+      }
+    sigprstate[2] = cint; 
+    }
+  
+// SIGQUIT
+  if (sigprstate[3] != cquit) {
+    if (cquit)   { 
+      sigaction(SIGQUIT, &ae, NULL);
+      puts("SophyaConfigureSignalhandling(): Activating SIGQUIT handling (-> throw) ...");
+      }
+    else  { 
+      sigaction(SIGQUIT, &ad, NULL);
+      puts("SophyaConfigureSignalhandling(): Back to default SIGQUIT handling ...");
+      }
+    sigprstate[3] = cquit; 
+    }
+  
+// SIGUSR1
+  if (sigprstate[4] != cusr1) {
+    if (cusr1)   { 
+      sigaction(SIGUSR1, &ae, NULL);
+      puts("SophyaConfigureSignalhandling(): Activating SIGUSR1 handling (-> throw) ...");
+      }
+    else  { 
+      sigaction(SIGUSR1, &ad, NULL);
+      puts("SophyaConfigureSignalhandling(): Back to default SIGUSR1 handling ...");
+      }
+    sigprstate[4] = cusr1;
+    }
+// SIGUSR2
+  if (sigprstate[5] != cusr2) {
+    if (cusr2)   { 
+      sigaction(SIGUSR2, &ae, NULL);
+      puts("SophyaConfigureSignalhandling(): Activating SIGUSR2 handling (-> throw) ...");
+      }
+    else  { 
+      sigaction(SIGUSR2, &ad, NULL);
+      puts("SophyaConfigureSignalhandling(): Back to default SIGUSR2 handling ...");
+      }
+    sigprstate[5] = cusr2;
+    }    
+}
+/* Nouvelle-Fonction */
+void SophyaProcessSignal(int s)
+{
+string msg;
+switch(s)
+  {
+  case SIGFPE :
+    puts("SophyaProcessSignal: ###Signal SIGFPE catched, throw catchedSIGFPE ###");
+    msg = "Caught SIGFPE";
+    throw ( CaughtSignalExc(msg, s) );
+  case SIGSEGV :
+    puts("SophyaProcessSignal: ###Signal SIGSEGV catched, throw catchedSIGSEGV ###");
+    msg = "Caught SIGSEGV";
+    throw ( CaughtSignalExc(msg, s) );
+  case SIGINT :
+    puts("SophyaProcessSignal: ###Signal SIGINT catched, throw catchedSIGINT ###");
+    msg = "Caught SIGINT";
+    throw ( CaughtSignalExc(msg, s) );
+  case SIGQUIT :
+    puts("SophyaProcessSignal: ###Signal SIGQUIT catched, throw catchedSIGQUIT ###");
+    msg = "Caught SIGQUIT";
+    throw ( CaughtSignalExc(msg, s) );
+  case SIGUSR1 :
+    puts("SophyaProcessSignal: ###Signal SIGUSR1 catched, throw catchedSIGUSR1 ###");
+    msg = "Caught SIGUSR1";
+    throw ( CaughtSignalExc(msg, s) );
+  case SIGUSR2 :
+    puts("SophyaProcessSignal: ###Signal SIGUSR2 catched, throw catchedSIGUSR2 ###");
+    msg = "Caught SIGUSR2";
+    throw ( CaughtSignalExc(msg, s) );
+  default :
+    printf("SophyaProcessSignal: ###Signal %d catched, throw  inconsistentErr ### \n", s);
+    msg = "Caught SIG???";
+    throw ( CaughtSignalExc(msg, s) );
+  }
+
+// return;
+}
Index: /tags/V_Dec2002/SophyaLib/SysTools/psighand.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SysTools/psighand.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SysTools/psighand.h	(revision 2309)
@@ -0,0 +1,15 @@
+// This may look like C code, but it is really -*- C++ -*-
+//  Pour la gestion des signaux a travers des exceptions
+
+#ifndef SOPHYASIGHANDLE_SEEN
+#define SOPHYASIGHANDLE_SEEN
+
+#include "machdefs.h"
+
+namespace SOPHYA {
+void SophyaConfigureSignalhandling(bool cfpe=false, bool csegv=false, 
+                                   bool cint=false, bool cquit=false, 
+                                   bool cusr1=false, bool cusr2=false); 
+} // namespace SOPHYA
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/SysTools/resusage.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SysTools/resusage.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SysTools/resusage.cc	(revision 2309)
@@ -0,0 +1,199 @@
+#include "resusage.h"
+
+#include <typeinfo>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/resource.h>
+#include <unistd.h>
+#include <time.h>
+#include <fcntl.h>
+#include <fstream.h>
+#include <stdio.h>
+#include <string>
+/*!
+  \class SOPHYA::ResourceUsage
+  \ingroup SysTools
+  This class gives acces to various system resource usage 
+  (CPU, memory, ...).
+  All returned values are in kilobytes for memory consumptions
+  and in milli-seconds fo CPU and elapsed times.
+  The information should be updated through the call to the 
+  Update() method. 
+  Note: The information is obtained through \c getrusage()   
+  and \c getrlimit() system calls, and depending on the OS, 
+  not all of the memory usage values are correctly filled.
+  \code
+  // How to check resource usage for a given part of the program
+  ResourceUsage res;
+  // --- Part of the program to be checked : Start
+  // ...
+  res.Update();
+  cout << " Memory size increase (KB):" << res.getDeltaMemorySize() << endl;
+  cout << " Resource usage info : \n" << res << endl;
+  \endcode
+*/
+/*!
+  Constructor. the \b Update() method is called.
+*/
+ResourceUsage::ResourceUsage()
+{
+  struct rlimit rl;
+  getrlimit(RLIMIT_DATA, &rl);
+  max_datasz = rl.rlim_cur/1024;
+#if defined(SunOS)
+  // Max resident size ne semble pas etre defini sur SunOS
+  max_rss = max_datasz; 
+#else
+  getrlimit(RLIMIT_RSS, &rl);
+  max_rss = rl.rlim_cur/1024;
+#endif
+  getrlimit(RLIMIT_STACK, &rl);
+  max_stack = rl.rlim_cur/1024;
+#if defined(Linux)
+  // recuperation des limites sous Linux 
+  // car je ne comprends pas ce que renc=voie getrlimit
+  // OPerdereau LAL Orsay  11/2002
+  ReadLinuxTotMem();
+#endif
+
+  cur_datasz = 0;
+  cur_stack = 0; 
+  cur_rss = 0; 
+  delta_rss = 0; 
+  cur_tottm = 0;
+  cur_usrtm = 0;
+  cur_systm = 0;
+  elapsed_time = 0;
+  delta_rss = 0;
+  delta_tottm = 0;
+  delta_elapsed_time = 0;
+  cur_pid = getpid();
+  Update();
+  
+}
+/*!
+   Destructor.
+*/
+ResourceUsage::~ResourceUsage()
+{
+}
+
+inline uint_8 s_timeval2msec(struct timeval & tv)
+{ 
+  uint_8 ret = tv.tv_sec; ret *= 1000; 
+  ret += tv.tv_usec/1000; return(ret); 
+}
+
+/*!
+  Update the CPU and memory usage information.
+*/
+int ResourceUsage::Update()
+{
+  struct rusage rsu;
+  int rc = getrusage(RUSAGE_SELF, &rsu);
+  delta_tottm = cur_tottm;
+  delta_rss = cur_rss;
+  cur_usrtm = s_timeval2msec(rsu.ru_utime);
+  cur_systm = s_timeval2msec(rsu.ru_stime);
+  cur_tottm = cur_usrtm+cur_systm;
+  delta_tottm = cur_tottm-delta_tottm;
+
+#if defined(Linux)
+  // Recuperation de la place en memoire ss Linux 
+  ReadLinuxMem();
+#else
+  cur_rss = rsu.ru_maxrss;
+  cur_datasz = rsu.ru_idrss;
+  cur_stack = rsu.ru_isrss;
+#endif
+
+  delta_rss = cur_rss-delta_rss;
+  delta_elapsed_time = elapsed_time;
+  time_t tm = time(NULL);
+  if (elapsed_time == 0) t0_time = tm;
+  elapsed_time = (tm - t0_time)*1000;
+  if (elapsed_time < 1) elapsed_time = 1;
+  delta_elapsed_time = elapsed_time-delta_elapsed_time;
+  return(rc);
+}
+
+/*!
+   Prints the CPU and memory usage information.
+   \param os : The output stream
+   \param lp : The print level (0 .. 2)
+   \param upd : if \c true , the Update method is called.
+*/
+void ResourceUsage::Print(ostream& os, int lp, bool upd) 
+{
+  if (upd) Update();
+  os << " --------------- ResourceUsage::Print(lp=" << lp 
+     <<" ) --------------- " << endl;
+  int load = getAverageCPULoad()*100.;
+  os << " CPU-Usage= " << getCPUTime() << " Elapsed= " << getElapsedTime()
+     << " msec - Load= " << load << " %" << endl;
+  long fracmem = getMemorySize()*100/getMaxMemorySize();
+  os << " MemoryUsage= " << getMemorySize() << " /Max= " << getMaxMemorySize() 
+     << " kbytes (" << fracmem << " %)" << endl;
+  if (lp < 1) return;
+  os << " CPU-Usage= " << cur_tottm << "ms (usr,sys)=(" 
+     << cur_usrtm << "," << cur_systm << ")" << endl;
+  os << "  DataSize=" << cur_datasz << " /Max " << max_datasz 
+     << " kbytes" << endl;
+  os << " StackSize=" << cur_stack  << " /Max " << max_stack 
+     << " kbytes" << endl;
+  os << "   ResSize=" << cur_rss  << " /Max " << max_rss 
+     << " kbytes" << endl;
+}
+/*!
+     Recuperation de la place en memoire ss Linux 
+     ecrit d'apres les sources du code de top 
+     O. Perdereau LAL Orsay 11/2002
+
+*/  
+void ResourceUsage::ReadLinuxMem(){ 
+
+#if defined(Linux)
+
+  char flnm[120];
+  
+  sprintf(flnm,"/proc/%d/statm",(int)cur_pid);
+  ifstream fich(flnm) ;
+
+ 
+  long lia,lib,lic,lid,lie,lif,lig;
+  
+  fich >> lia >> lib >> lic >> lid >> lie >> lif >> lig ;
+
+  cur_rss = lia*4; // les valeurs sont en pages de 4 k 
+  cur_datasz = lib*4;
+  cur_stack = lic*4;
+
+#endif
+
+}
+
+
+/*! 
+   Recuperation de la memoire dispo ss Linux 
+   ecrit d'apres les sources du code de top 
+   O. Perdereau LAL Orsay 11/2002
+*/
+void ResourceUsage::ReadLinuxTotMem(){
+#if defined(Linux)
+
+  char flnm[]="/proc/meminfo";
+  char buff[512];
+  ifstream fich(flnm) ;
+
+  fich.getline(buff,200); // on saute une ligne 
+
+  string tst;
+  long lia,lib,lic,lid,lie,lif;
+  fich >> tst >> lia >> lib >> lic >> lid >> lie >> lif;
+
+  max_rss = lia/1024; // conversion  en kbytes  
+
+#endif
+
+}
Index: /tags/V_Dec2002/SophyaLib/SysTools/resusage.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SysTools/resusage.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SysTools/resusage.h	(revision 2309)
@@ -0,0 +1,116 @@
+// This may look like C code, but it is really -*- C++ -*-
+// permet d'obtenir des informations sur les ressources utilisees
+//                                R. Ansari - Juillet 2002
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef RESUSAGE_H_SEEN
+#define RESUSAGE_H_SEEN
+
+#include "machdefs.h"
+#include <iostream.h>
+
+namespace SOPHYA {
+
+//! Acces to information about resource usage (memory, CPU, ...)
+
+class ResourceUsage
+{
+public:
+  ResourceUsage();
+  ~ResourceUsage();
+
+  int Update();
+
+  // Process Id
+  //! Returns the process id.
+  inline uint_8 getProcessId() { return cur_pid; }
+
+  // Memory usage in kilo-bytes  
+  // NOTE: getDataSize() getStackSize() retournent des valeurs bizarres
+  //! Returns the current memory (Resident) size (in kilo-bytes) 
+  inline uint_8 getMemorySize() { return cur_rss; }
+  //! Returns the maximum allowed memory size: Min( \c MaxResidentSize , \c MaxDataSize ))
+  inline uint_8 getMaxMemorySize() 
+    { return((getMaxResidentSize()<getMaxDataSize()) ? 
+	     getMaxResidentSize() :getMaxDataSize() ); }
+  //! Returns the increase in memory usage since the previous call to \b Update()
+  inline uint_8 getDeltaMemorySize() { return delta_rss; }
+
+  //! Returns the maximum allowd data segment size (in kilo-bytes)
+  inline uint_8 getMaxDataSize() { return((max_datasz>0)?max_datasz:1024); }
+  //! Returns the current data segment size (in kilo-bytes)
+  inline uint_8 getDataSize() { return cur_datasz; }  
+  //! Returns the maximum allowed resident size (in kilo-bytes)
+  inline uint_8 getMaxResidentSize() { return((max_rss>0)?max_rss:1024); }
+  //! Returns the current resident memory size (in kilo-bytes)
+  inline uint_8 getResidentSize() { return cur_rss; }
+  //! Returns the maximum allowed stack size (in kilo-bytes)
+  inline uint_8 getMaxStackSize() { return max_stack; }
+  //! Returns the current stack size (in kilo-bytes)
+  inline uint_8 getStackSize() { return cur_stack; }
+
+  
+  // Time in milli-second
+  //! Returns the total CPU time used (in milli-second)
+  inline uint_8 getCPUTime() { return cur_tottm; }
+  //! Returns the total elapsed time (in milli-second)
+  inline uint_8 getElapsedTime() { return elapsed_time; }
+  //! Returns the average load ( CPU time / elapsed time)
+  inline double  getAverageCPULoad() 
+    { return ((elapsed_time>1) ? (double)cur_tottm/(double)elapsed_time: 1.);}
+
+  //! Returns the CPU time used since the previous call to \b Update() (in milli-second)
+  inline uint_8 getDeltaCPUTime() { return delta_tottm; }
+  //! Returns the elapsed time since the previous call to \b Update() (in milli-second)
+  inline uint_8 getDeltaElapsedTime() { return delta_elapsed_time; }
+  //! Returns the CPU load since the previous call to \b Update()
+  inline double  getCPULoad() 
+    { return ((delta_elapsed_time>1) ? (double)delta_tottm/(double)delta_elapsed_time: 1.);}
+
+
+  //! Returns the total CPU time (in milli-second)
+  inline uint_8 getTotalCPUTime() { return cur_tottm; }
+  //! Returns the CPU time in user mode (in milli-second)
+  inline uint_8 getUserCPUTime() { return cur_usrtm; }
+  //! Returns the CPU time in system mode (in milli-second)
+  inline uint_8 getSysCPUTime() { return cur_systm; }
+
+
+  void  Print(ostream& os, int lp=0, bool upd=true);
+  //! Alias for the \b Print() method. 
+  inline void print(ostream& os, int lp=0, bool upd=true){ Print(os,lp,upd); }
+
+  void ReadLinuxMem();    // methode de lecture des infos memoire ss Linux - OPerdereau 
+  void ReadLinuxTotMem(); // methode de lecture des infos memoire ss Linux - OPerdereau 
+
+protected:
+  uint_8 max_datasz;  // Max data segment size (KBytes)
+  uint_8 max_rss;     // Max resident size
+  uint_8 max_stack;   // Max stack size
+
+  uint_8 cur_datasz;  // Current data segment size
+  uint_8 cur_rss;     // Current resident size
+  uint_8 cur_stack;   // Current stack size
+
+  uint_8 cur_tottm;   // Current total CPU-Time - in milli-second
+  uint_8 cur_usrtm;   // Current user CPU-Time - in milli-second 
+  uint_8 cur_systm;   // Current system CPU-Time - in milli-second 
+  uint_8 elapsed_time; // Elapsed time - in milli-second
+  uint_8 t0_time;      // time T0 in seconds 
+
+  // Delta_values : difference since last call to Update()
+  uint_8 delta_rss;     // Max resident size
+  uint_8 delta_tottm;   // Delta total CPU-Time - in milli-second
+ 
+  uint_8 delta_elapsed_time; // Elapsed time - in milli-second
+  uint_8 cur_pid ;          // process PID 
+};
+
+//! Prints the resource usage information on the output stream 
+inline ostream& operator << (ostream& os, ResourceUsage& ru)
+{ ru.Print(os,0,true); return(os); }
+
+} // namespace SOPHYA
+
+#endif
+
Index: /tags/V_Dec2002/SophyaLib/SysTools/systools.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SysTools/systools.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SysTools/systools.h	(revision 2309)
@@ -0,0 +1,18 @@
+#ifndef SYSTOOLS_H
+#define SYSTOOLS_H
+
+/*!
+   \defgroup SysTools SysTools module
+   This module contains interface to various services provided
+   by the operating system.
+*/
+
+#include "ctimer.h"
+#include "timing.h"
+#include "pdlmgr.h"
+#include "cxxcmplnk.h"
+#include "periodic.h"
+#include "psighand.h"
+#include "resusage.h"
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/SysTools/timing.c
===================================================================
--- /tags/V_Dec2002/SophyaLib/SysTools/timing.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SysTools/timing.c	(revision 2309)
@@ -0,0 +1,79 @@
+/*    Fonction d'impression de temps de calcul et de temps passe  */
+/*                               R.Ansari    Juin 93              */
+
+/*
+++
+  Module	Temps CPU, passé (C)
+  Lib	LibsUtil
+  include	timing.h
+
+	Fonctions permettant d'imprimer le temps CPU consommé et le temps 
+	passé.
+--
+*/ 
+
+/*
+++
+  void InitTim()
+	Initialisation des chronomètres
+  void PrtTim(char *comm)
+	Imprime le temps CPU, et le temps passé depuis 
+	le dernier appel à "PrtTim()" avec le commentaire
+	"comm". Imprime aussi le cumul du temps CPU et du 
+	temps passé depuis l'appel à "InitTim()".
+--
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+
+#include "timing.h"
+
+static clock_t CPUT0, CPUT;
+static time_t ELT0, ELT;
+ 
+ 
+/* Nouvelle-Fonction */
+/*!
+   \ingroup SysTools
+   Initializes CPU and elapsed time timer (C function).
+   The values of the CPU and elapsed time can then be printed 
+   using \b PrtTim() 
+*/
+void InitTim(void)
+{
+CPUT0 = CPUT = clock();
+ELT0 = ELT = time(NULL);
+return;
+}
+ 
+/* Nouvelle-Fonction */
+/*!
+   \ingroup SysTools
+   Prints the values of the CPU and elapsed time, since call to \b InitTim().
+*/
+void PrtTim(const char * Comm)
+{
+float tcal,tcalt;
+clock_t cput;
+time_t elt;
+int etm,etmt;
+ 
+elt = time(NULL);  cput = clock();
+tcalt = ( (float)(cput) - (float)(CPUT0) ) / (float)(CLOCKS_PER_SEC);
+tcal = ( (float)(cput) - (float)(CPUT) ) / (float)(CLOCKS_PER_SEC);
+etm = elt - ELT;
+etmt = elt - ELT0;
+printf("%s CPUTime: Total= %g  (Partial= %g) Sec. \n",
+       Comm, tcalt, tcal);
+printf("ElapsedTime(hh:mm:ss): Total= %02d:%02d:%02d ",
+       etmt/3600, (etmt%3600)/60, etmt%60);
+printf(" (Partial= %02d:%02d:%02d)\n",
+       etm/3600, (etm%3600)/60, etm%60);
+ 
+ELT = elt;
+CPUT = cput;
+return;
+}
Index: /tags/V_Dec2002/SophyaLib/SysTools/timing.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SysTools/timing.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SysTools/timing.h	(revision 2309)
@@ -0,0 +1,19 @@
+/*   Impression temps elapsed / Temps CPU     */
+/*                           Reza  -  93/94   */
+
+#ifndef TIMING_H_SEEN
+#define TIMING_H_SEEN
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void InitTim(void);                                                             
+void PrtTim(const char * Comm);                                                        
+                                                                                
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Index: /tags/V_Dec2002/SophyaLib/SysTools/zthread.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/SysTools/zthread.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SysTools/zthread.cc	(revision 2309)
@@ -0,0 +1,171 @@
+// Interface C++ aux Thread POSIX  -   R. Ansari 02/2001
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "zthread.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+/*!
+  \class SOPHYA::ZThread
+  \ingroup SysTools
+  This class provides an interface for creating and controlling threads.
+  The implementation uses the POSIX thread interface.
+  The ZThread objects can be sub classed with the redefinition of 
+  the \c run() method which then performs the task.
+  The default \c run() method of the base class can be used directly
+  to perform computation through a function (see \b setAction() method)
+  \sa SOPHYA::ZMutex
+  The following sample code shows the usage of ZThread object 
+  to run simultaneously to functions to perform computation.
+
+  \code
+  // The functions to perform computing
+  void fun1(void *arg) { }
+  void fun2(void *arg) { }
+  // ...
+  ZThread zt1;
+  zt1.setAction(fun1, arg[1]);
+  ZThread zt2;
+  zt2.setAction(fun2, arg[1]);
+  cout << " Starting threads ... " << endl;
+  zt1.start();
+  zt2.start();
+  cout << " Waiting for threads to end ... " << endl;  
+  zt1.join();
+  zt2.join();
+  \endcode
+*/
+
+#define CheckSt(st_, strg_)  if (st_ != 0)  perror(strg_); 
+
+/*
+extern "C" {
+  void * zthr_run( void * xthr);
+}
+*/
+
+static void * zthr_run(void * xthr)
+{
+  ZThread * thr = (ZThread *)xthr;
+  thr->run();
+  pthread_exit(NULL);
+  return NULL;
+}
+
+
+/* ------ Classe ZThread  -------  */
+/*!
+  Constructor, with optional specification of the thread stack size.
+*/
+ZThread::ZThread(size_t stacksize)
+{
+  _initok = false;
+  _ssize = 0;
+  _act = NULL;
+  _usp = NULL;
+  _rc = -99;
+}
+
+ZThread::~ZThread()
+{
+  // Que faut-il faire ?
+}
+
+/*!
+  Method which starts the thread.
+*/
+void ZThread::start()
+{
+  if (_initok) throw ZThreadExc("ZThread::Start() - Already started thread !");
+  int rc;
+  pthread_attr_t tha;
+  rc = pthread_attr_init(&tha);
+  CheckSt(rc,"ZThread::start() - Pb creating tha attribute object");
+  if (_ssize > 0) 
+    rc = pthread_attr_setstacksize(&tha, _ssize);
+  rc = pthread_create(&_thr, &tha, zthr_run, this);
+  CheckSt(rc,"ZThread::start() - Pb creating the thread object");     
+  _initok = true;
+  setRC(rc);      
+}
+
+/*!
+  Calls the pthread_cancel. Can be used to stop a running thread.
+*/
+void ZThread::cancel()
+{
+  if (!_initok) throw ZThreadExc("ZThread::cancel() - thread not started !");
+  int rc = pthread_cancel(_thr);
+  CheckSt(rc,"ZThread::cancel() - Pb pthread_cancel() ");  
+  setRC(-77);      
+}
+
+
+/*!
+  Waits for the thread to terminate. 
+*/
+void ZThread::join()
+{
+  if (!_initok) throw ZThreadExc("ZThread::join() - thread not started !");
+  void * x;
+  int rc = pthread_join(_thr, &x);
+  CheckSt(rc,"ZThread::Join() - Pb pthread_join() ");
+  return;  
+}
+
+/*!
+  This virtual method can be redefined in the derived class, in order 
+  to perform the actual computation.
+*/
+void ZThread::run()
+{
+  if (_act)  _act(_usp);
+  setRC(0);      
+  return;
+}
+
+
+/* ------ Classe ZMutex -------  */
+/*!
+  \class SOPHYA::ZMutex
+  \ingroup SysTools
+  This class implements an interface to the Mutual Exclusion objects
+  of the POSIX threads. 
+  The ZMutex objects should be used to control acces from different threads 
+  to common objects through the \b lock() and \b unlock() methods.  
+  \sa SOPHYA::ZSync
+*/
+
+/*!
+  Constructor: Creates a associated pair of POSIX \c pthread_mutex_t 
+  and \c pthread_cond_t objects
+*/
+ZMutex::ZMutex()
+{
+  _mutx = new pthread_mutex_t;
+  _condv = new pthread_cond_t;
+  int rc;
+  rc = pthread_mutex_init(_mutx, NULL);
+  CheckSt(rc,"ZMutex::ZMutex() Pb pthread_mutex_init");
+  rc = pthread_cond_init(_condv, NULL);
+  CheckSt(rc,"ZMutex::ZMutex() Pb pthread_cond_init");
+}
+
+ZMutex::~ZMutex()
+{
+  delete _mutx;
+  delete _condv;
+}
+
+/*!
+  \class SOPHYA::ZSync
+  \ingroup SysTools
+  This class can be used to insure that the execution of a given 
+  part of the code is synchronised, i.e. only a single thread 
+  goes through this at a given time.
+  The constructor acquires a lock on given \b ZMutex object,
+  which is released by the destructor.
+  The ZSync object should then be instanciated at the beginning of 
+  the synchronised instruction bloc.
+  \sa SOPHYA::ZMutex
+*/
Index: /tags/V_Dec2002/SophyaLib/SysTools/zthread.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/SysTools/zthread.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/SysTools/zthread.h	(revision 2309)
@@ -0,0 +1,106 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Interface C++ aux Thread POSIX  -   R. Ansari 02/2001
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef ZTHREAD_SEEN
+#define ZTHREAD_SEEN
+
+#include "machdefs.h"
+#include <pthread.h>
+#include "pexceptions.h"
+
+
+namespace SOPHYA {
+
+typedef void (* ZThreadAction) (void *);
+
+/*!
+  \class SOPHYA::ZThreadExc
+  \ingroup SysTools
+  This exception class is used by the classes implementing the interface 
+  to the POSIX threads (\b ZThread ...)
+*/  
+class ZThreadExc : public PException {
+public:
+  explicit ZThreadExc(const string& m, int id=0) : PException(m,id) {}
+};
+
+class ZThread {
+public:
+  explicit	ZThread(size_t stacksize=0);
+  virtual	~ZThread();
+  void		start();
+  void		cancel();
+  inline void   stop() { cancel(); }
+
+  void          join();
+  virtual void  run();
+
+  //! Sets the return code for the thread object
+  inline void   setRC(int rc) { _rc = rc; }
+  //! Return the value of the return code for the thread object
+  inline int    getRC(int rc) { return(_rc);
+ }
+  inline void	setAction(ZThreadAction act, void * usp=NULL)
+       {  _act = act;  _usp = usp; }
+
+
+  static inline void setCancelState(int st= PTHREAD_CANCEL_ENABLE) 
+       { int ocs; pthread_setcancelstate(st, &ocs); }
+  // PTHREAD_CANCEL_ENABLE  ou PTHREAD_CANCEL_DISABLE
+  static inline void setCancelType(int ct= PTHREAD_CANCEL_DEFERRED) 
+       { int oct; pthread_setcanceltype(ct, &oct); }
+  // PTHREAD_CANCEL_DEFERRED  ou  PTHREAD_CANCEL_ASYNCHRONOUS
+
+
+  // ---- Attribute variables ----
+  pthread_t _thr;
+  size_t _ssize;
+  int _rc;
+  bool _initok;
+
+  ZThreadAction _act;
+  void * _usp;
+};
+
+
+class ZMutex {
+public:
+  explicit	ZMutex();
+  virtual	~ZMutex();
+  //! Locks the mutex object
+  inline void	lock()
+    { pthread_mutex_lock(_mutx); } 
+  //! Unlocks the mutex object
+  inline void	unlock()
+    { pthread_mutex_unlock(_mutx); }
+  //! Waits for a condition change
+  inline void	wait()
+    { pthread_cond_wait(_condv, _mutx); }
+  //! Signal a condition change on the mutex object
+  inline void	signal()
+  { pthread_cond_signal(_condv); }
+  //! Broadcasts a condition change on the mutex object
+  inline void	broadcast()
+  { pthread_cond_broadcast(_condv); }
+
+  // Attributes
+  pthread_mutex_t * _mutx;
+  pthread_cond_t * _condv;
+};
+
+
+class ZSync {
+public:
+  explicit inline  ZSync(ZMutex & mtx) {_mtx = &mtx; mtx.lock(); }
+  inline	   ~ZSync() { if (_mtx) _mtx->unlock(); }
+
+private:
+  ZMutex * _mtx;
+  inline	ZSync() {_mtx = NULL; }
+
+};
+
+} // namespace SOPHYA
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/TArray/Makefile
===================================================================
--- /tags/V_Dec2002/SophyaLib/TArray/Makefile	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/TArray/Makefile	(revision 2309)
@@ -0,0 +1,110 @@
+include ../Mgr/Makefile.h
+ 
+all: $(LIB)libTArray.a
+clean:
+	rm -f $(OBJ)basarr.o $(OBJ)fioarr.o $(OBJ)matharr.o $(OBJ)sopemtx.o $(OBJ)tarray.o $(OBJ)tarrinit.o $(OBJ)tmatrix.o $(OBJ)toeplitzMatrix.o $(OBJ)tvector.o $(OBJ)utilarr.o
+	rm -f $(LIB)libTArray.a
+$(LIB)libTArray.a : $(OBJ)basarr.o $(OBJ)fioarr.o $(OBJ)matharr.o $(OBJ)sopemtx.o $(OBJ)tarray.o $(OBJ)tarrinit.o $(OBJ)tmatrix.o $(OBJ)toeplitzMatrix.o $(OBJ)tvector.o $(OBJ)utilarr.o
+	$(ARCXX) $(ARCXXFLAGS) $@ $($(ARARGS))
+ifeq ($(CXX),cxx)
+	$(CXX) $? $(CPPFLAGS) $(CXXFLAGS) -o $(OBJ)xx.x -Hf
+endif 
+ 
+$(OBJ)basarr.o: basarr.cc $(INC)machdefs.h \
+ $(INC)pexceptions.h basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h
+$(OBJ)fioarr.o: fioarr.cc $(INC)pexceptions.h \
+ $(INC)machdefs.h \
+ $(INC)fiondblock.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)anydataobj.h fioarr.h tarray.h \
+ basarr.h $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h utilarr.h tmatrix.h tvector.h
+$(OBJ)matharr.o: matharr.cc $(INC)machdefs.h \
+ matharr.h tarray.h basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h utilarr.h
+$(OBJ)sopemtx.o: sopemtx.cc $(INC)machdefs.h \
+ sopemtx.h tmatrix.h tarray.h basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h utilarr.h tvector.h \
+ $(INC)smathconst.h
+$(OBJ)tarray.o: tarray.cc $(INC)machdefs.h \
+ $(INC)pexceptions.h tarray.h basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h utilarr.h
+$(OBJ)tarrinit.o: tarrinit.cc $(INC)machdefs.h \
+ tarrinit.h $(INC)sophyainit.h fioarr.h \
+ tarray.h basarr.h $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h utilarr.h tmatrix.h \
+ tvector.h
+$(OBJ)tmatrix.o: tmatrix.cc $(INC)machdefs.h \
+ $(INC)pexceptions.h tmatrix.h tarray.h \
+ basarr.h $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h utilarr.h
+$(OBJ)toeplitzMatrix.o: toeplitzMatrix.cc toeplitzMatrix.h \
+ $(INC)machdefs.h \
+ $(INC)nbmath.h \
+ $(INC)smathconst.h \
+ $(INC)timing.h array.h tarray.h basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h utilarr.h tmatrix.h \
+ tvector.h matharr.h fioarr.h sopemtx.h \
+ $(INC)fftservintf.h \
+ $(INC)tmatrix.h \
+ $(INC)tvector.h \
+ $(INC)fftpserver.h
+$(OBJ)tvector.o: tvector.cc $(INC)machdefs.h \
+ $(INC)pexceptions.h tvector.h tmatrix.h \
+ tarray.h basarr.h $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h utilarr.h
+$(OBJ)utilarr.o: utilarr.cc $(INC)machdefs.h \
+ utilarr.h $(INC)mutyv.h \
+ $(INC)srandgen.h
Index: /tags/V_Dec2002/SophyaLib/TArray/Makefile.am
===================================================================
--- /tags/V_Dec2002/SophyaLib/TArray/Makefile.am	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/TArray/Makefile.am	(revision 2309)
@@ -0,0 +1,8 @@
+lib_LIBRARIES = libTArray.a
+
+libTArray_a_SOURCES = \
+basarr.cc  matharr.cc  tarray.cc    tmatrix.cc  utilarr.cc \
+fioarr.cc  sopemtx.cc  tarrinit.cc  tvector.cc
+
+
+DEFS = -I.. -I../include
Index: /tags/V_Dec2002/SophyaLib/TArray/array.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/TArray/array.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/TArray/array.h	(revision 2309)
@@ -0,0 +1,15 @@
+// This may look like C code, but it is really -*- C++ -*-
+//  All the necessari include files for array manipulation
+//                     R. Ansari, C.Magneville   03/2000
+
+#ifndef AllTArray_SEEN
+#define AllTArray_SEEN
+
+#include "tarray.h"
+#include "tmatrix.h"
+#include "tvector.h"
+#include "matharr.h"
+#include "fioarr.h"
+#include "sopemtx.h"
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/TArray/basarr.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/TArray/basarr.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/TArray/basarr.cc	(revision 2309)
@@ -0,0 +1,700 @@
+//      Base class for numerical arrays 
+//                     R. Ansari, C.Magneville   03/2000
+
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "pexceptions.h"
+#include "basarr.h"
+
+/*!
+  \class SOPHYA::BaseArray
+  \ingroup TArray
+  Base class for template arrays with number of dimensions up to 
+  \ref BASEARRAY_MAXNDIMS "BASEARRAY_MAXNDIMS".
+  This class is an abstract class and has no data connected to it.
+  
+  Define base methods, enum and defaults for TArray , TMatrix and TVector.
+  BaseArray objects can be used in particular for performing operations on 
+  arrays with unknown data types, or between arrays with different data types.
+*/
+
+// Variables statiques globales
+char * BaseArray::ck_op_msg_[6] =
+     {"???", "Size(int )", "IsPacked(int )"
+     ,"Stride(int )", "ElemCheckBound()", "operator()" };
+sa_size_t BaseArray::max_nprt_ = 50;
+int_4  BaseArray::prt_lev_ = 0;
+short  BaseArray::default_memory_mapping = CMemoryMapping;
+short  BaseArray::default_vector_type = ColumnVector;
+sa_size_t BaseArray::openmp_size_threshold = 200000;
+
+// ------ Methodes statiques globales --------
+
+//! Set maximum number of printed elements and print level
+/*!
+  \param nprt : maximum number of print
+  \param lev  : print level
+*/
+void BaseArray::SetMaxPrint(sa_size_t nprt, int_4 lev)
+{
+  max_nprt_ = nprt;
+  prt_lev_ = (lev < 3) ? lev : 3;
+}
+
+//! Set Size threshold for parallel routine call
+/*!
+  \param thr : thresold value
+*/
+void BaseArray::SetOpenMPSizeThreshold(sa_size_t thr)
+{
+  openmp_size_threshold = thr;
+}
+
+
+//! Compute totale size
+/*!
+  \param ndim : number of dimensions
+  \param siz : array of size along the \b ndim dimensions
+  \param step[ndim] : step value
+  \param offset : offset value
+  \return Total size of the array
+*/
+sa_size_t BaseArray::ComputeTotalSize(int_4 ndim, const sa_size_t * siz, sa_size_t step, sa_size_t offset)
+{
+  sa_size_t rs = step;
+  for(sa_size_t k=0; k<ndim; k++) rs *= siz[k];
+  return(rs+offset);
+}
+
+//! Set Default Memory Mapping
+/*!
+  \param mm : Memory Mapping type
+  \verbatim
+     mm == CMemoryMapping : C like memory mapping
+     mm == FortranMemoryMapping : Fortran like memory mapping
+  \endverbatim
+  \verbatim
+  # ===== For Matrices
+  *** MATHEMATICS:   m(row,column) with indexes running [1,n])
+                          | 11 12 13 |
+     matrix Math = Mmath= | 21 22 23 |
+                          | 31 32 33 |
+  *** IDL, \b FORTRAN: indexes data in \b row-major format:
+     indexes arrays in (column,row) order.
+     index IDL running [0,n[ ; index FORTRAN running [1,n]
+     M in memory: [ 11 12 13 : 21 22 23 : 31 32 33 : ... ]
+                     line 1  : line 2   : line 3  : ...
+     ex: Midl(0,2) = Mfor(1,3) = Mmath(3,1) = 31
+         Midl(2,0) = Mfor(3,1) = Mmath(1,3) = 13
+  *** C: indexes data in \b column-major format:
+     indexes arrays in [row][column] order.
+     index C running [0,n[
+     M in memory: [ 11 21 31 : 12 22 32 : 13 23 33 : ... ]
+                    column 1 : column 2 : column 3 : ...
+     ex: Mc[2][0] = Mmath(3,1) = 31
+         Mc[0][2] = Mmath(1,3) = 13
+  *** RESUME diff Idl/Fortan/C/Math:
+    Midl(col-1,row-1) = Mfor(col,row) = Mc[row-1][col-1] = Mmath(row,col)
+    TRANSPOSE(column-major array) --> row-major array
+  \endverbatim
+  \return default memory mapping value
+ */
+short BaseArray::SetDefaultMemoryMapping(short mm)
+{
+  default_memory_mapping = (mm != CMemoryMapping) ? FortranMemoryMapping : CMemoryMapping; 
+  return default_memory_mapping;
+}
+
+//! Set Default Vector Type
+/*!
+  \param vt : vector type (ColumnVector,RowVector)
+  \return default vector type value
+ */
+short BaseArray::SetDefaultVectorType(short vt)
+{
+  default_vector_type = (vt != ColumnVector) ? RowVector : ColumnVector ; 
+  return default_vector_type;
+}
+
+//! Select Memory Mapping
+/*!
+  Do essentially nothing.
+  \param mm : type of Memory Mapping (CMemoryMapping,FortranMemoryMapping)
+  \return return \b mm if it makes sense or default memory mapping value
+  \sa SetDefaultMemoryMapping
+ */
+short BaseArray::SelectMemoryMapping(short mm)
+{
+  if ( (mm == CMemoryMapping) || (mm == FortranMemoryMapping) )  return (mm) ; 
+  else return (default_memory_mapping);
+}
+
+//! Select Vector type
+/*!
+  Do essentially nothing.
+  \param vt : vector type (ColumnVector,RowVector)
+  \return return \b vt if it makes sense or default vector type
+  \sa SetDefaultVectorType
+ */
+short BaseArray::SelectVectorType(short vt)
+{
+  if ((vt == ColumnVector) || (vt == RowVector))  return(vt);
+  else return(default_vector_type);
+}
+
+//! Update Memory Mapping
+/*!
+  Update variables marowi_ macoli_ veceli_
+  \param mm : type of Memory Mapping (CMemoryMapping,FortranMemoryMapping)
+  \sa SetDefaultMemoryMapping
+ */
+void BaseArray::UpdateMemoryMapping(short mm)
+{
+  short vt = default_vector_type;
+  if ( (mm != CMemoryMapping) && (mm != FortranMemoryMapping) ) mm = default_memory_mapping;
+  if (mm == CMemoryMapping) {
+    marowi_  = 1;  macoli_ = 0;
+  }
+  else {
+    marowi_ = 0;  macoli_ = 1;
+  }
+
+  if ( (ndim_ == 2) && ((size_[0] == 1) || (size_[1] == 1)) ) {
+    // Choix automatique Vecteur ligne ou colonne
+    if ( size_[macoli_] == 1)  veceli_ = marowi_;
+    else veceli_ = macoli_;
+  }
+  else veceli_ = (vt ==  ColumnVector ) ?  marowi_ : macoli_;
+}
+
+//! Update Memory Mapping
+/*!
+  \param a  : Array to be compared with
+  \param mm : type of Memory Mapping or memory mapping transfert
+       (SameMemoryMapping,AutoMemoryMapping,CMemoryMapping,FortranMemoryMapping)
+  \sa SetDefaultMemoryMapping
+ */
+void BaseArray::UpdateMemoryMapping(BaseArray const & a, short mm)
+{
+  short vt = default_vector_type;
+  if (mm == SameMemoryMapping) {
+    mm = ((a.marowi_ == 1) ? CMemoryMapping : FortranMemoryMapping);
+    vt = (a.marowi_ == a.veceli_) ? ColumnVector : RowVector;
+  }
+  else if (mm == AutoMemoryMapping)   mm = default_memory_mapping;
+
+  if ( (mm != CMemoryMapping) && (mm != FortranMemoryMapping) ) mm = default_memory_mapping;
+  if (mm == CMemoryMapping) {
+    marowi_  = 1;  macoli_ = 0;
+  }
+  else {
+    marowi_ = 0;  macoli_ = 1;
+  }
+  if ( (ndim_ == 2) && ((size_[0] == 1) || (size_[1] == 1)) ) {
+    // Choix automatique Vecteur ligne ou colonne
+    if ( size_[macoli_] == 1)  veceli_ = marowi_;
+    else veceli_ = macoli_;
+  }
+  else veceli_ = (vt ==  ColumnVector ) ?  marowi_ : macoli_;
+}
+
+//! Set Memory Mapping type
+/*!
+  Compute values for variables marowi_ macoli_ veceli_
+  \param mm : Memory Mapping type (SameMemoryMapping,AutoMemoryMapping
+                                  ,CMemoryMapping,FortranMemoryMapping)
+  \sa SetDefaultMemoryMapping
+ */
+void BaseArray::SetMemoryMapping(short mm)
+{
+  if (mm == SameMemoryMapping) mm = GetMemoryMapping();
+  else if (mm == AutoMemoryMapping)  mm = default_memory_mapping;
+  if ( (mm != CMemoryMapping) && (mm != FortranMemoryMapping) ) mm = CMemoryMapping;
+  short vt = GetVectorType(); 
+  if (mm == CMemoryMapping) {
+    marowi_ =  1;  macoli_ = 0;
+  }
+  else {
+    marowi_ =  0;  macoli_ = 1;
+  }
+  if ( (ndim_ == 2) && ((size_[0] == 1) || (size_[1] == 1)) 
+       && (size_[0] != size_[1]) ) {
+    // Choix automatique Vecteur ligne ou colonne
+    if ( size_[macoli_] == 1)  veceli_ = marowi_;
+    else veceli_ = macoli_;
+  }
+  else  veceli_ = (vt ==  ColumnVector ) ?  marowi_ : macoli_;
+}
+
+//! Set Vector Type
+/*!
+  Compute values for variable veceli_
+  \param vt : vector type ()
+  \sa SetDefaultVectorType
+ */
+void BaseArray::SetVectorType(short vt)
+{
+  if (vt == SameVectorType) return;
+  if (vt == AutoVectorType) vt =  default_vector_type;
+  if ( (ndim_ == 2) && ((size_[0] == 1) || (size_[1] == 1)) ) {
+    // Choix automatique Vecteur ligne ou colonne
+    if ( size_[macoli_] == 1)  veceli_ = marowi_;
+    else veceli_ = macoli_;
+  }
+  else  veceli_ = (vt ==  ColumnVector ) ?  marowi_ : macoli_;
+}
+
+// -------------------------------------------------------
+//                Methodes de la classe
+// -------------------------------------------------------
+
+//! Default constructor
+BaseArray::BaseArray()
+  : mInfo(NULL)
+{
+  ndim_ = 0;
+  for(int_4 k=0; k<BASEARRAY_MAXNDIMS; k++) step_[k] = size_[k] = 0;
+  totsize_ = 0;
+  minstep_ = 0;
+  moystep_ = 0;
+  offset_ = 0;
+  // Default for matrices : Memory organisation and Vector type 
+  if (default_memory_mapping == CMemoryMapping) {
+    marowi_ =  1;  macoli_ = 0;
+  }
+  else {
+    marowi_ =  0;  macoli_ = 1;
+  }
+  veceli_ = (default_vector_type ==  ColumnVector ) ?  marowi_ : macoli_;
+  arrtype_ = 0;    // Default Array type, not a Matrix or Vector
+  
+}
+
+//! Destructor 
+BaseArray::~BaseArray()
+{
+}
+
+
+//! Returns true if the two arrays have compatible dimensions.
+/*!
+  \param a : array to be compared
+  \param smo : Return flag = true if the two arrays have the same memory organisation
+  \return true if \c NbDimensions() and \c Size() are equal, false if not
+
+  If the array (on which the operation is being performed, \c this) 
+  is a \b Matrix or a \b Vector, the matrix dimensions \c NRows() \c NCols()
+  are checked. The flag \c smo is returned true if the two arrays, viewed 
+  as a matrix have the same memory organisation.
+  Otherwise, (if the array is of not a Matrix or a Vector) 
+  the size compatibility viewed as a TArray is checked <tt> 
+  (Size(k) == a.Size(k), k=0,...NbDimensions()), </tt> disregard of the memory 
+  organisation and the row and column index. The flag \c smo is returned true 
+  in this case.
+*/
+bool BaseArray::CompareSizes(const BaseArray& a, bool& smo) const
+{
+  if (ndim_ != a.ndim_)  return(false);
+  if (arrtype_ == 0) {  // Simple TArray, not a matrix 
+    smo = true;
+    for(int_4 k=0; k<ndim_; k++) 
+      if (size_[k] != a.size_[k])  return(false);
+    return(true);
+  }
+  else {
+    smo = false;
+    if ( (size_[marowi_] != a.size_[a.marowi_]) || 
+	 (size_[macoli_] != a.size_[a.macoli_])  ) return(false);
+    if (ndim_ > 2)  
+      for(int_4 k=2; k<ndim_; k++) 
+	if (size_[k] != a.size_[k])  return(false);
+    if ( (macoli_ == a.macoli_) && (marowi_ == a.marowi_) ||
+         (veceli_ == a.veceli_) )  smo = true;
+    return(true);
+  }
+}
+
+//! Change dimension if some size == 1
+void BaseArray::CompactAllDim()
+{
+  if (ndim_ < 2)  return;
+  int_4 ndim = 0;
+  sa_size_t size[BASEARRAY_MAXNDIMS];
+  sa_size_t step[BASEARRAY_MAXNDIMS];
+  for(int_4 k=0; k<ndim_; k++) {
+    if (size_[k] < 2)  continue;
+    size[ndim] = size_[k];
+    step[ndim] = step_[k];
+    ndim++;
+  }
+  if (ndim == 0)  {
+    size[0] = size_[0];
+    step[0] = step_[0];
+    ndim = 1;
+  }
+  string exmsg = "BaseArray::CompactAllDim() ";
+  if (!UpdateSizes(ndim, size, step, offset_, exmsg))  throw( ParmError(exmsg) );
+  return;
+}
+
+//! Change dimension if some trailed size == 1
+void BaseArray::CompactTrailingDim()
+{
+  if (ndim_ < 2)  return;
+  int_4 ndim = 0;
+  sa_size_t size[BASEARRAY_MAXNDIMS];
+  sa_size_t step[BASEARRAY_MAXNDIMS];
+  for(int_4 k=0; k<ndim_; k++) {
+    size[ndim] = size_[k];
+    step[ndim] = step_[k];
+    if (size_[k] > 1)  ndim=k;
+  }
+  if (ndim == 0)  ndim = 1;
+  string exmsg = "BaseArray::CompactTrailingDim() ";
+  if (!UpdateSizes(ndim, size, step, offset_, exmsg))  throw( ParmError(exmsg) );
+  return;
+}
+
+//! return minimum value for step[ndim]
+int_4  BaseArray::MinStepKA() const
+{
+  for(int_4 ka=0; ka<ndim_; ka++)
+    if (step_[ka] == minstep_) return((int)ka);
+  return(0);
+}
+
+//! return maximum value for step[ndim]
+int_4  BaseArray::MaxSizeKA() const
+{
+  int_4 ka = 0;
+  sa_size_t mx = size_[0];
+  for(int_4 k=1; k<ndim_; k++)  
+    if (size_[k] > mx) {  ka = k;  mx = size_[k]; } 
+  return(ka);
+}
+
+
+//  Acces lineaire aux elements ....  Calcul d'offset
+// --------------------------------------------------
+// Position de l'element 0 du vecteur i selon l'axe ka
+// --------------------------------------------------
+//! return position of first element for vector \b i alond \b ka th axe.
+sa_size_t BaseArray::Offset(int_4 ka, sa_size_t i) const
+{
+
+  if ( (ndim_ < 1) || (i == 0) )  return(offset_);
+  //#ifdef SO_BOUNDCHECKING
+  if (ka >= ndim_) 
+    throw RangeCheckError("BaseArray::Offset(int_4 ka, sa_size_t i) Axe KA Error");
+  if ( i*size_[ka] >= totsize_ )  
+    throw RangeCheckError("BaseArray::Offset(int_4 ka, sa_size_t i) Index Error");
+  //#endif
+  sa_size_t idx[BASEARRAY_MAXNDIMS];
+  int_4 k;
+  sa_size_t rest = i;
+  idx[ka] = 0;
+  for(k=0; k<ndim_; k++) {
+    if (k == ka) continue;
+    idx[k] = rest%size_[k];   rest /= size_[k];
+  }
+  sa_size_t off = offset_;
+  for(k=0; k<ndim_; k++)  off += idx[k]*step_[k];
+  return (off);
+}
+
+//! return position of element \b ip.
+sa_size_t BaseArray::Offset(sa_size_t ip) const
+{
+  if ( (ndim_ < 1) || (ip == 0) )  return(offset_);
+  //#ifdef SO_BOUNDCHECKING
+  if (ip >= totsize_)
+    throw RangeCheckError("BaseArray::Offset(sa_size_t ip) Out of range index ip");
+  //#endif
+
+  sa_size_t idx[BASEARRAY_MAXNDIMS];
+  int_4 k;
+  sa_size_t rest = ip;
+  for(k=0; k<ndim_; k++) {
+    idx[k] = rest%size_[k];   rest /= size_[k];
+  }
+  //#ifdef SO_BOUNDCHECKING
+  if (rest != 0) 
+    throw PError("BaseArray::Offset(sa_size_t ip) BUG !!! rest != 0");
+  //#endif
+//   if (rest != 0) cerr << " BUG ---- BaseArray::Offset( " << ip << " )" << rest << endl;
+//   cerr << " DBG-Offset( " << ip << ")" ;
+//   for(k=0; k<ndim_; k++) cerr << idx[k] << "," ;
+//   cerr << " ZZZZ " << endl;
+  sa_size_t off = offset_;
+  for(k=0; k<ndim_; k++)  off += idx[k]*step_[k];
+  return (off);
+}
+//! return index of element \b ip, along the five array axes 
+void BaseArray::IndexAtPosition(sa_size_t ip, sa_size_t & ix, sa_size_t & iy, 
+				sa_size_t & iz, sa_size_t & it, sa_size_t & iu) const
+{
+  ix = iy = iz = it = iu = 0;
+  if ( (ndim_ < 1) || (ip == 0) )  return;
+  if (ip >= totsize_)
+    throw RangeCheckError("BaseArray::IndexAtPosition(...) Out of range index ip");
+  sa_size_t idx[BASEARRAY_MAXNDIMS];
+  int_4 k;
+  sa_size_t rest = ip;
+  for(k=0; k<ndim_; k++) {
+    idx[k] = rest%size_[k];   rest /= size_[k];
+    if (rest == 0)  break;
+  }
+  if (rest != 0) 
+    throw PError("BaseArray::IndexAtPosition(...) BUG !!! rest != 0");
+  ix = idx[0];
+  iy = idx[1];
+  iz = idx[2];
+  it = idx[3];
+  iu = idx[4];  
+  return;
+}
+
+//! return various parameters for double loop operations on two arrays.
+void BaseArray::GetOpeParams(const BaseArray& a, bool smo, int_4& ax, int_4& axa, sa_size_t& step,
+			     sa_size_t& stepa, sa_size_t& gpas, sa_size_t& naxa) const
+{
+  if (smo) { // Same memory organisation
+    ax = axa = MaxSizeKA();
+  }
+  else {
+    if (Size(RowsKA()) >= Size(ColsKA()) ) {
+      ax = RowsKA();
+      axa = a.RowsKA();
+    }
+    else {
+      ax = ColsKA();
+      axa = a.ColsKA();
+    }
+  }
+  step = Step(ax);
+  stepa = a.Step(axa);
+  gpas = Size(ax)*step;
+  naxa = Size()/Size(ax);
+  return;
+}
+
+// ----------------------------------------------------
+//       Impression, etc ...
+// ----------------------------------------------------
+
+//! Show infos on stream \b os (\b si to display DvList)
+void BaseArray::Show(ostream& os, bool si) const
+{
+  if (ndim_ < 1) {
+    os << "\n--- " << BaseArray::InfoString() << " Unallocated Array ! " << endl;
+    return;
+  } 
+  os << "\n--- " << InfoString() ; 
+  os << " ND=" << ndim_ << " SizeX*Y*...= " ;
+  for(int_4 k=0; k<ndim_; k++) { 
+    os << size_[k];
+    if (k<ndim_-1)  os << "x";
+  }
+  os << " ---" << endl;
+  if (prt_lev_ > 0) {
+    os <<  " TotSize= " << totsize_ << " Step(X Y ...)="  ;
+    for(int_4 k=0; k<ndim_; k++)     os << step_[k] << "  " ;
+    os << " Offset= " << offset_  << endl;
+  }
+  if (prt_lev_ > 1) {
+    os << " MemoryMapping=" << GetMemoryMapping() << " VecType= " << GetVectorType()
+       << " RowsKA= " << RowsKA() << " ColsKA= " << ColsKA() 
+       << " VectKA=" << VectKA() << " ArrayType=" << arrtype_ << endl;
+  }
+  if (!si && (prt_lev_ < 2)) return;
+  if (mInfo != NULL) os << (*mInfo) << endl;
+ 
+}
+
+//! Return BaseArray Type
+string BaseArray::InfoString() const
+{
+  string rs = "BaseArray Type= ";
+  rs +=  typeid(*this).name() ;
+  return rs;
+}
+
+//! Return attached DVList
+DVList& BaseArray::Info()
+{
+if (mInfo == NULL)  mInfo = new DVList;
+return(*mInfo);
+}
+
+//! Update sizes and information for array
+/*!
+  \param ndim : dimension
+  \param siz[ndim] : sizes
+  \param step : step (must be the same on all dimensions)
+  \param offset : offset of the first element
+  \return true if all OK, false if problems appear
+  \return string \b exmsg for explanation in case of problems
+ */
+bool BaseArray::UpdateSizes(int_4 ndim, const sa_size_t * siz, sa_size_t step, sa_size_t offset, string & exmsg)
+{
+  if (ndim >= BASEARRAY_MAXNDIMS) {
+    exmsg += " NDim Error";  return false;
+  }
+  if (step < 1) {
+    exmsg += " Step(=0) Error";  return false;
+  }
+
+  minstep_ = moystep_ = step;
+
+  // Flagging bad updates ...
+  ndim_ = 0;
+
+  totsize_ = 1;
+  int_4 k;
+  for(k=0; k<BASEARRAY_MAXNDIMS; k++) {
+    size_[k] = 1;
+    step_[k] = 0;
+  }
+  for(k=0; k<ndim; k++) {
+    size_[k] = siz[k] ;
+    step_[k] = totsize_*step;
+    totsize_ *= size_[k];
+  }
+  if (totsize_ < 1) {
+    exmsg += " Size Error";  return false;
+  }
+  offset_ = offset;
+  // Update OK 
+  ndim_ = ndim;
+  // Default for matrices : Memory organisation and Vector type 
+  SetMemoryMapping(BaseArray::SameMemoryMapping);
+  return true;
+}
+
+//! Update sizes and information for array
+/*!
+  \param ndim : dimension
+  \param siz[ndim] : sizes
+  \param step[ndim] : steps
+  \param offset : offset of the first element
+  \return true if all OK, false if problems appear
+  \return string \b exmsg for explanation in case of problems
+ */
+bool BaseArray::UpdateSizes(int_4 ndim, const sa_size_t * siz, const sa_size_t * step, sa_size_t offset, string & exmsg)
+{
+  if (ndim >= BASEARRAY_MAXNDIMS) {
+    exmsg += " NDim Error";  return false;
+  }
+
+  // Flagging bad updates ...
+  ndim_ = 0;
+
+  totsize_ = 1;
+  int_4 k;
+  for(k=0; k<BASEARRAY_MAXNDIMS; k++) {
+    size_[k] = 1;
+    step_[k] = 0;
+  }
+  sa_size_t minstep = step[0];
+  for(k=0; k<ndim; k++) {
+    size_[k] = siz[k] ;
+    step_[k] = step[k];
+    totsize_ *= size_[k];
+    if (step_[k] < minstep)  minstep = step_[k];
+  }
+  if (minstep < 1) {
+    exmsg += " Step(=0) Error";  return false;
+  }
+  if (totsize_ < 1) {
+    exmsg += " Size Error";  return false;
+  }
+  sa_size_t plast = 0;
+  for(k=0; k<ndim; k++)   plast += (siz[k]-1)*step[k];
+  if (plast == minstep*(totsize_-1) )  moystep_ = minstep;
+  else moystep_ = 0;
+  minstep_ = minstep;
+  offset_ = offset;
+  // Update OK 
+  ndim_ = ndim;
+  // Default for matrices : Memory organisation and Vector type 
+  SetMemoryMapping(BaseArray::SameMemoryMapping);
+  return true;
+}
+
+//! Update sizes and information relative to array \b a
+/*!
+  \param a : array to be compare with
+  \return true if all OK, false if problems appear
+  \return string \b exmsg for explanation in case of problems
+ */
+bool BaseArray::UpdateSizes(const BaseArray& a, string & exmsg)
+{
+  if (a.ndim_ >= BASEARRAY_MAXNDIMS) {
+    exmsg += " NDim Error";  return false;
+  }
+
+  // Flagging bad updates ...
+  ndim_ = 0;
+
+  totsize_ = 1;
+  int_4 k;
+  for(k=0; k<BASEARRAY_MAXNDIMS; k++) {
+    size_[k] = 1;
+    step_[k] = 0;
+  }
+  sa_size_t minstep = a.step_[0];
+  for(k=0; k<a.ndim_; k++) {
+    size_[k] = a.size_[k] ;
+    step_[k] = a.step_[k];
+    totsize_ *= size_[k];
+    if (step_[k] < minstep)  minstep = step_[k];
+  }
+  if (minstep < 1) {
+    exmsg += " Step(=0) Error";  return false;
+  }
+  if (totsize_ < 1) {
+    exmsg += " Size Error";  return false;
+  }
+
+  minstep_ = a.minstep_;
+  moystep_ = a.moystep_;
+  offset_ = a.offset_;
+  macoli_ = a.macoli_;
+  marowi_ = a.marowi_;
+  veceli_ = a.veceli_;
+  // Update OK 
+  ndim_ = a.ndim_;
+  return true;
+}
+
+
+//! Update sizes and information relative to array \b a
+/*!
+  \param a : array to be compare with
+  \param ndim : could be change (but should be less than the ndim of the current class)
+  \param siz[ndim],pos[ndim],step[ndim] : could be changed but must be
+             compatible within the memory size with those of the current class.
+  \return true if all OK, false if problems appear
+  \return string \b exmsg for explanation in case of problems
+ */
+void BaseArray::UpdateSubArraySizes(BaseArray & ra, int_4 ndim, sa_size_t * siz, sa_size_t * pos, sa_size_t * step) const
+{
+  if ( (ndim > ndim_) || (ndim < 1) ) 
+    throw(SzMismatchError("BaseArray::UpdateSubArraySizes( ... ) NDim Error") );
+  int_4 k;
+  for(k=0; k<ndim; k++) 
+    if ( (siz[k]*step[k]+pos[k]) > size_[k] )  
+      throw(SzMismatchError("BaseArray::UpdateSubArraySizes( ... ) Size/Pos Error") );
+  sa_size_t offset = offset_;
+  for(k=0; k<ndim_; k++) { 
+    offset += pos[k]*step_[k]; 
+    step[k] *= step_[k];
+  }
+  string exm = "BaseArray::UpdateSubArraySizes() ";
+  if (!ra.UpdateSizes(ndim, siz, step, offset,  exm))
+     throw( ParmError(exm) );
+  return;
+}
+
+
Index: /tags/V_Dec2002/SophyaLib/TArray/basarr.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/TArray/basarr.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/TArray/basarr.h	(revision 2309)
@@ -0,0 +1,246 @@
+// This may look like C code, but it is really -*- C++ -*-
+//      Base array class - Memory organisation management
+//                     R. Ansari, C.Magneville   03/2000
+
+#ifndef BaseArray_SEEN
+#define BaseArray_SEEN
+
+#include "machdefs.h"
+#include <math.h>
+#include <iostream.h>
+#include "anydataobj.h"
+#include "mutyv.h"
+#include "dvlist.h"
+
+
+//! Maximum number of dimensions for an array 
+/*! \anchor BASEARRAY_MAXNDIMS */
+#define BASEARRAY_MAXNDIMS  5
+
+namespace SOPHYA {  
+
+//   ------------ classe template Array ----------- 
+//! Base class for template arrays
+class BaseArray : public AnyDataObj {
+public:
+  //! To define Array or Matrix memory mapping
+  enum MemoryMapping {
+    AutoMemoryMapping = -1,  //!< define Auto Memory Mapping
+    SameMemoryMapping = 0,   //!< define Same Memory Mapping
+    CMemoryMapping = 1,      //!< define C Memory Mapping
+    FortranMemoryMapping = 2 //!< define Fortran Memory Mapping
+    };
+  //! To define Vector type
+  enum VectorType {
+    AutoVectorType = -1,  //!< define Auto Vector Type
+    SameVectorType = 0,   //!< define Same Vector Type
+    ColumnVector = 1,     //!< define Column Vector Type
+    RowVector = 2         //!< define Row Vector Type
+    };
+
+  // threshold for parallel routine call
+  static void	 SetOpenMPSizeThreshold(sa_size_t thr=200000);
+  //! Get Size threshold for parallel routine call
+  static inline sa_size_t GetOpenMPSizeThreshold() { return openmp_size_threshold; }
+
+  static void    SetMaxPrint(sa_size_t nprt=50, int_4 lev=0);   
+  //! Get maximum number of printed elements
+  static inline sa_size_t GetMaxPrint() { return max_nprt_; }
+  //! Get print  level
+  static inline int_4 GetPrintLevel() { return prt_lev_; }
+
+  static short   SetDefaultMemoryMapping(short mm=CMemoryMapping);
+  //! Get Default Memory Mapping
+  static inline short GetDefaultMemoryMapping() { return default_memory_mapping; }
+  static short   SetDefaultVectorType(short vt=ColumnVector);
+  //! Get Default Vector Type
+  static inline short GetDefaultVectorType() { return default_vector_type; }
+  
+  // Creator / destructor
+  BaseArray();
+  virtual ~BaseArray();
+
+  // Returns true if ndim and sizes are equal
+  virtual bool CompareSizes(const BaseArray& a, bool& smo) const;
+
+  // Compacts \b size=1 array dimensions
+  virtual void CompactAllDim(); // suppresses all size==1 dimensions 
+  virtual void CompactTrailingDim(); // suppresses size==1 dimensions after the last size>1 dimension
+
+  // Array dimensions
+  //! Return true if the array was allocated ( Rank() > 0 )
+  inline bool IsAllocated() const { return( (ndim_ > 0) ? true : false ); }
+  //! Return number of dimensions (array rank)
+  inline int_4 NbDimensions() const { return( ndim_ ); }
+  //! Return array rank (number of dimensions) 
+  inline int_4 Rank() const { return( ndim_ ); }
+
+  //! Return total size of the array
+  inline sa_size_t Size() const { return(totsize_); }
+  //! Return size along the first dimension
+  inline sa_size_t SizeX() const { return(size_[0]); }
+  //! Return size along the second dimension
+  inline sa_size_t SizeY() const { return(size_[1]); }
+  //! Return size along the third dimension
+  inline sa_size_t SizeZ() const { return(size_[2]); }
+  //! Return size along the \b ka th dimension
+  inline sa_size_t Size(int_4 ka) const { return(size_[CheckDI(ka,1)]); }
+
+  int_4 MaxSizeKA() const ;
+
+  //! Get memory organization
+  inline short  GetMemoryMapping() const 
+         { return ( (marowi_ == 1) ? CMemoryMapping : FortranMemoryMapping) ; }
+  //! line index dimension
+  inline int_4    RowsKA() const {return marowi_; }
+  //! column index dimension
+  inline int_4    ColsKA() const {return macoli_; }
+  //! Index dimension of the elements of a vector
+  inline int_4    VectKA() const {return veceli_; }
+  void          SetMemoryMapping(short mm=AutoMemoryMapping);
+
+  //! Get Vector type ( \b Line or \b Column vector )
+  inline short  GetVectorType() const 
+                { return((marowi_ == veceli_) ? ColumnVector : RowVector); }
+  void SetVectorType(short vt=AutoVectorType);
+
+  // memory organisation - packing information
+  //! return true if array is packed in memory
+  inline bool   IsPacked() const { return(moystep_ == 1); }
+  //! return true if array is packed along the first dimension
+  inline bool   IsPackedX() const { return(step_[0] == 1); }
+  //! return true if array is packed along the second dimension
+  inline bool   IsPackedY() const { return(step_[1] == 1); }
+  //! return true if array is packed along the third dimension
+  inline bool   IsPackedZ() const { return(step_[2] == 1); }
+  //! return true if array is packed along the \b ka th dimension
+  inline bool   IsPacked(int_4 ka) const { return(step_[CheckDI(ka,2)] == 1); }
+
+  //! return the minimum step value along all the dimensions
+  inline sa_size_t MinStep() const  { return(minstep_); }
+  //! return the average step value along all the dimensions
+  inline sa_size_t AvgStep() const  { return(moystep_); }
+  //! return the step along the first dimension
+  inline sa_size_t StepX() const { return(step_[0]); }
+  //! return the step along the second dimension
+  inline sa_size_t StepY() const { return(step_[1]); }
+  //! return the step along the third dimension
+  inline sa_size_t StepZ() const { return(step_[2]); }
+  //! return the step along the \b ka th dimension
+  inline sa_size_t Step(int_4 ka) const { return(step_[CheckDI(ka,3)]); }
+
+  int_4 MinStepKA() const ;
+
+  // Offset of element ip
+  sa_size_t Offset(sa_size_t ip=0) const ;
+  // Offset of the i'th vector along axe ka 
+  sa_size_t Offset(int_4 ka, sa_size_t i) const ;
+  inline sa_size_t  Offset(sa_size_t ix, sa_size_t iy, sa_size_t iz, sa_size_t it=0, sa_size_t iu=0) const;  
+  // Index values of element ip
+  void	         IndexAtPosition(sa_size_t ip, sa_size_t & ix, sa_size_t & iy, sa_size_t & iz, 
+				 sa_size_t & it, sa_size_t & iu) const;
+  // an abstract element acces methode
+  virtual MuTyV & ValueAtPosition(sa_size_t ip) const = 0;
+
+  // Pour recuperer pas et numero d'axe pour operations sur deux arrays
+  void   GetOpeParams(const BaseArray& a, bool smo, int_4& ax, int_4& axa, sa_size_t& step,
+		      sa_size_t& stepa, sa_size_t& gpas, sa_size_t& naxa) const;
+  // Impression, I/O, ...
+  void           Show(ostream& os, bool si=false) const;
+  //! Show information on \b cout
+  inline void    Show() const { Show(cout); }
+  virtual string InfoString() const;
+
+  // Lecture,Ecriture sur fichier ASCII
+  //! Reads an array from an ASCII stream
+  virtual sa_size_t ReadASCII(istream& is, sa_size_t & nr, sa_size_t & nc,
+			      char clm='#', const char* sep=" \t") = 0;
+  //! Writes an array to an ASCII stream
+  virtual void   WriteASCII(ostream& os) const = 0;
+
+  // DVList info Object
+  DVList& Info();
+
+protected:
+  inline int_4 CheckDI(int_4 ka, int msg) const ;
+  inline void CheckBound(sa_size_t ix, sa_size_t iy, sa_size_t iz, sa_size_t it, sa_size_t iu, int msg) const ;
+  // Changing Sizes/NDim ... return true if OK
+  bool UpdateSizes(int_4 ndim, const sa_size_t * siz, sa_size_t step, sa_size_t offset, string & exmsg);
+  bool UpdateSizes(int_4 ndim, const sa_size_t * siz, const sa_size_t * step, sa_size_t offset, string & exmsg);
+  bool UpdateSizes(const BaseArray& a, string & exmsg);
+  static sa_size_t ComputeTotalSize(int_4 ndim, const sa_size_t * siz, sa_size_t step, sa_size_t offset) ;
+  //  Organisation memoire
+  static short SelectMemoryMapping(short mm);
+  static short SelectVectorType(short vt);
+  void UpdateMemoryMapping(short mm);
+  void UpdateMemoryMapping(BaseArray const & a, short mm);
+
+  // Pour Extraction de sous-tableau 
+  virtual void UpdateSubArraySizes(BaseArray & ra, int_4 ndim, sa_size_t * siz, sa_size_t * pos, sa_size_t * step) const;
+
+  int_4  ndim_; //!< number of dimensions of array
+  sa_size_t size_[BASEARRAY_MAXNDIMS]; //!< array of the size in each dimension
+  sa_size_t totsize_; //!< Total number of elements
+  sa_size_t offset_;  //!< global offset -\> position of elem[0] in DataBlock
+  //! two consecutive elements distance in a given dimension 
+  sa_size_t step_[BASEARRAY_MAXNDIMS];
+  sa_size_t minstep_; //!< minimal step (in any axes)
+  sa_size_t moystep_; //!< mean step, if == 0 --\> non regular steps
+  int_2  marowi_; //!< For matrices, Row index in dimensions
+  int_2  macoli_; //!< For matrices, Column index in dimensions
+  int_2  veceli_; //!< For vectors, dimension index = marowi_/macoli_ (Row/Col vectors)
+  int_2 arrtype_; //!< 0 a TArray, 1 TMatrix , 2 TVector
+  DVList* mInfo;    //!< Infos (variables) attached to the array
+
+  static char * ck_op_msg_[6]; //!< Operation messages for CheckDI() CheckBound()
+  static sa_size_t max_nprt_; //!< maximum number of printed elements
+  static int_4 prt_lev_;  //!< Print level
+  static short default_memory_mapping; //!< Default memory mapping
+  static short default_vector_type;    //!< Default vector type Row/Column
+  static sa_size_t openmp_size_threshold; //!< Size limit for parallel routine calls
+};
+
+// --------------------------------------------------
+//        Methodes inline de verification
+// --------------------------------------------------
+//! to verify the compatibility of the dimension index
+inline int_4 BaseArray::CheckDI(int_4 ka, int msg)  const
+{
+  if ( (ka < 0) || (ka >= ndim_) ) {
+    string txt = "BaseArray::CheckDimensionIndex/Error ";   txt += ck_op_msg_[msg];
+    throw(RangeCheckError(txt));
+  }
+  return(ka);
+}
+
+//! to verify the compatibility of the indexes in all dimensions
+inline void BaseArray::CheckBound(sa_size_t ix, sa_size_t iy, sa_size_t iz, sa_size_t it, sa_size_t iu, int msg)  const
+{
+  if ( (ix >= size_[0]) || (ix < 0) || (iy >= size_[1]) || (iy < 0) || 
+       (iz >= size_[2]) || (iz < 0) || (it >= size_[3]) || (it < 0) ||
+       (iu >= size_[4]) || (iu < 0) )  {
+    string txt = "BaseArray::CheckArrayBound/Error ";   txt += ck_op_msg_[msg];
+    throw(RangeCheckError(txt));
+  }
+  return;
+}
+
+
+
+// --------------------------------------------------
+//        Position d'un element
+// --------------------------------------------------
+//! Offset of element (ix,iy,iz,it,iu)
+inline sa_size_t BaseArray::Offset(sa_size_t ix, sa_size_t iy, sa_size_t iz, sa_size_t it, sa_size_t iu) const
+{
+#ifdef SO_BOUNDCHECKING
+  CheckBound(ix, iy, iz, it, iu, 4);
+#endif
+  return ( offset_+  ix*step_[0] + iy*step_[1] + iz*step_[2] +
+	      it*step_[3] + iu*step_[4] );
+}
+
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/TArray/fioarr.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/TArray/fioarr.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/TArray/fioarr.cc	(revision 2309)
@@ -0,0 +1,244 @@
+//     Persistence manager for template numerical arrays
+//               R. Ansari, C.Magneville   03/2000
+
+#include "pexceptions.h"
+#include "fiondblock.h"
+#include "fioarr.h"
+#include "tmatrix.h"
+#include "tvector.h"
+#include "datatype.h"
+#include <typeinfo>
+
+// --------------------------------------------------------
+//   Les objets delegues pour la gestion de persistance 
+// --------------------------------------------------------
+/*!
+  \class SOPHYA::FIO_TArray
+  \ingroup TArray
+  Class for persistent management of TArray
+
+  This class manage also persistence for TMatrix and TVector.
+  \sa TArray TMatrix TVector.
+ */
+///////////////////////////////////////////////////////////
+
+//! Default constructor
+template <class T>
+FIO_TArray<T>::FIO_TArray()
+{
+  dobj=NULL;
+  ownobj=false;
+}
+
+
+//! Constructor from the file \b filename
+template <class T>
+FIO_TArray<T>::FIO_TArray(string const & filename) 
+{
+  dobj=NULL;
+  ownobj=false;
+  Read(filename);
+}
+
+//! Constructor from the TArray \b obj
+template <class T>
+FIO_TArray<T>::FIO_TArray(const TArray<T> & obj) 
+{ 
+  const TVector<T> * tv = dynamic_cast<const TVector<T> *>(&obj);
+  if (tv != NULL)  dobj = new TVector<T>(*tv, true);
+  else {
+  const TMatrix<T> * tm = dynamic_cast<const TMatrix<T> *>(&obj);
+  if (tm != NULL)  dobj = new TMatrix<T>(*tm, true);
+  else dobj = new TArray<T>(obj, true);
+  }
+  ownobj=true; 
+}
+
+//! Connect with a TArray \b obj
+template <class T>
+FIO_TArray<T>::FIO_TArray(TArray<T> * obj) 
+{ 
+  dobj = obj;
+  ownobj=false; 
+}
+
+//! destructor
+template <class T>
+FIO_TArray<T>::~FIO_TArray()
+{
+  if (ownobj && dobj) delete dobj;
+}
+
+//! Return pointer to the connected TArray
+template <class T>
+AnyDataObj* FIO_TArray<T>::DataObj()
+{
+  return(dobj);
+}
+
+//! Connect TArray \b o
+template <class T>
+void FIO_TArray<T>::SetDataObj(AnyDataObj & o)
+{
+  TArray<T> * po = dynamic_cast< TArray<T> * >(&o);
+  if (po == NULL) {
+    char buff[160];
+    sprintf(buff,"FIO_TArray<%s>::SetDataObj(%s) - Object type  error ! ",
+	    DataTypeInfo<T>::getTypeName().c_str(), typeid(o).name());
+    throw TypeMismatchExc(PExcLongMessage(buff));    
+  }
+  if (ownobj && dobj) delete dobj;
+  dobj = po; ownobj = false;
+} 
+
+template <class T>
+void FIO_TArray<T>::ReadSelf(PInPersist& is)
+{
+// On lit les 5 premiers uint_4
+//  0: Numero de version,  1 : Type (Array, matrix, Vector, ...)  2 != 0 , has Info
+//          1:Type = 0 TArray , 12=(4+8) TMatrix , 48=(16+32) TVector
+  uint_4 itab[5];
+  is.Get(itab,5);
+
+  // Checking version number
+  if (itab[0] < 2) 
+    FileFormatExc("FIO_TArray<T>::ReadSelf() - Unsupported (old V<2) version"); 
+
+  if (dobj == NULL) {
+    if (itab[1] == 12)   dobj = new TMatrix<T>;
+    else if (itab[1] == 48)   dobj = new TVector<T>;
+    else   dobj = new TArray<T>;
+  }
+// On lit les tailles, etc ...
+// On ecrit les tailles, etc ...
+  int_4 tmpi4s[5];
+  is.Get(tmpi4s, 5);
+  dobj->ndim_ = tmpi4s[0];
+  dobj->marowi_ = tmpi4s[1];
+  dobj->macoli_ = tmpi4s[2];
+  dobj->veceli_ = tmpi4s[3];
+// tmpi4s[4] Reserved for future use 
+
+// Tous les sa_size_t sont ecrit/lu en int_8 afin de maintenir la compatibilite  
+// entre version du programme utilisant int_4 OU int_8 pour sa_size_t 
+  int_8 tmpi8s[BASEARRAY_MAXNDIMS];
+  int kk;
+
+  is.Get(tmpi8s, BASEARRAY_MAXNDIMS);
+  for(kk=0; kk<BASEARRAY_MAXNDIMS; kk++) 
+    dobj->size_[kk] = tmpi8s[kk];
+  is.Get(tmpi8s, BASEARRAY_MAXNDIMS);
+  for(kk=0; kk<BASEARRAY_MAXNDIMS; kk++) 
+    dobj->step_[kk] = tmpi8s[kk];
+
+  is.Get(tmpi8s, 5);
+  dobj->totsize_ = tmpi8s[0];
+  dobj->offset_ = tmpi8s[1];
+  dobj->minstep_ = tmpi8s[2];
+  dobj->moystep_ = tmpi8s[3];
+// tmpi8s[4] Reserved for future use 
+
+// On lit le datablock
+  is >> dobj->DataBlock();
+// On ecrit le DVList info si necessaire
+  if (itab[2] != 0)  is >> dobj->Info();  
+}
+
+template <class T>
+void FIO_TArray<T>::WriteSelf(POutPersist& os) const
+{
+  if (dobj == NULL)   return;
+//  On ecrit 5 uint_4 .... 
+//  0: Numero de version,  1 : Type (Array, matrix, Vector, ...)  2 != 0 , has Info
+//          1:Type = 0 TArray , 12=(4+8) TMatrix , 48=(16+32) TVector
+  uint_4 typa = 0;
+  TVector<T> * tv = dynamic_cast<TVector<T> *>(dobj);
+  if (tv != NULL)  typa = 48;
+  else {
+  TMatrix<T> * tm = dynamic_cast<TMatrix<T> *>(dobj);
+  if (tm != NULL)  typa = 12;
+  else  typa = 0;
+  }
+
+  uint_4 itab[5];
+  itab[0] = 2;  // Numero de version a 2 depuis Aout 2000  - Reza
+  itab[1] = typa;  // Real object type
+  itab[2] = (dobj->mInfo != NULL) ? 1 : 0;
+  itab[3] = itab[4] = 0;
+  os.Put(itab,5);
+
+// On ecrit les tailles, etc ...
+  int_4 tmpi4s[5];
+  //  os.Put(dobj->ndim_);
+  //  os.Put(dobj->marowi_);
+  //  os.Put(dobj->macoli_);
+  //  os.Put(dobj->veceli_);
+  tmpi4s[0] = dobj->ndim_;
+  tmpi4s[1] = dobj->marowi_;
+  tmpi4s[2] = dobj->macoli_;
+  tmpi4s[3] = dobj->veceli_;
+  tmpi4s[4] = 0;   // Reserved for future use
+  os.Put(tmpi4s, 5);
+
+// Tous les sa_size_t sont ecrit en int_8 afin de pouvoir etre ecrit/relu
+// entre version du programme utilisant int_4 OU int_8 pour sa_size_t 
+  int_8 tmpi8s[BASEARRAY_MAXNDIMS];
+  int kk;
+  //  os.Put(dobj->size_, BASEARRAY_MAXNDIMS);
+  for(kk=0; kk<BASEARRAY_MAXNDIMS; kk++) 
+    tmpi8s[kk] = dobj->size_[kk];
+  os.Put(tmpi8s, BASEARRAY_MAXNDIMS);
+  //  os.Put(dobj->step_, BASEARRAY_MAXNDIMS);
+  for(kk=0; kk<BASEARRAY_MAXNDIMS; kk++) 
+    tmpi8s[kk] = dobj->step_[kk];
+  os.Put(tmpi8s, BASEARRAY_MAXNDIMS);
+
+  //  os.Put(dobj->totsize_);
+  //  os.Put(dobj->offset_);
+  //  os.Put(dobj->minstep_);
+  //  os.Put(dobj->moystep_);
+  tmpi8s[0] = dobj->totsize_;
+  tmpi8s[1] = dobj->offset_;
+  tmpi8s[2] = dobj->minstep_;
+  tmpi8s[3] = dobj->moystep_;
+  tmpi8s[4] = 0;  // Reserved for future use 
+  os.Put(tmpi8s, 5);
+  
+// On ecrit le datablock
+  os << dobj->DataBlock();
+// On ecrit le DVList info si necessaire
+  if (itab[2] != 0)  os << dobj->Info();
+}
+
+
+
+///////////////////////////////////////////////////////////////
+#ifdef __CXX_PRAGMA_TEMPLATES__
+// Instances des delegues FileIO (PPersist)
+// #pragma define_template FIO_TArray<uint_1>
+#pragma define_template FIO_TArray<uint_2>
+// #pragma define_template FIO_TArray<int_2>
+#pragma define_template FIO_TArray<int_4>
+#pragma define_template FIO_TArray<int_8>
+// #pragma define_template FIO_TArray<uint_4>
+// #pragma define_template FIO_TArray<uint_8>
+#pragma define_template FIO_TArray<r_8>
+#pragma define_template FIO_TArray<r_4>
+#pragma define_template FIO_TArray< complex<r_4> >
+#pragma define_template FIO_TArray< complex<r_8> >
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+// Instances des delegues FileIO (PPersist)
+// template class FIO_TArray<uint_1>;
+template class FIO_TArray<uint_2>;
+// template class FIO_TArray<int_2>;
+template class FIO_TArray<int_4>;
+template class FIO_TArray<int_8>;
+// template class FIO_TArray<uint_4>;
+// template class FIO_TArray<uint_8>;
+template class FIO_TArray<r_8>;
+template class FIO_TArray<r_4>;
+template class FIO_TArray< complex<r_4> >;
+template class FIO_TArray< complex<r_8> >;
+#endif
Index: /tags/V_Dec2002/SophyaLib/TArray/fioarr.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/TArray/fioarr.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/TArray/fioarr.h	(revision 2309)
@@ -0,0 +1,51 @@
+// This may look like C code, but it is really -*- C++ -*-
+//      template array class for numerical types
+//                     R. Ansari, C.Magneville   03/2000
+
+#ifndef FIOTArray_SEEN
+#define FIOTArray_SEEN
+
+#include "machdefs.h"
+#include <iostream.h>
+#include "tarray.h"
+#include "tmatrix.h"
+#include "tvector.h"
+#include "ppersist.h"
+
+namespace SOPHYA {
+/////////////////////////////////////////////////////////////////////////
+//! Class for persistent management of TArray
+template <class T>
+class FIO_TArray : public  PPersist  {
+public:
+  FIO_TArray();
+  FIO_TArray(string const & filename); 
+  FIO_TArray(const TArray<T> & obj);
+  FIO_TArray(TArray<T> * obj);
+  virtual ~FIO_TArray();
+  virtual AnyDataObj* DataObj();
+  virtual void        SetDataObj(AnyDataObj & o);
+  inline operator TArray<T>() { return(*dobj); }
+protected :
+  virtual void ReadSelf(PInPersist&);           
+  virtual void WriteSelf(POutPersist&) const;  
+  TArray<T> * dobj; //!< Pointer to the connected TArray
+  bool ownobj; //!< true if the connected object belong to the class
+};
+
+/*! \ingroup TArray \fn operator<<(POutPersist&,TArray<T>&)
+  \brief Write TArray \b obj into POutPersist stream \b os */
+template <class T>
+inline POutPersist& operator << (POutPersist& os, TArray<T> & obj)
+{ FIO_TArray<T> fio(&obj);  fio.Write(os);  return(os); }
+
+/*! \ingroup TArray \fn operator>>(PInPersist&,TArray<T>&)
+  \brief Read TArray \b obj from PInPersist stream \b os */
+template <class T>
+inline PInPersist& operator >> (PInPersist& is, TArray<T> & obj)
+{ FIO_TArray<T> fio(&obj);  fio.Read(is);  return(is); }
+
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/TArray/matharr.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/TArray/matharr.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/TArray/matharr.cc	(revision 2309)
@@ -0,0 +1,491 @@
+//  Usuall mathematical functions and operations on arrays
+//                     R. Ansari, C.Magneville   03/2000
+
+#include "machdefs.h"
+#include <math.h>
+#include "matharr.h"
+
+// ----------------------------------------------------
+//          Application d'une fonction
+// ----------------------------------------------------
+
+/*!
+  \class SOPHYA::MathArray
+  \ingroup TArray
+  Class for simple mathematical operation on arrays 
+  \warning Instanciated only for \b real and \b double (r_4, r_8) type arrays
+*/
+
+//! Apply Function In Place (function double version)
+/*!
+  \param a : array to be replaced in place
+  \param f : function for replacement
+  \return Return an array \b a filled with function f(a(i,j))
+*/
+template <class T>
+TArray<T>& MathArray<T>::ApplyFunctionInPlace(TArray<T> & a, Arr_DoubleFunctionOfX f)
+{
+  if (a.NbDimensions() < 1) 
+    throw RangeCheckError("MathArray<T>::ApplyFunctionInPlace(TArray<T> & a..) Not Allocated Array a !");
+  T * pe;
+  sa_size_t j,k;
+  if (a.AvgStep() > 0)   {  // regularly spaced elements
+    sa_size_t step = a.AvgStep(); 
+    sa_size_t maxx = a.Size()*step;
+    pe = a.Data();
+    for(k=0; k<maxx; k+=step )  pe[k] = (T)(f((double)pe[k])); 
+  }
+  else {    // Non regular data spacing ...
+    int_4 ka = a.MaxSizeKA();
+    sa_size_t step = a.Step(ka);
+    sa_size_t gpas = a.Size(ka)*step;
+    sa_size_t naxa = a.Size()/a.Size(ka);
+    for(j=0; j<naxa; j++)  {
+      pe = a.DataBlock().Begin()+a.Offset(ka,j);
+      for(k=0; k<gpas; k+=step)  pe[k] = (T)(f((double)pe[k]));
+    }
+  }
+  return(a);
+}
+
+//! Apply Function In Place (function float version)
+/*!
+  \param a : array to be replaced in place
+  \param f : function for replacement
+  \return Return an array \b a filled with function f(a(i,j))
+*/
+template <class T>
+TArray<T>& MathArray<T>::ApplyFunctionInPlace(TArray<T> & a, Arr_FloatFunctionOfX f)
+{
+  if (a.NbDimensions() < 1) 
+    throw RangeCheckError("MathArray<T>::ApplyFunctionInPlace(TArray<T> & a..) Not Allocated Array a !");
+  T * pe;
+  sa_size_t j,k;
+  if (a.AvgStep() > 0)   {  // regularly spaced elements
+    sa_size_t step = a.AvgStep(); 
+    sa_size_t maxx = a.Size()*step;
+    pe = a.Data();
+    for(k=0; k<maxx; k+=step )  pe[k] = (T)(f((float)pe[k])); 
+  }
+  else {    // Non regular data spacing ...
+    int_4 ka = a.MaxSizeKA();
+    sa_size_t step = a.Step(ka);
+    sa_size_t gpas = a.Size(ka)*step;
+    sa_size_t naxa = a.Size()/a.Size(ka);
+    for(j=0; j<naxa; j++)  {
+      pe = a.DataBlock().Begin()+a.Offset(ka,j);
+      for(k=0; k<gpas; k+=step)  pe[k] = (T)(f((float)pe[k]));
+    }
+  }
+  return(a);
+}
+
+
+//! Apply Function (function double version)
+/*!
+  \param a : argument array of the function
+  \param f : function for replacement
+  \return Return a new array filled with function f(a(i,j))
+*/
+template <class T>
+TArray<T> MathArray<T>::ApplyFunction(TArray<T> const & a, Arr_DoubleFunctionOfX f)
+{
+  TArray<T> ra;
+  ra = a;
+  ApplyFunctionInPlace(ra, f);
+  return(ra);
+}
+
+//! Apply Function (function float version)
+/*!
+  \param a : argument array of the function
+  \param f : function for replacement
+  \return Return a new array filled with function f(a(i,j))
+*/
+template <class T>
+TArray<T> MathArray<T>::ApplyFunction(TArray<T> const & a, Arr_FloatFunctionOfX f)
+{
+  TArray<T> ra;
+  ra = a;
+  ApplyFunctionInPlace(ra, f);
+  return(ra);
+}
+
+//! Compute \b mean and \b sigma of elements of array \b a, return \b mean
+template <class T>
+double MathArray<T>::MeanSigma(TArray<T> const & a, double & mean, double & sig)
+{
+  if (a.NbDimensions() < 1) 
+    throw RangeCheckError("MathArray<T>::MeanSigma(TArray<T> const & a..) Not Allocated Array a !");
+  const T * pe;
+  sa_size_t j,k;
+  mean=0.;
+  sig = 0.;
+  double valok;
+  if (a.AvgStep() > 0)   {  // regularly spaced elements
+    sa_size_t step = a.AvgStep(); 
+    sa_size_t maxx = a.Size()*step;
+    pe = a.Data();
+    for(k=0; k<maxx; k+=step )  { 
+      valok = (double) pe[k]; 
+      mean += valok;  sig += valok*valok;
+    }
+  }
+  else {    // Non regular data spacing ...
+    int_4 ka = a.MaxSizeKA();
+    sa_size_t step = a.Step(ka);
+    sa_size_t gpas = a.Size(ka)*step;
+    sa_size_t naxa = a.Size()/a.Size(ka);
+    for(j=0; j<naxa; j++)  {
+      pe = a.DataBlock().Begin()+a.Offset(ka,j);
+      for(k=0; k<gpas; k+=step) { 
+	valok = (double) pe[k]; 
+	mean += valok;  sig += valok*valok;
+      }
+    }
+  }
+  double dsz = (double)(a.Size());
+  mean /= dsz;
+  sig = sig/dsz - mean*mean;
+  if (sig >= 0.) sig = sqrt(sig);
+  return(mean);
+}
+
+
+//-------------------------------------------------------------------------------
+//      Definition utilitaire d'application de fonction 
+inline complex<r_8> ApplyComplexDoubleFunction(complex<r_8> z, 
+					       Arr_ComplexDoubleFunctionOfX f)
+{
+  return(f(z));
+}
+
+inline complex<r_4> ApplyComplexDoubleFunction(complex<r_4> z, 
+					       Arr_ComplexDoubleFunctionOfX f)
+{
+  complex<r_8> zd((r_8)z.real(), (r_8)z.imag());
+  zd = f(zd);
+  complex<r_4> zr((r_4)zd.real(), (r_4)zd.imag());
+  return(zr);
+}
+
+//-------------------------------------------------------------------------------
+
+/*!
+  \class SOPHYA::ComplexMathArray
+  \ingroup TArray
+  Class for simple mathematical operation on arrays 
+  \warning Instanciated only for \b real and \b double (r_4, r_8) complex arrays
+*/
+
+//! Apply Function In Place (complex arrays)
+/*!
+  \param a : complex array to be replaced in place
+  \param f : function for replacement
+  \return Return an array \b a filled with function f(a(i,j))
+*/
+template <class T>
+TArray< complex<T> >& ComplexMathArray<T>::ApplyFunctionInPlace(TArray< complex<T> > & a, Arr_ComplexDoubleFunctionOfX f)
+{
+  if (a.NbDimensions() < 1) 
+    throw RangeCheckError("ComplexMathArray< complex<T> >::ApplyFunctionInPlace(TArray< complex<T> > & a..) Not Allocated Array a !");
+  complex<T> * pe;
+  sa_size_t j,k;
+  if (a.AvgStep() > 0)   {  // regularly spaced elements
+    sa_size_t step = a.AvgStep(); 
+    sa_size_t maxx = a.Size()*step;
+    pe = a.Data();
+    for(k=0; k<maxx; k+=step )  pe[k] = ApplyComplexDoubleFunction(pe[k],f); 
+  }
+  else {    // Non regular data spacing ...
+    int_4 ka = a.MaxSizeKA();
+    sa_size_t step = a.Step(ka);
+    sa_size_t gpas = a.Size(ka)*step;
+    sa_size_t naxa = a.Size()/a.Size(ka);
+    for(j=0; j<naxa; j++)  {
+      pe = a.DataBlock().Begin()+a.Offset(ka,j);
+      for(k=0; k<gpas; k+=step)  pe[k] = ApplyComplexDoubleFunction(pe[k],f);
+    }
+  }
+  return(a);
+}
+
+
+
+//! Apply Function (complex arrays)
+/*!
+  \param a : argument array of the function
+  \param f : function for replacement
+  \return Return a new array filled with function f(a(i,j))
+*/
+template <class T>
+TArray< complex<T> > ComplexMathArray<T>::ApplyFunction(TArray< complex<T> > const & a, Arr_ComplexDoubleFunctionOfX f)
+{
+  TArray< complex<T> > ra;
+  ra = a;
+  ApplyFunctionInPlace(ra, f);
+  return(ra);
+}
+
+//! Create a complex array, from a real and an imaginary arrays
+/*!
+  \param p_real : array containing the real part of the complex output array
+  \param p_imag : array containing the imaginary part of the complex output array
+  \return Return a new complex array build from \b p_real and \b p_imag
+*/
+template <class T>
+TArray< complex<T> > ComplexMathArray<T>::FillFrom(TArray<T> const & p_real,
+						   TArray<T> const & p_imag)
+{
+  if (p_real.NbDimensions() < 1) 
+    throw RangeCheckError("ComplexMathArray<T>::FillFrom() - Not Allocated Array ! ");
+  bool smo;
+  if (!p_real.CompareSizes(p_imag, smo)) 
+    throw(SzMismatchError("ComplexMathArray<T>::FillFrom() SizeMismatch")) ;
+
+  TArray< complex<T> > ra;
+  ra.ReSize(p_real);
+
+  complex<T> * pe;
+  const T * per;
+  const T * pei;
+  sa_size_t j,k,ka;
+  if (smo && (p_real.AvgStep() > 0) && (p_imag.AvgStep() > 0))   {  // regularly spaced elements
+    sa_size_t step = p_real.AvgStep();
+    sa_size_t stepa = p_imag.AvgStep();
+    sa_size_t maxx = p_real.Size()*step;
+    per = p_real.Data();
+    pei = p_imag.Data();
+    pe = ra.Data();
+    for(k=0, ka=0;  k<maxx;  k+=step, ka+=stepa )  
+      pe[k] = complex<T>(per[k], pei[ka]) ;
+  }
+  else {    // Non regular data spacing ...
+    int_4 ax,axa;
+    sa_size_t step, stepa;
+    sa_size_t gpas, naxa;
+    p_real.GetOpeParams(p_imag, smo, ax, axa, step, stepa, gpas, naxa);
+    for(j=0; j<naxa; j++)  {
+      per = p_real.Data()+p_real.Offset(ax,j);
+      pei = p_imag.Data()+p_imag.Offset(axa,j);
+      pe = ra.Data()+ra.Offset(ax,j);
+      for(k=0, ka=0;  k<gpas;  k+=step, ka+=stepa)  
+	pe[k] = complex<T>(per[k], pei[ka]) ;
+    }
+  }
+  return(ra);
+}
+
+
+//! Returns the real part of the complex input array.
+/*!
+  \param a : input complex array
+  \return Return a new array filled with the real part of the input complex array elements
+*/
+
+template <class T>
+TArray<T> ComplexMathArray<T>::real(TArray< complex<T> > const & a)
+{
+  if (a.NbDimensions() < 1) 
+    throw RangeCheckError("ComplexMathArray< complex<T> >::real(TArray< complex<T> >& a) Not Allocated Array a !");
+  TArray<T> ra;
+  ra.ReSize(a);
+
+  const complex<T> * pe;
+  T * po;
+  sa_size_t j,k;
+  if (a.AvgStep() > 0)   {  // regularly spaced elements
+    sa_size_t step = a.AvgStep(); 
+    sa_size_t maxx = a.Size()*step;
+    pe = a.Data();
+    po = ra.Data();
+    for(k=0; k<maxx; k+=step )  po[k] = pe[k].real();
+  }
+  else {    // Non regular data spacing ...
+    int_4 ka = a.MaxSizeKA();
+    sa_size_t step = a.Step(ka);
+    sa_size_t gpas = a.Size(ka)*step;
+    sa_size_t naxa = a.Size()/a.Size(ka);
+    for(j=0; j<naxa; j++)  {
+      pe = a.DataBlock().Begin()+a.Offset(ka,j);
+      po = ra.DataBlock().Begin()+ra.Offset(ka,j);
+      for(k=0; k<gpas; k+=step)  po[k] = pe[k].real();
+    }
+  }
+  return(ra);
+}
+
+//! Returns the imaginary part of the complex input array.
+/*!
+  \param a : input complex array
+  \return Return a new array filled with the imaginary part of the input complex array elements
+*/
+
+template <class T>
+TArray<T> ComplexMathArray<T>::imag(TArray< complex<T> > const & a)
+{
+  if (a.NbDimensions() < 1) 
+    throw RangeCheckError("ComplexMathArray< complex<T> >::imag(TArray< complex<T> >& a) Not Allocated Array a !");
+  TArray<T> ra;
+  ra.ReSize(a);
+
+  const complex<T> * pe;
+  T * po;
+  sa_size_t j,k;
+  if (a.AvgStep() > 0)   {  // regularly spaced elements
+    sa_size_t step = a.AvgStep(); 
+    sa_size_t maxx = a.Size()*step;
+    pe = a.Data();
+    po = ra.Data();
+    for(k=0; k<maxx; k+=step )  po[k] = pe[k].imag();
+  }
+  else {    // Non regular data spacing ...
+    int_4 ka = a.MaxSizeKA();
+    sa_size_t step = a.Step(ka);
+    sa_size_t gpas = a.Size(ka)*step;
+    sa_size_t naxa = a.Size()/a.Size(ka);
+    for(j=0; j<naxa; j++)  {
+      pe = a.DataBlock().Begin()+a.Offset(ka,j);
+      po = ra.DataBlock().Begin()+ra.Offset(ka,j);
+      for(k=0; k<gpas; k+=step)  po[k] = pe[k].imag();
+    }
+  }
+  return(ra);
+}
+
+//! Returns the module squared of the complex input array.
+/*!
+  \param a : input complex array
+  \return Return a new array filled with the module squared of the input complex array elements 
+*/
+
+template <class T>
+TArray<T> ComplexMathArray<T>::module2(TArray< complex<T> > const & a)
+{
+  if (a.NbDimensions() < 1) 
+    throw RangeCheckError("ComplexMathArray< complex<T> >::module2(TArray< complex<T> >& a) Not Allocated Array a !");
+  TArray<T> ra;
+  ra.ReSize(a);
+
+  const complex<T> * pe;
+  T * po;
+  sa_size_t j,k;
+  if (a.AvgStep() > 0)   {  // regularly spaced elements
+    sa_size_t step = a.AvgStep(); 
+    sa_size_t maxx = a.Size()*step;
+    pe = a.Data();
+    po = ra.Data();
+    for(k=0; k<maxx; k+=step )  
+      po[k] = (pe[k].real()*pe[k].real()+pe[k].imag()*pe[k].imag());
+  }
+  else {    // Non regular data spacing ...
+    int_4 ka = a.MaxSizeKA();
+    sa_size_t step = a.Step(ka);
+    sa_size_t gpas = a.Size(ka)*step;
+    sa_size_t naxa = a.Size()/a.Size(ka);
+    for(j=0; j<naxa; j++)  {
+      pe = a.DataBlock().Begin()+a.Offset(ka,j);
+      po = ra.DataBlock().Begin()+ra.Offset(ka,j);
+      for(k=0; k<gpas; k+=step)  
+	po[k] = (pe[k].real()*pe[k].real()+pe[k].imag()*pe[k].imag());
+    }
+  }
+  return(ra);
+}
+
+//! Returns the module of the complex input array.
+/*!
+  \param a : input complex array
+  \return Return a new array filled with the module of the input complex array elements 
+*/
+
+template <class T>
+TArray<T> ComplexMathArray<T>::module(TArray< complex<T> > const & a)
+{
+  if (a.NbDimensions() < 1) 
+    throw RangeCheckError("ComplexMathArray< complex<T> >::module(TArray< complex<T> >& a) Not Allocated Array a !");
+  TArray<T> ra;
+  ra.ReSize(a);
+
+  const complex<T> * pe;
+  T * po;
+  sa_size_t j,k;
+  if (a.AvgStep() > 0)   {  // regularly spaced elements
+    sa_size_t step = a.AvgStep(); 
+    sa_size_t maxx = a.Size()*step;
+    pe = a.Data();
+    po = ra.Data();
+    for(k=0; k<maxx; k+=step )  
+      po[k] = sqrt((double)(pe[k].real()*pe[k].real()+pe[k].imag()*pe[k].imag()));
+  }
+  else {    // Non regular data spacing ...
+    int_4 ka = a.MaxSizeKA();
+    sa_size_t step = a.Step(ka);
+    sa_size_t gpas = a.Size(ka)*step;
+    sa_size_t naxa = a.Size()/a.Size(ka);
+    for(j=0; j<naxa; j++)  {
+      pe = a.DataBlock().Begin()+a.Offset(ka,j);
+      po = ra.DataBlock().Begin()+ra.Offset(ka,j);
+      for(k=0; k<gpas; k+=step)  
+	po[k] = sqrt((double)(pe[k].real()*pe[k].real()+pe[k].imag()*pe[k].imag()));
+    }
+  }
+  return(ra);
+}
+
+
+//! Returns the phase of the complex input array.
+/*!
+  \param a : input complex array
+  \return Return a new array filled with the phase of the input complex array elements 
+*/
+
+template <class T>
+TArray<T> ComplexMathArray<T>::phase(TArray< complex<T> > const & a)
+{
+  if (a.NbDimensions() < 1) 
+    throw RangeCheckError("ComplexMathArray< complex<T> >::phase(TArray< complex<T> >& a) Not Allocated Array a !");
+  TArray<T> ra;
+  ra.ReSize(a);
+
+  const complex<T> * pe;
+  T * po;
+  sa_size_t j,k;
+  if (a.AvgStep() > 0)   {  // regularly spaced elements
+    sa_size_t step = a.AvgStep(); 
+    sa_size_t maxx = a.Size()*step;
+    pe = a.Data();
+    po = ra.Data();
+    for(k=0; k<maxx; k+=step )  
+      po[k] = atan2((double)pe[k].imag(), (double)pe[k].real());
+  }
+  else {    // Non regular data spacing ...
+    int_4 ka = a.MaxSizeKA();
+    sa_size_t step = a.Step(ka);
+    sa_size_t gpas = a.Size(ka)*step;
+    sa_size_t naxa = a.Size()/a.Size(ka);
+    for(j=0; j<naxa; j++)  {
+      pe = a.DataBlock().Begin()+a.Offset(ka,j);
+      po = ra.DataBlock().Begin()+ra.Offset(ka,j);
+      for(k=0; k<gpas; k+=step)  
+	po[k] = atan2((double)pe[k].imag(), (double)pe[k].real());
+    }
+  }
+  return(ra);
+}
+
+
+///////////////////////////////////////////////////////////////
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template MathArray<r_4>
+#pragma define_template MathArray<r_8>
+#pragma define_template ComplexMathArray<r_4>
+#pragma define_template ComplexMathArray<r_8>
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class MathArray<r_4>;
+template class MathArray<r_8>;
+template class ComplexMathArray<r_4>;
+template class ComplexMathArray<r_8>;
+#endif
Index: /tags/V_Dec2002/SophyaLib/TArray/matharr.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/TArray/matharr.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/TArray/matharr.h	(revision 2309)
@@ -0,0 +1,179 @@
+// This may look like C code, but it is really -*- C++ -*-
+//  Usuall mathematical functions and operations on arrays
+//                     R. Ansari, C.Magneville   03/2000
+
+#ifndef MathArray_SEEN
+#define MathArray_SEEN
+
+#include "machdefs.h"
+#include <math.h>
+#include "tarray.h"
+
+namespace SOPHYA {
+
+//! Class for simple mathematical operation on arrays 
+template <class T>
+class MathArray {
+public:
+// Applying a function 
+  // Replaces the input array content with the result f(x)
+  virtual TArray<T>&  ApplyFunctionInPlace(TArray<T> & a, Arr_DoubleFunctionOfX f);
+  virtual TArray<T>&  ApplyFunctionInPlace(TArray<T> & a, Arr_FloatFunctionOfX f);
+  // Creates a new array and fills it with f(x)
+  virtual TArray<T>  ApplyFunction(TArray<T> const & a, Arr_DoubleFunctionOfX f);
+  virtual TArray<T>  ApplyFunction(TArray<T> const & a, Arr_FloatFunctionOfX f);
+  // Computing Mean-Sigma 
+  virtual double     MeanSigma(TArray<T> const & a, double & mean, double & sig);
+};
+
+////////////////////////////////////////////////
+//  Calcul de fonctions usuelles 
+
+// see below for g++   
+/*! \ingroup TArray \fn Fabs(const TArray<T>& a)
+  \brief computation on TArray */
+template <class T>
+inline TArray<T> Fabs(const TArray<T>& a)
+  { MathArray<T> ma;   return( ma.ApplyFunction(a, fabs) ); }
+
+/*! \ingroup TArray \fn Sqrt(const TArray<T>& a)
+  \brief computation on TArray */
+template <class T>
+inline TArray<T> Sqrt(const TArray<T>& a)
+  { MathArray<T> ma;   return( ma.ApplyFunction(a, sqrt) ); }
+
+/*! \ingroup TArray \fn Sin(const TArray<T>& a)
+  \brief computation on TArray */
+template <class T>
+inline TArray<T> Sin(const TArray<T>& a)
+  { MathArray<T> ma;   return( ma.ApplyFunction(a, sin) ); }
+
+/*! \ingroup TArray \fn Cos(const TArray<T>& a)
+  \brief computation on TArray */
+template <class T>
+inline TArray<T> Cos(const TArray<T>& a)
+  { MathArray<T> ma;   return( ma.ApplyFunction(a, cos) ); }
+
+/*! \ingroup TArray \fn tan(const TArray<T>& a)
+  \brief computation on TArray */
+template <class T>
+inline TArray<T> Tan(const TArray<T>& a)
+  { MathArray<T> ma;   return( ma.ApplyFunction(a, tan) ); }
+
+/*! \ingroup TArray \fn Asin(const TArray<T>& a)
+  \brief computation on TArray */
+template <class T>
+inline TArray<T> Asin(const TArray<T>& a)
+  { MathArray<T> ma;   return( ma.ApplyFunction(a, asin) ); }
+
+/*! \ingroup TArray \fn Acos(const TArray<T>& a)
+  \brief computation on TArray */
+template <class T>
+inline TArray<T> Acos(const TArray<T>& a)
+  { MathArray<T> ma;   return( ma.ApplyFunction(a, acos) ); }
+
+/*! \ingroup TArray \fn Atan(const TArray<T>& a)
+  \brief computation on TArray */
+template <class T>
+inline TArray<T> Atan(const TArray<T>& a)
+  { MathArray<T> ma;   return( ma.ApplyFunction(a, atan) ); }
+
+/*! \ingroup TArray \fn Exp(const TArray<T>& a)
+  \brief computation on TArray */
+template <class T>
+inline TArray<T> Exp(const TArray<T>& a)
+  { MathArray<T> ma;   return( ma.ApplyFunction(a, exp) ); }
+
+/*! \ingroup TArray \fn Log(const TArray<T>& a)
+  \brief computation on TArray */
+template <class T>
+inline TArray<T> Log(const TArray<T>& a)
+  { MathArray<T> ma;   return( ma.ApplyFunction(a, log) ); }
+
+/*! \ingroup TArray \fn Log10(const TArray<T>& a)
+  \brief computation on TArray */
+template <class T>
+inline TArray<T> Log10(const TArray<T>& a)
+  { MathArray<T> ma;   return( ma.ApplyFunction(a, log10) ); }
+
+
+/*! \ingroup TArray \fn MeanSigma(const TArray<T>&,double&,double&)
+  \brief Return \b mean and \b sigma of elements of array \b a */
+template <class T>
+inline double MeanSigma(const TArray<T>& a, double & mean, double & sig)
+  { MathArray<T> ma;   return( ma.MeanSigma(a, mean, sig) ); }
+
+/*! \ingroup TArray \fn Mean(const TArray<T>&)
+  \brief Return \b mean of elements of array \b a */
+template <class T>
+inline double Mean(const TArray<T>& a)
+  { MathArray<T> ma;  double mean, sig;  return( ma.MeanSigma(a, mean, sig) ); }
+
+
+//! Class for simple mathematical operation on complex arrays 
+template <class T>
+class ComplexMathArray {
+public:
+// Applying a function 
+  // Replaces the input array content with the result f(x)
+  virtual TArray< complex<T> >& ApplyFunctionInPlace(TArray< complex<T> >& a, 
+						     Arr_ComplexDoubleFunctionOfX f);
+  // Creates a new array and fills it with f(x)
+  virtual TArray< complex<T> > ApplyFunction(TArray< complex<T> > const & a, 
+					     Arr_ComplexDoubleFunctionOfX f);
+
+  // Creates a new array and fills it with f(x)
+  virtual TArray< complex<T> > FillFrom(TArray<T> const & p_real,
+					TArray<T> const & p_imag);
+
+  // Returns real-imaginary part of the complex array
+  virtual TArray<T> real(TArray< complex<T> >  const & a);
+  virtual TArray<T> imag(TArray< complex<T> >  const & a);
+  
+  // Returns module and phase of the complex input array 
+  virtual TArray<T> module2(TArray< complex<T> >  const & a);
+  virtual TArray<T> module(TArray< complex<T> >  const & a);
+  virtual TArray<T> phase(TArray< complex<T> >  const & a);  
+};
+
+/*! \ingroup TArray \fn real(const TArray< complex<T> >&)
+  \brief Return the \b real part of the input complex array \b a */
+template <class T>
+inline TArray<T> real(const TArray< complex<T> >& a)
+  { ComplexMathArray<T> cma;  return( cma.real(a) ); }
+
+/*! \ingroup TArray \fn imag(const TArray< complex<T> >&)
+  \brief Return the \b imaginary part of the input complex array \b a */
+template <class T>
+inline TArray<T> imag(const TArray< complex<T> >& a)
+  { ComplexMathArray<T> cma;  return( cma.imag(a) ); }
+
+/*! \ingroup TArray \fn module2(const TArray< complex<T> >&)
+  \brief Return the \b module squared of the input complex array \b a */
+template <class T>
+inline TArray<T> module2(const TArray< complex<T> >& a)
+  { ComplexMathArray<T> cma;  return( cma.module2(a) ); }
+
+/*! \ingroup TArray \fn module(const TArray< complex<T> >&)
+  \brief Return the \b module of the input complex array \b a */
+template <class T>
+inline TArray<T> module(const TArray< complex<T> >& a)
+  { ComplexMathArray<T> cma;  return( cma.module(a) ); }
+
+/*! \ingroup TArray \fn phase(const TArray< complex<T> >&)
+  \brief Return the \b phase of the input complex array \b a */
+template <class T>
+inline TArray<T> phase(const TArray< complex<T> >& a)
+  { ComplexMathArray<T> cma;  return( cma.phase(a) ); }
+
+/*! \ingroup TArray \fn ComplexArray(const TArray<T> &, const TArray<T> &)
+  \brief Return a complex array, with real and imaginary parts filled from the arguments  */
+template <class T>
+inline TArray< complex<T> > ComplexArray(const TArray<T> & p_real,
+					 const TArray<T> & p_imag)
+  { ComplexMathArray<T> cma;  return( cma.FillFrom(p_real, p_imag) ); }
+
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/TArray/objlist.list
===================================================================
--- /tags/V_Dec2002/SophyaLib/TArray/objlist.list	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/TArray/objlist.list	(revision 2309)
@@ -0,0 +1,10 @@
+basarr.o
+fioarr.o
+matharr.o
+sopemtx.o
+tarray.o
+tarrinit.o
+tmatrix.o
+toeplitzMatrix.o
+tvector.o
+utilarr.o
Index: /tags/V_Dec2002/SophyaLib/TArray/sopemtx.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/TArray/sopemtx.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/TArray/sopemtx.cc	(revision 2309)
@@ -0,0 +1,837 @@
+//                         C.Magneville, R.Ansari        03/2000
+
+#include "machdefs.h"
+#include <stdio.h>
+#include <iostream.h>
+#include <complex>
+#include <math.h>
+#include "sopemtx.h"
+#include "smathconst.h"
+
+////////////////////////////////////////////////////////////////
+// ---------------------------------------------------------- //
+//  La classe de gestion des lignes et colonnes d'une matrice //
+// ---------------------------------------------------------- //
+////////////////////////////////////////////////////////////////
+
+/*!
+  \class SOPHYA::TMatrixRC
+  \ingroup TArray
+  Class for representing rows, columns and diagonal of a matrix.
+  \sa TMatrix TArray
+  */
+
+//! Class of line, column or diagonal of a TMatrix
+/*!
+  A TMatrixRC represents a line, a column or the diagonal of a TMatrix
+ */
+template <class T>
+class TMatrixRC {
+public:
+  //! Define type of TMatrixRC
+  enum TRCKind {
+    TmatrixRow=0,  //!< TMatrixRC ligne
+    TmatrixCol=1,  //!< TMatrixRC column
+    TmatrixDiag=2  //!< TMatrixRC diagonal
+  };
+  TMatrixRC();
+  TMatrixRC(TMatrix<T>& m, TRCKind kind, uint_4 index=0);
+  virtual ~TMatrixRC() {}
+
+  // Acces aux rangees et colonnes de matrices
+  static TMatrixRC<T> Row(TMatrix<T> & m, uint_4 r);
+  static TMatrixRC<T> Col(TMatrix<T> & m, uint_4 c);
+  static TMatrixRC<T> Diag(TMatrix<T> & m);
+
+  // ---- A virer   $CHECK$ Reza 03/2000
+  //  int_4 Next();
+  //  int_4 Prev();
+  int_4 SetCol(int_4 c);
+  int_4 SetRow(int_4 r);
+  int_4 SetDiag();
+
+  static uint_4 Step(const TMatrix<T>& m, TRCKind rckind);
+  static T* Org(const TMatrix<T>&, TRCKind rckind, uint_4 ind=0);
+
+  //! Return the kind of TMatrix (line,column,diagonal)
+  TRCKind Kind() const { return kind; }
+  uint_4 NElts() const;
+  T& operator()(uint_4 i);
+  T  operator()(uint_4 i) const;
+
+
+   TMatrixRC<T>& operator = (const TMatrixRC<T>& rc);
+
+// ---- A virer   $CHECK$ Reza 03/2000
+//   TVector<T> GetVect() const;
+//   TMatrixRC<T>& operator += (const TMatrixRC<T>& rc);
+//   TMatrixRC<T>& operator -= (const TMatrixRC<T>& rc);
+
+  TMatrixRC<T>& operator *= (T x);
+  TMatrixRC<T>& operator /= (T x);
+
+//   TMatrixRC<T>& operator -= (T x);
+//   TMatrixRC<T>& operator += (T x);
+  
+
+  TMatrixRC<T>& LinComb(T a, T b, const TMatrixRC& rc, uint_4 first=0);
+  TMatrixRC<T>& LinComb(T b, const TMatrixRC<T>& rc, uint_4 first=0);
+
+  uint_4 IMaxAbs(uint_4 first=0);
+  void Print(ostream & os) const ;
+
+  static void Swap(TMatrixRC<T>& rc1, TMatrixRC<T>& rc2);
+
+  //! Define Absolute value for uint_1
+  inline static double Abs_Value(uint_1 v) {return (double) v;}
+  //! Define Absolute value for uint_2
+  inline static double Abs_Value(uint_2 v) {return (double) v;}
+  //! Define Absolute value for int_2
+  inline static double Abs_Value(int_2 v)  {return (v>0)? (double) v: (double) -v;}
+  //! Define Absolute value for int_4
+  inline static double Abs_Value(int_4 v)  {return (v>0)? (double) v: (double) -v;}
+  //! Define Absolute value for int_8
+  inline static double Abs_Value(int_8 v)  {return (v>0)? (double) v: (double) -v;}
+  //! Define Absolute value for uint_4
+  inline static double Abs_Value(uint_4 v) {return (double) v;}
+  //! Define Absolute value for uint_8
+  inline static double Abs_Value(uint_8 v) {return (double) v;}
+  //! Define Absolute value for r_4
+  inline static double Abs_Value(r_4 v)    {return (double) fabs((double)v);}
+  //! Define Absolute value for r_8
+  inline static double Abs_Value(r_8 v)    {return fabs(v);}
+  //! Define Absolute value for complex r_4
+  inline static double Abs_Value(complex<r_4> v)
+                {return sqrt(v.real()*v.real()+v.imag()*v.imag());}
+  //! Define Absolute value for complex r_8
+  inline static double Abs_Value(complex<r_8> v)
+                {return sqrt(v.real()*v.real()+v.imag()*v.imag());}
+
+protected:
+  TMatrix<T>* matrix;  //!< pointer to the TMatrix
+  T*          data;    //!< pointer to the beginnig of interesting datas
+  int_4       index;   //!< index of the line/column
+  uint_4      step;    //!< step of the line/column
+  TRCKind     kind;    //!< type: line, column or diagonal
+};
+
+//! Scalar product of two TMatrixRC
+/*!
+  \return sum[ a(i) * b(i) ]
+ */
+template <class T>
+inline T operator * (const TMatrixRC<T>& a, const TMatrixRC<T>& b)
+  {
+  if ( a.NElts() != b.NElts() )
+    throw(SzMismatchError("TMatrixRC::operator * size mismatch\n"));
+  if ( a.Kind() != b.Kind() )
+    throw(SzMismatchError("TMatrixRC::operator * type mismatch\n"));
+  T sum = 0;
+  for(uint_4 i=0; i<a.NElts(); i++) sum += a(i)*b(i);
+  return sum;
+  }
+
+//! Get the step in datas for a TMatrix for type rckind
+/*!
+  \param rckind : line, column or diagonal
+  \return step in TMatrix along TMatrixRC
+ */
+template <class T>
+inline uint_4 TMatrixRC<T>::Step(const TMatrix<T>& m, TRCKind rckind)
+  { switch (rckind) { case TmatrixRow  : return m.Step(m.ColsKA());
+                      case TmatrixCol  : return m.Step(m.RowsKA());
+                      case TmatrixDiag : return (m.Step(m.RowsKA())+m.Step(m.ColsKA())); }
+    return 0; }
+
+//! Get the origin of datas.
+/*!
+  Get the origin of datas in the TMatrix for a TMatrixRC for type
+  \b rckind and index \b index .
+  \param rckind : line, column or diagonal
+  \param index : index of the line or column.
+  \return adress of the first element in datas.
+ */
+template <class T>
+inline T* TMatrixRC<T>::Org(const TMatrix<T>& m, TRCKind rckind, uint_4 index)
+  { switch (rckind) { case TmatrixRow  : return const_cast<T *>(&(m(index,0)));
+                      case TmatrixCol  : return const_cast<T *>(&(m(0,index)));
+                      case TmatrixDiag : return const_cast<T *>(m.Data()); }
+    return NULL; }
+
+//! return number of elements for a TMatrixRC
+template <class T> inline uint_4 TMatrixRC<T>::NElts() const
+  { if (!matrix) return 0;
+    switch (kind) { case TmatrixRow  : return matrix->NCols();
+                    case TmatrixCol  : return matrix->NRows();
+                    case TmatrixDiag : return matrix->NCols(); }
+    return 0; }
+
+//! access of element \b i
+template <class T>
+inline T& TMatrixRC<T>::operator()(uint_4 i) {return data[i*step];}
+//! access of element \b i
+template <class T>
+inline T  TMatrixRC<T>::operator()(uint_4 i) const {return data[i*step];}
+
+////////////////////////////////////////////////////////////////
+//! Typedef to simplify TMatrixRC<r_8> writing
+typedef TMatrixRC<r_8> MatrixRC;
+
+
+//! Default constructor
+template <class T> TMatrixRC<T>::TMatrixRC()
+: matrix(NULL), data(NULL), index(0), step(0)
+{}
+
+//! Constructor
+/*!
+  \param m : matrix
+  \param rckind : select line, column or diagonal
+  \param ind : number of the line or column
+*/
+template <class T> TMatrixRC<T>::TMatrixRC(TMatrix<T>& m,TRCKind rckind,uint_4 ind)
+: matrix(&m), data(Org(m,rckind,ind)),
+  index(ind), step(Step(m,rckind)), kind(rckind)
+{
+if (kind == TmatrixDiag && m.NCols() != m.NRows())
+  throw(SzMismatchError("TMatrixRC::TMatrixRC(...,TmatrixDiag,...) size mismatch\n"));
+}
+
+////////////////////////////////////////////////////////////////
+// Acces aux rangees et colonnes de matrices
+
+//! Return TMatrixRC for line \b r of matrix \b m
+template <class T> 
+TMatrixRC<T> TMatrixRC<T>::Row(TMatrix<T> & m, uint_4 r) 
+{
+TMatrixRC<T> rc(m, TmatrixRow, r);
+return rc;
+}
+
+//! Return TMatrixRC for column \b r of matrix \b m
+template <class T> 
+TMatrixRC<T> TMatrixRC<T>::Col(TMatrix<T> & m, uint_4 c) 
+{
+TMatrixRC<T> rc(m, TmatrixCol, c);
+return rc;
+}
+
+//! Return TMatrixRC for diagonal of matrix \b m
+template <class T> 
+TMatrixRC<T> TMatrixRC<T>::Diag(TMatrix<T> & m) 
+{
+TMatrixRC<T> rc(m, TmatrixDiag);
+return rc;
+}
+
+
+// ---- A virer   $CHECK$ Reza 03/2000
+// template <class T> int_4 TMatrixRC<T>::Next()
+// {
+// if (!matrix || kind==TmatrixDiag) return -1;
+// index++;
+// if(kind == TmatrixRow) {
+//   if(index > (int_4)matrix->NRows()) {index = (int_4)matrix->NRows(); return -1;}
+//   data += matrix->NCols();
+// } else {
+//   if (index > (int_4)matrix->NCols()) {index = (int_4)matrix->NCols(); return -1;}
+//   data++;
+// }
+// return index;
+// }
+
+// template <class T> int_4 TMatrixRC<T>::Prev()
+// {
+// if (!matrix || kind == TmatrixDiag) return -1;
+// index--;
+// if(index < 0) {index = 0; return -1;}
+// if(kind == TmatrixRow) data -= matrix->NCols();
+// else data--;
+// return index;
+// }
+
+//! Set column \b c for this TMatrixRC
+template <class T> int_4 TMatrixRC<T>::SetCol(int_4 c)
+{
+if(!matrix) return -1;
+if(c<0 || c>(int_4)matrix->NCols()) return -1;
+kind = TmatrixCol;
+index = c;
+step = Step(*matrix, TmatrixCol);
+data = Org(*matrix, TmatrixCol, c);
+return c;
+}
+
+//! Set line \b r for this TMatrixRC
+template <class T> int_4 TMatrixRC<T>::SetRow(int_4 r)
+{
+if(!matrix) return -1;
+if(r<0 && r>(int_4)matrix->NRows()) return -1;
+kind = TmatrixRow;
+index = r;
+step = Step(*matrix, TmatrixRow);
+data = Org(*matrix, TmatrixRow, r);
+return r;
+}
+
+//! Set line diaginal for this TMatrixRC
+template <class T> int_4 TMatrixRC<T>::SetDiag()
+{
+if (!matrix) return -1;
+if (matrix->NCols() != matrix->NRows())
+  throw(SzMismatchError("TMatrixRC::SetDiag size mismatch\n"));
+kind = TmatrixDiag;
+index = 0;
+step = Step(*matrix, TmatrixDiag);
+data = Org(*matrix, TmatrixDiag);
+return 0;
+}
+
+//! Operator =
+template <class T> TMatrixRC<T>& TMatrixRC<T>::operator = (const TMatrixRC<T>& rc)
+{
+matrix = rc.matrix;
+data   = rc.data;
+index  = rc.index;
+step   = rc.step;
+kind   = rc.kind;
+return *this;
+}
+
+// ---- A virer   $CHECK$ Reza 03/2000
+// template <class T> TVector<T> TMatrixRC<T>::GetVect() const
+// {
+// TVector<T> v(NElts());
+// for (uint_4 i=0; i<NElts(); i++) v(i) = (*this)(i);
+// return v;
+// }
+
+// template <class T> TMatrixRC<T>& TMatrixRC<T>::operator += (const TMatrixRC<T>& rc)
+// {
+// if ( NElts() != rc.NElts() )
+//   throw(SzMismatchError("TMatrixRC::operator+= size mismatch\n"));
+// if ( kind != rc.kind )
+//   throw(SzMismatchError("TMatrixRC::operator+= type mismatch\n"));
+// for (uint_4 i=0; i<NElts(); i++) (*this)(i) += rc(i);
+// return *this;
+// }
+
+// template <class T> TMatrixRC<T>& TMatrixRC<T>::operator -= (const TMatrixRC<T>& rc)
+// {
+// if( NElts() != rc.NElts() )
+//   throw(SzMismatchError("TMatrixRC::operator-= size mismatch\n"));
+// if( kind != rc.kind )
+//   throw(SzMismatchError("TMatrixRC::operator-= type mismatch\n"));
+// for(uint_4 i=0; i<NElts(); i++) (*this)(i) -= rc(i);
+// return *this;
+// }
+
+//! Operator to multiply by constant \b x
+template <class T> TMatrixRC<T>& TMatrixRC<T>::operator *= (T x)
+{
+for(uint_4 i=0; i<NElts(); i++) (*this)(i) *= x;
+return *this;
+}
+
+//! Operator to divide by constant \b x
+template <class T> TMatrixRC<T>& TMatrixRC<T>::operator /= (T x)
+{
+for(uint_4 i=0; i<NElts(); i++) (*this)(i) /= x;
+return *this;
+}
+
+
+// ---- A virer   $CHECK$ Reza 03/2000
+// template <class T> TMatrixRC<T>& TMatrixRC<T>::operator -= (T x)
+// {
+// for(uint_4 i=0; i<NElts(); i++) (*this)(i) -= x;
+// return *this;
+// }
+
+// template <class T> TMatrixRC<T>& TMatrixRC<T>::operator += (T x)
+// {
+// for(uint_4 i=0; i<NElts(); i++) (*this)(i) += x;
+// return *this;
+// }
+
+//! Linear combination
+/*!
+  Do : \f$ MRC(i) = MRC(i)*a + rc(i)*b \f$
+  \return *this
+ */
+template <class T>
+TMatrixRC<T>& TMatrixRC<T>::LinComb(T a, T b, const TMatrixRC<T>& rc, uint_4 first)
+{
+if ( NElts() != rc.NElts() )
+  throw(SzMismatchError("TMatrixRC::LinComb size mismatch\n"));
+if ( kind != rc.kind )
+  throw(SzMismatchError("TMatrixRC::LinComb type mismatch\n"));
+for(uint_4 i=first; i<NElts(); i++) (*this)(i) = (*this)(i)*a + rc(i)*b;
+return *this;
+}
+
+//! Linear combination
+/*!
+  Do : \f$ MRC(i) = MRC(i) + rc(i)*b \f$
+ */
+template <class T>
+TMatrixRC<T>& TMatrixRC<T>::LinComb(T b, const TMatrixRC<T>& rc, uint_4 first)
+{
+if ( NElts() != rc.NElts() )
+  throw(SzMismatchError("TMatrixRC::LinComb size mismatch\n"));
+if ( kind != rc.kind )
+  throw(SzMismatchError("TMatrixRC::LinComb type mismatch\n"));
+for(uint_4 i=first; i<NElts(); i++) (*this)(i) += rc(i)*b;
+return *this;
+}
+
+//! Find maximum absolute value in TMatrixRC, search begin at \b first
+template <class T> uint_4 TMatrixRC<T>::IMaxAbs(uint_4 first)
+{
+if (first>NElts())
+  throw(SzMismatchError("TMatrixRC::IMaxAbs size mismatch\n"));
+uint_4 imax = first;
+double vmax = Abs_Value((*this)(first));
+for(uint_4 i=first+1; i<NElts(); i++) {
+  double v = Abs_Value((*this)(i));
+  if(v > vmax) {vmax = v; imax = i;}
+}
+return imax;
+}
+
+//! Print on stream \b os
+template <class T>
+void TMatrixRC<T>::Print(ostream & os) const
+{
+  os << " TMatrixRC<T>::Print(ostream & os) " << NElts() << " Kind=" 
+     << kind << " Index=" << index << " Step= " << step << endl;
+  for(uint_4 i=0; i<NElts(); i++) {
+    os << (*this)(i);
+    if (kind == TmatrixCol)  os << endl;
+    else os << ", "; 
+  }
+  os << endl;
+}
+
+//! Swap two TMatrixRC of the same kind
+template <class T>
+void TMatrixRC<T>::Swap(TMatrixRC<T>& rc1, TMatrixRC<T>& rc2)
+{
+if(rc1.NElts() != rc2.NElts())
+  throw(SzMismatchError("TMatrixRC::Swap size mismatch\n"));
+if(rc1.kind != rc2.kind)
+  throw(SzMismatchError("TMatrixRC::Swap type mismatch\n"));
+if(rc1.data == rc2.data) return;
+for(uint_4 i=0; i<rc1.NElts(); i++)
+  {T tmp = rc1(i); rc1(i) = rc2(i); rc2(i) = tmp;}
+}
+
+
+////////////////////////////////////////////////////////////////
+// ---------------------------------------------------------- //
+//      La classe de calcul simple sur les TMatrix            //
+// ---------------------------------------------------------- //
+////////////////////////////////////////////////////////////////
+
+//**** Pour inversion
+#ifndef M_LN2
+#define M_LN2 0.69314718055994530942
+#endif
+//// CMV BUG BUG : sur OSF 5.0 DMINEXP est deconnant (~1.e+19 !!!)
+#ifndef LN_MINDOUBLE
+#define LN_MINDOUBLE  (M_LN2 * (DMINEXP - 1))
+#endif
+#ifndef LN_MAXDOUBLE
+#define LN_MAXDOUBLE  (M_LN2 * DMAXEXP)
+#endif
+
+template <class T>
+int SimpleMatrixOperation<T>::GausPivScaling = PIV_GLOB_SCALE;
+
+//! Gaussian pivoting
+/*!
+  Do Gauss pivoting of \b a, doing the same operations on matrix \b b
+  \param computedet = true : return determimant of \b a (beware of over/underfloat)
+  \param computedet = false : return 1 if OK, 0 if not.
+  \verbatim
+  Solve linear system A(n,n) * X(n,m) = B(n,m)
+  and put solution X in B for return.
+  \endverbatim
+  \warning If \b b is identity matrix, return inverse of \b a
+  \warning matrix \b a and \b b are modified.
+ */  
+template <class T>
+T SimpleMatrixOperation<T>::GausPiv(TMatrix<T>& a, TMatrix<T>& b,bool computedet)
+// Pivot de Gauss
+// * Attention: egcs impose que cette fonction soit mise dans le .cc
+//              avant ::Inverse() (car Inverse() l'utilise)
+// {TMatrix A(a); TMatrix B(b); return (T) TMatrix::GausPiv(A,B);}
+{
+uint_4 n = a.NRows();
+if(n!=b.NRows())
+  throw(SzMismatchError("TMatrix::GausPiv size mismatch\n"));
+
+T det = 1;
+
+//////////////////
+// Data scaling //
+//////////////////
+
+// Pas de normalisation des donnees
+if(GausPivScaling==PIV_NO_SCALE) {
+  if(computedet) det = (T) 1;
+// normalisation des donnees ligne par ligne
+} else if(GausPivScaling==PIV_ROW_SCALE) {
+  double nrm = 0.;
+  for(uint_4 iii=0; iii<a.NRows(); iii++) {
+    uint_4 jjj; double vmax = -1.;
+    for(jjj=0; jjj<a.NCols(); jjj++) {
+      double v = TMatrixRC<T>::Abs_Value(a(iii,jjj));
+      if(v>vmax) vmax = v;
+    }
+    if(vmax>0.) {
+      for(jjj=0; jjj<a.NCols(); jjj++) a(iii,jjj) /= (T) vmax;
+      for(jjj=0; jjj<b.NCols(); jjj++) b(iii,jjj) /= (T) vmax;
+      nrm += log(vmax);
+    } else return (T) 0;
+  }
+  if(computedet) {
+    if(nrm <= LN_MINDOUBLE || nrm >= LN_MAXDOUBLE) {
+      cerr<<"GausPiv_Row: normalisation failure, "
+          <<"determinant has to be multiplied by exp("<<nrm<<")"<<endl;
+    } else det = (T) exp(nrm);
+  }
+// On fait une normalisation un peu brutale globale
+} else {
+  double vmin=MAXDOUBLE, vmax=0;
+  for(uint_4 iii=0; iii<a.NRows(); iii++)
+    for(uint_4 jjj=0; jjj<a.NCols(); jjj++) {
+      double v = TMatrixRC<T>::Abs_Value(a(iii,jjj));
+      if(v>vmax) vmax = v;
+      if(v<vmin && v>0.) vmin = v;
+  }
+  double nrm = sqrt(vmin*vmax);
+  if(nrm>0.) { a /= (T) nrm; b /= (T) nrm;} else return (T) 0;
+  if(computedet) {
+    nrm = a.NRows() * log(nrm);
+    if (nrm <= LN_MINDOUBLE || nrm >= LN_MAXDOUBLE) {
+      cerr<<"GausPiv_Glob: normalisation failure, "
+          <<"determinant has to be multiplied by exp("<<nrm<<")"<<endl;
+    } else det = (T) exp(nrm);
+  }
+}
+
+////////////////////////////////////////
+// Gaussian elimination with pivoting //
+////////////////////////////////////////
+
+TMatrixRC<T> pivRowa(a,TMatrixRC<T>::TmatrixRow);
+TMatrixRC<T> pivRowb(b,TMatrixRC<T>::TmatrixRow);
+
+for(uint_4 k=0; k<n-1; k++) {
+  uint_4 iPiv = TMatrixRC<T>::Col(a, k).IMaxAbs(k);
+  if(iPiv != k) {
+    TMatrixRC<T> aIPiv(TMatrixRC<T>::Row(a,iPiv));
+    TMatrixRC<T> aK(TMatrixRC<T>::Row(a, k));
+    TMatrixRC<T>::Swap(aIPiv,aK);
+    TMatrixRC<T> bIPiv(TMatrixRC<T>::Row(b, iPiv));
+    TMatrixRC<T> bK(TMatrixRC<T>::Row(b, k));
+    TMatrixRC<T>::Swap(bIPiv,bK);
+  }
+  T pivot = a(k,k);
+  if( TMatrixRC<T>::Abs_Value(pivot) < 1.e-50 ) return (T) 0;
+  if(computedet) det *= pivot;
+  pivRowa.SetRow(k); // to avoid constructors
+  pivRowb.SetRow(k);
+  for (uint_4 i=k+1; i<n; i++) {
+    T r = -a(i,k)/pivot;
+    TMatrixRC<T>::Row(a, i).LinComb(r, pivRowa); // + rapide que -= r * pivRowa
+    TMatrixRC<T>::Row(b, i).LinComb(r, pivRowb);
+  }
+}
+if(computedet) det *= a(n-1, n-1);
+
+// on remonte
+for(uint_4 kk=n-1; kk>0; kk--) {
+  T pivot = a(kk,kk);
+  if( TMatrixRC<T>::Abs_Value(pivot) <= 1.e-50 ) return (T) 0;
+  pivRowa.SetRow(kk); // to avoid constructors
+  pivRowb.SetRow(kk);
+  for(uint_4 jj=0; jj<kk; jj++) {
+    T r = -a(jj,kk)/pivot;
+    TMatrixRC<T>::Row(a, jj).LinComb(r, pivRowa);
+    TMatrixRC<T>::Row(b, jj).LinComb(r, pivRowb);
+  }
+}
+
+for(uint_4 l=0; l<n; l++) {
+  if( TMatrixRC<T>::Abs_Value(a(l,l)) <= 1.e-50 ) return (T) 0;
+  TMatrixRC<T>::Row(b, l) /= a(l,l);
+}
+
+return det;
+}
+
+//! Return the inverse matrix of \b A
+template <class T>
+TMatrix<T> SimpleMatrixOperation<T>::Inverse(TMatrix<T> const & A) 
+{
+TMatrix<T> a(A,false);
+TMatrix<T> b(a.NCols(),a.NRows());  b = IdentityMatrix(1.);
+if(GausPiv(a,b)==(T) 0)
+  throw(MathExc("TMatrix Inverse() Singular Matrix"));
+return b;
+}
+
+
+////////////////////////////////////////////////////////////////
+// ---------------------------------------------------------- //
+//               La classe fit lineaire                       //
+// ---------------------------------------------------------- //
+////////////////////////////////////////////////////////////////
+
+//! Creator
+template <class T>
+LinFitter<T>::LinFitter()
+{
+}
+
+//! Destructor
+template <class T>
+LinFitter<T>::~LinFitter()
+{
+}
+
+// fit lineaire des y(k) en tant que somme de c(i)f(i,x(k)), i=0..nf-1;
+//! Linear fitting
+/*!
+  Linear fit of y(k) as the sum of \f$ c(i)f(i,x(k)), i=0..nf-1 \f$
+  \param x : vector of X values
+  \param y : vector of datas
+  \param nf: number of functions
+  \param f : f(i,x(k)), i=0..nf-1
+  \return c : vector of solutions
+  \return return chisquare
+ */
+template <class T>
+r_8 LinFitter<T>::LinFit(const TVector<T>& x, const TVector<T>& y,
+                       uint_4 nf, T (*f)(uint_4,T), TVector<T>& c)
+{
+uint_4 n = x.NElts();
+if (n != y.NElts()) THROW(sizeMismatchErr);
+ 
+TMatrix<T> fx(nf,n);
+
+for(uint_4 i=0; i<nf; i++)
+  for(uint_4 j=0; j<n; j++) fx(i,j) = f(i,x(j));
+
+return LinFit(fx,y,c);
+}
+
+// fit lineaire des y(k) en tant que somme de c(i)f(i,x(k)), i=0..nf-1,
+// la matrice fx contient les valeurs des f: fx(i,j) = f(i, x(j)).
+//! Linear fitting
+/*!
+  Linear fit of y(k) as the sum of \f$ c(i)f(i,x(k)), i=0..nf-1 \f$.
+  \param fx : matrix which contains \f$ fx(i,j) = f(i, x(j)) \f$.
+  \param y : vector of datas
+  \return c : vector of solutions
+  \return return chisquare
+ */
+template <class T>
+r_8 LinFitter<T>::LinFit(const TMatrix<T>& fx, const TVector<T>& y, TVector<T>& c)
+{
+uint_4 n = y.NElts();
+if (n != fx.NCol()) THROW(sizeMismatchErr);
+
+uint_4 nf = fx.NRows();
+
+TMatrix<T> a(nf,nf);
+
+for(uint_4 j=0; j<nf; j++)
+  for(uint_4 k=j; k<nf; k++)
+     a(j,k) = a(k,j) = TMatrixRC<T>::Row(const_cast<TMatrix<T> &>(fx), j) 
+	             * TMatrixRC<T>::Row(const_cast<TMatrix<T> &>(fx), k);
+
+c = fx * y;
+
+if(SimpleMatrixOperation<T>::GausPiv(a,c)==(T) 0) THROW(singMatxErr);
+
+r_8 xi2 = 0., ax;
+T x;
+for(uint_4 k=0; k<n; k++) {
+  x = (T) 0;
+  for(uint_4 i=0; i<nf; i++) x += c(i) * fx(i,k);
+  x -= y(k);
+  ax = TMatrixRC<T>::Abs_Value(x);
+  xi2 += ax*ax;
+}
+return xi2;
+}
+
+// fit lineaire des y(k) en tant que somme de c(i)f(i,x(k)), i=0..nf-1,
+// errY2 contient les carres des erreurs sur les Y.
+// au retour, errC contient les erreurs sur les coefs.
+//! Linear fitting with errors
+/*!
+  Linear fit with errors of y(k) as the sum of \f$ c(i)f(i,x(k)), i=0..nf-1 \f$.
+  \param x : vector of X values
+  \param y : vector of datas
+  \param errY2 : vector of errors square on Y
+  \param nf: number of functions
+  \param f : f(i,x(k)), i=0..nf-1
+  \return c : vector of solutions
+  \return errC : vector of errors on solutions C
+  \return return chisquare
+ */
+template <class T>
+r_8 LinFitter<T>::LinFit(const TVector<T>& x, const TVector<T>& y,
+             const TVector<T>& errY2, uint_4 nf, T (*f)(uint_4,T),
+                                  TVector<T>& c, TVector<T>& errC)
+{
+uint_4 n = x.NElts();
+if (n != y.NElts()) THROW(sizeMismatchErr);
+
+TMatrix<T> fx(nf, n);
+for(uint_4 i=0; i<nf; i++)
+  for(uint_4 j=0; j<n; j++)
+    fx(i,j) = f(i,x(j));
+
+return LinFit(fx,y,errY2,c,errC);
+}
+
+// fit lineaire des y(k) en tant que somme de c(i)f(i,x(k)), i=0..nf-1,
+// la matrice fx contient les valeurs des f:
+// fx(i,j) = f(i, x(j)).
+// errY2 contient les carres des erreurs sur les Y.
+// au retour, errC contient les erreurs sur les coefs.
+//! Linear fitting with errors
+/*!
+  \param fx : matrix which contains \f$ fx(i,j) = f(i, x(j)) \f$.
+  \param y : vector of datas
+  \param errY2 : vector of errors square on Y
+  \return c : vector of solutions
+  \return errC : vector of errors on solutions on C
+  \return return chisquare
+ */
+template <class T>
+r_8 LinFitter<T>::LinFit(const TMatrix<T>& fx, const TVector<T>& y,
+           const TVector<T>& errY2,TVector<T>& c, TVector<T>& errC)
+{
+uint_4 n = y.NElts();
+if( n != errY2.NElts()) THROW(sizeMismatchErr);
+if( n != fx.NCol()) THROW(sizeMismatchErr);
+
+uint_4 nf = fx.NRows();
+
+TMatrix<T> a(nf,nf);
+
+c.Realloc(nf);
+errC.Realloc(nf);
+
+for(uint_4 j=0; j<nf; j++)
+  for(uint_4 k=j; k<nf; k++) {
+    T x=0;
+    // Matrice a inverser
+    for(uint_4 l=0; l<n; l++) x += fx(j,l)*fx(k,l)/errY2(l);
+    a(j,k) = a(k,j) = x;
+  }
+ 
+TMatrix<T> d(nf,nf+1);
+for(uint_4 k=0; k<nf; k++) {
+  T x = (T) 0;
+  // Second membre 1ere colonne
+  for(uint_4 l=0; l<n; l++) x += fx(k,l)*y(l)/errY2(l);             
+  d(k,0) = x;
+  // Reste second membre = Id.
+  for(uint_4 m=1; m<=nf; m++) d(k,m) = (k==m)?1:0;
+}
+
+if(SimpleMatrixOperation<T>::GausPiv(a,d)==(T) 0) THROW(singMatxErr);
+
+for(uint_4 l=0; l<nf; l++) {
+  c(l) = d(l,0);        // Parametres = 1ere colonne
+  errC(l) = d(l,l+1);   // Erreurs = diag inverse.
+}
+
+r_8 xi2 = 0., ax;
+T x;
+for(uint_4 jj=0; jj<n; jj++) {
+  x = (T) 0;
+  for(uint_4 ii=0; ii<nf; ii++) x += c(ii) * fx(ii,jj);
+    x -= y(jj);
+    ax = TMatrixRC<T>::Abs_Value(x);
+    xi2 += ax*ax/TMatrixRC<T>::Abs_Value(errY2(jj));
+  }
+  return xi2;
+}
+
+///////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+void _ZZ_TestTMatrixRC_YY_(TMatrix<r_8> & m)
+{
+  cout << " ::::: _ZZ_TestTMatrixRC_YY_ :::: M= \n" << m << endl;
+  TMatrixRC<r_8> l0 = TMatrixRC<r_8>::Row(m,0);
+  cout << "TMatrixRC<r_8>::Row(m,0) = \n" ;
+  l0.Print(cout);
+  TMatrixRC<r_8> l1 = TMatrixRC<r_8>::Row(m,1);
+  cout << "TMatrixRC<r_8>::Row(m,1) = \n" ;
+  l1.Print(cout);
+  l0.SetRow(2);
+  cout << "TMatrixRC<r_8>::l0.SetRow(2 = \n" ;
+  l0.Print(cout);
+
+  TMatrixRC<r_8> c0 = TMatrixRC<r_8>::Col(m,0);
+  cout << "TMatrixRC<r_8>::Col(m,0) = \n" ;
+  c0.Print(cout);
+  TMatrixRC<r_8> c1 = TMatrixRC<r_8>::Col(m,1);
+  cout << "TMatrixRC<r_8>::Col(m,1) = \n" ;
+  c1.Print(cout);  
+  c0.SetCol(2);
+  cout << "TMatrixRC<r_8>::c0.SetCol(2) = \n" ;
+  c0.Print(cout);
+  TMatrixRC<r_8> c00 = TMatrixRC<r_8>::Col(m,0);
+  TMatrixRC<r_8>::Swap(c0, c00);
+  cout << " :::::  M Apres Swap = \n" << m << endl;
+  
+}
+
+///////////////////////////////////////////////////////////////
+#ifdef __CXX_PRAGMA_TEMPLATES__
+// Instances gestion lignes/colonnes
+#pragma define_template TMatrixRC<int_4>
+#pragma define_template TMatrixRC<r_4>
+#pragma define_template TMatrixRC<r_8>
+#pragma define_template TMatrixRC< complex<r_4> >
+#pragma define_template TMatrixRC< complex<r_8> >
+#pragma define_template SimpleMatrixOperation<int_4>
+#pragma define_template SimpleMatrixOperation<r_4>
+#pragma define_template SimpleMatrixOperation<r_8>
+#pragma define_template SimpleMatrixOperation< complex<r_4> >
+#pragma define_template SimpleMatrixOperation< complex<r_8> >
+#pragma define_template LinFitter<r_4>
+#pragma define_template LinFitter<r_8>
+#pragma define_template LinFitter< complex<r_4> >
+#pragma define_template LinFitter< complex<r_8> >
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+// Instances gestion lignes/colonnes
+template class TMatrixRC<int_4>;
+template class TMatrixRC<r_4>;
+template class TMatrixRC<r_8>;
+template class TMatrixRC< complex<r_4> >;
+template class TMatrixRC< complex<r_8> >;
+template class SimpleMatrixOperation<int_4>;
+template class SimpleMatrixOperation<r_4>;
+template class SimpleMatrixOperation<r_8>;
+template class SimpleMatrixOperation< complex<r_4> >;
+template class SimpleMatrixOperation< complex<r_8> >;
+template class LinFitter<r_4>;
+template class LinFitter<r_8>;
+template class LinFitter< complex<r_4> >;
+template class LinFitter< complex<r_8> >;
+#endif
+
Index: /tags/V_Dec2002/SophyaLib/TArray/sopemtx.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/TArray/sopemtx.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/TArray/sopemtx.h	(revision 2309)
@@ -0,0 +1,180 @@
+// This may look like C code, but it is really -*- C++ -*-
+#ifndef SOpeMatrix_SEEN
+#define SOpeMatrix_SEEN
+
+#include "machdefs.h"
+#include "tmatrix.h"
+#include "tvector.h"
+
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+//------------------------------------------------------------//
+//      La classe de calcul simple sur les TMatrix            //
+//------------------------------------------------------------//
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+
+namespace SOPHYA {
+
+/*!
+  \class SimpleMatrixOperation
+  \ingroup TArray
+  Class for simple operation on TMatrix
+  \sa TMatrix TArray
+*/
+//! Class for simple operation on TMatrix
+template <class T>
+class SimpleMatrixOperation {
+public:
+  //! To define the type of data scaling for Gauss pivoting method (type T)
+  enum GausPivScal {
+    PIV_NO_SCALE = 0,   //!< do not scale datas for gauss pivoting
+    PIV_GLOB_SCALE = 1, //!< do a global scaling of datas for gauss pivoting (default)
+    PIV_ROW_SCALE = 2   //!< do a scaling by row of datas for gauss pivoting
+  };
+  static inline int SetGausPivScal(int gps = PIV_GLOB_SCALE)
+              { GausPivScaling = gps; return GausPivScaling; }
+
+  static TMatrix<T> Inverse(TMatrix<T> const & A);
+  static T GausPiv(TMatrix<T>& A, TMatrix<T>& B, bool computedet=false);
+
+protected:
+  static int GausPivScaling;
+};
+
+} // Fin du namespace
+
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+//------------------------------------------------------------//
+//              Resolution de systemes lineaires              //
+//------------------------------------------------------------//
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+
+namespace SOPHYA {
+
+//------------------------------------------------------------
+// Resolution du systeme A*C = B
+//------------------------------------------------------------
+/*! \ingroup TArray \fn LinSolveInPlace(TMatrix<T>&,TVector<T>&)
+    \brief  Solve A*C = B for C in place and return 1 if OK, 0 if not.
+*/
+template <class T>
+inline T LinSolveInPlace(TMatrix<T>& a, TVector<T>& b)
+{
+if(a.NCols() != b.NRows() || a.NCols() != a.NRows())
+  throw(SzMismatchError("LinSolveInPlace(TMatrix<T>,TVector<T>) size mismatch"));
+return SimpleMatrixOperation<T>::GausPiv(a,b);
+}
+
+//------------------------------------------------------------
+// Resolution du systeme A*C = B, avec C retourne dans B
+//------------------------------------------------------------
+/*! \ingroup TArray 
+    \fn LinSolve(const TMatrix<T>&, const TVector<T>&, TVector<T>&)
+    \brief Solve A*C = B and return C. Return 1 if OK, 0 if not.
+*/
+template <class T>
+inline T LinSolve(const TMatrix<T>& a, const TVector<T>& b, TVector<T>& c) {
+  if(a.NCols()!=b.NRows() || a.NCols()!=a.NRows())
+    throw(SzMismatchError("LinSolve(TMatrix<T>,TVector<T>) size mismatch"));
+    c = b; TMatrix<T> a1(a);
+  return SimpleMatrixOperation<T>::GausPiv(a1,c);
+}
+
+} // Fin du namespace
+
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+//------------------------------------------------------------//
+//                   Inverse d'une matrice                    //
+//------------------------------------------------------------//
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+
+namespace SOPHYA {
+
+/*! \ingroup TArray 
+    \fn Inverse(TMatrix<T> const &)
+    \brief To inverse a TMatrix.
+*/
+template <class T>
+inline TMatrix<T> Inverse(TMatrix<T> const & A)
+  {return SimpleMatrixOperation<T>::Inverse(A);}
+
+/*! \ingroup TArray 
+    \fn Determinant(TMatrix<T> const &)
+    \brief Return the TMatrix determinant
+*/
+template <class T>
+inline T Determinant(TMatrix<T> const & A) {
+  TMatrix<T> a(A,false);
+  TMatrix<T> b(a.NCols(),a.NRows());  b = IdentityMatrix(1.);
+  return SimpleMatrixOperation<T>::GausPiv(a,b,true);
+}
+
+/*! \ingroup TArray 
+    \fn GausPiv(TMatrix<T> const &,TMatrix<T> &, bool)
+    \brief Gauss pivoting on matrix \b A, doing the same operations
+           on matrix \b B.
+    \param computedet = true : return the determinant of \b A
+           (beware of over/underfloat), default is false.
+    \return determinant if requested, or 1 if OK.
+    \sa SOPHYA::SimpleMatrixOperation::GausPiv(TMatrix<T>&,TMatrix<T>&,bool)
+*/
+template <class T>
+inline T GausPiv(TMatrix<T> const & A,TMatrix<T> & B, bool computedet=false) {
+  TMatrix<T> a(A,false);
+  return SimpleMatrixOperation<T>::GausPiv(a,B,computedet);
+}
+
+
+} // Fin du namespace
+
+
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+//------------------------------------------------------------//
+//                   Linear fitting                           //
+//------------------------------------------------------------//
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+
+namespace SOPHYA {
+
+/*!
+  \class LinFitter
+  \ingroup TArray
+  Class for linear fitting
+  \sa TMatrix TArray
+*/
+
+//!  Class for linear fitting
+template <class T>
+class LinFitter {
+
+public :
+
+         LinFitter();
+virtual	~LinFitter();
+
+//! Linear fitting
+r_8 LinFit(const TVector<T>& x, const TVector<T>& y,
+	   uint_4 nf, T (*f)(uint_4,T), TVector<T>& c);
+
+//! Linear fitting
+r_8 LinFit(const TMatrix<T>& fx, const TVector<T>& y, TVector<T>& c);
+		      
+//! Linear fitting with errors
+r_8 LinFit(const TVector<T>& x, const TVector<T>& y, const TVector<T>& errY2,
+           uint_4 nf,T (*f)(uint_4,T), TVector<T>& c, TVector<T>& errC);
+
+//! Linear fitting with errors
+r_8 LinFit(const TMatrix<T>& fx, const TVector<T>& y,
+           const TVector<T>& errY2, TVector<T>& c, TVector<T>& errC);
+};
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/TArray/tarray.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/TArray/tarray.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/TArray/tarray.cc	(revision 2309)
@@ -0,0 +1,1167 @@
+//      template array class for numerical types
+//                     R. Ansari, C.Magneville   03/2000
+
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "pexceptions.h"
+#include "tarray.h"
+
+/*!
+  \class SOPHYA::TArray
+  \ingroup TArray
+  Class for template arrays with numerical data types (int, float, complex).
+
+  This class implements arrays with number of dimensions up to
+  \ref BASEARRAY_MAXNDIMS "BASEARRAY_MAXNDIMS"
+
+  Standard arithmetic operations on numerical arrays are implemented,
+  as well as sub-array manipulation services.
+  \b Array is a typedef for double precision floating point arrays ( TArray<r_8> )
+  \sa SOPHYA::Range
+  \sa SOPHYA::Sequence
+  \sa SOPHYA::MathArray
+
+  \code
+  #include "array.h"
+  // ...
+  // Creating and initialising a 1-D array of integers
+  TArray<int> ia(5);
+  EnumeratedSequence es;
+  es = 24, 35, 46, 57, 68;
+  ia = es;
+  cout << "Array<int> ia = " << ia;
+  // 2-D array of floats 
+  TArray<r_4> b(6,4), c(6,4);
+  // Initializing b with a constant
+  b = 2.71828;
+  // Filling c with random numbers  
+  c = RandomSequence(); 
+  // Arithmetic operations
+  TArray<r_4> d = b+0.3f*c;
+  cout << "Array<float> d = " << d;  
+  \endcode
+
+*/
+
+/*! \ingroup TArray
+  \typedef sa_size_t
+  \brief Array index range and size, defined to be a 4-byte or 8-byte integer 
+*/
+
+// -------------------------------------------------------
+//                Methodes de la classe
+// -------------------------------------------------------
+
+////////////////////////// Les constructeurs / destructeurs
+
+//! Default constructor
+template <class T>
+TArray<T>::TArray()
+  : BaseArray() , mNDBlock() 
+{
+}
+
+//! Constructor
+/*!
+  \param ndim : number of dimensions (less or equal to
+                \ref BASEARRAY_MAXNDIMS "BASEARRAY_MAXNDIMS")
+  \param siz[ndim] : size along each dimension
+  \param step : step (same for all dimensions)
+ */
+template <class T>
+TArray<T>::TArray(int_4 ndim, const sa_size_t * siz, sa_size_t step)
+  : BaseArray() , mNDBlock(ComputeTotalSize(ndim, siz, step, 1))
+{
+  string exmsg = "TArray<T>::TArray(int_4, sa_size_t *, sa_size_t)";
+  if (!UpdateSizes(ndim, siz, step, 0, exmsg))  throw( ParmError(exmsg) );
+}
+
+//! Constructor
+/*!
+  \param nx,ny,nz,nt,nu : sizes along first, second, third, fourth and fifth dimension
+ */
+template <class T>
+TArray<T>::TArray(sa_size_t nx, sa_size_t ny, sa_size_t nz, sa_size_t nt, sa_size_t nu)
+  : BaseArray() , mNDBlock(nx*((ny>0)?ny:1)*((nz>0)?nz:1)*((nt>0)?nt:1)*((nu>0)?nu:1)) 
+{
+  sa_size_t size[BASEARRAY_MAXNDIMS];
+  size[0] = nx;   size[1] = ny;   size[2] = nz;
+  size[3] = nt;   size[4] = nu;
+  int_4 ndim = 1;
+  if ((size[1] > 0) && (size[2] > 0) && (size[3] > 0) && (size[4] > 0) ) ndim = 5;
+  else if ((size[1] > 0) && (size[2] > 0) && (size[3] > 0) ) ndim = 4;
+  else if ((size[1] > 0) && (size[2] > 0)) ndim = 3;
+  else if (size[1] > 0)  ndim = 2;
+  else ndim = 1;
+  string exmsg = "TArray<T>::TArray(sa_size_t, sa_size_t, sa_size_t, sa_size_t, sa_size_t)";
+  if (!UpdateSizes(ndim, size, 1, 0, exmsg))  throw( ParmError(exmsg) );
+}
+
+//! Constructor
+/*!
+  \param ndim : number of dimensions
+  \param siz[ndim] : size along each dimension
+  \param db : datas are given by this NDataBlock
+  \param share : if true, data are shared, if false they are copied
+  \param step : step (same for all dimensions) in data block
+  \param offset : offset for first element in data block
+ */
+template <class T>
+TArray<T>::TArray(int_4 ndim, const sa_size_t * siz, NDataBlock<T> & db, bool share, sa_size_t step, sa_size_t offset)
+  : BaseArray() , mNDBlock(db, share) 
+{
+  string exmsg = "TArray<T>::TArray(int_4, sa_size_t *,  NDataBlock<T> & ... )";
+  if (!UpdateSizes(ndim, siz, step, offset, exmsg))  throw( ParmError(exmsg) );
+  if (mNDBlock.Size() < ComputeTotalSize(ndim, siz, step, offset)) {
+    exmsg += " DataBlock.Size() < ComputeTotalSize(...) " ;
+    throw( ParmError(exmsg) );
+  }
+}
+
+//! Constructor
+/*!
+  \param ndim : number of dimensions
+  \param siz[ndim] : size along each dimension
+  \param values : datas are given by this pointer
+  \param share : if true, data are shared, if false they are copied
+  \param step : step (same for all dimensions) in data block
+  \param offset : offset for first element in data block
+  \param br : if not NULL, dats are bridge with other datas
+  \sa NDataBlock
+ */
+template <class T>
+TArray<T>::TArray(int_4 ndim, const sa_size_t * siz, T* values, sa_size_t step, sa_size_t offset, Bridge* br)
+  : BaseArray() , mNDBlock(ComputeTotalSize(ndim, siz, step, 1), values, br) 
+{
+  string exmsg = "TArray<T>::TArray(int_4, sa_size_t *, T* ... )";
+  if (!UpdateSizes(ndim, siz, step, offset, exmsg))  throw( ParmError(exmsg) );
+}
+
+//! Constructor by copy
+/*!
+  \warning datas are \b SHARED with \b a.
+  \sa NDataBlock::NDataBlock(const NDataBlock<T>&)
+ */
+template <class T>
+TArray<T>::TArray(const TArray<T>& a)
+  : BaseArray() , mNDBlock(a.mNDBlock) 
+{
+  string exmsg = "TArray<T>::TArray(const TArray<T>&)";
+  if (!UpdateSizes(a, exmsg))  throw( ParmError(exmsg) );
+  if (a.mInfo) mInfo = new DVList(*(a.mInfo));
+}
+
+//! Constructor by copy
+/*!
+  \param share : if true, data are shared, if false they are copied
+ */
+template <class T>
+TArray<T>::TArray(const TArray<T>& a, bool share)
+  : BaseArray() , mNDBlock(a.mNDBlock, share) 
+{
+  if (a.NbDimensions() == 0)  return;  
+  string exmsg = "TArray<T>::TArray(const TArray<T>&, bool)";
+  if (!UpdateSizes(a, exmsg))  throw( ParmError(exmsg) );
+  if (a.mInfo) mInfo = new DVList(*(a.mInfo));
+}
+
+//! Constructor with size and contents copied (after conversion) from a different type TArray
+template <class T>
+TArray<T>::TArray(const BaseArray& a)
+  : BaseArray() , mNDBlock() 
+{
+  if (a.NbDimensions() == 0)  return;  
+  string exmsg = "TArray<T>::TArray(const BaseArray&)";
+  if (!UpdateSizes(a, exmsg))  throw( ParmError(exmsg) );
+  mNDBlock.ReSize(totsize_);    
+  //  if (a.mInfo) mInfo = new DVList(*(a.mInfo));  - pb protected !
+  ConvertAndCopyElt(a);
+}
+
+//! Destructor 
+template <class T>
+TArray<T>::~TArray()
+{
+}
+
+////////////////////////// Les methodes de copie/share
+
+//! Set array equal to \b a and return *this
+/*!
+  If the array is already allocated, CopyElt() is called
+  for checking that the two arrays have the same size and
+  for copying the array element values. For non allocated 
+  arrays,  CloneOrShare() is called. The array memory 
+  organization is also copied from \b a.
+  \warning Datas are copied (cloned) from \b a.
+  \sa CopyElt 
+  \sa CloneOrShare
+  \sa NDataBlock::operator=(const NDataBlock<T>&)
+*/
+template <class T>
+TArray<T>& TArray<T>::Set(const TArray<T>& a)
+{
+  if (this == &a) return(*this);
+  if (a.NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::Set(a ) - Array a not allocated ! ");
+  if (NbDimensions() < 1) CloneOrShare(a);
+  else CopyElt(a);
+  return(*this);
+}
+
+//! Set array elements equal to the \b a array elements, after conversion 
+template <class T>
+TArray<T>& TArray<T>::SetBA(const BaseArray& a)
+{
+  if (this == &a) return(*this);
+  if (a.NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::SetBA(a ) - Array a not allocated ! ");
+  if (NbDimensions() < 1) {
+    string exmsg = "TArray<T>::SetBA(const BaseArray& a)";
+    if (!UpdateSizes(a, exmsg))  throw( ParmError(exmsg) );
+    mNDBlock.ReSize(totsize_);    
+  }
+  ConvertAndCopyElt(a);
+  return(*this);
+}
+
+//! Clone array \b a
+template <class T>
+void TArray<T>::Clone(const TArray<T>& a)
+{
+  string exmsg = "TArray<T>::Clone()";
+  if (!UpdateSizes(a, exmsg))  throw( ParmError(exmsg) );
+  mNDBlock.Clone(a.mNDBlock);
+  if (mInfo) {delete mInfo; mInfo = NULL;}
+  if (a.mInfo) mInfo = new DVList(*(a.mInfo));
+}
+
+//! Clone if \b a is not temporary, share if temporary
+/*! \sa NDataBlock::CloneOrShare(const NDataBlock<T>&) */
+template <class T>
+void TArray<T>::CloneOrShare(const TArray<T>& a)
+{
+  string exmsg = "TArray<T>::CloneOrShare()";
+  if (!UpdateSizes(a, exmsg))  throw( ParmError(exmsg) );
+  mNDBlock.CloneOrShare(a.mNDBlock);
+  if (mInfo) {delete mInfo; mInfo = NULL;}
+  if (a.mInfo) mInfo = new DVList(*(a.mInfo));
+}
+
+//! Share data with a
+template <class T>
+void TArray<T>::Share(const TArray<T>& a)
+{
+  string exmsg = "TArray<T>::Share()";
+  if (!UpdateSizes(a, exmsg))  throw( ParmError(exmsg) );
+  mNDBlock.Share(a.mNDBlock);
+  if (mInfo) {delete mInfo; mInfo = NULL;}
+  if (a.mInfo) mInfo = new DVList(*(a.mInfo));
+}
+
+
+//! Sets or changes the array size 
+/*!
+  \param ndim : number of dimensions
+  \param siz[ndim] : size along each dimension
+  \param step : step (same for all dimensions)
+ */
+template <class T>
+void TArray<T>::ReSize(int_4 ndim, sa_size_t * siz, sa_size_t step)
+{
+  if (arrtype_ != 0) {
+    if (ndim != 2) 
+       throw( ParmError("TArray<T>::ReSize(ndim!=2,...) for Matrix" ) ); 
+    if ((arrtype_ == 2) && (siz[0] > 1) && (siz[1] > 1)) 
+       throw( ParmError("TArray<T>::ReSize(,siz[0]>1 && size[1]>1) for Vector" ) ); 
+  }
+  string exmsg = "TArray<T>::ReSize(int_4 ...)";
+  if (!UpdateSizes(ndim, siz, step, 0, exmsg))  throw( ParmError(exmsg) );
+  mNDBlock.ReSize(totsize_);    
+}
+
+//! Sets or changes the array size.
+/*!
+  The array size and memory layout are copied from the array \b a.
+  \param a : Array used as template for setting the size and memory layout.
+ */
+template <class T>
+void TArray<T>::ReSize(const BaseArray& a)
+{
+  if (arrtype_ != 0) {
+    if (a.NbDimensions() != 2) 
+       throw( ParmError("TArray<T>::ReSize(a.NbDimensions()!=2,...) for Matrix" ) ); 
+    if ((arrtype_ == 2) && (a.Size(0) > 1) && (a.Size(1) > 1)) 
+       throw( ParmError("TArray<T>::ReSize(a.Size(0)>1 && a.Size(1)>1) for Vector" ) ); 
+  }
+  string exmsg = "TArray<T>::ReSize(const TArray<T>&)";
+  if (!UpdateSizes(a, exmsg))  throw( ParmError(exmsg) );
+  mNDBlock.ReSize(totsize_);      
+}
+
+//! Re-allocate space for array
+/*!
+  \param ndim : number of dimensions
+  \param siz[ndim] : size along each dimension
+  \param step : step (same for all dimensions)
+  \param force : if true re-allocation is forced, if not it occurs
+          only if the required space is greater than the old one.
+ */
+template <class T>
+void TArray<T>::Realloc(int_4 ndim, sa_size_t * siz, sa_size_t step, bool force)
+{
+  if (arrtype_ != 0) {
+    if (ndim != 2) 
+       throw( ParmError("TArray<T>::Realloc(ndim!=2,...) for Matrix" ) ); 
+    if ((arrtype_ == 2) && (siz[0] > 1) && (siz[1] > 1)) 
+       throw( ParmError("TArray<T>::Realloc(,siz[0]>1 && size[1]>1) for Vector" ) ); 
+  }
+  string exmsg = "TArray<T>::Realloc()";
+  if (!UpdateSizes(ndim, siz, step, 0, exmsg))  throw( ParmError(exmsg) );
+  mNDBlock.Realloc(totsize_, force);    
+}
+
+
+//! Compact dimensions in one or more is equal to 1.
+template <class T>
+TArray<T>& TArray<T>::CompactAllDimensions()
+{
+  CompactAllDim();
+  return(*this);
+}
+
+//! Compact dimensions if the last one is equal to 1.
+template <class T>
+TArray<T>& TArray<T>::CompactTrailingDimensions()
+{
+  CompactTrailingDim();
+  return(*this);
+}
+
+//! Give value (in \b double) for element at position \b ip..
+template <class T>
+MuTyV & TArray<T>::ValueAtPosition(sa_size_t ip) const
+{
+#ifdef SO_BOUNDCHECKING
+  if (ip >= totsize_)  throw( ParmError("TArray<T>::ValueAtPosition(sa_size_t ip) Out-of-bound Error") );
+#endif
+  my_mtv = *(mNDBlock.Begin()+Offset(ip));
+  return( my_mtv );
+}
+
+//! Return array with elements packed
+/*!
+  \param force : if true, pack elements in a new array.
+                 If false and array is already packed, return
+                 an array that share data with the current one.
+  \return packed array
+ */
+template <class T>
+TArray<T> TArray<T>::PackElements(bool force) const
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::PackElements() - Not Allocated Array ! ");
+  if ( !force && (AvgStep() == 1) ) {
+    TArray<T> ra;
+    ra.Share(*this);
+    ra.SetTemp(true);
+    return(ra);
+  }
+  else {
+    TArray<T> ra(ndim_, size_, 1);
+    ra.CopyElt(*this);
+    ra.SetTemp(true);
+    return(ra);
+  }
+}
+
+// SubArrays 
+// $CHECK$ Reza 03/2000  Doit-on declarer cette methode const ?
+//! Extract a sub-array
+/*!
+  \param rx,ry,rz,rt,ru : range of extraction along dimensions
+  \sa Range
+ */
+template <class T>
+TArray<T> TArray<T>::SubArray(Range rx, Range ry, Range rz, Range rt, Range ru) const
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::operator () (Range, ...) - Not Allocated Array ! ");
+  int_4 ndim = 0;
+  sa_size_t size[BASEARRAY_MAXNDIMS];
+  sa_size_t step[BASEARRAY_MAXNDIMS];
+  sa_size_t pos[BASEARRAY_MAXNDIMS];
+  size[0] = rx.Size();
+  size[1] = ry.Size();
+  size[2] = rz.Size();
+  size[3] = rt.Size();
+  size[4] = ru.Size();
+
+  step[0] = rx.Step();
+  step[1] = ry.Step();
+  step[2] = rz.Step();
+  step[3] = rt.Step();
+  step[4] = ru.Step();
+
+  pos[0] = rx.Start();
+  pos[1] = ry.Start();
+  pos[2] = rz.Start();
+  pos[3] = rt.Start();
+  pos[4] = ru.Start();
+
+  ndim = ndim_;
+  TArray<T> ra;
+  UpdateSubArraySizes(ra, ndim, size, pos, step); 
+  ra.DataBlock().Share(this->DataBlock());
+  ra.SetTemp(true);
+  return(ra);
+}
+
+//   ...... Operation de calcul sur les tableaux ......
+//              ------- Attention --------
+//  Boucles normales prenant en compte les steps ....
+//  Possibilite de // , vectorisation
+
+//! Fill TArray with Sequence \b seq
+/*!
+  \param seq : sequence to fill the array
+  \sa Sequence
+ */
+template <class T>
+TArray<T>& TArray<T>::SetSeq(Sequence const & seq)
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::SetSeq(Sequence ) - Not Allocated Array ! ");
+  
+  T * pe;
+  sa_size_t j,k;
+  int_4 ka;
+  if (arrtype_ == 0)  ka = 0;
+  else ka = macoli_;
+  sa_size_t step = Step(ka);
+  sa_size_t gpas = Size(ka);
+  sa_size_t naxa = Size()/Size(ka);
+  for(j=0; j<naxa; j++)  {
+    pe = mNDBlock.Begin()+Offset(ka,j);
+/*  
+    Appel explicite de l'operateur de conversion 
+    suite a la suggestion de M. Reinecke, Reza 31/7/2002 
+#if !defined(__GNUG__)
+    for(k=0; k<gpas; k++)  pe[k*step] = (T) seq(j*gpas+k);
+#else
+    // g++ (up to 2.95.1) se melange les pinceaux  s'il y a le cast (T) pour l'instanciation des complexes 
+    for(k=0; k<gpas; k++)  pe[k*step] = seq(j*gpas+k);
+#endif
+   --- Appel explicite de l'operateur de conversion sur l'objet MuTyV 
+*/
+    for(k=0; k<gpas; k++)  pe[k*step] = seq(j*gpas+k).operator T();
+  }
+  return(*this);
+}
+
+//  >>>> Operations avec 2nd membre de type scalaire 
+
+//! Fill an array with a constant value \b x
+template <class T>
+TArray<T>& TArray<T>::SetT(T x)
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::SetT(T )  - Not Allocated Array ! ");
+  T * pe;
+  sa_size_t j,k;
+  if (AvgStep() > 0)   {  // regularly spaced elements
+    sa_size_t step = AvgStep();
+    sa_size_t maxx = totsize_*step;
+    pe = Data();
+    for(k=0; k<maxx; k+=step )  pe[k] = x;
+  }
+  else {    // Non regular data spacing ...
+    int_4 ka = MaxSizeKA();
+    sa_size_t step = Step(ka);
+    sa_size_t gpas = Size(ka)*step;
+    sa_size_t naxa = Size()/Size(ka);
+    for(j=0; j<naxa; j++)  {
+      pe = mNDBlock.Begin()+Offset(ka,j);
+      for(k=0; k<gpas; k+=step)  pe[k] = x;
+    }
+  }
+  return(*this);
+}
+
+//! Add a constant value \b x to an array
+template <class T>
+TArray<T>& TArray<T>::Add(T x)
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::Add(T )  - Not Allocated Array ! ");
+  T * pe;
+  sa_size_t j,k;
+  if (AvgStep() > 0)   {  // regularly spaced elements
+    sa_size_t step = AvgStep();
+    sa_size_t maxx = totsize_*step;
+    pe = Data();
+    for(k=0; k<maxx; k+=step )  pe[k] += x;
+  }
+  else {    // Non regular data spacing ...
+    int_4 ka = MaxSizeKA();
+    sa_size_t step = Step(ka);
+    sa_size_t gpas = Size(ka)*step;
+    sa_size_t naxa = Size()/Size(ka);
+    for(j=0; j<naxa; j++)  {
+      pe = mNDBlock.Begin()+Offset(ka,j);
+      for(k=0; k<gpas; k+=step)  pe[k] += x;
+    }
+  }
+  return(*this);
+}
+
+//! Substract a constant value \b x to an array
+/*! 
+Substract a constant from the *this = *this-x
+\param fginv == true : Perfoms the inverse subtraction (*this = x-(*this)) 
+*/
+template <class T>
+TArray<T>& TArray<T>::Sub(T x, bool fginv)
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::Sub(T )  - Not Allocated Array ! ");
+  T * pe;
+  sa_size_t j,k;
+  if (AvgStep() > 0)   {  // regularly spaced elements
+    sa_size_t step = AvgStep();
+    sa_size_t maxx = totsize_*step;
+    pe = Data();
+    if (fginv)
+      for(k=0; k<maxx; k+=step )  pe[k] = x-pe[k];
+    else
+      for(k=0; k<maxx; k+=step )  pe[k] -= x;
+  }
+  else {    // Non regular data spacing ...
+    int_4 ka = MaxSizeKA();
+    sa_size_t step = Step(ka);
+    sa_size_t gpas = Size(ka)*step;
+    sa_size_t naxa = Size()/Size(ka);
+    for(j=0; j<naxa; j++)  {
+      pe = mNDBlock.Begin()+Offset(ka,j);
+      if (fginv)
+	for(k=0; k<gpas; k+=step)  pe[k] = x-pe[k];
+      else
+	for(k=0; k<gpas; k+=step)  pe[k] -= x;
+    }
+  }
+  return(*this);
+}
+
+//! Multiply an array by a constant value \b x
+template <class T>
+TArray<T>& TArray<T>::Mul(T x)
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::Mul(T )  - Not Allocated Array ! ");
+  T * pe;
+  sa_size_t j,k;
+  if (AvgStep() > 0)   {  // regularly spaced elements
+    sa_size_t step = AvgStep();
+    sa_size_t maxx = totsize_*step;
+    pe = Data();
+    for(k=0; k<maxx; k+=step )  pe[k] *= x;
+  }
+  else {    // Non regular data spacing ...
+    int_4 ka = MaxSizeKA();
+    sa_size_t step = Step(ka);
+    sa_size_t gpas = Size(ka)*step;
+    sa_size_t naxa = Size()/Size(ka);
+    for(j=0; j<naxa; j++)  {
+      pe = mNDBlock.Begin()+Offset(ka,j);
+      for(k=0; k<gpas; k+=step)  pe[k] *= x;
+    }
+  }
+  return(*this);
+}
+
+//! Divide an array by a constant value \b x
+/*! 
+Divide the array by a constant *this = *this/x
+\param fginv == true : Perfoms the inverse division (*this = x/(*this)) 
+*/
+template <class T>
+TArray<T>& TArray<T>::Div(T x, bool fginv)
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::Div(T )  - Not Allocated Array ! ");
+  if (!fginv && (x == (T) 0) ) 
+    throw MathExc("TArray<T>::Div(T )  - Divide by zero ! ");
+  T * pe;
+  sa_size_t j,k;
+  if (AvgStep() > 0)   {  // regularly spaced elements
+    sa_size_t step = AvgStep();
+    sa_size_t maxx = totsize_*step;
+    pe = Data();
+    if (fginv)
+      for(k=0; k<maxx; k+=step )  pe[k] = x/pe[k];
+    else 
+      for(k=0; k<maxx; k+=step )  pe[k] /= x;
+  }
+  else {    // Non regular data spacing ...
+    int_4 ka = MaxSizeKA();
+    sa_size_t step = Step(ka);
+    sa_size_t gpas = Size(ka)*step;
+    sa_size_t naxa = Size()/Size(ka);
+    for(j=0; j<naxa; j++)  {
+      pe = mNDBlock.Begin()+Offset(ka,j);
+      if (fginv)
+	for(k=0; k<gpas; k+=step)  pe[k] = x/pe[k];
+      else 
+	for(k=0; k<gpas; k+=step)  pe[k] /= x;
+    }
+  }
+  return(*this);
+}
+
+
+//! Replace array elements values by their opposite ( a(i) -> -a(i) )
+template <class T>
+TArray<T>& TArray<T>::NegateElt()
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::NegateElt()  - Not Allocated Array ! ");
+  T * pe;
+  sa_size_t j,k;
+  if (AvgStep() > 0)   {  // regularly spaced elements
+    sa_size_t step = AvgStep();
+    sa_size_t maxx = totsize_*step;
+    pe = Data();
+    for(k=0; k<maxx; k+=step )  pe[k] = -pe[k];
+  }
+  else {    // Non regular data spacing ...
+    int_4 ka = MaxSizeKA();
+    sa_size_t step = Step(ka);
+    sa_size_t gpas = Size(ka)*step;
+    sa_size_t naxa = Size()/Size(ka);
+    for(j=0; j<naxa; j++)  {
+      pe = mNDBlock.Begin()+Offset(ka,j);
+      for(k=0; k<gpas; k+=step)  pe[k] = -pe[k];
+    }
+  }
+  return(*this);
+}
+
+//  >>>> Operations avec 2nd membre de type tableau
+//! Add two TArrays
+template <class T>
+TArray<T>& TArray<T>::AddElt(const TArray<T>& a)
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::AddElt(const TArray<T>& )  - Not Allocated Array ! ");
+  bool smo;
+  if (!CompareSizes(a, smo)) 
+    throw(SzMismatchError("TArray<T>::AddElt(const TArray<T>&) SizeMismatch")) ;
+
+  T * pe;
+  const T * pea;
+  sa_size_t j,k,ka;
+  if (smo && (AvgStep() > 0) && (a.AvgStep() > 0))   {  // regularly spaced elements
+    sa_size_t step = AvgStep();
+    sa_size_t stepa = a.AvgStep();
+    sa_size_t maxx = totsize_*step;
+    pe = Data();
+    pea = a.Data();
+    for(k=0, ka=0;  k<maxx;  k+=step, ka+=stepa )  pe[k] += pea[ka] ;
+  }
+  else {    // Non regular data spacing ...
+    int_4 ax,axa;
+    sa_size_t step, stepa;
+    sa_size_t gpas, naxa;
+    GetOpeParams(a, smo, ax, axa, step, stepa, gpas, naxa);
+    for(j=0; j<naxa; j++)  {
+      pe = mNDBlock.Begin()+Offset(ax,j);
+      pea = a.DataBlock().Begin()+a.Offset(axa,j);
+      for(k=0, ka=0;  k<gpas;  k+=step, ka+=stepa)  pe[k] += pea[ka]; 
+    }
+  }
+  return(*this);
+}
+
+//! Substract two TArrays
+/*! 
+Substract two TArrays *this = *this-a
+\param fginv == true : Perfoms the inverse subtraction (*this = a-(*this)) 
+*/
+template <class T>
+TArray<T>& TArray<T>::SubElt(const TArray<T>& a, bool fginv)
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::SubElt(const TArray<T>& )  - Not Allocated Array ! ");
+  bool smo;
+  if (!CompareSizes(a, smo)) 
+    throw(SzMismatchError("TArray<T>::SubElt(const TArray<T>&) SizeMismatch")) ;
+
+  T * pe;
+  const T * pea;
+  sa_size_t j,k,ka;
+  if (smo && (AvgStep() > 0) && (a.AvgStep() > 0) )   {  // regularly spaced elements
+    sa_size_t step = AvgStep();
+    sa_size_t stepa = a.AvgStep();
+    sa_size_t maxx = totsize_*step;
+    pe = Data();
+    pea = a.Data();
+    if (fginv) 
+      for(k=0, ka=0;  k<maxx;  k+=step, ka+=stepa )  pe[k] = pea[ka]-pe[k] ;
+    else 
+      for(k=0, ka=0;  k<maxx;  k+=step, ka+=stepa )  pe[k] -= pea[ka] ;
+  }
+  else {    // Non regular data spacing ...
+    int_4 ax,axa;
+    sa_size_t step, stepa;
+    sa_size_t gpas, naxa;
+    GetOpeParams(a, smo, ax, axa, step, stepa, gpas, naxa);
+    for(j=0; j<naxa; j++)  {
+      pe = mNDBlock.Begin()+Offset(ax,j);
+      pea = a.DataBlock().Begin()+a.Offset(axa,j);
+      if (fginv) 
+	for(k=0, ka=0;  k<gpas;  k+=step, ka+=stepa)  pe[k] = pea[ka]-pe[k] ;
+      else
+	for(k=0, ka=0;  k<gpas;  k+=step, ka+=stepa)  pe[k] -= pea[ka]; 
+    }
+  }
+  return(*this);
+}
+
+
+//! Multiply two TArrays (elements by elements)
+template <class T>
+TArray<T>& TArray<T>::MulElt(const TArray<T>& a)
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::MulElt(const TArray<T>& )  - Not Allocated Array ! ");
+  bool smo;
+  if (!CompareSizes(a, smo)) 
+    throw(SzMismatchError("TArray<T>::MulElt(const TArray<T>&) SizeMismatch")) ;
+
+  T * pe;
+  const T * pea;
+  sa_size_t j,k,ka;
+  if (smo && (AvgStep() > 0) && (a.AvgStep() > 0) )   {  // regularly spaced elements
+    sa_size_t step = AvgStep();
+    sa_size_t stepa = a.AvgStep();
+    sa_size_t maxx = totsize_*step;
+    pe = Data();
+    pea = a.Data();
+    for(k=0, ka=0;  k<maxx;  k+=step, ka+=stepa )  pe[k] *= pea[ka] ;
+  }
+  else {    // Non regular data spacing ...
+    int_4 ax,axa;
+    sa_size_t step, stepa;
+    sa_size_t gpas, naxa;
+    GetOpeParams(a, smo, ax, axa, step, stepa, gpas, naxa);
+    for(j=0; j<naxa; j++)  {
+      pe = mNDBlock.Begin()+Offset(axa,j);
+      pea = a.DataBlock().Begin()+a.Offset(axa,j);
+      for(k=0, ka=0;  k<gpas;  k+=step, ka+=stepa)  pe[k] *= pea[ka]; 
+    }
+  }
+  return(*this);
+}
+
+
+//! Divide two TArrays (elements by elements)
+/*! 
+Divide two TArrays *this = (*this)/a
+\param fginv == true : Perfoms the inverse division (*this = a/(*this)) 
+\param divzero == true : if a(i)==0. result is set to zero: (*this)(i)==0.
+*/
+template <class T>
+TArray<T>& TArray<T>::DivElt(const TArray<T>& a, bool fginv, bool divzero)
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::DivElt(const TArray<T>& )  - Not Allocated Array ! ");
+  bool smo;
+  if (!CompareSizes(a, smo)) 
+    throw(SzMismatchError("TArray<T>::DivElt(const TArray<T>&) SizeMismatch")) ;
+
+  T * pe;
+  const T * pea;
+  sa_size_t j,k,ka;
+  if (smo && (AvgStep() > 0) && (a.AvgStep() > 0) )   {  // regularly spaced elements
+    sa_size_t step = AvgStep();
+    sa_size_t stepa = a.AvgStep();
+    sa_size_t maxx = totsize_*step;
+    pe = Data();
+    pea = a.Data();
+    if(divzero) {
+      if (fginv) 
+        for(k=0, ka=0;  k<maxx;  k+=step, ka+=stepa )
+          {if(pe[k]==(T)0) pe[k] = (T)0; else pe[k] = pea[ka]/pe[k];}
+      else 
+        for(k=0, ka=0;  k<maxx;  k+=step, ka+=stepa )
+          {if(pea[k]==(T)0) pe[k] = (T)0; else pe[k] /= pea[ka] ;}
+    } else {
+      if (fginv) 
+        for(k=0, ka=0;  k<maxx;  k+=step, ka+=stepa )  pe[k] = pea[ka]/pe[k];
+      else 
+        for(k=0, ka=0;  k<maxx;  k+=step, ka+=stepa )  pe[k] /= pea[ka] ;
+    }
+  }
+  else {    // Non regular data spacing ...
+    int_4 ax,axa;
+    sa_size_t step, stepa;
+    sa_size_t gpas, naxa;
+    GetOpeParams(a, smo, ax, axa, step, stepa, gpas, naxa);
+    for(j=0; j<naxa; j++)  {
+      pe = mNDBlock.Begin()+Offset(ax,j);
+      pea = a.DataBlock().Begin()+a.Offset(axa,j);
+      if(divzero) {
+        if (fginv) 
+	  for(k=0, ka=0;  k<gpas;  k+=step, ka+=stepa)
+            {if(pe[k]==(T)0) pe[k] = (T)0; else pe[k] = pea[ka]/pe[k];} 
+        else
+	  for(k=0, ka=0;  k<gpas;  k+=step, ka+=stepa)
+            {if(pea[k]==(T)0) pe[k] = (T)0; else pe[k] /= pea[ka];} 
+      } else {
+        if (fginv) 
+	  for(k=0, ka=0;  k<gpas;  k+=step, ka+=stepa)  pe[k] = pea[ka]/pe[k]; 
+        else
+	  for(k=0, ka=0;  k<gpas;  k+=step, ka+=stepa)  pe[k] /= pea[ka]; 
+      }
+    }
+  }
+  return(*this);
+}
+
+//! Copy elements of \b a
+template <class T>
+TArray<T>& TArray<T>::CopyElt(const TArray<T>& a)
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::CopyElt(const TArray<T>& )  - Not Allocated Array ! ");
+  bool smo;
+  if (!CompareSizes(a, smo)) 
+    throw(SzMismatchError("TArray<T>::CopyElt(const TArray<T>&) SizeMismatch")) ;
+
+  T * pe;
+  const T * pea;
+  sa_size_t j,k,ka;
+  if (smo && (AvgStep() > 0) && (a.AvgStep() > 0) )   {  // regularly spaced elements
+    sa_size_t step = AvgStep();
+    sa_size_t stepa = a.AvgStep();
+    sa_size_t maxx = totsize_*step;
+    pe = Data();
+    pea = a.Data();
+    for(k=0, ka=0;  k<maxx;  k+=step, ka+=stepa )  pe[k] = pea[ka] ;
+  }
+  else {    // Non regular data spacing ...
+    int_4 ax,axa;
+    sa_size_t step, stepa;
+    sa_size_t gpas, naxa;
+    GetOpeParams(a, smo, ax, axa, step, stepa, gpas, naxa);
+    for(j=0; j<naxa; j++)  {
+      pe = mNDBlock.Begin()+Offset(ax,j);
+      pea = a.DataBlock().Begin()+a.Offset(axa,j);
+      for(k=0, ka=0;  k<gpas;  k+=step, ka+=stepa)  pe[k] = pea[ka]; 
+    }
+  }
+  return(*this);
+}
+
+//! Converts and Copy elements of \b a
+template <class T>
+TArray<T>& TArray<T>::ConvertAndCopyElt(const BaseArray& a)
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::ConvertAndCopyElt(const TArray<T>& )  - Not Allocated Array ! ");
+  bool smo;
+  if (!CompareSizes(a, smo)) 
+    throw(SzMismatchError("TArray<T>::ConvertAndCopyElt(const TArray<T>&) SizeMismatch")) ;
+
+  T * pe;
+  sa_size_t j,k,ka;
+  sa_size_t offa;
+  // Non regular data spacing ...
+  int_4 ax,axa;
+  sa_size_t step, stepa;
+  sa_size_t gpas, naxa;
+  GetOpeParams(a, smo, ax, axa, step, stepa, gpas, naxa);
+  for(j=0; j<naxa; j++)  {
+    pe = mNDBlock.Begin()+Offset(ax,j);
+    offa = a.Offset(axa,j);
+/*  
+    Appel explicite de l'operateur de conversion 
+    suite a la suggestion de M. Reinecke, Reza 31/7/2002 
+#if !defined(__GNUG__)
+    for(k=0, ka=0;  k<gpas;  k+=step, ka+=stepa)  pe[k] = (T)a.ValueAtPosition(offa+ka); 
+#else
+    // g++ (up to 2.95.1) se melange les pinceaux  s'il y a le cast (T) pour l'instanciation des complexes 
+    for(k=0, ka=0;  k<gpas;  k+=step, ka+=stepa)  pe[k] = a.ValueAtPosition(offa+ka); 
+#endif
+   --- Appel explicite de l'operateur de conversion sur l'objet MuTyV 
+*/
+    for(k=0, ka=0;  k<gpas;  k+=step, ka+=stepa)  
+      pe[k] = a.ValueAtPosition(offa+ka).operator T(); 
+  }
+  return(*this);
+}
+
+
+// Somme et produit des elements
+//! Sum all elements
+template <class T>
+T TArray<T>::Sum() const
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::Sum()  - Not Allocated Array ! ");
+  T ret=0;
+  const T * pe;
+  sa_size_t j,k;
+  if (AvgStep() > 0)   {  // regularly spaced elements
+    sa_size_t step = AvgStep();
+    sa_size_t maxx = totsize_*step;
+    pe = Data();
+    for(k=0; k<maxx; k+=step )  ret += pe[k];
+  }
+  else {    // Non regular data spacing ...
+    int_4 ka = MaxSizeKA();
+    sa_size_t step = Step(ka);
+    sa_size_t gpas = Size(ka)*step;
+    sa_size_t naxa = Size()/Size(ka);
+    for(j=0; j<naxa; j++)  {
+      pe = mNDBlock.Begin()+Offset(ka,j);
+      for(k=0; k<gpas; k+=step)  ret += pe[k] ;
+    }
+  }
+  return ret;
+}
+
+//! Multiply all elements
+template <class T>
+T TArray<T>::Product() const
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::Product()  - Not Allocated Array ! ");
+  T ret=(T)1;
+  const T * pe;
+  sa_size_t j,k;
+  if (AvgStep() > 0)   {  // regularly spaced elements
+    sa_size_t step = AvgStep();
+    sa_size_t maxx = totsize_*step;
+    pe = Data();
+    for(k=0; k<maxx; k+=step )  ret *= pe[k];
+  }
+  else {    // Non regular data spacing ...
+    int_4 ka = MaxSizeKA();
+    sa_size_t step = Step(ka);
+    sa_size_t gpas = Size(ka)*step;
+    sa_size_t naxa = Size()/Size(ka);
+    for(j=0; j<naxa; j++)  {
+      pe = mNDBlock.Begin()+Offset(ka,j);
+      for(k=0; k<gpas; k+=step)  ret *= pe[k] ;
+    }
+  }
+  return ret;
+}
+
+//! Returns the sum of all elements squared (Sum
+template <class T>
+T TArray<T>::SumX2() const
+{
+  if (NbDimensions() < 1) 
+    throw RangeCheckError("TArray<T>::SumX2()  - Not Allocated Array ! ");
+  T ret=0;
+  const T * pe;
+  sa_size_t j,k;
+  if (AvgStep() > 0)   {  // regularly spaced elements
+    sa_size_t step = AvgStep();
+    sa_size_t maxx = totsize_*step;
+    pe = Data();
+    for(k=0; k<maxx; k+=step )  ret += pe[k]*pe[k];
+  }
+  else {    // Non regular data spacing ...
+    int_4 ka = MaxSizeKA();
+    sa_size_t step = Step(ka);
+    sa_size_t gpas = Size(ka)*step;
+    sa_size_t naxa = Size()/Size(ka);
+    for(j=0; j<naxa; j++)  {
+      pe = mNDBlock.Begin()+Offset(ka,j);
+      for(k=0; k<gpas; k+=step)  ret += pe[k]*pe[k] ;
+    }
+  }
+  return ret;
+}
+
+//! Return the minimum and the maximum values of the array elements 
+/*!
+  This method generates an exception (\c MathExc) if called for complex arrays
+*/
+template <class T>
+void TArray<T>::MinMax(T& min, T& max) const
+{
+  const T * pe;
+  sa_size_t j,k;
+  int_4 ka = MaxSizeKA();
+  sa_size_t step = Step(ka);
+  sa_size_t gpas = Size(ka)*step;
+  sa_size_t naxa = Size()/Size(ka);
+  min = (*this)[0];
+  max = (*this)[0];
+  for(j=0; j<naxa; j++)  {
+    pe = mNDBlock.Begin()+Offset(ka,j);
+    for(k=0; k<gpas; k+=step) {
+      if (pe[k]<min)  min = pe[k];
+      else if (pe[k]>max)  max = pe[k];      
+    }
+  }
+  return;
+}
+
+void TArray< complex<r_4> >::MinMax(complex<r_4>& min, complex<r_4>& max) const
+{
+  throw MathExc("TArray< complex<r_4> >::MinMax(...) - No order in complex");
+}
+
+void TArray< complex<r_8> >::MinMax(complex<r_8>& min, complex<r_8>& max) const
+{
+  throw MathExc("TArray< complex<r_4> >::MinMax(...) - No order in complex");
+}
+
+// ----------------------------------------------------
+//       Impression, etc ...
+// ----------------------------------------------------
+
+//! Return a string that contain the type \b T of the array
+template <class T>
+string TArray<T>::InfoString() const
+{
+  string rs = "TArray<" ;
+  rs += typeid(T).name();
+  rs += "> ";
+  return(rs);
+}
+
+//! Print array
+/*!
+  \param os : output stream
+  \param maxprt : maximum numer of print
+  \param si : if true,  display attached DvList
+  \param ascd : if true, suppresses the display of line numbers,
+  suitable for ascii dump format.
+  \sa SetMaxPrint
+  \sa WriteASCII
+ */
+template <class T>
+void TArray<T>::Print(ostream& os, sa_size_t maxprt, bool si, bool ascd) const
+{
+  if (maxprt < 0)  maxprt = max_nprt_;
+  sa_size_t npr = 0;
+  Show(os, si);
+  if (ndim_ < 1) return;
+  sa_size_t k0,k1,k2,k3,k4;
+  for(k4=0; k4<size_[4]; k4++) {
+    if ((size_[4] > 1) && ascd) 
+      cout << "\n ----- Dimension 5 (U) K4= " << k4 << endl;
+    for(k3=0; k3<size_[3]; k3++) {
+      if ((size_[3] > 1) && ascd) 
+	cout << "\n ----- Dimension 4 (T) K3= " << k3 << endl;
+      for(k2=0; k2<size_[2]; k2++) {
+	if ((size_[2] > 1) & ascd) 
+	  cout << "\n ----- Dimension 3 (Z) K2= " << k2 << endl;
+	for(k1=0; k1<size_[1]; k1++) {
+	  if ( (size_[1] > 1) && (size_[0] > 10) && ascd) 
+	    cout << "----- Dimension 2 (Y) K1= " << k1 << endl;
+	  for(k0=0; k0<size_[0]; k0++) {
+            if(k0 > 0) os << " ";  
+            os << Elem(k0, k1, k2, k3, k4);     npr++;
+	    if (npr >= (sa_size_t) maxprt) {
+	      if (npr < totsize_)  os << "\n     .... " << endl; return;
+	    }
+	  }
+          os << endl;
+	}
+      }
+    }
+  }
+  os <<  endl;
+}
+
+//! Fill the array, decoding the ASCII input stream
+/*!
+  \param is : input stream (ASCII)
+  \param nr : Number of non empty (or comment) lines in stream (return value)
+  \param nc : Number of columns (= ntot/nlines) (return value)
+  \param clm : Lines starting with clm character are treated as comment lines
+  \param sep : word separator in lines
+  \return Number of decoded elements
+*/
+template <class T>
+sa_size_t TArray<T>::ReadASCII(istream& is, sa_size_t & nr, sa_size_t & nc,
+			       char clm, const char* sep)
+{
+  EnumeratedSequence es;
+  sa_size_t n = es.FillFromFile(is, nr, nc, clm, sep);
+  if ( (n < 1) || (nr < 1) || (nc < 1) ) return(n); 
+  if (!IsAllocated()) {
+    sa_size_t sz[2];
+    if (arrtype_ == 2) { // C'est un vecteur 
+      sz[0] = sz[1] = 1;
+      sz[veceli_] = n;
+    }
+    else {
+      sz[RowsKA()] = nr;
+      sz[ColsKA()] = nc;
+    }
+    ReSize(2, sz);
+  }
+  SetSeq(es);
+  cout << "TArray<T>::ReadASCII()/Info: " << n << " elements read from stream " 
+       << " (Row,Col= " << nr << "," << nc << ")" << endl;
+  return(n);
+}
+
+//! Writes the array content to the output stream, (in ASCII) 
+/*!
+  \param os : output stream (ASCII)
+  \sa Print
+ */
+template <class T>
+void TArray<T>::WriteASCII(ostream& os) const
+{
+  Print(os, Size(), false, true);
+}
+
+
+
+///////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////
+#ifdef __CXX_PRAGMA_TEMPLATES__
+/*
+#pragma define_template TArray<uint_1>
+#pragma define_template TArray<int_2>
+#pragma define_template TArray<uint_4>
+*/
+#pragma define_template TArray<uint_2>
+#pragma define_template TArray<uint_8>
+#pragma define_template TArray<int_4>
+#pragma define_template TArray<int_8>
+#pragma define_template TArray<r_4>
+#pragma define_template TArray<r_8>
+#pragma define_template TArray< complex<r_4> > 
+#pragma define_template TArray< complex<r_8> > 
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+/*
+template class TArray<uint_1>; 
+template class TArray<int_2>;  
+template class TArray<uint_4>;
+*/
+template class TArray<uint_2>;
+template class TArray<uint_8>;
+template class TArray<int_4>;
+template class TArray<int_8>;
+template class TArray<r_4>;
+template class TArray<r_8>;
+template class TArray< complex<r_4> >;
+template class TArray< complex<r_8> >;
+#endif
+
+
Index: /tags/V_Dec2002/SophyaLib/TArray/tarray.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/TArray/tarray.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/TArray/tarray.h	(revision 2309)
@@ -0,0 +1,411 @@
+// This may look like C code, but it is really -*- C++ -*-
+//      template array class for numerical types
+//                     R. Ansari, C.Magneville   03/2000
+
+#ifndef TArray_SEEN
+#define TArray_SEEN
+
+#include "machdefs.h"
+#include <math.h>
+#include <iostream.h>
+#include "basarr.h"
+#include "ndatablock.h"
+#include <complex>
+#include "utilarr.h"
+
+
+namespace SOPHYA {
+
+// Forward declaration
+template <class T> class FIO_TArray;
+
+//   --------------------------- classe template Array -----------------------
+//  ( See BaseArray class for data organisation in  memory and related methods )
+
+//! Class for template arrays
+template <class T>
+class TArray : public BaseArray {
+public:
+  // Creation / destruction 
+  TArray();
+  TArray(int_4 ndim, const sa_size_t * siz, sa_size_t step =1);
+  TArray(sa_size_t nx, sa_size_t ny=0, sa_size_t nz=0, sa_size_t nt=0, sa_size_t nu=0);
+  TArray(int_4 ndim, const sa_size_t * siz, NDataBlock<T> & db, bool share=false, sa_size_t step=1, sa_size_t offset=0);
+  TArray(int_4 ndim, const sa_size_t * siz, T* values, sa_size_t step=1, sa_size_t offset=0, Bridge* br=NULL);
+  TArray(const TArray<T>& a);
+  TArray(const TArray<T>& a, bool share);
+  TArray(const BaseArray& a);
+
+  virtual ~TArray();
+
+  // A = B
+  //! = operator between TArray
+  /*! \warning Datas are copied (cloned) from \b a.
+      \sa Set \sa NDataBlock::operator=(const NDataBlock<T>&) */
+  inline  TArray<T>& operator = (const TArray<T>& a) { return Set(a); }
+  virtual TArray<T>& Set(const TArray<T>& a);
+
+  //! = operator between  TArray 's with different types - Elements are converted.
+  inline  TArray<T>& operator = (const BaseArray& a) { return SetBA(a); }
+  virtual TArray<T>& SetBA(const BaseArray& a);
+
+  // Gestion taille/Remplissage
+  virtual void Clone(const TArray<T>& a); 
+  // partage les donnees si "a" temporaire, clone sinon.
+  void CloneOrShare(const TArray<T>& a);
+  // Share: partage les donnees de "a"
+  void Share(const TArray<T>& a);
+
+  void ReSize(int_4 ndim, sa_size_t * siz, sa_size_t step=1);
+  void ReSize(const BaseArray& a);
+  //! a synonym (alias) for method ReSize(int_4, ...)
+  inline void SetSize(int_4 ndim, sa_size_t * siz, sa_size_t step=1)
+		{ ReSize(ndim, siz, step); }
+  //! a synonym (alias) for method ReSize(const BaseArray&)
+  inline void SetSize(const BaseArray& a)
+		{ ReSize(a); }
+  void Realloc(int_4 ndim, sa_size_t * siz, sa_size_t step=1, bool force=false);
+
+  // Compacts size=1 array dimensions
+  virtual TArray<T>& CompactAllDimensions();
+  virtual TArray<T>& CompactTrailingDimensions();
+
+  // Packing array elements in memory
+  virtual TArray<T> PackElements(bool force=false) const ;
+
+  // SubArrays - $CHECK$ Reza 03/2000 je ne sais pas s'il faut declarer ca const ??
+  TArray<T> SubArray(Range rx, Range ry, Range rz, Range rt, Range ru) const ;
+
+  //! () operator for Sub arrays extraction
+  /*! \sa SubArray */
+  inline TArray<T> operator () (Range rx, Range ry, Range rz) const
+                   { return  SubArray(rx, ry, rz, Range(0), Range(0)); }
+  inline TArray<T> operator () (Range rx, Range ry, Range rz, Range rt) const
+                   { return  SubArray(rx, ry, rz, rt, Range(0)); }
+  inline TArray<T> operator () (Range rx, Range ry, Range rz, Range rt, Range ru) const
+                   { return  SubArray(rx, ry, rz, rt, ru); }
+
+  // ---- Access to data
+  // Definition of virtual element acces method inherited from BaseArray class 
+  virtual MuTyV & ValueAtPosition(sa_size_t ip) const;
+
+  // Data Access: operator overloaded inline acces methods 
+  inline T const& operator()(sa_size_t ix, sa_size_t iy, sa_size_t iz) const ;
+  inline T&       operator()(sa_size_t ix, sa_size_t iy, sa_size_t iz);
+  inline T const& operator()(sa_size_t ix, sa_size_t iy, sa_size_t iz, sa_size_t it, sa_size_t iu=0) const ;
+  inline T&       operator()(sa_size_t ix, sa_size_t iy, sa_size_t iz, sa_size_t it, sa_size_t iu=0);
+  inline T const& operator[](sa_size_t ip) const ;
+  inline T&       operator[](sa_size_t ip);
+
+  inline T const& Elem(sa_size_t ix, sa_size_t iy, sa_size_t iz, sa_size_t it=0, sa_size_t iu=0) const ;
+  inline T&       Elem(sa_size_t ix, sa_size_t iy, sa_size_t iz, sa_size_t it=0, sa_size_t iu=0);
+  inline T const& ElemCheckBound(sa_size_t ix, sa_size_t iy, sa_size_t iz, sa_size_t it=0, sa_size_t iu=0) const ;
+  inline T&       ElemCheckBound(sa_size_t ix, sa_size_t iy, sa_size_t iz, sa_size_t it=0, sa_size_t iu=0);
+
+  //! Return pointer to first element adress
+  inline        T* Data()       {return mNDBlock.Begin()+offset_;}
+  //! Return pointer to first element adress
+  inline const  T* Data() const {return mNDBlock.Begin()+offset_;}
+  //! Return reference to datablock NDataBlock
+  inline        NDataBlock<T>& DataBlock()       {return mNDBlock;}
+  //! Return reference to datablock NDataBlock
+  inline const  NDataBlock<T>& DataBlock() const {return mNDBlock;}
+
+  // Temporaire?
+  //! Are the array temporay ?
+  inline bool   IsTemp(void) const {return mNDBlock.IsTemp();}
+  //! Set the array as temporay
+  inline void   SetTemp(bool temp=false) const {mNDBlock.SetTemp(temp);}
+
+// Operations diverses  = , +=, ...
+// Conversion en type T, if Size() == 1
+  inline T toScalar();
+// Met les elements a une suite de valeurs
+  virtual TArray<T>&  SetSeq(Sequence const & seq);
+  //! Fill TArray with Sequence \b seq
+  inline  TArray<T>&  operator = (Sequence const & seq)    { return SetSeq(seq); }
+// A = x (tous les elements a x)
+  virtual TArray<T>&  SetT(T x);
+  //! Fill TArray with all elements equal to \b x
+  inline  TArray<T>&  operator = (T x)             { return SetT(x); }
+// A += -= *= /= x (ajoute, soustrait, ... x a tous les elements)
+  virtual TArray<T>&  Add(T x);
+  //! Add \b x to all elements
+  inline  TArray<T>&  operator += (T x)            { return Add(x); }
+  virtual TArray<T>&  Sub(T x, bool fginv=false);
+  //! Substract \b x to all elements
+  inline  TArray<T>&  operator -= (T x)            { return Sub(x); }
+  virtual TArray<T>&  Mul(T x);
+  //! Multiply all elements by \b x
+  inline  TArray<T>&  operator *= (T x)            { return Mul(x); }
+  virtual TArray<T>&  Div(T x, bool fginv=false);
+  //! Divide all elements by \b x
+  inline  TArray<T>&  operator /= (T x)            { return Div(x); }
+
+// applique le signe moins a tous les elements
+  virtual TArray<T>&  NegateElt();
+  
+// A += -=  (ajoute, soustrait element par element les deux tableaux )
+  virtual TArray<T>&  AddElt(const TArray<T>& a);
+  //! Operator TArray += TArray
+  inline  TArray<T>&  operator += (const TArray<T>& a)  { return AddElt(a); }
+  virtual TArray<T>&  SubElt(const TArray<T>& a, bool fginv=false);
+  //! Operator TArray -= TArray
+  inline  TArray<T>&  operator -= (const TArray<T>& a)  { return SubElt(a); }
+// Multiplication, division element par element les deux tableaux 
+  virtual TArray<T>&  MulElt(const TArray<T>& a);
+  virtual TArray<T>&  DivElt(const TArray<T>& a, bool fginv=false, bool divzero=false);
+// Recopie des valeurs, element par element
+  virtual TArray<T>&  CopyElt(const TArray<T>& a);
+// Recopie des valeurs avec conversion prealable, element par element
+  virtual TArray<T>&  ConvertAndCopyElt(const BaseArray& a);
+
+// Somme et produit des elements
+  virtual T Sum() const ;
+  virtual T Product() const ;
+// Somme du carre des elements
+  virtual T SumX2() const;
+// Valeur min et max des elements
+  virtual void MinMax(T& min, T& max) const ;
+
+// Impression, I/O, ...
+  virtual string InfoString() const;   
+  virtual void   Print(ostream& os, sa_size_t maxprt=-1, 
+		       bool si=false, bool ascd=false) const ;
+
+// Lecture,Ecriture sur fichier ASCII
+  virtual sa_size_t ReadASCII(istream& is, sa_size_t & nr, sa_size_t & nc,
+			      char clm='#', const char* sep=" \t");
+  virtual void   WriteASCII(ostream& os) const;
+
+//  Pour la gestion de persistance
+  friend class  FIO_TArray<T>;
+
+protected:
+
+  NDataBlock<T> mNDBlock; //!< Block for datas
+  mutable MuTyV my_mtv;   //!< for use by ValueAtPosition()
+};
+
+////////////////////////////////////////////////////////////////
+//   Surcharge d'operateur << 
+//! Print TArray \b a on stream \b os
+template <class T>
+inline ostream& operator << (ostream& os, const TArray<T>& a)
+                            { a.Print(os);    return(os);    }
+
+//   Surcharge d'operateur >> 
+//! Decodes the ASCII input stream \b is , filling TArray \b a elements
+template <class T>
+inline istream& operator >> (istream& is, TArray<T>& a)
+                            { sa_size_t nr, nc; 
+			      a.ReadASCII(is, nr, nc);    return(is);    }
+
+
+////////////////////////////////////////////////////////////////
+// Surcharge d'operateurs A (+,-,*,/) (T) x
+
+/*! \ingroup TArray \fn operator+(const TArray<T>&,T)
+  \brief Operator TArray = TArray + constant */
+template <class T> inline TArray<T> operator + (const TArray<T>& a, T b)
+    {TArray<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Add(b); return result;}
+
+/*! \ingroup TArray \fn operator+(T,const TArray<T>&)
+  \brief Operator TArray = constant + TArray */
+template <class T> inline TArray<T> operator + (T b,const TArray<T>& a)
+    {TArray<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Add(b); return result;}
+
+/*! \ingroup TArray \fn operator-(const TArray<T>&,T)
+  \brief Operator TArray = TArray - constant */
+template <class T> inline TArray<T> operator - (const TArray<T>& a, T b)
+    {TArray<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Sub(b); return result;}
+
+/*! \ingroup TArray \fn operator-(T,const TArray<T>&)
+  \brief Operator TArray = constant - TArray */
+template <class T> inline TArray<T> operator - (T b,const TArray<T>& a)
+    {TArray<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Sub(b,true); return result;}
+
+/*! \ingroup TArray \fn operator*(const TArray<T>&,T)
+  \brief Operator TArray = TArray * constant */
+template <class T> inline TArray<T> operator * (const TArray<T>& a, T b)
+    {TArray<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Mul(b); return result;}
+
+/*! \ingroup TArray \fn operator*(T,const TArray<T>&)
+  \brief Operator TArray = constant * TArray */
+template <class T> inline TArray<T> operator * (T b,const TArray<T>& a)
+    {TArray<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Mul(b); return result;}
+
+/*! \ingroup TArray \fn operator/(const TArray<T>&,T)
+  \brief Operator TArray = TArray / constant */
+template <class T> inline TArray<T> operator / (const TArray<T>& a, T b)
+    {TArray<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Div(b); return result;}
+
+/*! \ingroup TArray \fn operator/(T,const TArray<T>&)
+  \brief Operator TArray = constant / TArray  */
+template <class T> inline TArray<T> operator / (T b, const TArray<T>& a)
+    {TArray<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Div(b, true); return result;}
+
+////////////////////////////////////////////////////////////////
+// Surcharge d'operateurs B = -A
+
+/*! \ingroup TArray \fn operator - (const TArray<T>&)
+  \brief Operator - Returns an array with elements equal to the opposite of
+  the original array elements.  */
+template <class T> inline TArray<T> operator - (const TArray<T>& a)
+    {TArray<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.NegateElt(); return result;}
+
+////////////////////////////////////////////////////////////////
+// Surcharge d'operateurs C = A (+,-) B
+
+/*! \ingroup TArray \fn operator+(const TArray<T>&,const TArray<T>&)
+  \brief Operator TArray = TArray + TArray */
+template <class T>
+inline TArray<T> operator + (const TArray<T>& a,const TArray<T>& b)
+    { TArray<T> result; result.SetTemp(true); 
+    if (b.IsTemp())  { result.Share(b); result.AddElt(a); }
+    else { result.CloneOrShare(a); result.AddElt(b); }
+    return result; }
+
+/*! \ingroup TArray \fn operator-(const TArray<T>&,const TArray<T>&)
+  \brief Operator TArray = TArray - TArray */
+template <class T>
+inline TArray<T> operator - (const TArray<T>& a,const TArray<T>& b)
+    { TArray<T> result; result.SetTemp(true); 
+    if (b.IsTemp())  { result.Share(b); result.SubElt(a, true); }
+    else { result.CloneOrShare(a); result.SubElt(b); }
+    return result; }
+
+
+// --------------------------------------------------
+//        inline element acces methods
+// --------------------------------------------------
+
+//! Return element (ix,iy,iz,it,iu) value
+template <class T>
+inline T const& TArray<T>::Elem(sa_size_t ix, sa_size_t iy, sa_size_t iz, sa_size_t it, sa_size_t iu) const
+{
+  return ( *( mNDBlock.Begin()+ offset_+ 
+	      ix*step_[0] + iy*step_[1] + iz*step_[2] +
+	      it*step_[3] + iu*step_[4]) );
+}
+
+//! Return element (ix,iy,iz,it,iu) value
+template <class T>
+inline T & TArray<T>::Elem(sa_size_t ix, sa_size_t iy, sa_size_t iz, sa_size_t it, sa_size_t iu)
+{
+  return ( *( mNDBlock.Begin()+ offset_+ 
+	      ix*step_[0] + iy*step_[1] + iz*step_[2] +
+	      it*step_[3] + iu*step_[4]) );
+}
+
+//! Return element (ix,iy,iz,it,iu) value with Check of indexes bound first
+template <class T>
+inline T const& TArray<T>::ElemCheckBound(sa_size_t ix, sa_size_t iy, sa_size_t iz, sa_size_t it, sa_size_t iu) const
+{
+  CheckBound(ix, iy, iz, it, iu, 4);
+  return(Elem(ix, iy, iz, it, iu));
+}
+
+//! Return element (ix,iy,iz,it,iu) value with Check of indexes bound first
+template <class T>
+inline T & TArray<T>::ElemCheckBound(sa_size_t ix, sa_size_t iy, sa_size_t iz, sa_size_t it, sa_size_t iu)
+{
+  CheckBound(ix, iy, iz, it, iu, 4);
+  return(Elem(ix, iy, iz, it, iu));
+}
+
+//! Return element (ix,iy,iz) value
+template <class T>
+inline T const& TArray<T>::operator()(sa_size_t ix, sa_size_t iy, sa_size_t iz) const
+{
+#ifdef SO_BOUNDCHECKING
+  CheckBound(ix, iy, iz, 0, 0, 4);
+#endif
+  return ( *( mNDBlock.Begin()+ offset_+ 
+	      ix*step_[0] + iy*step_[1] + iz*step_[2]) );
+}
+
+//! Return element (ix,iy,iz) value
+template <class T>
+inline T & TArray<T>::operator()(sa_size_t ix, sa_size_t iy, sa_size_t iz) 
+{
+#ifdef SO_BOUNDCHECKING
+  CheckBound(ix, iy, iz, 0, 0, 4);
+#endif
+  return ( *( mNDBlock.Begin()+ offset_+ 
+	      ix*step_[0] + iy*step_[1] + iz*step_[2]) );
+}
+
+//! Operator () : return element (ix,iy,iz,it,iu) value
+template <class T>
+inline T const& TArray<T>::operator()(sa_size_t ix, sa_size_t iy, sa_size_t iz, sa_size_t it, sa_size_t iu) const
+{
+#ifdef SO_BOUNDCHECKING
+  CheckBound(ix, iy, iz, it, iu, 4);
+#endif
+  return ( *( mNDBlock.Begin()+ offset_+ 
+	      ix*step_[0] + iy*step_[1] + iz*step_[2] +
+	      it*step_[3] + iu*step_[4]) );
+}
+
+//! Operator () : return element (ix,iy,iz,it,iu) value
+template <class T>
+inline T & TArray<T>::operator()(sa_size_t ix, sa_size_t iy, sa_size_t iz, sa_size_t it, sa_size_t iu)
+{
+#ifdef SO_BOUNDCHECKING
+  CheckBound(ix, iy, iz, it, iu, 4);
+#endif
+  return ( *( mNDBlock.Begin()+ offset_+ 
+	      ix*step_[0] + iy*step_[1] + iz*step_[2] +
+	      it*step_[3] + iu*step_[4]) );
+}
+
+
+//! Operator [] : return element at positon ip
+template <class T>
+inline T const& TArray<T>::operator[](sa_size_t ip) const
+{
+#ifdef SO_BOUNDCHECKING
+  if (ip >= totsize_)  throw( ParmError("TArray<T>::operator[] Out-of-bound Error") );
+#endif
+return *(mNDBlock.Begin()+Offset(ip));
+}
+
+//! Operator [] : return element at positon ip
+template <class T>
+inline T & TArray<T>::operator[](sa_size_t ip) 
+{
+#ifdef SO_BOUNDCHECKING
+  if (ip >= totsize_)  throw( ParmError("TArray<T>::operator[] Out-of-bound Error") );
+#endif
+return *(mNDBlock.Begin()+Offset(ip));
+}
+
+
+//! Converts to a scalar (value of first element) if the array size is equal to 1 
+template <class T>
+inline T TArray<T>::toScalar()
+{ 
+  if (Size() != 1) throw(SzMismatchError("TArray<T>::operator T() Size() != 1")) ;
+  return ( (*this)[0] );
+}
+
+// Typedef pour simplifier
+/*! \ingroup TArray
+  \typedef Array
+  \brief To simplified TArray<r_8> writing
+*/
+typedef TArray<r_8> Array;
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/TArray/tarrinit.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/TArray/tarrinit.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/TArray/tarrinit.cc	(revision 2309)
@@ -0,0 +1,84 @@
+// Classe d'initialisation du module TArray (template Arrays)
+#include "machdefs.h"
+#include "tarrinit.h"
+
+#include "fioarr.h"
+
+/*!
+   \defgroup TArray TArray module
+   This module contains template arrays, matrices and vectors.
+*/
+
+/*!
+  \class SOPHYA::TArrayInitiator
+  \ingroup TArray
+  Array Matrices and Vector initiator
+*/
+
+int TArrayInitiator::FgInit = 0;
+
+TArrayInitiator::TArrayInitiator()
+  : SophyaInitiator()
+{
+  FgInit++;
+  if (FgInit > 1)  return;
+
+//   Enregistrement des classes PPersist du modules TArray
+  
+
+  //  PPRegister(FIO_TArray<uint_1>);
+  //  DObjRegister(FIO_TArray<uint_1>, TArray<uint_1>);
+  PPRegister(FIO_TArray<uint_2>);
+  DObjRegister(FIO_TArray<uint_2>, TArray<uint_2>);
+  DObjRegister(FIO_TArray<uint_2>, TMatrix<uint_2>);
+  DObjRegister(FIO_TArray<uint_2>, TVector<uint_2>);
+
+  //  PPRegister(FIO_TArray<int_2>);
+  //  DObjRegister(FIO_TArray<int_2>, TArray<int_2>);
+
+  PPRegister(FIO_TArray<int_4>);
+  DObjRegister(FIO_TArray<int_4>, TArray<int_4>);
+  DObjRegister(FIO_TArray<int_4>, TMatrix<int_4>);
+  DObjRegister(FIO_TArray<int_4>, TVector<int_4>);
+
+  PPRegister(FIO_TArray<int_8>);
+  DObjRegister(FIO_TArray<int_8>, TArray<int_8>);
+  DObjRegister(FIO_TArray<int_8>, TMatrix<int_8>);
+  DObjRegister(FIO_TArray<int_8>, TVector<int_8>);
+
+  //  PPRegister(FIO_TArray<uint_4>);
+  // DObjRegister(FIO_TArray<uint_4>, TArray<uint_4>);
+  //  PPRegister(FIO_TArray<uint_8>);
+  //  DObjRegister(FIO_TArray<uint_8>, TArray<uint_8>);
+  PPRegister(FIO_TArray<r_4>);
+  DObjRegister(FIO_TArray<r_4>, TArray<r_4>);
+  DObjRegister(FIO_TArray<r_4>, TMatrix<r_4>);
+  DObjRegister(FIO_TArray<r_4>, TVector<r_4>);
+
+  PPRegister(FIO_TArray<r_8>);
+  DObjRegister(FIO_TArray<r_8>, TArray<r_8>);
+  DObjRegister(FIO_TArray<r_8>, TMatrix<r_8>);
+  DObjRegister(FIO_TArray<r_8>, TVector<r_8>);
+
+  PPRegister(FIO_TArray< complex<r_4> >);
+  DObjRegister(FIO_TArray< complex<r_4> >, TArray< complex<r_4> >);
+  DObjRegister(FIO_TArray< complex<r_4> >, TMatrix< complex<r_4> >);
+  DObjRegister(FIO_TArray< complex<r_4> >, TVector< complex<r_4> >);
+
+  PPRegister(FIO_TArray< complex<r_8> >);
+  DObjRegister(FIO_TArray< complex<r_8> >, TArray< complex<r_8> >);
+  DObjRegister(FIO_TArray< complex<r_8> >, TMatrix< complex<r_8> >);
+  DObjRegister(FIO_TArray< complex<r_8> >, TVector< complex<r_8> >);
+
+}
+
+TArrayInitiator::~TArrayInitiator()
+{
+  FgInit--;
+}
+
+
+// On met un objet initiator en statique, pour les loaders qui savent 
+// appeler le constructeur des objets statiques   Reza 08/98
+static TArrayInitiator tarrayinit;
+
Index: /tags/V_Dec2002/SophyaLib/TArray/tarrinit.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/TArray/tarrinit.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/TArray/tarrinit.h	(revision 2309)
@@ -0,0 +1,28 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe d'initialiseur du module TArray
+
+#ifndef TARRAYINIT_H_SEEN
+#define TARRAYINIT_H_SEEN
+
+
+// Classe d''initialisation pour le module de NTools
+#include "sophyainit.h"
+
+namespace SOPHYA {
+
+//! Array Matrices and Vector initiator
+class TArrayInitiator : public SophyaInitiator {
+private:
+  static int FgInit;
+public:
+  			TArrayInitiator();
+  virtual		~TArrayInitiator();
+};
+
+#undef SophyaInit
+#define SophyaInit() TArrayInitiator tarrayinitiator
+
+} // Fin du namespace
+
+#endif
+
Index: /tags/V_Dec2002/SophyaLib/TArray/tmatrix.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/TArray/tmatrix.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/TArray/tmatrix.cc	(revision 2309)
@@ -0,0 +1,461 @@
+// $Id: tmatrix.cc,v 1.23 2002-11-15 09:35:44 ansari Exp $
+//                         C.Magneville          04/99
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "pexceptions.h"
+#include "tmatrix.h"
+
+/*!
+  \class SOPHYA::TMatrix
+  \ingroup TArray
+  
+  The TMatrix class specializes the TArray class for representing
+  two dimensional arrays as matrices. Matrix and vector operations,
+  such as matrix multiplication or transposition is implemented.
+  \b Matrix is a typedef for double precision floating point matrix ( TMatrix<r_8> ).
+
+  \sa SOPHYA::TArray  SOPHYA::TVector
+  \sa SOPHYA::Range  \sa SOPHYA::Sequence
+  \sa SOPHYA::MathArray  \sa SOPHYA::SimpleMatrixOperation
+
+  The following sample code illustrates vector-matrix multiplication 
+  and matrix inversion, using simple gauss inversion.
+  \code
+  #include "array.h"
+  // ....
+  int n = 5;      // Size of matrix and vectors here
+  Matrix a(n,n);  
+  a = RandomSequence(RandomSequence::Gaussian, 0., 2.5);
+  Vector x(n);
+  x = RegularSequence(1.,3.);
+  Vector b = a*x;
+  cout << " ----- Vector x = \n " << x << endl;
+  cout << " ----- Vector b = a*x = \n " << b << endl;
+  SimpleMatrixOperation<r_8> smo;
+  Matrix inva = smo.Inverse(a);
+  cout << " ----- Matrix Inverse(a) = \n " << inva << endl;
+  cout << " ----- Matrix a*Inverse(a) = \n " << inva*a << endl;
+  cout << " ----- Matrix Inverse(a)*b (=Inv(a)*a*x) = \n " << inva*b << endl;
+  cout << " ----- Matrix x-Inverse(a)*b = (=0 ?)\n " << x-inva*b << endl;  
+  \endcode
+  
+ */
+
+////////////////////////////////////////////////////////////////
+//**** Createur, Destructeur
+//! Default constructor
+template <class T>
+TMatrix<T>::TMatrix()
+// Constructeur par defaut.
+  : TArray<T>()
+{
+  arrtype_ = 1;   // Type = Matrix
+}
+
+//! constructor of a matrix with  r lines et c columns.
+/*!
+  \param r : number of rows
+  \param c : number of columns
+  \param mm : define the memory mapping type
+  \sa ReSize
+ */
+template <class T>
+TMatrix<T>::TMatrix(sa_size_t r,sa_size_t c, short mm)
+// Construit une matrice de r lignes et c colonnes.
+  :  TArray<T>() 
+{
+  if ( (r == 0) || (c == 0) )
+    throw ParmError("TMatrix<T>::TMatrix(sa_size_t r,sa_size_t c) NRows or NCols = 0");
+  arrtype_ = 1;   // Type = Matrix
+  ReSize(r, c, mm);
+}
+
+//! Constructor by copy
+/*!
+  \warning datas are \b SHARED with \b a.
+  \sa NDataBlock::NDataBlock(const NDataBlock<T>&)
+*/
+template <class T>
+TMatrix<T>::TMatrix(const TMatrix<T>& a)
+// Constructeur par copie
+  : TArray<T>(a)
+{
+  arrtype_ = 1;   // Type = Matrix
+  UpdateMemoryMapping(a, SameMemoryMapping);
+}
+
+//! Constructor by copy
+/*!
+  \param share : if true, share data. If false copy data
+ */
+template <class T>
+TMatrix<T>::TMatrix(const TMatrix<T>& a, bool share)
+// Constructeur par copie avec possibilite de forcer le partage ou non.
+: TArray<T>(a, share)
+{
+  arrtype_ = 1;   // Type = Matrix
+  UpdateMemoryMapping(a, SameMemoryMapping);
+}
+
+//! Constructor of a matrix from a TArray \b a
+template <class T>
+TMatrix<T>::TMatrix(const TArray<T>& a)
+: TArray<T>(a)
+{
+  if (a.NbDimensions() > 2) 
+    throw SzMismatchError("TMatrix<T>::TMatrix(const TArray<T>& a) a.NbDimensions()>2 ");
+  if (a.NbDimensions() == 1) {
+    size_[1] = 1;
+    step_[1] = size_[0]*step_[0];
+    ndim_ = 2;
+  }
+  arrtype_ = 1;   // Type = Matrix
+  UpdateMemoryMapping(a, SameMemoryMapping);
+}
+
+//! Constructor of a matrix from a TArray \b a
+/*!
+  \param a : TArray to be copied or shared
+  \param share : if true, share data. If false copy data
+  \param mm : define the memory mapping type
+ */
+template <class T>
+TMatrix<T>::TMatrix(const TArray<T>& a, bool share, short mm )
+: TArray<T>(a, share)
+{
+  if (a.NbDimensions() > 2) 
+    throw SzMismatchError("TMatrix<T>::TMatrix(const TArray<T>& a, ...) a.NbDimensions()>2");
+  if (a.NbDimensions() == 1) {
+    size_[1] = 1;
+    step_[1] = size_[0]*step_[0];
+    ndim_ = 2;
+  }
+  arrtype_ = 1;   // Type = Matrix
+  UpdateMemoryMapping(a, mm);
+}
+
+//! Constructor of a matrix from a TArray \b a , with a different data type
+template <class T>
+TMatrix<T>::TMatrix(const BaseArray& a)
+: TArray<T>()
+{
+  arrtype_ = 1;   // Type = Matrix
+  UpdateMemoryMapping(a, SameMemoryMapping);
+  SetBA(a);
+}
+
+
+
+//! Destructor
+template <class T>
+TMatrix<T>::~TMatrix()
+{
+}
+
+//! Set matrix equal to \b a and return *this
+/*!
+  \warning Datas are copied (cloned) from \b a.
+  \sa NDataBlock::operator=(const NDataBlock<T>&)
+*/
+template <class T>
+TArray<T>& TMatrix<T>::Set(const TArray<T>& a)
+{
+  if (a.NbDimensions() > 2) 
+    throw SzMismatchError("TMatrix<T>::Set(const TArray<T>& a) a.NbDimensions() > 2");
+  if ((arrtype_ == 2) && (a.NbDimensions() > 1) && (a.Size(0) > 1) && (a.Size(1) > 1) )
+    throw SzMismatchError("TMatrix<T>::Set(const TArray<T>& a) Size(0,1)>1 for Vector");
+  TArray<T>::Set(a);
+  if (NbDimensions() == 1) {
+    size_[1] = 1;
+    step_[1] = size_[0]*step_[0];
+    ndim_ = 2;
+  }
+  UpdateMemoryMapping(*this, SameMemoryMapping);
+  return(*this);
+}
+
+template <class T>
+TArray<T>& TMatrix<T>::SetBA(const BaseArray& a)
+{
+  if (a.NbDimensions() > 2) 
+    throw SzMismatchError("TMatrix<T>::SetBA(const BaseArray& a) a.NbDimensions() > 2");
+  if ((arrtype_ == 2) && (a.NbDimensions() > 1) && (a.Size(0) > 1) && (a.Size(1) > 1) )
+    throw SzMismatchError("TMatrix<T>::Set(const TArray<T>& a) Size(0,1)>1 for Vector");
+  TArray<T>::SetBA(a);
+  if (NbDimensions() == 1) {
+    size_[1] = 1;
+    step_[1] = size_[0]*step_[0];
+    ndim_ = 2;
+  }
+  UpdateMemoryMapping(*this, SameMemoryMapping);
+  return(*this);
+}
+
+
+
+//! Resize the matrix
+/*!
+  \param r : number of rows
+  \param c : number of columns
+  \param mm : define the memory mapping type
+         (SameMemoryMapping,CMemoryMapping
+         ,FortranMemoryMapping,DefaultMemoryMapping)
+ */
+template <class T>
+void TMatrix<T>::ReSize(sa_size_t r, sa_size_t c, short mm)
+{
+  if(r==0||c==0) 
+    throw(SzMismatchError("TMatrix::ReSize r or c==0 "));
+  if ((arrtype_ == 2) && (r > 1) && (c > 1))
+    throw(SzMismatchError("TMatrix::ReSize r>1&&c>1 for Vector "));
+  sa_size_t size[BASEARRAY_MAXNDIMS];
+  for(int_4 kk=0; kk<BASEARRAY_MAXNDIMS; kk++)  size[kk] = 0;
+  if (mm == SameMemoryMapping) mm = GetMemoryMapping();  
+  else if ( (mm != CMemoryMapping) && (mm != FortranMemoryMapping) ) 
+    mm = GetDefaultMemoryMapping();
+  if (mm == CMemoryMapping) {
+    size[0] = c;  size[1] = r;
+  }
+  else {
+    size[0] = r;  size[1] = c;
+  }
+  TArray<T>::ReSize(2, size, 1);
+  UpdateMemoryMapping(mm);
+}
+
+//! Re-allocate space for the matrix
+/*!
+  \param r : number of rows
+  \param c : number of columns
+  \param mm : define the memory mapping type
+  \param force : if true re-allocation is forced, if not it occurs
+          only if the required space is greater than the old one.
+  \sa ReSize
+ */
+template <class T>
+void TMatrix<T>::Realloc(sa_size_t r,sa_size_t c, short mm, bool force)
+{
+  if(r==0||c==0) 
+    throw(SzMismatchError("TMatrix::Realloc r or c==0 "));
+  if ((arrtype_ == 2) && (r > 1) && (c > 1))
+    throw(SzMismatchError("TMatrix::Realloc r>1&&c>1 for Vector "));
+  sa_size_t size[BASEARRAY_MAXNDIMS];
+  for(int_4 kk=0; kk<BASEARRAY_MAXNDIMS; kk++)  size[kk] = 0;
+  if (mm == SameMemoryMapping) mm = GetMemoryMapping();  
+  else if ( (mm != CMemoryMapping) && (mm != FortranMemoryMapping) ) 
+    mm = GetDefaultMemoryMapping();
+  if (mm == CMemoryMapping) {
+    size[0] = c;  size[1] = r;
+  }
+  else {
+    size[0] = r;  size[1] = c;
+  }
+  TArray<T>::Realloc(2, size, 1, force);
+  UpdateMemoryMapping(mm);
+}
+
+// $CHECK$ Reza 03/2000  Doit-on declarer cette methode const ?
+//! Return a submatrix define by \b Range \b rline and \b rcol
+template <class T>
+TMatrix<T> TMatrix<T>::SubMatrix(Range rline, Range rcol) const
+{
+  short mm = GetMemoryMapping();
+  Range rx, ry;
+  if (mm == CMemoryMapping)  { rx = rcol;  ry = rline; }
+  else { ry = rcol;  rx = rline; }
+  TMatrix sm(SubArray(rx, ry, Range(0), Range(0), Range(0)),true, mm);
+  sm.UpdateMemoryMapping(mm);
+  return(sm);
+}
+
+////////////////////////////////////////////////////////////////
+// Transposition
+//! Transpose matrix in place, by changing the memory mapping
+template <class T>
+TMatrix<T>& TMatrix<T>::TransposeSelf() 
+{
+  short vt = (marowi_ == veceli_) ? ColumnVector : RowVector;
+  int_4 rci = macoli_;
+  macoli_ = marowi_;
+  marowi_ = rci;
+  veceli_ = (vt ==  ColumnVector ) ?  marowi_ : macoli_;
+  return(*this);
+}
+
+
+//! Returns the transpose of the original matrix. 
+/*!
+  The data is shared between the two matrices
+  \return return a new matrix
+ */
+template <class T>
+TMatrix<T> TMatrix<T>::Transpose()
+{
+  TMatrix<T> tm(*this);
+  tm.TransposeSelf();
+  return tm;
+}
+
+//! Returns a new matrix, corresponding to the transpose of the original matrix
+/*!
+  \param mm : define the memory mapping type
+    (SameMemoryMapping,CMemoryMapping,FortranMemoryMapping)
+  \return return a new matrix
+ */
+template <class T>
+TMatrix<T> TMatrix<T>::Transpose(short mm)
+{
+  if (mm == SameMemoryMapping) mm = GetMemoryMapping();  
+  TMatrix<T> tm(NCols(), NRows(), mm);
+  for(sa_size_t i=0; i<NRows(); i++)
+    for(sa_size_t j=0; j<NCols(); j++) 
+      tm(j,i) = (*this)(i,j);
+  return tm;
+}
+
+//! Rearrange data in memory according to \b mm
+/*!
+  \param mm : define the memory mapping type
+    (SameMemoryMapping,CMemoryMapping,FortranMemoryMapping)
+  \warning If identical, return a matrix that share the datas
+ */
+template <class T>
+TMatrix<T> TMatrix<T>::Rearrange(short mm)
+{
+  if ( mm == SameMemoryMapping)  mm = GetMemoryMapping();
+  else if ( (mm != CMemoryMapping) && (mm != FortranMemoryMapping) ) 
+    mm = GetDefaultMemoryMapping();
+  
+  if  (mm == GetMemoryMapping())
+    return (TMatrix<T>(*this, true));
+  
+  TMatrix<T> tm(NRows(), NCols(), mm);
+  for(sa_size_t i=0; i<NRows(); i++)
+    for(sa_size_t j=0; j<NCols(); j++) 
+      tm(i,j) = (*this)(i,j);
+  return tm;
+}
+
+//! Set the matrix to the identity matrix \b imx
+template <class T>
+TMatrix<T>& TMatrix<T>::SetIdentity(IdentityMatrix imx)
+{
+  if (ndim_ == 0) {
+    sa_size_t sz = imx.Size();
+    if (sz < 1) sz = 1;
+    ReSize(sz, sz);
+  }
+  T diag = (T)imx.Diag();
+  if (NRows() != NCols()) 
+    throw SzMismatchError("TMatrix::operator= (IdentityMatrix) NRows() != NCols()") ;
+  *this = (T) 0;
+  for(sa_size_t i=0; i<NRows(); i++) (*this)(i,i) = diag;
+
+  return (*this);
+}
+
+
+
+////////////////////////////////////////////////////////////////
+//**** Impression
+//! Return info on number of rows, column and type \b T
+template <class T>
+string TMatrix<T>::InfoString() const
+{
+  string rs = "TMatrix<";
+  rs += typeid(T).name();
+  char buff[64];
+  sprintf(buff, ">(NRows=%ld, NCols=%ld)", (long)NRows(), (long)NCols());
+  rs += buff;
+  return(rs);  
+}
+
+//! Print matrix
+/*!
+  \param os : output stream
+  \param maxprt : maximum numer of print
+  \param si : if true,  display attached DvList
+  \param ascd : if true, suppresses the display of line numbers,
+  suitable for ascii dump format.
+  \sa SetMaxPrint
+ */
+template <class T>
+void TMatrix<T>::Print(ostream& os, sa_size_t maxprt, bool si, bool ascd) const
+{
+  if (maxprt < 0)  maxprt = max_nprt_;
+  sa_size_t npr = 0;
+  Show(os, si);
+  if (ndim_ < 1)  return;
+  sa_size_t kc,kr;  
+  for(kr=0; kr<size_[marowi_]; kr++) {
+    if ( (size_[marowi_] > 1) && (size_[macoli_] > 10) && ascd) cout << "----- Line= " << kr << endl;
+    for(kc=0; kc<size_[macoli_]; kc++) {
+      if(kc > 0) os << " ";  
+      os << (*this)(kr, kc);   npr++; 
+      if (npr >= (sa_size_t) maxprt) {
+	if (npr < totsize_)  os << "\n     .... " << endl; return;
+      }
+    }
+    os << endl;
+  }
+  os << endl;
+}
+
+////////////////////////////////////////////////////////////////
+//****  Multiplication matricielle  *****
+////////////////////////////////////////////////////////////////
+
+//! Return the matrix product C = (*this)*B
+/*!
+  \param mm : define the memory mapping type for the return matrix
+ */
+template <class T>
+TMatrix<T> TMatrix<T>::Multiply(const TMatrix<T>& b, short mm) const
+{
+  if (NCols() != b.NRows()) 
+    throw(SzMismatchError("TMatrix<T>::Multiply(b) NCols() != b.NRows() ") );
+  if (mm == SameMemoryMapping) mm = GetMemoryMapping();  
+  TMatrix<T> rm(NRows(), b.NCols(), mm);
+
+  const T * pea;
+  const T * peb;
+  T sum;
+  sa_size_t r,c,k;
+  sa_size_t stepa = Step(ColsKA());
+  sa_size_t stepb = b.Step(b.RowsKA());
+  // Calcul de C=rm = A*B   (A=*this)
+  for(r=0; r<rm.NRows(); r++)      // Boucle sur les lignes de A
+    for(c=0; c<rm.NCols(); c++) {     // Boucle sur les colonnes de B
+      sum = 0;
+      pea = &((*this)(r,0));       // 1er element de la ligne r de A
+      peb = &(b(0,c));                // 1er element de la colonne c de B
+      for(k=0; k<NCols(); k++)  sum += pea[k*stepa]*peb[k*stepb];
+      rm(r,c) = sum;
+    }
+
+  return rm;
+}
+
+///////////////////////////////////////////////////////////////
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template TMatrix<uint_2>
+#pragma define_template TMatrix<uint_8>
+#pragma define_template TMatrix<int_4>
+#pragma define_template TMatrix<int_8>
+#pragma define_template TMatrix<r_4>
+#pragma define_template TMatrix<r_8> 
+#pragma define_template TMatrix< complex<r_4> > 
+#pragma define_template TMatrix< complex<r_8> > 
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class TMatrix<uint_2>;
+template class TMatrix<uint_8>;
+template class TMatrix<int_4>;
+template class TMatrix<int_8>;
+template class TMatrix<r_4>;
+template class TMatrix<r_8>;
+template class TMatrix< complex<r_4> >;
+template class TMatrix< complex<r_8> >;
+#endif
Index: /tags/V_Dec2002/SophyaLib/TArray/tmatrix.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/TArray/tmatrix.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/TArray/tmatrix.h	(revision 2309)
@@ -0,0 +1,246 @@
+// This may look like C code, but it is really -*- C++ -*-
+//                         C.Magneville          04/99
+#ifndef TMatrix_SEEN
+#define TMatrix_SEEN
+
+#include "machdefs.h"
+#include "tarray.h"
+
+namespace SOPHYA {
+
+//! Class of matrices
+template <class T>
+class TMatrix : public TArray<T> {
+public:
+  // Creation / destruction 
+  TMatrix();
+  TMatrix(sa_size_t r,sa_size_t c, short mm=BaseArray::AutoMemoryMapping);
+  TMatrix(const TMatrix<T>& a);
+  TMatrix(const TMatrix<T>& a, bool share);
+  TMatrix(const TArray<T>& a); 
+  TMatrix(const TArray<T>& a,  bool share, short mm=BaseArray::AutoMemoryMapping);
+  TMatrix(const BaseArray& a); 
+
+  virtual ~TMatrix();
+
+  //  Pour verifiez la compatibilite de dimensions lors de l'affectation
+  virtual TArray<T>& Set(const TArray<T>& a);
+  //! Operator = between matrices
+  /*! \warning Datas are copied (cloned) from \b a.
+      \sa NDataBlock::operator=(const NDataBlock<T>&) */
+  inline  TMatrix<T>& operator = (const TMatrix<T>& a)
+                     { Set(a);  return(*this); }
+  //! Operator = between a matrix and an array 
+  inline  TMatrix<T>& operator = (const TArray<T>& a)
+                     { Set(a);  return(*this); }
+
+  virtual TArray<T>& SetBA(const BaseArray& a);
+  //! Operator = between matrices with different types
+  inline  TMatrix<T>& operator = (const BaseArray& a)
+                     { SetBA(a);  return(*this); }
+
+  // Size - Changing the Size 
+  //! return number of rows
+  inline sa_size_t NRows() const {return Size(marowi_); }
+  //! return number of columns
+  inline sa_size_t NCols() const {return Size(macoli_); }
+  //! return number of columns
+  inline sa_size_t NCol()  const {return Size(macoli_); } // back-compat Peida
+
+  void ReSize(sa_size_t r,sa_size_t c, short mm=BaseArray::SameMemoryMapping);
+  //! a synonym (alias) for method ReSize(sa_size_t, sa_size_t, short)
+  inline void SetSize(sa_size_t r,sa_size_t c, short mm=BaseArray::SameMemoryMapping)
+                 { ReSize(r, c, mm); }
+  // Reallocation de place
+  void Realloc(sa_size_t r,sa_size_t c, short mm=BaseArray::SameMemoryMapping, bool force=false);
+
+  // Sub-matrix extraction $CHECK$ Reza 03/2000  Doit-on declarer ces methode const ?
+  TMatrix<T> SubMatrix(Range rline, Range rcol) const ;
+  //! () : Return submatrix define by \b Range \b rline and \b rcol
+  inline TMatrix<T> operator () (Range rline, Range rcol) const 
+                    { return SubMatrix(rline, rcol); }
+  // Lignes et colonnes de la matrice
+  //! Return submatrix define by line \b ir (line vector)
+  inline TMatrix<T> Row(sa_size_t ir) const
+                    { return SubMatrix(Range(ir,ir), Range(0,NCols()-1)); }
+  //! Return submatrix define by column \b ic (column vector)
+  inline TMatrix<T> Column(sa_size_t ic) const
+                    { return SubMatrix(Range(0,NRows()-1), Range(ic,ic)); }
+
+  // Inline element acces methods 
+  inline T const& operator()(sa_size_t r,sa_size_t c) const;
+  inline T&       operator()(sa_size_t r,sa_size_t c);
+
+  // Operations matricielles
+  TMatrix<T>& TransposeSelf();
+  TMatrix<T>  Transpose();
+  //mm = SameMemoryMapping or CMemoryMapping or FortranMemoryMapping 
+  TMatrix<T>  Transpose(short mm); 
+  // Rearranging Matrix Elements
+  TMatrix<T>  Rearrange(short mm);
+
+  // Operateur d'affectation
+  // A = x (matrice diagonale Identite)
+  virtual TMatrix<T>& SetIdentity(IdentityMatrix imx);
+  // = : fill matrix with an identity matrix \b imx
+  inline  TMatrix<T>& operator = (IdentityMatrix imx) { return SetIdentity(imx); }
+
+  // = : fill matrix with a Sequence \b seq
+  inline  TMatrix<T>&  operator = (Sequence const & seq)    { SetSeq(seq); return(*this); }
+
+  // Operations diverses  avec une constante
+  //! = : fill matrix with constant value \b x
+  inline  TMatrix<T>&  operator = (T x)             { SetT(x); return(*this); }
+  //! += : add constant value \b x to matrix
+  inline  TMatrix<T>&  operator += (T x)            { Add(x); return(*this); }
+  //! -= : substract constant value \b x to matrix
+  inline  TMatrix<T>&  operator -= (T x)            { Sub(x); return(*this); }
+  //! *= : multiply matrix by constant value \b x
+  inline  TMatrix<T>&  operator *= (T x)            { Mul(x); return(*this); }
+  //! /= : divide matrix by constant value \b x
+  inline  TMatrix<T>&  operator /= (T x)            { Div(x); return(*this); }
+
+  //  operations avec matrices 
+  //! += : add a matrix
+  inline  TMatrix<T>&  operator += (const TMatrix<T>& a)  { AddElt(a); return(*this); }
+  //! -= : substract a matrix
+  inline  TMatrix<T>&  operator -= (const TMatrix<T>& a)  { SubElt(a); return(*this); }
+  TMatrix<T>  Multiply(const TMatrix<T>& b, short mm=BaseArray::SameMemoryMapping) const;
+  //! *= : matrix product : C = (*this)*B
+  inline  TMatrix<T>&  operator *= (const TMatrix<T>& b)
+          { this->Set(Multiply(b));  return(*this); }
+
+  // I/O print, ...
+  virtual string InfoString() const;
+  virtual void  Print(ostream& os, sa_size_t maxprt=-1, 
+		      bool si=false, bool ascd=false) const ;
+
+protected:
+};
+
+//  ---- inline acces methods ------
+ //! () : return element for line \b r and column \b c
+template <class T>
+inline T const& TMatrix<T>::operator()(sa_size_t r, sa_size_t c) const
+{
+#ifdef SO_BOUNDCHECKING
+  if (marowi_ == 0)   CheckBound(r, c, 0, 0, 0, 4);
+  else   CheckBound(c, r, 0, 0, 0, 4);
+#endif
+  return ( *( mNDBlock.Begin()+ offset_+ 
+	      r*step_[marowi_] + c*step_[macoli_] ) );
+}
+
+//! () : return element for line \b r and column \b c
+template <class T>
+inline T & TMatrix<T>::operator()(sa_size_t r, sa_size_t c) 
+{
+#ifdef SO_BOUNDCHECKING
+  if (marowi_ == 0)   CheckBound(r, c, 0, 0, 0, 4);
+  else   CheckBound(c, r, 0, 0, 0, 4);
+#endif
+  return ( *( mNDBlock.Begin()+ offset_+ 
+	      r*step_[marowi_] + c*step_[macoli_] ) );
+}
+////////////////////////////////////////////////////////////////
+// Surcharge d'operateurs A (+,-,*,/) (T) x
+
+/*! \ingroup TMatrix \fn operator+(const TMatrix<T>&,T)
+  \brief Operator TMatrix = TMatrix + constant */
+template <class T> inline TMatrix<T> operator + (const TMatrix<T>& a, T b)
+    {TMatrix<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Add(b); return result;}
+
+/*! \ingroup TMatrix \fn operator+(T,const TMatrix<T>&)
+  \brief Operator TMatrix = constant + TMatrix */
+template <class T> inline TMatrix<T> operator + (T b,const TMatrix<T>& a)
+    {TMatrix<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Add(b); return result;}
+
+/*! \ingroup TMatrix \fn operator-(const TMatrix<T>&,T)
+  \brief Operator TMatrix = TMatrix - constant */
+template <class T> inline TMatrix<T> operator - (const TMatrix<T>& a, T b)
+    {TMatrix<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Sub(b); return result;}
+
+/*! \ingroup TMatrix \fn operator-(T,const TMatrix<T>&)
+  \brief Operator TMatrix = constant - TMatrix */
+template <class T> inline TMatrix<T> operator - (T b,const TMatrix<T>& a)
+    {TMatrix<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Sub(b,true); return result;}
+
+/*! \ingroup TMatrix \fn operator*(const TMatrix<T>&,T)
+  \brief Operator TMatrix = TMatrix * constant */
+template <class T> inline TMatrix<T> operator * (const TMatrix<T>& a, T b)
+    {TMatrix<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Mul(b); return result;}
+
+/*! \ingroup TMatrix \fn operator*(T,const TMatrix<T>&)
+  \brief Operator TMatrix = constant * TMatrix */
+template <class T> inline TMatrix<T> operator * (T b,const TMatrix<T>& a)
+    {TMatrix<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Mul(b); return result;}
+
+/*! \ingroup TMatrix \fn operator/(const TMatrix<T>&,T)
+  \brief Operator TMatrix = TMatrix / constant */
+template <class T> inline TMatrix<T> operator / (const TMatrix<T>& a, T b)
+    {TMatrix<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Div(b); return result;}
+
+/*! \ingroup TMatrix \fn operator/(T,const TMatrix<T>&)
+  \brief Operator TMatrix = constant / TMatrix  */
+template <class T> inline TMatrix<T> operator / (T b, const TMatrix<T>& a)
+    {TMatrix<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.Div(b, true); return result;}
+
+////////////////////////////////////////////////////////////////
+// Surcharge d'operateurs B = -A
+
+/*! \ingroup TMatrix \fn operator - (const TMatrix<T>&)
+  \brief Operator - Returns a matrix with elements equal to the opposite of
+  the original matrix elements.  */
+template <class T> inline TMatrix<T> operator - (const TMatrix<T>& a)
+    {TMatrix<T> result; result.CloneOrShare(a); result.SetTemp(true); 
+    result.NegateElt(); return result;}
+
+
+// Surcharge d'operateurs C = A (+,-) B
+// $CHECK$ Reza 3/4/2000 Pas necessaire  de redefinir les operateurs
+// Defini au niveau de TArray<T> - Pour ameliorer l'efficacite
+// Doit-on le faire aussi pour les constantes ? - Fin de $CHECK$ Reza 3/4/2000
+
+/*! \ingroup TArray \fn operator+(const TMatrix<T>&,const TMatrix<T>&)
+  \brief + : add matrixes \b a and \b b */
+template <class T>
+inline TMatrix<T> operator + (const TMatrix<T>& a,const TMatrix<T>& b)
+    {TMatrix<T> result; result.SetTemp(true); 
+    if (b.IsTemp())  { result.Share(b); result.AddElt(a); }
+    else { result.CloneOrShare(a); result.AddElt(b); }
+    return result; }
+
+
+/*! \ingroup TArray \fn operator-(const TMatrix<T>&,const TMatrix<T>&)
+  \brief \- : substract matrixes \b a and \b b */
+template <class T>
+inline TMatrix<T> operator - (const TMatrix<T>& a,const TMatrix<T>& b)
+    {TMatrix<T> result; result.SetTemp(true); 
+    if (b.IsTemp())  { result.Share(b); result.SubElt(a, true); }
+    else { result.CloneOrShare(a); result.SubElt(b); }
+    return result; }
+
+// Surcharge d'operateurs C = A * B
+/*! \ingroup TArray \fn operator*(const TMatrix<T>&,const TMatrix<T>&)
+  \brief * : multiply matrixes \b a and \b b */
+template <class T> inline TMatrix<T> operator * (const TMatrix<T>& a, const TMatrix<T>& b)
+   { return(a.Multiply(b)); }
+
+// Typedef pour simplifier et compatibilite Peida
+/*! \ingroup TArray
+  \typedef Matrix
+  \brief To simplified TMatrix<r_8> writing
+*/
+typedef TMatrix<r_8> Matrix;
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/TArray/toeplitzMatrix.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/TArray/toeplitzMatrix.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/TArray/toeplitzMatrix.cc	(revision 2309)
@@ -0,0 +1,787 @@
+
+#include "toeplitzMatrix.h"
+#include "timing.h"   
+Toeplitz::Toeplitz() : hermitian_(false)
+  {
+    fftIntfPtr_=new FFTPackServer;
+    fftIntfPtr_->setNormalize(false);
+  }
+
+// matrice de Toplitz hermitienne. La premiere ligne est conjuguee de la 
+// premeire colonne donnee (vecteur firstCol)
+Toeplitz::Toeplitz(const TVector<complex<double> >& firstCol) : hermitian_(false)
+  {
+    fftIntfPtr_=new FFTPackServer;
+    fftIntfPtr_->setNormalize(false);
+    setMatrix(firstCol); 
+  }
+
+
+Toeplitz::~Toeplitz(){ if (fftIntfPtr_!=NULL) delete fftIntfPtr_;};
+
+
+// initialise matrice de Toeplitz hermitienne
+void  Toeplitz::setMatrix(const TVector<complex<double> >& firstCol) 
+  {
+    hermitian_ = true;
+    dimTop_ = firstCol.Size();
+    extensionACirculanteDyadique(firstCol);
+    //    transformeeFourier(vecteurCirculant_, CirculanteFourier_);
+  }
+
+// intialise la matrice de Toeplitz generale complexe
+void  Toeplitz::setMatrix(const TVector<complex<double> >& firstCol, const TVector<complex<double> >& firstRow) 
+  {
+    hermitian_ = false;
+    dimTop_ = firstCol.Size();
+  if (dimTop_ != firstRow.Size())
+    {
+      cout << " Toeplitz::setMatrix : nb col different de nbLignes " << endl; 
+    }
+    extensionACirculanteDyadique(firstCol, firstRow);
+    //    transformeeFourier(vecteurCirculant_, CirculanteFourier_);
+  }
+
+
+// intialise la matrice de Toeplitz generale reelle
+void  Toeplitz::setMatrix(const TVector<double>& firstCol, const TVector<double>& firstRow) 
+  {
+    hermitian_ = false;
+    dimTop_ = firstCol.Size();
+  if (dimTop_ != firstRow.Size())
+    {
+      cout << " Toeplitz::setMatrix : nb col different de nbLignes " << endl; 
+    }
+    extensionACirculanteDyadique(firstCol, firstRow);
+    //    transformeeFourier(vecteurCirculantD_, CirculanteFourier_);
+  }
+
+// intialise la matrice de Toeplitz generale reelle symetrique
+void  Toeplitz::setMatrix(const TVector<double>& firstCol) 
+  {
+    hermitian_ = true;
+    dimTop_ = firstCol.Size();
+    extensionACirculanteDyadique(firstCol);
+    //    transformeeFourier(vecteurCirculantD_, CirculanteFourier_);
+  }
+
+
+// resolution par gradient conjugue d'un systeme dont la matrice est 
+// la matrice de Toeplitz
+// (le vecteur b est le second membre)
+// renvoie le nombre d'iterations (-1 si non convergence)
+int Toeplitz::gradientToeplitz(TVector<complex<double> >& b) const
+{
+  // PrtTim(" entree gradient " );
+  int k;
+  if (dimTop_ != b.Size())
+    {
+      throw SzMismatchError("TOEPLITZMATRIX : gradientToeplitz : RHS dimensions mismatch \n");
+    }
+  if (!hermitian_) 
+    {
+      throw PException(" TOEPLITZMATRIX : conjugate gradient for hermitian matrix only\n");
+    }
+  int ndyad = vecteurCirculant_.Size();
+
+  TVector<complex<double> > a(dimTop_);
+  TVector<complex<double> > r(dimTop_);
+  TVector<complex<double> > q(ndyad);
+
+  a =complex<double>(0.,0.);
+  
+  r = b;
+  q =complex<double>(0.,0.);
+  // int dimTopM1 = dimTop_-1;
+   for (k=0; k<dimTop_; k++) q(k) = r(k);
+  //q(Range(0,dimTopM1)) = r;
+  //q.Print(cout, q.Size());  
+
+  double norm2Rk = prodScalaire(dimTop_,r,r).real();  
+  double norm2R0 = norm2Rk;  
+  int niter =0;
+    do 
+    {
+      int k;
+      TVector<complex<double> > Aq;
+      produitParVecFourier(q, Aq);
+      //
+      double  norme2Aq = prodScalaire(dimTop_,Aq,q).real();
+      complex<double> alpha = prodScalaire(dimTop_,r,r)/norme2Aq;
+      for (k=0; k<dimTop_; k++) a(k) += alpha*q(k);
+      for (k=0; k<dimTop_; k++) r(k) -= alpha*Aq(k);
+      double norm2Rkp1 = prodScalaire(dimTop_,r,r).real(); 
+      double beta = norm2Rkp1/norm2Rk;
+      for (k=0; k<dimTop_; k++) q(k) = r(k) + beta*q(k);
+
+      norm2Rk = norm2Rkp1;
+      
+      //  cout << " iteration " << niter+1 << " norme residu= " << norm2Rk << " critere arret " << norm2Rk/norm2R0 << endl;
+      niter++;
+    }
+
+    while (norm2Rk/norm2R0 > 1.e-12 && niter < 2*dimTop_);
+
+    //   PrtTim(" fin du gradient ");
+
+    // verification a supprimer 
+    //TMatrix<complex<double> > ttest(dimTop_, dimTop_);
+    //expliciteToeplitz(ttest);
+    //TVector<complex<double> > btest;
+    //ttest.Show();
+    //cout << " long vec circ " << dimTop_ << " long a " << a.Size() << endl;
+    //btest = ttest*a;
+    //for (int k=0; k< b.Size(); k++)
+    // {
+    //	cout << " verif gradient donnee " << b(k) << " retrouve " << btest(k) << endl;
+    //  }
+    //
+    b = a;
+    
+    if (niter == 2*dimTop_-1) niter = -1;
+    return niter;
+}
+
+
+// resolution par gradient conjugue d'un systeme dont la matrice est 
+// la matrice de Toeplitz
+// (le vecteur b est le second membre)
+// renvoie le nombre d'iterations (-1 si non converge
+int Toeplitz::gradientToeplitz(TVector<double>& b) const
+{
+  int k;
+  if (dimTop_ != b.Size())
+    {
+      throw SzMismatchError("TOEPLITZMATRIX : gradientToeplitz : RHS dimensions mismatch \n");
+    }
+  if (!hermitian_) 
+    {
+      throw PException(" TOEPLITZMATRIX : conjugate gradient for hermitian matrix only\n");
+    }
+
+  int ndyad = vecteurCirculantD_.Size();
+
+  TVector<double> a(dimTop_);
+  TVector<double> r(dimTop_);
+  TVector<double> q(ndyad);
+
+  a =0.;
+
+  r = b;
+  q =0.;
+  for (k=0; k<dimTop_; k++) q(k) = r(k);
+
+
+  double norm2Rk = prodScalaire(dimTop_,r,r);  
+  double norm2R0 = norm2Rk;  
+  int niter =0;
+  do 
+    {
+      int k;
+      TVector<double> Aq;
+      produitParVecFourier(q, Aq);
+
+      //
+      double  norme2Aq = prodScalaire(dimTop_,Aq,q);
+      double alpha = prodScalaire(dimTop_,r,r)/norme2Aq;
+      for (k=0; k<dimTop_; k++)
+	{
+	  a(k) += alpha*q(k);
+	  r(k) -= alpha*Aq(k);
+	}
+      double norm2Rkp1 = prodScalaire(dimTop_,r,r); 
+      double beta = norm2Rkp1/norm2Rk;
+      for (k=0; k<dimTop_; k++) q(k) = r(k) + beta*q(k);
+
+      norm2Rk = norm2Rkp1;
+      
+      //  cout << " iteration " << niter+1 << " norme residu= " << norm2Rk << " critere arret " << norm2Rk/norm2R0 << endl;
+      niter++;
+        }
+
+      while (norm2Rk/norm2R0 > 1.e-12 && niter < 2*dimTop_);
+    //   while (norm2Rk/norm2R0 > 1.e-12 && niter < 1);
+
+
+
+    // verification a supprimer 
+  //TMatrix<double> ttest(dimTop_, dimTop_);
+  //expliciteToeplitz(ttest);
+  // TVector<double> btest;
+  // ttest.Show();
+    //cout << " long vec circ " << dimTop_ << " long a " << a.Size() << endl;
+  // btest = ttest*a;
+  // for (int k=0; k< b.Size(); k++)
+  //  {
+  // 	cout << " verif gradient donnee " << b(k) << " retrouve " << btest(k) << endl;
+  //   }
+    //
+    b = a;
+    
+    if (niter == 2*dimTop_-1) niter = -1;
+    return niter;
+}
+// resolution par Gradient Conjugue Generalise d'un systeme dont 
+// la matrice est la matrice de Toeplitz
+// (le vecteur b est le second membre)
+// renvoie le nombre d'iterations (-1 si non converge
+int Toeplitz::CGSToeplitz(TVector<double>& b) const
+{
+  int k;
+  if (dimTop_ != b.Size())
+    {
+      throw SzMismatchError("TOEPLITZMATRIX : gradientToeplitz : RHS dimensions mismatch \n");
+    }
+
+  int ndyad = vecteurCirculantD_.Size();
+
+  TVector<double> x(dimTop_);
+  TVector<double> r(dimTop_);
+  TVector<double> r0(dimTop_);
+  TVector<double> q(ndyad);
+  TVector<double> p(ndyad);
+
+  // initialisations 
+  x =0.;
+  r0 = b;
+  r = r0;
+  q =0.;
+  p =0.;
+  for (k=0; k<dimTop_; k++)
+    {
+      q(k) = r(k);
+      p(k) = r(k);
+    }
+  int niter =0;
+  double r0rk = prodScalaire(dimTop_,r0,r);
+  double r0r0 = r0rk;
+  double rkrk = r0r0;
+  double r0rkp1 = r0rk;
+  do 
+    {
+      int k;
+      TVector<double> Aq;
+      produitParVecFourier(q, Aq);
+      TVector<double> Ap;
+      produitParVecFourier(p, Ap);
+
+      TVector<double> pMalphaAq(ndyad);
+
+
+      //
+
+      double  r0Aqk = prodScalaire(dimTop_,r0,Aq);
+      double alpha = r0rk/r0Aqk;
+      pMalphaAq = p-alpha*Aq;
+      TVector<double> aux(ndyad);
+      aux = p + pMalphaAq;
+      TVector<double> Aaux;
+      produitParVecFourier(aux, Aaux);
+
+      for (k=0; k<dimTop_; k++)
+      	{
+	  x(k) += alpha*aux(k);
+	  r(k) -= alpha*Aaux(k);
+	}
+      r0rkp1 = prodScalaire(dimTop_,r0,r); 
+      double beta = r0rkp1/r0rk;
+      for (k=0; k<dimTop_; k++) p(k) = r(k) + beta*pMalphaAq(k);
+      for (k=0; k<dimTop_; k++)
+	{
+	  q(k)  = p(k) + beta*(beta*q(k) + pMalphaAq(k));
+	}
+      r0rk  = r0rkp1;
+      rkrk = prodScalaire(dimTop_,r,r); 
+      //    cout << " iteration " << niter+1 << " rkrk= " << rkrk << " critere arret " << rkrk/r0r0 << endl;
+      niter++;
+        }
+
+     while (rkrk/r0r0 > 1.e-12 && niter < 2*dimTop_);
+  // while ( niter < 10*dimTop_);
+
+    // verification a supprimer 
+  //TMatrix<double> ttest(dimTop_, dimTop_);
+  //expliciteToeplitz(ttest);
+  //TVector<double> btest;
+  // ttest.Show();
+    //cout << " long vec circ " << dimTop_ << " long a " << a.Size() << endl;
+  //btest = ttest*x;
+  // for (int k=0; k< b.Size(); k++)
+  // {
+  //	cout << " verif gradient donnee " << b(k) << " retrouve " << btest(k) << endl;
+  //  }
+    //
+    b = x;
+    
+    if (niter == 2*dimTop_) niter = -1;
+    return niter;
+}
+// resolution par Double Gradient Conjugue d'un systeme dont 
+// la matrice est la matrice de Toeplitz
+// (le vecteur b est le second membre)
+// renvoie le nombre d'iterations (-1 si non converge
+int Toeplitz::DCGToeplitz(TVector<double>& b) 
+{
+  int k;
+  if (dimTop_ != b.Size())
+    {
+      throw SzMismatchError("TOEPLITZMATRIX : gradientToeplitz : RHS dimensions mismatch \n");
+    }
+
+  // on a besoin des produit (matrice trasposee)Xvectteur
+  // on initialise eventuellement la TF de Toeplitz transposee
+  if (CirculanteTransposeeFourier_.Size() == 0) initTFTransposeeToeplitzReelle();
+
+
+  int ndyad = vecteurCirculantD_.Size();
+
+  TVector<double> x(dimTop_);
+  TVector<double> r1(dimTop_);
+  TVector<double> r2(dimTop_);
+  TVector<double> d1(ndyad);
+  TVector<double> d2(ndyad);
+
+  // initialisations 
+  x =0.;
+  r1 = b;
+  r2 = r1;
+  d1 =0.;
+  d2 =0.;
+  for (k=0; k<dimTop_; k++)
+    {
+      d1(k) = r1(k);
+      d2(k) = r2(k);
+    }
+  int niter =0;
+  double r1r2k = prodScalaire(dimTop_,r1,r2);
+  double r1r2ini = r1r2k;
+  do 
+    {
+      int k;
+      TVector<double> Ad1;
+      produitParVecFourier(d1, Ad1);
+      TVector<double> tAd2;
+      produitTransposeeParVecFourier(d2, tAd2);
+
+      //
+      double  d2Ad1 = prodScalaire(dimTop_,d2,Ad1);
+      double alpha = r1r2k/d2Ad1;
+
+      for (k=0; k<dimTop_; k++)
+      	{
+	  x(k) += alpha*d1(k);
+	  r1(k) -= alpha*Ad1(k);
+	  r2(k) -= alpha*tAd2(k);
+	}
+      prodScalaire(dimTop_,r1,r2); 
+      double beta = prodScalaire(dimTop_,r1,r2)/r1r2k;
+      for (k=0; k<dimTop_; k++)
+	{
+	  d1(k)  = r1(k) + beta*d1(k);
+	  d2(k)  = r2(k) + beta*d2(k);
+	}
+      r1r2k = prodScalaire(dimTop_,r1,r2); 
+      //      cout << " iteration " << niter+1 << " r1r2= " << r1r2k << " critere arret " << r1r2k/r1r2ini << endl;
+      niter++;
+        }
+
+     while ( fabs(r1r2k/r1r2ini) > 1.e-12 && niter < 2*dimTop_);
+
+    // verification a supprimer 
+  //TMatrix<double> ttest(dimTop_, dimTop_);
+  //expliciteToeplitz(ttest);
+  //TVector<double> btest;
+  // ttest.Show();
+    //cout << " long vec circ " << dimTop_ << " long a " << a.Size() << endl;
+  //btest = ttest*x;
+  //for (int k=0; k< b.Size(); k++)
+  // {
+  //	cout << " verif gradient donnee " << b(k) << " retrouve " << btest(k) << endl;
+  //   }
+    //
+    b = x;
+    
+    if (niter == 2*dimTop_) niter = -1;
+    return niter;
+}
+
+
+void  Toeplitz::expliciteCirculante(TMatrix<complex<double> >& m) const
+{
+  int k;
+  int n= vecteurCirculant_.Size();
+  m.ReSize(n,n);
+  int decal=0;
+  for (k=0; k<n; k++)
+    {
+      int j;
+      int courant = 0;
+      for (j=decal; j< n; j++)
+	{
+	  m(j, k) = vecteurCirculant_(courant++);
+	}
+      for (j=0; j<decal; j++)
+	{
+	  m(j,k)= vecteurCirculant_(courant++);
+	}
+      decal++;
+    }
+}
+void  Toeplitz::expliciteToeplitz(TMatrix<complex<double> >& m) const
+{
+  int k;
+  int ndyad = vecteurCirculant_.Size();
+  m.ReSize(dimTop_, dimTop_);
+  for (k=0; k<dimTop_; k++)
+    {
+      int j;
+      for (j=k; j< dimTop_; j++)
+	{
+	  m(j, k) = vecteurCirculant_(j-k);
+	}
+      for (j=0; j<k; j++)
+	{
+	  m(k-j-1,k)= vecteurCirculant_(ndyad-j-1);
+	}
+    }
+}
+void  Toeplitz::expliciteToeplitz(TMatrix<double>& m) const
+{
+  int k;  
+  int ndyad = vecteurCirculantD_.Size();
+  m.ReSize(dimTop_, dimTop_);
+  for (k=0; k<dimTop_; k++)
+    {
+      int j;
+      for (j=k; j< dimTop_; j++)
+	{
+	  m(j, k) = vecteurCirculantD_(j-k);
+	}
+      for (j=0; j < k; j++)
+	{
+	  m(k-j-1,k)= vecteurCirculantD_(ndyad-j-1);
+	}
+    }
+}
+
+
+// resolution par gradient conjugue preconditionne d'un systeme 
+// dont la matrice est  la matrice de Toeplitz
+// (le vecteur b est le second membre)
+// renvoie le nombre d'iterations (-1 si non converge
+int Toeplitz::gradientToeplitzPreconTChang(TVector<complex<double> >& b) const
+{
+  int k;
+  if (dimTop_ != b.Size())
+    {
+      throw SzMismatchError("TOEPLITZMATRIX : gradientToeplitz : RHS dimensions mismatch \n");
+    }
+  if (!hermitian_) 
+    {
+      throw PException(" TOEPLITZMATRIX : conjugate gradient for hermitian matrix only\n");
+    }
+  int ndyad = vecteurCirculant_.Size();
+  // preconditionneur (en Fourier)
+  TVector<complex<double> > TFourierC;
+  fabricationTChangPreconHerm(TFourierC);
+
+
+  TVector<complex<double> > a(dimTop_);
+  TVector<complex<double> > r(dimTop_);
+  TVector<complex<double> > z(dimTop_);
+  TVector<complex<double> > q(ndyad);
+
+  a =complex<double>(0.,0.);
+  r = b;
+  inverseSystemeCirculantFourier(TFourierC, r, z);
+  q =complex<double>(0.,0.);
+  for (k=0; k<dimTop_; k++) q(k) = z(k);
+
+  complex<double> norm2zRk = prodScalaire(dimTop_,z,r);  
+  complex<double> norm2zR0 = norm2zRk;  
+  int niter =0;
+  double critere = 1.e+8;
+    do 
+    {
+      int k;
+      TVector<complex<double> > Aq;
+      produitParVecFourier(q, Aq);
+
+      // matrice hermitienne
+      double  norme2Aq = prodScalaire(dimTop_,Aq,q).real();
+      complex<double> alpha = norm2zRk/norme2Aq;
+      for (k=0; k<dimTop_; k++) a(k) += alpha*q(k);
+      for (k=0; k<dimTop_; k++) r(k) -= alpha*Aq(k);
+
+      inverseSystemeCirculantFourier(TFourierC, r, z);
+
+      complex<double> norm2zRkp1 = prodScalaire(dimTop_,z,r); 
+      complex<double> beta = norm2zRkp1/norm2zRk;
+      for (k=0; k<dimTop_; k++) q(k) = z(k) + beta*q(k);
+
+      norm2zRk = norm2zRkp1;
+      complex<double> rapport = norm2zRk/norm2zR0;
+      critere = fabs(rapport.real())+fabs(rapport.imag());
+      //   cout << " norme residu= " << norm2zRk << " critere arret " << critere << endl;
+      niter++;
+        }
+
+    while ( critere > 1.e-12 && niter < 2*dimTop_);
+    b = a;
+    if (niter == 2*dimTop_-1) niter = -1;
+    return niter;
+}
+
+// extension de la matrice Toeplitz a une matrice circulante, avec zeros
+// additionnels : pour pouvoir utiliser les FFT
+void Toeplitz::extensionACirculanteDyadique(const TVector<complex<double> >& firstCol, const TVector<complex<double> >& firstRow)
+{
+  // la matrice de Toeplitz doit etre etendue a (2N-1)x(2N_1) pour 
+  // la rendre circulante
+
+  int k;
+  int N = dimTop_;
+  int nEtendu = 2*N-1;
+  // on va completer avec des zeros, pour avoir une puissance de 2 (pour fft)
+  int ndyad=1;
+  while ( nEtendu >  ndyad)  
+    {
+      ndyad *=2;
+    }
+  //  cout << " extensionToeplitz: taille etendue de la matrice " << nEtendu << endl;
+  //  cout << " puissance de 2 trouvee " << ndyad << endl;
+
+
+  // extension de la matrice
+  vecteurCirculant_.ReSize(ndyad);
+  vecteurCirculant_ = complex<double>(0.,0.);
+  vecteurCirculant_(0) = firstCol(0);
+  for (k=1; k< N; k++)
+    {
+      vecteurCirculant_(k) = firstCol(k);
+      vecteurCirculant_(ndyad-k) = firstRow(k);
+    }
+  transformeeFourier(vecteurCirculant_, CirculanteFourier_);
+}
+
+
+// extension de la matrice Toeplitz a une matrice circulante, avec zeros
+// additionnels : pour pouvoir utiliser les FFT
+void Toeplitz::extensionACirculanteDyadique(const TVector<complex<double> >& firstCol)
+{
+  // la matrice de Toeplitz doit etre etendue a (2N-1)x(2N_1) pour 
+  // la rendre circulante
+
+  int k;
+  int N = dimTop_;
+  int nEtendu = 2*N-1;
+  // on va completer avec des zeros, pour avoir une puissance de 2 (pour fft)
+  int ndyad=1;
+  while ( nEtendu >  ndyad)  
+    {
+      ndyad *=2;
+    }
+  //  cout << " extensionToeplitz: taille etendue de la matrice " << nEtendu << endl;
+  //  cout << " puissance de 2 trouvee " << ndyad << endl;
+
+
+  // extension de la matrice
+  vecteurCirculant_.ReSize(ndyad);
+  vecteurCirculant_ = complex<double>(0.,0.);
+  vecteurCirculant_(0) = firstCol(0);
+  for (k=1; k< N; k++)
+    {
+      complex<double> aux = firstCol(k);
+      vecteurCirculant_(k) = aux;
+      vecteurCirculant_(ndyad-k) = conj(aux);
+    }
+  transformeeFourier(vecteurCirculant_, CirculanteFourier_);
+}
+
+
+// extension de la matrice Toeplitz a une matrice circulante, avec zeros
+// additionnels : pour pouvoir utiliser les FFT
+void Toeplitz::extensionACirculanteDyadique(const TVector<double>& firstCol, const TVector<double>& firstRow)
+{
+  // la matrice de Toeplitz doit etre etendue a (2N-1)x(2N_1) pour 
+  // la rendre circulante
+
+  int k;
+  int N = dimTop_;
+  int nEtendu = 2*N-1;
+  // on va completer avec des zeros, pour avoir une puissance de 2 (pour fft)
+  int ndyad=1;
+  while ( nEtendu >  ndyad)  
+    {
+      ndyad *=2;
+    }
+  //  cout << " extensionToeplitz: taille etendue de la matrice " << nEtendu << endl;
+  //  cout << " puissance de 2 trouvee " << ndyad << endl;
+
+
+  // extension de la matrice
+  vecteurCirculantD_.ReSize(ndyad);
+  vecteurCirculantD_ = 0.;
+
+  vecteurCirculantD_(0) = firstCol(0);
+  for (k=1; k< N; k++)
+    {
+      vecteurCirculantD_(k) = firstCol(k);
+      vecteurCirculantD_(ndyad-k) = firstRow(k);
+    }
+  transformeeFourier(vecteurCirculantD_, CirculanteFourier_);
+}
+
+
+
+// extension de la matrice Toeplitz a une matrice circulante, avec zeros
+// additionnels : pour pouvoir utiliser les FFT
+void Toeplitz::extensionACirculanteDyadique(const TVector<double>& firstCol)
+{
+  // la matrice de Toeplitz doit etre etendue a (2N-1)x(2N_1) pour 
+  // la rendre circulante
+
+
+  int k;
+  int N = dimTop_;
+  int nEtendu = 2*N-1;
+  // on va completer avec des zeros, pour avoir une puissance de 2 (pour fft)
+  int ndyad=1;
+  while ( nEtendu >  ndyad)  
+    {
+      ndyad *=2;
+    }
+  //  cout << " extensionToeplitz: taille etendue de la matrice " << nEtendu << endl;
+  //  cout << " puissance de 2 trouvee " << ndyad << endl;
+
+
+  // extension de la matrice
+  vecteurCirculantD_.ReSize(ndyad);
+  vecteurCirculantD_ = 0.;
+  vecteurCirculantD_(0) = firstCol(0);
+  for (k=1; k< N; k++)
+    {
+      double aux = firstCol(k);
+      vecteurCirculantD_(k) = aux;
+      vecteurCirculantD_(ndyad-k) = aux;
+    }
+  transformeeFourier(vecteurCirculantD_, CirculanteFourier_);
+}
+
+
+// produit de la matrice de toeplitz par un vecteur (par transformee de 
+// fourier) resultat dans Tq
+void Toeplitz::produitParVecFourier(const TVector<complex<double> >& q, TVector<complex<double> >& Tq) const
+{
+  int k;
+  int n = q.Size();
+  if (n != vecteurCirculant_.Size() )
+    {
+      cout << " produitToepVecFourier: dimensions matrice vecteur incompatibles " << endl;
+      return;
+    }
+  TVector<complex<double> > qFourier;
+  transformeeFourier(q, qFourier);
+
+
+    TVector<complex<double> > produitFourier(n);
+    for (k=0; k<qFourier.Size(); k++)
+     {
+      produitFourier(k) = CirculanteFourier_(k)*qFourier(k);
+     }
+     transformeeInverseFourier(produitFourier,Tq); 
+}
+
+
+
+
+// produit de la matrice de toeplitz par un vecteur (par transformee de 
+// fourier) resultat dans Tq
+void Toeplitz::produitParVecFourier(const TVector<double>& q, TVector<double>& Tq) const
+{
+  int k;
+  int n = q.Size();
+  if (n != vecteurCirculantD_.Size() )
+    {
+      cout << " produitParVecFourier: dimensions matrice vecteur incompatibles " << "vecteur  " << n << " matrice "<< vecteurCirculantD_.Size()  << endl;
+      return;
+    }
+  // cout << " le vecteur " << endl;
+  TVector<complex<double> > qFourier;
+  transformeeFourier(q, qFourier);
+  int  M = qFourier.Size();  
+  TVector<complex<double> > produitFourier(M);
+  for (k=0; k< M; k++)
+    { 
+      produitFourier(k) = CirculanteFourier_(k)*qFourier(k);
+    }
+  transformeeInverseFourier(produitFourier,Tq); 
+}
+// produit de la transposee de matrice de toeplitz par un vecteur 
+// (par transformee de fourier) resultat dans Tq
+void Toeplitz::produitTransposeeParVecFourier(const TVector<double>& q, TVector<double>& Tq) const
+{
+  int k;
+  int n = q.Size();
+  if (n != vecteurCirculantD_.Size() )
+    {
+      cout << " produitTransposeeParVecFourier: dimensions matrice vecteur incompatibles " << "vecteur  " << n << " matrice "<< vecteurCirculantD_.Size()  << endl;
+      return;
+    }
+  // cout << " le vecteur " << endl;
+  TVector<complex<double> > qFourier;
+  transformeeFourier(q, qFourier);
+  int  M = qFourier.Size();  
+  TVector<complex<double> > produitFourier(M);
+  for (k=0; k< M; k++)
+    { 
+      produitFourier(k) = CirculanteTransposeeFourier_(k)*qFourier(k);
+    }
+  transformeeInverseFourier(produitFourier,Tq); 
+}
+
+
+void Toeplitz::fabricationTChangPreconHerm(TVector<complex<double> >& TFourierC) const
+{
+  int k;
+  TVector<complex<double> > C(dimTop_);
+  C(0) = vecteurCirculant_(0);
+  for (k=1; k<dimTop_; k++)
+    {
+      C(k) = (double(dimTop_-k)*vecteurCirculant_(k) + double(k)*conj(vecteurCirculant_(dimTop_-k)))/double(dimTop_);
+    }
+  transformeeFourier(C, TFourierC);
+  // verifier qu'il n'y a pas de terme nul (pour pouvoir inverser)
+  int index =0;
+  for (k=0; k<dimTop_; k++)
+    {
+      if ( fabs(TFourierC(k).real())== 0. &&  fabs(TFourierC(k).imag()) == 0.)
+	{
+	  index = 1;
+	  break;
+	}
+    }
+  if (index == 1) 
+    {
+      cout << " fabricationTChangPreconHerm  ; ATTENTION : un terme de la TF du preconditionneur est nul! " << endl;
+    }
+
+}
+void Toeplitz::inverseSystemeCirculantFourier(const TVector<complex<double> >& TFourierC, const TVector<complex<double> >& secondMembre, TVector<complex<double> >& resul) const
+{
+  int k;
+  int n = TFourierC.Size();
+  if (n != secondMembre.Size() )
+    {
+      cout << " inverseSystemeCirculantFourier: dimensions matrice vecteur incompatibles " << endl;
+      return;
+    }
+  TVector<complex<double> > SmFourier;
+  transformeeFourier(secondMembre, SmFourier);
+  TVector<complex<double> > quotientFourier(n);
+  for (k=0; k<n; k++)
+    {
+      quotientFourier(k) = SmFourier(k)/TFourierC(k);
+    }
+  transformeeInverseFourier(quotientFourier,resul); 
+}
Index: /tags/V_Dec2002/SophyaLib/TArray/toeplitzMatrix.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/TArray/toeplitzMatrix.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/TArray/toeplitzMatrix.h	(revision 2309)
@@ -0,0 +1,175 @@
+#ifndef TOEPLITZMATRIX_SEEN
+#define TOEPLITZMATRIX_SEEN
+
+
+
+// matrice de Toeplitz reelle ou complexe
+//------------------------------------------------------------------
+//   *****   Guy Le Meur -- LAL-Orsay mars 2002 ****************
+//-------------------------------------------------------------------
+
+
+#include "machdefs.h"    // Definitions specifiques SOPHYA
+
+#include <math.h>
+#include <iostream.h>
+
+#include "nbmath.h"
+#include "timing.h"
+
+#include "array.h"
+
+#include "fftservintf.h"
+#include "fftpserver.h"
+
+// classe pour decrire une matrice de Toeplitz reelle ou complexe, 
+// symetrique (hermitienne) ou non. 
+// Methodes de gradient conjugues pour resolution de systemes (uniquement
+// pour symetriques ou hermitiennes, pour le moment)
+
+class Toeplitz
+{
+
+ private: 
+  // verouiller le clonage
+Toeplitz(const Toeplitz&)  {}
+Toeplitz &operator = (const Toeplitz&) {return *this;}
+
+public:
+
+Toeplitz();
+Toeplitz(const TVector<complex<double> >& firstCol);
+
+~Toeplitz();
+
+  // toeplitz complexe generale
+  void  setMatrix(const TVector<complex<double> >& firstCol, const TVector<complex<double> >& firstRow); 
+  // toeplitz hermitienne
+  void  setMatrix(const TVector<complex<double> >& firstCol); 
+  // toeplitz reelle generale
+  void  setMatrix(const TVector<double>& firstCol, const TVector<double>& firstRow); 
+  // toeplitz reelle symetrique
+  void  setMatrix(const TVector<double>& firstCol); 
+
+
+  int gradientToeplitz(TVector<complex<double> >& b) const;
+  int gradientToeplitz(TVector<double>& b) const;
+
+  int gradientToeplitzPreconTChang(TVector<complex<double> >& b) const;
+
+  int CGSToeplitz(TVector<double>& b) const;
+  int DCGToeplitz(TVector<double>& b) ;
+
+private:
+
+inline complex<double> prodScalaire(int n,  TVector<complex<double> >& v1, TVector<complex<double> >& v2) const
+{
+  complex<double> produit = complex<double>(0.,0.);
+  for (int k =0; k<n; k++) produit += v1(k)*conj(v2(k));
+  return produit;
+}
+inline double prodScalaire(int n,  TVector<double>& v1, TVector<double>& v2) const
+{
+  double produit = 0.;
+  for (int k =0; k<n; k++) produit += v1(k)*v2(k);
+  return produit;
+}
+
+
+inline void transformeeFourier(const TVector<complex<double> >& v, TVector< complex<double> >& tv) const
+{
+  fftIntfPtr_-> FFTForward(v, tv);
+} 
+inline void transformeeFourier(const TVector<double>& v, TVector< complex<double> >& tv) const
+{
+  fftIntfPtr_-> FFTForward(v, tv);
+} 
+
+
+inline void transformeeInverseFourier(const TVector<complex<double> >& tv, TVector<complex<double> >& v) const
+{
+  int n= tv.Size();
+  fftIntfPtr_-> FFTBackward(tv, v);
+  v/=n;
+} 
+inline void transformeeInverseFourier(const TVector<complex<double> >& tv, TVector<double>& v) const
+{
+  int n= tv.Size();
+  fftIntfPtr_-> FFTBackward(tv, v);
+  double fac = 1./(2*(n-1));
+  v *= fac;
+} 
+
+inline void initTFTransposeeToeplitzComplexe() 
+{
+  int k;
+  int ndyad = vecteurCirculant_.Size();
+  TVector<complex<double> > vecteurCirculantTranspose(ndyad);
+  vecteurCirculantTranspose =  complex<double>(0.,0.);
+  vecteurCirculantTranspose(0) = vecteurCirculant_(0);
+  for (k=1; k< dimTop_; k++)
+    {
+      vecteurCirculantTranspose(k) = vecteurCirculant_(ndyad-k);
+      vecteurCirculantTranspose(ndyad-k) = vecteurCirculant_(k);
+    }
+
+  transformeeFourier(vecteurCirculantTranspose, CirculanteTransposeeFourier_);
+}
+inline void initTFTransposeeToeplitzReelle() 
+{
+  int k;
+  int ndyad = vecteurCirculantD_.Size();
+  TVector<double> vecteurCirculantTranspose(ndyad);
+  vecteurCirculantTranspose =  0.;
+  vecteurCirculantTranspose(0) = vecteurCirculantD_(0);
+  for (k=1; k< dimTop_; k++)
+    {
+      vecteurCirculantTranspose(k) = vecteurCirculantD_(ndyad-k);
+      vecteurCirculantTranspose(ndyad-k) = vecteurCirculantD_(k);
+    }
+
+  transformeeFourier(vecteurCirculantTranspose, CirculanteTransposeeFourier_);
+}
+
+void extensionACirculanteDyadique(const TVector<complex<double> >& firstCol, const TVector<complex<double> >& firstRow);
+
+void extensionACirculanteDyadique(const TVector<double>& firstCol, const TVector<double>& firstRow);
+void extensionACirculanteDyadique(const TVector<complex<double> >& firstCol);
+
+void extensionACirculanteDyadique(const TVector<double>& firstCol);
+
+
+// matrice circulante entree par sa T. de Fourier
+void produitParVecFourier(const TVector<complex<double> >& q, TVector<complex<double> >& Tq) const;
+void produitParVecFourier(const TVector<double>& q, TVector<double>& Tq) const;
+
+void produitTransposeeParVecFourier(const TVector<double>& q, TVector<double>& Tq) const;
+
+
+// preconditionneur pour une Toeplitz HERMITIENNE
+// LE RESUTAT EST UNE TRANSFORMEE DE FOURIER
+void fabricationTChangPreconHerm(TVector<complex<double> >& TFourierC) const;
+
+// matrice circulante entree par sa T. de Fourier
+void inverseSystemeCirculantFourier(const TVector<complex<double> >& TFourierC, const TVector<complex<double> >& secondMembre, TVector<complex<double> >& resul) const;
+
+
+void expliciteCirculante(TMatrix<complex<double> >& m) const;
+void expliciteToeplitz(TMatrix<complex<double> >& m) const;
+void expliciteToeplitz(TMatrix<double>& m) const;
+
+
+  bool hermitian_;
+  int dimTop_;
+  TVector<complex<double> > vecteurCirculant_;
+  TVector<double> vecteurCirculantD_;
+  TVector<complex<double> > CirculanteFourier_;
+  TVector<complex<double> > CirculanteTransposeeFourier_;
+  FFTServerInterface* fftIntfPtr_;
+};
+
+
+// fin classe Toeplitz
+
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/TArray/triangmtx.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/TArray/triangmtx.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/TArray/triangmtx.h	(revision 2309)
@@ -0,0 +1,169 @@
+// This may look like C code, but it is really -*- C++ -*-
+
+#ifndef TRIANGMTX_H_SEEN
+#define TRIANGMTX_H_SEEN
+
+#include "ndatablock.h"
+#include "pexceptions.h"
+
+// doit etre mis en dehors du namespace
+/*!
+  \class SOPHYA::TriangularMatrix
+  \ingroup TArray
+  Class for inferior triangular matrix (base class for the class Alm)
+*/
+
+namespace SOPHYA {
+  
+//! Class for inferior triangular matrix (base class for the class Alm)
+template <class T>
+class TriangularMatrix {
+public :
+
+//! Default constructor
+TriangularMatrix()   {;};
+//! instanciate a triangular matrix from the number of rows
+TriangularMatrix(int rowSize)  : long_diag_((uint_4)rowSize) 
+  {
+    elem_.ReSize((uint_4) (rowSize*(rowSize+1)/2) ); 
+  }
+//! Copy constructor (possibility of sharing datas)
+  TriangularMatrix(const TriangularMatrix<T>& a,  bool share=false)  : elem_(a.elem_, share),  long_diag_(a.long_diag_) {;}
+
+//! resize the matrix with a new number of rows
+inline void ReSizeRow(int rowSize) 
+  {
+    long_diag_=(uint_4)rowSize;
+    elem_.ReSize(long_diag_*(long_diag_+1)/2);
+  }
+
+TriangularMatrix<T>& SetT(T a)
+  {
+    if (long_diag_ < 1)
+    throw RangeCheckError("TriangularMatrix<T>::SetT(T )  - TriangularMatrix not dimensionned ! ");
+    elem_ = a;
+    return (*this);
+  }
+
+//! () operator : access to elements row \b l and column \b m
+inline T& operator()(int l, int m) 
+  {
+      return  elem_(indexOfElement(l,m));
+  }
+
+inline T& operator()(int index) 
+  {
+      return  elem_(index);
+  }
+
+
+//! () operator : access to elements row \b l and column \b m
+inline T const& operator()(int l, int m) const 
+  {
+      return *(elem_.Begin()+ indexOfElement(l,m));
+  }
+
+inline T const& operator()(int index) const 
+  {
+      return *(elem_.Begin()+ index);
+  }
+
+TriangularMatrix<T>& Set(const TriangularMatrix<T>& a)
+  {
+    if (this != &a) 
+      {
+	if (a.Size() < 1) 
+	  throw RangeCheckError(" TriangularMatrix<T>::Set()- Array a not allocated ! ");
+      }
+    if (Size() < 1)  CloneOrShare(a);
+    else CopyElt(a);
+    return(*this);
+  }
+
+inline TriangularMatrix<T>& operator = (const TriangularMatrix<T>& a)
+                                                           {return Set(a);}
+
+TriangularMatrix<T>& CopyElt(const  TriangularMatrix<T>& a)
+  {
+    if (Size() < 1) 
+      throw RangeCheckError("TriangularMatrix<T>::CopyElt(const TriangularMatrix<T>& )  - Not Allocated Array ! ");
+    if (Size() != a.Size() )
+      throw(SzMismatchError("TriangularMatrix<T>::CopyElt(const TriangularMatrix<T>&) SizeMismatch")) ;
+    long_diag_ = a.long_diag_;
+    int k;
+    for (k=0; k< Size(); k++) elem_(k) = a.elem_(k);
+    return(*this);
+  }
+
+void CloneOrShare(const  TriangularMatrix<T>& a)
+  {
+    long_diag_ = a.long_diag_;
+    elem_.CloneOrShare(a.elem_);
+  }
+
+
+//! Return number of rows
+inline  int_4  rowNumber() const {return (int_4)long_diag_;}
+
+//! Return size of the total array
+  inline int_4 Size() const {return elem_.Size();}
+
+  inline bool CheckRelativeIndices(int_4 l, int_4 m) const 
+   {
+     if ( l < m ) 
+       {
+	 throw RangeCheckError("TriangularMatrix<T>::CheckRelativeIndices: indices out of range " );
+       }
+     return true;
+   }
+  inline bool CheckAbsoluteIndice(int_4 l, int_4 m) const 
+   {
+     if ( indexOfElement(l,m) >= elem_.Size() )
+       {
+	 throw RangeCheckError("TriangularMatrix<T>::CheckAbsoluteIndice: indices out of range " );
+       }
+   }
+  inline bool CheckAbsoluteIndice(int_4 ind) const 
+   {
+     if ( ind >= elem_.Size() )
+       {
+	 throw RangeCheckError("TriangularMatrix<T>::CheckAbsoluteIndice: indices out of range " );
+       }
+   }
+
+void Print(int nbLignes=0)
+  {
+    if (nbLignes == 0 ) nbLignes = long_diag_;
+    cout << " ***** matrice triangulaire : ********* " << endl;
+    for (int k=0; k < nbLignes; k++)
+      {
+	for (int kc = 0; kc <= k ; kc++)
+	  {
+	    cout << " " << elem_(indexOfElement(k,kc));
+	  }
+	cout << endl;
+      }
+    cout << "---------------- fin matrice ------------" << endl;
+  }
+
+  //Return pointer to first element address
+  //inline T* Data()  {return elem_.Begin();}
+
+//! compute the address of an element in the single array representing the matrix
+inline uint_4 indexOfElement(int i,int j) const 
+{
+  //  return(i*(i+1)/2+j);
+  // the (inferior triangular )matrix is stored column by column
+  return(i+ long_diag_*j-j*(j+1)/2);
+}
+
+private: 
+
+uint_4 long_diag_;    //!< size of the square matrix
+NDataBlock<T> elem_;  //!< Data block
+
+  };
+  
+}   // namespace SOPHYA
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/TArray/tvector.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/TArray/tvector.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/TArray/tvector.cc	(revision 2309)
@@ -0,0 +1,239 @@
+// $Id: tvector.cc,v 1.15 2002-11-15 09:35:44 ansari Exp $
+//                         C.Magneville          04/99
+#include "machdefs.h"
+#include <stdlib.h>
+#include "pexceptions.h"
+#include "tvector.h"
+
+/*!
+  \class SOPHYA::TVector
+  \ingroup TArray
+
+  The TVector class specializes the TMatrix class for representing 
+  row or column vectors.
+
+  \b Vector is a typedef for double precision floating point vectors ( TVector<r_8> ).
+
+  \sa SOPHYA::TArray SOPHYA::TMatrix
+  \sa SOPHYA::Range SOPHYA::Sequence
+  \sa SOPHYA::MathArray
+
+  The following sample code illustrates sub-vector manipulation:
+  \code
+  #include "array.h"
+  // ...
+  // Input Vector containing a noisy periodic signal
+  Vector in(1024), out(1024);
+  in = RandomSequence(RandomSequence::Gaussian, 0., 1.);
+  for(int kk=0; kk<in.Size(); kk++)
+    in(kk) += 2*sin(kk*0.05);
+  // Compute the output vector by a simple low pass filter
+  Vector out(1024);
+  int w = 2;
+  for(int k=w; k<in.Size()-w; k++)
+    out(k) = in(Range(k-w, k+w).Sum()/(2.*w+1.);
+  \endcode
+*/
+
+////////////////////////////////////////////////////////////////
+//**** Createur, Destructeur
+
+//! Default constructor
+template <class T>
+TVector<T>::TVector()
+  : TMatrix<T>()
+{
+  arrtype_ = 2;   // Type = Vector
+}
+
+//! construct a vector
+/*!
+  \param n : number of elements
+  \param lcv : line or column vector ?
+  \param mm : memory mapping type
+  \sa SelectVectorType
+ */
+template <class T>
+TVector<T>::TVector(sa_size_t n, short lcv, short mm)
+// Constructeur 
+  : TMatrix<T>(1,1,mm)
+{
+  arrtype_ = 2;   // Type = Vector
+  lcv = SelectVectorType(lcv);
+  ReSize(n,lcv);
+}
+
+//! Constructor by copy
+/*!
+  \warning datas are \b SHARED with \b a.
+  \sa NDataBlock::NDataBlock(const NDataBlock<T>&)
+*/
+template <class T>
+TVector<T>::TVector(const TVector<T>& a)
+// Constructeur par copie
+  : TMatrix<T>(a)
+{
+  arrtype_ = 2;   // Type = Vector
+}
+
+//! Constructor by copy
+/*!
+  \param share : if true, share data. If false copy data
+ */
+template <class T>
+TVector<T>::TVector(const TVector<T>& a, bool share)
+// Constructeur par copie avec possibilite de forcer le partage ou non.
+: TMatrix<T>(a, share)
+{
+  arrtype_ = 2;   // Type = Vector
+}
+
+//! Constructor from a TArray
+template <class T>
+TVector<T>::TVector(const TArray<T>& a)
+: TMatrix<T>(a)
+{
+  if ( (size_[0] != 1) && (size_[1] != 1) )
+    throw SzMismatchError("TVector<T>::TVector(const TArray<T>& a) NRows()!=1 && NCols()!=1 ");
+  arrtype_ = 2;   // Type = Vector
+}
+
+
+//! Constructor of a vector from a TArray \b a
+/*!
+  \param a : TArray to be copied or shared
+  \param share : if true, share data. If false copy data
+  \param mm : define the memory mapping type
+  \param lcv : line or column vector ?
+  \sa SelectVectorType
+ */
+template <class T>
+TVector<T>::TVector(const TArray<T>& a, bool share, short lcv, short mm)
+: TMatrix<T>(a, share, mm)
+{
+  if ( (size_[0] != 1) && (size_[1] != 1) )
+    throw SzMismatchError("TVector<T>::TVector(const TArray<T>& a) NRows()!=1 && NCols()!=1 ");
+  arrtype_ = 2;   // Type = Vector
+  if ( (size_[0] == 1) && (size_[1] == 1) ) {
+    if (lcv == SameVectorType) lcv = a.GetVectorType();
+    if ( (lcv != ColumnVector) && (lcv != RowVector) ) lcv = GetDefaultVectorType();
+    veceli_ = (lcv ==  ColumnVector ) ?  marowi_ : macoli_;
+  }
+}
+
+//! Constructor of a vector from a TArray \b a , with a different data type
+template <class T>
+TVector<T>::TVector(const BaseArray& a)
+: TMatrix<T>(a)
+{
+  if ( (size_[0] != 1) && (size_[1] != 1) )
+    throw SzMismatchError("TVector<T>::TVector(const BaseArray& a) NRows()!=1 && NCols()!=1 ");
+  arrtype_ = 2;   // Type = Vector
+}
+
+//! Destructor
+template <class T>
+TVector<T>::~TVector()
+{
+}
+
+//! Resize the vector
+/*!
+  \param n : number of elements
+  \param lcv : line or column vector ?
+  \sa SelectVectorType
+ */
+template <class T>
+void TVector<T>::ReSize(sa_size_t n, short lcv)
+{
+  if( n == 0 ) 
+    throw(SzMismatchError("TVector::ReSize() n = 0 "));
+  sa_size_t r,c;
+  if (lcv == SameVectorType)  lcv = GetVectorType();
+  else if ( (lcv != ColumnVector) && (lcv != RowVector) ) lcv = GetDefaultVectorType();
+  if (lcv == ColumnVector) { r = n;  c = 1; }
+  else { c = n; r = 1; }
+  TMatrix<T>::ReSize(r,c);
+  veceli_ = (lcv ==  ColumnVector ) ?  marowi_ : macoli_;
+}
+
+//! Re-allocate space for the vector
+/*!
+  \param n : number of elements
+  \param lcv : line or column vector ?
+  \param force : if true re-allocation is forced, if not it occurs
+          only if the required space is greater than the old one.
+  \sa ReSize SelectVectorType
+ */
+template <class T>
+void TVector<T>::Realloc(sa_size_t n, short lcv, bool force)
+{
+  if( n == 0 ) 
+    throw(SzMismatchError("TVector::Realloc() n = 0 "));
+  sa_size_t r,c;
+  if (lcv == SameVectorType)  lcv = GetVectorType();
+  else if ( (lcv != ColumnVector) && (lcv != RowVector) ) lcv = GetDefaultVectorType();
+  if (lcv == ColumnVector) { r = n;  c = 1; }
+  else { c = n; r = 1; }
+  TMatrix<T>::Realloc(r,c,SameMemoryMapping,force);
+  veceli_ = (lcv ==  ColumnVector ) ?  marowi_ : macoli_;
+}
+
+// $CHECK$ Reza 03/2000  Doit-on declarer cette methode const ?
+//! Return a subvector define by \b Range \b relt
+template <class T>
+TVector<T> TVector<T>::SubVector(Range relt) const
+{
+  Range rr, cr;
+  if (GetVectorType() == ColumnVector )  rr = relt; 
+  else cr = relt;
+  TMatrix<T> const & mtx = (*this);
+  TVector sv( mtx(rr, cr) , true, GetVectorType(), GetMemoryMapping() );
+  return(sv);  
+}
+
+//! Return the norm \f$ \sum{V(i)^2} \f$
+template <class T>
+T TVector<T>::Norm2() const
+{
+  T ret = 0;
+  for(sa_size_t k=0; k<Size(); k++)   ret += (*this)(k)*(*this)(k);
+  return ret;
+}
+
+//! Return info on number of rows, column and type \b T
+template <class T>
+string TVector<T>::InfoString() const
+{
+  string rs = "TVector<";
+  rs += typeid(T).name();
+  char buff[64];
+  sprintf(buff, ">(%ld) (nr=%ld, nc=%ld)", (long)NElts(), (long)NRows(), (long)NCols());
+  rs += buff;
+  return(rs);  
+
+}
+
+///////////////////////////////////////////////////////////////
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template TVector<uint_2>
+#pragma define_template TVector<uint_8>
+#pragma define_template TVector<int_4>
+#pragma define_template TVector<int_8>
+#pragma define_template TVector<r_4>
+#pragma define_template TVector<r_8>
+#pragma define_template TVector< complex<r_4> > 
+#pragma define_template TVector< complex<r_8> > 
+#endif
+
+#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
+template class TVector<uint_2>;
+template class TVector<uint_8>;
+template class TVector<int_4>;
+template class TVector<int_8>;
+template class TVector<r_4>;
+template class TVector<r_8>;
+template class TVector< complex<r_4> >;
+template class TVector< complex<r_8> >;
+#endif
+
Index: /tags/V_Dec2002/SophyaLib/TArray/tvector.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/TArray/tvector.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/TArray/tvector.h	(revision 2309)
@@ -0,0 +1,123 @@
+// This may look like C code, but it is really -*- C++ -*-
+//                         C.Magneville          05/99
+#ifndef TVector_SEEN
+#define TVector_SEEN
+
+#include "tmatrix.h"
+
+namespace SOPHYA {
+
+//! Class of vector (line or column)
+template <class T>
+class TVector : public TMatrix<T> {
+public:
+  // Creation / destruction 
+  TVector();
+  TVector(sa_size_t n, short lcv=AutoVectorType, short mm=AutoMemoryMapping);
+  TVector(const TVector<T>& v);
+  TVector(const TVector<T>& v, bool share);
+  TVector(const TArray<T>& a);
+  TVector(const TArray<T>& a,  bool share, short lcv=AutoVectorType, short mm=AutoMemoryMapping);
+  TVector(const BaseArray& a);
+
+  virtual ~TVector();
+
+  //! Operator = 
+  /*! \warning Datas are copied (cloned) from \b a.
+      \sa NDataBlock::operator=(const NDataBlock<T>&) */
+  inline  TVector<T>& operator = (const TVector<T>& a)
+                       { Set(a);  return(*this); }
+  //! Operator = between a vector and a matrix 
+  inline  TVector<T>& operator = (const TMatrix<T>& a)
+                       { Set(a);  return(*this); }
+  //! Operator = between a vector and an array 
+  inline  TVector<T>& operator = (const TArray<T>& a)
+                       { Set(a);  return(*this); }
+  //! Operator = between Vectors with different types
+  inline  TVector<T>& operator = (const BaseArray& a)
+                       { SetBA(a);  return(*this); }
+    
+  // Gestion taille/Remplissage
+  void ReSize(sa_size_t n, short lcv=SameVectorType ); 
+  //! a synonym (alias) for method ReSize(sa_size_t, short)
+  inline void SetSize(sa_size_t n, short lcv=SameVectorType )
+              { ReSize(n, lcv); }
+  void Realloc(sa_size_t n, short lcv=SameVectorType, bool force=false);
+
+  // Sub-Vector extraction $CHECK$ Reza 03/2000  Doit-on declarer cette methode const ?
+  TVector<T> SubVector(Range relt) const ;
+  //! Extract a vector define by Range \b relt
+  inline TVector<T> operator () (Range relt) const 
+                    { return SubVector(relt); }
+
+  // Informations pointeur/data
+  //! return the number of elements
+  inline sa_size_t NElts() const {return Size(); }
+  
+  // Inline element acces methods 
+  inline T const& operator()(sa_size_t n) const;
+  inline T&       operator()(sa_size_t n);
+
+  // Operateur d'affectation
+  //! Fill the vector with Sequence \b seq
+  inline  TVector<T>&  operator = (Sequence const & seq) { SetSeq(seq); return(*this); }
+
+  // Operations diverses  avec une constante
+  //! Set vector elements to constant value \b x
+  inline  TVector<T>&  operator = (T x)             { SetT(x); return(*this); }
+  //! Add constant value \b x to vector elements
+  inline  TVector<T>&  operator += (T x)            { Add(x); return(*this); }
+  //! Substract constant value \b x to vector elements
+  inline  TVector<T>&  operator -= (T x)            { Sub(x); return(*this); }
+  //! Multiply vector elements by constant value \b x
+  inline  TVector<T>&  operator *= (T x)            { Mul(x); return(*this); }
+  //! Divide vector elements by constant value \b x
+  inline  TVector<T>&  operator /= (T x)            { Div(x); return(*this); }
+
+  //  operations avec matrices 
+  //! += : add a vector in place
+  inline  TVector<T>&  operator += (const TVector<T>& a)  { AddElt(a); return(*this); }
+  //! += : substract a vector in place
+  inline  TVector<T>&  operator -= (const TVector<T>& a)  { SubElt(a); return(*this); }
+
+  // Norme(^2) 
+  T Norm2() const ;
+
+  virtual string InfoString() const;
+
+};
+
+//  ---- inline acces methods ------
+
+//! Return the value of element \b n
+template <class T>
+inline T const& TVector<T>::operator()(sa_size_t n) const
+{
+#ifdef SO_BOUNDCHECKING
+  if (veceli_ == 0)   CheckBound(n, 0, 0, 0, 0, 4);
+  else   CheckBound(0, n, 0, 0, 0, 4);
+#endif
+  return ( *( mNDBlock.Begin()+ offset_ + n*step_[veceli_] ) );
+}
+
+//! Return the value of element \b n
+template <class T>
+inline T & TVector<T>::operator()(sa_size_t n) 
+{
+#ifdef SO_BOUNDCHECKING
+  if (veceli_ == 0)   CheckBound(n, 0, 0, 0, 0, 4);
+  else   CheckBound(0, n, 0, 0, 0, 4);
+#endif
+  return ( *( mNDBlock.Begin()+ offset_ + n*step_[veceli_] ) );
+}
+
+// Typedef pour simplifier et compatibilite Peida
+/*! \ingroup TArray
+  \typedef Vector
+  \brief To simplified TVector<r_8> writing
+*/
+typedef TVector<r_8> Vector;
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaLib/TArray/utilarr.cc
===================================================================
--- /tags/V_Dec2002/SophyaLib/TArray/utilarr.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/TArray/utilarr.cc	(revision 2309)
@@ -0,0 +1,370 @@
+//     Utility classes for template numerical arrays
+//                     R. Ansari, C.Magneville   03/2000
+
+#include "machdefs.h"
+#include "utilarr.h"
+#include "srandgen.h"
+
+// Classe utilitaires
+
+Sequence::~Sequence()
+{
+}
+
+//////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::RandomSequence
+  \ingroup TArray
+  Base class to generate a sequence of random values
+*/
+
+//! Constructor
+/*!
+  \param typ : generator type
+  \param m : mean parameter of the generator (if needed)
+  \param s : sigma parameter of the generator (if needed)
+ */
+RandomSequence::RandomSequence(int typ, double m, double s)
+{
+  typ_ = (typ == Flat) ? Flat : Gaussian;
+  mean_ = m;
+  sig_ = s;
+}
+RandomSequence::~RandomSequence()
+{
+}
+
+//! Return random sequence values.
+/*!
+  \return If typ = Flat : return [-1,+1]*sig + mean
+  \return If typ = Gaussian : return gaussian distributed
+                          with \b mean mean and sigma \b sig
+ */
+double RandomSequence::Rand()
+{
+  if (typ_ == Flat) 
+    return(drandpm1()*sig_ + mean_);
+  else return(GauRnd(mean_, sig_));
+}
+
+MuTyV & RandomSequence::Value(sa_size_t k) const 
+{
+  if (typ_ == Flat) retv_ = drandpm1()*sig_ + mean_;
+  else retv_ = GauRnd(mean_, sig_);
+  return retv_;
+}
+
+
+//////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::RegularSequence
+  \ingroup TArray
+  Class to generate a sequence of values
+*/
+
+//! Constructor
+/*!
+  \param start : start value
+  \param step : step value
+  \param f : pointer to the sequence function (default = NULL, f(x)=x )
+
+  See \ref RegularSequenceOperat "operator()"
+ */
+RegularSequence::RegularSequence(double start, double step, Arr_DoubleFunctionOfX f)
+{
+  start_ = start;
+  step_ = step;
+  myf_ = f;
+}
+
+RegularSequence::~RegularSequence()
+{
+}
+
+//! Get the \b k th value
+/*!
+  \param k : index of the value
+  \anchor RegularSequenceOperat
+  
+  \return f(start+k*step)
+
+ */
+
+MuTyV & RegularSequence::Value (sa_size_t k) const 
+{
+  double x = start_+(double)k*step_;
+  if (myf_)  x = myf_(x);
+  retv_ = x;
+  return(retv_);
+}
+
+/*!
+  \class SOPHYA::EnumeratedSequence
+  \ingroup TArray
+  Explicitly defined sequence of values. The comma operator has
+  been redefined to let an easy definition of sequences.
+  
+  \code
+  // Initializing a sequence 
+  EnumeratedSequence es;
+  es = 11, 22, 33, 44, 55, 66;
+  
+  for(int k=0; k<8; k++) 
+    cout << " k= " << k << " es(k)= " << es(k) << endl; 
+
+  // Decoding a sequence from a string
+  EnumeratedSequence ess;
+  int nbad;
+  ess.Append("56.5 (1.,-1.) 4 8 16", nbad);
+  cout << ess;
+  \endcode
+*/
+
+//! Default constructor
+EnumeratedSequence::EnumeratedSequence()
+{
+}
+
+//! Copy constructor
+EnumeratedSequence::EnumeratedSequence(EnumeratedSequence const & es)
+{
+  Append(es);
+}
+
+EnumeratedSequence::~EnumeratedSequence()
+{
+}
+
+//! Return the k th value in the sequence (default = 0)
+MuTyV & EnumeratedSequence::Value (sa_size_t k) const 
+{
+  if (k >= vecv_.size())  retv_ = 0;
+  else retv_ = vecv_[k];
+  return(retv_);
+}
+
+//! Appends a new value to the sequence
+EnumeratedSequence & EnumeratedSequence::operator , (MuTyV const & v)
+{
+  vecv_.push_back(v);
+  return(*this);
+}
+
+//! Initialize the sequence with a single value \b v
+EnumeratedSequence & EnumeratedSequence::operator = (MuTyV const & v)
+{
+  vecv_.clear();
+  vecv_.push_back(v);
+  return(*this);
+}
+
+//! Copy operator
+EnumeratedSequence & EnumeratedSequence::operator = (EnumeratedSequence const & seq)
+{
+  Clear();
+  Append(seq);
+  return(*this);  
+}
+
+
+//! Prints the list to the output stream \b os
+void EnumeratedSequence::Print(ostream& os) const 
+{
+  os << " EnumeratedSequence::Print() - Size()= " << Size() << endl;
+  for(int k=0; k<vecv_.size(); k++) {
+    os << vecv_[k];
+    if ((k > 0) && (k%10 == 0))  os << endl;
+    else os << " " ;
+  }
+  os << endl;
+  return;
+}
+
+//! Append the \b seq to the end of the sequence.
+/*!
+  \return the number of added elements.
+*/ 
+sa_size_t EnumeratedSequence::Append(EnumeratedSequence const & seq)
+{
+  for(int k=0; k<seq.vecv_.size(); k++) 
+    vecv_.push_back(seq.vecv_[k]);
+  return(seq.vecv_.size());
+}
+
+//! Decodes the string, appending values to the end of the sequence.
+/*!
+  \param str : string to be decoded
+  \param nbad : number of unmatched quotes or parenthesis (returned value)
+  \param sep : word separator in string. Each word is decoded as a MuTyV value.
+  \return the number of added elements.
+*/ 
+sa_size_t EnumeratedSequence::Append(string const & str, int& nbad, const char* sep)
+{
+  nbad = 0;
+  sa_size_t n = 0;
+  size_t l = str.length();
+  if (l < 1) return(0);
+  //  if ((str[0] == '#') || (str[0] == '*')) return(0);
+  size_t q = 0;
+  size_t p = 0;
+  /*
+  size_t p = str.find_first_not_of(sep);
+  if ((str[p] == '+') || (str[p] == '-')) {
+    if (p == l-1)  return(0);
+    if (!isdigit(str[p+1])) return(0);
+  }
+  else if (!isdigit(str[p]) && (str[p] != '\'') && (str[p] != '(') ) return(0);
+  */
+  while(q < l) {
+    p = str.find_first_not_of(sep,q);
+    if (p >= l)  break;
+    if (str[p] == '\'')    {  // Decodage d'un string
+      q = str.find('\'',p+1);
+      if (q < l) {
+	vecv_.push_back(MuTyV(str.substr(p+1,q-p-1)));
+	n++;	q++;
+      }
+      else nbad++;
+    }
+    else if (str[p] == '(')    {  // Decodage d'un complex
+      q = str.find(')',p);
+      if (q < l) {
+	q++;
+	MuTyV mtv(str.substr(p,q-p));
+	complex<r_8> z = mtv.operator complex<r_8>();
+	vecv_.push_back(MuTyV(z));
+	n++;
+      }
+      else nbad++;      
+    }
+    else { 
+      q = str.find_first_of(sep,p);
+      if ( !isdigit(str[p]) && !(str[p] == '+')
+        && !(str[p] == '-') && !(str[p] == '.') ) { // une chaine
+	vecv_.push_back(MuTyV(str.substr(p,q-p)));
+        n++;
+      }
+      else {  // C'est un nombre 
+	if (str.find_first_of(".eE",p) < q)   { // c'est un flottant
+	  r_8 x = atof(str.substr(p,q-p).c_str());
+	  vecv_.push_back(MuTyV(x));
+	}
+	else {   // un entier
+	  int_8 l = atol(str.substr(p,q-p).c_str());
+	  vecv_.push_back(MuTyV(l));
+	}
+	n++;
+      }
+    }
+  }
+  return (n);
+}
+
+//! Decodes the input ASCII stream, creating a sequence of values
+/*! \param is : Input ASCII stream
+    \param nr : Number of non empty (or comment) lines in stream (return value)
+    \param nc : Number of columns (= ntot/nlines) (return value)
+    \param clm : Lines starting with clm character are treated as comment lines
+    \param sep : word separator in lines
+    \return Number of decoded elements
+*/
+sa_size_t EnumeratedSequence::FillFromFile(istream& is, sa_size_t& nr, sa_size_t& nc,
+					   char clm, const char* sep)
+{
+  nr = 0;
+  nc = 0;
+  sa_size_t n = 0;
+  char buff[256];
+  string line;
+  int nbad, nbadtot, nel;
+  nbadtot = nbad = 0;
+  while (!is.eof()) {
+    is.clear(); 
+    is.getline(buff, 256);
+    //    cout << " DBG : buff=" << buff << " :state=" << is.rdstate() << endl;
+    line += buff;  nel = 0;
+    if (is.good()) {
+      if ((line.length() > 0) && (line[0]!=clm)) {
+	nel = Append(line, nbad);
+	if (nel > 0)  { 
+	  nr++;  n += nel;
+	}
+	nbadtot += nbad;
+      }
+      //	      cout << " Decoding line = " << line << " Nel= " << nel << endl;
+      line = "";
+    }
+  }
+  if ((line.length() > 0) && (line[0]!=clm)) {
+    nel = Append(line, nbad);
+    //        cout << " Decoding Eline = " << line << " Nel= " << nel << endl;
+    if (nel > 0)  { 
+      nr++;  n += nel;
+    }
+    nbadtot += nbad;
+    line = ""; 
+  }
+  if (nbadtot > 0) 
+    cout << "EnumeratedSequence::FillFromFile()/Warning " << nbadtot 
+	 << " bad match (quotes or parenthesis) in stream " << endl;
+  nc = n/nr;
+  return (n);
+}
+
+//////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::Range
+  \ingroup TArray
+  Class to define a range of indexes
+*/
+
+//! Constructor
+/*!
+  Define a range of indexes
+  \param start : start index (inclusive)
+  \param end : end index (inclusive)
+  \param size : size (number of elements, used if end \<= start)
+  \param step : step (or stride)
+
+  \warning If \b end \> \b start, \b size is computed automatically
+  \warning If not \b size is fixed and \b end recomputed
+ */
+Range::Range(sa_size_t start, sa_size_t end, sa_size_t size, sa_size_t step)
+{
+  start_ = start;
+  step_ = (step > 0) ? step : 1;
+  if (end > start) {  // Taille calcule automatiquement 
+    end_ = end;
+    if (step_ > ((end_-start_)+1))  size_ = 1;
+    else size_ = ((end-start)+1)/step_;
+  }
+  else {     // Taille fixee
+    size_ = size;
+    end_ = start_+size_*step_;
+  }
+}
+
+/*
+Range & Range::operator = (sa_size_t start)
+{
+  start_ = start;
+  size_ = 1;
+  step_ = 1;
+  return (*this);
+}
+*/
+
+
+//////////////////////////////////////////////////////////
+/*!
+  \class SOPHYA::IdentityMatrix
+  \ingroup TArray
+  Class to define an identity matrix
+*/
+
+//! Constructor of a (n,n) diagonal matrix with value diag on the diagonal
+IdentityMatrix::IdentityMatrix(double diag, sa_size_t n)
+{
+  size_ = n;
+  diag_ = diag;
+}
Index: /tags/V_Dec2002/SophyaLib/TArray/utilarr.h
===================================================================
--- /tags/V_Dec2002/SophyaLib/TArray/utilarr.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaLib/TArray/utilarr.h	(revision 2309)
@@ -0,0 +1,162 @@
+// This may look like C code, but it is really -*- C++ -*-
+//     Utility classes for template numerical arrays 
+//                     R. Ansari, C.Magneville   03/2000
+
+#ifndef UtilArray_SEEN
+#define UtilArray_SEEN
+
+#include "machdefs.h"
+#include "mutyv.h"
+
+#include <stdlib.h>
+#include <vector>
+
+namespace SOPHYA {   
+
+/* Quelques utilitaires pour les tableaux (Array) */             
+
+/*! \ingroup TArray
+  \typedef Arr_DoubleFunctionOfX
+  \brief define a function of double which returns a double
+*/
+typedef double (* Arr_DoubleFunctionOfX) (double x);
+/*! \ingroup TArray
+  \typedef Arr_FloatFunctionOfX
+  \brief define a function of float which returns a float
+*/
+typedef float  (* Arr_FloatFunctionOfX)  (float x);
+
+/*! \ingroup TArray
+  \typedef Arr_ComplexDoubleFunctionOfX
+  \brief define a function of a complex<double> which returns a complex<double>
+*/
+typedef complex<double> (* Arr_ComplexDoubleFunctionOfX) (complex<double> x);
+/*! \ingroup TArray
+  \typedef Arr_ComplexFloatFunctionOfX
+  \brief define a function of complex<float> which returns a complex<float>
+*/
+typedef float  (* Arr_ComplexFloatFunctionOfX)  (complex<float> x);
+
+//////////////////////////////////////////////////////////
+//! Class to generate a sequence of values
+class Sequence {
+public:
+  virtual ~Sequence();
+  virtual MuTyV & Value(sa_size_t k) const = 0;
+  inline MuTyV & operator () (sa_size_t k) const { return(Value(k)) ; }
+};
+
+class RandomSequence : public Sequence {
+public:
+  //! to define the generator type
+  enum {
+    Gaussian = 0, //!< gaussian generator
+    Flat = 1      //!< Flat generator
+    };
+
+  explicit RandomSequence(int typ = RandomSequence::Gaussian, double m=0., double s=1.);
+  virtual  ~RandomSequence();
+  virtual MuTyV & Value(sa_size_t k) const ;
+  double   Rand();
+
+protected:
+  int typ_;            //!< random generation type
+  double mean_, sig_;  //!< generation parameters mean and sigma (if needed)
+  mutable MuTyV retv_;
+};
+
+
+//////////////////////////////////////////////////////////
+//! Class to generate a sequence of values
+class RegularSequence : public Sequence {
+public:
+  explicit RegularSequence (double start=0., double step=1., Arr_DoubleFunctionOfX f=NULL);
+  virtual  ~RegularSequence();
+
+  //! return start value of the sequence
+  inline double & Start() { return start_; }
+  //! return step value of the sequence
+  inline double & Step() { return step_; }
+
+  virtual MuTyV & Value(sa_size_t k) const ;
+
+protected:
+  double start_;              //!< start value of the sequence
+  double step_;               //!< step value of the sequence
+  Arr_DoubleFunctionOfX myf_; //!< pointer to the sequence function
+  mutable MuTyV retv_;
+};
+
+//////////////////////////////////////////////////////////
+//! Class for creation and handling of an explicitly defined list of values
+
+class EnumeratedSequence : public Sequence  {
+public:
+  explicit EnumeratedSequence();
+           EnumeratedSequence(EnumeratedSequence const & es);
+  virtual ~EnumeratedSequence();
+  virtual MuTyV & Value(sa_size_t k) const ;
+
+  inline sa_size_t Size() const { return vecv_.size(); }
+
+  EnumeratedSequence & operator , (MuTyV const & v);
+  EnumeratedSequence & operator = (MuTyV const & v);
+
+  EnumeratedSequence & operator = (EnumeratedSequence const & es);
+
+  inline  void         Clear()  { vecv_.clear(); }      
+  void                 Print(ostream& os) const;
+
+  sa_size_t            Append(EnumeratedSequence const & seq);
+  sa_size_t            Append(string const & str, int & nbad, const char* sep=" \t");
+  sa_size_t            FillFromFile(istream& is, sa_size_t& nr, sa_size_t& nc, 
+				    char clm='#', const char* sep=" \t");
+
+private:
+  vector<MuTyV> vecv_;
+  mutable MuTyV retv_;
+};
+
+inline ostream& operator << (ostream& os, const EnumeratedSequence& a)
+                            { a.Print(os);    return(os);    }
+
+  //inline EnumeratedSequence operator , (MuTyV const & a, MuTyV const & b)
+  //{ EnumeratedSequence seq;   return ((seq,a),b) ; }
+
+//////////////////////////////////////////////////////////
+//! Class to define a range of indexes
+class Range {
+public:
+  explicit Range(sa_size_t start=0, sa_size_t end=0, sa_size_t size=1, sa_size_t step=1);
+  //! Return the start index
+  inline sa_size_t & Start()  {  return start_; }
+  //! Return the last index
+  inline sa_size_t & End()    {  return end_; }
+  //! Return the size
+  inline sa_size_t & Size()   {  return size_; }
+  //! Return the step
+  inline sa_size_t & Step()   {  return step_; }
+protected:
+  sa_size_t start_; //!< start index
+  sa_size_t end_;   //!< end index
+  sa_size_t size_;  //!< size
+  sa_size_t step_;  //!< step
+};
+
+//////////////////////////////////////////////////////////
+//! Class to define an identity matrix
+class IdentityMatrix {
+public:
+  explicit IdentityMatrix(double diag=1., sa_size_t n=0);
+  //! return the size of the identity matrix
+  inline sa_size_t Size() { return size_; }
+  //! return the value of the diagonal elements
+  inline double Diag() { return diag_; }
+protected:
+  sa_size_t size_; //!< size of the matrix
+  double diag_; //!< value of the diagonal elements
+};
+
+} // Fin du namespace
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/DemoPIApp/Makefile
===================================================================
--- /tags/V_Dec2002/SophyaPI/DemoPIApp/Makefile	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/DemoPIApp/Makefile	(revision 2309)
@@ -0,0 +1,36 @@
+MODULEDECCXXFLAGS := -msg_quiet 
+include $(DPCBASEREP)/Include/MakefileUser.h
+LIBS = -L$(SLB) -lPI -lextsophya -lsophya -lm 
+
+ifeq ($(MACHEROS),OSF1)
+LIBS := $(LIBS) -lfor
+endif
+ifeq ($(MACHEROS),Linux)
+LIBS := $(LIBS) -ldl -lf2c
+endif
+
+%.so:$(OBJ)%.o 
+%:%.cc
+%:%.o
+%.o:%.cc
+%.o:%.c
+%:%.c
+
+.PRECIOUS: %.so  
+
+
+%:%.so
+	echo $@ " made (.so) "
+
+%.so:$(OBJ)%.o
+	$(LINK.cc) -shared -o $@ $< $(LIBS)
+
+$(OBJ)%.o:%.cc 
+	$(COMPILE.cc)  -o $@ $<
+
+$(OBJ)%.o:%.c
+	$(COMPILE.c) -c $(CFLAGS)   $(USERFLAGS) -o $@ $< 
+
+dump :
+	echo $(LIBS)
+
Index: /tags/V_Dec2002/SophyaPI/DemoPIApp/addelts.pic
===================================================================
--- /tags/V_Dec2002/SophyaPI/DemoPIApp/addelts.pic	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/DemoPIApp/addelts.pic	(revision 2309)
@@ -0,0 +1,24 @@
+#  Drawing a gaussian using the predefined limits and no default title  
+#  with Defining the 2D plot limits
+func exp(-(x-2)*(x-2)/12.) -10 20  100 "xylimits=-10,30,-0.4,1.2 orange normalline notit" 
+#  Setting the top and bottom titles 
+settitle 'addelts.pic : Top Title ' 'Bottom Title (addelts.pic) '  siennared
+#  Superimposing a sin(x)/x function 
+func sin(x)/x 0.1 30 100 'green same'
+#  Setting axes attributes
+setaxesatt 'bigboldfont timesfont'
+#  Adding a text string and a line to the display
+addtext 15 0.2 'f(x) = sin(x)/x' gold
+addline 0 0.8 20 0.2 red
+#  Rectangle drawing
+addfrect 5 0.85 10 0.95 navyblue 
+addrect 7 1.05 8 0.75 purple 
+#  Drawing circles 
+addfcirc 18 0.75 0.25 violet 
+addfcirc 18 0.75 0.15 violetred 
+addfcirc 18 0.75 0.07 magenta 
+addfcirc 22 0.55 0.10 blueviolet 
+addfcirc 26 0.55 0.10 darkviolet 
+#  Make an Encapsulated Postscript file (eps)
+pssetfilename 
+w2eps addelts.eps
Index: /tags/V_Dec2002/SophyaPI/DemoPIApp/demo.pic
===================================================================
--- /tags/V_Dec2002/SophyaPI/DemoPIApp/demo.pic	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/DemoPIApp/demo.pic	(revision 2309)
@@ -0,0 +1,21 @@
+#   macro de commande piapp -  Exemple de demo
+#  Mode Trace -> On 
+traceon
+#  Suppression de tous les objets existants
+delobjs *
+#  ouverture de fichier PPF
+openppf demo.ppf
+# affichage divers dans une fenetre graphique 2x2
+zone 2 2 
+#  Affichage d'histo 1D
+disp h1d blue
+#  Affichage d'histo 2D
+disp h2d 
+#  Trace de fonction
+func sin(x)/x 0.1 10. 200 gold
+#  Representation en surface d'une matrice
+surf mtx1 colbr32
+#  Trace des points 3d en utilisant une commande a la paw dans une fenetre
+n/plot nt31.z%y%x ! ! win
+#  Trace des points 3d avec des erreurs superpose au dessin precedant
+nt3d nt32 x y  z ex ey ez - - 'same fcirclemarker7 red'
Index: /tags/V_Dec2002/SophyaPI/DemoPIApp/exlink.pic
===================================================================
--- /tags/V_Dec2002/SophyaPI/DemoPIApp/exlink.pic	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/DemoPIApp/exlink.pic	(revision 2309)
@@ -0,0 +1,12 @@
+#  Exemple de fichier de commande pour linker et appeler une fonction user
+#  Appel a make pour construire le module
+shell gmake user.so
+#  Link de la fonction user ds user.so
+link user.so user
+#  L'appel a user cree un nouvel NTuple
+call user toto titi 
+print usernt
+#  On affiche quelque chose du NTuple sortant
+zone 1 
+plot2de usernt 5*x y ex ey  1. blue,fcirclemarker5 
+
Index: /tags/V_Dec2002/SophyaPI/DemoPIApp/exmod.pic
===================================================================
--- /tags/V_Dec2002/SophyaPI/DemoPIApp/exmod.pic	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/DemoPIApp/exmod.pic	(revision 2309)
@@ -0,0 +1,18 @@
+#  Exemple de macro de commandes pour charger un module
+# Mode trace
+traceon
+#  On passe une commande shell pour fabriquer le module
+shell gmake exmodule.so
+# On charge le module
+loadmodule exmodule.so exmodule
+#  Deux nouvelles commandes sont definies maintenant
+excmd1 
+excmd2
+
+#  On fabrique deux vecteurs
+zone 1 2
+newvec v1 20 sin(x)
+newvec v2 10 cos(x*0.2)+sin(x*0.2)
+#  Execution des commandes de exmodule
+excmd1 v1
+excmd2 v1 v2
Index: /tags/V_Dec2002/SophyaPI/DemoPIApp/exmodule.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/DemoPIApp/exmodule.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/DemoPIApp/exmodule.cc	(revision 2309)
@@ -0,0 +1,106 @@
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream.h>
+#include <math.h>
+
+#include <typeinfo>
+
+#include <vector>
+#include <string>
+
+#include "piacmd.h"
+#include "nobjmgr.h"
+#include "pistdimgapp.h"
+
+
+//  Exemple de module chargeable ds piapp 
+
+//  Declaration de la fonction d'activation et de desactivation du module
+extern "C" {
+void exmodule_init();
+void exmodule_end();
+}
+
+
+//  Une classe commande-executor, permettant d'enregistrer de 
+//  nouvelles commandes a piapp
+class exmoduleExecutor : public CmdExecutor {
+public:
+                exmoduleExecutor();
+  virtual       ~exmoduleExecutor();
+  // Execute s'occupe de l'execution effective des commandes
+  virtual int   Execute(string& keyw, vector<string>& args, string& toks);
+};
+
+/* --Methode-- */
+exmoduleExecutor::exmoduleExecutor()
+{
+
+PIACmd * mpiac;
+NamedObjMgr omg;
+mpiac = omg.GetImgApp()->CmdInterpreter();
+
+// On enregistre deux nouvelles commandes 
+string hgrp = "ExModuleCmd";
+// commande excmd1
+string kw = "excmd1";
+string usage = "exmd1: Appel Print pour obj1 \n" ;
+usage += "Usage: excmd1 obj1 ";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+// commande excmd2
+kw = "excmd2";
+usage = "exmd2: Appel Print pour obj1 et obj2 \n" ;
+usage += "Usage: excmd2 obj1 obj2";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+}
+
+/* --Methode-- */
+exmoduleExecutor::~exmoduleExecutor()
+{
+}
+
+/* --Methode-- */
+int exmoduleExecutor::Execute(string& kw, vector<string>& tokens, string&)
+{
+
+NamedObjMgr omg;
+if (kw == "excmd1") {
+  if (tokens.size() < 1) {
+    cout << "Usage: excmd1 obj1" << endl;
+    return(0);
+    }
+  omg.PrintObj(tokens[0]);
+  }
+else if (kw == "excmd2") {
+  if (tokens.size() < 2) {
+    cout << "Usage: excmd2 obj1 obj2" << endl;
+    return(0);
+    }
+  omg.PrintObj(tokens[0]);
+  omg.PrintObj(tokens[1]);
+  }
+
+return(0);
+
+}
+
+static exmoduleExecutor * piaerex = NULL;
+/* Nouvelle-Fonction */
+void exmodule_init()
+{
+// Fonction d'initialisation du module
+// Appele par le gestionnaire de modules de piapp (PIACmd::LoadModule())
+if (piaerex) delete piaerex;
+piaerex = new exmoduleExecutor;
+}
+
+/* Nouvelle-Fonction */
+void exmodule_end()
+{
+// Desactivation du module
+if (piaerex) delete piaerex;
+piaerex = NULL;
+}
+
Index: /tags/V_Dec2002/SophyaPI/DemoPIApp/user.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/DemoPIApp/user.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/DemoPIApp/user.cc	(revision 2309)
@@ -0,0 +1,46 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <iostream.h>
+#include <string>
+
+#include "nobjmgr.h"
+
+#include "tvector.h"
+#include "histos.h"
+#include "histos2.h"
+#include "ntuple.h"
+
+#include "nbrandom.h"
+
+// ---------- Fonction pour link ds piapp -----------------
+// Exemple de fonction pouvant etre linke a piapp 
+// La fonction doit etre declare extern "C"
+extern "C" {
+  void user(vector<string>& args);
+}
+
+void user(vector<string>& args)
+{
+  // On instancie un objet NamedObjMgr
+  NamedObjMgr omg;
+  cout << " User Function user(...) nargs=" << args.size() << endl;
+
+  // On cree un NTuple et on le remplit
+  float xnt[4];
+  char *ntn[4] = {"x","y","ex","ey"};
+  int nent,i;
+  nent = 100;
+  NTuple* nt = new NTuple(4,ntn);  // Creation NTuple (AVEC new )
+  for(i=0; i<nent; i++) {
+    xnt[0] = i*50./nent; xnt[1] = 0.2*xnt[0]*xnt[0]+(NorRand()*xnt[0]/3.);
+    xnt[2] = 0.; xnt[3] = xnt[0]/3.;
+    nt->Fill(xnt);
+  }
+
+  // On ajoute le ntuple cree a la liste des objets geres par piapp
+  string nom = "usernt";
+  omg.AddObj(nt, nom);
+  return;
+}
+
Index: /tags/V_Dec2002/SophyaPI/PI/Makefile
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/Makefile	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/Makefile	(revision 2309)
@@ -0,0 +1,321 @@
+MODULECXXREPNAME := PI
+MODULEDECCXXFLAGS := -msg_quiet
+include ../Mgr/Makefile.h
+ 
+all: $(LIB)libPI.a
+$(LIB)libPI.a : $(OBJ)lut.o $(OBJ)parradapter.o $(OBJ)pi3ddrw.o $(OBJ)pi3dwdg.o $(OBJ)piapplgen.o $(OBJ)piapplx.o $(OBJ)piaxes.o $(OBJ)piaxestools.o $(OBJ)pibwdggen.o $(OBJ)pibwdgx.o $(OBJ)picmap.o $(OBJ)picmapgen.o $(OBJ)picmapview.o $(OBJ)picmapx.o $(OBJ)picons.o $(OBJ)picontainergen.o $(OBJ)picontainerx.o $(OBJ)pidrawer.o $(OBJ)pidrawwin.o $(OBJ)pidrwtools.o $(OBJ)pieldrw.o $(OBJ)pievthandler.o $(OBJ)pifilechogen.o $(OBJ)pifilechox.o $(OBJ)pifontgen.o $(OBJ)pifontx.o $(OBJ)pigraph3d.o $(OBJ)pigraphgen.o $(OBJ)pigraphps.o $(OBJ)pigraphuc.o $(OBJ)pigraphx.o $(OBJ)pigratt.o $(OBJ)pigrcoord.o $(OBJ)piimage.o $(OBJ)piimgtools.o $(OBJ)pilineatt.o $(OBJ)pilistgen.o $(OBJ)pilistx.o $(OBJ)pimenubargen.o $(OBJ)pimenubarx.o $(OBJ)pimenugen.o $(OBJ)pimenux.o $(OBJ)pimsghandler.o $(OBJ)pioptmenugen.o $(OBJ)pioptmenux.o $(OBJ)piperiodx.o $(OBJ)pipixmapgen.o $(OBJ)pipixmapx.o $(OBJ)piscdrawwdg.o $(OBJ)pistdwdggen.o $(OBJ)pistdwdgx.o $(OBJ)pistzwin.o $(OBJ)pisurfdr.o $(OBJ)pitherm.o $(OBJ)piwdggen.o $(OBJ)piwdgx.o $(OBJ)piwindowgen.o $(OBJ)piwindowx.o $(OBJ)pixtbase.o $(OBJ)piyfxdrw.o $(OBJ)psfile.o
+	$(AR) $(ARFLAGS)  $@ $($(ARARGS)) 
+ifeq ($(CXX),cxx)
+	$(CXX) $? $(CPPFLAGS) $(CXXFLAGS) -o $(OBJ)xx.x -Hf
+endif 
+ 
+clean:
+	rm -f $(OBJ)lut.o $(OBJ)parradapter.o $(OBJ)pi3ddrw.o $(OBJ)pi3dwdg.o $(OBJ)piapplgen.o $(OBJ)piapplx.o $(OBJ)piaxes.o $(OBJ)piaxestools.o $(OBJ)pibwdggen.o $(OBJ)pibwdgx.o $(OBJ)picmap.o $(OBJ)picmapgen.o $(OBJ)picmapview.o $(OBJ)picmapx.o $(OBJ)picons.o $(OBJ)picontainergen.o $(OBJ)picontainerx.o $(OBJ)pidrawer.o $(OBJ)pidrawwin.o $(OBJ)pidrwtools.o $(OBJ)pieldrw.o $(OBJ)pievthandler.o $(OBJ)pifilechogen.o $(OBJ)pifilechox.o $(OBJ)pifontgen.o $(OBJ)pifontx.o $(OBJ)pigraph3d.o $(OBJ)pigraphgen.o $(OBJ)pigraphps.o $(OBJ)pigraphuc.o $(OBJ)pigraphx.o $(OBJ)pigratt.o $(OBJ)pigrcoord.o $(OBJ)piimage.o $(OBJ)piimgtools.o $(OBJ)pilineatt.o $(OBJ)pilistgen.o $(OBJ)pilistx.o $(OBJ)pimenubargen.o $(OBJ)pimenubarx.o $(OBJ)pimenugen.o $(OBJ)pimenux.o $(OBJ)pimsghandler.o $(OBJ)pioptmenugen.o $(OBJ)pioptmenux.o $(OBJ)piperiodx.o $(OBJ)pipixmapgen.o $(OBJ)pipixmapx.o $(OBJ)piscdrawwdg.o $(OBJ)pistdwdggen.o $(OBJ)pistdwdgx.o $(OBJ)pistzwin.o $(OBJ)pisurfdr.o $(OBJ)pitherm.o $(OBJ)piwdggen.o $(OBJ)piwdgx.o $(OBJ)piwindowgen.o $(OBJ)piwindowx.o $(OBJ)pixtbase.o $(OBJ)piyfxdrw.o $(OBJ)psfile.o
+ifeq ($(CXX),cxx)
+	cd $(REPM); rm -f *.o
+endif 
+ 
+$(OBJ)lut.o: lut.cc $(INC)machdefs.h lut.h
+$(OBJ)parradapter.o: parradapter.cc parradapter.h \
+ $(INC)machdefs.h lut.h
+$(OBJ)pi3ddrw.o: pi3ddrw.cc pi3ddrw.h pisysdep.h \
+ $(INC)machdefs.h pidrawer.h pibwdggen.h \
+ piwdgx.h piwdggen.h pimsghandler.h picolist.h picmap.h picmapx.h \
+ picmapgen.h pigraphx.h pigraphgen.h pifontx.h pifontgen.h pigrcoord.h \
+ pilineatt.h pigraphuc.h pievthandler.h psfile.h pigratt.h piaxes.h \
+ pieldrw.h pigraph3d.h
+$(OBJ)pi3dwdg.o: pi3dwdg.cc pi3dwdg.h pisysdep.h \
+ $(INC)machdefs.h pi3ddrw.h pidrawer.h \
+ pibwdggen.h piwdgx.h piwdggen.h pimsghandler.h picolist.h picmap.h \
+ picmapx.h picmapgen.h pigraphx.h pigraphgen.h pifontx.h pifontgen.h \
+ pigrcoord.h pilineatt.h pigraphuc.h pievthandler.h psfile.h pigratt.h \
+ piaxes.h pieldrw.h pigraph3d.h pibwdgx.h pigraphps.h pidrwtools.h \
+ pistdwdgx.h pistdwdggen.h pioptmenux.h pioptmenugen.h pimenux.h \
+ pimenugen.h piwindowx.h piwindowgen.h picontainerx.h picontainergen.h \
+ piapplx.h piapplgen.h pimenubarx.h pimenubargen.h picons.h
+$(OBJ)piapplgen.o: piapplgen.cc piapplgen.h pimsghandler.h \
+ $(INC)machdefs.h pisysdep.h picontainerx.h \
+ picontainergen.h piwdgx.h piwdggen.h picolist.h pimenubarx.h \
+ pimenubargen.h pimenux.h pimenugen.h picons.h pistdwdgx.h \
+ pistdwdggen.h pibwdgx.h pibwdggen.h picmap.h picmapx.h picmapgen.h \
+ pigraphx.h pigraphgen.h pifontx.h pifontgen.h pigrcoord.h pilineatt.h \
+ pigraphuc.h pievthandler.h psfile.h pigraphps.h
+$(OBJ)piapplx.o: piapplx.cc piapplx.h piapplgen.h pimsghandler.h \
+ $(INC)machdefs.h pisysdep.h picontainerx.h \
+ picontainergen.h piwdgx.h piwdggen.h picolist.h pimenubarx.h \
+ pimenubargen.h pimenux.h pimenugen.h picons.h pistdwdgx.h \
+ pistdwdggen.h pibwdgx.h pibwdggen.h picmap.h picmapx.h picmapgen.h \
+ pigraphx.h pigraphgen.h pifontx.h pifontgen.h pigrcoord.h pilineatt.h \
+ pigraphuc.h pievthandler.h psfile.h pigraphps.h
+$(OBJ)piaxes.o: piaxes.cc $(INC)machdefs.h piaxes.h \
+ pigraphuc.h pisysdep.h pigraphgen.h piwdgx.h piwdggen.h \
+ pimsghandler.h picolist.h picmap.h picmapx.h picmapgen.h pifontx.h \
+ pifontgen.h pigrcoord.h pilineatt.h pigratt.h
+$(OBJ)piaxestools.o: piaxestools.cc piaxes.h pigraphuc.h pisysdep.h \
+ $(INC)machdefs.h pigraphgen.h piwdgx.h \
+ piwdggen.h pimsghandler.h picolist.h picmap.h picmapx.h picmapgen.h \
+ pifontx.h pifontgen.h pigrcoord.h pilineatt.h pigratt.h piaxestools.h \
+ pistdwdgx.h pistdwdggen.h pioptmenux.h pioptmenugen.h pimenux.h \
+ pimenugen.h piwindowx.h piwindowgen.h picontainerx.h picontainergen.h \
+ piapplx.h piapplgen.h pimenubarx.h pimenubargen.h picons.h pibwdgx.h \
+ pibwdggen.h pigraphx.h pievthandler.h psfile.h pigraphps.h \
+ piscdrawwdg.h pidrawer.h pieldrw.h
+$(OBJ)pibwdggen.o: pibwdggen.cc pibwdggen.h pisysdep.h \
+ $(INC)machdefs.h piwdgx.h piwdggen.h \
+ pimsghandler.h picolist.h picmap.h picmapx.h picmapgen.h pigraphx.h \
+ pigraphgen.h pifontx.h pifontgen.h pigrcoord.h pilineatt.h \
+ pigraphuc.h pievthandler.h psfile.h pidrawer.h pigratt.h piaxes.h \
+ pigraphps.h pidrwtools.h pistdwdgx.h pistdwdggen.h pioptmenux.h \
+ pioptmenugen.h pimenux.h pimenugen.h piwindowx.h piwindowgen.h \
+ picontainerx.h picontainergen.h piapplx.h piapplgen.h pimenubarx.h \
+ pimenubargen.h picons.h pibwdgx.h
+$(OBJ)pibwdgx.o: pibwdgx.cc pixtbaseP.h pibwdgx.h pisysdep.h \
+ $(INC)machdefs.h pibwdggen.h piwdgx.h \
+ piwdggen.h pimsghandler.h picolist.h picmap.h picmapx.h picmapgen.h \
+ pigraphx.h pigraphgen.h pifontx.h pifontgen.h pigrcoord.h pilineatt.h \
+ pigraphuc.h pievthandler.h psfile.h pigraphps.h pixtbase.h
+$(OBJ)picmap.o: picmap.cc picmap.h pisysdep.h \
+ $(INC)machdefs.h picmapx.h picmapgen.h
+$(OBJ)picmapgen.o: picmapgen.cc picmapgen.h pisysdep.h \
+ $(INC)machdefs.h picmapx.h picmap.h
+$(OBJ)picmapview.o: picmapview.cc picmapview.h pisysdep.h \
+ $(INC)machdefs.h pibwdgx.h pibwdggen.h \
+ piwdgx.h piwdggen.h pimsghandler.h picolist.h picmap.h picmapx.h \
+ picmapgen.h pigraphx.h pigraphgen.h pifontx.h pifontgen.h pigrcoord.h \
+ pilineatt.h pigraphuc.h pievthandler.h psfile.h pigraphps.h
+$(OBJ)picmapx.o: picmapx.cc piwdgx.h piwdggen.h \
+ $(INC)machdefs.h pimsghandler.h picolist.h \
+ picmapx.h picmapgen.h pisysdep.h
+$(OBJ)picons.o: picons.cc pisysdep.h \
+ $(INC)machdefs.h pimenux.h pimenugen.h \
+ piwdgx.h piwdggen.h pimsghandler.h picolist.h picons.h pistdwdgx.h \
+ pistdwdggen.h picontainerx.h picontainergen.h pibwdgx.h pibwdggen.h \
+ picmap.h picmapx.h picmapgen.h pigraphx.h pigraphgen.h pifontx.h \
+ pifontgen.h pigrcoord.h pilineatt.h pigraphuc.h pievthandler.h \
+ psfile.h pigraphps.h
+$(OBJ)picontainergen.o: picontainergen.cc picontainergen.h pisysdep.h \
+ $(INC)machdefs.h piwdgx.h piwdggen.h \
+ pimsghandler.h picolist.h
+$(OBJ)picontainerx.o: picontainerx.cc picontainerx.h pisysdep.h \
+ $(INC)machdefs.h picontainergen.h piwdgx.h \
+ piwdggen.h pimsghandler.h picolist.h
+$(OBJ)pidrawer.o: pidrawer.cc $(INC)machdefs.h \
+ pidrawer.h pibwdggen.h pisysdep.h piwdgx.h piwdggen.h pimsghandler.h \
+ picolist.h picmap.h picmapx.h picmapgen.h pigraphx.h pigraphgen.h \
+ pifontx.h pifontgen.h pigrcoord.h pilineatt.h pigraphuc.h \
+ pievthandler.h psfile.h pigratt.h piaxes.h pidrwtools.h pistdwdgx.h \
+ pistdwdggen.h pioptmenux.h pioptmenugen.h pimenux.h pimenugen.h \
+ piwindowx.h piwindowgen.h picontainerx.h picontainergen.h piapplx.h \
+ piapplgen.h pimenubarx.h pimenubargen.h picons.h pibwdgx.h \
+ pigraphps.h ucckprot.h
+$(OBJ)pidrawwin.o: pidrawwin.cc pidrawwin.h pisysdep.h \
+ $(INC)machdefs.h piwindowx.h piwindowgen.h \
+ picontainerx.h picontainergen.h piwdgx.h piwdggen.h pimsghandler.h \
+ picolist.h piscdrawwdg.h pibwdgx.h pibwdggen.h picmap.h picmapx.h \
+ picmapgen.h pigraphx.h pigraphgen.h pifontx.h pifontgen.h pigrcoord.h \
+ pilineatt.h pigraphuc.h pievthandler.h psfile.h pigraphps.h \
+ pistdwdgx.h pistdwdggen.h pidrawer.h pigratt.h piaxes.h pieldrw.h
+$(OBJ)pidrwtools.o: pidrwtools.cc pidrwtools.h pisysdep.h \
+ $(INC)machdefs.h pistdwdgx.h pistdwdggen.h \
+ piwdgx.h piwdggen.h pimsghandler.h picolist.h pioptmenux.h \
+ pioptmenugen.h pimenux.h pimenugen.h piwindowx.h piwindowgen.h \
+ picontainerx.h picontainergen.h piapplx.h piapplgen.h pimenubarx.h \
+ pimenubargen.h picons.h pibwdgx.h pibwdggen.h picmap.h picmapx.h \
+ picmapgen.h pigraphx.h pigraphgen.h pifontx.h pifontgen.h pigrcoord.h \
+ pilineatt.h pigraphuc.h pievthandler.h psfile.h pigraphps.h \
+ piscdrawwdg.h pidrawer.h pigratt.h piaxes.h pieldrw.h pi3dwdg.h \
+ pi3ddrw.h pigraph3d.h
+$(OBJ)pieldrw.o: pieldrw.cc $(INC)machdefs.h \
+ pieldrw.h pidrawer.h pibwdggen.h pisysdep.h piwdgx.h piwdggen.h \
+ pimsghandler.h picolist.h picmap.h picmapx.h picmapgen.h pigraphx.h \
+ pigraphgen.h pifontx.h pifontgen.h pigrcoord.h pilineatt.h \
+ pigraphuc.h pievthandler.h psfile.h pigratt.h piaxes.h
+$(OBJ)pievthandler.o: pievthandler.cc pievthandler.h pisysdep.h \
+ $(INC)machdefs.h pimsghandler.h piwdgx.h \
+ piwdggen.h picolist.h pigraphx.h pigraphgen.h picmap.h picmapx.h \
+ picmapgen.h pifontx.h pifontgen.h pigrcoord.h pilineatt.h
+$(OBJ)pifilechogen.o: pifilechogen.cc pifilechogen.h pisysdep.h \
+ $(INC)machdefs.h piwdgx.h piwdggen.h \
+ pimsghandler.h picolist.h
+$(OBJ)pifilechox.o: pifilechox.cc pisysdep.h \
+ $(INC)machdefs.h piapplx.h piapplgen.h \
+ pimsghandler.h picontainerx.h picontainergen.h piwdgx.h piwdggen.h \
+ picolist.h pimenubarx.h pimenubargen.h pimenux.h pimenugen.h picons.h \
+ pistdwdgx.h pistdwdggen.h pibwdgx.h pibwdggen.h picmap.h picmapx.h \
+ picmapgen.h pigraphx.h pigraphgen.h pifontx.h pifontgen.h pigrcoord.h \
+ pilineatt.h pigraphuc.h pievthandler.h psfile.h pigraphps.h \
+ pifilechox.h pifilechogen.h piwindowx.h piwindowgen.h
+$(OBJ)pifontgen.o: pifontgen.cc pigraphgen.h pisysdep.h \
+ $(INC)machdefs.h piwdgx.h piwdggen.h \
+ pimsghandler.h picolist.h picmap.h picmapx.h picmapgen.h pifontx.h \
+ pifontgen.h pigrcoord.h pilineatt.h
+$(OBJ)pifontx.o: pifontx.cc pisysdep.h \
+ $(INC)machdefs.h pifontx.h pifontgen.h \
+ piwdgx.h piwdggen.h pimsghandler.h picolist.h
+$(OBJ)pigraph3d.o: pigraph3d.cc pigraph3d.h pisysdep.h \
+ $(INC)machdefs.h pigraphuc.h pigraphgen.h \
+ piwdgx.h piwdggen.h pimsghandler.h picolist.h picmap.h picmapx.h \
+ picmapgen.h pifontx.h pifontgen.h pigrcoord.h pilineatt.h
+$(OBJ)pigraphgen.o: pigraphgen.cc pigraphgen.h pisysdep.h \
+ $(INC)machdefs.h piwdgx.h piwdggen.h \
+ pimsghandler.h picolist.h picmap.h picmapx.h picmapgen.h pifontx.h \
+ pifontgen.h pigrcoord.h pilineatt.h
+$(OBJ)pigraphps.o: pigraphps.cc pigraphps.h pisysdep.h \
+ $(INC)machdefs.h pigraphgen.h piwdgx.h \
+ piwdggen.h pimsghandler.h picolist.h picmap.h picmapx.h picmapgen.h \
+ pifontx.h pifontgen.h pigrcoord.h pilineatt.h psfile.h
+$(OBJ)pigraphuc.o: pigraphuc.cc $(INC)machdefs.h \
+ pigraphuc.h pisysdep.h pigraphgen.h piwdgx.h piwdggen.h \
+ pimsghandler.h picolist.h picmap.h picmapx.h picmapgen.h pifontx.h \
+ pifontgen.h pigrcoord.h pilineatt.h ucckprot.h
+$(OBJ)pigraphx.o: pigraphx.cc pigraphx.h pisysdep.h \
+ $(INC)machdefs.h pigraphgen.h piwdgx.h \
+ piwdggen.h pimsghandler.h picolist.h picmap.h picmapx.h picmapgen.h \
+ pifontx.h pifontgen.h pigrcoord.h pilineatt.h
+$(OBJ)pigratt.o: pigratt.cc pigratt.h pisysdep.h \
+ $(INC)machdefs.h pigraphgen.h piwdgx.h \
+ piwdggen.h pimsghandler.h picolist.h picmap.h picmapx.h picmapgen.h \
+ pifontx.h pifontgen.h pigrcoord.h pilineatt.h
+$(OBJ)pigrcoord.o: pigrcoord.cc pigrcoord.h pisysdep.h \
+ $(INC)machdefs.h
+$(OBJ)piimage.o: piimage.cc piimage.h parradapter.h \
+ $(INC)machdefs.h lut.h pisysdep.h pieldrw.h \
+ pidrawer.h pibwdggen.h piwdgx.h piwdggen.h pimsghandler.h picolist.h \
+ picmap.h picmapx.h picmapgen.h pigraphx.h pigraphgen.h pifontx.h \
+ pifontgen.h pigrcoord.h pilineatt.h pigraphuc.h pievthandler.h \
+ psfile.h pigratt.h piaxes.h pipixmapx.h pipixmapgen.h pibwdgx.h \
+ pigraphps.h pistdwdgx.h pistdwdggen.h piwindowx.h piwindowgen.h \
+ picontainerx.h picontainergen.h picmapview.h piimgtools.h \
+ pioptmenux.h pioptmenugen.h pimenux.h pimenugen.h piapplx.h \
+ piapplgen.h pimenubarx.h pimenubargen.h picons.h pidrwtools.h \
+ piscdrawwdg.h piyfxdrw.h
+$(OBJ)piimgtools.o: piimgtools.cc piimgtools.h pisysdep.h \
+ $(INC)machdefs.h pistdwdgx.h pistdwdggen.h \
+ piwdgx.h piwdggen.h pimsghandler.h picolist.h pioptmenux.h \
+ pioptmenugen.h pimenux.h pimenugen.h piwindowx.h piwindowgen.h \
+ picontainerx.h picontainergen.h piapplx.h piapplgen.h pimenubarx.h \
+ pimenubargen.h picons.h pibwdgx.h pibwdggen.h picmap.h picmapx.h \
+ picmapgen.h pigraphx.h pigraphgen.h pifontx.h pifontgen.h pigrcoord.h \
+ pilineatt.h pigraphuc.h pievthandler.h psfile.h pigraphps.h piimage.h \
+ parradapter.h lut.h pieldrw.h pidrawer.h pigratt.h piaxes.h \
+ pipixmapx.h pipixmapgen.h picmapview.h
+$(OBJ)pilineatt.o: pilineatt.cc pilineatt.h pisysdep.h \
+ $(INC)machdefs.h
+$(OBJ)pilistgen.o: pilistgen.cc pilistgen.h pisysdep.h \
+ $(INC)machdefs.h piwdgx.h piwdggen.h \
+ pimsghandler.h picolist.h
+$(OBJ)pilistx.o: pilistx.cc pilistx.h pilistgen.h pisysdep.h \
+ $(INC)machdefs.h piwdgx.h piwdggen.h \
+ pimsghandler.h picolist.h picontainerx.h picontainergen.h
+$(OBJ)pimenubargen.o: pimenubargen.cc pimenubargen.h pisysdep.h \
+ $(INC)machdefs.h pimenux.h pimenugen.h \
+ piwdgx.h piwdggen.h pimsghandler.h picolist.h piapplx.h piapplgen.h \
+ picontainerx.h picontainergen.h pimenubarx.h picons.h pistdwdgx.h \
+ pistdwdggen.h pibwdgx.h pibwdggen.h picmap.h picmapx.h picmapgen.h \
+ pigraphx.h pigraphgen.h pifontx.h pifontgen.h pigrcoord.h pilineatt.h \
+ pigraphuc.h pievthandler.h psfile.h pigraphps.h
+$(OBJ)pimenubarx.o: pimenubarx.cc pimenubarx.h pimenubargen.h pisysdep.h \
+ $(INC)machdefs.h pimenux.h pimenugen.h \
+ piwdgx.h piwdggen.h pimsghandler.h picolist.h piapplx.h piapplgen.h \
+ picontainerx.h picontainergen.h picons.h pistdwdgx.h pistdwdggen.h \
+ pibwdgx.h pibwdggen.h picmap.h picmapx.h picmapgen.h pigraphx.h \
+ pigraphgen.h pifontx.h pifontgen.h pigrcoord.h pilineatt.h \
+ pigraphuc.h pievthandler.h psfile.h pigraphps.h
+$(OBJ)pimenugen.o: pimenugen.cc pimenugen.h pisysdep.h \
+ $(INC)machdefs.h piwdgx.h piwdggen.h \
+ pimsghandler.h picolist.h
+$(OBJ)pimenux.o: pimenux.cc pisysdep.h \
+ $(INC)machdefs.h pimenubarx.h pimenubargen.h \
+ pimenux.h pimenugen.h piwdgx.h piwdggen.h pimsghandler.h picolist.h
+$(OBJ)pimsghandler.o: pimsghandler.cc pimsghandler.h \
+ $(INC)machdefs.h
+$(OBJ)pioptmenugen.o: pioptmenugen.cc pioptmenugen.h pisysdep.h \
+ $(INC)machdefs.h pimenux.h pimenugen.h \
+ piwdgx.h piwdggen.h pimsghandler.h picolist.h
+$(OBJ)pioptmenux.o: pioptmenux.cc pisysdep.h \
+ $(INC)machdefs.h pioptmenux.h pioptmenugen.h \
+ pimenux.h pimenugen.h piwdgx.h piwdggen.h pimsghandler.h picolist.h \
+ pistdwdgx.h pistdwdggen.h piapplx.h piapplgen.h picontainerx.h \
+ picontainergen.h pimenubarx.h pimenubargen.h picons.h pibwdgx.h \
+ pibwdggen.h picmap.h picmapx.h picmapgen.h pigraphx.h pigraphgen.h \
+ pifontx.h pifontgen.h pigrcoord.h pilineatt.h pigraphuc.h \
+ pievthandler.h psfile.h pigraphps.h
+$(OBJ)piperiodx.o: piperiodx.cc piwdgx.h piwdggen.h \
+ $(INC)machdefs.h pimsghandler.h picolist.h \
+ piperiodx.h $(INC)periodic.h
+$(OBJ)pipixmapgen.o: pipixmapgen.cc pipixmapgen.h pisysdep.h \
+ $(INC)machdefs.h pibwdgx.h pibwdggen.h \
+ piwdgx.h piwdggen.h pimsghandler.h picolist.h picmap.h picmapx.h \
+ picmapgen.h pigraphx.h pigraphgen.h pifontx.h pifontgen.h pigrcoord.h \
+ pilineatt.h pigraphuc.h pievthandler.h psfile.h pigraphps.h
+$(OBJ)pipixmapx.o: pipixmapx.cc pipixmapx.h pipixmapgen.h pisysdep.h \
+ $(INC)machdefs.h pibwdgx.h pibwdggen.h \
+ piwdgx.h piwdggen.h pimsghandler.h picolist.h picmap.h picmapx.h \
+ picmapgen.h pigraphx.h pigraphgen.h pifontx.h pifontgen.h pigrcoord.h \
+ pilineatt.h pigraphuc.h pievthandler.h psfile.h pigraphps.h
+$(OBJ)piscdrawwdg.o: piscdrawwdg.cc \
+ $(INC)machdefs.h piscdrawwdg.h pisysdep.h \
+ pibwdgx.h pibwdggen.h piwdgx.h piwdggen.h pimsghandler.h picolist.h \
+ picmap.h picmapx.h picmapgen.h pigraphx.h pigraphgen.h pifontx.h \
+ pifontgen.h pigrcoord.h pilineatt.h pigraphuc.h pievthandler.h \
+ psfile.h pigraphps.h pistdwdgx.h pistdwdggen.h piwindowx.h \
+ piwindowgen.h picontainerx.h picontainergen.h pidrawer.h pigratt.h \
+ piaxes.h pieldrw.h pidrwtools.h pioptmenux.h pioptmenugen.h pimenux.h \
+ pimenugen.h piapplx.h piapplgen.h pimenubarx.h pimenubargen.h \
+ picons.h piaxestools.h
+$(OBJ)pistdwdggen.o: pistdwdggen.cc pistdwdggen.h pisysdep.h \
+ $(INC)machdefs.h piwdgx.h piwdggen.h \
+ pimsghandler.h picolist.h
+$(OBJ)pistdwdgx.o: pistdwdgx.cc pisysdep.h \
+ $(INC)machdefs.h pistdwdgx.h pistdwdggen.h \
+ piwdgx.h piwdggen.h pimsghandler.h picolist.h picontainerx.h \
+ picontainergen.h
+$(OBJ)pistzwin.o: pistzwin.cc pistzwin.h pisysdep.h \
+ $(INC)machdefs.h piwindowx.h piwindowgen.h \
+ picontainerx.h picontainergen.h piwdgx.h piwdggen.h pimsghandler.h \
+ picolist.h piperiodx.h $(INC)periodic.h \
+ psfile.h pifontgen.h pigraphgen.h picmap.h picmapx.h picmapgen.h \
+ pifontx.h pigrcoord.h pilineatt.h
+$(OBJ)pisurfdr.o: pisurfdr.cc pisurfdr.h parradapter.h \
+ $(INC)machdefs.h lut.h pi3ddrw.h pisysdep.h \
+ pidrawer.h pibwdggen.h piwdgx.h piwdggen.h pimsghandler.h picolist.h \
+ picmap.h picmapx.h picmapgen.h pigraphx.h pigraphgen.h pifontx.h \
+ pifontgen.h pigrcoord.h pilineatt.h pigraphuc.h pievthandler.h \
+ psfile.h pigratt.h piaxes.h pieldrw.h pigraph3d.h
+$(OBJ)pitherm.o: pitherm.cc pitherm.h pisysdep.h \
+ $(INC)machdefs.h pibwdgx.h pibwdggen.h \
+ piwdgx.h piwdggen.h pimsghandler.h picolist.h picmap.h picmapx.h \
+ picmapgen.h pigraphx.h pigraphgen.h pifontx.h pifontgen.h pigrcoord.h \
+ pilineatt.h pigraphuc.h pievthandler.h psfile.h pigraphps.h
+$(OBJ)piwdggen.o: piwdggen.cc piwdggen.h \
+ $(INC)machdefs.h pimsghandler.h picolist.h \
+ picontainergen.h pisysdep.h piwdgx.h pievthandler.h pigraphx.h \
+ pigraphgen.h picmap.h picmapx.h picmapgen.h pifontx.h pifontgen.h \
+ pigrcoord.h pilineatt.h psfile.h
+$(OBJ)piwdgx.o: piwdgx.cc piwdgx.h piwdggen.h \
+ $(INC)machdefs.h pimsghandler.h picolist.h \
+ picontainerx.h pisysdep.h picontainergen.h pievthandler.h pigraphx.h \
+ pigraphgen.h picmap.h picmapx.h picmapgen.h pifontx.h pifontgen.h \
+ pigrcoord.h pilineatt.h
+$(OBJ)piwindowgen.o: piwindowgen.cc piwindowgen.h pisysdep.h \
+ $(INC)machdefs.h picontainerx.h \
+ picontainergen.h piwdgx.h piwdggen.h pimsghandler.h picolist.h \
+ psfile.h pifontgen.h pigraphgen.h picmap.h picmapx.h picmapgen.h \
+ pifontx.h pigrcoord.h pilineatt.h
+$(OBJ)piwindowx.o: piwindowx.cc piwindowx.h piwindowgen.h pisysdep.h \
+ $(INC)machdefs.h picontainerx.h \
+ picontainergen.h piwdgx.h piwdggen.h pimsghandler.h picolist.h
+$(OBJ)pixtbase.o: pixtbase.cc pixtbaseP.h pibwdgx.h pisysdep.h \
+ $(INC)machdefs.h pibwdggen.h piwdgx.h \
+ piwdggen.h pimsghandler.h picolist.h picmap.h picmapx.h picmapgen.h \
+ pigraphx.h pigraphgen.h pifontx.h pifontgen.h pigrcoord.h pilineatt.h \
+ pigraphuc.h pievthandler.h psfile.h pigraphps.h pixtbase.h
+$(OBJ)piyfxdrw.o: piyfxdrw.cc $(INC)machdefs.h \
+ piyfxdrw.h pisysdep.h parradapter.h lut.h pidrawer.h pibwdggen.h \
+ piwdgx.h piwdggen.h pimsghandler.h picolist.h picmap.h picmapx.h \
+ picmapgen.h pigraphx.h pigraphgen.h pifontx.h pifontgen.h pigrcoord.h \
+ pilineatt.h pigraphuc.h pievthandler.h psfile.h pigratt.h piaxes.h
+$(OBJ)psfile.o: psfile.cc psfile.h $(INC)machdefs.h \
+ pisysdep.h pifontgen.h pigraphgen.h piwdgx.h piwdggen.h \
+ pimsghandler.h picolist.h picmap.h picmapx.h picmapgen.h pifontx.h \
+ pigrcoord.h pilineatt.h
Index: /tags/V_Dec2002/SophyaPI/PI/Tests/Makefile
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/Tests/Makefile	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/Tests/Makefile	(revision 2309)
@@ -0,0 +1,59 @@
+MODULECXXREPNAME := PITest
+MODULEDECCXXFLAGS := -msg_quiet
+include $(DPCDEVREP)/Include/Makefile.h
+
+
+ifdef NOSHLIB
+LIBF =  $(LIB)libPI.a $(LIB)libOutils++.a $(LIB)libcoutils.a 
+LIBS = -L$(LIB) -lPIext -lPI -lOutils++ -lcoutils -lXm -lXt -lX11 -lm
+ifeq ($(CXX),cxx)
+# librairie des instances de templates cxx
+LIBS := $(LIBS) -lertcxx -lertcxxpi
+endif
+else
+LIBF =  $(SLB)libPI.so $(SLB)libsophya.so  
+LIBS = -L$(SLB) -lPI -lsophya -L/usr/X11R6/lib -lXm -lXp -lXt -lX11 -lm
+endif
+
+ifeq (${MACHEROS},Linux)
+  LIBS := $(LIBS) -ldl
+endif
+
+ifndef (NOSHLIB)
+LIBS := $(SLIBS) $(LIBS)
+endif
+
+
+LDLIBS := $(LIBS) $(LDLIBS)
+
+%:%.cc
+%:%.o
+%.o:%.cc
+%.o:%.c
+%:%.c
+
+.PRECIOUS: $(EXE)% $(OBJ)%.o
+
+%:$(EXE)%
+	echo $@ " done"
+
+$(EXE)%:$(OBJ)%.o
+	$(LINK.cc)  -o $@ $< $(LIBS)
+
+$(OBJ)%.o:%.cc
+	$(COMPILE.cc)   $(USERFLAGS) -o $@ $<
+
+$(EXE)%:$(OBJ)%.cc
+	$(LINK.cc) $(USERFLAGS)  -o $@ $< $(LIBS) 
+
+$(EXE)%:$(OBJ)%.c
+	$(LINK.c)  $(USERFLAGS) -o $@ $< $(LIBS) 
+
+$(OBJ)%.o:%.c
+	$(COMPILE.c) -c $(CFLAGS) $(USERFLAGS) -o $@ $< 
+
+
+clean:
+	rm -f $(OBJ)pit0.o $(OBJ)pit1.o $(OBJ)pitcons.o $(OBJ)pitgr.o $(OBJ)pitst.o
+	rm -f $(EXE)pit0 $(EXE)pit1 $(EXE)pitcons $(EXE)pitgr $(EXE)pitst
+	if [ -d $(OBJ)cxxrep_PITest ] ; then cd $(OBJ)cxxrep_PITest ; rm -f *.o ; fi
Index: /tags/V_Dec2002/SophyaPI/PI/Tests/midasitt.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/Tests/midasitt.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/Tests/midasitt.cc	(revision 2309)
@@ -0,0 +1,523 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include <iostream.h>
+
+#include "pisysdep.h"
+
+#include PIAPP_H
+#include PIMENU_H 
+#include PISTDWDG_H 
+#include PIWIN_H
+#include PIPERIODIC_H
+
+#include "pidrawwin.h"
+#include "piscdrawwdg.h"
+#include "piimage.h"
+#include "parradapter.h"
+
+#include "psfile.h"
+
+#include "piimgtools.h"
+#include "pidrwtools.h"
+
+#include "pisurfdr.h"
+#include "pi3dwdg.h"
+#include "piyfxdrw.h"
+
+//  ---------- classe PITApp -----------------------
+class PITApp : public PIApplication {
+public:
+     PITApp(int narg=0, char* arg[]=NULL);
+     ~PITApp();
+     virtual void   Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+
+  PIMenu* m[3];
+  PIText* txt;
+  PIPixmap* zoom;  
+  PICMapView* cmapv;
+  PIWindow *mCurW;
+  PIColorMap midas_cmap;
+};
+
+/* Tableau pour lire les composantes RGB de MIDAS_ITT */
+static double rgb_r[512];
+static double rgb_g[512];
+static double rgb_b[512];
+static int rgb_ncol = 0;
+
+/* --Methode-- */
+PITApp::PITApp(int narg, char* arg[])
+  : PIApplication(360, 130, narg, arg) , midas_cmap("MIDAS_ColMap", rgb_ncol)
+{
+
+m[0] = new PIMenu(Menubar(),"Fichier");
+m[0]->AppendItem("Info", 10101);
+m[0]->AppendItem("Close", 10110);
+m[0]->AppendItem("Exit", 10150);
+// On accroche le menu au Menubar
+AppendMenu(m[0]);
+
+// 2eme Menu
+
+m[1] = new PIMenu(Menubar(),"Graphics");
+m[1]->AppendItem("Sin(x)/x", 10201);
+m[1]->AppendItem("YfXDrawer", 10202);
+m[1]->AppendItem("2-Drawers", 10203);
+m[1]->AppendItem("Surf-3D", 10204);
+m[1]->AppendItem("Surf-3D-Color", 10205);
+m[1]->AppendItem("Image", 10206);
+m[1]->AppendItem("Image Gauss", 10207);
+
+AppendMenu(m[1]);
+
+
+m[2] = new PIMenu(Menubar(),"Tools");
+m[2]->AppendItem("ShowImageTools", 10301);
+m[2]->AppendItem("ShowDrawerTools", 10302);
+m[2]->AppendItem("PostScript (EPS)", 10305);
+AppendMenu(m[2]);
+
+MainWin()->SetSize(360,130);
+zoom = new PIPixmap(MainWin(), "Zoom", 90, 90, 5, 5);
+zoom->SetBinding(PIBK_elastic,PIBK_elastic,PIBK_elastic,PIBK_elastic);
+// zoom->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_elastic,PIBK_fixed);
+cmapv = new PICMapView(MainWin(), "CMapView", 350, 25, 5, 100);
+cmapv->SetBinding(PIBK_elastic,PIBK_elastic,PIBK_elastic,PIBK_elastic);
+// cmapv->SetBinding(PIBK_fixed,PIBK_free,PIBK_fixed,PIBK_free);
+// Creation d' zone texte multiligne
+txt = new PIText(MainWin(), "mltext", 250, 90, 105, 5);
+txt->SetBinding(PIBK_elastic,PIBK_elastic,PIBK_elastic,PIBK_elastic);
+// txt->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_fixed,PIBK_free);
+txt->SetMutiLineMode(true);
+txt->SetTextEditable(false);
+txt->SetText("");
+
+// On alloue les couleurs de la MIDAS_ITT
+ cout << " Allocating MIDAS ITT colors in midas_cmap  NCol=" << rgb_ncol << endl;
+PIColor col;  //  Les couleurs PI sont des entiers de 0 a 65535 (16 bits)
+for(int kc=0; kc<rgb_ncol; kc++) {
+  col.red   = (short unsigned)(rgb_r[kc]*65535); 
+  col.green = (short unsigned)(rgb_g[kc]*65535); 
+  col.blue  = (short unsigned)(rgb_b[kc]*65535); 
+  midas_cmap.AllocColor(col, kc);
+  }
+SetReady();
+}
+
+/* --Methode-- */
+PITApp::~PITApp()
+{
+for(int i=0; i<3; i++)  delete m[i]; 
+delete txt;
+delete cmapv;
+delete zoom;
+}  
+
+
+static int nbwin = 0;
+static int numpsf = 0;
+static int fgswcol = 0;
+
+static double fsinc(double x) {if ( (x>-1.e-8) && (x<1.e-8) ) return(0.); else return (sin(x)/x);}
+
+/* --Methode-- */
+void PITApp::Process(PIMessage msg, PIMsgHandler* sender, void* data)
+{
+char strg[64];
+int i,j;
+
+if ( ( ModMsg(msg) == PIMsg_Active) || (ModMsg(msg) == PIMsg_Close) ) {
+  PIWdg *sndw;
+  sndw = (PIWdg *)sender;      
+  if (sndw->kind() ==  PIWindow::ClassId)  {
+    if (ModMsg(msg) == PIMsg_Close)  { 
+      printf("PITApp::Process()/Debug : Closing Window %lx \n", (long)sender);
+      delete (PIWindow *)sender;  
+      mCurW = NULL; }
+    else  mCurW = (PIWindow *)sender;
+  }
+}
+else
+  {
+  switch(UserMsg(msg))
+    {
+
+// --------- 1er menu ----------
+    case 10101:     
+      txt->SetText("pitgr: PI Graphics Tests \n * 2-D graphics \n * 3-D Graphics \n Image display ");
+      break;
+
+    case 10110 :
+      if (mCurW)  { mCurW->Hide();  delete mCurW;}
+      mCurW = NULL;
+      break;
+
+    case 10150:          // Sortie d'application
+      Stop();
+      break;
+
+
+// ----------  3eme menu --------
+    case 10301 :
+      PIImgTools::ShowPIImgTools();
+      break;
+    case 10302 :
+      PIDrwTools::ShowPIDrwTools();
+      break;
+    case 10305 :
+      if(mCurW) {
+        char buff[64];
+        sprintf(buff, "pigr_%d.eps", numpsf);        numpsf++;
+        printf("Creating EPS File %s (Encapsulated PostScript) \n", buff);
+        PSFile *mps;
+	mps = new PSFile(buff);
+	mCurW->PSPrint(mps,0,0);
+	delete mps;
+        }
+      break;
+
+// ----------  2eme menu --------
+
+    case 10201 :        //  Trace de la fonction sin(x)/x
+      {
+      SetBusy();    // souris -> montre 
+      txt->SetText("PIScDrawWdg Creation\n Sin(x)/x \n Button 1 -> Coord \n  Button 2 Zoom \n <Alt>O <Alt>V \n Try DrawerTools");
+
+      PIFuncDrawer* mfd = new PIFuncDrawer(fsinc);
+      mfd->GetGraphicAtt().SetColAtt(PI_Gold);
+      mfd->GetGraphicAtt().SetLineAtt(PI_NormalLine);
+      nbwin++; sprintf(strg,"2D Graphics (PI W %d)", nbwin);
+      PIWindow* wp = new PIWindow(this, strg, PIWK_normal,  300, 300, 150, 150);
+      wp->SetAutoDelChilds(true);
+      PIScDrawWdg* scd = new PIScDrawWdg(wp, "scwdg-sinc", 300, 300, 0, 0);
+      scd->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_fixed, PIBK_fixed);
+      scd->SetLimits(0.1, 30., -1., 1.);
+      scd->AddScDrawer(mfd,true);
+      PIGraphicAtt gatt;
+      gatt.SetColAtt(PI_Red);
+      scd->BaseDrawer()->ElDrwMgr().ElAddText(2., 0.8, "Y = Sin(x)/x", gatt, 0);
+
+      scd->SetTitles(" --- PIFuncDrawer (Sin(x)/x) --- ","");
+      wp->Show();    // On affiche  la fenetre 
+      SetReady();    //  souris->pointeur , on n'est plus occupe
+      }
+      break;
+
+
+    case 10202 :    // Trace Test de PIYfXDrawer
+      {
+      SetBusy();    // souris -> montre 
+      txt->SetText("PIScDrawWdg Creation\n PIYfXDrawer \n Button 1 -> Coord \n  Button 2 Zoom \n <Alt>O <Alt>V \n Try DrawerTools");
+
+      float* vpx = new float[30]; 
+      float* vpy = new float[30]; 
+      int i;   double x;
+      for(i=0; i<30; i++) { x = 8.*i/30;  vpx[i] = x;  vpy[i] = 3*cos(x)+2*sin(x); }
+      PIYfXDrawer* mxyd = new   PIYfXDrawer( new P1DAdapter<float>(vpx, 30, true), 
+                                            new P1DAdapter<float>(vpy, 30, true), true); 
+      mxyd->GetGraphicAtt().SetColAtt(PI_Red);
+      mxyd->GetGraphicAtt().SetMarkerAtt(7, PI_FTriangleMarker);
+
+      nbwin++; sprintf(strg,"2D Graphics (PI W %d)", nbwin);
+      PIWindow* awp = new PIWindow(this, strg, PIWK_normal, 300, 300, 300, 300);
+      PIScDrawWdg* scd = new PIScDrawWdg(awp, "scwdg-YfX", 300, 300, 0, 0);
+      scd->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_fixed, PIBK_fixed);
+      scd->AddScDrawer(mxyd,true);
+      scd->SetTitles(" --- PIYfXDrawer (3*cons(x)+2*sin(x)) --- ","");
+      awp->SetAutoDelChilds(true);
+      awp->Show();
+      SetReady();
+      }
+      break;
+
+    case 10203 :    // FunDrawer + PIYfXDrawer
+      {
+      SetBusy();    // souris -> montre 
+      txt->SetText("PIScDrawWdg Creation\n PIYfXDrawer + FuncDrawer(Sin(x)/x) \n Button 1 -> Coord \n  Button 2 Zoom \n <Alt>O <Alt>V \n Try DrawerTools");
+
+      float* vpx = new float[30]; 
+      float* vpy = new float[30]; 
+      int i;   double x;
+      for(i=0; i<30; i++) { x = 8.*i/30;  vpx[i] = x;  vpy[i] = 3*cos(x)+2*sin(x); }
+      PIYfXDrawer* mxyd = new   PIYfXDrawer( new P1DAdapter<float>(vpx, 30, true), 
+                                             new P1DAdapter<float>(vpy, 30, true), true); 
+
+      mxyd->GetGraphicAtt().SetColAtt(PI_Magenta);
+      mxyd->GetGraphicAtt().SetMarkerAtt(7, PI_FBoxMarker);
+
+      PIFuncDrawer* mfd = new PIFuncDrawer(fsinc);
+      mfd->GetGraphicAtt().SetColAtt(PI_Blue);
+      mfd->GetGraphicAtt().SetLineAtt(PI_NormalLine);
+
+      nbwin++; sprintf(strg,"2D Graphics (PI W %d)", nbwin);
+      PIWindow* awp = new PIWindow(this, strg, PIWK_normal, 400, 400, 300, 300);
+      PIScDrawWdg* scd = new PIScDrawWdg(awp, "scwdg-YfX", 400, 400, 0, 0);
+      scd->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_fixed, PIBK_fixed);
+      scd->AddScDrawer(mxyd,true);
+      scd->AddScDrawer(mfd,true);
+      scd->SetTitles(" --- PIYfXDrawer + PIFuncDrawer --- ","");
+      awp->SetAutoDelChilds(true);
+      awp->Show();
+
+      SetReady();
+      }
+      break;
+
+    case 10207 :
+      {
+      SetBusy();    // souris -> montre 
+      txt->SetText("PIImage Creation\n Image Display \n Button 1 -> Coord/value \n  Button 2 Select Rectangle \n Butt on 3 Move \n <Alt>O <Alt>V <Alt>C \n Try ImageTools");
+ 
+      int sx=400, sy=600;
+      printf(" Creating Image (%dx%d) ... ", sx, sy);
+      float* img = new float[sx*sy];
+      int i, j;
+      for(i=0;i<sx;i++) {
+        double x = (i-sx/2.)/(sx/5.);
+        for(j=0;j<sy;j++) {
+          double y = (j-sy/2.)/(sy/5.);
+          y = -0.5*(x*x+y*y);
+          if(y<-80.) y=0.;
+          img[j*sx+i] = 1000.*exp(-0.5*(x*x+y*y));
+        }
+      }
+      printf("  >> OK \n");
+      nbwin++; sprintf(strg,"Image (PI W %d)", nbwin);
+      PIWindow* awp = new PIWindow(this, strg, PIWK_normal, sx, sy, 300, 300);
+      PIImage * pii = new PIImage(awp, "fitsimage", sx, sy, 0, 0);
+      pii->SetBinding(PIBK_fixed, PIBK_fixed, PIBK_fixed, PIBK_fixed);
+      pii->SetZoomWin(zoom, false);
+      pii->SetCMapWin(cmapv, false);
+      pii->ShowCursor(true);
+      pii->SetColMap(&midas_cmap, false);
+      awp->SetAutoDelChilds(true);
+      awp->Show();
+      pii->SetImage(new P2DAdapter<float>(img, sx, sy, true), true);
+      SetReady();
+      }
+      break;
+
+    case 10206 :
+      {
+      SetBusy();    // souris -> montre 
+      txt->SetText("PIImage Creation\n Image Display \n Button 1 -> Coord/value \n  Button 2 Select Rectangle \n Butt on 3 Move \n <Alt>O <Alt>V <Alt>C \n Try ImageTools");
+ 
+      int sx, sy;
+      sx = 400; 
+      sy = 600;
+      printf(" Creating Image (%dx%d) ... ", sx, sy);
+      float* img = new float[sx*sy];
+      int i, j, k, kk, i0, j0;
+      double lamp, amp,x,y;
+      for(k=0; k<sx*sy; k++)   img[k] = 1000.+(random()%200-100);
+//   On genere 500 etoiles
+      for(k=0; k<500; k++) {
+        i0 = 20+random()%(sx-20);
+        j0 = 20+random()%(sy-20);
+        lamp = 2.0+0.012*(random()%100);
+        amp = pow(10., lamp);
+//        if (k%5 == 0)  printf(" DBG %d %d - %g \n", i0, j0, flux);
+        for(i=i0-15; i<i0+15; i++) {
+          if(i<0 || i>=sx) continue;
+          for(j=j0-15; j<j0+15; j++) {
+            if(j<0 || j>=sy) continue;
+            x = i-i0;  y = j-j0;
+            kk = j*sx+i;
+            img[kk] += amp*exp(-(x*x)/7.-(y*y)/8.);
+            }
+	}
+      }
+      printf("  >> OK \n");
+     
+      nbwin++; sprintf(strg,"Image (PI W %d)", nbwin);
+      PIWindow* awp = new PIWindow(this, strg, PIWK_normal, sx, sy, 300, 300);
+      PIImage * pii = new PIImage(awp, "fitsimage", sx, sy, 0, 0);
+      pii->SetBinding(PIBK_fixed, PIBK_fixed, PIBK_fixed, PIBK_fixed);
+      pii->SetZoomWin(zoom, false);
+      pii->SetCMapWin(cmapv, false);
+      pii->ShowCursor(true);
+      pii->SetColMap(&midas_cmap, false);
+      awp->SetAutoDelChilds(true);
+      awp->Show();
+      pii->SetImage(new P2DAdapter<float>(img, sx, sy, true), true);
+      SetReady();
+      }
+      break;
+
+
+//    Dessins 3D  
+    case 10204:         
+      {
+      SetBusy();    // souris -> montre 
+      txt->SetText("PIDraw3DWdg Creation\n 3-D Surf Display \n Button 1 \n (Shift) Button 2 Rotate \n Button Zoom \n <Alt>O <Alt>V \n Try DrawerTools");
+
+      printf(" Creating Matrix 80x60  ... ");
+      float* tf = new float[60*80];
+      int i,j,k;
+      double xp,yp,rp;
+      for(i=0; i<80; i++)
+        for(j=0; j<60; j++) { 
+           xp = i-30;   yp = j-20;
+           rp = (xp*xp)/16.+(yp*yp)/9.;
+           tf[j*80+i] = 10.*exp(-rp);
+           xp = i-50;   yp = j-28;
+           rp = (xp*xp)/9.+(yp*yp)/9.;
+           tf[j*80+i] += 4.*exp(-rp);
+        }
+      printf("  >> OK \n");
+
+      nbwin++; sprintf(strg,"3D Surf (PI W %d)", nbwin);
+      PIWindow* awp = new PIWindow(this, strg, PIWK_normal, 500, 500, 200, 200);
+      PISurfaceDrawer* sd = new PISurfaceDrawer(new P2DAdapter<float>(tf, 80, 60, true), true, true, true);
+      PIDraw3DWdg* drw3 = new PIDraw3DWdg(awp, "ex3ddrw", 500, 500, 0, 0);
+      drw3->SetBinding(PIBK_fixed , PIBK_fixed , PIBK_fixed, PIBK_fixed);
+      drw3->AddDrawer3D(sd, false);
+      drw3->SetTitles(" --- PISurfaceDrawer (80x60) --- ","");
+      awp->SetAutoDelChilds(true);
+      awp->Show();
+      SetReady();
+      }
+      break;
+
+    case 10205:         
+      {
+      SetBusy();    // souris -> montre 
+      txt->SetText("PIDraw3DWdg Creation\n 3-D Surf Display \n Button 1 \n (Shift) Button 2 Rotate \n Button Zoom \n <Alt>O <Alt>V \n Try DrawerTools");
+
+      printf(" Creating Matrix 50x50  ... ");
+      float * tf = new float[2500];
+      int i,j;
+      double xp,yp,rp;
+      for(i=0; i<50; i++)
+        for(j=0; j<50; j++) { 
+           xp = i-15;   yp = j-25;
+           rp = (xp*xp)/16.+(yp*yp)/16.;
+           tf[j*50+i] = 11.*exp(-rp);
+           xp = i-35;   yp = j-15;
+           rp = (xp*xp)/9.+(yp*yp)/9.;
+           tf[j*50+i] += 3.*exp(-rp);
+           xp = i-45;   yp = j-40;
+           rp = (xp*xp)/10.+(yp*yp)/20.;
+           tf[j*50+i] += 6.*exp(-rp);
+        }
+      printf("  >> OK \n");
+
+      nbwin++; sprintf(strg,"PI W# %d 3D Surf", nbwin);
+      PIWindow* awp = new PIWindow(this, strg, PIWK_normal, 500, 500, 200, 200);
+      PISurfaceDrawer* sd = new PISurfaceDrawer(new P2DAdapter<float>(tf, 50, 50, true), true, true, true);
+      if (fgswcol%3 == 0) sd->GetGraphicAtt().SetColMapId(CMAP_COLRJ32);
+      else if (fgswcol%3 == 1) sd->GetGraphicAtt().SetColMapId(CMAP_COLBR32);
+      else sd->GetGraphicAtt().SetColMapId(CMAP_COLRV32);
+      fgswcol++;
+      PIDraw3DWdg* drw3 = new PIDraw3DWdg(awp, "ex3ddrw", 600, 600, 0, 0);
+      drw3->SetBinding(PIBK_fixed , PIBK_fixed , PIBK_fixed, PIBK_fixed);
+      drw3->AddDrawer3D(sd, false);
+      drw3->SetTitles(" --- PISurfaceDrawer (50x50) --- ","");
+      awp->SetAutoDelChilds(true);
+      awp->Show();
+      SetReady();
+      }
+      break;
+
+    default :
+//      printf("PITApp::Process() Msg= %d (%d - %d)??? \n", 
+//            (int)msg, (int)UserMsg(msg),(int)ModMsg(msg));
+     break;
+    }
+  }
+return;
+}
+
+
+// ................................................................
+//                   programme principal 
+// ................................................................
+
+
+
+int main(int narg, char *arg[])
+{
+
+if ( (narg < 2) || (strcmp(arg[1],"-h") == 0) ) {
+  printf("midasitt : MIDAS ITT color table test  \n");
+  printf("  Usage : midasitt MIDAS_ITT_File [Xt options] \n");
+  return(0);
+  }
+
+
+string midas_itt_file = arg[1];
+
+cout << " Reading RGB values from MIDAS_ITT file " << (string)arg[1];
+FILE * fip = fopen(arg[1], "r");
+if (fip == NULL) {
+  cout << "midasitt ERROR opening file " << (string)arg[1] << endl;
+  return(2);
+  }
+
+char lineb[512];
+int nlread = 0;
+int numl = 0;
+while ( (fgets(lineb,512,fip) != NULL) && (nlread < 512) ) {
+  lineb[9] = '\0';
+  numl = atoi(lineb);
+  if (numl != (nlread+1) ) continue;
+  lineb[25] = '\0';
+  rgb_r[nlread] = atof(lineb+14);
+  lineb[41] = '\0';
+  rgb_g[nlread] = atof(lineb+30);
+  lineb[60] = '\0';
+  rgb_b[nlread] = atof(lineb+46);
+  nlread++;
+}
+
+fclose(fip);
+if (nlread != 256) {
+  cout << "midasitt ERROR number of lines != 256  " << nlread << endl;
+  return(3);
+}
+ rgb_ncol = nlread;
+
+int kl;
+cout << "MIDAS_ITT: RGB - Red      ( File" << (string)arg[1] << ")" << endl;
+for(kl=0; kl<rgb_ncol; kl++)  { 
+    cout << rgb_r[kl] << ", " ;
+    if ((kl%8) == 0)  cout << endl;
+}
+cout << endl;
+cout << "MIDAS_ITT: RGB - Green    ( File" << (string)arg[1] << ")" << endl;
+for(kl=0; kl<rgb_ncol; kl++)  { 
+    cout << rgb_g[kl] << ", " ;
+    if ((kl%8) == 0)  cout << endl;
+}
+cout << endl;
+cout << "MIDAS_ITT: RGB - Blue    ( File" << (string)arg[1] << ")" << endl;
+for(kl=0; kl<rgb_ncol; kl++)  { 
+    cout << rgb_b[kl] << ", " ;
+    if ((kl%8) == 0)  cout << endl;
+}
+
+cout << "\n \n" << endl;
+
+
+PITApp* app = new PITApp(narg, arg);
+int sx,sy;
+PIApplicationPrefCompSize(sx, sy);
+printf("##### pit-main() PrefCompSize= %d %d ##### \n", sx, sy);
+PIApplicationScreenSize(sx, sy);
+printf("##### pit-main() ScreenSize= %d %d ##### \n", sx, sy);
+PIColorMap* cmap = new PIColorMap(CMAP_GREY32);
+printf("##### pit-main() NbTotColors=%d Already Allocated= %d ##### \n", 
+       cmap->TotNbColors(), cmap->NbAllocColors()); 
+
+
+app->Run();
+
+delete cmap;
+delete app;
+exit(0);
+}
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/Tests/pilinetst.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/Tests/pilinetst.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/Tests/pilinetst.cc	(revision 2309)
@@ -0,0 +1,396 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+
+#include <iostream.h>
+
+#include "pisysdep.h"
+#include PIAPP_H
+#include PIWIN_H 
+#include PIMENU_H 
+#include PISTDWDG_H 
+#include PIBWDG_H
+
+/*  Composante graphique de trace de chaine de lignes et de fleches */
+
+// ---- Declaration de la classe LineDrawWdg --------
+class LineDrawWdg : public PIBaseWdg
+{
+public:
+// Les methodes ...
+
+                  LineDrawWdg(PIContainerGen *par, char *nom,
+                         int sx=10, int sy=10, int px=0, int py=0);
+  virtual         ~LineDrawWdg();
+
+// Traitement des evenements   
+//  virtual void   Resize();
+  virtual void   Draw(PIGraphic* g, int x0, int y0, int dx, int dy);
+
+  virtual void   But1Press(int x, int y);
+  virtual void   Keyboard(int key, PIKeyModifier kmod);
+
+protected:
+  PIColors mCol;
+  int mArrSz;
+};
+
+// ---- Declaration de la classe ArrowDrawWdg --------
+class ArrowDrawWdg : public LineDrawWdg
+{
+public:
+// Les methodes ...
+
+                  ArrowDrawWdg(PIContainerGen *par, char *nom,
+                         int sx=10, int sy=10, int px=0, int py=0);
+  virtual         ~ArrowDrawWdg();
+
+// Traitement des evenements   
+//  virtual void   Resize();
+  virtual void   Draw(PIGraphic* g, int x0, int y0, int dx, int dy);
+
+  //  virtual void   But1Press(int x, int y);
+  //  virtual void   Keyboard(int key, PIKeyModifier kmod);
+
+};
+
+
+
+/* ........................................................... */
+/*     Classe LineDrawWdg (Implementation des methodes)             */
+/* ........................................................... */
+
+/* --Methode-- */
+LineDrawWdg::LineDrawWdg(PIContainerGen *par, char *nom,
+                       int sx, int sy, int px, int py) 
+: PIBaseWdg(par, nom, sx, sy, px, py)
+
+{
+  mCol = PI_Black;
+  mArrSz = 7;
+  ActivateKeyboard();
+  ActivateButton(1);
+}
+
+/* --Methode-- */
+LineDrawWdg::~LineDrawWdg()
+{
+}
+ 
+
+/* --Methode-- */
+void LineDrawWdg::Draw(PIGraphicGen* g, int /*x0*/, int /*y0*/, int /*dx*/, int /*dy*/)
+{
+PILineAtt latt;
+
+if (g->kind() != PI_PSFileGraphics ) EraseWindow();
+g->SelForeground(mCol);
+
+g->SelLine(PI_NormalLine);
+g->DrawLine(10,20, 160, 20);
+g->DrawString(200,20,"PI_NormalLine");
+
+g->SelLine(PI_ThinLine);
+g->DrawLine(10,40, 160, 40);
+g->DrawString(200,40,"PI_ThinLine");
+
+g->SelLine(PI_ThickLine);
+g->DrawLine(10,60, 160, 60);
+g->DrawString(200,60,"PI_ThickLine");
+
+latt = PILineAtt(6);
+g->SelLine(latt);
+g->DrawLine(10,80, 160, 80);
+g->DrawString(200,80,"PILineAtt(6)");
+
+g->SelLine(PI_DashedLine);
+g->DrawLine(10,100, 160, 100);
+g->DrawString(200,100,"PI_DashedLine");
+
+g->SelLine(PI_DottedLine);
+g->DrawLine(10,120, 160, 120);
+g->DrawString(200,120,"PI_DottedLine");
+
+g->SelLine(PI_DashDottedLine);
+g->DrawLine(10,140, 160, 140);
+g->DrawString(200,140,"PI_DashDottedLine");
+
+latt = PILineAtt(3,PI_LineDashDotted);
+g->SelLine(latt);
+g->DrawLine(10,160, 160, 160);
+g->DrawString(200,160,"PILineAtt(3,PI_LineDashDotted)");
+
+return;
+}
+
+/* --Methode-- */
+void LineDrawWdg::Keyboard(int key, PIKeyModifier kmod)
+{
+
+bool fgref = true;
+switch (key) {
+ case 'd':
+   mCol = PI_Black;
+   break;
+ case 'r':
+   mCol = PI_Red;
+   break;
+ case 'b':
+   mCol = PI_Blue;
+   break;
+ case 'g':
+   mCol = PI_Green;
+   break;
+ case 'y':
+   mCol = PI_Yellow;
+   break;
+ case 'm':
+   mCol = PI_Magenta;
+   break;
+ case '1':
+   mArrSz = 5;
+   break;
+ case '2':
+   mArrSz = 6;
+   break;
+ case '3':
+   mArrSz = 7;
+   break;
+ case '4':
+   mArrSz = 8;
+   break;
+ case '5':
+   mArrSz = 9;
+   break;
+ case '6':
+   mArrSz = 10;
+   break;
+   
+ default:
+   fgref = false;
+}
+
+if (fgref) Refresh(); 
+
+return;
+}
+/* --Methode-- */
+void LineDrawWdg::But1Press(int x, int y)
+{
+  Send(Msg(), PIMsg_Active);
+}
+
+
+/* ........................................................... */
+/*     Classe ArrowDrawWdg (Implementation des methodes)             */
+/* ........................................................... */
+
+/* --Methode-- */
+ArrowDrawWdg::ArrowDrawWdg(PIContainerGen *par, char *nom,
+                       int sx, int sy, int px, int py) 
+: LineDrawWdg(par, nom, sx, sy, px, py)
+
+{
+}
+
+/* --Methode-- */
+ArrowDrawWdg::~ArrowDrawWdg()
+{
+}
+ 
+
+/* --Methode-- */
+void ArrowDrawWdg::Draw(PIGraphicGen* g, int /*x0*/, int /*y0*/, int /*dx*/, int /*dy*/)
+{
+PILineAtt latt;
+ double x1[12], x2[12];
+ double y1[12], y2[12];
+ double x0[6]={70,210,350,70,210,350};
+ double y0[6]={70,70,70,210,210,210};
+ double r1=15, r2=60;
+ PILineTypes lt[6] = {PI_NormalLine, PI_ThinLine, PI_ThinLine,
+		      PI_NormalLine, PI_ThinLine, PI_ThinLine};
+ PIArrowMarker amk[6] = 
+   {PI_BasicArrowMarker, PI_BasicArrowMarker, PI_TriangleArrowMarker,  
+    PI_FTriangleArrowMarker, PI_ArrowShapedArrowMarker, PI_FArrowShapedArrowMarker};
+
+if (g->kind() != PI_PSFileGraphics ) EraseWindow();
+g->SelForeground(mCol);
+int i,j,k;
+for(k=0; k<6; k++) {
+  g->SelLine(lt[k]);
+  g->SelArrowMarker(mArrSz,amk[k]);
+  for(i=0; i<12; i++) {
+    x1[i] = x0[k] + cos(i*M_PI/6.)*r1; 
+    x2[i] = x0[k] + cos(i*M_PI/6.)*r2; 
+    y1[i] = y0[k] + sin(i*M_PI/6.)*r1; 
+    y2[i] = y0[k] + sin(i*M_PI/6.)*r2; 
+    if (k != 1)  g->DrawArrowMarker(x1[i], y1[i], x2[i], y2[i], true);
+    else  g->DrawArrowMarker(x2[i], y2[i], x1[i], y1[i], true);
+  }
+}
+
+g->DrawArrowMarker(10, 300, 150, 300, true);
+g->DrawString(200, 300, " ArrowDrawWdg");
+return;
+}
+
+/* ........................................................... */
+/*                       Classe PITApp                         */
+/* ........................................................... */
+class PITApp : public PIApplication {
+public:
+     PITApp(int narg=0, char* arg[]=NULL);
+     ~PITApp();
+     virtual void   Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+private :
+  PIMenu* m[2];
+  PIText* txt;
+  PIWindow* mcurwin;
+  PSFile *mPS;
+};
+
+
+/* --Methode-- */
+PITApp::PITApp(int narg, char* arg[])
+: PIApplication(300, 100, narg, arg)
+{
+
+//  Menus, les numeros ds AppendItem sont les numeros de messages
+//  qui seront passes a Process() et permettent d'identifier l'action
+
+//  Creation du premier menu  
+
+m[0] = new PIMenu(Menubar(),"Actions");
+m[0]->AppendItem("LineDrawWdg", 10101);
+m[0]->AppendItem("ArrowDrawWdg", 10102);
+m[0]->AppendItem("->eps", 10111);
+m[0]->AppendItem("->ps", 10112);
+m[0]->AppendItem("Exit", 10105);
+// On accroche le menu au Menubar
+AppendMenu(m[0]);
+
+
+// Creation d' zone texte multiligne
+txt = new PIText(MainWin(), "mltext", true, true, 290, 90, 5, 5);
+txt->SetBinding(PIBK_elastic,PIBK_elastic,PIBK_elastic,PIBK_elastic);
+// txt->SetMutiLineMode(true);
+txt->SetTextEditable(false);
+txt->SetText("");
+txt->SetText("LineDrawWdg/Keyboard: d,r,g,b,y, - 1,2...,6 \n (black,red,blue,green,yellow,magenta - Arrow Size) ");
+
+mcurwin = NULL;
+mPS = new PSFile("piline.ps", PI_Auto);
+SetReady();
+}
+
+/* --Methode-- */
+PITApp::~PITApp()
+{
+delete m[0]; 
+delete txt;
+delete mPS;
+}  
+
+static int numpsf = 0;
+static int nbwin = 0;
+/* --Methode-- */
+void PITApp::Process(PIMessage msg, PIMsgHandler* sender, void* /*data*/)
+{
+
+char strg[256];
+
+// Gestion des actions en fonctions des messages
+
+if ( ( ModMsg(msg) == PIMsg_Active) || (ModMsg(msg) == PIMsg_Close) ) {
+  PIWdg *sndw;
+  sndw = (PIWdg *)sender;      
+  if (sndw->kind() ==  PIWindow::ClassId)  {
+    if (ModMsg(msg) == PIMsg_Close)  { 
+      delete (PIWindow *)sender;  
+      mcurwin = NULL;  
+      }
+    else mcurwin = (PIWindow *)sender;
+  }
+}
+
+else switch(UserMsg(msg))    {
+
+    case 10101: // Creation d'un LineDrawWdg
+      {
+      nbwin++;
+      sprintf(strg, "Creation LineDrawWdg   \n Fenetre No %d ", nbwin);
+      sprintf(strg,"LineDraw - %d", nbwin);
+      PIWindow* wp = new PIWindow(this, strg, PIWK_normal,  350, 250, 150, 150);
+      wp->SetAutoDelChilds(true);
+      LineDrawWdg* exb  = new LineDrawWdg(wp, "LineDraw", 350, 250, 0, 0);
+      exb->SetBinding(PIBK_fixed,PIBK_elastic,PIBK_elastic,PIBK_elastic);
+      wp->SetUserData(exb);
+      wp->Show();
+      }
+    break;
+
+    case 10102: // Creation d'un ArrowDrawWdg
+      {
+      nbwin++;
+      sprintf(strg, "Creation ArrowDrawWdg   \n Fenetre No %d ", nbwin);
+      sprintf(strg,"ArrowDraw - %d", nbwin);
+      PIWindow* wp = new PIWindow(this, strg, PIWK_normal,  420, 350, 150, 150);
+      wp->SetAutoDelChilds(true);
+      ArrowDrawWdg* exb  = new ArrowDrawWdg(wp, "ArrowDraw", 420, 350, 0, 0);
+      exb->SetBinding(PIBK_fixed,PIBK_elastic,PIBK_elastic,PIBK_elastic);
+      wp->SetUserData(exb);
+      wp->Show();
+      }
+    break;
+
+
+    case 10111:          // -> eps
+      if (mcurwin) {
+        char buff[64];
+        sprintf(buff, "piline_%d.eps", numpsf);        numpsf++;
+        printf("Creating EPS File %s (Encapsulated PostScript) \n", buff);
+        PSFile *mps;
+	mps = new PSFile(buff);
+	mcurwin->PSPrint(mps,0,0);
+	delete mps;
+        }
+      break;    
+    
+    case 10112:          // -> eps
+      if (mcurwin) {
+        printf("Current Window to Postscript file piline.ps \n");
+	mcurwin->PSPrint(mPS,0,0);
+        }
+      break;        
+
+    case 10105:          // Sortie d'application
+      Stop();
+      break;
+
+  }
+return;
+}
+
+
+// ................................................................
+//                   programme principal 
+// ................................................................
+
+int main(int narg, char *arg[])
+{
+if ( (narg > 1) && (strcmp(arg[1],"-h") == 0) ) {
+  printf("pilinetst : LineDrawWdg  test \n");
+  printf("  Usage : pilinetst [Xt options] \n");
+  }
+//  Creation de l'objet application et appel de Run()
+PITApp* app = new PITApp(narg, arg);
+// puts("appel de Application.Run() ... ");
+app->Run();
+
+delete app;
+exit(0);
+}
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/Tests/pist.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/Tests/pist.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/Tests/pist.cc	(revision 2309)
@@ -0,0 +1,939 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <iostream.h>
+
+#include "pisysdep.h"
+#include PIAPP_H
+#include PIWIN_H 
+#include PIMENU_H 
+#include PISTDWDG_H 
+#include PIBWDG_H
+
+/*  Composante graphique de trace de chaine de caracteres  */
+
+// ---- Declaration de la classe StringDrawWdg --------
+class StringDrawWdg : public PIBaseWdg
+{
+public:
+// Les methodes ...
+
+                  StringDrawWdg(PIContainerGen *par, char *nom,
+                         int sx=10, int sy=10, int px=0, int py=0);
+  virtual         ~StringDrawWdg();
+
+// Traitement des evenements   
+//  virtual void   Resize();
+  virtual void   Draw(PIGraphic* g, int x0, int y0, int dx, int dy);
+
+  virtual void   But1Press(int x, int y);
+  virtual void   Keyboard(int key, PIKeyModifier kmod);
+
+protected:
+  PIFontAtt mFAtt,mSFAtt;
+  PIFontSize mFSize, mSFSize;
+  PIFontName mFName, mSFName;
+  int mSL[10], mSH[10];
+};
+
+
+// ---- Declaration de la classe StringDrawWdg --------
+class StringPosDrawWdg : public StringDrawWdg
+{
+public:
+// Les methodes ...
+
+                  StringPosDrawWdg(PIContainerGen *par, char *nom,
+                         int sx=10, int sy=10, int px=0, int py=0);
+  virtual         ~StringPosDrawWdg();
+  inline void     SetTextDirection(PIGrTextDirection txtdir) { mTxtDir = txtdir; }
+
+// Traitement des evenements   
+//  virtual void   Resize();
+  virtual void   Draw(PIGraphic* g, int x0, int y0, int dx, int dy);
+
+protected:
+  PIGrTextDirection mTxtDir;  
+};
+
+// ---- Declaration de la classe CompStringDrawWdg --------
+class CompStringDrawWdg : public StringDrawWdg
+{
+public:
+// Les methodes ...
+
+                  CompStringDrawWdg(PIContainerGen *par, char *nom,
+				    int sx=10, int sy=10, int px=0, int py=0);
+  virtual         ~CompStringDrawWdg();
+// Traitement des evenements   
+//  virtual void   Resize();
+  virtual void   Draw(PIGraphic* g, int x0, int y0, int dx, int dy);
+
+protected:
+};
+
+
+/* ........................................................... */
+/*     Classe StringDrawWdg (Implementation des methodes)             */
+/* ........................................................... */
+
+/* --Methode-- */
+StringDrawWdg::StringDrawWdg(PIContainerGen *par, char *nom,
+                       int sx, int sy, int px, int py) 
+: PIBaseWdg(par, nom, sx, sy, px, py)
+
+{
+  mFAtt = PI_RomanFont;
+  mFSize = PI_NormalSizeFont;
+  mSFAtt = PI_NotDefFontAtt;
+  mSFSize = PI_NotDefFontSize;
+  mSFName = mFName = PI_CourierFont;
+  for(int k=0; k<10; k++) 
+    mSL[k] = mSH[k] = 0;
+  ActivateKeyboard();
+  ActivateButton(1);
+}
+
+/* --Methode-- */
+StringDrawWdg::~StringDrawWdg()
+{
+}
+ 
+
+/* --Methode-- */
+void StringDrawWdg::Draw(PIGraphicGen* g, int /*x0*/, int /*y0*/, int /*dx*/, int /*dy*/)
+{
+PIFontAtt att[4] = { PI_RomanFont, PI_BoldFont, PI_ItalicFont, PI_BoldItalicFont};
+PIFontSize fsz[5] = { PI_TinySizeFont, PI_SmallSizeFont, PI_NormalSizeFont, 
+		      PI_LargeSizeFont, PI_HugeSizeFont };
+PIFontName fn[4] = { PI_CourierFont, PI_HelveticaFont, 
+		     PI_TimesFont, PI_SymbolFont};
+char * fnstr[4] = { "Courier-Font", "Helvetica-Font", 
+		     "Times-Font", "Symbol-Font"};
+char * attstr[4] = { "RomanFont" , "BoldFont", "ItalicFont", "BoldItalicFont"};
+char * fszstr[5] = { "TinySizeFont", "SmallSizeFont", "NormalSizeFont", 
+		      "LargeSizeFont", "HugeSizeFont" };
+
+if (g->kind() != PI_PSFileGraphics ) EraseWindow();
+
+
+int ia=0, js=0;
+int k;
+for(k=0; k<4; k++)
+  if (att[k] == mFAtt)  {ia = k; break; }
+for(k=0; k<5; k++)
+  if (fsz[k] == mFSize)  {js = k; break; }
+
+if ((mFSize != mSFSize) || (mFAtt != mSFAtt))
+  for(k=0; k<10; k++)
+    mSL[k] = mSH[k] = 0;
+PIFont f(16, PI_DefaultFont);
+g->SelFont(f);
+  g->SelForeground(PI_Black);
+g->DrawString(50,24,attstr[ia]);
+g->DrawString(XSize()/2,24,fszstr[js]);
+ int fh,fa,fd;
+ fh = f.GetFontHeight(fa, fd);
+ cout << " FontSize= " << f.GetFontSize() << " FontHeight= " << fh << endl;
+g->DrawFBox(XSize()/2-30, 24-fh+2, fh, fh);
+
+
+g->SelForeground(PI_Black);
+g->SelLine(PI_NormalLine);
+g->DrawBox(4, 4, XSize()-8, YSize()-8);
+
+g->SelForeground(PI_Yellow);
+g->SelLine(PI_ThickLine);
+g->DrawBox(XSize()/4, YSize()/4, XSize()/2, YSize()/2);
+g->SelLine(PI_NormalLine);
+g->DrawBox(XSize()/4+10, YSize()/4+10, XSize()/2-20, YSize()/2-20);
+g->SelLine(PI_ThinLine);
+g->DrawBox(XSize()/4+20, YSize()/4+20, XSize()/2-40, YSize()/2-40);
+
+
+
+int xpos, ypos;
+PIGrCoord asc, desc;
+double sl, sh;
+char * s1 = "0123456789";
+char * s2 = "PI GUI Library";
+
+g->SelLine(PI_NormalLine);
+for(k=0; k<4; k++) {
+  PIFont fx(14,fn[k]);
+  fx.SetFontSz(mFSize);
+  fx.SetFontAtt(mFAtt);
+  g->SelFont(fx);
+  g->SelForeground(PI_Red);
+  xpos = (double)XSize()*0.3;
+  ypos = (double)YSize()*0.2*k+50;
+  g->DrawString(xpos, ypos, fnstr[k]);
+  g->SelForeground(PI_Black);
+  xpos = 20;
+  ypos = (double)YSize()*(0.2*k+0.1)+50;
+  g->DrawString(xpos, ypos, s1);
+  if ((mSL[2*k] == 0) || (mSH[2*k] == 0)) {
+    mSL[2*k] = g->CalcStringWidth(s1);
+    mSH[2*k] = g->GetFontHeight(asc, desc);
+  }
+  sl = mSL[2*k];  sh = mSH[2*k];
+  g->DrawBox(xpos-0.05*sl, ypos-1.*sh, sl*1.1, sh*1.2);
+  xpos = XSize()/2+20;
+  g->SelForeground(PI_Blue);
+  g->DrawString(xpos, ypos, s2);
+  if ((mSL[2*k+1] == 0) || (mSH[2*k+1] == 0)) {
+    mSL[2*k+1] = g->CalcStringWidth(s2);
+    mSH[2*k+1] = g->GetFontHeight(asc, desc);
+  }
+  sl = mSL[2*k+1];  sh = mSH[2*k+1];
+  g->SelForeground(PI_Blue);
+  g->DrawBox(xpos-0.05*sl, ypos-1.*sh, sl*1.1, sh*1.2);
+  xpos = XSize()/2+20;
+}
+
+g->SelForeground(PI_Green);
+g->SelLine(PI_ThinLine);
+for(k=0; k<4; k++) {
+  xpos = 0.2*(k+1)*(double)XSize();
+  ypos = 0.2*(k+1)*(double)YSize();
+  g->DrawLine(xpos, 0, xpos, YSize()-1);
+  g->DrawLine(0, ypos, XSize()-1, ypos);
+}
+return;
+}
+
+/* --Methode-- */
+void StringDrawWdg::Keyboard(int key, PIKeyModifier kmod)
+{
+PIFontName fn[4] = { PI_CourierFont, PI_HelveticaFont, 
+		     PI_TimesFont, PI_SymbolFont};
+
+bool fgref = true;
+switch (key) {
+ case 'r':
+   mFAtt = PI_RomanFont;
+   break;
+ case 'b':
+   mFAtt = PI_BoldFont;
+   break;
+ case 'i':
+   mFAtt = PI_ItalicFont;
+   break;
+ case 'I':
+   mFAtt = PI_BoldItalicFont;
+   break;
+ case 'C':
+   mFName = PI_CourierFont;
+   break;
+ case 'H':
+   mFName = PI_HelveticaFont;
+   break;
+ case 'T':
+   mFName = PI_TimesFont;
+   break;
+ case 'S':
+   mFName = PI_SymbolFont;
+   break;
+ case '1':
+   mFSize = PI_TinySizeFont;
+   break;
+ case '2':
+   mFSize = PI_SmallSizeFont;
+   break;
+ case '3':
+   mFSize = PI_NormalSizeFont;
+   break;
+ case '4':
+   mFSize = PI_LargeSizeFont;
+   break;
+ case '5':
+   mFSize = PI_HugeSizeFont;
+   break;
+ default:
+   fgref = false;
+}
+
+if (fgref) Refresh(); 
+
+return;
+}
+/* --Methode-- */
+void StringDrawWdg::But1Press(int x, int y)
+{
+  Send(Msg(), PIMsg_Active);
+}
+
+/* ........................................................... */
+/*     Classe StringPosDrawWdg (Implementation des methodes)             */
+/* ........................................................... */
+
+/* --Methode-- */
+StringPosDrawWdg::StringPosDrawWdg(PIContainerGen *par, char *nom,
+                       int sx, int sy, int px, int py) 
+: StringDrawWdg(par, nom, sx, sy, px, py)
+
+{
+  mTxtDir = PI_TextDirectionHorizontal;
+}
+
+/* --Methode-- */
+StringPosDrawWdg::~StringPosDrawWdg()
+{
+}
+ 
+
+/* --Methode-- */
+void StringPosDrawWdg::Draw(PIGraphicGen* g, int /*x0*/, int /*y0*/, int /*dx*/, int /*dy*/)
+{
+PIFontAtt att[4] = { PI_RomanFont, PI_BoldFont, PI_ItalicFont, PI_BoldItalicFont};
+PIFontSize fsz[5] = { PI_TinySizeFont, PI_SmallSizeFont, PI_NormalSizeFont, 
+		      PI_LargeSizeFont, PI_HugeSizeFont };
+PIFontName fn[4] = { PI_CourierFont, PI_HelveticaFont, 
+		     PI_TimesFont, PI_SymbolFont};
+char * fnstr[4] = { "Courier-Font", "Helvetica-Font", 
+		     "Times-Font", "Symbol-Font"};
+char * attstr[4] = { "RomanFont" , "BoldFont", "ItalicFont", "BoldItalicFont"};
+char * fszstr[5] = { "TinySizeFont", "SmallSizeFont", "NormalSizeFont", 
+		      "LargeSizeFont", "HugeSizeFont" };
+
+if (g->kind() != PI_PSFileGraphics ) EraseWindow();
+
+
+int ia=0, js=0;
+int k;
+for(k=0; k<4; k++)
+  if (att[k] == mFAtt)  {ia = k; break; }
+for(k=0; k<5; k++)
+  if (fsz[k] == mFSize)  {js = k; break; }
+
+if ((mFSize != mSFSize) || (mFAtt != mSFAtt))
+  for(k=0; k<10; k++)
+    mSL[k] = mSH[k] = 0;
+PIFont f(14, PI_DefaultFont, mFAtt);
+g->SelFont(f);
+g->SelForeground(PI_Black);
+g->SelLine(PI_ThinLine);
+
+g->DrawString(20,24,"StringPosDraw");
+g->DrawString(XSize()/3,24,attstr[ia]);
+g->DrawString(2*XSize()/3,24,fszstr[js]);
+
+
+PIFont fx(14,fn[2]);
+fx.SetFontSz(mFSize);
+fx.SetFontAtt(mFAtt);
+g->SelFont(fx);
+int fh,fa,fd;
+fh = fx.GetFontHeight(fa, fd);
+cout << " FontSize= " << f.GetFontSize() << " FontHeight= " << fh << endl;
+
+
+int xpos, ypos;
+char * s1;
+
+if (mTxtDir != PI_TextDirectionHorizontal) {
+  xpos = 50;  ypos = 450;
+  s1 = "V_Top-H_Left-TxDUp";
+  g->SelForeground(PI_Red);
+  g->DrawLine(xpos-10, ypos, xpos+10, ypos); 
+  g->DrawLine(xpos, ypos-50, xpos, ypos+50);
+  g->SelForeground(PI_Black);
+  g->DrawString(xpos, ypos, s1, 
+		PI_HorizontalLeft|PI_VerticalTop|PI_TextDirectionVerticalUp);  
+
+  xpos = 100;  ypos = 400;
+  s1 = "V_Top-H_Center-TxDUp";
+  g->SelForeground(PI_Red);
+  g->DrawLine(xpos-10, ypos, xpos+10, ypos); 
+  g->DrawLine(xpos, ypos-50, xpos, ypos+50);
+  g->SelForeground(PI_Black);
+  g->DrawString(xpos, ypos, s1, 
+		PI_HorizontalCenter|PI_VerticalTop|PI_TextDirectionVerticalUp);
+
+  xpos = 150;  ypos = 350;
+  s1 = "V_Top-H_Right-TxDUp";
+  g->SelForeground(PI_Red);
+  g->DrawLine(xpos-10, ypos, xpos+10, ypos); 
+  g->DrawLine(xpos, ypos-50, xpos, ypos+50);
+  g->SelForeground(PI_Black);
+  g->DrawString(xpos, ypos, s1, 
+		PI_HorizontalRight|PI_VerticalTop|PI_TextDirectionVerticalUp);
+
+  xpos = 50;  ypos = 250;
+  s1 = "V_Center-H_Left-TxDUp";
+  g->SelForeground(PI_Red);
+  g->DrawLine(xpos-10, ypos, xpos+10, ypos); 
+  g->DrawLine(xpos, ypos-50, xpos, ypos+50);
+  g->SelForeground(PI_Black);
+  g->DrawString(xpos, ypos, s1, 
+		PI_HorizontalLeft|PI_VerticalCenter|PI_TextDirectionVerticalUp);  
+
+  xpos = 100;  ypos = 200;
+  s1 = "V_Base-H_Center-TxDUp";
+  g->SelForeground(PI_Red);
+  g->DrawLine(xpos-10, ypos, xpos+10, ypos); 
+  g->DrawLine(xpos, ypos-50, xpos, ypos+50);
+  g->SelForeground(PI_Black);
+  g->DrawString(xpos, ypos, s1, 
+		PI_HorizontalCenter|PI_VerticalBaseLine|PI_TextDirectionVerticalUp);
+
+  xpos = 150;  ypos = 150;
+  s1 = "V_Bot-H_Right-TxDUp";
+  g->SelForeground(PI_Red);
+  g->DrawLine(xpos-10, ypos, xpos+10, ypos); 
+  g->DrawLine(xpos, ypos-50, xpos, ypos+50);
+  g->SelForeground(PI_Black);
+  g->DrawString(xpos, ypos, s1, 
+		PI_HorizontalRight|PI_VerticalBottom|PI_TextDirectionVerticalUp);
+
+
+  xpos = 200;  ypos = 100;
+  s1 = "V_Top-H_Left-TxDown";
+  g->SelForeground(PI_Red);
+  g->DrawLine(xpos-10, ypos, xpos+10, ypos); 
+  g->DrawLine(xpos, ypos-50, xpos, ypos+50);
+  g->SelForeground(PI_Black);
+  g->DrawString(xpos, ypos, s1, 
+		PI_HorizontalLeft|PI_VerticalTop|PI_TextDirectionVerticalDown);  
+
+  xpos = 250;  ypos = 150;
+  s1 = "V_Top-H_Center-TxDown";
+  g->SelForeground(PI_Red);
+  g->DrawLine(xpos-10, ypos, xpos+10, ypos); 
+  g->DrawLine(xpos, ypos-50, xpos, ypos+50);
+  g->SelForeground(PI_Black);
+  g->DrawString(xpos, ypos, s1, 
+		PI_HorizontalCenter|PI_VerticalTop|PI_TextDirectionVerticalDown);
+
+  xpos = 300;  ypos = 200;
+  s1 = "V_Top-H_Right-TxDown";
+  g->SelForeground(PI_Red);
+  g->DrawLine(xpos-10, ypos, xpos+10, ypos); 
+  g->DrawLine(xpos, ypos-50, xpos, ypos+50);
+  g->SelForeground(PI_Black);
+  g->DrawString(xpos, ypos, s1, 
+		PI_HorizontalRight|PI_VerticalTop|PI_TextDirectionVerticalDown);
+
+  xpos = 200;  ypos = 300;
+  s1 = "V_Center-H_Left-TxDown";
+  g->SelForeground(PI_Red);
+  g->DrawLine(xpos-10, ypos, xpos+10, ypos); 
+  g->DrawLine(xpos, ypos-50, xpos, ypos+50);
+  g->SelForeground(PI_Black);
+  g->DrawString(xpos, ypos, s1, 
+		PI_HorizontalLeft|PI_VerticalCenter|PI_TextDirectionVerticalDown);  
+
+  xpos = 250;  ypos = 350;
+  s1 = "V_Base-H_Center-TxDown";
+  g->SelForeground(PI_Red);
+  g->DrawLine(xpos-10, ypos, xpos+10, ypos); 
+  g->DrawLine(xpos, ypos-50, xpos, ypos+50);
+  g->SelForeground(PI_Black);
+  g->DrawString(xpos, ypos, s1, 
+		PI_HorizontalCenter|PI_VerticalBaseLine|PI_TextDirectionVerticalDown);
+
+  xpos = 300;  ypos = 400;
+  s1 = "V_Bot-H_Right-TxDown";
+  g->SelForeground(PI_Red);
+  g->DrawLine(xpos-10, ypos, xpos+10, ypos); 
+  g->DrawLine(xpos, ypos-50, xpos, ypos+50);
+  g->SelForeground(PI_Black);
+  g->DrawString(xpos, ypos, s1, 
+		PI_HorizontalRight|PI_VerticalBottom|PI_TextDirectionVerticalDown);
+
+
+  return;
+}
+// --------------- Vertical Top -----------------
+
+xpos = 30;  ypos = 75;
+s1 = "V_Top-H_Left";
+g->SelForeground(PI_Red);
+g->DrawLine(xpos-50, ypos, xpos+50, ypos); 
+g->DrawLine(xpos, ypos-10, xpos, ypos+10);
+g->SelForeground(PI_Black);
+g->DrawString(xpos, ypos, s1, PI_HorizontalLeft|PI_VerticalTop);
+
+xpos = XSize()/2;  ypos = 75;
+s1 = "V_Top-H_Center";
+g->SelForeground(PI_Red);
+g->DrawLine(xpos-50, ypos, xpos+50, ypos); 
+g->DrawLine(xpos, ypos-10, xpos, ypos+10);
+g->SelForeground(PI_Black);
+g->DrawString(xpos, ypos, s1, PI_HorizontalCenter|PI_VerticalTop);
+
+xpos = XSize()-30;  ypos = 75;
+s1 = "V_Top-H_Right";
+g->SelForeground(PI_Red);
+g->DrawLine(xpos-50, ypos, xpos+50, ypos); 
+g->DrawLine(xpos, ypos-10, xpos, ypos+10);
+g->SelForeground(PI_Black);
+g->DrawString(xpos, ypos, s1, PI_HorizontalRight|PI_VerticalTop);
+
+// --------------- Vertical Center ----------------- 
+xpos = 30;  ypos = 150;
+s1 = "V_Center-H_Left";
+g->SelForeground(PI_Red);
+g->DrawLine(xpos-50, ypos, xpos+50, ypos); 
+g->DrawLine(xpos, ypos-10, xpos, ypos+10);
+g->SelForeground(PI_Black);
+g->DrawString(xpos, ypos, s1, PI_HorizontalLeft|PI_VerticalCenter);
+
+xpos = XSize()/2;  ypos = 150;
+s1 = "V_Center-H_Center";
+g->SelForeground(PI_Red);
+g->DrawLine(xpos-50, ypos, xpos+50, ypos); 
+g->DrawLine(xpos, ypos-10, xpos, ypos+10);
+g->SelForeground(PI_Black);
+g->DrawString(xpos, ypos, s1, PI_HorizontalCenter|PI_VerticalCenter);
+
+xpos = XSize()-30;  ypos = 150;
+s1 = "V_Center-H_Right";
+g->SelForeground(PI_Red);
+g->DrawLine(xpos-50, ypos, xpos+50, ypos); 
+g->DrawLine(xpos, ypos-10, xpos, ypos+10);
+g->SelForeground(PI_Black);
+g->DrawString(xpos, ypos, s1, PI_HorizontalRight|PI_VerticalCenter);
+ 
+// --------------- Vertical BaseLine -----------------
+xpos = 30;  ypos = 250;
+s1 = "V_Base-H_Left";
+g->SelForeground(PI_Red);
+g->DrawLine(xpos-50, ypos, xpos+50, ypos); 
+g->DrawLine(xpos, ypos-10, xpos, ypos+10);
+g->SelForeground(PI_Black);
+g->DrawString(xpos, ypos, s1, PI_HorizontalLeft|PI_VerticalBaseLine);
+
+xpos = XSize()/2;  ypos = 250;
+s1 = "V_Base-H_Center";
+g->SelForeground(PI_Red);
+g->DrawLine(xpos-50, ypos, xpos+50, ypos); 
+g->DrawLine(xpos, ypos-10, xpos, ypos+10);
+g->SelForeground(PI_Black);
+g->DrawString(xpos, ypos, s1, PI_HorizontalCenter|PI_VerticalBaseLine);
+
+xpos = XSize()-30;  ypos = 250;
+s1 = "V_Base-H_Center";
+g->SelForeground(PI_Red);
+g->DrawLine(xpos-50, ypos, xpos+50, ypos); 
+g->DrawLine(xpos, ypos-10, xpos, ypos+10);
+g->SelForeground(PI_Black);
+g->DrawString(xpos, ypos, s1, PI_HorizontalRight|PI_VerticalBaseLine);
+
+// --------------- Vertical Bottom -----------------
+xpos = 30;  ypos = 325;
+s1 = "V_Bottom-H_Left";
+g->SelForeground(PI_Red);
+g->DrawLine(xpos-50, ypos, xpos+50, ypos); 
+g->DrawLine(xpos, ypos-10, xpos, ypos+10);
+g->SelForeground(PI_Black);
+g->DrawString(xpos, ypos, s1, PI_HorizontalLeft|PI_VerticalBottom);
+
+xpos = XSize()/2;  ypos = 325;
+s1 = "V_Bottom-H_Center";
+g->SelForeground(PI_Red);
+g->DrawLine(xpos-50, ypos, xpos+50, ypos); 
+g->DrawLine(xpos, ypos-10, xpos, ypos+10);
+g->SelForeground(PI_Black);
+g->DrawString(xpos, ypos, s1, PI_HorizontalCenter|PI_VerticalBottom);
+
+xpos = XSize()-30;  ypos = 325;
+s1 = "V_Bottom-H_Center";
+g->SelForeground(PI_Red);
+g->DrawLine(xpos-50, ypos, xpos+50, ypos); 
+g->DrawLine(xpos, ypos-10, xpos, ypos+10);
+g->SelForeground(PI_Black);
+g->DrawString(xpos, ypos, s1, PI_HorizontalRight|PI_VerticalBottom);
+ 
+return;
+}
+
+/* ........................................................... */
+/*     Classe CompStringDrawWdg (Implementation des methodes)             */
+/* ........................................................... */
+
+/* --Methode-- */
+CompStringDrawWdg::CompStringDrawWdg(PIContainerGen *par, char *nom,
+                       int sx, int sy, int px, int py) 
+: StringDrawWdg(par, nom, sx, sy, px, py)
+
+{
+}
+
+/* --Methode-- */
+CompStringDrawWdg::~CompStringDrawWdg()
+{
+}
+ 
+
+/* --Methode-- */
+void CompStringDrawWdg::Draw(PIGraphicGen* g, int /*x0*/, int /*y0*/, int /*dx*/, int /*dy*/)
+{
+PIFontAtt att[4] = { PI_RomanFont, PI_BoldFont, PI_ItalicFont, PI_BoldItalicFont};
+PIFontSize fsz[5] = { PI_TinySizeFont, PI_SmallSizeFont, PI_NormalSizeFont, 
+		      PI_LargeSizeFont, PI_HugeSizeFont };
+PIFontName fn[4] = { PI_CourierFont, PI_HelveticaFont, 
+		     PI_TimesFont, PI_SymbolFont};
+char * fnstr[4] = { "Courier-Font", "Helvetica-Font", 
+		     "Times-Font", "Symbol-Font"};
+char * attstr[4] = { "RomanFont" , "BoldFont", "ItalicFont", "BoldItalicFont"};
+char * fszstr[5] = { "TinySizeFont", "SmallSizeFont", "NormalSizeFont", 
+		      "LargeSizeFont", "HugeSizeFont" };
+
+if (g->kind() != PI_PSFileGraphics ) EraseWindow();
+
+
+int ia=0, js=0;
+int k;
+for(k=0; k<4; k++)
+  if (att[k] == mFAtt)  {ia = k; break; }
+for(k=0; k<5; k++)
+  if (fsz[k] == mFSize)  {js = k; break; }
+
+if ((mFSize != mSFSize) || (mFAtt != mSFAtt))
+  for(k=0; k<10; k++)
+    mSL[k] = mSH[k] = 0;
+PIFont f(14, PI_DefaultFont, mFAtt);
+g->SelFont(f);
+g->SelForeground(PI_Black);
+g->SelLine(PI_ThinLine);
+
+g->DrawString(20,24,"StringDraw");
+g->DrawString(XSize()/5,24,attstr[ia]);
+g->DrawString(XSize()/3,24,fszstr[js]);
+
+
+PIFont fx(14,fn[2]);
+fx.SetFontSz(mFSize);
+fx.SetFontAtt(mFAtt);
+g->SelFont(fx);
+int fh,fa,fd;
+fh = fx.GetFontHeight(fa, fd);
+cout << " FontSize= " << f.GetFontSize() << " FontHeight= " << fh << endl;
+
+g->DrawCompString(XSize()/2,40,"10","-34",NULL);
+g->DrawCompString(XSize()/2+60,40,"10","+78",NULL);
+g->DrawCompString(XSize()/2+120,40, "10", NULL, "a");
+
+int xpos, ypos;
+char *s, *su, *sd;
+
+// --------------- Vertical Top -----------------
+
+xpos = 30;  ypos = 75;
+s = "HLeftVTop";
+su = "824";
+sd = "ij";
+g->SelForeground(PI_Red);
+g->DrawLine(xpos-50, ypos, xpos+50, ypos); 
+g->DrawLine(xpos, ypos-10, xpos, ypos+10);
+g->SelForeground(PI_Black);
+g->DrawCompString(xpos, ypos, s, su, sd, PI_HorizontalLeft|PI_VerticalTop);
+
+xpos = XSize()/2;  ypos = 75;
+s = "HCenVTop";
+su = "76843";
+sd = "abc";
+g->SelForeground(PI_Red);
+g->DrawLine(xpos-50, ypos, xpos+50, ypos); 
+g->DrawLine(xpos, ypos-10, xpos, ypos+10);
+g->SelForeground(PI_Black);
+g->DrawCompString(xpos, ypos, s, su, sd, PI_HorizontalCenter|PI_VerticalTop);
+
+xpos = XSize()-30;  ypos = 75;
+s = "HRigVTop";
+su = "76843";
+sd = "abc";
+g->SelForeground(PI_Red);
+g->DrawLine(xpos-50, ypos, xpos+50, ypos); 
+g->DrawLine(xpos, ypos-10, xpos, ypos+10);
+g->SelForeground(PI_Black);
+g->DrawCompString(xpos, ypos, s, su, sd, PI_HorizontalRight|PI_VerticalTop);
+
+// --------------- Vertical Center ----------------- 
+xpos = 30;  ypos = 150;
+s = "HLeftVCen";
+su = "32987";
+sd = NULL;
+g->SelForeground(PI_Red);
+g->DrawLine(xpos-50, ypos, xpos+50, ypos); 
+g->DrawLine(xpos, ypos-10, xpos, ypos+10);
+g->SelForeground(PI_Black);
+g->DrawCompString(xpos, ypos, s, su, sd, PI_HorizontalLeft|PI_VerticalCenter);
+
+xpos = XSize()/2;  ypos = 150;
+s = "HCenVCen";
+su = "32987";
+sd = "klm";
+g->SelForeground(PI_Red);
+g->DrawLine(xpos-50, ypos, xpos+50, ypos); 
+g->DrawLine(xpos, ypos-10, xpos, ypos+10);
+g->SelForeground(PI_Black);
+g->DrawCompString(xpos, ypos, s, su, sd, PI_HorizontalCenter|PI_VerticalCenter);
+
+xpos = XSize()-30;  ypos = 150;
+s = "HRigVCen";
+su = "2";
+sd = "alpha";
+g->SelForeground(PI_Red);
+g->DrawLine(xpos-50, ypos, xpos+50, ypos); 
+g->DrawLine(xpos, ypos-10, xpos, ypos+10);
+g->SelForeground(PI_Black);
+g->DrawCompString(xpos, ypos, s, su, sd, PI_HorizontalRight|PI_VerticalCenter);
+
+// --------------- Vertical BaseLine -----------------
+xpos = 30;  ypos = 250;
+s = "HLeftVBas";
+su = "3";
+sd = "beta";
+g->SelForeground(PI_Red);
+g->DrawLine(xpos-50, ypos, xpos+50, ypos); 
+g->DrawLine(xpos, ypos-10, xpos, ypos+10);
+g->SelForeground(PI_Black);
+g->DrawCompString(xpos, ypos, s, su, sd, PI_HorizontalLeft|PI_VerticalBaseLine);
+
+xpos = XSize()/2;  ypos = 250;
+s = "HCenVBas";
+su = "gamma";
+sd = "44";
+g->SelForeground(PI_Red);
+g->DrawLine(xpos-50, ypos, xpos+50, ypos); 
+g->DrawLine(xpos, ypos-10, xpos, ypos+10);
+g->SelForeground(PI_Black);
+g->DrawCompString(xpos, ypos, s, su, sd, PI_HorizontalCenter|PI_VerticalBaseLine);
+
+xpos = XSize()-30;  ypos = 250;
+s = "HRigVBas";
+su = "55";
+sd = "alpha";
+g->SelForeground(PI_Red);
+g->DrawLine(xpos-50, ypos, xpos+50, ypos); 
+g->DrawLine(xpos, ypos-10, xpos, ypos+10);
+g->SelForeground(PI_Black);
+g->DrawCompString(xpos, ypos, s, su, sd, PI_HorizontalRight|PI_VerticalBaseLine);
+
+// --------------- Vertical Bottom -----------------
+xpos = 30;  ypos = 325;
+s = "HLeftVBot";
+su = "abc";
+sd = "6";
+g->SelForeground(PI_Red);
+g->DrawLine(xpos-50, ypos, xpos+50, ypos); 
+g->DrawLine(xpos, ypos-10, xpos, ypos+10);
+g->SelForeground(PI_Black);
+g->DrawCompString(xpos, ypos, s, su, sd, PI_HorizontalLeft|PI_VerticalBottom);
+
+xpos = XSize()/2;  ypos = 325;
+s = "HCentVBot";
+su = NULL;
+sd = "lm";
+g->SelForeground(PI_Red);
+g->DrawLine(xpos-50, ypos, xpos+50, ypos); 
+g->DrawLine(xpos, ypos-10, xpos, ypos+10);
+g->SelForeground(PI_Black);
+g->DrawCompString(xpos, ypos, s, su, sd, PI_HorizontalCenter|PI_VerticalBottom);
+
+xpos = XSize()-30;  ypos = 325;
+s = "HLeftVBot";
+su = NULL;
+sd = NULL;
+g->SelForeground(PI_Red);
+g->DrawLine(xpos-50, ypos, xpos+50, ypos); 
+g->DrawLine(xpos, ypos-10, xpos, ypos+10);
+g->SelForeground(PI_Black);
+g->DrawCompString(xpos, ypos, s, su, sd, PI_HorizontalRight|PI_VerticalBottom);
+ 
+return;
+}
+
+/* ........................................................... */
+/*                       Classe PITApp                         */
+/* ........................................................... */
+class PITApp : public PIApplication {
+public:
+     PITApp(int narg=0, char* arg[]=NULL);
+     ~PITApp();
+     virtual void   Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+private :
+  PIMenu* m[2];
+  PIText* txt;
+  PIWindow* mcurwin;
+  PSFile *mPS;
+};
+
+
+/* --Methode-- */
+PITApp::PITApp(int narg, char* arg[])
+: PIApplication(300, 100, narg, arg)
+{
+
+//  Menus, les numeros ds AppendItem sont les numeros de messages
+//  qui seront passes a Process() et permettent d'identifier l'action
+
+//  Creation du premier menu  
+
+m[0] = new PIMenu(Menubar(),"Actions");
+m[0]->AppendItem("StringDrawWdg", 10101);
+m[0]->AppendItem("StringPosDrawWdg", 10102);
+m[0]->AppendItem("CompStringDrawWdg", 10103);
+m[0]->AppendItem("StringPosVertical", 10104);
+
+m[0]->AppendItem("->eps", 10111);
+m[0]->AppendItem("->ps", 10112);
+m[0]->AppendItem("Exit", 10105);
+// On accroche le menu au Menubar
+AppendMenu(m[0]);
+
+
+// Creation d' zone texte multiligne
+txt = new PIText(MainWin(), "mltext", true, true, 290, 90, 5, 5);
+txt->SetBinding(PIBK_elastic,PIBK_elastic,PIBK_elastic,PIBK_elastic);
+// txt->SetMutiLineMode(true);
+txt->SetTextEditable(false);
+txt->SetText("");
+txt->SetText("StringDrawWdg/Keyboard: \n r,b,i,I (Roman,bold,italic,bolditalic) \n Size 1,2,3,4,5\n C,H,T,S (Courier,Helvetica,Times,Symbol)");
+
+mcurwin = NULL;
+mPS = new PSFile("pist.ps", PI_Auto);
+SetReady();
+}
+
+/* --Methode-- */
+PITApp::~PITApp()
+{
+delete m[0]; 
+delete txt;
+delete mPS;
+}  
+
+static int numpsf = 0;
+static int nbwin = 0;
+/* --Methode-- */
+void PITApp::Process(PIMessage msg, PIMsgHandler* sender, void* /*data*/)
+{
+
+char strg[256];
+
+// Gestion des actions en fonctions des messages
+
+if ( ( ModMsg(msg) == PIMsg_Active) || (ModMsg(msg) == PIMsg_Close) ) {
+  PIWdg *sndw;
+  sndw = (PIWdg *)sender;      
+  if (sndw->kind() ==  PIWindow::ClassId)  {
+    if (ModMsg(msg) == PIMsg_Close)  { 
+      delete (PIWindow *)sender;  
+      mcurwin = NULL;  
+      }
+    else mcurwin = (PIWindow *)sender;
+  }
+}
+
+else switch(UserMsg(msg))    {
+
+    case 10101: // Creation d'un StringDrawWdg
+      {
+      nbwin++;
+      sprintf(strg, "Creation StringDrawWdg   \n Fenetre No %d ", nbwin);
+      sprintf(strg,"StringDrawWdg - %d", nbwin);
+      PIWindow* wp = new PIWindow(this, strg, PIWK_normal,  400, 400, 150, 150);
+      wp->SetAutoDelChilds(true);
+      StringDrawWdg* exb  = new StringDrawWdg(wp, "sdrawwdg", 400, 400, 0, 0);
+      exb->SetBinding(PIBK_fixed,PIBK_elastic,PIBK_elastic,PIBK_elastic);
+      wp->SetUserData(exb);
+      wp->Show();
+      }
+    break;
+
+    case 10102: // Creation d'un StringPosDrawWdg
+      {
+      nbwin++;
+      sprintf(strg, "Creation StringPosDrawWdg   \n Fenetre No %d ", nbwin);
+      sprintf(strg,"StringPosDrawWdg - %d", nbwin);
+      PIWindow* wp = new PIWindow(this, strg, PIWK_normal,  600, 400, 150, 150);
+      wp->SetAutoDelChilds(true);
+      StringPosDrawWdg* exb  = new StringPosDrawWdg(wp, "sposdrawwdg", 600, 400, 0, 0);
+      exb->SetBinding(PIBK_fixed,PIBK_elastic,PIBK_elastic,PIBK_elastic);
+      wp->SetUserData(exb);
+      wp->Show();
+      }
+    break;
+
+    case 10103: // Creation d'un StringPosDrawWdg
+      {
+      nbwin++;
+      sprintf(strg, "Creation CompStringDrawWdg   \n Fenetre No %d ", nbwin);
+      sprintf(strg,"CompStringDrawWdg - %d", nbwin);
+      PIWindow* wp = new PIWindow(this, strg, PIWK_normal,  600, 400, 150, 150);
+      wp->SetAutoDelChilds(true);
+      CompStringDrawWdg* exb  = new CompStringDrawWdg(wp, "compposdrawwdg", 600, 400, 0, 0);
+      exb->SetBinding(PIBK_fixed,PIBK_elastic,PIBK_elastic,PIBK_elastic);
+      wp->SetUserData(exb);
+      wp->Show();
+      }
+    break;
+
+    case 10104: // Creation d'un StringPosDrawWdg-VerticalStringDir
+      {
+      nbwin++;
+      sprintf(strg, "Creation StringPosDrawWdg-Vertical   \n Fenetre No %d ", nbwin);
+      sprintf(strg,"StringPosDrawWdg-Vertical - %d", nbwin);
+      PIWindow* wp = new PIWindow(this, strg, PIWK_normal,  400, 600, 150, 150);
+      wp->SetAutoDelChilds(true);
+      StringPosDrawWdg* exb  = new StringPosDrawWdg(wp, "sposdrawwdgvert", 400, 600, 0, 0);
+      exb->SetTextDirection(PI_TextDirectionVerticalUp);
+      exb->SetBinding(PIBK_fixed,PIBK_elastic,PIBK_elastic,PIBK_elastic);
+      wp->SetUserData(exb);
+      wp->Show();
+      }
+    break;
+
+
+    case 10111:          // -> eps
+      if (mcurwin) {
+        char buff[64];
+        sprintf(buff, "pist_%d.eps", numpsf);        numpsf++;
+        printf("Creating EPS File %s (Encapsulated PostScript) \n", buff);
+        PSFile *mps;
+	mps = new PSFile(buff);
+	mcurwin->PSPrint(mps,0,0);
+	delete mps;
+        }
+      break;    
+    
+    case 10112:          // -> eps
+      if (mcurwin) {
+        printf("Current Window to Postscript file pist.ps \n");
+	mcurwin->PSPrint(mPS,0,0);
+        }
+      break;        
+
+    case 10105:          // Sortie d'application
+      Stop();
+      break;
+
+  }
+return;
+}
+
+
+// ................................................................
+//                   programme principal 
+// ................................................................
+
+int main(int narg, char *arg[])
+{
+if ( (narg > 1) && (strcmp(arg[1],"-h") == 0) ) {
+  printf("pist : StringDrawWdg  test \n");
+  printf("  Usage : pidrstrtst [Xt options] \n");
+  }
+//  Creation de l'objet application et appel de Run()
+PITApp* app = new PITApp(narg, arg);
+// puts("appel de Application.Run() ... ");
+app->Run();
+
+delete app;
+exit(0);
+}
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/Tests/pit0.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/Tests/pit0.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/Tests/pit0.cc	(revision 2309)
@@ -0,0 +1,309 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <iostream.h>
+
+
+#include "pisysdep.h"
+
+#include PIAPP_H
+#include PIMENU_H 
+#include PISTDWDG_H 
+#include PIWIN_H
+#include PIPERIODIC_H
+
+//  ----- Declaration de la classe ArgsWind : Fenetre de dialogue -------
+class ArgsWind : public PIWindow {
+public :
+                ArgsWind(PIApplication *par);
+                ~ArgsWind();
+          void  SetLabels(char *lab1, char *lab2, char *lab3);
+          void  SetTexts(char *tx1, char *tx2, char *tx3);
+          void  GetTexts(char *tx1, char *tx2, char *tx3);
+  virtual void  Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+
+private:
+  PILabel  * mLab[3];
+  PIButton * mBut[2];
+  PIText * mText[3];
+  };
+
+//  ----- Declaration de notre classe PIApplication (PITApp) -------
+class PITApp : public PIApplication {
+public:
+     PITApp(int narg=0, char* arg[]=NULL);
+     ~PITApp();
+     virtual void   Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+
+  PILabel *lab;
+
+private :
+  PIMenu * m[2];
+  PIPeriodX mPeriod;
+  ArgsWind *mAW;
+};
+
+
+
+/* ........................................................... */
+/*              Classe ArgsWindow (methodes)                   */
+/* ........................................................... */
+
+
+/* --Methode-- */
+ArgsWind::ArgsWind(PIApplication *par)
+: PIWindow((PIMsgHandler *)par, "Args", PIWK_dialog, 100, 100, 150, 150)
+{
+int bsx, bsy;
+
+// On definit la taille a partir de la taille par defaut des composantes 
+printf("ArgsWind::ArgsWind() \n");
+PIApplicationPrefCompSize(bsx, bsy);
+// On redefinit la taille de la fenetre
+SetSize(bsx*7, bsy*6);
+
+// Creation de champs "labels"
+mLab[0] = new PILabel(this, "UserArg-1:", bsx*2, bsy, bsx/3, bsy/4); 
+mLab[1] = new PILabel(this, "UserArg-2", bsx*2, bsy, bsx/3, bsy/4 + (bsy/4+bsy) );
+mLab[2] = new PILabel(this, "UserArg-3", bsx*2, bsy, bsx/3, bsy/4 + 2*(bsy/4+bsy) );
+
+// Creation de champs textes 
+mText[0] = new PIText(this, "UsArg1", bsx*4, bsy, bsx*2+(bsx*2/3), bsy/4);
+mText[0]->SetText("Hello ");
+mText[1] = new PIText(this, "UsArg2", bsx*4, bsy, bsx*2+(bsx*2/3), bsy/4 + (bsy/4+bsy) );
+mText[1]->SetText("1. -1.");
+mText[2] = new PIText(this, "UsArg3", bsx*4, bsy, bsx*2+(bsx*2/3), bsy/4 + 2*(bsy/4+bsy) );
+mText[2]->SetText("1. -1.");
+
+// Creation de bouton d'action 
+//  Attention : Numero de message pour Process()
+mBut[0] = new PIButton(this, "OK",  555, bsx*2, bsy, bsx, 4.5*bsy);
+mBut[1] = new PIButton(this, "Cancel", 777, bsx*2, bsy, 4*bsx, 4.5*bsy);
+
+//  Taille et position proportionnelles a la taille de la fenetre pour les elements
+for(int i=0; i<3; i++) {
+  mLab[i]->SetBinding(PIBK_elastic , PIBK_elastic , PIBK_elastic , PIBK_elastic);
+  //Test  mLab[i]->SetBinding(PIBK_fixed , PIBK_fixed , PIBK_free , PIBK_free);
+  mText[i]->SetBinding(PIBK_elastic , PIBK_elastic , PIBK_elastic , PIBK_elastic);
+  //Test  mText[i]->SetBinding(PIBK_free , PIBK_fixed , PIBK_fixed , PIBK_free);
+  }
+for(int ii=0; ii<2; ii++) mBut[ii]->SetBinding(PIBK_elastic , PIBK_elastic , PIBK_elastic , PIBK_elastic);
+
+}
+
+/* --Methode-- */
+ArgsWind::~ArgsWind()
+{
+for(int i=0; i<3; i++)
+  {
+  delete mLab[i];
+  delete mText[i];
+  }
+
+delete mBut[0]; 
+delete mBut[1]; 
+}
+
+/* --Methode-- */
+void ArgsWind::SetLabels(char *lab1, char *lab2, char *lab3)
+// Permet de changer les etiquettes (les label)
+{
+mLab[0]->SetLabel(lab1);
+mLab[1]->SetLabel(lab2);
+mLab[2]->SetLabel(lab3);
+}
+
+/* --Methode-- */
+void ArgsWind::SetTexts(char *tx1, char *tx2, char *tx3)
+// Permet de changer les contenu des champs texte
+{
+mText[0]->SetText(tx1);
+mText[1]->SetText(tx2);
+mText[2]->SetText(tx3);
+
+}
+
+/* --Methode-- */
+void ArgsWind::GetTexts(char *tx1, char *tx2, char *tx3)
+// Permet de recuperer les contenus des champs texte
+// ATTENTION : Il faut qu'il y ait assez de place 
+// ds tx1, tx2, tx3 pour que la fonction puisse y copier 
+// les chaines
+{
+strcpy(tx1, mText[0]->GetText().c_str());
+strcpy(tx2, mText[1]->GetText().c_str());
+strcpy(tx3, mText[2]->GetText().c_str());
+}
+
+/* --Methode-- */
+void ArgsWind::Process(PIMessage msg, PIMsgHandler* /*sender*/, void* /*data*/)
+{
+float xmin, xmax, ymin, ymax;
+float fmin, fmax;
+
+switch (UserMsg(msg))
+  {
+  case 777:   // Bouton cancel - On s'en va 
+    this->Hide();
+    break;
+
+  case 555:    // Bouton OK
+// On recupere les textes des 3 champs :
+    printf("ArgsWind::Process() Txt[0] = %s \n", mText[0]->GetText().c_str());
+    sscanf(mText[1]->GetText().c_str(),"%g %g", &xmin, &xmax);
+    printf("... XMin/Max= %g %g \n", xmin, xmax);
+    this->Hide();
+    break;    
+  }
+    
+return;
+}
+
+
+/* ........................................................... */
+/*               Classe PITApp (methodes)                      */
+/* ........................................................... */
+
+static void mypact(void *);
+
+/* --Methode-- */
+PITApp::PITApp(int narg, char* arg[])
+: PIApplication(270, 100, narg, arg), mPeriod(1)   // Periode de 1 seconde pour le "timer"
+{
+
+//  Menus, les numeros ds AppendItem sont les numeros de messages
+//  qui seront passes a Process() et permettent d'identifier l'action
+
+//  Creation du premier menu  
+//  Update :
+//  Mis a jour du Label se trouvant ds la fenetre principal avec l'heure
+//  Start, Stop :
+//  Demarrage et Arret d'une fonction Timer (PIPeriodic) pour 
+//  la mise a jour periodique de ce champ
+//  Exit : 
+//  Arret et sortie du programme
+  cout << " PITApp::PITApp() - Creating menus " << endl;
+m[0] = new PIMenu(Menubar(),"Fichier");
+m[0]->AppendItem("Update", 10101);
+m[0]->AppendItem("Start", 10102);
+m[0]->AppendItem("Stop", 10103);
+m[0]->AppendItem("ArgsWindow", 10104);
+m[0]->AppendSeparator();
+m[0]->AppendItem("Exit", 10105);
+// On accroche le menu au Menubar
+AppendMenu(m[0]);
+
+m[1] = new PIMenu(Menubar(),"Edit");
+m[1]->AppendItem("Cut", 10201);
+m[1]->AppendItem("Copy", 10202);
+m[1]->AppendItem("Paste", 10203);
+// On accroche le menu au Menubar
+AppendMenu(m[1]);
+
+
+// Creation de deux labels - Un pour l'heure, l'autre pour X-Y 
+// de la fenetre histo
+  cout << " PITApp::PITApp() - Creating PILabel " << endl;
+lab = new PILabel(this->MainWin(), "time", 250, 50, 10, 10);
+
+mPeriod.SetAction(mypact);
+
+// Fenetre de dialogue
+mAW = new ArgsWind(this);
+SetReady();
+}
+
+/* --Methode-- */
+PITApp::~PITApp()
+{
+delete m[0]; delete m[1]; delete lab;
+delete mAW;
+}  
+
+/* --Methode-- */
+void PITApp::Process(PIMessage msg, PIMsgHandler* sender, void* /*data*/)
+{
+
+char strg[64];
+
+ printf("DBG-PITApp::Process() Msg= %d (%d - %d) Sender=%lx (This=%lx) \n", 
+	(int)msg, (int)UserMsg(msg),(int)ModMsg(msg), (long)sender, (long)this);
+
+// Gestion des actions en fonctions des messages
+      printf("DBG-PITApp::Process() Msg= %d (%d - %d) - Sender=%lx - %lx\n", 
+            (int)msg, (int)UserMsg(msg),(int)ModMsg(msg), (long)sender, (long)this);
+
+switch(UserMsg(msg))    {
+
+    case 10101:     // On met a l'heure
+      mypact(NULL);    
+      break;
+
+    case 10102:
+      mPeriod.Start();   // On demarre la montre 
+      break;
+
+    case 10103:
+      mPeriod.Stop();    // On arrete la montre 
+      break;
+
+    case 10104 :     // Apparition de la fenetre de dialogue
+      mAW->Show();
+      break;
+
+    case 10105:          // Sortie d'application
+      Stop();
+      break;
+
+    case 10201:          // 2 eme menu
+    case 10202:          //    "   "
+    case 10203:          //    "   "
+      printf("PITApp::Process() Msg= %d (%d - %d) Menu 2 not implemented \n",
+              (int)msg, (int)UserMsg(msg),(int)ModMsg(msg));
+      break;
+
+    default :
+      printf("PITApp::Process() Msg= %d (%d - %d)??? \n", 
+            (int)msg, (int)UserMsg(msg),(int)ModMsg(msg));
+     break;
+    
+  }
+return;
+}
+
+static PITApp * app;
+
+/* Nouvelle-Fonction */
+void mypact(void *)
+// Fonction pour lire l'heure de la machine et mettre a jour le champ label
+{
+time_t tm;
+char *s;
+time(&tm);
+s = ctime(&tm);
+// printf("mypact_Info:  %d  (%s)", tm, s);
+app->lab->SetLabel((string)s);
+return;
+}
+
+// ................................................................
+//                   programme principal 
+// ................................................................
+
+int main(int narg, char *arg[])
+{
+if ( (narg > 1) && (strcmp(arg[1],"-h") == 0) ) {
+  printf("pit0 : Standard widget test \n");
+  printf("  Usage : pit0 [Xt options] \n");
+  }
+//  Creation de l'objet application et appel de Run()
+app = new PITApp(narg, arg);
+puts("appel de Application.Run() ... ");
+app->Run();
+
+delete app;
+exit(0);
+}
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/Tests/pit1.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/Tests/pit1.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/Tests/pit1.cc	(revision 2309)
@@ -0,0 +1,571 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <iostream.h>
+
+#include "pisysdep.h"
+#include PIAPP_H
+#include PIWIN_H 
+#include PIMENU_H 
+#include PISTDWDG_H 
+#include PIBWDG_H
+#include "piscdrawwdg.h"
+#include "pievthandler.h"
+#include "parradapter.h"
+
+#include "piyfxdrw.h"
+
+/*  Exemple d'utilisation PIBaseWdg - Creation d'une nouvelle composante graphique  */
+
+// ---- Declaration de la classe ExBWdg --------
+class ExBWdg : public PIBaseWdg
+{
+public:
+// Les methodes ...
+
+                  ExBWdg(PIContainerGen *par, char *nom,
+                         int sx=10, int sy=10, int px=0, int py=0);
+  virtual         ~ExBWdg();
+
+// Traitement des evenements   
+//  virtual void   Resize();
+  virtual void   Draw(PIGraphic* g, int x0, int y0, int dx, int dy);
+
+  virtual void   But1Press(int x, int y);
+  virtual void   But1Release(int x, int y);
+  virtual void   But2Press(int x, int y);
+  virtual void   But2Release(int x, int y);
+  virtual void   But3Press(int x, int y);
+  virtual void   But3Release(int x, int y);
+  virtual void   Keyboard(int key, PIKeyModifier kmod);
+
+protected:
+  int mfnt, mmrk;
+  int nc;
+  char str[32];
+};
+
+
+/* ........................................................... */
+/*     Classe ExBWdg (Implementation des methodes)             */
+/* ........................................................... */
+
+/* --Methode-- */
+ExBWdg::ExBWdg(PIContainerGen *par, char *nom,
+                       int sx, int sy, int px, int py) 
+: PIBaseWdg(par, nom, sx, sy, px, py)
+
+{
+mmrk = mfnt = nc = 0;
+strcpy(str, "Hello !");
+for(int i=strlen(str); i<20; i++) str[i] = ' ';
+str[20] = '\0';
+
+ActivateKeyboard();
+ActivateButton(1);
+ActivateButton(2);
+ActivateButton(3);
+}
+
+/* --Methode-- */
+ExBWdg::~ExBWdg()
+{
+}
+ 
+/* --Methode-- 
+void ExBWdg::Resize()
+{
+}
+*/
+
+/* --Methode-- */
+void ExBWdg::Draw(PIGraphicGen* g, int /*x0*/, int /*y0*/, int /*dx*/, int /*dy*/)
+{
+PIFontAtt att[4] = { PI_RomanFont, PI_BoldFont, PI_ItalicFont, PI_BoldItalicFont};
+PIFontSize fsz[4] = { PI_TinySizeFont, PI_SmallSizeFont, PI_NormalSizeFont, PI_LargeSizeFont};
+PIMarker  pmk[11] = { PI_DotMarker , PI_PlusMarker, PI_CrossMarker,  
+                 PI_CircleMarker, PI_FCircleMarker,
+                 PI_BoxMarker, PI_FBoxMarker,
+                 PI_TriangleMarker, PI_FTriangleMarker,
+                 PI_StarMarker, PI_FStarMarker };
+
+if (g->kind() != PI_PSFileGraphics ) EraseWindow();
+
+g->SelMarker(8, pmk[mmrk]);
+
+g->SelLine(PI_NormalLine);
+g->DrawBox(10,10, XSize()-20, YSize()-20);
+
+g->SelLine(PI_ThinLine);
+g->DrawFBox(20, 20, 20, 20);
+g->DrawCircle(30, 30, 15);
+
+g->SelForeground(PI_Red);
+g->DrawFCircle(70, 30, 15);
+
+g->SelForeground(PI_Yellow);
+g->DrawFBox(10, 60, 120, 20);
+
+PIFont f0;
+g->SelFont(f0);
+g->SelForeground(PI_Black);
+g->DrawString(20, 110, str);
+PIFont f(PI_TimesFont);
+f.SetFontSz(fsz[mfnt]);
+g->SelFont(f);
+g->DrawString(20, 130, "Times-Font");
+PIFont f2(14,PI_CourierFont, att[mfnt]);
+g->SelFont(f2);
+g->SelForeground(PI_Red);
+g->DrawString(20, 150, "Courier-Font");
+PIFont f3(14,PI_TimesFont, att[mfnt]);
+g->SelFont(f3);
+g->SelForeground(PI_Blue);
+g->DrawString(20, 170, "Times-Font");
+PIFont f4(14,PI_HelveticaFont, att[mfnt]);
+g->SelFont(f4);
+g->SelForeground(PI_Black);
+g->DrawString(20, 190, "Helvetica-Font");
+PIFont f5(14,PI_SymbolFont);
+g->SelFont(f5);
+g->DrawString(20, 210, "Symbol-Font");
+g->SelFont(f0);
+
+
+g->SelLine(PI_ThinLine);
+g->DrawLine(20, 140, 50, 130);
+g->SelLine(PI_NormalLine);
+g->DrawLine(50, 140, 80, 130);
+g->SelLine(PI_ThickLine);
+g->DrawLine(80, 140, 110, 130);
+
+g->SelForeground(PI_Magenta);
+g->DrawFCircle(120, 30, 15);
+g->SelForeground(PI_Grey);
+g->DrawFCircle(120, 60, 15);
+
+
+
+
+PIGrCoord x[5] = { 150, 165, 180, 195, 210 };
+PIGrCoord y[5] = { 50, 50, 50, 50, 50 };
+
+g->SelForeground(PI_Black);
+g->DrawMarkers(x, y, 5);
+return;
+}
+
+
+static char strbuff[128];
+/* --Methode-- */
+void ExBWdg::But1Press(int x, int y)
+{
+SelPointerShape(PI_CrossPointer);
+sprintf(strbuff,"Pos X= %d Y= %d", x, y);
+mWGrC->SelFont(PI_NormalSizeFont, PI_BoldFont);
+mWGrC->DrawString(x+10, y, strbuff);
+Send(Msg(), PIMsg_Active);
+return;
+}
+
+/* --Methode-- */
+void ExBWdg::But1Release(int x, int y)
+{
+SelPointerShape(PI_ArrowPointer);
+Refresh();
+return;
+}
+
+/* --Methode-- */
+void ExBWdg::But2Press(int x, int y)
+{
+if (++mfnt > 3)  mfnt = 0;
+if (++mmrk > 10)  mmrk = 0; 
+return;
+}
+
+/* --Methode-- */
+void ExBWdg::But2Release(int x, int y)
+{
+Refresh();
+return;
+}
+
+/* --Methode-- */
+void ExBWdg::But3Press(int x, int y)
+{
+SelPointerShape(PI_HandPointer);
+mWGrC->SelForeground(PI_Blue);
+mWGrC->DrawFBox(XSize()/3, YSize()/3, XSize()/8, YSize()/8);
+return;
+}
+
+/* --Methode-- */
+void ExBWdg::But3Release(int x, int y)
+{
+mWGrC->SelForeground(PI_White);
+mWGrC->DrawFBox(XSize()/3, YSize()/3, XSize()/8, YSize()/8);
+mWGrC->SelForeground(PI_Black);
+SelPointerShape(PI_ArrowPointer);
+return;
+}
+
+/* --Methode-- */
+void ExBWdg::Keyboard(int key, PIKeyModifier kmod)
+{
+str[nc] = key;  str[nc+1] = '\0';
+if (++nc > 30)  nc = 0;
+char buf[16];
+
+if (key == PIK_Return) { Refresh(); nc = 0; return; }
+mWGrC->SelFont(PI_NormalSizeFont, PI_BoldFont);
+sprintf(buf," %c (%3d) ", (char) key, key, (int)kmod);
+mWGrC->DrawOpaqueString(20, 75, buf);
+
+if ( (kmod == PIKM_Alt) && (key == 'c') ) {
+  printf("ExBWdg::Keyboard: Test-Copy ... \n"); 
+  ClaimSelection();
+}
+if ( (kmod == PIKM_Alt) && (key == 'v') ) {
+  printf("ExBWdg::Keyboard: Test-Paste ... \n"); 
+  RequestSelection();
+}
+
+return;
+}
+
+// ----- Exemple d'une classe heritant de PIScDrawWdg ----
+/* ........................................................... */
+/*                         Classe ScSample                     */
+/* ........................................................... */
+
+class ScSample : public PIScDrawWdg {
+public:
+  ScSample(PIContainerGen *par, char *nom,
+           int sx=10, int sy=10, int px=0, int py=0);
+  virtual ~ScSample();
+};
+
+static double fpol(double x) {return (0.3*x*x*x-x*x+7.);}
+static float xpts[10] =  {-2.4, -2  , -1., 1., 1.7, 2.2, 3., 3.75, 4.3,  4.8};
+static float ypts[10] =   {-5  , -1.5, 2.5, 5., 8.0, 12., 9., 6.00, 2.2, -3.0};
+
+ScSample::ScSample(PIContainerGen *par, char *nom,
+                  int sx, int sy, int px, int py)
+:PIScDrawWdg(par, nom, sx, sy, px, py)
+
+{
+// Definition des limites
+SetLimits(-3,5,-10,15);
+
+// Creation et ajout d'un drawer de fonctions
+PIFuncDrawer* mfd = new PIFuncDrawer(fpol);
+mfd->GetGraphicAtt().SetColAtt(PI_Blue);
+mfd->GetGraphicAtt().SetLineAtt(PI_NormalLine);
+AddScDrawer(mfd,true);
+
+// Creation et ajout d'un drawer de points
+PIYfXDrawer* mxyd = new PIYfXDrawer(new P1DAdapter<float>(xpts, 10, false), 
+                                    new P1DAdapter<float>(ypts, 10, false), true);
+mxyd->GetGraphicAtt().SetColAtt(PI_Magenta);
+mxyd->GetGraphicAtt().SetMarkerAtt(7, PI_FBoxMarker);
+AddScDrawer(mxyd, true);
+
+// Ajout de texte
+BaseDrawer()->GetGraphicAtt().SetFontAtt(PI_NormalSizeFont, PI_BoldFont);
+PIGraphicAtt gatt;
+gatt.SetColAtt(PI_Red);
+BaseDrawer()->ElDrwMgr().ElAddText(-2.8, 12., "---- ScSample ----", gatt, 0);
+BaseDrawer()->ElDrwMgr().ElAddText(-2.8, 10.,  "f(x)=0.3*x^3-x^2+7.", gatt, 0);
+
+SetAxesFlags(kAxesDflt);
+}
+
+ScSample::~ScSample()
+{
+}
+
+//      ----------- Une classe EventHandler ----------
+class MyEvHandler :  public PIEventHandler {
+public :
+			MyEvHandler();
+			~MyEvHandler();
+  virtual void		Draw(PIGraphic* g, int x0, int y0, int dx, int dy);
+  virtual void		ProcessEvent();
+  inline bool 		GrabOK() { return(grabok); }
+
+protected :
+  PIScreenBuffer* mscb;
+  int mposx, mposy;
+  int mposx2, mposy2;
+  int msx, msy;
+  bool grabok;
+};
+
+/* --Methode-- */
+MyEvHandler::MyEvHandler()
+        : PIEventHandler()
+{
+mscb = new PIScreenBuffer(100, 100);
+msx = 100;   msy = 100;
+mposx = mposy = 0;
+mposx2 = mposy2 = 0;
+grabok = false;
+}
+
+/* --Methode-- */
+MyEvHandler::~MyEvHandler()
+{
+delete mscb;
+}
+
+/* --Methode-- */
+void MyEvHandler::Draw(PIGraphic* g, int, int, int, int)
+{
+if (GrabOK()) {
+  printf("MyEvHandler::Draw() : Copying from ScreenBuffer to wdg (%lx) \n", (unsigned long)CurrentWdg());
+  mscb->CopyToWdg(CurrentWdg(), 0, 0, msx, msy, CurrentWdg()->XSize()/2, CurrentWdg()->YSize()/2);
+  }
+else printf("MyEvHandler::Draw() : Grab first from source \n");
+}
+
+/* --Methode-- */
+void MyEvHandler::ProcessEvent()
+{
+printf("MyEvHandler::ProcessEvent() \n");
+switch (EventType()) {
+
+  case PIEvent_But3Press : 
+    mposx = GetPosX();
+    mposy = GetPosY();
+    break;
+
+  case PIEvent_But3Release : 
+    mposx2 = GetPosX();
+    mposy2 = GetPosY();
+    printf("MyEvHandler::ProcessEvent(): Rectangle(%d,%d - %d,%d) \n", mposx, mposy, mposx2, mposy2);
+//    ((PIBaseWdg*)CurrentWdg())->WindowGraphic()->DrawBox(mposx, mposy, (mposx2-mposx), (mposy2-mposy));
+    break;
+
+  case PIEvent_Keyboard :
+    if ((GetKeyMod() == PIKM_Alt) && ((GetKey() == 'G') || (GetKey() == 'g')) ) {
+      printf("MyEvHandler::ProcessEvent(): Grabbing(%dx%d) from Wdg(%lx)@(%d,%d) \n", 
+             msx, msy, (unsigned long)CurrentWdg(), mposx, mposy);
+      mscb->CopyFromWdg(CurrentWdg(), mposx, mposy, msx, msy, 0, 0);
+      grabok = true;
+      }
+    break;
+
+  default :
+    printf("MyEvHandler::ProcessEvent(): Unexpected Event (Type = %d) received \n", (int)EventType());
+    break;
+  }
+
+return;
+}
+
+/* ........................................................... */
+/*                       Classe PITApp                         */
+/* ........................................................... */
+class PITApp : public PIApplication {
+public:
+     PITApp(int narg=0, char* arg[]=NULL);
+     ~PITApp();
+     virtual void   Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+private :
+  PIMenu* m[2];
+  PIText* txt;
+  MyEvHandler* evh;
+  PIWindow* mcurwin;
+  PIWdg* mdrhw;
+  PIWdg* mevhw;
+  PIWdg* mcurw;  
+};
+
+
+/* --Methode-- */
+PITApp::PITApp(int narg, char* arg[])
+: PIApplication(300, 100, narg, arg)
+{
+
+//  Menus, les numeros ds AppendItem sont les numeros de messages
+//  qui seront passes a Process() et permettent d'identifier l'action
+
+//  Creation du premier menu  
+
+m[0] = new PIMenu(Menubar(),"Actions");
+m[0]->AppendItem("Info", 10101);
+m[0]->AppendItem("New ExBwdg", 10102);
+m[0]->AppendItem("New ScSample", 10103);
+m[0]->AppendItem("->eps", 10111);
+m[0]->AppendItem("Exit", 10105);
+// On accroche le menu au Menubar
+AppendMenu(m[0]);
+
+m[1] = new PIMenu(Menubar(),"Edit");
+m[1]->AppendItem("Copy", 10201);
+m[1]->AppendItem("Paste", 10202);
+// On accroche le menu au Menubar
+AppendMenu(m[1]);
+
+// Creation d' zone texte multiligne
+txt = new PIText(MainWin(), "mltext", true, true, 290, 90, 5, 5);
+txt->SetBinding(PIBK_elastic,PIBK_elastic,PIBK_elastic,PIBK_elastic);
+// txt->SetMutiLineMode(true);
+txt->SetTextEditable(false);
+txt->SetText("");
+
+evh = new MyEvHandler; 
+mcurwin = NULL;
+mcurw = NULL;  
+mdrhw = NULL;
+mdrhw = NULL;
+SetReady();
+}
+
+/* --Methode-- */
+PITApp::~PITApp()
+{
+delete m[0]; delete m[1]; delete txt;
+}  
+
+static int numpsf = 0;
+static int nbwin = 0;
+/* --Methode-- */
+void PITApp::Process(PIMessage msg, PIMsgHandler* sender, void* /*data*/)
+{
+
+char strg[256];
+
+// Gestion des actions en fonctions des messages
+
+if ( ( ModMsg(msg) == PIMsg_Active) || (ModMsg(msg) == PIMsg_Close) ) {
+  PIWdg *sndw;
+  sndw = (PIWdg *)sender;      
+  if (sndw->kind() ==  PIWindow::ClassId)  {
+    if (ModMsg(msg) == PIMsg_Close)  { 
+//      printf("PITApp::Process()/Debug : Closing Window %lx \n", (long)sender);
+      if (mcurwin->UserData() == mcurw) mcurw = NULL;
+      if (mcurwin->UserData() == mdrhw) mdrhw = NULL;
+      if (mcurwin->UserData() == mevhw) mevhw = NULL;
+      delete (PIWindow *)sender;  
+      mcurwin = NULL;  
+      }
+    else mcurwin = (PIWindow *)sender;
+  }
+  else if ( ModMsg(msg) ==  PIMsg_Active) mcurw = sndw;
+}
+
+else switch(UserMsg(msg))    {
+
+    case 10101:     // Info 
+      txt->SetText("pit1: PITApp \n PIBaseWdg - PIScDrawWdg test \n ExBWdg (:PIBaseWdg) Creation \n ScSample (:PIScDrawWdg) creation");
+    break;
+
+    case 10102: // Creation d'un ExBWdg
+      {
+      nbwin++;
+      sprintf(strg, "Creation ExBwdg \n Fenetre No %d \n Test keyborard, button 1/2/3", nbwin);
+      txt->SetText(strg);
+      sprintf(strg,"Window %d - ExBwdg", nbwin);
+      PIWindow* wp = new PIWindow(this, strg, PIWK_normal,  250, 250, 150, 150);
+      wp->SetAutoDelChilds(true);
+      ExBWdg* exb  = new ExBWdg(wp, "bwdg", 250, 250, 0, 0);
+      exb->SetBinding(PIBK_fixed,PIBK_elastic,PIBK_elastic,PIBK_elastic);
+      wp->SetUserData(exb);
+      wp->Show();
+      }
+    break;
+
+    case 10103:   // Creation d'un ScSample
+      {
+      nbwin++;
+      sprintf(strg, "Creation Scsample \n Fenetre No %d \n Button 1 -> mouse position \n Button 2 -> Zoom \n keyboard <Alt>O <Alt>V", nbwin);
+      txt->SetText(strg);
+      sprintf(strg,"Window %d - ScSample", nbwin);
+      PIWindow* wp = new PIWindow(this, strg, PIWK_normal,  400, 400, 200, 200);
+      wp->SetAutoDelChilds(true);
+      ScSample* sc  = new ScSample(wp, "scsample", 400, 400, 0, 0);
+      sc->SetBinding(PIBK_elastic,PIBK_elastic,PIBK_elastic,PIBK_elastic);
+      wp->SetUserData(sc);
+      wp->Show();
+      }
+      break;
+
+    case 10111:          // -> eps
+      if (mcurwin) {
+        char buff[64];
+        sprintf(buff, "pit_%d.eps", numpsf);        numpsf++;
+        printf("Creating EPS File %s (Encapsulated PostScript) \n", buff);
+        PSFile *mps;
+	mps = new PSFile(buff);
+	mcurwin->PSPrint(mps,0,0);
+	delete mps;
+        }
+      break;        
+    case 10105:          // Sortie d'application
+      Stop();
+      break;
+
+
+    case 10201:          // 2 eme menu  Copy
+      if (mcurw == NULL) { printf("PITApp::Process()/Warning : Select a window for copy \n"); 
+        sprintf(strg, "Warning : Select a window for copy");
+        txt->SetText(strg);
+        }
+      else {
+        printf("Adding EventHandler to Wdg %lx", (long)mcurw);
+        sprintf(strg, "Adding EventHandler to Wdg %lx \n, Use button 3 to select copy zone \n, <Alt>G to Get copy",
+                (long)mcurw);
+        txt->SetText(strg);
+        if (mevhw != NULL) mevhw->RemoveEventHandler(evh);  mevhw = NULL;  
+        mcurw->AddEventHandler(evh, PIEvent_But3Press | PIEvent_But3Release | PIEvent_Keyboard, false);
+        }
+      break;
+      
+    case 10202:          //   2eme Menu - Paste
+      if (mcurw == NULL) { printf("PITApp::Process()/Warning : Select a window for paste \n"); 
+        sprintf(strg, "Warning : Select a window for paste");
+        txt->SetText(strg);
+        }
+      else {
+        printf("Adding DrawHandler to Wdg %lx \n - Refreshing Wdg", (long)mcurw);
+        sprintf(strg, "Adding DrawHandler to Wdg %lx \n - Refreshing Wdg", (long)mcurw);
+        txt->SetText(strg); 
+        mcurw->AddDrawHandler(evh, false); 
+        mdrhw = mcurw;
+        ((PIBaseWdg*)mcurw)->Refresh();
+        }
+      break;
+      
+    default :
+      //      printf("PITApp::Process() Msg= %d (%d - %d)??? \n", 
+      //            (int)msg, (int)UserMsg(msg),(int)ModMsg(msg));
+     break;
+    
+  }
+return;
+}
+
+
+// ................................................................
+//                   programme principal 
+// ................................................................
+
+int main(int narg, char *arg[])
+{
+if ( (narg > 1) && (strcmp(arg[1],"-h") == 0) ) {
+  printf("pit1 : ExBWdg (:PIBaseWdg) / ScSample (:PIScDrawWdg) test \n");
+  printf("  Usage : pit1 [Xt options] \n");
+  }
+//  Creation de l'objet application et appel de Run()
+PITApp* app = new PITApp(narg, arg);
+// puts("appel de Application.Run() ... ");
+app->Run();
+
+delete app;
+exit(0);
+}
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/Tests/pitcons.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/Tests/pitcons.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/Tests/pitcons.cc	(revision 2309)
@@ -0,0 +1,296 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <iostream.h>
+#include <X11/Intrinsic.h>
+#include <Xm/Xm.h>  // Pour *DBG*
+
+#include "pisysdep.h"
+
+#include PIAPP_H
+#include PIMENU_H 
+#include PISTDWDG_H 
+#include PIWIN_H
+#include "picons.h"
+
+class PITApp : public PIApplication {
+public:
+     PITApp(int narg=0, char* arg[]=NULL);
+     ~PITApp();
+     virtual void   Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL
+);
+
+// protected :
+     
+  PIMenu * m[2];
+  PIWindow *mCurW;
+  PIButton *but[2];
+};
+
+
+static PIConsole* scons=NULL;
+static PIConsole* cons=NULL;
+
+/* --Methode-- */
+PITApp::PITApp(int narg, char* arg[])
+: PIApplication(600, 300, narg, arg)
+{
+
+
+m[0] = new PIMenu(Menubar(),"Fichier");
+m[0]->AppendItem("NewConsole", 10101);
+m[0]->AppendItem("StdOut", 10102);
+m[0]->AppendItem("StdOut-2", 10103);
+m[0]->AppendItem("StdErr", 10104);
+m[0]->AppendItem("StdErr-2", 10105);
+m[0]->AppendItem("AccCmd", 10110);
+m[0]->AppendItem("AccCmd-2", 10111);
+m[0]->AppendItem("Exit", 10177,"Q");
+// On accroche le menu au Menubar
+AppendMenu(m[0]);
+
+
+m[1] = new PIMenu(Menubar(),"Actions");
+m[1]->AppendItem("Normal", 10201);
+m[1]->AppendItem("Bold", 10202);
+m[1]->AppendItem("Italique", 10203);
+m[1]->AppendItem("Reverse", 10204);
+m[1]->AppendItem("Print", 10205);
+m[1]->AppendItem("PrintNNL", 10206);
+m[1]->AppendItem("COUT", 10207);
+m[1]->AppendItem("PrintErr", 10208);
+m[1]->AppendItem("CERR", 10209);
+
+AppendMenu(m[1]);
+
+but[0] = but[1] = NULL;
+
+but[0] = new PIButton(MainWin(), "OK", 501, 50,  25, 30, 10);
+but[1] = new PIButton(MainWin(), "Cancel", 502, 50,  25, 100, 10);
+// printf("---DBG--- %lx %lx %lx \n", XtWindow(MainWin()->XtWdg()), 
+//       XtWindow(but[0]->XtWdg()), XtWindow(but[1]->XtWdg()) ); 
+
+scons = new PIConsole(MainWin(), "PIConsole", 4540, 120, 70, 600, 250, 0, 50, true );
+
+// printf("---DBG-2=== %lx %lx % \n", XtWindow(PIXtTopWdg()), 
+//       XtWindow(scons->XtWdg()));
+
+int kkk;
+for(kkk=0; kkk<10; kkk++) { 
+  scons->AddStr("A-B-C-JHGTREWQ====Reza Ansari");
+  scons->AddChar('\n'); 
+  }
+for(kkk=0; kkk<5; kkk++) {
+  scons->AddStr("**** CMV ****", PIVA_Bold);
+  scons->AddStr(" Hello, Comment ca va ? Salam - Bye, Bye ",PIVA_Ital); 
+  scons->AddChar('\n'); 
+  }
+  
+
+scons->AcceptCmd(true,8);
+// RedirectOutStream(scons);
+// RedirectErrStream(scons);
+
+
+ 
+mCurW = NULL;    // Fenetre courante
+SetReady();
+}
+
+/* --Methode-- */
+PITApp::~PITApp()
+{
+  MainWin()->Hide();  // Pb de plantage de ~PIConsole(), delete mScb , 07/2000
+  //  cerr << " Deleting scons ... \n " << endl;
+  if (scons) delete scons;
+  //  cerr << " Deleting cons ... \n " << endl;
+  if (cons) delete cons;
+  //  cerr << " end of  PITApp::~PITApp()... \n " << endl;
+}  
+
+static int lines = 0;
+
+/* --Methode-- */
+void PITApp::Process(PIMessage msg, PIMsgHandler* sender, void* data)
+{
+int i,l;
+char buff[128];
+
+/*   Debug version Motif
+XmNavigationType navtyp;
+Boolean trav;
+
+Arg  wargs[2];
+navtyp = 0;
+trav = FALSE;
+XtSetArg(wargs[0],XmNnavigationType, &navtyp);  
+XtSetArg(wargs[1],XmNtraversalOn, &trav);  
+XtGetValues(((PIWdg*)sender)->XtWdg(), wargs, 2);
+
+printf("-- DBG -- PITApp::Process() Widget= %lx (%lx) \n", (long) ((PIWdg*)sender)->XtWdg(), (long)sender);
+printf(" NavType = %d  (None=%d)  Trav= %d (False=%d) \n", (int)navtyp, (int)XmNONE, (int)trav, (int)FALSE);
+*/
+
+
+if ( ( ModMsg(msg) == PIMsg_Active) || (ModMsg(msg) == PIMsg_Close) ) {
+  PIWdg *sndw;
+  sndw = (PIWdg *)sender;      
+  if (sndw->kind() ==  PIWindow::ClassId)  {
+    if (ModMsg(msg) == PIMsg_Close)  { 
+      printf("PITApp::Process()/Debug : Closing Window %lx \n", (long)sender);
+      delete (PIWindow *)sender;  
+      mCurW = NULL; }
+    else  mCurW = (PIWindow *)sender;
+  }
+}
+else
+  {
+  switch(UserMsg(msg))
+    {
+    case 4540: 
+      if (ModMsg(msg) == PIMsg_OK) 
+ //       printf("Cmd from Console L=%d [%s] \n", strlen((char*)data), (char*)data ); 
+        printf("Cmd from Console \n"); 
+      else 
+        printf("Console Msg= %d Mod = %d \n",UserMsg(msg), ModMsg(msg));
+      break; 
+
+// --------- 1er menu ----------
+    case 10101: 
+      {
+      PIWindow* win = new PIWindow(this, "Console-2", PIWK_normal, 500, 200, 200, 200);
+      win->SetAutoDelChilds(true);
+      win->Show();
+      cons = new PIConsole(win, "PIConsole-2", 4560, 100, 60, 500, 200, 0, 0 );
+      int kkk;
+      for(kkk=0; kkk<20; kkk++) { 
+        cons->AddStr("A-B-C-JHGTREWQ====Reza Ansari");
+        cons->AddChar('\n'); 
+        }
+      for(kkk=0; kkk<25; kkk++) {
+        cons->AddStr("**** CMV ****", PIVA_Bold);
+        cons->AddStr(" Hello, Comment ca va ? Salam - Bye, Bye ",PIVA_Ital); 
+        cons->AddChar('\n'); 
+        }
+      }
+      break;
+    case 10102: 
+      RedirectOutStream(scons);
+      break;
+
+    case 10103: 
+      RedirectOutStream(cons);
+      break;
+
+    case 10104: 
+      RedirectErrStream(scons);
+      break;
+
+    case 10105: 
+      RedirectErrStream(cons);
+      break;
+
+    case 10110 :
+      if (scons) scons->AcceptCmd(true,5);
+      break;
+    case 10111 :
+      if (cons) cons->AcceptCmd(true);
+      break;
+
+    case 10177:          // Sortie d'application
+      Stop();
+      break;
+
+// ----------  2eme menu --------
+  case 10207 :
+    for(l=0; l<3; l++) 
+      cout << "TApp: Test-Cout (K= " << l << ") " << endl ; 
+    break;
+  case 10205 :
+    for(l=0; l<4; l++) 
+      printf("TApp: Test-Redirect Print %d - %d \n", l, lines); lines++;
+    break;
+  case 10206 :
+      printf("TApp: T-Print NNL %d n", lines);
+    break;
+
+  case 10209 :
+    for(l=0; l<2; l++) 
+      cerr << "TApp: CERR--Test (K= " << l << ") " << endl ; 
+    break;
+  case 10208 :
+    for(l=0; l<8; l++) 
+      fprintf(stderr, "TApp: StdErr Redirect  %d - %d \n", l, lines);  lines++;
+    break;
+
+  case 10204 :
+    for(l=0; l<1; l++) {
+      sprintf(buff, "TApp: Line type Reverse No %d ", lines);
+      scons->AddStr(buff, PIVA_Reverse, false);
+      sprintf(buff, "Normal  ");
+      scons->AddStr(buff, PIVA_Def, false);
+      sprintf(buff, "Bold  ");
+      scons->AddStr(buff, PIVA_Bold, false);
+      lines++;
+    }   
+    scons->Refresh();
+    break;
+  
+  case 10202 :
+    for(l=0; l<3; l++) {
+      sprintf(buff, "TApp: Line type Bold No %d \n", lines);
+      scons->AddStr(buff, PIVA_Bold, false);
+      lines++;
+    }   
+    scons->Refresh();
+    break;
+  
+  case 10203 :
+    for(l=0; l<3; l++) {
+      sprintf(buff, "Line type Italique No %d \n", lines);
+      scons->AddStr(buff, PIVA_Ital, false);
+      lines++;
+    }   
+    scons->Refresh();
+    break;
+  
+  case 10201 :
+    for(l=0; l<3; l++) {
+      sprintf(buff, "Tapp: Line type Normal No %d \n", lines);
+      scons->AddStr(buff, PIVA_Def, false);
+      lines++;
+    }   
+    scons->Refresh();
+    break;
+
+
+    default :
+      printf("PIDemoApp::Process() Msg= %d (%d - %d)??? \n", 
+            (int)msg, (int)UserMsg(msg),(int)ModMsg(msg));
+     break;
+    }
+  }
+return;
+}
+
+
+static PITApp * app;
+
+
+int main(int narg, char *arg[])
+{
+
+  // PeidaStarRecoInitiator InitStar;
+
+app = new PITApp(narg, arg);
+app->SetBusy();
+puts("appel de Application.Run() ... ");
+app->SetReady();
+app->Run();
+
+delete app;
+exit(0);
+}
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/Tests/pitgr.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/Tests/pitgr.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/Tests/pitgr.cc	(revision 2309)
@@ -0,0 +1,430 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include <iostream.h>
+
+#include "pisysdep.h"
+
+#include PIAPP_H
+#include PIMENU_H 
+#include PISTDWDG_H 
+#include PIWIN_H
+#include PIPERIODIC_H
+
+#include "pidrawwin.h"
+#include "piscdrawwdg.h"
+#include "piyfxdrw.h"
+#include "piimage.h"
+#include "parradapter.h"
+
+#include "psfile.h"
+
+#include "piimgtools.h"
+#include "pidrwtools.h"
+#include "piaxestools.h"
+
+#include "pisurfdr.h"
+#include "pi3dwdg.h"
+
+
+//  ---------- classe PITApp -----------------------
+class PITApp : public PIApplication {
+public:
+     PITApp(int narg=0, char* arg[]=NULL);
+     ~PITApp();
+     virtual void   Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+
+  PIMenu* m[3];
+  PIText* txt;
+  PIPixmap* zoom;  
+  PICMapView* cmapv;
+  PIWindow *mCurW;
+};
+
+
+/* --Methode-- */
+PITApp::PITApp(int narg, char* arg[])
+: PIApplication(360, 130, narg, arg) 
+{
+
+m[0] = new PIMenu(Menubar(),"Fichier");
+m[0]->AppendItem("Info", 10101);
+m[0]->AppendItem("Close", 10110);
+m[0]->AppendItem("Exit", 10150);
+// On accroche le menu au Menubar
+AppendMenu(m[0]);
+
+// 2eme Menu
+
+m[1] = new PIMenu(Menubar(),"Graphics");
+m[1]->AppendItem("Sin(x)/x", 10201);
+m[1]->AppendItem("YfXDrawer", 10202);
+m[1]->AppendItem("2-Drawers", 10203);
+m[1]->AppendItem("Surf-3D", 10204);
+m[1]->AppendItem("Surf-3D-Color", 10205);
+m[1]->AppendItem("Image", 10206);
+
+AppendMenu(m[1]);
+
+
+m[2] = new PIMenu(Menubar(),"Tools");
+m[2]->AppendItem("ShowImageTools", 10301);
+m[2]->AppendItem("ShowDrawerTools", 10302);
+m[2]->AppendItem("ShowAxesTools", 10303);
+m[2]->AppendItem("PostScript (EPS)", 10305);
+AppendMenu(m[2]);
+
+MainWin()->SetSize(360,130);
+zoom = new PIPixmap(MainWin(), "Zoom", 90, 90, 5, 5);
+// zoom->SetBinding(PIBK_elastic,PIBK_elastic,PIBK_elastic,PIBK_elastic);
+// zoom->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_elastic,PIBK_fixed);
+cmapv = new PICMapView(MainWin(), "CMapView", 350, 25, 5, 100);
+// cmapv->SetBinding(PIBK_elastic,PIBK_elastic,PIBK_elastic,PIBK_elastic);
+cmapv->SetBinding(PIBK_fixed,PIBK_free,PIBK_fixed,PIBK_free);
+// Creation d' zone texte multiligne
+txt = new PIText(MainWin(), "mltext", 250, 90, 105, 5);
+// txt->SetBinding(PIBK_elastic,PIBK_elastic,PIBK_elastic,PIBK_elastic);
+txt->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_fixed,PIBK_free);
+txt->SetMutiLineMode(true);
+txt->SetTextEditable(false);
+txt->SetText("");
+
+SetReady();
+}
+
+/* --Methode-- */
+PITApp::~PITApp()
+{
+for(int i=0; i<3; i++)  delete m[i]; 
+delete txt;
+delete cmapv;
+delete zoom;
+}  
+
+
+static int nbwin = 0;
+static int numpsf = 0;
+static int fgswcol = 0;
+
+static double fsinc(double x) {if ( (x>-1.e-8) && (x<1.e-8) ) return(0.); else return (sin(x)/x);}
+
+/* --Methode-- */
+void PITApp::Process(PIMessage msg, PIMsgHandler* sender, void* data)
+{
+char strg[64];
+int i,j;
+
+ printf("DBG-PITApp::Process() Msg= %d (%d - %d) Sender=%lx (This=%lx) \n", 
+	(int)msg, (int)UserMsg(msg),(int)ModMsg(msg), (long)sender, (long)this);
+
+if ( ( ModMsg(msg) == PIMsg_Active) || (ModMsg(msg) == PIMsg_Close) ) {
+  PIWdg *sndw;
+  sndw = (PIWdg *)sender;      
+  if (sndw->kind() ==  PIWindow::ClassId)  {
+    if (ModMsg(msg) == PIMsg_Close)  { 
+      printf("PITApp::Process()/Debug : Closing Window %lx \n", (long)sender);
+      delete (PIWindow *)sender;  
+      mCurW = NULL; }
+    else  mCurW = (PIWindow *)sender;
+  }
+  else if (sender == this) {
+    printf(" PIMsg_Close from Application !!! \n");
+    return;
+  }
+}
+else
+  {
+  switch(UserMsg(msg))
+    {
+
+// --------- 1er menu ----------
+    case 10101:     
+      txt->SetText("pitgr: PI Graphics Tests \n * 2-D graphics \n * 3-D Graphics \n Image display ");
+      break;
+
+    case 10110 :
+      if (mCurW)  { mCurW->Hide();  delete mCurW;}
+      mCurW = NULL;
+      break;
+
+    case 10150:          // Sortie d'application
+      Stop();
+      break;
+
+
+// ----------  3eme menu --------
+    case 10301 :
+      PIImgTools::ShowPIImgTools();
+      break;
+    case 10302 :
+      PIDrwTools::ShowPIDrwTools();
+      break;
+    case 10303 :
+      PIAxesTools::ShowPIAxesTools();
+      break;
+    case 10305 :
+      if(mCurW) {
+        char buff[64];
+        sprintf(buff, "pigr_%d.eps", numpsf);        numpsf++;
+        printf("Creating EPS File %s (Encapsulated PostScript) \n", buff);
+        PSFile *mps;
+	mps = new PSFile(buff);
+	mCurW->PSPrint(mps,0,0);
+	delete mps;
+        }
+      break;
+
+// ----------  2eme menu --------
+
+    case 10201 :        //  Trace de la fonction sin(x)/x
+      {
+      SetBusy();    // souris -> montre 
+      txt->SetText("PIScDrawWdg Creation\n Sin(x)/x \n Button 1 -> Coord \n  Button 2 Zoom \n <Alt>O <Alt>V \n Try DrawerTools");
+
+      PIFuncDrawer* mfd = new PIFuncDrawer(fsinc);
+      mfd->GetGraphicAtt().SetColAtt(PI_Gold);
+      mfd->GetGraphicAtt().SetLineAtt(PI_NormalLine);
+      nbwin++; sprintf(strg,"2D Graphics (PI W %d)", nbwin);
+      PIWindow* wp = new PIWindow(this, strg, PIWK_normal,  300, 300, 150, 150);
+      wp->SetAutoDelChilds(true);
+      PIScDrawWdg* scd = new PIScDrawWdg(wp, "scwdg-sinc", 300, 300, 0, 0);
+      scd->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_fixed, PIBK_fixed);
+      scd->SetLimits(0.1, 30., -1., 1.);
+      scd->AddScDrawer(mfd,true);
+      PIGraphicAtt gatt;
+      gatt.SetColAtt(PI_Red);
+      scd->BaseDrawer()->ElDrwMgr().ElAddText(2., 0.8, "Y = Sin(x)/x", gatt, 0);
+      scd->SetTitles(" --- PIFuncDrawer (Sin(x)/x) --- ", "");
+      wp->Show();    // On affiche  la fenetre 
+      SetReady();    //  souris->pointeur , on n'est plus occupe
+      }
+      break;
+
+
+    case 10202 :    // Trace Test de PIYfXDrawer
+      {
+      SetBusy();    // souris -> montre 
+      txt->SetText("PIScDrawWdg Creation\n PIYfXDrawer \n Button 1 -> Coord \n  Button 2 Zoom \n <Alt>O <Alt>V \n Try DrawerTools");
+
+      float* vpx = new float[30]; 
+      float* vpy = new float[30]; 
+      int i;   double x;
+      for(i=0; i<30; i++) { x = 8.*i/30;  vpx[i] = x;  vpy[i] = 3*cos(x)+2*sin(x); }
+      PIYfXDrawer* mxyd = new   PIYfXDrawer( new P1DAdapter<float>(vpx, 30, true), 
+                                            new P1DAdapter<float>(vpy, 30, true), true); 
+      mxyd->GetGraphicAtt().SetColAtt(PI_Red);
+      mxyd->GetGraphicAtt().SetMarkerAtt(7, PI_FTriangleMarker);
+
+      nbwin++; sprintf(strg,"2D Graphics (PI W %d)", nbwin);
+      PIWindow* awp = new PIWindow(this, strg, PIWK_normal, 300, 300, 300, 300);
+      PIScDrawWdg* scd = new PIScDrawWdg(awp, "scwdg-YfX", 300, 300, 0, 0);
+      scd->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_fixed, PIBK_fixed);
+      scd->AddScDrawer(mxyd,true);
+      scd->SetTitles(" --- PIYfXDrawer (3*cons(x)+2*sin(x)) --- ", "");
+      awp->SetAutoDelChilds(true);
+      awp->Show();
+      SetReady();
+      }
+      break;
+
+    case 10203 :    // FunDrawer + PIYfXDrawer
+      {
+      SetBusy();    // souris -> montre 
+      txt->SetText("PIScDrawWdg Creation\n PIYfXDrawer + FuncDrawer(Sin(x)/x) \n Button 1 -> Coord \n  Button 2 Zoom \n <Alt>O <Alt>V \n Try DrawerTools");
+
+      float* vpx = new float[30]; 
+      float* vpy = new float[30]; 
+      int i;   double x;
+      for(i=0; i<30; i++) { x = 8.*i/30;  vpx[i] = x;  vpy[i] = 3*cos(x)+2*sin(x); }
+      PIYfXDrawer* mxyd = new   PIYfXDrawer( new P1DAdapter<float>(vpx, 30, true), 
+                                             new P1DAdapter<float>(vpy, 30, true), true); 
+
+      mxyd->GetGraphicAtt().SetColAtt(PI_Magenta);
+      mxyd->GetGraphicAtt().SetMarkerAtt(7, PI_FBoxMarker);
+
+      PIFuncDrawer* mfd = new PIFuncDrawer(fsinc);
+      mfd->GetGraphicAtt().SetColAtt(PI_Blue);
+      mfd->GetGraphicAtt().SetLineAtt(PI_NormalLine);
+
+      nbwin++; sprintf(strg,"2D Graphics (PI W %d)", nbwin);
+      PIWindow* awp = new PIWindow(this, strg, PIWK_normal, 400, 400, 300, 300);
+      PIScDrawWdg* scd = new PIScDrawWdg(awp, "scwdg-YfX", 400, 400, 0, 0);
+      scd->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_fixed, PIBK_fixed);
+      scd->AddScDrawer(mxyd,true);
+      scd->AddScDrawer(mfd,true);
+      scd->SetTitles(" --- PIYfXDrawer + PIFuncDrawer --- ", "");
+      awp->SetAutoDelChilds(true);
+      awp->Show();
+
+      SetReady();
+      }
+      break;
+
+    case 10206 :
+      {
+      SetBusy();    // souris -> montre 
+      txt->SetText("PIImage Creation\n Image Display \n Button 1 -> Coord/value \n  Button 2 Select Rectangle \n Butt on 3 Move \n <Alt>O <Alt>V <Alt>C \n Try ImageTools");
+ 
+      int sx, sy;
+      sx = 400; 
+      sy = 600;
+      printf(" Creating Image (%dx%d) ... ", sx, sy);
+      float* img = new float[sx*sy];
+      int i, j, k, kk, i0, j0;
+      double lamp, amp,x,y;
+      for(k=0; k<sx*sy; k++)   img[k] = 1000.+(random()%200-100);
+//   On genere 500 etoiles
+      for(k=0; k<500; k++) {
+        i0 = 20+random()%(sx-20);
+        j0 = 20+random()%(sy-20);
+        lamp = 2.0+0.012*(random()%100);
+        amp = pow(10., lamp);
+//        if (k%5 == 0)  printf(" DBG %d %d - %g \n", i0, j0, flux);
+        for(i=i0-15; i<i0+15; i++) {
+          if(i<0 || i>=sx) continue;
+          for(j=j0-15; j<j0+15; j++) {
+            if(j<0 || j>=sy) continue;
+            x = i-i0;  y = j-j0;
+            kk = j*sx+i;
+            img[kk] += amp*exp(-(x*x)/7.-(y*y)/8.);
+            }
+	}
+      }
+      printf("  >> OK \n");
+     
+      nbwin++; sprintf(strg,"Image (PI W %d)", nbwin);
+      PIWindow* awp = new PIWindow(this, strg, PIWK_normal, sx, sy, 300, 300);
+      PIImage * pii = new PIImage(awp, "fitsimage", sx, sy, 0, 0);
+      pii->SetBinding(PIBK_fixed, PIBK_fixed, PIBK_fixed, PIBK_fixed);
+      pii->SetZoomWin(zoom, false);
+      pii->SetCMapWin(cmapv, false);
+      pii->ShowCursor(true);
+      awp->SetAutoDelChilds(true);
+      awp->Show();
+      pii->SetImage(new P2DAdapter<float>(img, sx, sy, true), true);
+      SetReady();
+      }
+      break;
+
+
+//    Dessins 3D  
+    case 10204:         
+      {
+      SetBusy();    // souris -> montre 
+      txt->SetText("PIDraw3DWdg Creation\n 3-D Surf Display \n Button 1 \n (Shift) Button 2 Rotate \n Button Zoom \n <Alt>O <Alt>V \n Try DrawerTools");
+
+      printf(" Creating Matrix 80x60  ... ");
+      float* tf = new float[60*80];
+      int i,j,k;
+      double xp,yp,rp;
+      for(i=0; i<80; i++)
+        for(j=0; j<60; j++) { 
+           xp = i-30;   yp = j-20;
+           rp = (xp*xp)/16.+(yp*yp)/9.;
+           tf[j*80+i] = 10.*exp(-rp);
+           xp = i-50;   yp = j-28;
+           rp = (xp*xp)/9.+(yp*yp)/9.;
+           tf[j*80+i] += 4.*exp(-rp);
+        }
+      printf("  >> OK \n");
+
+      nbwin++; sprintf(strg,"3D Surf (PI W %d)", nbwin);
+      PIWindow* awp = new PIWindow(this, strg, PIWK_normal, 500, 500, 200, 200);
+      PISurfaceDrawer* sd = new PISurfaceDrawer(new P2DAdapter<float>(tf, 80, 60, true), true, true, true);
+      PIDraw3DWdg* drw3 = new PIDraw3DWdg(awp, "ex3ddrw", 500, 500, 0, 0);
+      drw3->SetBinding(PIBK_fixed , PIBK_fixed , PIBK_fixed, PIBK_fixed);
+      drw3->AddDrawer3D(sd, false);
+      drw3->SetTitles(" --- PISurfaceDrawer (80x60) --- ", "");
+      awp->SetAutoDelChilds(true);
+      awp->Show();
+      SetReady();
+      }
+      break;
+
+    case 10205:         
+      {
+      SetBusy();    // souris -> montre 
+      txt->SetText("PIDraw3DWdg Creation\n 3-D Surf Display \n Button 1 \n (Shift) Button 2 Rotate \n Button Zoom \n <Alt>O <Alt>V \n Try DrawerTools");
+
+      printf(" Creating Matrix 50x50  ... ");
+      float * tf = new float[2500];
+      int i,j;
+      double xp,yp,rp;
+      for(i=0; i<50; i++)
+        for(j=0; j<50; j++) { 
+           xp = i-15;   yp = j-25;
+           rp = (xp*xp)/16.+(yp*yp)/16.;
+           tf[j*50+i] = 11.*exp(-rp);
+           xp = i-35;   yp = j-15;
+           rp = (xp*xp)/9.+(yp*yp)/9.;
+           tf[j*50+i] += 3.*exp(-rp);
+           xp = i-45;   yp = j-40;
+           rp = (xp*xp)/10.+(yp*yp)/20.;
+           tf[j*50+i] += 6.*exp(-rp);
+        }
+      printf("  >> OK \n");
+
+      nbwin++; sprintf(strg,"PI W# %d 3D Surf", nbwin);
+      PIWindow* awp = new PIWindow(this, strg, PIWK_normal, 500, 500, 200, 200);
+      PISurfaceDrawer* sd = new PISurfaceDrawer(new P2DAdapter<float>(tf, 50, 50, true), true, true, true);
+      if (fgswcol%3 == 0) sd->GetGraphicAtt().SetColMapId(CMAP_COLRJ32);
+      else if (fgswcol%3 == 1) sd->GetGraphicAtt().SetColMapId(CMAP_COLBR32);
+      else sd->GetGraphicAtt().SetColMapId(CMAP_COLRV32);
+      fgswcol++;
+      PIDraw3DWdg* drw3 = new PIDraw3DWdg(awp, "ex3ddrw", 600, 600, 0, 0);
+      drw3->SetBinding(PIBK_fixed , PIBK_fixed , PIBK_fixed, PIBK_fixed);
+      drw3->AddDrawer3D(sd, false);
+      drw3->SetTitles(" --- PISurfaceDrawer (50x50) --- ", "");
+      awp->SetAutoDelChilds(true);
+      awp->Show();
+      SetReady();
+      }
+      break;
+
+    default :
+      printf("PITApp::Process() Msg= %d (%d - %d)??? \n", 
+            (int)msg, (int)UserMsg(msg),(int)ModMsg(msg));
+     break;
+    }
+  }
+return;
+}
+
+
+// ................................................................
+//                   programme principal 
+// ................................................................
+
+int main(int narg, char *arg[])
+{
+
+if ( (narg > 1) && (strcmp(arg[1],"-h") == 0) ) {
+  printf("pitgr : PI 2D Graphics/ 3D Surface plot/ Image Display Tests  \n");
+  printf("  Usage : pitgr [Xt options] \n");
+  }
+
+
+PITApp* app = new PITApp(narg, arg);
+int sx,sy,sxmm,symm,resx,resy;
+PIApplicationPrefCompSize(sx, sy);
+printf("##### pit-main() PrefCompSize= %d %d ##### \n", sx, sy);
+PIApplicationScreenSize(sx, sy);
+printf("##### pit-main() ScreenSize (pixels) = %d %d ##### \n", sx, sy);
+PIApplicationScreenSizeMM(sxmm, symm);
+printf("##### pit-main() ScreenSize (mm) = %d %d ##### \n", sxmm, symm);
+PIApplicationScreenResolution(resx, resy);
+printf("##### pit-main() ScreenResolution (pixel/cm) = %d %d ##### \n", resx, resy);
+PIColorMap* cmap = new PIColorMap(CMAP_GREY32);
+printf("##### pit-main() NbTotColors=%d Already Allocated= %d ##### \n", 
+       cmap->TotNbColors(), cmap->NbAllocColors());
+app->Run();
+
+ printf("Apres app->Run(); \n");
+delete cmap;
+delete app;
+exit(0);
+}
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/Tests/pitst.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/Tests/pitst.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/Tests/pitst.cc	(revision 2309)
@@ -0,0 +1,436 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+/*  Ceci est un programme test des differents composants de PI : PEIDA Interactif */
+/*                 Reza ,  96-98                                                  */
+
+/*   C'est ecrit n'importe comment !     */
+ 
+#include "pisysdep.h"
+
+#include PIAPP_H
+#include PIWIN_H 
+#include PIMENU_H 
+#include PIOPTMENU_H 
+#include PISTDWDG_H 
+#include PIBWDG_H 
+#include PIPIXMAP_H 
+#include PIFILECHO_H 
+#include PILIST_H
+
+#include "piscdrawwdg.h"
+#include "piyfxdrw.h"
+
+/*
+int SysBeep(int n)
+{
+for(int i=0; i<n; i++)  putchar('\007');
+return(0);
+}
+*/
+
+class PITestApp : public PIApplication {
+public:
+	PITestApp(int sx, int sy);
+	~PITestApp();
+
+	virtual void	Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+
+    PIMenu  *m[5];
+    PIMenu  *mc[2];
+    PICheckBox * ckb;
+    PIText * text;
+    PIButton * bouton;
+    PIButton * bouton2, * bouton3, * bouton4, * bouton5;
+    PIButton * bouton11, * bouton12, * bouton13,* bouton14 ,* bouton15 ;
+    PILabel * label;
+    PIScale * scl;
+    PIMenu  * menu;
+    PIOptMenu * opt, * opt2;
+    bool stnewmen[2];
+
+};
+
+
+
+PITestApp::PITestApp(int sx, int sy)
+: PIApplication(550, 350)
+{
+char ans[128];
+   m[0] = new PIMenu(Menubar(),"File");
+   m[0]->AppendItem("Open", 10101);
+   m[0]->AppendItem("Close", 10102);
+   m[0]->AppendItem("New", 10103);
+//   m[0]->AppendItem("ScBar", 10105);
+   m[0]->AppendItem("Quit", 10104);
+
+   m[1] = new PIMenu(Menubar(),"Edit");
+   m[1]->AppendItem("Copier", 10201);
+   m[1]->AppendItem("Coller", 10202);
+   m[1]->AppendItem("Couper", 10203);
+   m[1]->AppendCheckItem("Check It", 10205);
+   mc[0] = new PIMenu(m[1], "Cascade");
+   mc[0]->AppendItem("EdeCas-1", 10221);
+   mc[0]->AppendItem("EdeCas-2", 10222);
+   mc[0]->AppendItem("EdeCas-3", 10223);
+   m[1]->AppendPDMenu(mc[0]);
+
+   m[2] = new PIMenu(Menubar(),"Operation");
+   m[2]->AppendItem("AddItem", 10301);
+   m[2]->AppendItem("DelItemName", 10302);
+   m[2]->AppendItem("DelItemMsg", 10303);
+
+   m[3] = new PIMenu(Menubar(),"Special");
+   m[3]->AppendItem("Spec-Opt1", 10401);
+   m[3]->AppendItem("Spec-Opt2", 10402);
+   m[3]->AppendItem("Spec-Cascade", 10403);
+   mc[1] = new PIMenu(m[3], "Spec-Cascade");
+   mc[1]->AppendItem("Spec-Cas-1", 10441);
+   mc[1]->AppendItem("Spec-Cas-2", 10442);
+   mc[1]->AppendItem("Spec-Cas-3", 10443);
+   m[3]->AppendPDMenu(mc[1]);
+   m[3]->AppendCheckItem("Checkable", 10414);
+
+   m[4] = new PIMenu(Menubar(),"AddMenu2");
+   m[4]->AppendItem("option-A", 10501);
+   m[4]->AppendItem("option-B", 10502);
+   m[4]->AppendItem("option-C", 10503);
+
+   AppendMenu(m[0]);
+   AppendMenu(m[1]);   
+   AppendMenu(m[2]);
+
+  ckb = new PICheckBox(this->MainWin(), "CheckBox", 166, 60, 20, 10, 10);
+  text = new PIText(this->MainWin(), "TEXTE", 180, 30, 20,40);
+  text->SetMsg(7440);
+  label  = new PILabel(this->MainWin(), "Label", 180, 20, 20,80);
+  label->SetBorderWidth(1);
+  bouton = new PIButton(this->MainWin(), "->Menu", 33, 60, 25, 20, 120);
+  bouton2 = new PIButton(this->MainWin(), "Dialog", 333, 60, 25, 100, 120);
+  bouton3 = new PIButton(this->MainWin(), "ScDraw", 433, 60, 25, 180, 120);
+  bouton4 = new PIButton(this->MainWin(), "Pixmap", 133, 60, 25, 260, 120);
+  bouton5 = new PIButton(this->MainWin(), "List", 533, 60, 25, 340, 120);
+
+  scl = new PIScale(this->MainWin(), "Scale", 88, kSDirRtoL, 200, 20, 10, 150);
+  scl->SetMinMax(5, 45);
+
+  int psx, psy;
+  PrefCompSz(psx, psy);
+  cout << " Creation bouton 11 -14 avec Sx,Sy= " << psx << " , " << psy << endl;
+
+  bouton11 = new PIButton(this->MainWin(), "AddMen-1", 1133, psx*1.5, psy, 20, 250);
+  bouton12 = new PIButton(this->MainWin(), "AddMen-2", 1233, psx*1.5, psy, 40+psx*1.5, 250);
+  stnewmen[0] = stnewmen[1] = false;
+  bouton13 = new PIButton(this->MainWin(), "Ready/Bloc", 1333, psx*1.5, psy, 20, 300);
+  bouton14 = new PIButton(this->MainWin(), "TS-BWdg", 1433, psx*1.5, psy, 40+psx*1.5, 300);
+  bouton15 = new PIButton(this->MainWin(), "TS-MenuIt", 1533, psx*1.5, psy, 60+psx*3, 300);
+
+//  XSync(PIXDisplay(), FALSE);
+//  printf("Creation PIPUMenu DoIt-1... \n");   gets(ans);
+  menu = new PIMenu(this->MainWin(), "myMenu");
+//  XSync(PIXDisplay(), FALSE);
+//  printf("Apres Creation PIPUMenu -AppendItem() 1 ... \n");   gets(ans);
+
+  menu->AppendItem("DoIt-1", 4401);
+//  XSync(PIXDisplay(), FALSE);
+//  printf("Apres Creation PIPUMenu -AppendItem() 2 ... \n");   gets(ans);
+
+  menu->AppendItem("DoIt-2", 4402);
+  menu->AppendItem("DoIt-25", 4425);
+  menu->AppendItem("DoIt-26", 4426);
+  menu->AppendItem("Check-33", 4433);
+
+//  XSync(PIXDisplay(), FALSE);
+//  printf("Creation PIPUMenu Copier ... \n");   gets(ans);
+
+
+  opt = new PIOptMenu(this->MainWin(), "Option-Menu-1", 120, 25, 10, 200);
+  opt->AppendItem("Linear", 5601);
+  opt->AppendItem("Log.", 5602);
+  opt->AppendItem("Sqrt", 5603);
+  opt->AppendItem("Expon", 5604);
+  opt->AppendItem("Polyn", 5605);
+
+  string ops = "Sqrt";
+  opt->SetValueStr(ops);
+
+  opt2 = new PIOptMenu(this->MainWin(), "Option-Menu-1", 120, 25, 150, 200);
+  opt2->AppendItem("Copier", 80201);
+  opt2->AppendItem("Coller", 80202);
+  opt2->AppendItem("Couper", 80203);
+  opt2->AppendItem("Undo", 80204);
+  opt2->AppendItem("Select-All", 80205);
+  
+}
+
+PITestApp::~PITestApp()
+{
+  delete ckb;
+  delete text;
+  delete label;
+  delete bouton;
+  delete bouton2;
+  delete bouton3;
+  delete bouton4;
+  delete bouton5;
+  delete bouton11;
+  delete bouton12;
+  delete bouton13;
+  delete bouton14;
+  delete bouton15;
+  delete menu;
+  delete m[0]; delete m[1]; delete m[2]; delete m[3]; delete m[4];
+  delete mc[0]; delete mc[1];
+  delete opt;
+  delete opt2;
+  delete scl;
+}
+
+/* ........................................................... */
+/*                         Classe ScSample                     */
+/* ........................................................... */
+
+class ScSample : public PIScDrawWdg {
+public:
+  ScSample(PIContainerGen *par, char *nom,
+           int sx=10, int sy=10, int px=0, int py=0);
+  virtual ~ScSample();
+};
+
+static double fpol(double x) {return (0.3*x*x*x-x*x+7.);}
+static double fx2(double x) {return (0.5*x*x);}
+
+ScSample::ScSample(PIContainerGen *par, char *nom,
+                  int sx, int sy, int px, int py)
+:PIScDrawWdg(par, nom, sx, sy, px, py)
+
+{
+// Definition des limites
+SetLimits(-3,5,-10,15);
+
+// Creation et ajout d'un drawer de fonctions
+PIFuncDrawer* mfd = new PIFuncDrawer(fpol);
+mfd->GetGraphicAtt().SetColAtt(PI_Blue);
+mfd->GetGraphicAtt().SetLineAtt(PI_NormalLine);
+AddScDrawer(mfd,true);
+PIFuncDrawer* mfd2 = new PIFuncDrawer(fx2);
+mfd2->GetGraphicAtt().SetColAtt(PI_Red);
+mfd2->GetGraphicAtt().SetLineAtt(PI_NormalLine);
+AddScDrawer(mfd2,true);
+SetAxesFlags(kAxesDflt);
+}
+
+ScSample::~ScSample()
+{
+}
+
+static ScSample *scs1, *scs2, *scs3;
+static PIScrollBar *scb, *scb2;
+
+static PIWindow * wp3, *wp4, *wp5, *wp6;
+static PIPixmap * pxm;
+static unsigned char  pixels[25000];
+static PIFileChooser *pfc;
+static bool  fgpxm = false;
+static bool  fgt = false;
+static bool  fgt2 = false;
+static bool  fgt3 = false;
+
+static PIListX * pil;
+
+void
+PITestApp::Process(PIMessage msg, PIMsgHandler* sender, void* data)
+{
+  static int x = 0;
+  static PIMessage numsg=8800;
+
+  char truc[256];
+  sprintf(truc,"< %ld - %d (%d)>",msg,x++, (int)((PIWdgGen *)sender)->kind());
+  this->label->SetLabel(truc);
+  sprintf(truc,"[%d] Msg= %ld (%d-%d) Kind=(%d)  Data= (%ld - %lx)",x, msg, (int)UserMsg(msg),
+         (int)ModMsg(msg), (int)((PIWdgGen *)sender)->kind(), (long)data, (long)data);
+  puts(truc);
+
+  if (ModMsg(msg) == PIMsg_Active) 
+     printf("Process: Setting active Wdg (%lx) \n", (long)sender); 
+
+  if (ModMsg(msg) == PIMsg_Close)
+    {
+    printf("Close Message received (Sender= %lx)\n", (long)sender);
+    return;
+    }
+
+  msg = UserMsg(msg);
+  if (msg == 33) { ckb->SetState(true);  menu->Show(); }
+    
+  if (msg == 133)
+    {
+    if (!fgpxm)  { wp3->Show();  fgpxm = true; }
+    for (int i=0; i<25000; i++)  pixels[i] = rand()%256;
+    if ((x % 3) == 0)  pxm->SetColMapId(CMAP_GREY32);
+    if ((x % 3) == 1)  pxm->SetColMapId(CMAP_COLRJ32);
+    if ((x % 3) == 2)  pxm->SetColMapId(CMAP_COLBR32);
+    }
+
+  if (msg == 333)  wp4->Show();
+  if ( (msg == 6001) || (msg == 6002) )  wp4->Hide();
+
+  if (msg == 433)
+    {
+    if (fgt2) { wp5->Hide();   fgt2 = false; }
+    else { wp5->Show();   fgt2 = true; }
+    }
+
+  if (msg == 533)
+    {
+    if (fgt3) { wp6->Hide(); fgt3 = false; }
+    else { wp6->Show(); fgt3 = true; }
+    }
+
+  if ( (msg == 1133) || (msg == 1233) )  {  // On ajoute ou on enleve un  menu du menu-bar
+    int idxmen = (msg-1133)/100;
+    cout << " Add/Remove Menu idxmen= " << idxmen << " Bool= " 
+         << Menubar()->IsSensitive(m[idxmen+3])  << " ( " << stnewmen[idxmen] << ")" << endl;
+    if ( Menubar()->IsSensitive(m[idxmen+3]) ) 
+      { Menubar()->RemoveMenu(m[idxmen+3]); stnewmen[idxmen] = false; }
+    else  { Menubar()->AppendMenu(m[idxmen+3]); stnewmen[idxmen] = true; }
+  }
+
+  if (msg == 1333) {  // Changement de sensibilite de Menu-Bar (par SetBusy())
+    cout << " SetSens() Menubar,  State= " <<  GetState()  << endl;
+    if (GetState() != kReadyState)  SetReady();
+    else  SetBlocked();
+  }
+
+  if (msg == 1533) {  // Changement de sensibilite de  Cascade
+    cout << " ChangeSensitivity()  Cascade Bool= " <<  m[1]->IsSensitive("Cascade")  << endl;
+    if (m[1]->IsSensitive("Cascade") )  m[1]->SetSensitivity("Cascade", false); 
+    else  m[1]->SetSensitivity("Cascade", true); 
+  }
+
+  if (msg == 1433) {  // Changement de sensibilite de  BaseWidget (ScSample)
+    if (scs1->IfSensitive())  scs1->SetUnSensitive();
+    else scs1->SetSensitive();
+  }
+//  if (msg == 555)   (this->menu)->Show(); 
+
+  if (msg == 10105)  scb->SetSlSize(atoi(((char *)text->GetText().c_str())));
+  if (msg == 10104)  Stop();
+  if (msg == 10101)  { pfc->AcceptNewFile(false); pfc->Show(); }
+  if (msg == 10103)  { pfc->AcceptNewFile(true); pfc->Show(); }
+
+  if ((msg == 10205) || (msg == 166))  { // CheckItem Menu  or checkbox
+    cout << "PITestApp::Process CheckItem/Box Menu (" << msg 
+         << ") State=" <<  *((bool *)data) << endl; 
+  }
+
+  if (msg == 10301)  
+   { 
+   numsg++;    
+   string nit;
+   nit = text->GetText();
+   m[1]->AppendItem((char *)nit.c_str(), numsg); 
+   opt2->SetValue(numsg);
+   }
+
+  if (msg == 10302)  { m[1]->DeleteItem((char *)text->GetText().c_str()); }
+  if (msg == 10303)  
+    {
+    string nit;
+    nit = text->GetText();
+    long ml =  atol(nit.c_str());
+    m[1]->DeleteItemMsg(ml);
+    opt2->SetValue(10201);
+    }
+
+
+  if (msg > 9000) printf("PITestApp::MenubarReturn: %d --> %lx \n", msg, (long)data);
+  if (msg == 5000)  
+    { 
+    if (data) 
+      { 
+      printf("PITestApp::Process(5000) OK from PIFileChooser: %s \n", (char *)data); 
+    }
+    else printf("PITestApp::Process(5000) Cancel from PIFileChooser (data=NULL) \n");  }
+
+  if ((msg / 100) == 56) 
+    printf("PITestApp::Process(%d) : %lx \n", (int)msg, (long)data); 
+
+  if (msg == 8811) printf("PITestApp::Process(8811) ScrollBar( %d ) \n", *( (int*)data) );
+  else if (msg == 8821) printf("PITestApp::Process(8821) ScrollBar( %d ) \n", *( (int*)data) );
+
+}
+
+int main(int narg, char *arg[])
+{
+  int mii;
+
+  if (narg < 2) {
+    printf("Usage pitst str1 [str2 ....] \n");  exit(1); 
+  }
+
+  PITestApp * app;
+  app = new PITestApp(350, 350);
+
+
+  wp4 = new PIWindow(app, "Window-4", PIWK_dialog,  200, 200, 350, 350);
+  PIButton bt1(wp4, "OK", 6001, 60, 30, 20, 160);
+  PIButton bt2(wp4, "Cancel", 6002, 60, 30, 100, 160);
+  bt1.SetBinding(PIBK_elastic,PIBK_elastic,PIBK_elastic,PIBK_elastic);
+  bt2.SetBinding(PIBK_elastic,PIBK_elastic,PIBK_elastic,PIBK_elastic);
+  PILabel  lb1(wp4, "Editable", 40, 30, 10, 10);
+    lb1.SetBinding(PIBK_elastic,PIBK_elastic,PIBK_elastic,PIBK_elastic);
+  PIText  tx1(wp4, "A00", 100, 30, 60, 10);  
+    tx1.SetBinding(PIBK_elastic,PIBK_elastic,PIBK_elastic,PIBK_elastic);
+  tx1.SetText("Hello");
+  tx1.SetTextEditable(false);
+  //  PILabel  lb2(wp4, "", 30, 20, 10, 40);
+  PIText  tx2(wp4, "A11", 180, 100, 15, 50);
+  tx2.SetMutiLineMode(true);
+  tx2.SetText(" Bonjour, \n Comment ca va ? \n A demain. ");
+    tx2.SetBinding(PIBK_elastic,PIBK_elastic,PIBK_elastic,PIBK_elastic);
+
+  wp3 = new PIWindow(app, "Window-3", PIWK_normal, 200, 200, 350, 350);
+  pxm = new PIPixmap(wp3, "myPixmap", 150, 150, 10, 10);
+  pxm->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_fixed,PIBK_fixed );
+  pxm->SetPixmap(pixels, 150, 150);
+
+  wp5 = new PIWindow(app, "Window-5", PIWK_normal,  420, 450, 200, 200);
+  scs1 = new ScSample(wp5, "ScSample", 200, 200, 0, 0);
+  scs1->SetBinding(PIBK_elastic,PIBK_elastic,PIBK_elastic,PIBK_elastic);
+  scs2 = new ScSample(wp5, "ScSample", 160, 160, 220, 20);
+  printf("DBG-WP5 (A) , SCS2, SzC %d %d , Sz %d %d Pos %d %d \n", wp5->XSize(),
+         wp5->YSize(), scs2->XSize(), scs2->YSize(),scs2->XPos(), scs2->YPos() ); 
+//  scs2->SetBinding(PIBK_elastic,PIBK_fixed,PIBK_fixed,PIBK_elastic);
+  scs2->SetBinding(PIBK_elastic,PIBK_elastic,PIBK_elastic,PIBK_elastic);
+  printf("DBG-WP5 (B) , SCS2, SzC %d %d , Sz %d %d Pos %d %d \n", wp5->XSize(),
+         wp5->YSize(), scs2->XSize(), scs2->YSize(),scs2->XPos(), scs2->YPos() ); 
+
+  scb = new PIScrollBar(wp5, "ScBar", 8811, kSDirUpDown, 15, 420, 405, 0);
+  scb->SetBinding(PIBK_free,PIBK_fixed,PIBK_fixed,PIBK_fixed);
+  scb->ActivateDrag(true);
+  scb2 = new PIScrollBar(wp5, "ScBar", 8821, kSDirRtoL, 420, 15, 0, 425);
+  scb2->SetBinding(PIBK_fixed,PIBK_free,PIBK_fixed,PIBK_fixed);
+
+  scs3 = new ScSample(wp5, "ScSample", 200, 200, 100, 220);
+  scs3->SetBinding(PIBK_elastic,PIBK_elastic,PIBK_elastic,PIBK_elastic);
+
+  pfc = new PIFileChooser(app,"FileChooser", 5000); 
+//  pfc->SetPath("/exp/eros/ImagRed/");
+
+  wp6 = new PIWindow(app, "Window-List", PIWK_normal,  200, 250, 300, 400);
+  pil = new PIListX(wp6, "MyList", 200, 250, 0, 0);
+  pil->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_fixed,PIBK_fixed);
+  for(mii=1; mii<narg; mii++)
+    {
+//    printf("AppendItem[%d] - %s (%ld) \n", mii, arg[mii],  3330+mii);  
+     pil->AppendItem(arg[mii], 3330+mii);  
+//    puts("Append-OK");
+    }
+  pil->SetMultipleSelect(true);
+  pil->SelectItem("user.cc");
+//  Int32 ioNumber = 100;
+  app->Run();
+  delete app;
+  exit(0);
+}
Index: /tags/V_Dec2002/SophyaPI/PI/Tests/xp0.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/Tests/xp0.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/Tests/xp0.cc	(revision 2309)
@@ -0,0 +1,107 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <iostream.h>
+
+
+#include "pisysdep.h"
+
+#include PIAPP_H
+#include PIMENU_H 
+#include PISTDWDG_H 
+
+//  ----- Declaration de notre classe PIApplication (PITApp) -------
+//  ----------- PIApplication (PITApp) class declaration -----------
+
+class PITApp : public PIApplication {
+public:
+     PITApp(int narg=0, char* arg[]=NULL);
+     ~PITApp();
+     virtual void   Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+
+private :
+  PIMenu * m;
+  PIText * txt;
+};
+
+
+
+
+/* ........................................................... */
+/*               Classe PITApp (methodes)                      */
+/* ........................................................... */
+
+
+/* --Methode-- */
+PITApp::PITApp(int narg, char* arg[])
+: PIApplication(260, 150, narg, arg)
+
+{
+//  Menus, les numeros ds AppendItem sont les numeros de messages
+//  qui seront passes a Process() et permettent d'identifier l'action
+
+//  Creation du menu  
+m = new PIMenu(Menubar(),"Fichier");
+m->AppendItem("Get Text", 10101);
+m->AppendItem("Exit", 10105);
+// On accroche le menu au Menubar
+AppendMenu(m);
+
+// Creation d'une zone texte multi-lignes editable
+txt = new PIText(MainWin(), "mltext", 250, 140, 5, 5);
+txt->SetMutiLineMode(true);
+txt->SetTextEditable(true);
+txt->SetText("");
+
+SetReady();
+}
+
+/* --Methode-- */
+PITApp::~PITApp()
+{
+delete m; 
+delete txt; 
+}  
+
+/* --Methode-- */
+void PITApp::Process(PIMessage msg, PIMsgHandler* sender, void* /*data*/)
+{
+// Gestion des actions en fonctions des messages
+switch(UserMsg(msg))    {
+
+    case 10101:     // On recupere le texte du PIText
+      cout << "\n PITApp::Process( 10101, ...) - PIText content : " << endl;
+      cout << txt->GetText() << endl;
+      break;
+
+    case 10105:          // Sortie d'application
+      Stop();
+      break;
+
+    default :
+     break;
+    
+  }
+return;
+}
+
+
+// ................................................................
+//                   programme principal 
+// ................................................................
+
+int main(int narg, char *arg[])
+{
+if ( (narg > 1) && (strcmp(arg[1],"-h") == 0) ) {
+  printf("xp0 : simple PI example program \n");
+  printf("  Usage : xp0 [Xt options] \n");
+  }
+//  Creation de l'objet application et appel de Run()
+PITApp * app = new PITApp(narg, arg);
+puts("appel de Application.Run() ... ");
+app->Run();
+
+delete app;
+exit(0);
+}
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/Tests/xp1.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/Tests/xp1.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/Tests/xp1.cc	(revision 2309)
@@ -0,0 +1,193 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <iostream.h>
+
+#include "pisysdep.h"
+
+#include PIAPP_H
+#include PIMENU_H 
+#include PISTDWDG_H 
+#include PIWIN_H
+
+//  ----- Declaration de la classe ArgsWind : Fenetre de dialogue -------
+class ArgsWind : public PIWindow {
+public :
+                ArgsWind(PIApplication *par);
+                ~ArgsWind();
+  virtual void  Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+
+private:
+  PILabel  * mLab[2];
+  PIButton * mBut[2];
+  PIText * mText[2];
+  };
+
+//  ----- Declaration de notre classe PIApplication (PITApp) -------
+class PITApp : public PIApplication {
+public:
+     PITApp(int narg=0, char* arg[]=NULL);
+     ~PITApp();
+     virtual void   Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+
+private :
+  PILabel *lab;
+  PIMenu * m[2];
+  ArgsWind *mAW;
+};
+
+
+/* ........................................................... */
+/*              Classe ArgsWindow (methodes)                   */
+/* ........................................................... */
+
+/* --Methode-- */
+ArgsWind::ArgsWind(PIApplication *par)
+: PIWindow((PIMsgHandler *)par, "Args", PIWK_dialog, 100, 100, 150, 150)
+{
+int bsx, bsy;
+
+// On definit la taille a partir de la taille par defaut des composantes 
+PIApplicationPrefCompSize(bsx, bsy);
+// On redefinit la taille de la fenetre
+SetSize(bsx*4, bsy*4);
+
+// Creation de champs "labels"
+mLab[0] = new PILabel(this, "Arg-1:", bsx, bsy, bsx/3, bsy/4); 
+mLab[1] = new PILabel(this, "Arg-2", bsx, bsy, bsx/3, bsy/4 + (bsy/4+bsy) );
+
+// Creation de champs textes 
+mText[0] = new PIText(this, "UsArg1", bsx*2, bsy, bsx+(bsx*2/3), bsy/4);
+mText[0]->SetText("Hello ");
+mText[1] = new PIText(this, "UsArg2", bsx*2, bsy, bsx+(bsx*2/3), 
+                      bsy/4 + (bsy/4+bsy) );
+mText[1]->SetText("1. -1.");
+
+// Creation de bouton d'action 
+//  Attention : Numero de message pour Process()
+mBut[0] = new PIButton(this, "GetText",  555, bsx*1.5, bsy, bsx*0.25, 2.75*bsy);
+mBut[1] = new PIButton(this, "Dismiss", 777, bsx*1.5, bsy, 2.25*bsx, 2.75*bsy);
+
+//  Taille et position proportionnelles a la taille de la fenetre pour les elements
+for(int i=0; i<2; i++) {
+  mLab[i]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+  mText[i]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+  }
+for(int ii=0; ii<2; ii++) 
+  mBut[ii]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+}
+
+/* --Methode-- */
+ArgsWind::~ArgsWind()
+{
+for(int i=0; i<2; i++)
+  {
+  delete mLab[i];
+  delete mText[i];
+  }
+
+delete mBut[0]; 
+delete mBut[1]; 
+}
+
+
+/* --Methode-- */
+void ArgsWind::Process(PIMessage msg, PIMsgHandler* /*sender*/, void* /*data*/)
+{
+
+switch (UserMsg(msg))
+  {
+  case 777:   // Bouton dismiss - On s'en va 
+    this->Hide();
+    break;
+
+  case 555:    // Bouton GetText
+// On recupere les textes des  PIText :
+    cout << "\n  ArgsWind::Process() " << endl; 
+    cout << " Text-0 = " << mText[0]->GetText() << endl;
+    cout << " Text-1 = " << mText[1]->GetText() << endl;
+    break;    
+  }
+    
+return;
+}
+
+/* ........................................................... */
+/*               Classe PITApp (methodes)                      */
+/* ........................................................... */
+
+/* --Methode-- */
+PITApp::PITApp(int narg, char* arg[])
+: PIApplication(250, 60, narg, arg)
+{
+
+m[0] = new PIMenu(Menubar(),"Fichier");
+m[0]->AppendItem("ShowArgs", 10101);
+m[0]->AppendItem("HideArgs", 10102);
+m[0]->AppendItem("Exit", 10105);
+// On accroche le menu au Menubar
+AppendMenu(m[0]);
+
+m[1] = new PIMenu(Menubar(),"Edit");
+m[1]->AppendItem("Cut", 10201);
+m[1]->AppendItem("Copy", 10202);
+m[1]->AppendItem("Paste", 10203);
+// On accroche le menu au Menubar
+AppendMenu(m[1]);
+
+// Creation d' un label
+lab = new PILabel(this->MainWin(), "xp1 - PI example program", 240, 40, 5, 10);
+// Fenetre de dialogue
+mAW = new ArgsWind(this);
+SetReady();
+}
+
+/* --Methode-- */
+PITApp::~PITApp()
+{
+delete m[0]; 
+delete m[1]; 
+delete lab;
+delete mAW;
+}  
+
+/* --Methode-- */
+void PITApp::Process(PIMessage msg, PIMsgHandler* sender, void* /*data*/)
+{
+// Gestion des actions en fonctions des messages
+
+switch(UserMsg(msg))    {
+    case 10101 :     // Apparition de la fenetre de dialogue
+      mAW->Show();
+      break;
+    case 10102 :     // Apparition de la fenetre de dialogue
+      mAW->Hide();
+      break;
+    case 10105:          // Sortie d'application
+      Stop();
+      break;
+
+    default :
+      cout << "PITApp::Process() Msg= " << msg << " UserMsg= " 
+           << UserMsg(msg) << " ModMsg= " << ModMsg(msg) << endl;
+     break;    
+  }
+return;
+}
+// ................................................................
+//                   programme principal 
+// ................................................................
+
+int main(int narg, char *arg[])
+{
+if ( (narg > 1) && (strcmp(arg[1],"-h") == 0) ) {
+  printf("xp0 : simple PI example program \n");
+  printf("  Usage : xp0 [Xt options] \n");
+  }
+//  Creation de l'objet application et appel de Run()
+PITApp * app = new PITApp(narg, arg);
+puts("appel de Application.Run() ... ");
+app->Run();
+
+delete app;
+exit(0);
+}
Index: /tags/V_Dec2002/SophyaPI/PI/Tests/xp2.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/Tests/xp2.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/Tests/xp2.cc	(revision 2309)
@@ -0,0 +1,256 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <iostream.h>
+
+#include "pisysdep.h"
+#include PIAPP_H
+#include PIWIN_H 
+#include PIMENU_H 
+#include PISTDWDG_H 
+#include PIBWDG_H
+
+
+/*  Exemple d'utilisation PIBaseWdg - 
+    Creation d'une nouvelle composante graphique  */
+
+// ---- Declaration de la classe ExBWdg --------
+class ExBWdg : public PIBaseWdg
+{
+public:
+// Les methodes ...
+
+                  ExBWdg(PIContainerGen *par, char *nom,
+                         int sx=10, int sy=10, int px=0, int py=0);
+  virtual         ~ExBWdg();
+
+// Traitement des evenements   
+  virtual void   Draw(PIGraphic* g, int x0, int y0, int dx, int dy);
+
+  virtual void   But1Press(int x, int y);
+  virtual void   Ptr1Move(int x, int y);
+  virtual void   But1Release(int x, int y);
+  virtual void   Keyboard(int key, PIKeyModifier kmod);
+
+private:
+  struct rect {
+    PIGrCoord x,y;
+    PIGrCoord dx,dy;
+    PIColors col;
+  };
+  typedef list<rect> RectList;  // Liste de rectangles
+  RectList rlist;
+  int mcol;
+  int x1, x2, y1, y2;
+};
+
+
+/* ........................................................... */
+/*     Classe ExBWdg (Implementation des methodes)             */
+/* ........................................................... */
+
+/* --Methode-- */
+ExBWdg::ExBWdg(PIContainerGen *par, char *nom,
+                       int sx, int sy, int px, int py) 
+: PIBaseWdg(par, nom, sx, sy, px, py)
+
+{
+mcol = 0;  // numero de couleur
+x1 = x2 = y1 = y2 = 0;
+ActivateKeyboard();  
+ActivateButton(1);
+ActivateMove(1);     
+}
+
+/* --Methode-- */
+ExBWdg::~ExBWdg()
+{
+}
+ 
+
+/* --Methode-- */
+void ExBWdg::Draw(PIGraphicGen* g, int /*x0*/, int /*y0*/, int /*dx*/, int /*dy*/)
+{
+EraseWindow();
+g->SelForeground(PI_Black);
+g->SelFont(PI_NormalSizeFont, PI_BoldFont);
+g->DrawString(10,20,"Button-1 to draw rectangles ");
+g->DrawString(10,40,"<Alt>C to clear all ");
+
+RectList::iterator it;
+
+//  Boucle sur les rectangles
+for (it = rlist.begin(); it != rlist.end(); it++) {
+  g->SelForeground((*it).col);  // selection couleur
+  g->DrawFBox((*it).x, (*it).y, (*it).dx, (*it).dy );  // trace de rectangle 
+  }
+return;
+}
+
+static PIColors collist[15] = {
+                 PI_Black, PI_Grey,
+                 PI_Red, PI_Blue, PI_Green,  
+                 PI_Yellow, PI_Magenta, 
+                 PI_Cyan, PI_Turquoise, PI_NavyBlue, 
+                 PI_Orange, PI_SiennaRed, PI_Purple,  
+                 PI_LimeGreen, PI_Gold };
+
+static char strbuff[128];
+/* --Methode-- */
+void ExBWdg::But1Press(int x, int y)
+{
+SelPointerShape(PI_CrossPointer);
+// Initialisation pour trace d'un rectangle elastique  (en mode XOR)
+mWGrC->SelForeground(PI_Magenta);
+mWGrC->SelGOMode(PI_GOXOR);
+mWGrC->SelLine(PI_ThinLine);
+x1 = x2 = x;
+y1 = y2 = y;
+return;
+}
+/* --Methode-- */
+void ExBWdg::Ptr1Move(int x, int y)
+{
+// On efface le rectangle 
+mWGrC->DrawBox(x1, y1, x2-x1, y2-y1);
+x2 = x;   y2 = y;
+// On trace le nouveau
+mWGrC->DrawBox(x1, y1, x2-x1, y2-y1);
+}
+
+/* --Methode-- */
+void ExBWdg::But1Release(int x, int y)
+{
+SelPointerShape(PI_ArrowPointer);
+// On efface le rectangle 
+mWGrC->DrawBox(x1, y1, x2-x1, y2-y1);
+mWGrC->SelGOMode(PI_GOCopy);
+// On ajoute le rectangle dans la liste
+rect r;
+r.col = collist[mcol];
+mcol = (mcol+1)%15;  
+r.x = x1; r.y = y1;  r.dx = x-x1;  r.dy = y-y1;
+rlist.push_back(r);
+mWGrC->SelForeground(r.col);
+mWGrC->DrawFBox(r.x, r.y, r.dx, r.dy);
+return;
+}
+
+/* --Methode-- */
+void ExBWdg::Keyboard(int key, PIKeyModifier kmod)
+{
+
+if ( (kmod == PIKM_Alt) && ( (key == 'c') || (key == 'C') ) ) {
+// On efface tout 
+  rlist.erase(rlist.begin(), rlist.end());
+// On rafraichit la fenetre
+  Refresh();
+}
+return;
+}
+
+
+//  ----- Declaration de notre classe PIApplication (PITApp) -------
+//  ----------- PIApplication (PITApp) class declaration -----------
+
+class PITApp : public PIApplication {
+public:
+     PITApp(int narg=0, char* arg[]=NULL);
+     ~PITApp();
+     virtual void   Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+
+private :
+  PIMenu * m;
+  PILabel *lab;
+};
+
+
+
+
+/* ........................................................... */
+/*               Classe PITApp (methodes)                      */
+/* ........................................................... */
+
+
+/* --Methode-- */
+PITApp::PITApp(int narg, char* arg[])
+: PIApplication(250, 60, narg, arg)
+
+{
+//  Menus, les numeros ds AppendItem sont les numeros de messages
+//  qui seront passes a Process() et permettent d'identifier l'action
+
+//  Creation du menu  
+m = new PIMenu(Menubar(),"Fichier");
+m->AppendItem("New BaseWdg", 10101);
+m->AppendItem("Exit", 10105);
+// On accroche le menu au Menubar
+AppendMenu(m);
+// Creation d' un label
+lab = new PILabel(this->MainWin(), "xp2 - PI New Widget creation", 240, 40, 5, 10);
+
+
+SetReady();
+}
+
+/* --Methode-- */
+PITApp::~PITApp()
+{
+delete m; 
+delete lab; 
+}  
+
+static int nbwin = 0;
+/* --Methode-- */
+void PITApp::Process(PIMessage msg, PIMsgHandler* sender, void* /*data*/)
+{
+// Gestion des actions en fonctions des messages
+switch(UserMsg(msg))    {
+
+    case 10101:     // On cree une fenetre et une ExBWdg et on les affiche
+      {
+      nbwin++;
+      char strg[64];
+      sprintf(strg,"Window %d - ExBwdg", nbwin);
+      PIWindow* wp = new PIWindow(this, strg, PIWK_normal,  250, 250, 150, 150);
+      wp->SetAutoDelChilds(true);
+      ExBWdg* exb  = new ExBWdg(wp, "bwdg", 250, 250, 0, 0);
+      exb->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_fixed,PIBK_fixed);
+      wp->Show();
+      }
+      break;
+
+    case 10105:          // Sortie d'application
+      Stop();
+      break;
+
+    default :
+     break;
+    
+  }
+return;
+}
+
+
+// ................................................................
+//                   programme principal 
+// ................................................................
+
+int main(int narg, char *arg[])
+{
+if ( (narg > 1) && (strcmp(arg[1],"-h") == 0) ) {
+  printf("xp0 : simple PI example program \n");
+  printf("  Usage : xp0 [Xt options] \n");
+  }
+//  Creation de l'objet application et appel de Run()
+PITApp * app = new PITApp(narg, arg);
+puts("appel de Application.Run() ... ");
+app->Run();
+
+delete app;
+exit(0);
+}
+
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/Tests/xp3.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/Tests/xp3.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/Tests/xp3.cc	(revision 2309)
@@ -0,0 +1,299 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include <iostream.h>
+
+#include "pisysdep.h"
+
+#include PIAPP_H
+#include PIMENU_H 
+#include PISTDWDG_H 
+#include PIWIN_H
+#include PIPERIODIC_H
+
+#include "piscdrawwdg.h"
+#include "piimage.h"
+#include "parradapter.h"
+
+#include "psfile.h"
+
+#include "piimgtools.h"
+#include "pidrwtools.h"
+
+#include "pisurfdr.h"
+#include "piyfxdrw.h"
+
+#include "pi3dwdg.h"
+
+//  ---------- classe PITApp -----------------------
+class PITApp : public PIApplication {
+public:
+     PITApp(int narg=0, char* arg[]=NULL);
+     ~PITApp();
+     virtual void   Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+
+  PIMenu* m[2];
+  PIPixmap* zoom;  
+  PIWindow *mCurW;
+};
+
+
+/* --Methode-- */
+PITApp::PITApp(int narg, char* arg[])
+: PIApplication(250, 130, narg, arg) 
+{
+
+// Menu creation 
+// First menu 
+m[0] = new PIMenu(Menubar(),"Fichier");
+// Show Image Tools window
+m[0]->AppendItem("ShowImageTools", 10101);    
+// Show drawer Tools (Graphic Att.) window
+m[0]->AppendItem("ShowDrawerTools", 10102);   
+// Creating eps file from a graphic / image
+m[0]->AppendItem("PostScript (EPS)", 10105);  
+m[0]->AppendItem("Exit", 10150);
+// Appending menu to menu bar 
+AppendMenu(m[0]);
+
+// 2nd Menu
+m[1] = new PIMenu(Menubar(),"Graphics");
+m[1]->AppendItem("2-Drawers", 10201); //  2D drawer superposition 
+m[1]->AppendItem("Surf-3D", 10202);   //  Surface (3D) drawer
+m[1]->AppendItem("Image", 10203);     //  Image view object
+// Appending menu to menu bar 
+AppendMenu(m[1]);
+
+// Creating Zoom PixMap for PIImage
+zoom = new PIPixmap(MainWin(), "Zoom", 150, 120, 5, 5);
+zoom->SetBinding(PIBK_elastic,PIBK_elastic,PIBK_elastic,PIBK_elastic);
+mCurW = NULL;
+SetReady();
+}
+
+/* --Methode-- */
+PITApp::~PITApp()
+{
+for(int i=0; i<2; i++)  delete m[i]; 
+delete zoom;
+}  
+
+static int nbwin = 0;
+static int numpsf = 0;
+static int fgswcol = 0;
+
+// Sin(x)/x function 
+static double fsinc(double x) 
+{ if ( (x>-1.e-8) && (x<1.e-8) ) return(0.); else return (sin(x)/x); }
+// fill 50x50 array
+static float *  surf_fill_matx();   
+// fill sx * sy array with random stars
+static float *  img_fill_array(int sx, int sy);   
+
+/* --Methode-- */
+void PITApp::Process(PIMessage msg, PIMsgHandler* sender, void* data)
+{
+char strg[64];
+int i,j;
+
+// Defining ative window 
+if ( ModMsg(msg) == PIMsg_Active) {
+  PIWdg *sndw = (PIWdg *)sender;      
+  if (sndw->kind() ==  PIWindow::ClassId) mCurW = (PIWindow *)sender;
+  return;
+}
+
+switch(UserMsg(msg))
+  {
+// --------- 1st menu ----------
+  case 10101 :
+    PIImgTools::ShowPIImgTools();    // Image tools window
+    break;
+  case 10102 :
+    PIDrwTools::ShowPIDrwTools();    // drawer tool (graphic att. window)
+    break;
+
+  case 10105 :                       // Creating eps file
+    if(mCurW) {
+      char buff[64];
+      sprintf(buff, "xp3_%d.eps", numpsf);        numpsf++;
+      printf("Creating EPS File %s (Encapsulated PostScript) \n", buff);
+      PSFile *mps;
+      mps = new PSFile(buff);
+      mCurW->PSPrint(mps,0,0);
+      delete mps;
+      }
+      break;
+
+  case 10150:                        // Exit 
+    Stop();
+    break;
+
+
+// ----------  2nd menu --------
+  case 10201 :    // FunDrawer + PIYfXDrawer
+    {
+    // Creating two tables y[k] = 3 cos(x[k]) + 2 sin(x[k])
+    float* vpx = new float[30]; 
+    float* vpy = new float[30]; 
+    int i;   double x;
+    for(i=0; i<30; i++) { x = 8.*i/30;  vpx[i] = x;  vpy[i] = 3*cos(x)+2*sin(x); }
+      
+    // Using PIYfXDrawer and P1DAdapter<T> 
+    PIYfXDrawer* mxyd = new PIYfXDrawer(new P1DAdapter<float>(vpx, 30, true), 
+                                  new P1DAdapter<float>(vpy, 30, true), true); 
+    // Changing graphic attributes for the drawer
+    mxyd->GetGraphicAtt().SetColAtt(PI_Magenta);
+    mxyd->GetGraphicAtt().SetMarkerAtt(7, PI_FBoxMarker);
+
+    // Using PIFuncDrawer and changing its attributes
+    PIFuncDrawer* mfd = new PIFuncDrawer(fsinc);
+    mfd->GetGraphicAtt().SetColAtt(PI_Blue);
+    mfd->GetGraphicAtt().SetLineAtt(PI_NormalLine);
+
+    nbwin++; sprintf(strg,"2D Graphics (PI W %d)", nbwin);
+    // Creating a window 
+    PIWindow* awp = new PIWindow(this, strg, PIWK_normal, 400, 400, 300, 300);
+    // Creating a PIScDrawWdg (manages drawers with zoom, ... capabilities)
+    PIScDrawWdg* scd = new PIScDrawWdg(awp, "scwdg-YfX", 400, 400, 0, 0);
+    scd->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_fixed, PIBK_fixed);
+
+    // Adding the two drawers to  PIScDrawWdg
+    scd->AddScDrawer(mxyd,true);
+    scd->AddScDrawer(mfd,true);
+    scd->SetTitles(" --- PIYfXDrawer + PIFuncDrawer --- ", "");
+    awp->SetAutoDelChilds(true);
+    awp->Show();
+    }
+   break;
+
+   case 10202:   //  3D surface drawer         
+    {
+    float * tf = surf_fill_matx();   // Creating and filling a 50x50 Matrix 
+    // Creating a new window
+    nbwin++; sprintf(strg,"PI W# %d 3D Surf", nbwin);
+    PIWindow* awp = new PIWindow(this, strg, PIWK_normal, 500, 500, 200, 200);
+    // Creating a 3-D surface drawer , using 2D array adapter (P2DAdapter<float>)
+    PISurfaceDrawer* sd = new PISurfaceDrawer(
+                  new P2DAdapter<float>(tf, 50, 50, true), true, true, true);
+    // Selecting color map
+    if (fgswcol%3 == 0) sd->GetGraphicAtt().SetColMapId(CMAP_COLRJ32);
+    else if (fgswcol%3 == 1) sd->GetGraphicAtt().SetColMapId(CMAP_COLBR32);
+    else sd->GetGraphicAtt().SetColMapId(CMAP_GREY32);
+    fgswcol++;
+    // Creating a 3D Widget (managing 3D-Drawers, rotation , ... )
+    PIDraw3DWdg* drw3 = new PIDraw3DWdg(awp, "ex3ddrw", 600, 600, 0, 0);
+    drw3->SetBinding(PIBK_fixed , PIBK_fixed , PIBK_fixed, PIBK_fixed);
+    // Adding the drawer
+    drw3->AddDrawer3D(sd, false);
+    drw3->SetTitles(" --- PISurfaceDrawer (50x50) --- ", "");
+    // Showing the window
+    awp->SetAutoDelChilds(true);
+    awp->Show();
+    }
+    break;
+
+  case 10203 :     // Image display
+    {
+    int sx, sy;
+    sx = 400; 
+    sy = 600;
+    float * img = img_fill_array(sx, sy);   // Creating and filling a 400x600 array 
+   
+    // Creating a new window  
+    nbwin++; sprintf(strg,"Image (PI W %d)", nbwin);
+    PIWindow* awp = new PIWindow(this, strg, PIWK_normal, sx, sy, 300, 300);
+    // Creating an image view object PIImage
+    PIImage * pii = new PIImage(awp, "fitsimage", sx, sy, 0, 0);
+    pii->SetBinding(PIBK_fixed, PIBK_fixed, PIBK_fixed, PIBK_fixed);
+    pii->SetZoomWin(zoom, false);  // assigning zoom Pixmap 
+    pii->ShowCursor(true);
+    // Showing the window
+    awp->SetAutoDelChilds(true);
+    awp->Show();
+    // Assigning data to PIImage object, using 2D array adapter P2DAdapter<float>
+    pii->SetImage(new P2DAdapter<float>(img, sx, sy, true), true);
+    }
+    break;
+
+    default :
+//      printf("PITApp::Process() Msg= %d (%d - %d)??? \n", 
+//            (int)msg, (int)UserMsg(msg),(int)ModMsg(msg));
+     break;
+    }
+  
+return;
+}
+
+
+
+// ................................................................
+//                     main program 
+// ................................................................
+
+int main(int narg, char *arg[])
+{
+if ( (narg > 1) && (strcmp(arg[1],"-h") == 0) ) {
+  printf("xp3 : PI graphic object example program \n");
+  printf("  Usage : xp3 [Xt options] \n");
+  }
+
+// Creating and running the application
+PITApp* app = new PITApp(narg, arg);
+app->Run();
+
+delete app;
+exit(0);
+}
+
+// -------------------------------------------------------
+// ---- test function to fill 50x50 matrix ----
+static float *  surf_fill_matx()
+{
+float * tf =   new float[2500];
+int i,j;
+double xp,yp,rp;
+for(i=0; i<50; i++)
+  for(j=0; j<50; j++) { 
+    xp = i-15;   yp = j-25;
+    rp = (xp*xp)/16.+(yp*yp)/16.;
+    tf[j*50+i] = 11.*exp(-rp);
+    xp = i-35;   yp = j-15;
+    rp = (xp*xp)/9.+(yp*yp)/9.;
+    tf[j*50+i] += 3.*exp(-rp);
+    xp = i-45;   yp = j-40;
+    rp = (xp*xp)/10.+(yp*yp)/20.;
+    tf[j*50+i] += 6.*exp(-rp);
+    }
+return(tf);
+}
+
+//---- test function to fill an image array (with random stars) ----
+static float *  img_fill_array(int sx, int sy)
+{
+  float* img = new float[sx*sy];
+  int i, j, k, kk, i0, j0;
+  double lamp, amp,x,y;
+  for(k=0; k<sx*sy; k++)   img[k] = 1000.+(random()%200-100);
+//   On genere 500 etoiles
+  for(k=0; k<500; k++) {
+    i0 = 20+random()%(sx-20);
+    j0 = 20+random()%(sy-20);
+    lamp = 2.0+0.012*(random()%100);
+    amp = pow(10., lamp);
+//        if (k%5 == 0)  printf(" DBG %d %d - %g \n", i0, j0, flux);
+    for(i=i0-15; i<i0+15; i++) {
+      if(i<0 || i>=sx) continue;
+      for(j=j0-15; j<j0+15; j++) {
+	if(j<0 || j>=sy) continue;
+	x = i-i0;  y = j-j0;
+	kk = j*sx+i;
+	img[kk] += amp*exp(-(x*x)/7.-(y*y)/8.);
+      }
+    }
+  }
+  return(img);
+}
+
Index: /tags/V_Dec2002/SophyaPI/PI/exclude
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/exclude	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/exclude	(revision 2309)
@@ -0,0 +1,30 @@
+piperiodmac.cc
+pifontmac.cc
+piapplmac.cc
+pibwdgmac.cc
+picmapmac.cc
+picontainermac.cc
+pifilechomac.cc
+pigraphmac.cc
+pilistmac.cc
+pimenubarmac.cc
+pimenumac.cc
+pioptmenumac.cc
+pipixmapmac.cc
+pippapplmac.cc
+pippwindowmac.cc
+pistdwdgmac.cc
+piwdgmac.cc
+piwindowmac.cc
+pippapplmac.cc
+pipplist.cc
+pippmenubar.cc
+pippoptmenu.cc
+pippviewadapter.cc
+pippwindowmac.cc
+piupdattachment.cc
+pierrdisp.cc
+piup.cc
+piup_def.cc
+xdispim.c
+piup.c
Index: /tags/V_Dec2002/SophyaPI/PI/exclude_dpc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/exclude_dpc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/exclude_dpc	(revision 2309)
@@ -0,0 +1,30 @@
+piperiodmac.cc
+pifontmac.cc
+piapplmac.cc
+pibwdgmac.cc
+picmapmac.cc
+picontainermac.cc
+pifilechomac.cc
+pigraphmac.cc
+pilistmac.cc
+pimenubarmac.cc
+pimenumac.cc
+pioptmenumac.cc
+pipixmapmac.cc
+pippapplmac.cc
+pippwindowmac.cc
+pistdwdgmac.cc
+piwdgmac.cc
+piwindowmac.cc
+pippapplmac.cc
+pipplist.cc
+pippmenubar.cc
+pippoptmenu.cc
+pippviewadapter.cc
+pippwindowmac.cc
+piupdattachment.cc
+pierrdisp.cc
+piup.cc
+piup_def.cc
+xdispim.c
+piup.c
Index: /tags/V_Dec2002/SophyaPI/PI/lut.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/lut.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/lut.cc	(revision 2309)
@@ -0,0 +1,120 @@
+// Classe Look-Up-Table  pour convertir image en entree ds
+// une table de couleur.
+//       Classe LUT              R. Ansari  05/95
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "machdefs.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+#include "lut.h"
+
+
+/* --Methode-- */
+
+LUT::LUT(double min, double max, unsigned short ncol, int typ, int ntable) 
+{
+int nlev;
+
+bornes=NULL;
+nlev = ncol-2;
+if (nlev < 1)  nlev = 1;
+bornes = new double[nlev+1];
+
+if (bornes == NULL)  return;
+type = typ;  nLevel = nlev;
+table = NULL;  
+tablenbin = 0;
+SetLut(min, max, typ);
+return;
+}
+
+/* --Methode-- */
+LUT::~LUT()
+{
+if (type<0)  return;
+delete[] bornes;
+delete[] table;
+}
+
+/* --Methode-- */
+void LUT::SetLut(double min, double max, int typ, int ntable)
+{
+
+if(  (typ != kLutType_Lin)  && (typ != kLutType_Log)
+  && (typ != kLutType_Sqrt) && (typ != kLutType_Square)
+  )  typ = kLutType_Lin;
+type = typ;
+if (max <= min)  max = min+1.;
+if (nLevel > 0)
+  {
+  int i;
+  double dx;
+  double dlx;
+  switch (typ)
+    {
+    case kLutType_Lin :
+      dx = (max-min)/(double)nLevel;
+      for(i=0; i<nLevel; i++)
+        bornes[i] = min+(double)i*dx;
+      break;
+    case kLutType_Log :
+      dlx = log(max-min) / (double)nLevel;
+      for(i=0; i<nLevel; i++)
+        bornes[i] = min+(double)exp((double)i*dlx);
+      break;
+    case kLutType_Sqrt :
+      dlx = sqrt(max-min) / (double)nLevel;
+      for(i=0; i<nLevel; i++)
+        bornes[i] = min+((double)i*dlx)*((double)i*dlx);
+      break;
+    case kLutType_Square :
+      dlx = (max-min)*(max-min) / (double)nLevel;
+      for(i=0; i<nLevel; i++)
+        bornes[i] = min+(double)sqrt((double)i*dlx);
+      break;
+    default:
+      for(i=0; i<nLevel; i++)
+        bornes[i] = min;
+      break;
+    }
+  bornes[nLevel] = max; 
+  }
+else  bornes[0] = 0.5*(min+max);
+ComputeTable((ntable > nLevel) ? ntable : tablenbin);
+return; 
+}
+
+/* --Methode-- */
+void LUT::Print()
+{
+int i;
+
+printf("LUT_Info: Type= %d NLevel= %d Min,Max= %g %g \n",
+       type, nLevel, bornes[0], bornes[nLevel]);
+for(i=0; i<=nLevel; i++)
+  printf("..Bornes[%d] = %g \n", i, bornes[i]);
+return;
+}
+
+/* --Methode-- */
+unsigned short LUT::Apply(double x)
+{
+int i;
+for(i=0;i<=nLevel;i++)  
+  if (x < bornes[i])  return(i);
+return(nLevel+1);
+}
+
+/* --Methode-- */
+void LUT::ComputeTable(int nt)
+{
+if (nt <= 0) nt = 16*(nLevel+2);
+else if (nt < (nLevel+2))  nt = (nLevel+2);
+tablenbin = nt;
+table = new unsigned short [nt-2];
+tablebinwidth = (Max()-Min())/(nt-2);
+double x = Min()+0.5*tablebinwidth;
+for(int i=0; i<nt-2; i++)  { table[i] = Apply(x); x += tablebinwidth; }
+}
Index: /tags/V_Dec2002/SophyaPI/PI/lut.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/lut.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/lut.h	(revision 2309)
@@ -0,0 +1,55 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe Look-Up-Table  pour convertir image en entree ds
+// une table de couleur.
+//       Classe LUT              R. Ansari  05/95
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef LUT_SEEN
+#define LUT_SEEN
+
+// LUT : Look-Up-Table avec nLevel bins entre min et max
+// Apply retourne * 0 < min   * nLevel+1 > max 
+// et de 1 a nLevel pour min<=x<max
+
+// Type de lut possibles (Seul Lineaire implemente 05/95
+enum {kLutType_Lin=1, kLutType_Log=2, kLutType_Sqrt=3, kLutType_Square=4};
+
+class LUT 
+{
+public:
+  
+  LUT(double min, double max, unsigned short ncol=16, int typ=kLutType_Lin, int ntable=0);
+  ~LUT();
+  void SetLut(double min, double max, int typ=kLutType_Lin, int ntable=0);
+  void Print();
+  unsigned short Apply(double x);
+  inline unsigned short ApplyFast(double x)
+    { 
+    if (x < Min())  return(0);
+    if (x >= Max() )  return(nLevel+1);  
+    int k = (int)((x-Min())/tablebinwidth);
+    return(table[k]); 
+    } 
+
+  inline double Min() { return(bornes[0]); };
+  inline double Max() { return(bornes[nLevel]); };
+  inline int Type() { return(type); };
+  inline int NCol() { return(nLevel+2); };
+
+protected:
+  void ComputeTable(int nt);
+
+  int type;
+  int nLevel;
+  double * bornes;
+  int tablenbin;
+  unsigned short * table;
+  double tablebinwidth;
+
+};
+
+#endif
+
+
+
+  
Index: /tags/V_Dec2002/SophyaPI/PI/objlist.list
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/objlist.list	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/objlist.list	(revision 2309)
@@ -0,0 +1,61 @@
+lut.o
+parradapter.o
+pi3ddrw.o
+pi3dwdg.o
+piapplgen.o
+piapplx.o
+piaxes.o
+piaxestools.o
+pibwdggen.o
+pibwdgx.o
+picmap.o
+picmapgen.o
+picmapview.o
+picmapx.o
+picons.o
+picontainergen.o
+picontainerx.o
+pidrawer.o
+pidrawwin.o
+pidrwtools.o
+pieldrw.o
+pievthandler.o
+pifilechogen.o
+pifilechox.o
+pifontgen.o
+pifontx.o
+pigraph3d.o
+pigraphgen.o
+pigraphps.o
+pigraphuc.o
+pigraphx.o
+pigratt.o
+pigrcoord.o
+piimage.o
+piimgtools.o
+pilineatt.o
+pilistgen.o
+pilistx.o
+pimenubargen.o
+pimenubarx.o
+pimenugen.o
+pimenux.o
+pimsghandler.o
+pioptmenugen.o
+pioptmenux.o
+piperiodx.o
+pipixmapgen.o
+pipixmapx.o
+piscdrawwdg.o
+pistdwdggen.o
+pistdwdgx.o
+pistzwin.o
+pisurfdr.o
+pitherm.o
+piwdggen.o
+piwdgx.o
+piwindowgen.o
+piwindowx.o
+pixtbase.o
+piyfxdrw.o
+psfile.o
Index: /tags/V_Dec2002/SophyaPI/PI/parradapter.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/parradapter.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/parradapter.cc	(revision 2309)
@@ -0,0 +1,510 @@
+//     Classes ArrayAdapter           R. Ansari  05/98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+// #include "ctimer.h"   Pour mesure TCPU 
+#include "parradapter.h"
+
+//++
+// Class	P1DArrayAdapter
+// Lib		PI
+// include	parradapter.h
+//
+//	Adaptateur de tableaux 1-D . La méthode "Value(i)" doit être redéfinie
+//	dans une classe dérivée.
+//
+//--
+//++
+// Links	Voir aussi
+// P2DArrayAdapter
+// P1DAdapter<T>
+//--
+
+//++
+// Titre	Constructeur, méthodes
+//--
+//++
+// P1DArrayAdapter(int sz)
+//	Constructeur - Tableau 1D de taille "sz"
+// double  Value(int i)
+//	Retourne la valeur de l'element "i" - virtuelle pure - doit etre 
+//	surchargee dans une classe derivee.
+// int Size()
+//	Retourne la taille du tableau
+// void DefineXCoordinate(double x0, double dx)
+//	Definition de l'axe des coordonnees correspondant a l'indice du tableau
+//	a partir d'un offser "x0" et d'un increment "dx"
+// double X(int i)
+//	Retourne l'abcisse de l'element "i"
+//--
+
+/* --Methode-- */
+P1DArrayAdapter::P1DArrayAdapter(int sz)
+{
+mSize=sz;
+DefineXCoordinate(0, 1.);
+}
+
+/* --Methode-- */
+P1DArrayAdapter::~P1DArrayAdapter()
+{
+}
+
+/* --Methode-- */
+void P1DArrayAdapter::DefineXCoordinate(double x0, double dx)
+{
+mOx = x0;  mDx = dx;
+}
+
+/* --Methode-- */
+double P1DArrayAdapter::X(int i)
+{
+return(mOx+mDx*i);
+}
+
+
+//++
+// Class	P2DArrayAdapter
+// Lib		PI
+// include	parradapter.h
+//
+//	Adaptateur de tableaux 2-D . La méthode "Value(i,j)" doit être redéfinie
+//	dans une classe dérivée.
+//
+//--
+//++
+// Links	Voir aussi
+// P1DArrayAdapter
+// P2DAdapter<T>
+//--
+
+//++
+// Titre	Constructeur, méthodes
+//--
+//++
+// P2DArrayAdapter(int sx=0, int sy=0)
+//	Constructeur - Tableau 2D "sx * sy"
+// void ConfigureAxes(bool invx=false, bool invy=false, bool exy=false, \
+//                    int sx=-1, int sy=-1)
+//	Definit la configuration des axes - Les axes X et Y peuvent etre
+//	inverses, et echanges. Si "sx" et "sy" sont positifs, ils definissent
+//	les nouvelles valeurs de la taille du tableau.
+// GetAxesConfiguration(bool& invx, bool& invy, bool& exy)
+//	Renvoie la configuration des axes.
+// DefineXYCoordinates(double x0, double y0, double dx, double dy)
+//	Definit le systeme de coordonnees associe aux deux axes du tableau,
+//	a partir d'un offser et d'un increment.
+// double Value(int ix, int iy)
+//	Renvoie la valeur du tableau en "(i,j)" - Doit etre definie par les 
+//	classes derivees.
+// void XYfromxy(int ix, int iy, double& x, double& y)
+//	Coordonnees "x,y" a partir d'indice du tableau
+//--
+
+/* --Methode-- */
+P2DArrayAdapter::P2DArrayAdapter(int sx, int sy)
+{
+sX = sx; sY = sy; 
+sgnX = sgnY = 1;
+offX = offY = 0;
+invX = invY = eXY = false;
+DefineXYCoordinates(0.,0.,1.,1.);
+SetInfoStringFunction(NULL);
+}
+
+/* --Methode-- */
+P2DArrayAdapter::~P2DArrayAdapter()
+{
+}
+
+/* --Methode-- */
+void P2DArrayAdapter::ConfigureAxes(bool invx, bool invy, bool exy, int sx, int sy)
+{
+invX = invx;  invY = invy;  eXY = exy; 
+if ( (sx > 0) && (sy > 0) )   { sX = sx; sY = sy; }
+if (invX) { sgnX = -1;  offX = sX-1; } 
+else { sgnX = 1; offX = 0; }
+if (invY) { sgnY = -1;  offY = sY-1; } 
+else { sgnY = 1; offY = 0; }
+}
+
+/* --Methode-- */
+void P2DArrayAdapter::DefineXYCoordinates(double x0, double y0, double dx, double dy)
+{
+mOx = x0;   mOy = y0;
+mDx = dx;   mDy = dy;
+}
+
+/* --Methode-- */
+void P2DArrayAdapter::XYfromxy(int ix, int iy, double& x, double& y)
+{
+x = mOx+ix*mDx;
+y = mOy+iy*mDy; 
+}
+
+static char ibuff[256];
+
+/* --Methode-- */
+char * P2DArrayAdapter::InfoString(int ix, int iy)
+{
+  double x,y;
+  this->Coord(ix, iy, x, y);
+  char * isr = "";
+  if (ISFunc != NULL)  isr = ISFunc(this, ix, iy);
+  sprintf(ibuff,"X= %g Y= %g  Pix= %g %s   ", 
+          x, y , (*this)(ix, iy), isr);
+  return (ibuff);
+}
+
+/* --Methode-- */
+int P2DArrayAdapter::CheckDyn(double& min, double& max, double& moy, double& sig, int& nbnul, int& nbsat, int vit)
+{
+// TIMEF ; 
+double m = 0.;
+double s = 0.;
+double dv; 
+
+int n9 = 0;
+int n0 = 0;
+
+if (min >= max) { min = -9.e69; max = 9.e69; }
+double minpix = max;
+double maxpix = min; 
+double pixv;
+// printf("DEBUG_CHECKDYN-IN %d - %g %g ", vit, min, max);
+
+int n = 0;
+if (vit < 1) vit = 1;
+if (sX*sY/vit < 1000) {
+  vit = sX*sY/1000;
+  if (vit < 1) vit = 1;
+}
+
+// printf(" -> vit=%d \n", vit);
+for(int j=0; j<sY; j++) 
+  for(int i=0; i<sX; i++)   {
+    if (++n % vit != 0)  continue;
+    pixv = Value(i,j);
+    if (pixv <= max && pixv >= min) {  
+      if (pixv < minpix)  minpix = pixv;
+      if (pixv > maxpix)  maxpix = pixv; 
+      dv = (double)pixv;
+      m += dv;  s += (dv*dv);
+      }
+    else  {  
+      if (pixv > max)  n9++;
+      if (pixv < min)  n0++; 
+    }
+  }
+
+nbnul = n0*vit;  nbsat = n9*vit;
+min = minpix;  max = maxpix; 
+
+n -= (n0+n9);
+if (n > 0)
+  { dv = (double)n;  m /= dv;  s = s/dv - m*m;
+  if (s>0.)  s = sqrt(s);  else s = 0.;
+  moy = m;  sig = s; }
+else { moy = 0.;  sig = -1.; }
+
+// printf("DEBUG_CHECKDYN: %d %g %g - %g %g \n", n, min, max, moy, sig);
+return(n);
+}
+
+
+/* --Methode-- */
+void P2DArrayAdapter::ComputeLut_PicHisto(double& min, double& max, int nbsig, double fracmax)
+{
+// TIMEF ; 
+int MINNBIN = 64;
+int MAXNBIN = 1024;
+
+int nbin = sX*sY/10;
+nbin = (nbin < MINNBIN) ? MINNBIN : ((nbin > MAXNBIN) ? MAXNBIN : nbin );
+int vitesse = sX*sY / 20000;
+vitesse = (vitesse < 1) ? 1 : ((vitesse > 25) ? 25 : vitesse );
+
+
+//  Variable decrivant l'histogramme 
+double minhis, maxhis, binwidth;
+int under,over,tothis;
+int_4 *phis;
+int_4 *q;
+
+double MINDYNAMIC = 1.e-48;          /* Gamme dynamique minimale (MaxAff-MinAff)*/
+double FRACPIC = 0.6065;            /*  Valeur de exp(-0.5)   */
+
+
+
+if ( min >= (max-MINDYNAMIC) ) { 
+  int nbnul, nbsat, nok;
+  double moy, sig; 
+  nok = CheckDyn(min, max, moy, sig, nbnul, nbsat, vitesse);
+  if (nok < 1) { min=0.; max = 1.;  return; }
+  }
+if ( min >= (max-MINDYNAMIC) )  max = min+MINDYNAMIC;
+minhis = min;
+maxhis = max;
+binwidth = (maxhis-minhis) / nbin;
+if (binwidth < MINDYNAMIC/MINNBIN) { 
+  binwidth = MINDYNAMIC/MINNBIN;
+  maxhis = nbin*binwidth + minhis;
+  }
+// printf("DEBUG nbin minhis maxhis binwidth = %d %g %g %g \n", nbin, minhis, maxhis, binwidth);
+
+/* allocation dynamique de memoire et mise a zero de l'histogramme */
+phis = new int_4[nbin];
+for ( q=phis ; q<phis+nbin ; *q++ = 0 )  ;
+under = over = tothis = 0;
+
+//  Boucle sur les pixels   
+//  Pour aller plus vite, on prend un pixel sur vitesse   
+int kk = 0;
+int bin;
+for(int j=0; j<sY; j++)
+  for(int i=0; i<sX; i++) {
+    if ( (++kk % vitesse) != 0) continue;
+   /* remplissage de l'histogramme */
+    bin = (int)((Value(i, j) - minhis) / binwidth) ;
+    if ( bin < 0 )  under++;
+    else  {
+      if (bin < nbin) { (*(phis+bin))++; tothis++; }
+      else   over++; 
+      }
+    }     /*  Fin de for : Boucle sur les pixels   */
+
+/*  On verifie qu'il y a eu une entree ds l'histo */
+if (tothis <= 0)
+  { delete[] phis;  return; }
+  
+/* recherche du maximum */
+int binmax = -1 ; 
+int hmax = -1 ; 
+q = phis;
+for (kk = 0 ; kk < nbin ;  kk++, q++ )
+  if ( *(q) > hmax ) {hmax = *(q) ; binmax = kk ;}
+
+if ( (binmax < 0) || (binmax >= nbin) )
+  { delete[] phis;  return; }
+
+
+/*   On va chercher le sigma du fond  SigmaLeft, SigmaRight */
+int hmin = (int) ( (double)(hmax) * FRACPIC ) ;
+
+int sigr = 0;
+q = phis+binmax;
+while ( ((*q) > hmin) && (sigr < (nbin-binmax)) )  { sigr++;  q++; }
+int sigl = 0;
+q = phis+binmax;
+while ( ((*q) > hmin) && (sigl < binmax) )  { sigl++; q--; }
+
+
+if (nbsig == 0) nbsig = 1;
+if (nbsig < 0)  {  /*   On considere le cas ou NbSigmas est negatif   */
+  if ( (bin = binmax+nbsig*sigl) < 0 )  bin = 0;
+  min = minhis + (double)bin*binwidth;
+  if ( (bin = binmax-nbsig*sigr) >= nbin ) bin = nbin-1;
+  max = minhis + (double)bin*binwidth;
+  if (max < (min+MINDYNAMIC))  max = min+MINDYNAMIC;
+  delete[] phis;  return; 
+  }
+
+// NbSigma positif 
+if ( (bin = binmax+nbsig*sigl) >= nbin ) {
+  min = minhis + binmax*binwidth;
+  max = maxhis;
+  if (max < (min+MINDYNAMIC))  max = min+MINDYNAMIC;
+  delete[] phis;  return;
+  }
+
+min = minhis + bin*binwidth;
+
+/*   Calcul du nb de pixel entre MinAff et ValSat  */
+int nbpix = 0;
+for( q = phis+bin ; q < phis+nbin ; q++)  nbpix += (*q);
+nbpix = (int_4)((double)nbpix * fracmax);
+int nbpix2 = 0; q = phis+bin; 
+int k = bin;
+while( (nbpix2 < nbpix) && (k < nbin) )  
+  { nbpix2 += (*q); k++; q++; }
+
+max = minhis + (double)k*binwidth;
+delete[] phis;
+if (max < (min+MINDYNAMIC))  max = min+MINDYNAMIC;
+
+return;
+}
+
+
+/* --Methode-- */
+unsigned char * P2DArrayAdapter::ComputePixmap(LUT* lut, int ofx, int ofy, int zm, 
+                int xwsz, int ywsz, unsigned char * opix, int * oxsp, int * oysp)
+{
+// TIMEF ; 
+unsigned char *pix, *pp, ucp;
+int zmm=1;
+int npx, npy, nppx, nppy, nszp, oszp;
+int i,j,k,l;
+double vpx;
+
+/*
+printf("Debug_ComputePixmap off= %d %d zm=%d Size=(%d,%d) \n", 
+      ofx, ofy, zm, XSize(), YSize());
+*/
+
+if ( (XSize() <= 0) || (YSize() <= 0) || (lut == NULL) || (ofx < 0) || (ofy < 0) ) 
+  { *oxsp = *oysp = 0; return(NULL); }
+
+npx = XSize()-ofx;
+npy = YSize()-ofy;
+
+if ((zm == 0) || (zm == -1))  zm = 1;
+
+if (zm >= 1)
+  {
+  if (npx > (xwsz/zm))  npx = xwsz/zm; 
+  if (npy > (ywsz/zm))  npy = ywsz/zm;
+  nppx = npx*zm;   nppy = npy*zm;
+  }
+else
+  {
+  zmm = -zm;
+  nppx = npx/zmm;   nppy = npy/zmm;
+  if (nppx > xwsz)  nppx = xwsz; 
+  if (nppy > ywsz)  nppy = ywsz;
+  npx = nppx*zmm;   npy = nppy*zmm; 
+  }
+
+oszp = (*oxsp)*(*oysp);
+nszp = nppx*nppy;
+if ( oszp != nszp )
+  {
+  if (opix)  delete[] opix;
+  pix = new unsigned char[nppx*nppy];
+  if (pix == NULL)  { *oxsp = *oysp = 0; ; return(NULL); }
+  }
+else  pix = opix;
+*oxsp = nppx; *oysp = nppy;
+
+/*
+printf("Debug_ComputePixmap %d %d %d (%d-%d %d-%d)\n", 
+      ofx, ofy, zm, npx,nppx, npy,nppy);
+*/
+
+pp = pix;
+if (eXY) { // Echange Axe X,Y 
+  if (zm == 1)  {  // Pas de zoom  
+    for(j=ofy; j<ofy+npy; j++)
+      for(i=ofx; i<ofx+npx; i++) 
+        { *pp = (unsigned char) lut->ApplyFast( 
+                this->Value(j*sgnX+offX, i*sgnY+offY));  
+           pp++; }
+    }
+  else if (zm < -1) {       // Compression 
+    double fv = (double)(zmm*zmm); 
+    for(j=ofy; j<ofy+npy; j+=zmm)
+      for(i=ofx; i<ofx+npx; i+=zmm) {
+        vpx = 0;
+        for(l=0; l<zmm; l++)
+          for(k=0; k<zmm; k++)
+            vpx += this->Value( (j+l)*sgnX+offX, (i+k)*sgnY+offY);
+        *pp = (unsigned char) lut->ApplyFast(vpx/fv); 
+        pp++;
+        }
+    }
+  else  {      // Agrandissement
+    for(j=ofy; j<ofy+npy; j++)
+      for(i=ofx; i<ofx+npx; i++)  {
+        ucp = (unsigned char) lut->ApplyFast(this->Value(j*sgnX+offX, i*sgnY+offY));
+        for(l=0; l<zm; l++)  {
+          pp = pix+((j-ofy)*zm+l)*nppx+((i-ofx)*zm);
+          for(k=0; k<zm; k++)  { *pp = ucp; pp++; }  
+	  }
+        }
+    }
+  }     // Fin du cas avec echange d'axe X/Y 
+else {
+  if (zm == 1)  {  // Pas de zoom  
+    for(j=ofy; j<ofy+npy; j++)
+      for(i=ofx; i<ofx+npx; i++) 
+        { *pp = (unsigned char) lut->ApplyFast( 
+                this->Value(i*sgnX+offX, j*sgnY+offY));  
+           pp++; }
+    }
+  else if (zm < -1) {       // Compression 
+    double fv = (double)(zmm*zmm); 
+    for(j=ofy; j<ofy+npy; j+=zmm)
+      for(i=ofx; i<ofx+npx; i+=zmm) {
+        vpx = 0;
+        for(l=0; l<zmm; l++)
+          for(k=0; k<zmm; k++)
+            vpx += this->Value( (i+k)*sgnX+offX, (j+l)*sgnY+offY);
+        *pp = (unsigned char) lut->ApplyFast(vpx/fv); 
+        pp++;
+        }
+    }
+  else  {      // Agrandissement
+    for(j=ofy; j<ofy+npy; j++)
+      for(i=ofx; i<ofx+npx; i++)  {
+        ucp = (unsigned char) lut->ApplyFast(this->Value(i*sgnX+offX, j*sgnY+offY));
+        for(l=0; l<zm; l++)  {
+          pp = pix+((j-ofy)*zm+l)*nppx+((i-ofx)*zm);
+          for(k=0; k<zm; k++)  { *pp = ucp; pp++; }  
+	  }
+        }
+    }
+  }
+return(pix);
+}
+
+//++
+// Class	P1DAdapter<T>
+// Lib		PI
+// include	parradapter.h
+//
+//	Adaptateur de tableaux 1-D, construit à partir d'un pointeur
+//	"T* data"
+//--
+//++
+// Links	Voir aussi
+// P1DArrayAdapter
+// P2DAdapter<T>
+//--
+
+//++
+// Titre	Constructeur
+//--
+//++
+// P1DAdapter<T>(T* data, int sz, bool ad=false)
+//	Constructeur à partir d'un tableau "T* data", de taille "sz".
+//	Si "ad==true", le destructeur libere l'espace mémoire de "data"
+//	par delete. 
+//--
+
+//++
+// Class	P2DAdapter<T>
+// Lib		PI
+// include	parradapter.h
+//
+//	Adaptateur de tableaux 2-D, construit a partir d'un pointeur
+//	"T* data"
+//--
+//++
+// Links	Voir aussi
+// P2DArrayAdapter
+// P1DAdapter<T>
+//--
+
+//++
+// Titre	Constructeur
+//--
+//++
+// P2DAdapter(T* data, int sx, int sy, bool ad=false)
+//	Constructeur à partir d'un pointeur "T* data", représentant un
+//	tableau 2D de taille "sx * sy".
+//	Si "ad==true", le destructeur libere l'espace mémoire de "data"
+//	par delete. 
+//--
Index: /tags/V_Dec2002/SophyaPI/PI/parradapter.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/parradapter.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/parradapter.h	(revision 2309)
@@ -0,0 +1,129 @@
+// This may look like C code, but it is really -*- C++ -*-
+//     Classes ArrayAdapter           R. Ansari  05/98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+
+#ifndef PARRADAPTER_SEEN
+#define PARRADAPTER_SEEN
+
+#include "machdefs.h"
+#include "lut.h"
+
+class P1DArrayAdapter {
+public :
+                  P1DArrayAdapter(int sz=0);
+  virtual         ~P1DArrayAdapter();
+ 
+  virtual double  Value(int i) = 0;
+  inline  int     Size() { return (mSize) ; }
+  virtual void    DefineXCoordinate(double x0, double dx);
+  virtual double  X(int i);
+     
+protected :
+  int mSize;
+  double mOx, mDx;
+};
+
+// Cette classe est un adaptateur pour les PIImages et 
+// autres classes de PI qui operent sur des structures 
+// de type Tableaux 2-D (images, ...) 
+class P2DArrayAdapter;
+
+typedef char * (* P2DAA_InfoStringFunc) (P2DArrayAdapter * aa, int ix, int iy);
+/* Longueur de retour de P2DAA_InfoString : 128 char */
+ 
+class P2DArrayAdapter {
+public :
+                  P2DArrayAdapter(int sx=0, int sy=0);
+  virtual 	  ~P2DArrayAdapter();
+
+  void  	  ConfigureAxes(bool invx=false, bool invy=false, bool exy=false,
+                                int sx=-1, int sy=-1);
+
+  inline void     GetAxesConfiguration(bool& invx, bool& invy, bool& exy)
+                               { invx = invX; invy = invY; exy = eXY; }
+
+  virtual void    DefineXYCoordinates(double x0, double y0, double dx, double dy);
+// Doit etre defini par les classes derivees
+  virtual double  Value(int ix, int iy) = 0;   
+
+  virtual void    XYfromxy(int ix, int iy, double& x, double& y);
+
+  virtual char *  InfoString(int ix, int iy);
+
+  inline  void    SetInfoStringFunction(P2DAA_InfoStringFunc isf)
+                  { ISFunc = isf; }
+
+  inline  int     XSize() { return ( eXY ? sY : sX ) ; }
+  inline  int     YSize() { return ( eXY ? sX : sY ) ; }
+
+  inline  void    XYCoord(int i, int j, double& x, double& y)
+                         { int ix, iy;  IJ2xy(i, j, ix, iy); 
+                           XYfromxy(ix, iy, x, y); }
+  inline  void    Coord(int i, int j, double& x, double& y)
+                       { int ix, iy;  double f; IJ2xy(i, j, ix, iy); 
+                       XYfromxy(ix, iy, x, y); if (eXY) {f=x; x=y; y=f; } }
+  inline  double  operator() (int i, int j) 
+                         { int ix, iy;  IJ2xy(i, j, ix, iy); 
+                         return Value(ix, iy); }
+  inline void     IJ2xy(int i, int j, int& x, int& y)
+                  { if  (eXY) {int ii = i; i = j; j = ii; }
+                  x = i*sgnX+offX; y = j*sgnY+offY; 
+                  return; }
+
+//    Calcul Min-Max, Moy-Sig
+  virtual int     CheckDyn(double& min, double& max, double& moy, double& sig, int& nbnul, int& nbsat, int vit=10);
+//    Calcul AutoLut
+  virtual void    ComputeLut_PicHisto(double& min, double& max, int nbsig=1, double fracmax=0.95);
+
+//    Calcul pixmap avec un LUT
+  virtual unsigned char * ComputePixmap(LUT* lut, int ofx, int ofy, int zm, 
+                           int xwsz, int ywsz, unsigned char * opix, 
+                           int * oxsp, int * oysp);
+protected :
+  int sX, sY;
+  double mOx, mDx, mOy, mDy;
+  int sgnX, sgnY;
+  int offX, offY;
+  bool invX, invY, eXY;
+
+  P2DAA_InfoStringFunc ISFunc;
+
+};
+
+template <class T> 
+class P1DAdapter : public P1DArrayAdapter {
+public :
+                  P1DAdapter(T* data, int sz, bool ad=false) :
+                    P1DArrayAdapter(sz)
+                    { aDel = ad; mData = data; }
+
+  virtual 	  ~P1DAdapter() { if ( (aDel) && (mData != NULL) ) delete[] mData; }
+  virtual double  Value(int i) 
+                    {  if ( (i < 0) || (i >= mSize) ) return(0.); 
+                    return(mData[i]); }
+protected :
+  bool aDel;
+  T* mData;
+};
+
+
+template <class T> 
+class P2DAdapter : public P2DArrayAdapter {
+public :
+                  P2DAdapter(T* data, int sx, int sy, bool ad=false) :
+                    P2DArrayAdapter(sx, sy)
+                    { aDel = ad; mData = data; }
+
+  virtual 	  ~P2DAdapter() { if ( (aDel) && (mData != NULL) ) delete[] mData; }
+  virtual double   Value(int ix, int iy) 
+                    {  if ( (ix < 0)  || (iy < 0) || (ix >= sX) || (iy >= sY) ) return(0.); 
+                    return(mData[ix+iy*sX]); }
+protected :
+  bool aDel;
+  T* mData;
+};
+
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pi.rsc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pi.rsc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pi.rsc	(revision 2309)
@@ -0,0 +1,28 @@
+PeidaInt*background:                         LightGrey
+PeidaInt*default*background:                 LightGrey
+PeidaInt*bottomShadowColor:                  Black
+PeidaInt*default*bottomShadowColor:          Black
+PeidaInt*Foreground:                         Black
+PeidaInt*default*Foreground:                 Black
+PeidaInt*topShadowColor:                     White
+PeidaInt*default*topShadowColor:             White
+PeidaInt*borderColor:                        Black
+
+PeidaInt*XmLabel.borderWidth:                1
+PeidaInt*XmScrollBar*background:             LightBlue
+PeidaInt*XmDrawingArea*background:           Black
+PeidaInt*XmPushButton*borderWidth:           0
+
+PeidaInt*XmText*XmNshadowThickness:          1
+PeidaInt*XmText*XmNhighlightThickness:          2
+
+PeidaInt*DefMenubar*XtNwidth:           250
+PeidaInt*DefMenubar*XtNheight:          30
+
+PeidaInt*fontList:           -*-helvetica-bold-r-normal-*-14-*-*-*-*-*-ISO8859-1
+PeidaInt*default*fontList:    -*-helvetica-bold-r-normal-*-14-*-*-*-*-*-ISO8859-1
+
+# Attention, ne pas mettre de blanc a la fin du nom de fonte
+PeidaInt*fontFamilyName:   *-courier
+
+PeidaInt*XmToggleButton*selectColor:                  Red
Index: /tags/V_Dec2002/SophyaPI/PI/pi3ddrw.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pi3ddrw.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pi3ddrw.cc	(revision 2309)
@@ -0,0 +1,352 @@
+// Module PI : Peida Interactive PIDrawer3D PIDraw3DWdg
+// Drawer  3D                    R. Ansari 06/98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "pi3ddrw.h"
+
+
+// ......................................................................
+// ........................  Classe PIDrawer3D ..........................
+// ......................................................................
+//++
+// Class	PIDrawer3D
+// Lib		PI
+// include	pidrawer.h
+//
+//	Classe pour la création d'objets, capables de produire
+//	un dessin 3D dans une composante graphique.
+//--
+//++
+// Links	Parent
+// PIDrawer
+//--
+//++
+// Links	Voir aussi
+// PIGraphic3D
+// PIDraw3DWdg
+//--
+
+//++
+// Titre	Constructeur, méthodes
+//--
+//++
+// PIDrawer3D()
+//	Constructeur
+// void Set3DView_Obs(double xo, double yo, double zo, double teta, double phi, double psi, -
+//               double dax, double day, double co, double dco=0.2)
+//	Définition de la vue 3D. Voir "PIGraphic3D::Set3DCS_Obs(...)"
+// void Set3DView(double xc, double yc, double zc, double xo, double yo, double zo, -
+//                double dax, double day, double dco=0.2, double psi=0.)
+//	Définition de la vue 3D. Voir "PIGraphic3D::Set3DCS(...)"
+// bool Get3DView(double& xc, double& yc, double& zc, double& xo, double& yo, double& zo, -
+//                double& teta, double& phi, double& psi, double& dax, double& day, double& co, double& dco)
+//	Renvoie la définition de la Vue-3D. Retourne "true " si définie par "Set3DView_Obs()"
+// void Set3DBox(double xmin, double xmax, double ymin, double ymax, double zmin, double zmax)
+//	Définition de la boite 3D.
+//
+// void Draw3DBoxe(PIGraphic3D* g3, double xx1, double xx2, double yy1, double yy2,  -
+//                 double zz1, double zz2, double xl1, double xl2, -
+//                 double yl1, double yl2, double zl1, double zl2)
+//	Trace une boîte avec les coordonnées matérialisant la vue 3D.
+//--
+
+/* --Methode-- */
+PIDrawer3D::PIDrawer3D()
+        : PIDrawer()
+{
+  xO = yO = 0.; zO = -10.;
+  xC = yC = zC = 0.;
+  tO = fO = pO = 0.; 
+  daxO = dayO = 0.25;
+  lCO = 10.;  dlCO = 3.;  
+  v3D_obs = false;
+  Set3DBox(-1., 1., -1., 1., -1., 1.);
+}
+
+/* --Methode-- */
+PIDrawer3D::~PIDrawer3D()
+{
+}
+
+/* --Methode-- */
+void PIDrawer3D::Set3DView_Obs(double xo, double yo, double zo, double teta, double phi, double psi, 
+                               double dax, double day, double co, double dco)
+{
+  tO = teta;  fO = phi;  pO = psi;
+  daxO = dax;  dayO = day;
+  lCO = co;   dlCO = dco;
+  v3D_obs = true;
+}
+
+/* --Methode-- */
+void PIDrawer3D::Set3DView(double xc, double yc, double zc, double xo, double yo, double zo, 
+                           double dax, double day, double dco, double psi)
+{
+  xC = xc;  yC = yc;  zC = zc;
+  xO = xo;  yO = yo;  zO = zo;
+  pO = psi;
+  daxO = dax;  dayO = day;
+  dlCO = dco;
+  v3D_obs = false;
+}
+
+/* --Methode-- */
+bool PIDrawer3D::Get3DView(double& xc, double& yc, double& zc, double& xo, double& yo, double& zo,
+                           double& teta, double& phi, double& psi, double& dax, double& day, double& co, double& dco)
+{
+  xo = xO;  yo = yO;  zo = zO;
+  xc = xC;  yc = yC;  zc = zC;
+  teta = tO;  phi = fO;  psi = pO;
+  dax = daxO;   day = dayO;
+  co = lCO;     dco = dlCO;
+  return(v3D_obs);
+}
+/* --Methode-- */
+void PIDrawer3D::Set3DBox(double xmin, double xmax, double ymin, double ymax,
+			  double zmin, double zmax)
+{
+  x3Min = xmin;  x3Max = xmax;
+  y3Min = ymin;  y3Max = ymax;
+  z3Min = zmin;  z3Max = zmax;
+}
+
+/* --Methode-- */
+PIGraphicUC* PIDrawer3D::SetDrwWdg(PIBaseWdgGen* drw, int x0, int y0, int dx, int dy, PIGraphicGen* g)
+{
+  mBWdg = drw;
+  xW0 = x0;   yW0 = y0;
+  xWd = dx;   yWd = dy;
+  if (mGrUC)  delete mGrUC;
+  PIGraphic3D* gr3d;
+  gr3d = new PIGraphic3D(g, x0, y0, dx, dy);
+  if (v3D_obs)  gr3d->Set3DCS_Obs(xO, yO, zO, tO, fO, pO, daxO, dayO, lCO, dlCO);
+  else  gr3d->Set3DCS(xC,yC,zC, xO, yO, zO, daxO, dayO, dlCO, pO);
+  if (mFgHighLight) gr3d->SelGOMode(PI_GOInvert);  // $CHECK$ A changer , Reza 07/2001
+  mGrUC = gr3d;
+  return(gr3d); 
+}
+
+/* --Methode-- */
+void PIDrawer3D::DrawAxes(PIGraphicUC* g)
+{
+  if (axesFlags == kAxesNone) return;
+#if defined(CC_HAS_RTTI_SUPPORT)
+  PIGraphic3D* g3 = dynamic_cast<PIGraphic3D*>(g);
+#else
+  PIGraphic3D* g3 = (PIGraphic3D*)(g);
+#endif
+  Draw3DBoxe(g3, XMin3(), XMax3(), YMin3(), YMax3(), ZMin3(), ZMax3(),
+                 XMin3(), XMax3(), YMin3(), YMax3(), ZMin3(), ZMax3());  
+}
+
+/* --Methode-- */
+void PIDrawer3D::Draw3DBoxe(PIGraphic3D* g3, 
+                            double xx1, double xx2, double yy1, double yy2, 
+                            double zz1, double zz2, double xl1, double xl2, 
+                            double yl1, double yl2, double zl1, double zl2)
+{
+  if (mGrAtt.GetLineAtt() == PI_NotDefLineAtt)    g3->SelLine(PI_ThinLine);
+  // RZZZZZ  if (mGrAtt. == PI_NotDefFontSize)    g3->SelFontSz((YMax()-YMin())/150.);
+
+  PIGrCoord x1,y1,z1,x2,y2,z2;
+  char strg[64];
+  int k;
+  int NTicks = 5;  // Nb de ticks sur chaque axe
+
+  x1 = xx1;  y1 = yy1;  z1 = zz1;
+  x2 = xx2;   y2 = yy1;   z2 = zz1; 
+  g3->DrawLine3D(x1, y1, z1, x2, y2, z2);
+  y1 = y2 = yy2;
+  g3->DrawLine3D(x1, y1, z1, x2, y2, z2);
+  z1 = z2 = zz2;
+  g3->DrawLine3D(x1, y1, z1, x2, y2, z2);
+  y1 = y2 = yy1;  
+  g3->DrawLine3D(x1, y1, z1, x2, y2, z2);
+
+// Trace des ticks et labels axe X :
+  x1 = x2 = xx1;   y1 = y2 = yy1;  z1 = z2 = zz1;
+  for (k=0; k<NTicks; k++) {
+    x1 = x2 = (xx1+(double)k*(xx2-xx1)/(NTicks-1.));
+    z1 = zz1; z2 = zz1-0.02*(zz2-zz1);
+    y1 = y2 = yy1;
+    g3->DrawLine3D(x1, y1, z1, x2, y2, z2);
+    z2 = zz1-0.05*(zz2-zz1); 
+    y2 = yy1-0.075*(yy2-yy1);  
+    sprintf(strg,"%.2g", xl1+(double)k*(xl2-xl1)/(NTicks-1.));
+    g3->DrawString3D(x2, y2, z2, strg);
+    }
+  x2 = xx2+0.075*(xx2-xx1);  y2 = yy1;   z2 = zz1-0.05*(zz2-zz1); 
+  g3->DrawString3D(x2, y2, z2, "X");
+
+  x1 = xx1;  y1 = yy1;  z1 = zz1;
+  x2 = xx1;   y2 = yy2;   z2 = zz1; 
+  g3->DrawLine3D(x1, y1, z1, x2, y2, z2);
+  x1 = x2 = xx2;
+  g3->DrawLine3D(x1, y1, z1, x2, y2, z2);
+  z1 = z2 = zz2;
+  g3->DrawLine3D(x1, y1, z1, x2, y2, z2);
+  x1 = x2 = xx1;  
+  g3->DrawLine3D(x1, y1, z1, x2, y2, z2);
+  x1 = x2 = xx2;   y1 = y2 = yy1;  z1 = z2 = zz1;
+  for (k=1; k<NTicks; k++) {   // Attention, par le tick 0 pour Y
+    y1 = y2 = (yy1+(double)k*(yy2-yy1)/(NTicks-1.));
+    z2 = zz1-0.02*(zz2-zz1);
+    x1 = x2 = xx2; 
+    g3->DrawLine3D(x1, y1, z1, x2, y2, z2);
+    z2 = zz1-0.05*(zz2-zz1); 
+    x2 = xx2+0.075*(xx2-xx1);  
+    sprintf(strg,"%.2g", yl1+(double)k*(yl2-yl1)/(NTicks-1.));
+    g3->DrawString3D(x2, y2, z2, strg);
+    }
+  x2 = xx2;  y2 = yy2+0.075*(yy2-yy1);   z2 = zz1-0.05*(zz2-zz1); 
+  g3->DrawString3D(x2, y2, z2, "Y");
+
+  x1 = xx1;  y1 = yy1;  z1 = zz1;
+  x2 = xx1;   y2 = yy1;   z2 = zz2; 
+  g3->DrawLine3D(x1, y1, z1, x2, y2, z2);
+  x1 = x2 = xx2;
+  g3->DrawLine3D(x1, y1, z1, x2, y2, z2);
+  y1 = y2 = yy2;
+  g3->DrawLine3D(x1, y1, z1, x2, y2, z2);
+  x1 = x2 = xx1;  
+  g3->DrawLine3D(x1, y1, z1, x2, y2, z2);
+  x1 = x2 = xx1;   y1 = y2 = yy1;  z1 = z2 = zz1;
+  for (k=0; k<NTicks; k++) {
+    z1 = z2 = (zz1+(double)k*(zz2-zz1)/(NTicks-1.));
+    y2 = yy1-0.015*(yy2-yy1);
+    x2 = xx1-0.015*(xx2-xx1);
+    g3->DrawLine3D(x1, y1, z1, x2, y2, z2);
+    x2 = xx1-0.1*(xx2-xx1);  
+    y2 = yy1-0.1*(yy2-yy1);  
+    sprintf(strg,"%.2g", zl1+(double)k*(zl2-zl1)/(NTicks-1.));
+    g3->DrawString3D(x2, y2, z2, strg);
+    }
+  x2 = xx1-0.075*(xx2-xx1);  y2 = yy1-0.075*(yy2-yy1);   z2 = zz2+0.05*(zz2-zz1); 
+  g3->DrawString3D(x2, y2, z2, "Z");
+
+}
+
+/*  --------------------------------------------------------------  */
+/*  ------------------- Classe PIElDrawer3D ------------------------  */
+/*  --------------------------------------------------------------  */
+
+//++
+// Class	PIElDrawer3D
+// Lib		PI
+// include	p3ddrw.h
+//
+//	Classe de traceur ("Drawer") capable de gérer et de 
+//	tracer une liste d'éléments simples. Cette classe
+//	est utilisé pour le tracé des axes et des éléments de
+//	texte ds les "PIScDrawWdg", "PIDraw3DWdg" et "PIImage".
+//--
+//++
+// Links	Parents
+// PIDrawer3D
+//--
+//++
+// Links	Voir aussi
+// PIElDrawer
+// PIElDrwMgr
+//--
+
+//++
+// Titre	Constructeurs et méthodes
+//--
+
+//++
+// PIElDrawer3D()
+//	Constructeur
+//--
+
+/* --Methode-- */
+PIElDrawer3D::PIElDrawer3D()
+{
+  ShowTitles();
+}
+
+/* --Methode-- */
+PIElDrawer3D::~PIElDrawer3D()
+{
+}
+
+
+//++
+//  void  SetTitles(string tt, string tb)
+//  void  SetTitles(string tt, string tb, PIGraphicAtt const& att)
+//	Ajout de titres haut ("tt") et bas ("tb")
+//--
+
+
+/* --Methode-- */
+int PIElDrawer3D::DecodeOptionString(vector<string> & opt, bool rmdecopt)
+{
+  int nopt0 = opt.size();
+  if (nopt0 < 1)  return(0);  
+  int ndec1 = PIDrawer::DecodeOptionString(opt, rmdecopt);
+  if ((nopt0 - ndec1) < 1) return(ndec1);  // si tout a ete decode
+  vector<string> udopt;
+  unsigned int k = 0;
+  int ndec = opt.size();
+  for( k=0; k<opt.size(); k++ ) {
+    string opts = opt[k];
+    if (opts == "title" || opts == "tit") ShowTitles(true);
+    else if (opts == "notitle" || opts == "notit") ShowTitles(false);
+    else {
+      ndec--;
+      if (rmdecopt)  udopt.push_back(opts);
+    }
+  }  
+
+  if (rmdecopt)  opt = udopt;
+  return(ndec+ndec1);
+}
+
+
+/* --Methode-- */
+void  PIElDrawer3D::Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax)
+{
+SelGraAtt(g);   // DrawAxes change certains attributs graphiques
+DrawAxes(g);   // Trace des axes 
+g->SelFont(PI_NormalSizeFont);
+SelGraAtt(g);   // DrawAxes change certains attributs graphiques
+
+// Trace des titres 
+if ( showTitles && ((titleT.length() > 0) || (titleB.length() > 0)) ) {
+  PIGraphicAtt grs = GetGraphicAtt();
+  UpdateGraphicAtt(titleAtt);
+  SelGraAtt(g); 
+
+  aXdir = false;  // Vrai si Axe X de Droite vers Gauche 
+  aYdir = false;  // Vrai si Axe Y de Haut vers Bas
+  double fx, fy, fh;
+//  fh = g->GetFontHeightUC(gas, gds);
+  fh = 0.075*(YMax()-YMin());
+  if ( titleT.length() > 0) {
+      if (g->isAxeYDirUpDown()) fy = g->DeltaUCY(YMin(), -fh);
+      else fy = g->DeltaUCY(YMax(), fh);
+      g->DrawString((XMax()+XMin())*0.5, fy, titleT.c_str(), PI_HorizontalCenter | PI_VerticalBottom);
+//      printf(" PIElDrawer3D::Draw()/DBG (%g , %g) %s  - %g \n", fx, fy, titleT.c_str(), fh);
+    }
+  if ( titleB.length() > 0) {
+      fx = g->CalcStringWidth(titleB.c_str());
+      if(aXdir) fx = g->DeltaUCX(XMax(), -(XMax()-XMin()-fx)/2.);
+      else fx = g->DeltaUCX(XMin(), (XMax()-XMin()-fx)/2.);
+      if (g->isAxeYDirUpDown()) fy =  g->DeltaUCY(YMax(), fh*1.5);
+      else fy = g->DeltaUCY(YMin(), -fh*1.5);
+      g->DrawString((XMax()+XMin())*0.5, fy, titleB.c_str(), PI_HorizontalCenter | PI_VerticalBottom);
+//      printf(" PIElDrawer3D::Draw()/DBG (%g , %g) %s  - %g \n", fx, fy, titleT.c_str(), fh);
+    }
+  SetGraphicAtt(grs);
+  }
+
+ SelGraAtt(g);
+// Trace des elements
+ ElDrwMgr().DrawElements(g, xmin, ymin, xmax, ymax);
+
+}
+
Index: /tags/V_Dec2002/SophyaPI/PI/pi3ddrw.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pi3ddrw.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pi3ddrw.h	(revision 2309)
@@ -0,0 +1,97 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive PIDrawer3D PIDraw3DWdg
+// Drawer  3D                R. Ansari 06/98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PIDRW3D_H_SEEN
+#define PIDRW3D_H_SEEN
+
+#include "pisysdep.h"
+#include "pidrawer.h"
+#include "pieldrw.h"
+#include "pigraph3d.h"
+
+
+
+// -----------------  Traceur (Drawer) 3D  -------------------
+
+class PIDrawer3D : public PIDrawer
+{
+public :
+			PIDrawer3D();
+  virtual		~PIDrawer3D();
+
+  virtual void		Set3DView_Obs(double xo, double yo, double zo, double teta, double phi, double psi, 
+                                      double dax, double day, double co, double dco=0.2);
+  virtual void       	Set3DView(double xc, double yc, double zc, double xo, double yo, double zo, 
+                                  double dax, double day, double dco=0.2, double psi=0.);
+  bool           	Get3DView(double& xc, double& yc, double& zc, double& xo, double& yo, double& zo,
+                                  double& teta, double& phi, double& psi, double& dax, double& day, double& co, double& dco);
+
+  virtual void		Set3DBox(double xmin, double xmax, double ymin, double ymax,
+				 double zmin, double zmax); 
+  
+  virtual PIGraphicUC*	SetDrwWdg(PIBaseWdgGen* drw, int x0, int y0, int dx, int dy, PIGraphicGen* g);
+
+  virtual void       	DrawAxes(PIGraphicUC* g);
+  virtual void       	Draw3DBoxe(PIGraphic3D* g3, double xx1, double xx2, double yy1, double yy2, 
+                                                    double zz1, double zz2, double xl1, double xl2, 
+                                                    double yl1, double yl2, double zl1, double zl2);
+
+  double XMin3() const {return x3Min;}
+  double XMax3() const {return x3Max;}
+  double YMin3() const {return y3Min;}
+  double YMax3() const {return y3Max;}
+  double ZMin3() const {return z3Min;}
+  double ZMax3() const {return z3Max;}
+
+protected :
+  double xO, yO, zO;  // Position observateur = camera
+  double xC, yC, zC;  // Position centre du champ
+  double tO,fO,pO;    // Orientation observateur (Teta, Phi, Psi, Angles d Euler)
+  double daxO, dayO;  // Demi-ouverture de la camera suivant les deux axes de projection (xp/zp, yp/zp) 
+  double lCO, dlCO;   // Distance Camera-Centre du champ et profondeur de champ 
+  bool v3D_obs;      // Si defini par Set3DView_Obs 
+  double x3Min, x3Max;  // Pour delimiter le cube 3D 
+  double y3Min, y3Max;  // Pour delimiter le cube 3D 
+  double z3Min, z3Max;  // Pour delimiter le cube 3D 
+};
+
+
+// -----------------  Traceur d'elements 3D  -------------------
+class PIElDrawer3D : public PIDrawer3D
+{
+public:
+                     PIElDrawer3D();
+  virtual           ~PIElDrawer3D();
+
+//   Methode de decodage des options
+  virtual int        DecodeOptionString(vector<string> & opt, bool rmdecopt=true);
+
+  virtual void       Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax); 
+
+  inline PIElDrwMgr& ElDrwMgr()    { return eltsMgr; }
+
+  inline void        SetTitles(string tt, string tb)   { titleT = tt;  titleB = tb; }
+  inline void        SetTitles(string tt, string tb, PIGraphicAtt const& att) 
+                        { titleT = tt;  titleB = tb; titleAtt = att; }
+  inline void        ShowTitles(bool fg=true) { showTitles = fg; }
+
+// -- Pour compatibilite avec l'interface precedente , Reza 08/2002 
+  inline void        ElDel(int id) { eltsMgr.ElDel(id); }
+  inline void        ElDelLast()   { eltsMgr.ElDelLast(); }
+  inline void        ElDelAll()    { eltsMgr.ElDelAll(); }
+  
+  inline int	     ElAddText(PIGrCoord x, PIGrCoord y, const char* s)
+                                   { return eltsMgr.ElAddText(x, y, s); }
+
+protected:
+  PIElDrwMgr eltsMgr;
+  string titleT, titleB;       // Titre Haut - Bas
+  PIGraphicAtt titleAtt;       // Attributs graphiques de trace de titre
+  bool showTitles;             // Affichage des titres si true
+
+};
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pi3dwdg.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pi3dwdg.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pi3dwdg.cc	(revision 2309)
@@ -0,0 +1,527 @@
+// Module PI : Peida Interactive PIDrawer3D PIDraw3DWdg
+// DrawWidget 3D                R. Ansari 06/98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "pi3dwdg.h"
+#include "pidrwtools.h"
+
+// ......................................................................
+// .......................  Classe PIDraw3DWdg ..........................
+// ......................................................................
+
+//++
+// Class	PIDraw3DWdg
+// Lib		PI
+// include	pi3dwdg.h
+//
+//   	Classe pour la l'affichage et la manipulation d'un ensemble
+//	de *Drawer3D* avec la gestion de zoom, rotation, déplacement
+//	d'objet.
+//	* Bouton-1 : Envoie le message "PIMsg_Active".
+//	* Bouton-2 : Permet de faire tourner l'observateur (caméra) 
+//	autour de l'objet.
+//	* Shift-Bouton-2 : Permet de tourner l'objet en maintenant 
+//	la caméra fixe. Cette fonction peut-être réalisée sans le shift
+//	à partir du centre de l'objet, en l'ayant préalablement activée
+//	par <Alt>S.
+//	* Bouton-3 : Gestion de zoom (On approche/ éloigne la caméra, ou 
+//	on change l'angle d'ouverture) 
+//
+//	Gestion du clavier :
+//	* <Alt>G : Affichage d'une fenêtre de changement des attributs graphiques
+//	* <Alt>O : Action identique a <Alt>G
+//	* <Alt>V : Copier/*Coller* Ajout du texte du buffer copier/coller
+//	sur l'objet à la position courante de la souris
+//	* <Alt>Z : Supprime les élément graphiques ajoutés au dessin.
+//	* <Alt>E : Supprime le dernier élément graphique ajouté.
+//	* <Alt>A : Active/desactive l'affichage des axes
+//	* <Alt>R : Reinitialise la vue 3D (vue par défaut) et rafraichit le dessin.
+//	* <Alt>S : Active/desactive le mode de rotation d'objet sans Shift
+//
+//--
+//++
+// Links	Parents
+// PIBaseWdg
+//--
+//++
+// Links	Voir aussi
+// PIDrawer3D
+//--
+
+//++
+// Titre	Constructeur, méthodes
+//--
+//++
+// PIDraw3DWdg(PIContainerGen *par, const char *nom, int sx=100, int sy=100, int px=0, int py=0)
+//	Constructeur
+// long	 kind()
+//	Renvoie le type de l'objet ("=PIDraw3DWdg::ClassId")
+// int AddDrawer3D(PIDrawer3D*, bool ad=false)
+//	Ajoute un Drawer3D
+//--
+
+/* --Methode-- */
+PIDraw3DWdg::PIDraw3DWdg(PIContainerGen *par, const char *nom, int sx, int sy, int px, int py)
+        : PIBaseWdg(par, nom, sx, sy, px, py)
+{  
+  vfixed = false;
+//  SetDefaultDrawRectangle(0.12, 0.12, 0.88, 0.88, true);
+  SetDefaultDrawRectangle(0., 0., 1., 1., true);
+  mBDrw = new PIElDrawer3D;
+  mBDrw->SetLimits(0.12,0.88, 0.12,0.88, kAxeDirLtoR,kAxeDirDownUp);
+  AddDrawer(mBDrw, 0.12, 0.12, 0.88, 0.88, true, false, false);
+  mPx = mPy = 0;
+
+  lPx = lPy = 0;
+  lCol = PI_Black;
+  cTeta = cPhi = 0.;  cUlen = 1.;
+
+  ActivateKeyboard();
+  ActivateButton(2);    //  Pour pouvoir tourner la camera
+  ActivateMove(2);      
+  ActivateButton(3);    //  Pour deplacer la camera le long de son axe
+  ActivateMove(3);
+  ActivateButton(1);    
+
+  mGr3d = new PIGraphic3D(mWGrC, 0, 0, sx, sy);
+  rOfg = false;
+  axfg = true;
+  skcfg = false;
+}
+
+/* --Methode-- */
+PIDraw3DWdg::~PIDraw3DWdg()
+{
+  delete mBDrw;
+  delete mGr3d;
+}
+
+/* --Methode-- */
+void PIDraw3DWdg::Set3DView_Obs(double xo, double yo, double zo, double teta, double phi, double psi, 
+                                double dax, double day, double co, double dco)
+{
+  mGr3d->Set3DCS_Obs(xo, yo, zo, teta, phi, psi, dax, day, co, dco);
+  list<int>::iterator it;
+  for(it = m3DrIl.begin(); it != m3DrIl.end(); it++)   
+#if defined(CC_HAS_RTTI_SUPPORT)
+    (dynamic_cast<PIDrawer3D*>(GetDrawerId(*it)))->Set3DView_Obs(xo, yo, zo, teta, phi, psi, dax, day, co, dco);
+#else
+    ((PIDrawer3D*)(GetDrawerId(*it)))->Set3DView_Obs(xo, yo, zo, teta, phi, psi, dax, day, co, dco);
+#endif
+  vfixed = true;
+}
+
+/* --Methode-- */
+void PIDraw3DWdg::Set3DView(double xc, double yc, double zc, double xo, double yo, double zo, 
+                            double dax, double day, double dco, double psi)
+{
+  mGr3d->Set3DCS(xc, yc, zc, xo, yo, zo, dax, day, dco, psi);
+  list<int>::iterator it;
+  for(it = m3DrIl.begin(); it != m3DrIl.end(); it++)   
+#if defined(CC_HAS_RTTI_SUPPORT)
+    (dynamic_cast<PIDrawer3D*>(GetDrawerId(*it)))->Set3DView(xc, yc, zc, xo, yo, zo, dax, day, dco, psi);
+#else
+    ((PIDrawer3D*)(GetDrawerId(*it)))->Set3DView(xc, yc, zc, xo, yo, zo, dax, day, dco, psi);
+#endif
+  vfixed = true;
+}
+
+/* --Methode-- */
+bool PIDraw3DWdg::Get3DView(double& xc, double& yc, double& zc, double& xo, double& yo, double& zo, 
+                            double& teta, double& phi, double& psi, double& dax, double& day, double& co, double& dco)
+{
+  return(mGr3d->Get3DCS(xc, yc, zc, xo, yo, zo, teta, phi, psi, dax, day, co, dco));
+}
+
+
+/* --Methode-- */
+void PIDraw3DWdg::Update3DView()
+{
+  list<int>::iterator it = m3DrIl.begin();
+  if (it == m3DrIl.end())  return;
+#if defined(CC_HAS_RTTI_SUPPORT)
+  PIDrawer3D* dr3 = dynamic_cast<PIDrawer3D*>(GetDrawerId(*it));
+#else
+  PIDrawer3D* dr3 = (PIDrawer3D*)(GetDrawerId(*it));
+#endif
+  if (dr3 == NULL)  return;
+  dr3->UpdateLimits();
+  double xo, yo, zo, xc, yc, zc, teta, phi, psi, dax, day, co, dco;
+  bool vobs;
+  vobs = dr3->Get3DView(xc, yc, zc, xo, yo, zo, teta, phi, psi, dax, day, co, dco);
+  if (vobs) Set3DView_Obs(xo, yo, zo, teta, phi, psi, dax, day, co, dco);
+  else Set3DView(xc, yc, zc, xo, yo, zo, dax, day, dco, psi);
+  Refresh();
+}
+
+/* --Methode-- */
+int PIDraw3DWdg::DecodeOptionString(vector<string> & opt, bool rmdecopt)
+{
+  // AFAIRE - Reza 01/03/2002 
+  return(0);
+}
+
+
+/* --Methode-- */
+void PIDraw3DWdg::SetDrawers3DView()
+{
+  double xc, yc, zc, xo, yo, zo;
+  double teta, phi, psi;
+  double dax, day, co, dco;
+  bool vo;
+  vo = mGr3d->Get3DCS( xc, yc, zc, xo, yo, zo, teta, phi, psi, dax, day, co, dco);
+  list<int>::iterator it;
+
+#if defined(CC_HAS_RTTI_SUPPORT)
+  if (vo)   for(it = m3DrIl.begin(); it != m3DrIl.end(); it++)   
+    (dynamic_cast<PIDrawer3D*>(GetDrawerId(*it)))->Set3DView_Obs(xo, yo, zo, teta, phi, psi, dax, day, co, dco);
+  else   for(it = m3DrIl.begin(); it != m3DrIl.end(); it++)   
+    (dynamic_cast<PIDrawer3D*>(GetDrawerId(*it)))->Set3DView(xc, yc, zc, xo, yo, zo, dax, day, dco, psi);    
+#else
+  if (vo)   for(it = m3DrIl.begin(); it != m3DrIl.end(); it++)   
+    ((PIDrawer3D*)(GetDrawerId(*it)))->Set3DView_Obs(xo, yo, zo, teta, phi, psi, dax, day, co, dco);
+  else   for(it = m3DrIl.begin(); it != m3DrIl.end(); it++)   
+    ((PIDrawer3D*)(GetDrawerId(*it)))->Set3DView(xc, yc, zc, xo, yo, zo, dax, day, dco, psi);    
+#endif
+
+}
+
+/* --Methode-- */
+int PIDraw3DWdg::AddDrawer3D(PIDrawer3D* dr3, bool ad)
+{
+if (!vfixed)  { 
+  dr3->UpdateLimits();
+  double xo, yo, zo, xc, yc, zc, teta, phi, psi, dax, day, co, dco;
+  bool vobs;
+  vobs = dr3->Get3DView(xc, yc, zc, xo, yo, zo, teta, phi, psi, dax, day, co, dco);
+  if (vobs) Set3DView_Obs(xo, yo, zo, teta, phi, psi, dax, day, co, dco);
+  else Set3DView(xc, yc, zc, xo, yo, zo, dax, day, dco, psi);
+  }
+else { 
+  double xc, yc, zc, xo, yo, zo, teta, phi, psi, dax, day, co, dco;
+  if ( Get3DView(xc, yc, zc, xo, yo, zo, teta, phi, psi, dax, day, co, dco) ) 
+      dr3->Set3DView_Obs(xo, yo, zo, teta, phi, psi, dax, day, co, dco);
+  else  dr3->Set3DView(xc, yc, zc, xo, yo, zo, dax, day, co, psi);
+  }
+int id = AddDrawer(dr3, false, false, ad);
+if (m3DrIl.size() == 0)  dr3->SetAxesFlags(kStdAxes);
+else dr3->SetAxesFlags(kAxesNone);
+m3DrIl.push_back(id);
+return(id);
+}
+
+/* --Methode-- */
+void PIDraw3DWdg::RemoveDrawer(int id)
+{
+  list<int>::iterator it;
+  for(it = m3DrIl.begin(); it != m3DrIl.end(); it++)   
+    if ( (*it) == id )  { m3DrIl.erase(it);  break; }
+  PIBaseWdg::RemoveDrawer(id);
+}
+
+/* --Methode-- */
+void PIDraw3DWdg::DeleteDrawers()
+{
+  m3DrIl.erase(m3DrIl.begin(),  m3DrIl.end());
+  PIBaseWdg::DeleteDrawers();
+}
+
+/* --Methode-- */
+void PIDraw3DWdg::Keyboard(int key, PIKeyModifier kmod)
+{
+if (kmod == PIKM_Alt) {
+  if (key == 'V' || key == 'v') RequestSelection();  // Pour coller (copier/coller)  
+  else if (key == 'Z' || key == 'z') { mBDrw->ElDelAll();  Refresh(); } // Pour supprimer tous les signes 
+  else if (key == 'E' || key == 'e') { mBDrw->ElDelLast();  Refresh(); } // Pour supprimer le dernier element ajoute
+  else if (key == 'O' || key == 'o') { // fenetre des options de controle du drawer actif
+    PIDrawer* actdrw = GetActiveDrawer();
+    if (actdrw != NULL) actdrw->ShowControlWindow(this);
+  }
+  else if (key == 'G' || key == 'g') // Fenetre des options graphiques de trace
+    PIDrwTools::ShowPIDrwTools(this);   
+
+  else if (key == 'A' || key == 'a')  {    // On affiche ou on enleve les axes
+    axfg = !axfg;
+    list<int>::iterator it;
+    if (axfg) 
+      for(it = m3DrIl.begin(); it != m3DrIl.end(); it++)  
+         GetDrawerId(*it)->SetAxesFlags(kAxesNone);
+    else { 
+      it = m3DrIl.begin(); 
+      if (it != m3DrIl.end())  GetDrawerId(*it)->SetAxesFlags(kStdAxes);
+      }
+    Refresh(); 
+    }
+//  <Alt>S active la sensibilite de la zone centrale pour tourner l'objet
+  else if (key == 'S' || key == 's')  skcfg = !skcfg;  
+  else if (key == 'R' || key == 'r')  Update3DView();
+  }
+}
+
+/* --Methode-- */
+void PIDraw3DWdg::PasteSelection(unsigned int typ, void *pdata, unsigned int l)
+{
+if (typ != PICP_string) return;
+int ll = (l<256) ? l+1 : 256;
+char pc[256];
+strncpy(pc, (char*)pdata, ll-1);  pc[ll-1] = '\0';
+// printf("PIDraw3DWdg::PasteSelection() / Debug  %s - %d %d -> %g %g \n", pc, 
+//        mPx, mPy, (double)mPx/(double)XSize(), 1.-(double)mPy/(double)YSize());
+mBDrw->ElAddText((double)mPx/(double)XSize(), 1.-(double)mPy/(double)YSize(), pc );
+mBDrw->Refresh();
+}
+
+/* --Methode-- */
+void PIDraw3DWdg::But2Press(int x, int y)
+{
+  mGr3d->SetBaseGraphic(mWGrC, 0, 0, XSize(), YSize());
+  double xo, yo, zo;
+  double teta, phi, psi;
+  double dax, day, co, dco;
+  mGr3d->Get3DCS(cXc, cYc, cZc, xo, yo, zo, teta, phi, psi, dax, day, co, dco);
+//   puts("\n PIDraw3DWdg::But2Press() ");
+//   mGr3d->PrintCS();
+  lPx = x;  lPy = y;
+
+// Pour savoir si on se trouve ds la zone centrale   
+  int czx = XSize()/10;
+  int czy = YSize()/10;
+  PIKeyModifier kmod;
+  unsigned long tm;
+  GetLastEventInfo(kmod, tm);
+  rOfg = false;
+  if (kmod ==  PIKM_Shift)  rOfg = true;
+  else if (skcfg) {
+    int dmix = x-XSize()/2;
+    int dmiy = y-YSize()/2;
+    if (dmix < 0) dmix = -dmix;
+    if (dmiy < 0) dmiy = -dmiy;
+    if ((dmix < czx) && (dmiy < czy))  rOfg = true;
+    }
+
+  cUlen = 0.5*(dax+day)*co*0.3;    cDax = dax;   cDay = day;  clCO = co; 
+  cTeta = teta;   cPhi = phi;
+  SelPointerShape(PI_TDLRArrowPointer);
+  lCol = mWGrC->GetForeground();
+  //  mWGrC->SelForeground(GetBackgroundColor());
+  mWGrC->SelForeground(PI_Magenta);
+/*
+  {
+  char buff[256];
+  sprintf(buff, "But2Press() C=%g %g %g  T,P=%g %g   ", xc, yc, zc, cTeta, cPhi); 
+  mWGrC->DrawOpaqueString(0,20,buff);
+  }
+*/
+  DrawXYZAxes();
+  if (rOfg)  { czx /= 2;   czy /= 2;  mWGrC->DrawBox(XSize()/2-czx, YSize()/2-czy, czx*2, czy*2); }
+ 
+  Send(Msg(), PIMsg_Active);
+  PIDrwTools::SetCurrentBaseWdg(this);
+}
+
+/* --Methode-- */
+void PIDraw3DWdg::Ptr2Move(int x, int y)
+{
+  DrawXYZAxes();
+  double teta, phi;
+
+  if (rOfg) { 
+    phi = cPhi + (M_PI*0.25*(double)(x-lPx)/XSize());
+    teta = cTeta - (M_PI*0.25*(double)(y-lPy)/YSize());
+    mGr3d->RotateObject(teta, phi, false);
+    }
+  else {
+    phi = cPhi - (M_PI*0.5*(double)(x-lPx)/XSize());
+    teta = cTeta + (M_PI*0.5*(double)(y-lPy)/YSize());
+    mGr3d->RotateObserver(teta, phi, 0., false);
+    }
+/*  {
+  char buff[256];
+  sprintf(buff, "Ptr2Move() T,P=%g %g -> %g %g  ", cTeta, cPhi, teta, phi); 
+  mWGrC->DrawOpaqueString(0,20,buff);
+  }
+*/
+  DrawXYZAxes();
+}
+
+
+/* --Methode-- */
+void PIDraw3DWdg::But2Release(int x, int y)
+{
+  DrawXYZAxes();
+  if (rOfg) {
+    int czx = XSize()/20;
+    int czy = YSize()/20;
+    mWGrC->DrawBox(XSize()/2-czx, YSize()/2-czy, czx*2, czy*2);
+    }
+
+//  puts("\n PIDraw3DWdg::But2Release()");
+//  mGr3d->PrintCS();
+  SelPointerShape(PI_ArrowPointer);
+  mWGrC->SelForeground(lCol);
+  SetDrawers3DView();
+  Refresh();
+}
+
+
+/* --Methode-- */
+void PIDraw3DWdg::But3Press(int x, int y)
+{
+  double xo, yo, zo;
+  double teta, phi, psi;
+  double dax, day, co, dco;
+  mGr3d->Get3DCS(cXc, cYc, cZc, xo, yo, zo, teta, phi, psi, dax, day, co, dco);
+  mGr3d->SetBaseGraphic(mWGrC, 0, 0, XSize(), YSize());
+  lPx = x;  lPy = y;  
+  cUlen = 0.5*(dax+day)*co*0.3;    cDax = dax;   cDay = day;  clCO = co;
+  cTeta = teta;   cPhi = phi;
+  SelPointerShape(PI_TDLRArrowPointer);
+  lCol = mWGrC->GetForeground();
+  //  mWGrC->SelForeground(GetBackgroundColor());
+  mWGrC->SelForeground(PI_Magenta);
+/*
+  {
+  char buff[256];
+  sprintf(buff, "But3Press() C=%g %g %g  O= %g %g %g  L= %g   ", xc, yc, zc, xo, yo, zo, co); 
+  mWGrC->DrawOpaqueString(0,20,buff);
+  }
+*/
+  DrawXYZAxes();
+  Send(Msg(), PIMsg_Active);
+  PIDrwTools::SetCurrentBaseWdg(this);
+}
+
+/* --Methode-- */
+void PIDraw3DWdg::Ptr3Move(int x, int y)
+{
+  DrawXYZAxes();
+  double rapx = (double)(lPx-x)/XSize();
+  if (rapx > 0.) rapx = rapx*2.+1;
+  else rapx += 1.;
+  if (rapx < 0.3)  rapx = 0.3;
+  if (rapx > 3.)  rapx = 3.;
+  double rapy = (double)(y-lPy)/YSize();
+  if (rapy > 0.) rapy = rapy*2.+1;
+  else rapy += 1.;
+  if (rapy < 0.3)  rapy = 0.3;
+  if (rapy > 3.)  rapy = 3.;
+/*
+  {
+  char buff[256];
+  sprintf(buff, "Ptr3Move() Rap=%g %g -> %g %g %g     ", rapx, rapy, rapy*clCO, rapx*cDax, rapx*cDay);
+  mWGrC->DrawOpaqueString(0,20,buff);
+  }
+*/
+  mGr3d->ZoomInOut(rapy*clCO, rapx*cDax, rapx*cDay, false);
+  DrawXYZAxes();
+}
+
+/* --Methode-- */
+void PIDraw3DWdg::But3Release(int x, int y)
+{
+  DrawXYZAxes();
+  SelPointerShape(PI_ArrowPointer);
+  mWGrC->SelForeground(lCol);
+  SetDrawers3DView();
+  Refresh();
+}
+
+
+/* --Methode-- */
+void PIDraw3DWdg::DrawXYZAxes()
+{
+  mWGrC->SelGOMode(PI_GOXOR);
+  PIGrCoord x1,y1,z1,x2,y2,z2;
+  x1 = cXc;  y1 = cYc;  z1 = cZc;
+  x2 = cXc+cUlen;   y2 = cYc;   z2 = cZc; 
+  mGr3d->DrawLine3D(x1, y1, z1, x2, y2, z2);
+  x2 = cXc+cUlen*1.1;
+  mGr3d->DrawString3D(x2, y2, z2, "X");
+  x2 = cXc;   y2 = cYc+cUlen;   z2 = cZc; 
+  mGr3d->DrawLine3D(x1, y1, z1, x2, y2, z2);
+  y2 = cYc+cUlen*1.1;
+  mGr3d->DrawString3D(x2, y2, z2, "Y");   
+  x2 = cXc;   y2 = cYc;   z2 = cZc+cUlen; 
+  mGr3d->DrawLine3D(x1, y1, z1, x2, y2, z2);
+  z2 = cZc+cUlen*1.1;
+  mGr3d->DrawString3D(x2, y2, z2, "Z");   
+//   mGr3d->DrawCircle(0., 0., daxO*0.30);
+  char buff[256];
+  double xc,yc,zc,xo,yo,zo,teta,phi,psi,dax,day,co,dco;
+  mGr3d->Get3DCS(xc,yc,zc,xo,yo,zo,teta,phi,psi,dax,day,co,dco);
+  sprintf(buff, " C: %g %g %g -> O: %g %g %g  (T/P0= %g %g)     ", xc,yc,zc, xo, yo, zo, cTeta, cPhi);
+  mWGrC->DrawString(0,20,buff);
+  sprintf(buff, " T,P= %g %g %g lCO= %g  dax= %g %g UL=%g    ", teta,phi,psi,co,dax,day,cUlen); 
+  mWGrC->DrawString(0,40,buff);
+  mWGrC->SelGOMode(PI_GOCopy);  
+
+}
+
+
+/* --Methode-- */
+void PIDraw3DWdg::But1Press(int x, int y)
+{
+  Send(Msg(), PIMsg_Active);
+  PIDrwTools::SetCurrentBaseWdg(this);
+  mPx = x;  mPy = y;
+  if ( (x > 50) || ( y > 50) ) return; 
+  Update3DView();
+}
+
+/*   Pour debugger sur bouton-3 
+static int isw = 0;
+void PIDraw3DWdg::But3Press(int x, int y)
+x -= XSize()/2;
+y -= YSize()/2;
+
+double fx = (double)x/XSize(); 
+double fy = (double)y/YSize(); 
+if ( (fx<0.2) && (fx>-0.2) && (fy<0.2) && (fy>-0.2) ) {
+  
+  if ((isw%3) == 0) { 
+    Set3DView(0., 0., 0., 0., 0., -3. , 0.3, 0.3, 2); 
+    puts("\n Set3DView(0., 0., 0., 0., 0., -3. , 0.3, 0.3, 2)");
+  }
+  else if ((isw%3) == 1) { 
+    Set3DView(0., 0., 0., 2., 1., 3. , 0.3, 0.3, 2);
+    puts("\n Set3DView(0., 0., 0., 2., 1., 3. , 0.3, 0.3, 2)");
+  }
+  else if ((isw%3) == 2) { 
+    Set3DView_Obs(0.,4.,0.,3.14159/2.,-3.14159/2.,0.,0.25,0.25,4.,2.);
+    puts("\n Set3DView_Obs(0.,4.,0.,3.14159/2.,3.14159/2.,0.,0.25,0.25,4.,2.)");
+  }
+  isw++;
+  mGr3d->PrintCS();
+  double xc,yc,zc,xo,yo,zo,teta,phi,psi,dax,day,co,dco;
+  mGr3d->Get3DCS(xc,yc,zc,xo,yo,zo,teta,phi,psi,dax,day,co,dco);
+  mGr3d->Set3DCS(xc,yc,zc,xo,yo,zo,dax,day,dco,psi);
+  mGr3d->PrintCS();
+  mGr3d->Set3DCS_Obs(xo,yo,zo,teta,phi,psi,dax,day,co,dco);
+  mGr3d->PrintCS();
+  puts(" --------------------- \n");
+  Refresh();
+  return;
+}
+if ((x > 0) && (y > 0) )  { 
+  puts(" But3Press()Set3DView(0., 0., 0., 5., 0., 0. , 0.3, 0.3, 2)");
+  Set3DView(0., 0., 0., 5., 0., 0. , 0.3, 0.3, 2);
+}
+else if ((x < 0) && (y > 0) )  { 
+  puts(" But3Press()Set3DView(0., 0., 0., 0., 5., 1. , 0.3, 0.3, 2) ");
+  Set3DView(0., 0., 0., 0., 5., 1. , 0.3, 0.3, 2);
+}
+else  if ((x < 0) && (y < 0) ) {
+  puts(" But3Press()Set3DView(0., 0., 0., 1., 1., 5. , 0.3, 0.3, 2)");
+  Set3DView(0., 0., 0., 1., 1., 5. , 0.3, 0.3, 2);
+}
+else {
+  puts(" But3Press()Set3DView(0., 0., 0., -3., -3., 3. , 0.3, 0.3, 2)");
+  Set3DView(0., 0., 0., -3., -3., 3. , 0.3, 0.3, 2);
+}
+
+Refresh();
+*/
Index: /tags/V_Dec2002/SophyaPI/PI/pi3dwdg.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pi3dwdg.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pi3dwdg.h	(revision 2309)
@@ -0,0 +1,88 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive PIDrawer3D PIDraw3DWdg
+//      DrawWidget 3D       R. Ansari 06/98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PIWDG3D_H_SEEN
+#define PIWDG3D_H_SEEN
+
+#include "pisysdep.h"
+#include "pi3ddrw.h"
+
+#include PIBWDG_H
+
+
+
+
+//------------------------------ Classe PIDrawer3D --------------------
+
+class PIDraw3DWdg : public PIBaseWdg {
+public:
+  enum {ClassId = 5500};
+
+			PIDraw3DWdg(PIContainerGen *par, const char *nom,
+                                    int sx=100, int sy=100, int px=0, int py=0);
+  virtual		~PIDraw3DWdg();
+  virtual long		kind() {return ClassId; }
+
+
+  virtual void		Set3DView_Obs(double xo, double yo, double zo, double teta, double phi, double psi, 
+                                      double dax, double day, double co, double dco=0.2);
+  virtual void       	Set3DView(double xc, double yc, double zc, double xo, double yo, double zo, 
+                                  double dax, double day, double dco=0.2, double psi=0.);
+  bool           	Get3DView(double& xc, double& yc, double& zc, double& xo, double& yo, double& zo, 
+                                  double& teta, double& phi, double& psi, double& dax, double& day, double& co, double& dco);
+
+  virtual void          Update3DView();   // Vue 3-D a partir de Drawer No 1
+
+  inline void	     	SetTitles(const char* tt=NULL, const char* tb=NULL)
+                                  { mBDrw->SetTitles(tt, tb); }
+  inline void	     	SetTitles(string const & tt, string const & tb)
+                                  { mBDrw->SetTitles(tt, tb); }
+  inline PIElDrawer3D*  BaseDrawer() { return mBDrw; };
+
+//   Methode permettant de decoder des options a partir de chaines
+  virtual int           DecodeOptionString(vector<string> & opt, bool rmdecopt=true);
+
+// Ajoute un Drawer 
+  int                   AddDrawer3D(PIDrawer3D*, bool ad=false);   
+
+//  Pour tenir trace des Drawers-3D qui sont detruits 
+  virtual void      	RemoveDrawer(int id);       
+  virtual void       	DeleteDrawers();            
+
+  virtual void		But1Press(int x, int y);
+
+  virtual void		But2Press(int x, int y);
+  virtual void		But2Release(int x, int y);
+  virtual void		Ptr2Move(int x, int y);
+
+  virtual void		But3Press(int x, int y);
+  virtual void		But3Release(int x, int y);
+  virtual void		Ptr3Move(int x, int y);
+
+  virtual void 		Keyboard(int key, PIKeyModifier kmod);
+  virtual void 		PasteSelection(unsigned int typ, void *pdata, unsigned int l);
+
+
+protected :
+  virtual void		SetDrawers3DView();
+  virtual void		DrawXYZAxes();
+
+  PIElDrawer3D* mBDrw;   // Objet traceur d'elements de fond
+  int mPx, mPy;        // Position pointeur - Bouton-1 
+  
+  bool vfixed;       // SetView fait ou pas
+  list<int> m3DrIl;  // Liste des Id drawers 3D 
+  PIGraphic3D* mGr3d;   // PIGraphic3D courante
+  int lPx, lPy;         // dernier position pointeur
+  PIColors lCol;        // Couleur
+  double cTeta, cPhi, cUlen;    // Pour garder valeurs avant rotation, Unite de longeur
+  double cXc, cYc, cZc;         // Pour garder position du centre de champ 
+  double clCO, cDax, cDay;      // Pour garder les valeurs avant Zoom In/Out
+  bool  rOfg;                  // si Vrai  on fait tourner l'objet et pas la camera
+  bool  axfg;                  // si Vrai on trace les axes
+  bool  skcfg;                 // si Vrai click-2 au centre -> rotation objet
+};
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/piapplgen.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piapplgen.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piapplgen.cc	(revision 2309)
@@ -0,0 +1,183 @@
+//  Classe de base d'objets application pour 
+//  les programmes graphiques interactives
+//
+//                  E.Aubourg , R. Ansari  96 - 98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+//++
+// Class	PIApplication
+// Lib		PI
+// include	piapplgen.h
+//
+//	Classe de base pour l'objet application. L'objet PIApplication 
+//	doit être créé avant la création des autres objets de PI.
+//	La classe "PIApplication" a implémentation dépendante 
+//	du systeme utilisé (Mac, XWindow, ...). La classe "PIApplicationGen" 
+//	est la classe qui définit l'interface, et ne doit pas être instanciée 
+//	directement (Méthodes virtuelles pures). Les objets instanciés sont 
+//	de la classes "PIApplication" et le fichier entête correspondant est 
+//	"PIAPP_H" défini dans "pisysdep.h".
+//--
+//++
+// Links	Parents
+// PIMsgHandler
+//--
+//++
+// Titre	Constructeur
+//--
+//++
+// PIApplication(int sx=200, int sy=30, int narg=0, char *arg[]=NULL)
+//	Constructeur. "sx,sy" est la taille de la fenêtre principale
+//	(ou PIContainer) associée à l'application. Des arguments
+//	optionnels, par exemple celle de la ligne de commande peuvent 
+//	être transmis à l'objet PIApplication. Dans le cas d'Unix/XWindow
+//	par exemple, les options reconnues par la Xtoolkit peuvent 
+//	être passées à l'objet application.
+//--
+
+//++
+// Titre	Méthodes
+//--
+//++
+// PIContainer*   MainWin()
+//	Renvoie le pointeur de l'objet "PIContainer" associé à l'application.
+// PIMenubar*   Menubar()
+//	Renvoie le pointeur de l'objet "PIMenubar" associé à l'application.
+// void AppendMenu(PIMenu *pdm)
+//	Ajoute le "PIMenu *pdm" au Menubar de l'application. Le titre 
+//	du menu dans le menubar est le nom de l'objet menu. 
+// void Run() Stop
+//	Démarre, arrête la boucle d'événements.
+//--
+
+
+#include "piapplgen.h"
+
+// Variable qui contient le pointeur de l'application courante
+// permet de recuperer la taille pref pour la fonction globale 
+static PIApplicationGen * curapp = NULL;
+
+PIApplicationGen::PIApplicationGen()
+:topcont(NULL), menubar(NULL), mState(0)
+{
+curapp = this;   
+}
+
+PIApplicationGen::~PIApplicationGen()
+{}
+
+
+void PIApplicationGen::AppendMenu(PIMenu *pdm)
+{
+if (menubar)
+  menubar->AppendMenu(pdm);
+return;
+}
+
+//++
+// void SetReady()
+//	Modifie l'état global de l'application - Pssage à l'état normal,
+//	prêt à traiter les actions utilisateur.
+// void SetBusy()
+//	Passage en mode de calcul - La souris prend la forme de la montre
+//	pour la fenêtre principale
+// void SetBlocked()
+//	Passge en mode bloqué. La barre de menu devient insensible
+// int GetState()
+//	Renvoie l'état global de l'application "(kReadyState, kBusyState, kBlockedState)".
+//--
+void PIApplicationGen::SetReady()
+{
+mState = kReadyState;
+}
+
+void PIApplicationGen::SetBusy()
+{
+mState = kBusyState;
+}
+
+void PIApplicationGen::SetBlocked()
+{
+mState = kBlockedState;
+}
+
+int PIApplicationGen::GetState()
+{
+return mState;
+}
+
+//++
+// Titre	Redirection StdOut, StdErr
+//	Il est possible de rediriger les flots de sortie
+//	standard et d'erreur vers un objet PIConsol.
+//--
+
+//++
+// void  RedirectOutStream(PIConsole* cons, unsigned char va= PIVA_Def)
+//	Redirige le flot de sortie ("stdout" sous Unix) vers l'objet 
+//	PIConsole "cons". si "cons==NULL", redirection 
+//	sur le flot original.
+//
+// void  RedirectErrStream(PIConsole* cons, unsigned char va= PIVA_Def)
+//	Redirige le flot des messages d'erreur ("stderr" sous Unix) 
+//	vers l'objet PIConsole "cons". si "cons==NULL", redirection
+//	 sur le flot original.
+//--
+
+//++
+// Titre	Informations globales
+//	Les méthodes suivantes permettent d'acceder aux informations  
+//	concernant l'écran (tailles, ...). Des fonctions globales sont 
+//	prévues ( "PIApplicationPrefCompSize()" et "PIApplicationScreenSize()" )
+//	afin d'obtenir ces informations sans avoir besoin d'une instance de la 
+//	classes application.
+//--
+//++
+// void  PIApplicationPrefCompSize(int& szx, int& szy)
+//	Fonction globale
+// void  PrefCompSize(int& szx, int& szy)
+//	Renvoie la taille préférée pour les composantes standard. "szx,szy" 
+//	est la taille (en pixels) pour un champ texte, ou un bouton "(PIText, PIButton)" 
+//	avec l'étiquette ou un contenu de 6 caractères (Ex: Cancel).
+//
+// void  PIApplicationScreenSize(int& szx, int& szy)
+//	Fonction globale
+// void  ScreenSize(int& szx, int& szy)
+//	Renvoie la taille de l'écran en pixels 
+//
+// void  PIApplicationScreenSizeMM(int& szx, int& szy)
+//	Fonction globale
+// void  ScreenSizeMM(int& szx, int& szy)
+//	Renvoie la taille de l'écran en mm 
+// 
+// void  PIApplicationScreenResolution(int& resolx, int& resoly)
+//	Fonction globale
+// void  ScreenResolution(int& resolx, int& resoly)
+//	Renvoie la resolution de l'ecran en pixels / cm
+//  
+//--
+
+void     PIApplicationPrefCompSize(int& szx, int& szy)
+{
+szx = szy = 10;
+if (curapp)  curapp->PrefCompSize(szx, szy);
+return; 
+}
+void     PIApplicationScreenSize(int& szx, int& szy)
+{
+szx = szy = 500;
+if (curapp)  curapp->ScreenSize(szx, szy);
+return; 
+}
+void     PIApplicationScreenSizeMM(int& szx, int& szy)
+{
+szx = szy = 400;
+if (curapp)  curapp->ScreenSizeMM(szx, szy);
+return; 
+}
+void     PIApplicationScreenResolution(int& resolx, int& resoly)
+{
+resolx = resoly = 30;
+if (curapp)  curapp->ScreenResolution(resolx, resoly);
+return; 
+}
Index: /tags/V_Dec2002/SophyaPI/PI/piapplgen.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piapplgen.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piapplgen.h	(revision 2309)
@@ -0,0 +1,52 @@
+#ifndef PIAPPLGEN_H_SEEN
+#define PIAPPLGEN_H_SEEN
+
+#include "pimsghandler.h"
+#include "pisysdep.h"
+#include PICONT_H
+#include PIMENUBAR_H
+#include "picons.h"
+
+
+class PIApplicationGen : public PIMsgHandler {
+public:
+        enum { kReadyState=0, kBusyState=1, kBlockedState=2 };
+
+				  PIApplicationGen();
+	virtual		          ~PIApplicationGen();
+	
+	virtual void              Run()=0;
+	virtual void              Stop()=0;
+
+        virtual void              SetReady();
+        virtual void              SetBusy(); 
+        virtual void              SetBlocked();
+        virtual int               GetState();
+
+
+	virtual PIContainer*      MainWin() {return topcont;}
+        virtual PIMenubar*        Menubar() {return menubar;}
+
+        virtual void              AppendMenu(PIMenu *pdm);
+
+        virtual void              PrefCompSize(int& szx, int& szy) = 0;
+        virtual void              ScreenSize(int& szx, int& szy) = 0;
+        virtual void              ScreenSizeMM(int& szx, int& szy) = 0;
+        virtual void              ScreenResolution(int& resolx, int& resoly) = 0;
+
+        virtual void              RedirectOutStream(PIConsole* cons, unsigned char va= PIVA_Def)  = 0;
+        virtual void              RedirectErrStream(PIConsole* cons, unsigned char va= PIVA_Ital|PIVA_Red) = 0;
+
+protected:
+    PIContainer               *topcont;
+    PIMenubar                 *menubar;
+    int                       mState;
+};
+
+//   Fonction globale pour recuperer la taille standard des composants (taille x,y) 
+void     PIApplicationPrefCompSize(int& szx, int& szy);  
+void     PIApplicationScreenSize(int& szx, int& szy);  
+void     PIApplicationScreenSizeMM(int& szx, int& szy);  
+void     PIApplicationScreenResolution(int& resolx, int& resoly);
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/piapplmac.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piapplmac.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piapplmac.cc	(revision 2309)
@@ -0,0 +1,120 @@
+
+#include "piapplmac.h"
+#include "pippmenubar.h"
+#include "pippapplmac.h"
+#include "piwindowmac.h"
+
+#include <LApplication.h>
+#include <LGrowZone.h>
+#include <UDrawingState.h>
+#include <UMemoryMgr.h>
+#include <SIOUX.h>
+#include <LAttachment.h>
+
+class PIInit {
+public:
+  PIInit() {
+    SIOUXSettings.initializeTB = false;
+    SIOUXSettings.standalone = false;
+    SIOUXSettings.setupmenus = false;
+    SIOUXSettings.showstatusline = true;
+  }
+};
+
+PIInit piInit;
+
+static PIApplication* cur_piapp = NULL;
+PIApplication* PIApplicationGetApp() { return cur_piapp; }
+
+
+class PISIOUXAttachment : public LAttachment {
+public:
+  PISIOUXAttachment();
+protected:
+ virtual void	ExecuteSelf(
+							MessageT		inMessage,
+							void			*ioParam);
+};
+
+PISIOUXAttachment::PISIOUXAttachment()
+: LAttachment()
+{}
+
+void PISIOUXAttachment::ExecuteSelf(MessageT msg, void* p)
+{
+  if (msg == msg_Event)
+    mExecuteHost = !SIOUXHandleOneEvent((EventRecord*)p);
+  if (!mExecuteHost)
+    UDesktop::NormalizeWindowOrder();
+}
+
+PIApplicationMac::PIApplicationMac(int sx, int sy, int /*narg*/, char** /*arg*/)
+{
+  SIOUXSettings.initializeTB = false;
+  SIOUXSettings.standalone = false;
+  SIOUXSettings.setupmenus = false;
+  SIOUXSettings.showstatusline = true;
+									// Set Debugging options
+	SetDebugThrow_(debugAction_Alert);
+	SetDebugSignal_(debugAction_Alert);
+
+	InitializeHeap(3);				// Initialize Memory Manager
+									// Parameter is number of Master Pointer
+									//   blocks to allocate
+	
+									// Initialize standard Toolbox managers
+	UQDGlobals::InitializeToolbox(&qd);
+	
+	new LGrowZone(20000);			// Install a GrowZone function to catch
+									//    low memory situations.
+									
+		// Register functions to create core PowerPlant classes
+	
+	RegisterAllPPClasses();
+
+	macAppli = new PIPPApplMac;
+	macAppli->AddAttachment(new PISIOUXAttachment);
+	
+    menubar = new PIMenubar(this, "DefMenubar");
+    topcont = new PIWindowMac(this, "TopLevel", PIWK_floating, sx, sy, 10, 45);
+
+  cur_piapp = this;
+}
+
+
+PIApplicationMac::~PIApplicationMac()
+{
+	delete macAppli;
+}
+
+void
+PIApplicationMac::Run()
+{
+    topcont->Show();
+	macAppli->Run();
+}
+
+void
+PIApplicationMac::Stop()
+{
+	macAppli->DoQuit();
+}
+
+/* --Methode-- */
+void PIApplicationMac::PrefCompSz(int& szx, int& szy)
+{
+  szx = 10;
+  szy = 10;
+}
+
+/* --Methode-- */
+void PIApplicationMac::ScreenSz(int& szx, int& szy)
+{
+  szx = 800;
+  szy = 600;
+}
+
+void PIApplicationMac::RedirectOutStream(PIConsole* cons, unsigned char va)
+{}
+void PIApplicationMac::RedirectErrStream(PIConsole* cons, unsigned char va)
+{}
Index: /tags/V_Dec2002/SophyaPI/PI/piapplmac.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piapplmac.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piapplmac.h	(revision 2309)
@@ -0,0 +1,28 @@
+#ifndef PIAPPLMAC_H_SEEN
+#define PIAPPLMAC_H_SEEN
+
+#include "piapplgen.h"
+
+class LApplication;
+class PIApplicationMac : public PIApplicationGen {
+public:
+					PIApplicationMac(int sx=200, int sy=30, int narg=0, char *arg[]=NULL);
+	virtual		   ~PIApplicationMac();
+	
+	virtual void    Run();
+	virtual void    Stop();
+	
+        virtual void              PrefCompSz(int& szx, int& szy);
+        virtual void              ScreenSz(int& szx, int& szy);
+
+        virtual void              RedirectOutStream(PIConsole* cons, unsigned char va= PIVA_Def);
+        virtual void              RedirectErrStream(PIConsole* cons, unsigned char va= PIVA_Ital);
+//protected:
+	LApplication* macAppli;
+};
+
+typedef PIApplicationMac PIApplication;
+
+//  Pour recuperer un objet PIApplication 
+PIApplication* PIApplicationGetApp();
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/piapplx.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piapplx.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piapplx.cc	(revision 2309)
@@ -0,0 +1,408 @@
+#include <stdio.h>
+#include <X11/cursorfont.h>
+#include <X11/IntrinsicP.h>
+#include <X11/Shell.h>
+#include <X11/StringDefs.h>
+#include <Xm/Xm.h>
+#include "piapplx.h"
+#include "picontainerx.h"
+
+// $CHECK$ - Reza Aout 99
+// Il y a un probleme sur la gestion de la taille de la fenetre principale
+// SetBinding(elastic) ne marche correctement pas sur la fenetre principale
+// et Des SetSize intempestive peuvent generer des comportements bizarres ! 
+
+// Pour rediriger stdout 
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <iostream.h>
+
+
+// #define DEBUG_APPLX
+
+static Cursor a_curs[3];
+static bool a_fgcur=false;
+
+//  Voir fichier pimenux.cc , Pour resoudre certains conflits avec les WindowManagers
+void SetTopWdgForMenuX(SysDWdg mtw);
+
+static PIApplication* cur_piapp = NULL;
+PIApplication* PIApplicationGetApp() { return cur_piapp; }
+
+
+// Classe de container special pour top-container de Application X
+
+class PITopContAppX : public PIContainer {
+public :
+	    	PITopContAppX(PIContainer *par, char *nom, PIWdg* topw,
+                          int sx=10, int sy=10, int px=0, int py=0);
+   virtual  	~PITopContAppX(); 
+
+   virtual void SetSize(int sx, int sy);
+   virtual void SetPos(int px, int py);
+
+PIWdg* mTopWdg;
+};
+
+
+/* --Methode-- */
+PITopContAppX::PITopContAppX(PIContainer *par, char *nom, PIWdg* topw, int sx, int sy, int px, int py)
+        : PIContainer(par, nom, (sx>10)?sx:10, (sy>10)?sy:10, px, py)
+{
+ mTopWdg = topw;
+ SetBinding(PIBK_fixed, PIBK_fixed, PIBK_fixed, PIBK_fixed);  
+}
+
+/* --Methode-- */
+PITopContAppX::~PITopContAppX()
+{
+}
+
+/* --Methode-- */
+void PITopContAppX::SetSize(int sx, int sy)
+{
+if ((sx <10) || (sy < 10) ) return; 
+
+int px = XPos();
+int py = YPos();
+// Probleme sur Sun - Reza 10/99 , REGLE 08/2000
+
+mTopWdg->SetSize(sx+px, sy+py);
+
+XtConfigureWidget(Parent()->XtWdg(),  0, 0, sx+px, sy+py, 0);
+XtConfigureWidget(XtWdg(),  px, py, sx, sy, 0);
+// SetPos(px, py);
+// PIContainer::SetSize(sx, sy); 
+}
+
+
+/* --Methode-- */
+void PITopContAppX::SetPos(int px, int py)
+{
+}
+
+// ---------------------------------------------
+// Fonction pour gestion des close-window
+
+/* Nouvelle-Fonction */
+static int fgactl = 0;
+
+static void CloseWindow (Widget w, XEvent*, String*,Cardinal*)
+{
+XtCallCallbacks(w,  XtNpopdownCallback, NULL);
+}
+
+/* Nouvelle-Fonction */
+static void popdwn_cb_app(Widget /*w*/, XtPointer *usd,  XtPointer * )
+{
+PIApplicationX * app = (PIApplicationX *) usd;
+app->SendSelf(0,PIMsg_Close, NULL) ;
+}
+
+
+/* --Methode-- */
+PIApplicationX::PIApplicationX(int sx, int sy, int narg, char *arg[])
+: PIApplicationGen()
+{
+int sxt, syt;
+
+#ifdef DEBUG_APPLX
+puts("PIApplicationX::PIApplicationX()_info : App creation");
+#endif
+mStop = true;
+
+
+topwdg = new PIWdgX(narg, arg);
+
+int msx,msy;
+PrefCompSize(msx, msy);
+msy+=5;
+topwdg->SetSize(sx, sy+msy);
+//DBG printf("PIApplicationX-DBG:: Size=%d %d \n", topwdg->XSize(), topwdg->YSize());
+
+intcont = new PIContainerX((PIMsgHandler *)this, topwdg, "MBCont", 
+                            sx, sy+msy, 0, 0);
+// Pb avec les Popup MenuX et certains Window Manager , voir pimenux.cc
+SetTopWdgForMenuX(intcont->XtWdg());
+
+menubar = new PIMenubar(this, "DefMenubar");
+Menubar()->SetBinding(PIBK_fixed, PIBK_fixed, PIBK_fixed, PIBK_free);
+sxt = ( sx > Menubar()->XSize() ) ? sx : Menubar()->XSize();
+syt = ( sy > 10 ) ? sy : 10;
+// syt += Menubar()->YSize();
+// syt += msy;
+// topwdg->SetSize(sxt, syt);
+// MBCont()->SetSize(sxt, syt);
+if (sx < sxt)  sx = sxt;
+if (sy < 10) sy = 10;
+topcont = new PITopContAppX(MBCont(), "TopLevelCont", topwdg, 
+                            sx, sy, 0, msy);
+MBCont()->Show();
+//DBG printf("PIApplicationX-DBG2:: MBContSize=%d %d \n", MBCont()->XSize(), MBCont()->YSize());
+
+
+topcont->Show();
+
+
+if (!a_fgcur)
+  {
+  Display *mdsp;
+  mdsp = XtDisplay (topwdg->XtWdg()); 
+  a_curs[0] = XCreateFontCursor(mdsp, XC_arrow);
+  a_curs[1] = XCreateFontCursor(mdsp, XC_X_cursor);
+  a_curs[2] = XCreateFontCursor(mdsp, XC_watch);
+  }
+
+topwdg->Manage();
+
+// ------------------------------------------------------
+//   Pour la gestion des close window des Window manager 
+
+if (fgactl == 0)    { 
+  XtActionsRec desact = {(char *)"CloseWindow" ,CloseWindow};
+  int szx, szy, szf;
+  XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
+  XtAppAddActions(*appctx, &desact, 1);  
+  Display *mdsp;
+  mdsp = XtDisplay (topwdg->XtWdg()); 
+  Atom wmd;
+  wmd = XInternAtom(mdsp, "WM_DELETE_WINDOW",False);
+  XSetWMProtocols(mdsp, XtWindow(topwdg->XtWdg()), &wmd, 1);
+  fgactl = 1; 
+}
+
+XtTranslations trans;
+trans = XtParseTranslationTable("<Message>WM_PROTOCOLS:CloseWindow()");
+XtOverrideTranslations(topwdg->XtWdg() , trans);
+Arg warg[2];
+XtSetArg(warg[0], XmNdeleteResponse, XmDO_NOTHING);
+XtSetValues(topwdg->XtWdg(), warg, 1);
+
+XtAddCallback(topwdg->XtWdg(), XtNpopdownCallback,
+	      (XtCallbackProc)popdwn_cb_app, (XtPointer)this);
+
+// ------------------------------------------------------
+
+cur_piapp = this;
+mState = -1;
+SetReady();
+}
+
+/* --Methode-- */
+PIApplicationX::~PIApplicationX()
+{
+#ifdef DEBUG_APPLX
+puts("PIApplicationX::~PIApplicationX()_info : App delete");
+#endif
+Display *mdsp;
+mdsp = XtDisplay (topwdg->XtWdg()); 
+topwdg->UnManage();
+delete menubar;
+if (topcont != MBCont())  delete topcont;
+delete intcont;
+delete topwdg;
+XtCloseDisplay(mdsp);
+cur_piapp = NULL;
+return;
+}
+
+/* --Methode-- */
+void PIApplicationX::Run()
+{
+XEvent evt;
+#ifdef DEBUG_APPLX
+puts("PIApplicationX::Run()_info : App Run ");
+#endif
+
+
+int szx, szy, szf;
+XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
+
+// Pour appeler FinishCreate() des objets dans la fenetre principale 
+if (mStop) { // C'est la premiere fois
+  topcont->SetSize(topcont->XSize(), topcont->YSize());
+  // topwdg->SetSize(MBCont()->XSize(), MBCont()->YSize());
+  MBCont()->FinishCreate();   
+  }
+else mStop = true;   // On rerentre apres un stop 
+while (mStop)
+  {
+  XtAppNextEvent(*appctx, &evt);
+  XtDispatchEvent(&evt);
+  }
+return;
+}
+
+
+/* --Methode-- */
+void PIApplicationX::SetReady()
+{
+Display * mdsp = XtDisplay (topwdg->XtWdg());
+if (mState != kReadyState)
+  {
+  mState = kReadyState;
+  Menubar()->SetSensitive();
+  XDefineCursor(mdsp, XtWindow(topwdg->XtWdg()), a_curs[0]);
+  }
+XFlush(mdsp);
+}
+
+/* --Methode-- */
+void PIApplicationX::SetBusy()
+{
+Display * mdsp = XtDisplay (topwdg->XtWdg());
+if (mState != kBusyState)
+  {
+  mState = kBusyState;
+  Menubar()->SetSensitive();
+//  if ( XtIsRealized(topwdg->XtWdg()) )
+  XDefineCursor(mdsp, XtWindow(topwdg->XtWdg()), a_curs[2]);
+  }
+XFlush(mdsp);
+}
+
+/* --Methode-- */
+void PIApplicationX::SetBlocked()
+{
+Display * mdsp = XtDisplay (topwdg->XtWdg());
+if (mState != kBlockedState)
+  {
+  mState = kBlockedState;
+  Menubar()->SetUnSensitive();
+  XDefineCursor(mdsp, XtWindow(topwdg->XtWdg()), a_curs[1]);
+  }
+XFlush(mdsp);
+return;
+}
+
+
+/* --Methode-- */
+void PIApplicationX::PrefCompSize(int& szx, int& szy)
+{
+int szf;
+PIXtAppCtx(szx, szy, szf);
+return;
+}
+
+/* --Methode-- */
+void PIApplicationX::ScreenSize(int& szx, int& szy)
+{
+Display * dsp = PIXDisplay();
+szx = DisplayWidth(dsp, DefaultScreen(dsp));
+szy = DisplayHeight(dsp, DefaultScreen(dsp));
+}
+
+/* --Methode-- */
+void PIApplicationX::ScreenSizeMM(int& szx, int& szy)
+{
+Display * dsp = PIXDisplay();
+szx = DisplayWidthMM(dsp, DefaultScreen(dsp));
+szy = DisplayHeightMM(dsp, DefaultScreen(dsp));
+}
+
+/* --Methode-- */
+void PIApplicationX::ScreenResolution(int& resolx, int& resoly)
+{
+Display * dsp = PIXDisplay();
+resolx = (int)((double)DisplayWidth(dsp, DefaultScreen(dsp))*10./
+  (double)DisplayWidthMM(dsp, DefaultScreen(dsp)));
+resoly = (int)((double)DisplayHeight(dsp, DefaultScreen(dsp))*10./
+  (double)DisplayHeightMM(dsp, DefaultScreen(dsp)));
+}
+
+
+
+
+
+/* Call-Back - Fonction privee de ce fichier */
+static void redirectstream_callback(XtPointer, int *, XtInputId*);
+
+static PIConsole* consstream[2] = {NULL, NULL};
+static unsigned char streamva[2] = { PIVA_Def, PIVA_Ital};
+static int streamno[2] = {0,1};
+static XtInputId inputid[2];
+static int origfiledes[2]={-1, -1};   // descripteurs de fichiers de depart
+
+static void redirectstream_callback(XtPointer cld, int * fd, XtInputId* /*iid*/)
+{
+char buff[128];
+int nr;
+
+int idx = *((int*)cld);
+if (idx != 1) idx = 0; 
+if (!consstream[idx]) return;
+while ( (nr=read(*fd, buff, 127)) > 0 ) {
+  buff[nr] = '\0'; consstream[idx]->AddStr(buff, streamva[idx], false);
+  }
+consstream[idx]->Refresh();
+}
+
+/* --Methode-- */
+void PIApplicationX::RedirectOutStream(PIConsole* cons, unsigned char va)
+{
+if ( origfiledes[0]<0 )  origfiledes[0] = fcntl(1, F_DUPFD);     
+if ( cons == consstream[0]) return;
+if ( (consstream[0]) && (cons) ) { consstream[0] = cons; streamva[0] = va; return; }
+else if (!cons) { 
+  consstream[0] = NULL;  
+  XtRemoveInput(inputid[0]);
+  dup2(origfiledes[0], 1);
+  return;
+  }
+
+consstream[0] = cons; streamva[0] = va;
+
+int p[2];
+pipe(p);
+// Redirection de stdout (fid=1) :  
+close(1);
+dup(p[1]);
+close(p[1]);
+fcntl(p[0], F_SETFL, O_NONBLOCK);
+
+#if (!defined(__GNUG__) && !defined(HPUX))
+setlinebuf(stdout);
+#endif
+ios::sync_with_stdio();
+
+int szx, szy, szf;
+XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
+inputid[0] = XtAppAddInput(*appctx, p[0], (XtPointer) XtInputReadMask, 
+                           redirectstream_callback, (XtPointer) streamno);
+}
+
+/* --Methode-- */
+void PIApplicationX::RedirectErrStream(PIConsole* cons, unsigned char va)
+{
+if ( origfiledes[1]<0 )  origfiledes[1] = fcntl(2, F_DUPFD);     
+if ( cons == consstream[1]) return;
+if ( (consstream[1]) && (cons) ) { consstream[1] = cons; streamva[1] = va; return; }
+else if (!cons) { 
+  consstream[1] = NULL;  
+  XtRemoveInput(inputid[1]);
+  dup2(origfiledes[1], 2);
+  return;
+  }
+
+consstream[1] = cons; streamva[1] = va;
+
+int p[2];
+pipe(p);
+// Redirection de stderr (fid=2) :
+close(2);
+dup(p[1]);
+close(p[1]);
+fcntl(p[0], F_SETFL, O_NONBLOCK);
+
+#if (!defined(__GNUG__) && !defined(HPUX))
+setlinebuf(stderr);
+#endif
+ios::sync_with_stdio();
+
+int szx, szy, szf;
+XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
+inputid[1] = XtAppAddInput(*appctx, p[0], (XtPointer) XtInputReadMask, 
+                           redirectstream_callback, (XtPointer) (streamno+1));
+}
+
Index: /tags/V_Dec2002/SophyaPI/PI/piapplx.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piapplx.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piapplx.h	(revision 2309)
@@ -0,0 +1,40 @@
+#ifndef PIAPPLX_H_SEEN
+#define PIAPPLX_H_SEEN
+
+#include "piapplgen.h"
+#include "piwdgx.h"
+#include "picontainerx.h"
+
+class PIApplicationX : public PIApplicationGen {
+public:
+  		            PIApplicationX(int sx=200, int sy=30, int narg=0, char *arg[]=NULL);
+
+  virtual	            ~PIApplicationX();
+	
+  virtual void              Run();
+  virtual void              Stop() { mStop = false; }
+
+  virtual void              SetReady();
+  virtual void              SetBusy(); 
+  virtual void              SetBlocked();
+
+  virtual void              PrefCompSize(int& szx, int& szy);
+  virtual void              ScreenSize(int& szx, int& szy);
+  virtual void              ScreenSizeMM(int& szx, int& szy);
+  virtual void              ScreenResolution(int& resolx, int& resoly);
+
+  virtual void              RedirectOutStream(PIConsole* cons, unsigned char va= PIVA_Def);
+  virtual void              RedirectErrStream(PIConsole* cons, unsigned char va= PIVA_Ital|PIVA_Red);
+
+  PIContainer*              MBCont() { return intcont; }
+protected:
+  PIWdg * topwdg;
+  PIContainer * intcont;
+  bool mStop;
+};
+
+typedef PIApplicationX PIApplication;
+
+//  Pour recuperer un objet PIApplication 
+PIApplication* PIApplicationGetApp();
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/piaxes.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piaxes.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piaxes.cc	(revision 2309)
@@ -0,0 +1,810 @@
+// Module PI : Peida Interactive     PIAxes
+// Methodes de trace des axes 
+//                    R. Ansari - 2002
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "machdefs.h"
+#include <stdio.h>
+#include <iostream.h>
+#include <strings.h>
+#include <math.h>
+#include "piaxes.h"
+
+//++
+// Class	PIAxes
+// Lib		PI
+// include	piaxes.h
+//
+//	Classe gestionnaire de tracé d'axes. A utiliser dans
+//	un objet PIDrawer.
+//--
+//++
+// Links	Voir
+// PIDrawer
+//--
+
+//++
+// Titre	Constructeurs et méthodes
+//--
+
+
+inline void dble_SWAP(double& a,double& b) {double tmp=a; a=b; b=tmp;}
+
+//++
+// PIAxes()
+//	Constructeur.
+//--
+
+/* --Methode-- */
+PIAxes::PIAxes()
+{
+  setupDone = false;
+}
+
+/* --Methode-- */
+PIAxes::~PIAxes()
+{
+}
+
+//++
+// void  DrawXYAxes(PIGraphicUC* g, PIGraphicAtt& gratt, unsigned int flags, bool afsz)
+//	Trace les axes en utilisant les limites de l'objet PIGraphicUC. 
+//	"flags" spécifie les attributs d'axes. Constantes prédéfinies: 
+//|	kStdAxes : Axes passant par le centre
+//|     kBoxAxes : Axes entourant le tracé
+//|	kIntTicks, kExtTicks
+//|	kMajTicks, kMinTicks
+//|	kAxesDflt = kStdAxes | kTicks | kLabels
+//|	kGridOn, kAxesNone
+//	Si "afsz == true", la taille de fonte est choisie automatiquement.
+//
+// void DrawXYAxes(PIGraphicUC* g, PIGraphicAtt& gratt, unsigned int flags, bool afsz, \
+//      double xmin, double xmax, double ymin, double ymax)
+//	Tracé d'axes avec spécification des limites d'axes.
+//
+// void DrawXCaption(PIGraphicUC* g, string const& xLabel, PIGraphicAtt const& att)
+//	Tracé du label d'axe X.
+// void DrawYCaption(PIGraphicUC* g, string const& YLabel, PIGraphicAtt const& att)
+//	Tracé du label d'axe Y.
+//--
+
+/* --Methode-- */
+void PIAxes::DrawXYAxes(PIGraphicUC* g, PIGraphicAtt& gratt, 
+			unsigned int flags, bool afsz)
+{
+  PIGrCoord xmin, xmax, ymin, ymax;
+  g->GetGrSpace(xmin, xmax, ymin, ymax);
+  DrawXYAxes(g, gratt, flags, afsz, (double)xmin, (double)xmax, 
+	     (double)ymin, (double)ymax);
+}
+
+/* --Methode-- */
+void PIAxes::DrawXYAxes(PIGraphicUC* g, PIGraphicAtt& gratt, 
+			unsigned int flags, bool afsz,
+			double xmin, double xmax, double ymin, double ymax)
+{
+  Setup(g, xmin, xmax, ymin, ymax);
+  //  g->NoClip();
+
+  if (gratt.GetLineAtt() == PI_NotDefLineAtt)  g->SelLine(PI_ThinLine);
+  else g->SelLine(gratt.GetLineAtt());
+  if (gratt.GetColor() == PI_NotDefColor) g->SelForeground(PI_Black);
+  else g->SelForeground(gratt.GetColor());
+
+  if(afsz) { 
+    double fsz = xMajTickLen*3.5;
+    g->SelFontSz(fsz);
+  }
+
+  if (flags & kStdAxes) {
+
+    // Les axes
+    
+    g->DrawLine(xMin, (yMin+yMax)/2., xMax, (yMin+yMax)/2.);
+    g->DrawLine((xMin+xMax)/2., yMin, (xMin+xMax)/2., yMax);
+    PIArrowMarker amk = g->GetArrowMarker();
+    if (amk == PI_NotDefArrowMarker) amk = PI_FArrowShapedArrowMarker;
+    g->SelArrowMarkerSz(xMajTickLen*2., amk);
+    //    g->SelArrowMarker(5, g->GetArrowMarker());
+    double xm2 = g->DeltaUCX(xMax, yMajTickLen*3.);
+    g->DrawArrowMarker(xMax, (yMin+yMax)/2., xm2, (yMin+yMax)/2., true);
+    double ym2 = g->DeltaUCY(yMax, xMajTickLen*3.);
+    g->DrawArrowMarker((xMin+xMax)/2., yMax, (xMin+xMax)/2., ym2, true);
+    // La grille en pointilles
+
+    if (flags & kGridOn) DrawGrid(g);
+  
+    // Les ticks majeurs
+  
+    if (flags & kMajTicks) {
+        DrawHTicks(g, (yMin+yMax)/2., xMajTickLen, xMajTickLen, xMajTicks);
+        DrawVTicks(g, (xMin+xMax)/2., yMajTickLen, yMajTickLen, yMajTicks);
+    }
+    
+    // Les ticks mineurs
+  
+    if (flags & kMinTicks) {
+        DrawHTicks(g, (yMin+yMax)/2., xMinTickLen, xMinTickLen, xMinTicks);
+        DrawVTicks(g, (xMin+xMax)/2., yMinTickLen, yMinTickLen, yMinTicks);
+    }
+    
+    // Les labels
+    
+    if (flags & kLabels) {
+      if (!aYdir)
+        DrawHLabels(g, (yMin+yMax)/2.-xMajTickLen*2, xMajTicks, PI_VerticalTop);
+      else 
+        DrawHLabels(g, (yMin+yMax)/2.+xMajTickLen*2, xMajTicks, PI_VerticalTop);
+      if (!aXdir)
+        DrawVLabels(g, (xMin+xMax)/2.-yMajTickLen*2, yMajTicks, PI_HorizontalRight);
+      else 
+        DrawVLabels(g, (xMin+xMax)/2.+yMajTickLen*2, yMajTicks, PI_HorizontalRight);
+    }
+    
+  }
+  
+  if (flags & kBoxAxes) {
+  
+    // La boite
+    
+    g->DrawLine(xMin, yMin, xMax, yMin);
+    g->DrawLine(xMax, yMin, xMax, yMax);
+    g->DrawLine(xMax, yMax, xMin, yMax);
+    g->DrawLine(xMin, yMax, xMin, yMin);
+
+    // Longueur des ticks
+    if (flags&kTicks) flags |= kExtTicks;
+    double extXMajTickLen = flags&kExtTicks ? xMajTickLen : 0;
+    double intXMajTickLen = flags&kIntTicks ? xMajTickLen : 0;
+    double extXMinTickLen = flags&kExtTicks ? xMinTickLen : 0;
+    double intXMinTickLen = flags&kIntTicks ? xMinTickLen : 0;
+    double extYMajTickLen = flags&kExtTicks ? yMajTickLen : 0;
+    double intYMajTickLen = flags&kIntTicks ? yMajTickLen : 0;
+    double extYMinTickLen = flags&kExtTicks ? yMinTickLen : 0;
+    double intYMinTickLen = flags&kIntTicks ? yMinTickLen : 0;
+
+    // La grille en pointilles
+
+    if (flags & kGridOn) DrawGrid(g);
+
+    // Les ticks majeurs
+  
+    if (flags & kMajTicks) {
+        DrawHTicks(g, yMin, intXMajTickLen, extXMajTickLen, xMajTicks);
+        DrawHTicks(g, yMax, extXMajTickLen, intXMajTickLen, xMajTicks);
+        DrawVTicks(g, xMin, extYMajTickLen, intYMajTickLen, yMajTicks);
+        DrawVTicks(g, xMax, intYMajTickLen, extYMajTickLen, yMajTicks);
+    }
+    
+    // Les ticks mineurs
+  
+    if (flags & kMinTicks) {
+        DrawHTicks(g, yMin, intXMinTickLen, extXMinTickLen, xMinTicks);
+        DrawHTicks(g, yMax, extXMinTickLen, intXMinTickLen, xMinTicks);
+        DrawVTicks(g, xMin, extYMinTickLen, intYMinTickLen, yMinTicks);
+        DrawVTicks(g, xMax, intYMinTickLen, extYMinTickLen, yMinTicks);
+    }
+
+
+    // Les labels
+    
+    if (flags & kLabels) {
+      if (!aYdir) {
+        DrawHLabels(g, g->DeltaUCY(yMin, -xMajTickLen*2), xMajTicks, PI_VerticalTop);
+      }
+      else {
+        DrawHLabels(g, g->DeltaUCY(yMax,  xMajTickLen*2), xMajTicks, PI_VerticalTop);
+      }
+      if (!aXdir) {
+        DrawVLabels(g, g->DeltaUCX(xMin, -yMajTickLen*2), yMajTicks, PI_HorizontalRight);
+      }
+      else {
+        DrawVLabels(g, g->DeltaUCX(xMax,  yMajTickLen*2), yMajTicks, PI_HorizontalRight);
+      }
+    }
+  }
+  g->Clip();
+  
+}
+
+/* --Methode-- */
+void PIAxes::DrawXCaption(PIGraphicUC* g, PIGraphicAtt& att, unsigned int flags, string const& xLabel)
+{
+  if (xLabel.length() < 1) return;
+  if (!setupDone) {
+    PIGrCoord xmin, xmax, ymin, ymax;
+    g->GetGrSpace(xmin, xmax, ymin, ymax);
+    Setup(g, xmin, xmax, ymin, ymax);
+  }
+  if ( (att.GetFontName() != PI_DefaultFont) ||
+       (att.GetFontAtt() != PI_NotDefFontAtt) )
+    g->SelFont(att.GetFont());
+  PIColors fcol = att.GetFgColor(); 
+  if (fcol != PI_NotDefColor)    g->SelForeground(fcol);
+
+  double fx,fy,fh;
+  if (flags&kBoxAxes) { 
+    fh = -0.090*(yMax-yMin);  
+    if (g->isAxeYDirUpDown()) fy = yMax;
+    else fy = yMin;
+  }
+  else {
+    fh = 0.04*(yMax-yMin);  
+    fy = 0.5*(yMin+yMax);
+  }
+  if (g->isAxeYDirUpDown()) fh = -fh;
+  fy = g->DeltaUCY(fy, fh);
+  fx = g->DeltaUCX(xMax, -(xMax-xMin)*0.25);
+  g->DrawString(fx, fy, xLabel.c_str(), 
+		PI_HorizontalCenter | PI_VerticalCenter);  
+}
+
+/* --Methode-- */
+void PIAxes::DrawYCaption(PIGraphicUC* g, PIGraphicAtt& att, unsigned int flags, string const& yLabel)
+{
+  if (yLabel.length() < 1) return;
+  if (!setupDone) {
+    PIGrCoord xmin, xmax, ymin, ymax;
+    g->GetGrSpace(xmin, xmax, ymin, ymax);
+    Setup(g, xmin, xmax, ymin, ymax);
+  }
+  if ( (att.GetFontName() != PI_DefaultFont) ||
+       (att.GetFontAtt() != PI_NotDefFontAtt) )
+    g->SelFont(att.GetFont());
+  PIColors fcol = att.GetFgColor(); 
+  if (fcol != PI_NotDefColor)    g->SelForeground(fcol);
+
+  double fx,fy,fh;
+  if (flags&kBoxAxes) { 
+    fh = -0.125*(xMax-xMin);
+    if (g->isAxeXDirRtoL()) fx = xMax;
+    else fx = xMin;
+  }
+  else {
+    fh = 0.04*(xMax-xMin);
+    fx = 0.5*(xMin+xMax);
+  }
+  if (g->isAxeXDirRtoL()) fh = -fh;
+  fx = g->DeltaUCX(fx, fh);
+  fy = g->DeltaUCY(yMax,-(yMax-yMin)*0.25);
+  unsigned long txtflg = PI_HorizontalCenter | PI_VerticalCenter | PI_TextDirectionVerticalUp;
+  if (g->isAxeYDirUpDown()) 
+    txtflg = PI_HorizontalCenter | PI_VerticalCenter | PI_TextDirectionVerticalDown;
+  g->DrawString(fx, fy, yLabel.c_str(), txtflg);
+  
+}
+
+/* --Methode-- */
+void PIAxes::Setup(PIGraphicUC* g, double xmin, double xmax, 
+		       double ymin, double ymax)
+{
+  
+  xMin = xmin;  xMax = xmax;
+  yMin = ymin;  yMax = ymax;
+
+  aXdir = g->isAxeXDirRtoL();
+  aYdir = g->isAxeYDirUpDown();
+  aXlog = g->isLogScaleX();
+  aYlog = g->isLogScaleY();
+
+  int ntick_x = (aXlog) ? 10 : 10;
+  if(aXlog) BestTicksLog(xMin,xMax,ntick_x,xMajTicks,xMinTicks);
+  else BestTicks(xMin,xMax,ntick_x,xMajTicks,xMinTicks);
+
+  int ntick_y = (aYlog) ? 12 : 12;
+  if(aYlog) BestTicksLog(yMin,yMax,ntick_y,yMajTicks,yMinTicks);
+  else BestTicks(yMin,yMax,ntick_y,yMajTicks,yMinTicks);
+
+  yMajTickLen = (xMax-xMin)/100;
+  yMinTickLen = (xMax-xMin)/200;  // Au lieu de 250, Reza 20/10/02
+  xMajTickLen = (yMax-yMin)/100;
+  xMinTickLen = (yMax-yMin)/200;  // Au lieu de 250, Reza 20/10/02
+
+  setupDone = true;
+}
+
+
+/* --Methode-- */
+void PIAxes::DrawHTicks(PIGraphicUC* g, double y, double tickUp, 
+			double tickDown, vector<double>& xticks)
+{
+  if(xticks.size()==0) return;
+  for(unsigned int i=0;i<xticks.size();i++) {
+    if(xticks[i]<xMin) continue;
+    if(xticks[i]>xMax) break;
+    g->DrawLine(xticks[i],g->DeltaUCY(y,-tickDown),xticks[i],g->DeltaUCY(y,tickUp));
+  }
+}
+
+/* --Methode-- */
+void PIAxes::DrawVTicks(PIGraphicUC* g, double x, double tickLeft, 
+			double tickRight, vector<double>& yticks)
+{
+  if(yticks.size()==0) return;
+  for(unsigned int i=0;i<yticks.size();i++) {
+    if(yticks[i]<yMin) continue;
+    if(yticks[i]>yMax) break;
+    g->DrawLine(g->DeltaUCX(x,-tickLeft),yticks[i],g->DeltaUCX(x,tickRight),yticks[i]);
+  }
+}
+
+/* --Methode-- */
+void PIAxes::DrawHLabels(PIGraphicUC* g, double y, vector<double>& xticks, unsigned long just)
+{
+  if(xticks.size()==0) return;
+
+  // Choix du bon format pour les labels des axes
+  string format; double xstep;
+  int npuiss = Le_Bon_Format(xticks,format,xstep);
+  double fac=(npuiss!=0)? fac=pow(10.,(double)npuiss): 1.;
+
+  char label[64];
+  double dum,xpixdeb,xpixfin,largpix;
+  g->UC2GrC(xMin-2.*(xMax-xMin),y,xpixfin,dum);
+  for(unsigned int i=0;i<xticks.size();i++) {
+    if(xticks[i]<xMin) continue;
+    if(xticks[i]>xMax) break;
+    //Attention erreur d'arrondi x->0 (on code 5.1698e-26 au lieu de 0)
+    double xx = (fabs(xticks[i]/xstep)<1.e-5) ? 0.: xticks[i];
+    sprintf(label,format.c_str(),xx/fac); Arrange_Label(label);
+    double largeur = g->CalcStringWidth(label);
+    g->DUC2GrC(largeur,0.,largpix,dum);
+    g->UC2GrC(xticks[i],y,xpixdeb,dum);   xpixdeb -= largpix/2.;
+    //cout<<"xticks="<<xticks[i]<<" largpix="<<largpix
+    //    <<" xpixdeb="<<xpixdeb<<" xpixfin="<<xpixfin<<endl;
+    if((aXdir && xpixdeb<xpixfin) || (!aXdir && xpixdeb>xpixfin)) {
+      g->DrawString(xticks[i],y,label,PI_HorizontalCenter|just);
+      xpixfin = xpixdeb + 1.1*largpix;
+    }
+  }
+
+  if(npuiss!=0) {
+    PIGrCoord asc,desc;
+    double h = g->GetFontHeight(asc,desc);
+    if((aYdir && (just&PI_VerticalBottom)) || (!aYdir && (just&PI_VerticalTop))) h=-h; 
+    double xm = (aXdir)? xMin: xMax;
+    double ym = g->DeltaUCY(y,1.5*h);
+    sprintf(label,"%d",npuiss);
+    g->DrawCompString(xm,ym,"x 10",label,NULL,PI_HorizontalCenter|just);
+  }
+
+}
+
+/* --Methode-- */
+void PIAxes::DrawVLabels(PIGraphicUC* g, double x, vector<double>& yticks, unsigned long just)
+{
+  if(yticks.size()==0) return;
+
+  // Choix du bon format pour les labels des axes;
+  string format; double ystep;
+  int npuiss = Le_Bon_Format(yticks,format,ystep);
+  double fac=(npuiss!=0)? fac=pow(10.,(double)npuiss): 1.;
+
+  char label[64];
+  PIGrCoord asc,desc;
+  double dum,ypixdeb,ypixfin,hautpix,hauteur=g->GetFontHeight(asc,desc);
+  g->DUC2GrC(0.,hauteur,dum,hautpix);
+  g->UC2GrC(x,yMin-2.*(yMax-yMin),dum,ypixfin);
+  for(unsigned int i=0;i<yticks.size();i++) {
+    if(yticks[i]<yMin) continue;
+    if(yticks[i]>yMax) break;
+    double yy = (fabs(yticks[i]/ystep)<1.e-5) ? 0.: yticks[i];
+    sprintf(label,format.c_str(),yy/fac); Arrange_Label(label);
+    g->UC2GrC(x,yticks[i],dum,ypixdeb);   ypixdeb -= hautpix/2.;
+    // -- Attention: ypix=0 est en haut de l'ecran
+    //               (ypix croissants vers le bas de l'ecran)
+    //    donc bien que yMin<yMax on a yMinPix>yMaxPix
+    //cout<<"yticks="<<yticks[i]<<" hautpix="<<hautpix
+    //    <<" ypixdeb="<<ypixdeb<<" ypixfin="<<ypixfin<<endl;
+    if((aYdir && ypixdeb>ypixfin) || (!aYdir && ypixdeb<ypixfin)) {
+      g->DrawString(x,yticks[i],label,PI_VerticalCenter|just);
+      ypixfin = ypixdeb + 1.1*hautpix;
+    }
+  }
+
+  if(npuiss!=0) {
+    if(aYdir) hauteur = -hauteur; 
+    double ym = (aYdir)? yMin: yMax; ym = g->DeltaUCY(ym,hauteur);
+    sprintf(label,"%d",npuiss);
+    g->DrawCompString(x,ym,"x 10",label,NULL,PI_VerticalBottom|just);
+  }
+
+}
+
+/* --Methode-- */
+void PIAxes::DrawGrid(PIGraphicUC* g)
+{
+  PILineAtt savlineatt = g->GetLineAtt();
+  g->SelLine(PI_ThinDottedLine);
+
+  if(xMajTicks.size()>0)
+    for(unsigned int i=0;i<xMajTicks.size();i++) {
+      if(xMajTicks[i]>xMax) break;
+      g->DrawLine(xMajTicks[i], yMin, xMajTicks[i], yMax);
+    }
+
+  if(yMajTicks.size()>0)
+    for(unsigned int i=0;i<yMajTicks.size();i++) {
+      if(yMajTicks[i]>yMax) break;
+      g->DrawLine(xMin, yMajTicks[i], xMax, yMajTicks[i]);
+    }
+
+  g->SelLine(savlineatt);
+}
+
+////////////////////////////////////////////////////////////////////////
+//////////////////// METHODES STATIQUES ////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+/* --Methode-Static-- */
+void PIAxes::ReSizeMinMax(bool axelog,double& vmin,double& vmax,double garde)
+//  Calcul du min et du max du display a partir des valeurs min et max a plotter
+{
+ if(garde<0. || garde>=1.) garde = 0.025;
+ // cout<<"ReSizeMinMax[log="<<axelog<<",garde="<<garde<<"] vmin="<<vmin<<" vmax="<<vmax<<endl;
+ // Cas d'une echelle lineaire
+ if(!axelog || vmax<=0.) {
+   double dv = garde*(vmax-vmin);
+   vmin -= dv;
+   vmax += dv;
+ }
+
+ // Cas d'une echelle log avec un range raisonnable
+ else if(vmin>0.) {
+   double dv = pow(vmax/vmin,garde);
+   vmin /= dv;
+   vmax *= dv;
+ }
+
+ // Cas d'une echelle log avec un range de-raisonnable
+ else if(vmin<=0.) {
+   if(vmin<0.)  vmin += garde*vmin;
+   if(vmax==1.) vmax  = 1.+garde;
+   if(vmax>1.)  vmax  = pow(vmax,1.+garde);
+     else       vmax  = pow(vmax,1.-garde);
+ }
+
+ // cout<<"           vmin="<<vmin<<" vmax="<<vmax<<endl;
+}
+
+/* --Methode-Static-- */
+void PIAxes::BestTicks(double xmin,double xmax,int nticks
+                      ,vector<double>& majticks,vector<double>& minticks)
+// *** Calcul de l'intervalle entre les ticks et de la valeur du premier tick
+//     pour un axe lineaire
+{
+ if(nticks<=0) nticks = 1;
+
+ double d=xmax-xmin; if(d<1.e-100) d=1.e-100;
+ double ld  = log10(d);
+ double fld = floor( ((ld<0.)? -ld: ld) );
+ double del,del0;
+ fld = (ld>=0.)? fld-2.: -(fld+2.);
+ del0 = del = pow(10.,fld);
+ // *** Intervalle entre les ticks
+ // xmin  xmax    d       ld       fld -->fld  del0
+ // 1     1500    1499    3.17     3      1    10^1
+ // 1     9500    9499    3.98     3      1    10^1
+ // 1     1.005   0.005  -2.3      3     -5    10^-5
+ // 1     1.995   0.995  -0.0022   1     -3    10^-3
+ // - Et recherche de la valeur del={del0,2*del0,...,20*del0,...}
+ // telle que "nticks*del" soit le plus petit nombre ">=xmax-xmin"
+ double fac[9] = {2.,5.,10.,20.,50.,100.,200.,500.,1000.};
+ for(int k=0;k<9;k++) {
+   //cout<<"BestTicks: "<<k<<" del="<<del<<" d/del="<<d/del<<"<"<<nticks<<endl;
+   if(d/del < (double)nticks) break;
+   del=fac[k]*del0;
+ }
+ double steptick=del;
+ //***  Valeur du premier tick
+ majticks.resize(0);
+ double xfirsttick = floor(fabs(xmin)/steptick)*steptick;
+   if(xmin<0.) xfirsttick *= -1.;
+ if(xfirsttick<xmin) xfirsttick += steptick;
+ while(xfirsttick<=xmax+steptick/10.)
+   {majticks.push_back(xfirsttick); xfirsttick+= steptick;}
+ //***  Gestion des ticks mineurs
+ minticks.resize(0);
+ if(majticks.size()>1) {
+   double steptickmin = steptick/5.;
+   double xfirsttickmin = majticks[0];
+   while(xfirsttickmin<=xmax+steptickmin/10.)
+     {minticks.push_back(xfirsttickmin); xfirsttickmin+= steptickmin;}
+ }
+}
+/* --Methode-Static-- */
+void PIAxes::BestTicksLog(double xmin,double xmax,int nticks
+                      ,vector<double>& majticks,vector<double>& minticks)
+// *** Calcul des ticks pour un axe logarithmique
+{
+ if(nticks<=0) nticks = 1;
+ //cout<<"BestTicksLog: xmin="<<xmin<<" xmax="<<xmax<<" nticks="<<nticks<<endl;
+
+ // Si xmax<=0, on garde BestTicks
+ if(xmax<=0. ) {
+   //cout<<"Choix de BestTicks car xmax="<<xmax<<endl;
+   BestTicks(xmin,xmax,nticks,majticks,minticks);
+   return;
+ }
+
+ int dmin, dmax=int(floor(log10(xmax)));
+ if(xmin>0.) {
+   // Dynamique trop faible, on garde BestTicks
+   if(xmax/xmin<5.) {
+     //cout<<"Choix de BestTicks car xmax/xmin="<<xmax/xmin<<" <5"<<endl;
+     BestTicks(xmin,xmax,nticks,majticks,minticks);
+     return;
+   }
+   dmin=int(floor(log10(xmin)));
+ } else {
+   if(dmax>3) dmin = dmax/3;
+   else dmin = dmax-1;
+ }
+ if(dmax==dmin) dmax++; else if(dmax<dmin) dmax=dmin+1;
+ int inc = (dmax-dmin+1)/nticks; if(inc<1) inc=1;
+ //cout<<" dmin="<<dmin<<" dmax="<<dmax<<" inc="<<inc<<endl;
+
+ majticks.resize(0);
+ {for(int i=dmin;i<=dmax;i+=inc) {
+   double x = pow(10.,(double)i);
+   if(x<xmin || x>xmax) continue;
+   majticks.push_back(x);
+ }}
+ //cout<<"majticks.size()="<<majticks.size()<<endl;
+
+ // Pas de puissance de 10 dans l'intervalle on garde BestTicks
+ if(majticks.size()==0) {
+   BestTicks(xmin,xmax,nticks,majticks,minticks);
+   return;
+ }
+
+ // Pas suffisamment de ticks majeurs
+ if((int)majticks.size()<=nticks/2) {
+   int nins = nticks/(majticks.size()+1);
+   if(nins<=0) nins=1;
+   //cout<<"nins="<<nins<<endl;
+   // Sequence judicieuse pour remplir les ticks manquants
+   // nins = 1 on insere 3
+   //        2           2 5
+   //        3           2 4 6
+   //        4           1.5 2 4 6
+   //      >=5 on reste au cas precedent  
+   double seqmaj[4][4] = {{3.,0,0,0},{2.,5.,0,0},{2.,4.,6.,0},{1.5,2.,4.,6.}};
+   if(nins>4) nins=4;
+   vector<double> tmp;
+   {for(unsigned int i=0;i<=majticks.size();i++) {
+     double xt;
+     if(i<majticks.size()) xt = majticks[i]/10.;
+       else                xt = majticks[i-1];
+     for(int n=0;n<nins;n++) {
+       double xins = seqmaj[nins-1][n]*xt;
+       if(xins<xmin || xins>xmax) continue;
+       tmp.push_back(xins);
+     }
+     if(i<majticks.size()) tmp.push_back(majticks[i]);
+   }}
+   majticks = tmp;
+ }
+ //cout<<"...majticks.size()="<<majticks.size()<<endl;
+
+ // Les ticks mineurs
+ minticks.resize(0);
+ {for(unsigned int i=0;i<majticks.size()-1;i++) {
+   double dx = (majticks[i+1]-majticks[i])/10.;
+   minticks.push_back(majticks[i]);
+   for(int j=2;j<=8;j+=2)  {
+     double x = majticks[i] + j*dx;
+     if(x<xmin || x>xmax) continue;
+     minticks.push_back(x);
+   }
+ }}
+ minticks.push_back(majticks[majticks.size()-1]);
+ //cout<<"...minticks.size()="<<minticks.size()<<endl;
+
+ // Si on a xmin<=0., on insere zero dans les ticks majeurs
+ if(xmin<=0.) {
+   vector<double> tmp = majticks;
+   majticks.resize(0); majticks.push_back(0.);
+   for(unsigned int i=0;i<tmp.size();i++) majticks.push_back(tmp[i]);
+   //cout<<"...xmin="<<xmin<<"<=0. add majticks[0]="<<majticks[0]<<endl;
+ }
+
+}
+
+/* --Methode-Static-- */
+int PIAxes::BonFormatAxes(double xmin,double xmax,double xstep
+                         ,string& format,int typf,int add_digit)
+// *** Calcul format optimal pour ecrire les labels numeriques des axes:
+// ---- Input
+// . xmin,xmax : limites du plot sur l'axe considere.
+// . xstep : distance entre les ticks.
+// . add_digit : nombre de digits a ajouter au nombre de digits minimum.
+// . typf : type de format en sortie
+//        0 : format optimum %-nn.mme ou %-nn.mmf selon valeurs
+//        1 : format %-nn.mme
+//        2 : format %-nn.mmf pour imprimer x/10^npuiss
+//            tel que x/10^npuiss soit entre [0,10]
+//        3 : format %-nn.mmf
+// ---- Output
+// . format : le format d'impression
+// ---- Return:
+// Si typ=0 ou 1 ou 3
+//   "ndig" : nombre de digits necessaires pour distinguer
+//            les valeurs xmin+k*dx (<=xmax)
+// Si typ=2
+//   "npuiss" : tel que x/10^npuiss soit entre 0 et 10
+//              Dans ce cas le format est celui qui imprime x/10^npuiss
+{
+ format = "%-5g";  // format par default
+ if(xmin>=xmax) {if(typf==2) return 0; else return -1;}
+
+ if(xstep<=0. || xstep>xmax-xmin) xstep = xmax-xmin;
+
+ double axmin=fabs(xmin), axmax=fabs(xmax);
+ if(axmin>axmax) dble_SWAP(axmin,axmax);
+
+ double l10amax = log10(axmax), l10xstep = log10(xstep);
+ int il10amax = int(floor(l10amax));
+
+ // choix du type de format
+ char ftype = 'e';
+ int npuiss = 0;
+ if(typf==2) {
+   npuiss = il10amax-1;  // nombre entre [0,10]
+   //npuiss = il10amax;  // nombre entre [0,1]
+   if(npuiss<-300 || npuiss>300) {
+     ftype='e'; npuiss=0;
+   } else {
+     // On recalcule les valeurs de decision pour  axmax/10^npuiss, xstep/10^npuiss
+     l10amax -= (double)npuiss; l10xstep -=  (double)npuiss;
+     il10amax = int(floor(l10amax));
+     ftype = 'f';
+   }
+ } else if(typf==1) {
+   ftype='e';
+ } else if(typf==3) {
+   ftype='f';
+ } else {
+   ftype='e';
+   // On evite d'ecrire +a.bbbe+ccc -> format %f
+   // Ex: 1.2345e+2 -> 123.45   /  -1.2345e+2 -> -123.45
+   //     1.2345e-1 -> 0.12345  /  -1.2345e-1 -> -0.12345
+   if((axmin>=1e-4 || axmin==0.) && axmax<1e4) ftype='f';
+ }
+
+ //printf("BonFormatAxes[npuiss=%d]: xmin=%-21.14e xmax=%-21.14e\n",npuiss,xmin,xmax);
+ //printf("        xstep=%-21.14e log10(xstep/10^%d)=%g\n",xstep,npuiss,l10xstep);
+ //printf("        axmax=%-21.14e log10(axmax/10^%d)=%g diff=%g\n"
+ //      ,axmax,npuiss,l10amax,l10amax-l10xstep);
+
+ // Nombre de digits necessaires pour ecrire axmax et xstep
+ int ndig = il10amax  -  int(floor(l10xstep));
+ if(ndig<0) ndig *= -1;  ndig += 1;
+ //printf("ndig=%d",ndig);
+ 
+ // Add more digits (or suppress digits)
+ ndig += add_digit; if(ndig<0) ndig=0;
+ //printf(" + %d  ==> ndig=%d\n",add_digit,ndig);
+
+ // Calcul du bon format
+ char str[16];
+ if(ftype=='f') { // Calcul du format %-nn.mmf
+   int mm=-1, nn;
+   if(il10amax<0) { // +0.12345 +0.0012345 +0.0012345 ...
+     mm = ndig - il10amax - 1; nn = mm+3;
+   } else {         // +1.2345 +12.345 +123.45 ...
+     mm = ndig - il10amax - 1; nn = ndig+2;
+   }
+   //printf("format %%f : mm=%d  nn=%d\n",mm,nn);
+   if(mm<0.) mm=0; if(nn<mm+3) nn=mm+3;
+   sprintf(str,"%%-%d.%df",nn,mm);
+ } else if(ftype=='e') { // Calcul du format %-nn.mme
+   //   +d.<--ddd-->e+123
+   //   1 2         34567  ==> nn=ndig+7   mm=ndig-1
+   sprintf(str,"%%-%d.%de",ndig+7,ndig-1);
+ }
+
+ format = str;
+ //printf("format=[%s]\n",format.c_str());
+
+ if(typf==2) return npuiss;
+ return ndig;
+}
+
+/* --Methode-- */
+int PIAxes::Le_Bon_Format(vector<double>& xticks,string& format,double& xstep)
+// Methode static de decision du bon format
+// Decide quel format est le mieux adapte pour ecrire les labels des axes
+// Decide si une puissance de 10 doit etre deportee en bout d'axe
+// - Input:
+//   xticks : vecteur des ticks a ecrire (calcule par BestTicks)
+// - Output:
+//   format : format a utiliser
+//   xstep  : step entre 2 graduations
+// - Return:
+//   npuiss : si format choisit avec ecriture
+//            avec label des puissances de 10 deporte
+//   0      : sinon
+{
+ format="%g"; xstep=1.;
+ if(xticks.size()<=1) return 0;
+
+ // On decide du format
+ xstep=xticks[1]-xticks[0];
+ int npuiss = BonFormatAxes(xticks[0],xticks[xticks.size()-1],xstep,format,2,1);
+ if(npuiss>=-2 && npuiss<=2) {
+   npuiss = 0;
+   BonFormatAxes(xticks[0],xticks[xticks.size()-1],xstep,format,3,1);
+ }
+
+ return npuiss;
+}
+
+void PIAxes::Arrange_Label(char *label)
+// --- Mise en forme optimale du label numerique
+// Enleve les blancs, les zeros, le point et les e00
+//        inutiles a la fin d'un label
+{
+ size_t lenl=strlen(label);
+ if(lenl==0) return;
+
+ // --- On enleve les blancs et plus au debut du label
+ if(label[0]==' ' || label[0]=='+') {
+   char *str=new char[lenl+2];
+   strcpy(str,label);
+   unsigned i=0;
+   for(i=0;i<lenl;i++) if(str[i]!=' ' && str[i]!='+') break;
+   strcpy(label,&str[i]);
+   delete [] str;
+   lenl=strlen(label);
+   if(lenl==0) return;
+ }
+
+ // --- On enleve les blancs a la fin du label
+ if(label[lenl-1]==' ') {
+   for(int i=lenl-1;i>=0;i--) {
+     if(label[i]!=' ') break;
+     label[i]='\0';
+   }
+   lenl=strlen(label);
+ }
+
+ // --- On enleve les e... E... non-significatifs
+ // ex: a.be-zzz  a.be+zzz  a.bezzz avec zzz=0,00,000,...
+ // Attention on n'enleve pas si: a.be+10
+ // Attention on ne fait rien si: e+10
+ char* e=index(label,'e');
+ if(e==NULL) e=index(label,'E');
+ if(e) {
+   for(int i=lenl-1;i>=0;i--) {
+     if(isdigit(label[i]) && label[i]!='0') break;
+     if(label[i]=='e' || label[i]=='E')
+       {label[i]='\0'; lenl=strlen(label); break;}
+   }
+ }
+
+ // --- On enleve les zeros non-significatifs a la fin du label
+ // On enleve des zeros ou le point si: ab. ab.czzz avec zzz=0,00,000,...
+ // Attention on n'enleve pas de zeros si: abzzz
+ // Attention a ne pas enlever des zeros si on a ab.ccce+a0
+ // Attention on traite 0eaaa -> 0
+ if(index(label,'.')==NULL) return;  // Recherche d'un point
+ string stre;
+ if(e) {if(e==label) return; stre=e; *e='\0'; lenl=strlen(label);}
+ {for(int i=lenl-1;i>=0;i--) {
+   if(label[i]=='0') label[i]='\0';
+   else if(label[i]=='.') {
+     if(i>0) label[i]='\0';
+     else {
+       // Attention: ".e+10" -> "1e+10" MAIS "." -> "0"
+       if(e) strcpy(label,"1"); else strcpy(label,"0");
+     }
+     break;
+   }
+   else break;  // Ni un point ni un zero
+ }}
+ if(e) {
+   if(strlen(label)==1) if(label[0]=='0') return;
+   strcat(label,stre.c_str());
+ }
+
+}
Index: /tags/V_Dec2002/SophyaPI/PI/piaxes.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piaxes.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piaxes.h	(revision 2309)
@@ -0,0 +1,91 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Methodes de trace d'axes - 
+//                             R. Ansari  2002
+// (C) LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PIAXES_H
+#define PIAXES_H
+
+#include "pigraphuc.h"
+#include "pigratt.h"
+#include <vector>
+
+enum {
+  kStdAxes     = 0x0001,
+  kBoxAxes     = 0x0002,
+  kTicks       = 0x0004,
+  kIntTicks    = 0x0010,
+  kExtTicks    = 0x0020,
+  kMajTicks    = 0x0040,
+  kMinTicks    = 0x0080,
+  kLabels      = 0x1000,
+  kGridOn      = 0x2000,
+  kAxesDflt    = kStdAxes | kTicks | kLabels,       // Axes trace par defaut
+  kAxesNone    = 0                                  // Pas de trace d axe  
+};
+
+
+class PIAxes {
+public:
+
+                    PIAxes();
+  virtual           ~PIAxes();
+
+  virtual void      DrawXYAxes(PIGraphicUC* g, PIGraphicAtt& gratt, 
+			       unsigned int flags, bool afsz);
+
+  virtual void      DrawXYAxes(PIGraphicUC* g, PIGraphicAtt& gratt, 
+			       unsigned int flags, bool afsz, 
+			       double xmin, double xmax, 
+			       double ymin, double ymax);
+
+
+  virtual void      DrawXCaption(PIGraphicUC* g, PIGraphicAtt& att, unsigned int flags,
+				 string const& xLabel); 
+  virtual void      DrawYCaption(PIGraphicUC* g, PIGraphicAtt& att, unsigned int flags,
+				 string const& YLabel); 
+
+  //  virtual void      DrawHorizontalAxe(double xmin, double xmax, double y, 
+
+  //  Calcul du min et du max du display a partir des valeurs min et max a plotter
+  static void ReSizeMinMax(bool axelog,double& vmin,double& vmax,double garde=0.025);
+  //  Calcul des Distances optimales des subdivisions (STATIC)
+  static void BestTicks(double xmin,double xmax,int nticks
+		       ,vector<double>& majticks,vector<double>& minticks);
+  static void BestTicksLog(double xmin,double xmax,int nticks
+			  ,vector<double>& majticks,vector<double>& minticks);
+  //  Calcul du format optimal (STATIC)
+  static int BonFormatAxes(double xmin,double xmax,double xstep
+			  ,string& format,int typf=0,int add_digit=0);
+  //  Decision du format optimal pour les axes (STATIC)
+  static int Le_Bon_Format(vector<double>& xticks,string& format,double& xstep);
+  //  Mise en forme optimale du label numerique (STATIC)
+  static void Arrange_Label(char *label);
+
+protected:
+  void Setup(PIGraphicUC* g,double xmin,double xmax,double ymin,double ymax);
+
+  void DrawHTicks(PIGraphicUC* g, double y, double tickUp, double tickDown, vector<double>& xticks);
+  void DrawVTicks(PIGraphicUC* g, double x, double tickLeft, double tickRight, vector<double>& yticks);
+  void DrawHLabels(PIGraphicUC* g, double y, vector<double>& xticks, unsigned long just=0);
+  void DrawVLabels(PIGraphicUC* g, double x, vector<double>& yticks, unsigned long just=0);
+  void DrawGrid(PIGraphicUC* g);
+
+
+  bool   setupDone;  // Si Setup a ete appele
+
+  double xMin, xMax, yMin, yMax; 
+  bool   aXdir, aYdir;           // Sens des axes horiz, vertical 
+  bool   aXlog, aYlog;           // Echelle log pour les axes horiz, vertical 
+  bool   axesAFSz;
+  
+  vector<double> xMajTicks;
+  vector<double> xMinTicks;
+  vector<double> yMajTicks;
+  vector<double> yMinTicks;
+  double xMajTickLen,  xMinTickLen;
+  double yMajTickLen,  yMinTickLen;
+
+};
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/piaxestools.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piaxestools.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piaxestools.cc	(revision 2309)
@@ -0,0 +1,383 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Outils de manipulation des axes des PIScDrawWdg
+//                                   R. Ansari 07/2001
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include <stdlib.h>
+#include <iostream.h>
+
+#include "piaxes.h"
+#include "piaxestools.h"
+
+//++
+// Class	PIAxesTools
+// Lib		PI
+// include	piaxestools.h
+//
+//	Classe de fenêtre de dialogue permettant de modifier interactivement
+//	Permet aussi de modifier les attributs d'axes pour les "PIScDrawWdg"
+//--
+// Links	Parents
+// PIWindow
+//--
+//++
+// Links	Voir aussi
+// PIScDrawWdg
+//--
+
+//++
+// Titre	Méthodes statiques
+//--
+//++
+// void  ShowPIAxesTools() 	
+//	Méthode statique permettant l'affichage de la fenêtre de contrôle des
+//	attributs graphiques des "Drawer". L'instance de la classe
+//	 "PIAxesTools" est créée si nécessaire.
+// void  HidePIAxesTools() 
+//	Désacative (cache) la fenêtre "PIAxesTools" (méthode statique).
+// void  SetCurrentBaseWdg(PIBaseWdgGen* cbw)
+//	Méthode statique permettant de sélectionner le "PIBaseWdg" courant.
+// PIBaseWdgGen*  GetCurrentBaseWdg()
+//	Retourne le "PIBaseWdg" courant (méthode statique).
+//--
+
+
+PIAxesTools* PIAxesTools::cwaxet = NULL;
+PIScDrawWdg* PIAxesTools::curscdwdg = NULL;
+
+/* --Methode-- */
+void PIAxesTools::ShowPIAxesTools() 
+{
+if (cwaxet == NULL)  cwaxet = new PIAxesTools(PIApplicationGetApp());
+cwaxet->Show();
+}
+
+/* --Methode-- */
+void PIAxesTools::HidePIAxesTools() 
+{
+if (cwaxet == NULL)  return; 
+cwaxet->Hide();
+}
+
+/* --Methode-- */
+void PIAxesTools::SetCurrentScDrawWdg(PIScDrawWdg* csw)
+{
+if (curscdwdg == csw) return;
+curscdwdg = csw;
+}
+
+/* --Methode-- */
+PIScDrawWdg* PIAxesTools::GetCurrentScDrawWdg()
+{
+return(curscdwdg);
+}
+
+/* --Methode-- */
+PIAxesTools::PIAxesTools(PIApplication* par)
+: PIWindow((PIMsgHandler*)par, "PIAxesTools", PIWK_normal, 240, 240, 150, 150)
+, mTypAction(0), mSclAction(0.)
+{
+int bsx, bsy, spx, spy;
+int bsycb, spycb;
+
+// On definit la taille a partir de la taille par defaut des composantes 
+// PIApplicationPrefCompSize(bsx, bsy);
+par->PrefCompSize(bsx, bsy);  // environ 6 lettres
+spx = bsx/10;
+spy = bsy/4;
+
+bsycb = 0.80*bsy+0.5;  // Taille des checkbox
+spycb = 0.80*spy+0.5;  // Espace-Y inter checkbox
+
+int wszx = 6*spx+3.5*bsx; 
+int wszy = 5*bsy+9*spy+4*bsycb+3*spycb;
+SetSize(wszx, wszy);
+
+int cpx = spx;
+int cpy = spy*2;
+mLab[0] = new PILabel(this, "X Min Max", 1.25*bsx, bsy, cpx, cpy);
+cpy += spy+bsy; 
+mLab[1] = new PILabel(this, "Y Min Max", 1.25*bsx, bsy, cpx, cpy);
+mLab[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+mLab[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+cpy = spy*2;
+cpx += spx+1.25*bsx; 
+mText[0] = new PIText(this, "x_min_max", 2.25*bsx+2*spx, bsy, cpx, cpy);
+mText[0]->SetText("-1.0  1.0");
+cpy += spy+bsy; 
+mText[1] = new PIText(this, "y_min_max", 2.25*bsx+2*spx, bsy, cpx, cpy);
+mText[1]->SetText("-1.0  1.0");
+mText[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+mText[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+cpy += spy+bsy; 
+cpx = spx+0.25*bsx;
+mCkb[3] = new PICheckBox(this,"LogScale-X", 2003, bsx*1.5, bsycb, cpx, cpy);
+cpx += bsx*1.5+3*spx;
+mCkb[4] = new PICheckBox(this,"LogScale-Y", 2004, bsx*1.5, bsycb, cpx, cpy);
+mCkb[3]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+mCkb[4]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+cpx = spx+0.25*bsx;
+cpy += spycb+bsycb;
+mCkb[0] = new PICheckBox(this,"X-RightLeft", 2000, bsx*1.5, bsycb, cpx, cpy);
+cpx += bsx*1.5+3*spx;
+mCkb[1] = new PICheckBox(this,"Y-UpDn", 2001, bsx*1.5, bsycb, cpx, cpy);
+mCkb[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+mCkb[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+cpx = spx+0.25*bsx;
+cpy += spycb+bsycb;
+mCkb[5] = new PICheckBox(this,"Centerd-Axes", 2005, bsx*1.5, bsycb, cpx, cpy);
+cpx += bsx*1.5+3*spx;
+mCkb[2] = new PICheckBox(this,"Grid", 2002, bsx*1.5, bsycb, cpx, cpy);
+mCkb[5]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+mCkb[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+cpx = spx+0.25*bsx;
+cpy += spycb+bsycb;
+mCkb[6] = new PICheckBox(this,"Minor-Ticks", 2006, bsx*1.5, bsycb, cpx, cpy);
+cpx += 3*spx+1.5*bsx; 
+mCkb[7] = new PICheckBox(this,"AutoFontSize", 2007, bsx*1.5, bsycb, cpx, cpy);
+mCkb[6]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+mCkb[7]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+
+cpy += spy+bsy; 
+cpx = spx+0.25*bsx;
+mBut[0] = new PIButton(this, "GetAxesInfo", 2100, bsx*1.5, bsy, cpx, cpy);
+cpx += bsx*1.5+4*spx;
+mBut[1] = new PIButton(this, "AutoLimits", 2200, bsx*1.5, bsy, cpx, cpy);
+mBut[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+mBut[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+cpy += spy+bsy; 
+cpx = spx+0.25*bsx;
+mBut[2] = new PIButton(this, "SetAxes", 2500, bsx*1.5, bsy, cpx, cpy);
+cpx += bsx*1.5+4*spx;
+mBut[3] = new PIButton(this, "Dismiss", 2777, bsx*1.5, bsy, cpx, cpy);
+mBut[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+mBut[3]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+  cpy += spy+bsy; 
+  cpx = spx;
+mBut[4] = new PIButton(this,"<<",2801,0.5*bsx,bsy,cpx,cpy);
+mBut[4]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+ cpx += spx+0.5*bsx;
+mBut[5] = new PIButton(this,"<",2802,0.5*bsx,bsy,cpx,cpy);
+mBut[5]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+ cpx += spx+0.5*bsx;
+mOpt = new PIOptMenu(this,"choix-action",1.5*bsx,bsy,cpx,cpy);
+mOpt->AppendItem("Transl X",2850);  // mTypAction=0
+mOpt->AppendItem("Transl Y",2851);  // mTypAction=1
+mOpt->AppendItem("Zoom X",2852);    // mTypAction=2
+mOpt->AppendItem("Zoom Y",2853);    // mTypAction=3
+mOpt->AppendItem("Zoom X-Y",2854);  // mTypAction=4
+mOpt->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+ string sdum="Transl X"; mOpt->SetValueStr(sdum); mTypAction=0;
+ cpx += spx+1.5*bsx;
+mBut[6] = new PIButton(this,">",2803,0.5*bsx,bsy,cpx,cpy);
+mBut[6]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+ cpx += spx+0.5*bsx;
+mBut[7] = new PIButton(this,">>",2804,0.5*bsx,bsy,cpx,cpy);
+mBut[7]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+cwaxet = this;
+}
+
+/* --Methode-- */
+PIAxesTools::~PIAxesTools()
+{
+if (cwaxet == this)  cwaxet = NULL;
+int i;
+for(i=0;i<2;i++) delete mLab[i];
+for(i=0;i<2;i++) delete mText[i];
+for(i=0;i<8;i++) delete mBut[i];
+for(i=0;i<8;i++) delete mCkb[i];
+delete mOpt;
+}
+
+/* --Methode-- */
+void PIAxesTools::Show()
+{
+PIWindow::Show();
+UpdateAxesInfoFromScWdg();
+return;
+}
+
+/* --Methode-- */
+void PIAxesTools::UpdateAxesInfoFromScWdg()
+{
+char buff[128];
+if (curscdwdg != NULL) {
+  string format,dum;
+  PIScDrawWdg* scd = curscdwdg;
+    PIAxes::BonFormatAxes(scd->XMin(),scd->XMax(),-1.,format,0,2);
+    dum = format; dum += "  "; dum += format;
+  sprintf(buff,dum.c_str(),scd->XMin(),scd->XMax());
+  mText[0]->SetText(buff);
+    PIAxes::BonFormatAxes(scd->YMin(),scd->YMax(),-1.,format,0,2);
+    dum = format; dum += "  "; dum += format;
+  sprintf(buff,dum.c_str(),scd->YMin(),scd->YMax());
+  mText[1]->SetText(buff);
+  int xa, ya;
+  scd->GetAxesConfig(xa, ya);
+  if (xa & kAxeDirRtoL) mCkb[0]->SetState(true);
+  else mCkb[0]->SetState(false);
+  if (ya & kAxeDirUpDown)  mCkb[1]->SetState(true);
+  else mCkb[1]->SetState(false);
+  if (scd->GetAxesFlags() & kGridOn) mCkb[2]->SetState(true);
+  else mCkb[2]->SetState(false);
+  if (scd->GetAxesFlags() & kStdAxes) mCkb[5]->SetState(true);
+  else mCkb[5]->SetState(false);
+  if (scd->GetAxesFlags() & kMinTicks) mCkb[6]->SetState(true);
+  else mCkb[6]->SetState(false);
+  mCkb[3]->SetState(scd->isLogScaleX());
+  mCkb[4]->SetState(scd->isLogScaleY());
+  mCkb[7]->SetState(scd->BaseDrawer()->isAxesAutoFontSize());
+  }
+else {
+  mText[0]->SetText("-1.0  1.0");
+  mText[1]->SetText("-1.0  1.0");
+  mCkb[0]->SetState(false);
+  mCkb[1]->SetState(false);
+  mCkb[2]->SetState(false);
+  mCkb[3]->SetState(false);
+  mCkb[4]->SetState(false);
+  mCkb[5]->SetState(false);
+  mCkb[6]->SetState(false);
+  mCkb[7]->SetState(true);
+  }
+
+return;
+}
+
+void PIAxesTools::SetAxes(bool refr)
+{
+  PIScDrawWdg* scd = curscdwdg;
+  if ( scd == NULL )  return;
+
+  double xmin, xmax, ymin, ymax;
+  if(mText[0]->GetText().length()>1 && mSclAction==0.) {
+    xmin = -1.;   xmax = 1.;
+    sscanf(mText[0]->GetText().c_str(), "%lg %lg" , &xmin, &xmax);
+  } else {
+    xmin = scd->XMin();
+    xmax = scd->XMax();
+  }
+  if(mText[1]->GetText().length()>1 && mSclAction==0.) {
+    ymin = -1.;   ymax = 1.;
+    sscanf(mText[1]->GetText().c_str(), "%lg %lg" , &ymin, &ymax);
+  } else {
+    ymin = scd->YMin();
+    ymax = scd->YMax();
+  }
+
+  if(mSclAction!=0.) {
+    double d;
+    if(mTypAction==0) { // Translation X
+      d = mSclAction*(xmax-xmin); xmin += d; xmax += d;
+    } else if(mTypAction==1) { // Translation Y
+      d = mSclAction*(ymax-ymin); ymin += d; ymax += d;
+    } else { // Zoom X, Y ou X-Y
+      double c, s=(mSclAction>0.)? 1./(1.+mSclAction): (1.-mSclAction);
+      if((mTypAction==2 || mTypAction==4) && xmax-xmin>0.) {
+        c = (xmin+xmax)/2.; d = s*(xmax-xmin)/2.;
+        xmin = c - d; xmax = c + d;
+      }
+      if((mTypAction==3 || mTypAction==4) && ymax-ymin>0.) {
+        c = (ymin+ymax)/2.; d = s*(ymax-ymin)/2.;
+        ymin = c - d; ymax = c + d;
+      }
+    }
+  }
+
+  int axrl = kAxeDirLtoR;
+  int ayud = kAxeDirDownUp;
+  if (mCkb[0]->GetState())  axrl = kAxeDirRtoL ;
+  if (mCkb[1]->GetState())  ayud = kAxeDirUpDown;
+  scd->SetLimits(xmin, xmax, ymin, ymax, axrl, ayud);
+  unsigned int flags = scd->GetAxesFlags();
+
+  if (mCkb[2]->GetState()) flags |= kGridOn;
+  else  flags &= ~kGridOn;
+  if (mCkb[5]->GetState()) { flags |= kStdAxes;  flags &= ~kBoxAxes; }
+  else { flags &= ~kStdAxes;  flags |= kBoxAxes; }
+  if (mCkb[6]->GetState()) flags |= kMinTicks;
+  else  flags &= ~kMinTicks;
+
+  scd->SetAxesFlags(flags);
+
+  scd->SetLogScale(mCkb[3]->GetState(), mCkb[4]->GetState() );
+  scd->BaseDrawer()->SetAxesAutoFontSize(mCkb[7]->GetState() );
+  if (refr) scd->Refresh();
+  return;
+}
+
+/* --Methode-- */
+void PIAxesTools::Process(PIMessage msg, PIMsgHandler* /*sender*/, void* /*data*/)
+{
+// Petit deplacement (zoom) ">"  ou "<"  de 20%
+// Grand deplacement (zoom) ">>" ou "<<" de 50%
+// *** ATTENTION: Valeurs OBLIGATOIREMENT ]0,1[ bornes exclues ***
+double smallstep=0.2, bigstep=0.5;
+
+msg = UserMsg(msg);
+mSclAction = 0.;
+
+switch (msg) {
+
+  case 2100 :
+    UpdateAxesInfoFromScWdg();
+    break;
+  case 2200 :
+    if ( curscdwdg != NULL ) { 
+      curscdwdg->UpdateLimits();
+      UpdateAxesInfoFromScWdg();
+    }
+    break;
+  case 2500 :
+    SetAxes(true);
+    break;
+
+  case 2777 :
+    Hide();
+    break;
+
+  case 2801 :  // <
+    mSclAction = -bigstep;
+    SetAxes(true);
+    break;
+  case 2802 :  // <<
+    mSclAction = -smallstep;
+    SetAxes(true);
+    break;
+  case 2803 :  // >
+    mSclAction = smallstep;
+    SetAxes(true);
+    break;
+  case 2804 :  // >>
+    mSclAction = bigstep;
+    SetAxes(true);
+    break;
+
+  case 2850 :
+  case 2851 :
+  case 2852 :
+  case 2853 :
+  case 2854 :
+    mTypAction = msg - 2850;
+    break;
+
+  default :
+    break;
+  }
+
+return;
+}
+
+
+
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/piaxestools.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piaxestools.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piaxestools.h	(revision 2309)
@@ -0,0 +1,51 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Outils de manipulation des PIDrawer  R. Ansari 06/98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PIAXESTOOLS_H_SEEN
+#define PIAXESTOOLS_H_SEEN
+
+#include "pisysdep.h"
+#include PISTDWDG_H
+#include PIOPTMENU_H
+#include PIWIN_H
+#include PIAPP_H
+#include "piscdrawwdg.h"
+
+// ---------- fenetre de dialogue pour modifs limites et attributs d'axe ----------
+// --------------------------------------------------------------------------------
+
+
+class PIAxesTools : public PIWindow 
+{
+public :
+  PIAxesTools(PIApplication* par);
+  ~PIAxesTools();
+  virtual void  Show();
+
+  static PIAxesTools* curlutw;
+  static void ShowPIAxesTools();
+  static void HidePIAxesTools();
+  static void SetCurrentScDrawWdg(PIScDrawWdg* csw);
+  static PIScDrawWdg* GetCurrentScDrawWdg();
+
+protected:
+  virtual void  UpdateAxesInfoFromScWdg();
+  virtual void  SetAxes(bool refr);
+  virtual void  Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+
+private:
+// Pour changer les axes
+  PILabel* mLab[2];
+  PIButton* mBut[8];
+  PIText* mText[2];
+  PICheckBox* mCkb[8];
+  PIOptMenu * mOpt;
+  unsigned short mTypAction;
+  double mSclAction;
+
+  static PIScDrawWdg* curscdwdg;
+  static PIAxesTools* cwaxet;
+};
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pibwdggen.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pibwdggen.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pibwdggen.cc	(revision 2309)
@@ -0,0 +1,679 @@
+// Module PI : Peida Interactive     PIBaseWdg
+// Classe de base pour nouvelles composantes graphiques  96
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include <stdio.h>
+
+#include "pibwdggen.h"
+#include "pidrawer.h"
+#include "pigraphps.h"
+#include "pidrwtools.h"
+
+static inline void dbl_swap(double& a, double& b) { double tmp = a; a = b; b = tmp;  } 
+
+//++
+// Class	PIBaseWdg
+// Lib		PI
+// include	pibwdggen.h
+//
+//   	Classe de base pour la création de nouvelles composantes graphiques.
+//	Le traitement des événements liés à l'écran, clavier, souris se fait
+//	à travers des méthodes de cette classe : "Resize()", "But1Press()", ...
+//	La classe "PIBaseWdg" supporte en outre un mécanisme permettant
+//	d'associer un ou plusieurs objets traceur (*Drawer*) capables 
+//	de se dessiner dans la fenêtre associée à l'objet.
+//	La classe "PIBaseWdgGen" définit l'interface et ne peut pas être instanciée 
+//	directement (Méthodes virtuelles pures). Les objets instanciés sont de la 
+//	classe "PIBaseWdg" et le fichier entête correspondant est "PIBWDG_H"
+//	défini dans "pisysdep.h".
+//--
+//++
+// Links	Parents
+// PIWdg
+//--
+//++
+// Links	Voir aussi
+// PIGraphic
+// PIDrawer
+//--
+
+// ---------- Les methodes de la classe  PIBWdgGen ------------
+
+//++
+// Titre	Constructeur
+//--
+//++
+//  PIBaseWdgGen(PIContainerGen *par, const char *nom, int sx=10, int sy=10, int px=0, int py=0)
+//	Création d'un objet contenu dans l'objet *PIContainer* "par", de
+//	taille "sx,sy", se trouvant à la position "px,py" avec le nom "nom"	
+//--
+
+//++
+// Titre	Méthodes
+//--
+//++
+// void  SelPointerShape(PIPointer ptr=PI_ArrowPointer) 
+//	Choix de la forme du pointeur (souris) pour la fenêtre 
+//	associée à l'objet.
+//|	PI_ArrowPointer, PI_CrossPointer, PI_HandPointer, PI_TDLRArrowPointer
+// PIPointer  GetPointerShape() 
+//	Renvoie la forme du pointeur
+//--
+
+//++
+// Titre	Activation du traitement des événements
+//--
+//++
+// void  ActivatePtrCross()
+//	Active l'appel aux méthodes "Enter()" et "Leave()" lorsque la souris
+//	rentre ou sort de la fenêtre correspondante à l'objet
+// void  ActivateButton(int b)
+//	Active l'appel aux méthodes "ButbPress()" et "ButxRelease()" pour
+//	le bouton "b" de la souris ("b=1,2,3")
+// void  ActivateMove(int b) 
+//	Active l'appel aux méthodes "PtrbMove()" lors des mouvements de
+//	la souris avec le bouton "b" enfoncé ("b=1,2,3")
+//	L'appel avec "bid=0" active l'appel à la méthode "PtrMove()"
+//	Lors des mouvements de souris sans bouton enfoncé.
+// void  ActivateKeyboard()
+//	Active l'appel à la méthode "Keyboard()" lors de l'appui sur les 
+//	touches du clavier.
+//--
+
+ 
+/* --Methode-- */
+PIBaseWdgGen::PIBaseWdgGen(PIContainerGen *par, const char *nom,
+                       int sx, int sy, int px, int py) :
+PIWdg(par, nom, sx, sy, px, py)
+{
+mDrwId=0;   // Compteur des numeros sequentiel des PIDrawer
+mActDrwId = -1;  // Identificateur du drawer actif
+mAdfg=false;    // Pour controle d'appel de RemoveDrawer()
+mWGrC = NULL;   // PIGraphic (Contexte graphique) associe a la fenetre}
+                // Doit etre cree par PIBaseWdgX/Mac/... 
+SetDefaultDrawRectangle(0., 0., 1., 1., true);
+SetDefaultDrawerLimits(0., 1., 0., 1., kAxeDirLtoR, kAxeDirUpDown);
+SetDefaultDrawerLogScale(false, false);
+}
+
+/* --Methode-- */
+PIBaseWdgGen::~PIBaseWdgGen()
+{
+delete mWGrC;
+DeleteDrawers();
+if (PIDrwTools::GetCurrentBaseWdg() == this) 
+  PIDrwTools::SetCurrentBaseWdg(NULL);
+}
+ 
+
+/* --Methode-- 
+void PIBaseWdgGen::Refresh()
+{
+if ( IsVisible() )  { 
+  Draw(mWGrC, 0, 0, XSize(), YSize());
+  CallDrawers(mWGrC); 
+}
+return;
+}
+*/
+
+//++
+// Titre	Gestion des événements
+//--
+//++
+// void  Draw(PIGraphic* g, int x0, int y0, int dx, int dy)
+//	Méthode appelée lorsqu'il faut redessiner tout ou partie de
+//	la fenêtre. La zone a rafraîchir est determinée par 
+//	"(x0,y0)", "dx,dy" et "g" est l'objet "PIGraphic" 
+//	qui doit être utilisé.
+//	Cette méthode ne doit pas être appelé directement. 
+//	Pour rafraîchir le contenu de la fenêtre, il faut appeler
+//	la méthode "Refresh()"
+// void  Resize()
+//	Méthode appelée lorsque la taille de l'objet est modifiée.
+//	"XSize()", "YSize()" fournissent la nouvelle taille de l'objet.
+// void  Enter()
+//	Méthode appelée lorsque le pointeur rentre dans la fenêtre
+//	(Si "ActivatePtrCross()" a été appelé )
+// void  Leave()
+//	Méthode appelée lorsque le pointeur quitte la fenêtre
+//	(Si "ActivatePtrCross()" a été appelé )
+// void  ButbPress(int x, int y)  (b=1,2,3)
+//	Méthode appelée lorsque le bouton "b=1,2,3" de la souris est enfoncé.
+//	"x,y" : Position de la souris
+//	(Si "ActivateButton(b)" a été appelé )
+// void  ButbRelease(int x, int y)   (b=1,2,3)
+//	Méthode appelée lorsque le bouton "b=1,2,3" de la souris est relaché.
+//	"x,y" : Position de la souris
+//	(Si "ActivateButton(b)" a été appelé )
+// void  PtrMove(int x, int y)
+//	Méthode appelée lors des mouvements de la souris. "x,y" : Position de la souris
+//	(Si "ActivateMove(0)" a été appelé )
+// void  PtrbMove(int x, int y)     (b=1,2,3)
+//	Méthode appelée lors des mouvements de la souris, avec le 
+//	bouton "b=1,2,3" appuyé. "x,y" : Position de la souris
+//	(Si "ActivateMove(b)" a été appelé )
+// void  Keyboard(int key, PIKeyModifier kmod)
+//	Méthode appelée en réponse à des actions sur le clavier.
+//	"key" est le code ASCII de la touche enfoncé - "kmod" indique
+//	si des touches speciaux étaient enfoncés en même temps.
+//|	kmod =  PIKM_Blank |  PIKM_Shift | PIKM_Alt | PIKM_Cntl
+//	Des constantes ont été définis pour certaines touches particulières
+//|	PIK_Return , PIK_Enter , PIK_BackSpace, PIK_Delete
+//|	PIK_Tab , PIK_Escape , PIK_Up , PIK_Down, 
+//|	PIK_Right , PIK_Left , PIK_Previous , PIK_Next
+//--
+
+/* --Methode-- */
+void PIBaseWdgGen::Draw(PIGraphic* g, int x0, int y0, int dx, int dy)
+{
+#ifdef DEBUG_RZXB
+puts("Debug_PIBaseWdgGen::Draw() Efface la fenetre par defaut ! ");
+#endif
+if (g->kind() != PI_PSFileGraphics) EraseWindow(x0, y0, dx, dy);
+return;
+}
+
+/* --Methode-- */
+void PIBaseWdgGen::Resize()
+{
+#ifdef DEBUG_RZXB
+puts("Debug_PIBaseWdgGen::Resize()  resize notify ");
+#endif
+return;
+}
+
+
+/* --Methode-- */
+void PIBaseWdgGen::Enter()
+{
+#ifdef DEBUG_RZXB
+puts("Debug_PIBaseWdgGen::Enter() enter notify ");
+#endif
+return;
+}
+
+/* --Methode-- */
+void PIBaseWdgGen::Leave()
+{
+#ifdef DEBUG_RZXB
+puts("Debug_PIBaseWdgGen::Leave() leave notify ");
+#endif
+return;
+}
+
+
+/* --Methode-- */
+void PIBaseWdgGen::But1Press(int /*x*/, int /*y*/)
+{
+Send(Msg(), PIMsg_Active);
+#ifdef DEBUG_RZXB
+printf ("PIBaseWdgGen::But1Press PosX,Y= %d %d \n", x, y);
+#endif
+return;
+}
+
+/* --Methode-- */
+void PIBaseWdgGen::But1Release(int /*x*/, int /*y*/)
+{
+#ifdef DEBUG_RZXB
+printf ("PIBaseWdgGen::ButReleasePosX,Y= %d %d \n", x, y);
+#endif
+return;
+}
+
+/* --Methode-- */
+void PIBaseWdgGen::But2Press(int /*x*/, int /*y*/)
+{
+return;
+}
+
+/* --Methode-- */
+void PIBaseWdgGen::But2Release(int /*x*/, int /*y*/)
+{
+return;
+}
+
+/* --Methode-- */
+void PIBaseWdgGen::But3Press(int /*x*/, int /*y*/)
+{
+return;
+}
+
+/* --Methode-- */
+void PIBaseWdgGen::But3Release(int /*x*/, int /*y*/)
+{
+return;
+}
+
+/* --Methode-- */
+void PIBaseWdgGen::PtrMove(int /*x*/, int /*y*/)
+{
+#ifdef DEBUG_RZXB
+printf ("Debug_PIBaseWdgGen::PtrMove PosX,Y= %d %d \n", x, y);
+#endif
+return;
+}
+
+/* --Methode-- */
+void PIBaseWdgGen::Ptr1Move(int /*x*/, int /*y*/)
+{
+#ifdef DEBUG_RZXB
+printf ("Debug_PIBaseWdgGen::Ptr1Move PosX,Y= %d %d \n", x, y);
+#endif
+return;
+}
+
+/* --Methode-- */
+void PIBaseWdgGen::Ptr2Move(int /*x*/, int /*y*/)
+{
+return;
+}
+
+
+/* --Methode-- */
+void PIBaseWdgGen::Ptr3Move(int /*x*/, int /*y*/)
+{
+return;
+}
+
+/* --Methode-- */
+void PIBaseWdgGen::Keyboard(int /*key*/, PIKeyModifier /*kmod*/)
+{
+#ifdef DEBUG_RZXB
+printf("PIBaseWdgGen::Keyboard: Key= %d (%c)  Mod= %d \n", key, (char)key, (int)kmod); 
+#endif
+return;
+}
+
+
+/* --Methode-- */
+void PIBaseWdgGen::PSPrint(PSFile * psf, int ofx, int ofy, double scale_x, double scale_y)
+{
+if (!psf) return;
+PIGraphicPS grpsf(psf, (PIWdg *)this, ofx, ofy, scale_x, scale_y);
+Draw(&grpsf, 0, 0, XSize(), YSize());
+CallDrawers(&grpsf); 
+return;
+}
+
+//++
+// Titre	Gestion des traceurs (PIDrawer)
+//	Un même "PIDrawer" peut être attaché simultanement à plusieurs "PIBaseWdg", ainsi
+//	que plusieurs fois au même "PIBaseWdg", avec des identificateurs différents.
+//	Un des traceurs, par défaur le dernier ajouté est considéré comme le traceur 
+//	actif ou sélectionné (voir "SetActiveDrawer" ...).
+//--
+//++
+// void  SetDefaultDrawRectangle(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2, bool psz=true)
+//	Définition du rectangle d'attachement par défaut. "(x1,y1)" et "(x2,y2)" determinent
+//	les positions des deux coins opposés.
+//	si "psz=true", les coordonnées sont supposées être des facteurs multiplicatifs 
+//	des dimensions de l'objet.
+// void  SetDefaultDrawerLimits(double xmin, double xmax, double ymin, double ymax, -
+//                              int axrl=kAxeDirSame, int ayud=kAxeDirSame)
+//	Définition du système de coordonnées par défaut d'un drawer attaché 
+//	en "autolim=true"
+// void  SetDefaultDrawerLogScale(bool logx, bool logy)
+//	Définition d'échelle logarithmique pour le système de coordonnées par défaut
+//	d'un drawer attaché en "autolim=true".
+//
+//--
+
+/* --Methode-- */
+void PIBaseWdgGen::SetDefaultDrawRectangle(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2, bool psz)
+{
+mDrX1 = x1;  mDrY1 = y1;
+mDrX2 = x2;  mDrY2 = y2;   mDrElastic = psz;
+}
+
+/* --Methode-- */
+void PIBaseWdgGen::SetDefaultDrawerLimits(double xmin, double xmax, double ymin, double ymax,
+                                          int axrl, int ayud)
+{
+mDrXmin = xmin;   mDrXmax = xmax; 
+mDrYmin = ymin;   mDrYmax = ymax; 
+if (axrl != kAxeDirSame)   mDXdir = axrl;    
+if (ayud != kAxeDirSame)   mDYdir = ayud;
+}
+
+/* --Methode-- */
+void PIBaseWdgGen::SetDefaultDrawerLogScale(bool logx, bool logy)
+{
+mDXlog = logx; 
+mDYlog = logy; 
+}
+
+//++
+// int  AddDrawer(PIDrawer* drw, PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2, -
+//                bool psz=true, bool clip=true, bool ad=false)
+//	Attachement d'un "PIDrawer" au rectangle défini les coordonnées des deux coins opposés.
+//	si "psz=true", les coordonnées sont supposées être des facteurs multiplicatifs 
+//	des dimensions de l'objet.
+//	si "clip=true", "PIDrawer* drw" ne peut dessiner en dehors de son rectangle
+//	d'attachement.
+//	si "ad=true", le "PIDrawer* drw" est détruit lors de la destruction de l'objet PIBaseWdg.
+//	La méthode retourne l'identificateur du drawer attaché.
+// int  AddDrawer(PIDrawer* drw, bool autolim=false, bool clip=true, bool ad=false)
+//	Ajout d'un "PIDrawer" au rectangle d'attachement par défaut. 
+//	Si "autolim=true", l'objet "PIBaseWdg" impose l'espace de coordonnées utilisateur
+//	à l'aide des valeurs définies par "SetDefaultDrawerLimits()".
+//	Si ""clip=true", "PIDrawer* drw" ne peut dessiner en dehors de son rectangle 
+//	d'attachement.
+//	si "ad=true", le "PIDrawer* drw" est détruit lors de la destruction de l'objet PIBaseWdg.
+//	La méthode retourne l'identificateur du drawer attaché.
+//--
+
+/* --Methode-- */
+int PIBaseWdgGen::AddDrawer(PIDrawer* drw, PIGrCoord x1, PIGrCoord y1,  
+                            PIGrCoord x2, PIGrCoord y2, bool psz, bool clip, bool ad)
+{
+if (drw == NULL)   return(0);
+mDrwId++;
+BWDrwId did;
+did.x1 = x1;  did.y1 = y1;
+did.x2 = x2;  did.y2 = y2;
+did.autoszp = did.autolim = false;   
+did.elastic = psz;  did.clip = clip;
+did.id = mDrwId;  did.ad = ad; 
+did.drw = drw;
+mDrwList.push_back(did);
+drw->Attach(this, mDrwId);
+mActDrwId = mDrwId;   // Le dernier drawer ajoute devient le drawer actif par defaut
+return(mDrwId);
+}
+
+/* --Methode-- */
+int PIBaseWdgGen::AddDrawer(PIDrawer* drw, bool autolim, bool clip, bool ad)
+{
+if (drw == NULL)   return(0);
+mDrwId++;
+BWDrwId did;
+did.x1 = 0.;  did.y1 = 0.;
+did.x2 = 1.;  did.y2 = 1.;
+did.autoszp = true;   did.autolim = autolim;   
+did.elastic = false;   did.clip = clip;
+did.id = mDrwId;  did.ad = ad; 
+did.drw = drw;
+mDrwList.push_back(did);
+drw->Attach(this, mDrwId);
+mActDrwId = mDrwId;   // Le dernier drawer ajoute devient le drawer actif par defaut
+return(mDrwId);
+}
+
+
+//++
+// void  MoveResizeDrawer(int id, PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2, bool psz=true)
+//	Modification du rectangle d'attachement du PIDrawer avec l'identificateur "id" , retourné
+//	par "AddDrawer()"
+// void  RemoveDrawer(int id)
+//	Ote le drawer "id" de la liste
+// void  DeleteDrawers()
+//	Ote tous les drawers de la liste. Détruit ceux ajoutés avec l'option "ad=true" 
+//--
+
+/* --Methode-- */
+void PIBaseWdgGen::MoveResizeDrawer(int id,  PIGrCoord x1, PIGrCoord y1,  PIGrCoord x2, PIGrCoord y2, bool psz)
+{
+vector<BWDrwId>::iterator it;
+for(it = mDrwList.begin(); it != mDrwList.end(); it++)  
+  if ((*it).id == id) { 
+    (*it).x1 = x1;  (*it).y1 = y1;
+    (*it).x2 = x2;  (*it).y2 = y2;
+    (*it).elastic = psz;
+    break;
+  }
+return;
+}
+
+/* --Methode-- */
+void PIBaseWdgGen::RemoveDrawer(int id)
+{
+if (mAdfg)  return;
+vector<BWDrwId>::iterator it;
+for(it = mDrwList.begin(); it != mDrwList.end(); it++)
+  if ((*it).id == id) {
+    (*it).drw->Detach(this, id); mDrwList.erase(it); 
+    if (id == mActDrwId) {
+      if (NbDrawers() > 0) mActDrwId = (*(mDrwList.end()-1)).id;
+      else mActDrwId = -1;
+    }
+  break; 
+  }
+return;
+}
+
+/* --Methode-- */
+void PIBaseWdgGen::DeleteDrawers()
+{
+mAdfg = true;
+vector<BWDrwId>::iterator it;
+for(it = mDrwList.begin(); it != mDrwList.end(); it++)  
+  if ((*it).ad)  delete (*it).drw;
+mDrwList.erase(mDrwList.begin(), mDrwList.end() );
+mActDrwId = -1;
+mAdfg = false;
+return;
+}
+
+//++
+// int  NbDrawers()
+//	Retourne le nombre de PIDrawer attachés
+// PIDrawer*  GetDrawerId(int id)
+//	Retourne le PIDrawer avec l'identificateur id
+// PIDrawer*  GetDrawer(int n)
+//	Retourne le PIDrawer "n=0..NbDrawers()-1" de la liste
+//--
+
+/* --Methode-- */
+int PIBaseWdgGen::NbDrawers()
+{
+return(mDrwList.size());
+}
+
+
+/* --Methode-- */
+PIDrawer* PIBaseWdgGen::GetDrawer(int n)
+{
+if ( (n < 0) || (n >= mDrwList.size()) ) return(NULL);
+return(mDrwList[n].drw);
+}
+
+/* --Methode-- */
+PIDrawer* PIBaseWdgGen::GetDrawerId(int id)
+{
+vector<BWDrwId>::iterator it;
+for(it = mDrwList.begin(); it != mDrwList.end(); it++)  
+  if ((*it).id == id)  return((*it).drw);
+return(NULL);
+}
+
+
+//++
+// void  SetActiveDrawerId(int id)
+//	Sélectionne le traceur (PIDrawer) avec l'identificateur "id" comme traceur actif.
+// void  SetActiveDrawer(int n)
+//	Sélectionne le traceur numéro "n" de la liste comme traceur actif.
+// int   GetActiveDrawerId()
+//	Retourne l'identificateur du traceur actif (-1 si pas de traceur actif).
+// int   GetActiveDrawerNum()
+//	Retourne le numéro du traceur actif dans la liste (index dans le vecteur de traceurs -
+//	-1 si pas de traceur actif).
+// PIDrawer*  GetActiveDrawer()
+//	Retourne le pointeur sur le traceur actif (NULL si pas de traceur actif).
+//--
+
+/* --Methode-- */
+void PIBaseWdgGen::SetActiveDrawerId(int id)
+{
+vector<BWDrwId>::iterator it;
+for(it = mDrwList.begin(); it != mDrwList.end(); it++)  
+  if ((*it).id == id) { mActDrwId = id; break; }
+return;
+}
+
+/* --Methode-- */
+void PIBaseWdgGen::SetActiveDrawer(int n)
+{
+if ( (n >= 0) && (n < mDrwList.size()) ) mActDrwId = mDrwList[n].id;
+return;
+}
+
+/* --Methode-- */
+int PIBaseWdgGen::GetActiveDrawerId()
+{
+  return(mActDrwId);
+}
+
+/* --Methode-- */
+int PIBaseWdgGen::GetActiveDrawerNum()
+{
+  if (mActDrwId < 0) return(-1);
+  for(int i=0; i<mDrwList.size(); i++) 
+    if (mDrwList[i].id == mActDrwId) return(i);
+  return(-1);
+}
+
+/* --Methode-- */
+PIDrawer*  PIBaseWdgGen::GetActiveDrawer()
+{
+  if (mActDrwId < 0) return(NULL); 
+  else return(GetDrawerId(mActDrwId));
+}
+
+//++
+// void  CallDrawers(PIGraphic* g, int x0=0, int y0=0, int dx=0, int dy=0)
+//	Appel de la méthode de tracé pour tous les Drawers
+// void  CallDrawer(int id);
+//	Appel de la méthode de tracé pour le drawer avec l'identificateur "id"
+//--
+
+/* --Methode-- */
+void PIBaseWdgGen::CallDrawers(PIGraphic* g, int x0, int y0, int dx, int dy)
+{
+double xmin,ymin, xmax, ymax;
+PIGraphicUC* guc;
+int drx0, dry0, drdx, drdy;
+int ddrx0, ddry0, ddrdx, ddrdy;
+
+if (mDrElastic) { 
+  ddrx0 = (int)((double) mDrX1 * (double)XSize());
+  ddry0 = (int)((double) mDrY1 * (double)YSize());
+  ddrdx = (int)((double) mDrX2 * (double)XSize()) - ddrx0 ;
+  ddrdy = (int)((double) mDrY2 * (double)YSize()) - ddry0 ;
+  }
+else {
+  ddrx0 = (int)mDrX1;   ddry0 = (int)mDrY1;  
+  ddrdx = (int)mDrX2-ddrx0;   ddrdy = (int)mDrY2-ddry0;  
+  }
+
+bool sxy = false;
+if ((dx > 0) && (dy > 0))  sxy = true;
+
+vector<BWDrwId>::iterator it;
+for(it = mDrwList.begin(); it != mDrwList.end(); it++) {
+  g->SaveGraphicAtt();
+  if ( (*it).autoszp )   // Taille/position  par defaut impose par PIBaseWdg 
+    { drx0 = ddrx0;  dry0 = ddry0;   drdx = ddrdx;  drdy = ddrdy; } 
+  else {
+    if ( (*it).elastic  ) {   // Taille/position defin en fraction de la taille du PIBaseWdg
+      drx0 = (int)((double)(*it).x1 * (double)XSize());
+      dry0 = (int)((double)(*it).y1 * (double)YSize());
+      drdx = (int)((double)(*it).x2 * (double)XSize()) - drx0 ;
+      drdy = (int)((double)(*it).y2 * (double)YSize()) - dry0 ;
+      }
+    else {
+      drx0 = (int)(*it).x1 ;  dry0 = (int)(*it).y1 ; 
+      drdx = (int)(*it).x2-drx0 ;  drdy = (int)(*it).y2-dry0 ; 
+      }
+    }
+// L'ordre des operations ici est importante 
+  if ( (*it).autolim ) {
+     (*it).drw->SetLimits(mDrXmin, mDrXmax, mDrYmin, mDrYmax, mDXdir, mDYdir);     
+     (*it).drw->SetLogScale(mDXlog, mDYlog);
+  }
+  guc = (*it).drw->SetDrwWdg(this, drx0, dry0, drdx, drdy, g);
+  if ((*it).clip)  g->SetClipRectangle(drx0, dry0, drdx , drdy);  
+  (*it).drw->SelGraAtt(guc);
+  if (sxy) {
+    guc->GrC2UC(x0, y0, xmin, ymin);
+    guc->GrC2UC(x0+dx, y0+dy, xmax, ymax);
+    }
+  else {
+    guc->GrC2UC(0, 0, xmin, ymin);
+    guc->GrC2UC(XSize(), YSize(), xmax, ymax);    
+    } 
+  if (xmin > xmax)  dbl_swap(xmin,xmax);
+  if (ymin > ymax)  dbl_swap(ymin,ymax);
+  (*it).drw->Draw(guc, xmin, ymin, xmax, ymax);
+  g->RestoreGraphicAtt();
+  if ((*it).clip)  g->ClearClipRectangle();
+  }
+
+return;
+}
+
+/* --Methode-- */
+void PIBaseWdgGen::CallDrawer(int id)
+{
+double xmin,ymin, xmax, ymax;
+PIGraphicUC* guc;
+int drx0, dry0, drdx, drdy;
+int ddrx0, ddry0, ddrdx, ddrdy;
+
+PIGraphic* g = WindowGraphic();
+
+if (mDrElastic) { 
+  ddrx0 = (int)((double) mDrX1 * (double)XSize());
+  ddry0 = (int)((double) mDrY1 * (double)YSize());
+  ddrdx = (int)((double) mDrX2 * (double)XSize()) - ddrx0 ;
+  ddrdy = (int)((double) mDrY2 * (double)YSize()) - ddry0 ;
+  }
+else {
+  ddrx0 = (int)mDrX1;   ddry0 = (int)mDrY1;  
+  ddrdx = (int)mDrX2-ddrx0;   ddrdy = (int)mDrY2-ddry0;  
+  }
+vector<BWDrwId>::iterator it;
+for(it = mDrwList.begin(); it != mDrwList.end(); it++) 
+  if ((*it).id == id) {
+    g->SaveGraphicAtt();
+    if ( (*it).autoszp )   // Taille/position  par defaut impose par PIBaseWdg 
+      { drx0 = ddrx0;  dry0 = ddry0;   drdx = ddrdx;  drdy = ddrdy; } 
+    else {
+      if ( (*it).elastic  ) {   // Taille/position defin en fraction de la taille du PIBaseWdg
+        drx0 = (int)((double)(*it).x1 * (double)XSize());
+        dry0 = (int)((double)(*it).y1 * (double)YSize());
+        drdx = (int)((double)(*it).x2 * (double)XSize()) - drx0 ;
+        drdy = (int)((double)(*it).y2 * (double)YSize()) - dry0 ;
+        }
+      else {
+        drx0 = (int)(*it).x1 ;  dry0 = (int)(*it).y1 ; 
+        drdx = (int)(*it).x2-drx0 ;  drdy = (int)(*it).y2-dry0 ; 
+        }
+      }
+// L'ordre des operations ici est importante 
+    if ( (*it).autolim ) {
+       (*it).drw->SetLimits(mDrXmin, mDrXmax, mDrYmin, mDrYmax, mDXdir, mDYdir);
+       (*it).drw->SetLogScale(mDXlog, mDYlog);
+    }
+    guc = (*it).drw->SetDrwWdg(this, drx0, dry0, drdx, drdy, g);
+    if ((*it).clip)  g->SetClipRectangle(drx0, dry0, drdx , drdy);
+    (*it).drw->SelGraAtt(guc);
+    guc->GrC2UC(0, 0, xmin, ymin);
+    guc->GrC2UC(XSize(), YSize(), xmax, ymax);     
+    if (xmin > xmax)  dbl_swap(xmin,xmax);
+    if (ymin > ymax)  dbl_swap(ymin,ymax);
+    (*it).drw->Draw(guc, xmin, ymin, xmax, ymax);
+    g->RestoreGraphicAtt();    
+    if ((*it).clip)  g->ClearClipRectangle();
+    break;
+  }
+return;
+}
+
+
+/* --Methode-- */
+PIGraphic* PIBaseWdgGen::WindowGraphic()
+{
+return(mWGrC);
+}
Index: /tags/V_Dec2002/SophyaPI/PI/pibwdggen.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pibwdggen.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pibwdggen.h	(revision 2309)
@@ -0,0 +1,134 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive      PIBaseWdgGen
+// Classe de base pour la creation de nouvelles composantes
+// graphiques interactives       
+//                        R.Ansari -  E.Aubourg 96
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PIBWDGGEN_H_SEEN
+#define PIBWDGGEN_H_SEEN
+
+
+#include "pisysdep.h"
+#include PIWDG_H
+#include PICMAP_H
+#include PIGRAPHIC_H
+#include "pigraphuc.h"
+#include "pievthandler.h"
+#include "psfile.h"
+
+// Mettre dans cet ordre, sinon g++ a des problemes   
+#include <vector>   
+
+
+enum PIPointer { PI_ArrowPointer = 1, PI_CrossPointer = 2, 
+                 PI_HandPointer = 3, PI_TDLRArrowPointer = 4 };
+
+
+class PIBaseWdgGen : public PIWdg
+{
+public:
+  enum {ClassId = 5000};
+
+// Les methodes ...
+
+                     PIBaseWdgGen(PIContainerGen *par, const char *nom,
+                                   int sx=10, int sy=10, int px=0, int py=0);
+  virtual            ~PIBaseWdgGen();
+
+  virtual long       kind() {return ClassId; }
+
+//  Activation des evenements
+  virtual void       ActivatePtrCross()        = 0;
+  virtual void       ActivateButton(int bid)   = 0;
+  virtual void       ActivateMove(int bid)     = 0;
+  virtual void       ActivateKeyboard()        = 0;
+
+//  Divers :   forme de la souris
+  virtual void       SelPointerShape(PIPointer ptr=PI_ArrowPointer)          = 0;
+  virtual PIPointer  GetPointerShape()                                       = 0;
+  virtual void       AssignKeyboard()                                        = 0;
+
+//  Fonctions qui doivent contenir le dessin du contenu du widget lui-meme
+  virtual void       Draw(PIGraphic* g, int x0, int y0, int dx, int dy);
+  
+// Traitement des evenements   
+  virtual void       Resize();
+  virtual void       Enter();
+  virtual void       Leave();  
+  virtual void       But1Press(int x, int y);  
+  virtual void       But1Release(int x, int y); 
+  virtual void       But2Press(int x, int y);
+  virtual void       But2Release(int x, int y);
+  virtual void       But3Press(int x, int y);
+  virtual void       But3Release(int x, int y);
+  virtual void       PtrMove(int x, int y);
+  virtual void       Ptr1Move(int x, int y);
+  virtual void       Ptr2Move(int x, int y);
+  virtual void       Ptr3Move(int x, int y);
+  virtual void       Keyboard(int key, PIKeyModifier kmod);
+
+// Acces aux caracteristiques du dernier evenement 
+  virtual void       GetLastEventInfo(PIKeyModifier& kmod, unsigned long& tm) = 0;
+
+// PostScript output
+  virtual void       PSPrint(PSFile* psf, int ofx = 0, int ofy = 0,
+			     double scale_x=1., double scale_y=1.);
+
+// ------ Gestion des Drawers  ------
+  friend class PIDrawer;
+  virtual void       SetDefaultDrawRectangle(PIGrCoord x1, PIGrCoord y1, 
+                                             PIGrCoord x2, PIGrCoord y2, bool psz=true); 
+  virtual void       SetDefaultDrawerLimits(double xmin, double xmax, double ymin, double ymax,
+                                            int axrl=kAxeDirSame, int ayud=kAxeDirSame); 
+  virtual void	     SetDefaultDrawerLogScale(bool logx, bool logy);
+  inline  bool       isDefaultDrawerLogScaleX() { return(mDXlog); }
+  inline  bool       isDefaultDrawerLogScaleY() { return(mDYlog); }
+
+  virtual int        AddDrawer(PIDrawer* drw, PIGrCoord x1, PIGrCoord y1, 
+                               PIGrCoord x2, PIGrCoord y2, 
+                               bool psz=true, bool clip=true, bool ad=false);
+  virtual int        AddDrawer(PIDrawer* drw, bool autolim=false, bool clip=true, bool ad=false);
+  virtual void       MoveResizeDrawer(int id, PIGrCoord x1, PIGrCoord y1, 
+                                      PIGrCoord x2, PIGrCoord y2, bool psz=true);
+  virtual void       RemoveDrawer(int id);       // Ote un drawer de la liste
+  virtual void       DeleteDrawers();            // Ote tous les drawers, delete des drawers ajoute avec ad=true
+// Acces aux drawers 
+  virtual int        NbDrawers();
+  virtual PIDrawer*  GetDrawerId(int id);   
+  virtual PIDrawer*  GetDrawer(int n); 
+  
+// Quel est le drawer actif
+  virtual void       SetActiveDrawerId(int id);   
+  virtual void       SetActiveDrawer(int n);   
+  virtual int        GetActiveDrawerId();   
+  virtual int        GetActiveDrawerNum();   
+  virtual PIDrawer*  GetActiveDrawer();   
+
+//  Trace des Drawers ...          
+  virtual void       CallDrawers(PIGraphic* g, int x0=0, int y0=0, int dx=0, int dy=0); 
+  virtual void       CallDrawer(int id);
+
+// Devrait etre protected - mis ici a cause de cxx  11/07/97  Reza
+  struct BWDrwId { int id; PIGrCoord x1, y1, x2, y2; bool autoszp, autolim, elastic, clip, ad;  PIDrawer* drw; };
+
+  virtual PIGraphic*  WindowGraphic();
+
+// -------------- Variables membre protegees -------------------
+protected:
+  PIGraphicWin* mWGrC;  // PIGraphic (Contexte graphique) associe a la fenetre
+  bool mAdfg;           // Pour la gestion de DeleteDrawers() quand appele par delete de PIBaseWdg
+  int mDrwId;           // Compteur pour DrawerId
+  int mActDrwId;        // Identificateur du drawer actif
+  vector<BWDrwId> mDrwList;   // Liste des drawers et leur Id
+//  Definition de la zone de trace et limites UC des drawers par defaut  
+  PIGrCoord mDrX1, mDrY1,  mDrX2,  mDrY2;  
+  bool mDrElastic;   // true --> Coord en fraction de la taille 
+  double mDrXmin, mDrXmax, mDrYmin, mDrYmax;   // Limites par defaut - UC
+  int  mDXdir, mDYdir;                        // Sens des axes par defaut
+  bool mDXlog, mDYlog;                        // true -> echelle log - axes par defaut
+};
+
+
+#endif /* PIBWDGGEN_H_SEEN */
+
Index: /tags/V_Dec2002/SophyaPI/PI/pibwdgmac.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pibwdgmac.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pibwdgmac.cc	(revision 2309)
@@ -0,0 +1,157 @@
+#include <stdio.h>
+
+#include <LString.h>
+#include "pibwdgmac.h"
+#include "piupdattachment.h"
+#include <algobase.h>
+#include <string.h>
+
+#define mGraphic mWGrC  
+
+// Les methodes de la classe  PIBWdgGen
+ 
+/* --Methode-- */
+PIBaseWdgMac::PIBaseWdgMac(PIContainerGen *par, char *nom,
+                       int sx, int sy, int px, int py) :
+PIBaseWdgGen(par, nom, sx, sy, px, py) 
+{
+    mGraphic = new PIGraphicMac(this);
+
+    mAdapter->AddAttachment(new PIUpdAttachment(this));
+    mPane->AddAttachment(new PIUpdAttachment(this));
+    cursor = NULL;
+    
+
+}
+
+
+/* --Methode-- */
+PIBaseWdgMac::~PIBaseWdgMac()
+{
+}
+
+/* --Methode-- */
+void PIBaseWdgMac::ActivatePtrCross()
+{
+// toujours actif pour le moment
+}
+
+/* --Methode-- */
+void PIBaseWdgMac::ActivateButton(int /*bid*/)
+{
+}
+
+/* --Methode-- */
+void PIBaseWdgMac::ActivateMove(int /*bid*/)
+{
+}
+
+/* --Methode-- */
+void PIBaseWdgMac::ActivateKeyboard()
+{
+}
+
+/* --Methode-- */
+void PIBaseWdgMac::EraseWindow(int x0, int y0, int dx, int dy)
+{
+  if (mPane->FocusDraw()) {
+     GrafPtr p = mPane->GetMacPort();
+     if (p) EraseRgn(p->visRgn);
+//	   Rect r;
+//	   mPane->CalcPortFrameRect(r);
+//       EraseRect(&r);
+  }
+}
+
+
+
+/* --Methode-- */
+void PIBaseWdgMac::SelPointerShape(PIPointer ptr)
+{
+  CursHandle c;
+  if (mPane->FocusDraw()) {
+    switch(ptr) {
+      case PI_ArrowPointer:
+        cursor = &qd.arrow;
+        break;
+      case PI_CrossPointer:
+        c = GetCursor(crossCursor);
+        HLock((Handle)c);
+        cursor = c ? *c : NULL;
+        break;
+      case PI_HandPointer:
+        c = GetCursor(128);
+        HLock((Handle)c);
+        cursor = c ? *c : NULL;
+        break;
+    }
+  }
+  mPtrS = ptr;
+}
+
+
+
+/* --Methode-- */
+PIPointer  PIBaseWdgMac::GetPointerShape()
+{
+return (mPtrS);
+}
+
+
+
+/* --Methode-- */
+bool PIBaseWdgMac::AdjustCursor()
+{
+  if (cursor) {
+    ::SetCursor(cursor);
+    return true;
+  }
+  return false;
+}
+
+/* --Methode-- 
+void PIBaseWdgMac::Refresh()
+{
+if (mPane->IsVisible())
+  Draw();
+}
+   J'ai mis cette fonction ds PIWdgMac::IsVisible()    Reza $CHECK$  01/12/97 
+*/
+
+
+
+void PIBaseWdgMac::SetBackgroundColor(PIColors col)
+{
+  if (mPane->FocusDraw()) {
+    long color;
+    switch (col) {
+      case PI_Black:
+        color = blackColor;
+        break;
+      case PI_White:
+        color = whiteColor;
+        break;
+      case PI_Red:
+        color = redColor;
+        break;
+      case PI_Blue:
+        color = blueColor;
+        break;
+      case PI_Green:
+        color = greenColor;
+        break;
+      case PI_Yellow:
+        color = yellowColor;
+        break;
+      default:
+        color = blackColor;
+    }
+    mBCol = col;
+    ::BackColor(color);
+  }
+}
+
+PIColors  PIBaseWdgMac::GetBackgroundColor() 
+{
+return (mBCol);
+}
Index: /tags/V_Dec2002/SophyaPI/PI/pibwdgmac.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pibwdgmac.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pibwdgmac.h	(revision 2309)
@@ -0,0 +1,49 @@
+/* Widget Xt pour affichage d'image  Interface Public    */
+/*                                    Reza 10/95         */
+
+#ifndef PIBWDGMAC_H_SEEN
+#define PIBWDGMAC_H_SEEN
+
+#include "pisysdep.h"
+#include "pibwdggen.h"
+
+
+class PIBaseWdgMac : public PIBaseWdgGen
+{
+public:
+// Les methodes ...
+
+                     PIBaseWdgMac(PIContainerGen *par, char *nom,
+                                   int sx=10, int sy=10, int px=0, int py=0);
+  virtual           ~PIBaseWdgMac();
+
+//  Activation des evenements
+  virtual void       ActivatePtrCross();
+  virtual void       ActivateButton(int bid);
+  virtual void       ActivateMove(int bid);
+  virtual void       ActivateKeyboard();
+
+//  Divers : couleur de fond, Effacement fenetre,  forme de la souris
+  virtual void       SetBackgroundColor(PIColors col=PI_White);
+  virtual void       EraseWindow(int x0=0, int y0=0, int dx=0, int dy=0);
+  virtual void       SelPointerShape(PIPointer ptr=PI_ArrowPointer);
+  virtual PIColors   GetBackgroundColor();
+  virtual PIPointer  GetPointerShape();
+  virtual void       AssignKeyboard() {}
+
+// Acces aux caracteristiques du dernier evenement 
+  virtual void       GetLastEventInfo(PIKeyModifier& kmod, unsigned long& tm);
+
+protected:
+  friend class       PIUpdAttachment;
+  virtual bool       AdjustCursor();
+  CursPtr            cursor;
+  
+
+  PIPointer mPtrS;
+  PIColors  mBCol;
+};
+
+typedef PIBaseWdgMac PIBaseWdg;
+
+#endif /* RZXBASE_H_SEEN */
Index: /tags/V_Dec2002/SophyaPI/PI/pibwdgx.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pibwdgx.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pibwdgx.cc	(revision 2309)
@@ -0,0 +1,249 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive      PIBaseWdg
+//                                    Reza 95-96
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include <stdio.h>
+
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#include <X11/cursorfont.h>
+
+#include <X11/IntrinsicP.h>
+#include <X11/CoreP.h>
+
+#include "pixtbaseP.h"
+#include "pixtbase.h"
+
+#include "pibwdgx.h"
+
+
+// #define DEBUG_PIBWDGX     Flag pour impression de debug etc ...
+static unsigned long colpixwhite, colpixblack;
+#define NMAXCURS 5 
+static Cursor curs[NMAXCURS];
+
+
+/* --Methode-- */
+PIBaseWdgX::PIBaseWdgX(PIContainerGen *par, const char *nom,
+                       int sx, int sy, int px, int py) 
+: PIBaseWdgGen(par, nom, sx, sy, px, py)
+
+{
+Arg  wargs[3];
+
+Init();
+mWGrC = NULL; // PIGraphic (Contexte graphique) associe a la fenetre
+finishDone = false;     // FinishCreate() pas encore appele
+
+CreateXtWdg(nom, piXtBaseWidgetClass, NULL, sx, sy, px, py);
+
+XtSetArg(wargs[0],PIXNobject,this); 
+XtSetArg(wargs[1],XtNbackground, colpixwhite);  
+XtSetArg(wargs[2],XtNborderWidth, (Dimension)0);  
+XtSetValues(XtWdg(), wargs, 3);
+
+((PIXtBaseWidget)XtWdg())->pixtbase.myeventmask = 0;
+XtUninstallTranslations(XtWdg());
+
+mPtrS = PI_CrossPointer;
+SelPointerShape();
+// PIGraphic (Contexte graphique) associe a la fenetre
+// Si pas cree par FinishCreate()
+if (!mWGrC) mWGrC = new PIGraphicX(this);   
+SetBackgroundColor();
+SetForegroundColor();
+Manage();
+}
+
+
+/* --Methode-- */
+PIBaseWdgX::~PIBaseWdgX()
+{
+#ifdef DEBUG_PIBWDGX 
+printf("PIBaseWdgX::~PIBaseWdgX()_Debug: Object= %lx (%lx) Wdg= %lx \n",
+(long)this, (long)(((PIXtBaseWidget)XtWdg())->pixtbase.objet), (long)XtWdg() );  
+#endif
+Arg  wargs[2];
+XtSetArg(wargs[0],PIXNobject,NULL); 
+XtSetValues(XtWdg(), wargs, 1);
+}
+
+/* --Methode-- */
+void PIBaseWdgX::FinishCreate()
+{
+// appele par la fenetre mere, apres XtRealize()
+if (finishDone) { 
+  fprintf(stderr, "BUG/PIBaseWdgX::FinishCreate() multiple call \n"); 
+  return; 
+  }
+PIWdgX::FinishCreate();
+
+// J'active le backing store pour la fenetre X
+XSetWindowAttributes xswa;
+if (!XtIsRealized(XtWdg())) XtRealizeWidget( XtWdg() ) ;
+
+Window mwi = XtWindow(XtWdg());
+
+/*
+XWindowAttributes xwa;
+XGetWindowAttributes(PIXDisplay(), mwi, &xwa);
+printf("PIBaseWdgX::FinishCreate()  BS= %d  (No=%d Map=%d Always=%d) planes=%lx \n", 
+       xwa.backing_store, NotUseful, WhenMapped, Always, (long)xwa.backing_planes);
+*/
+xswa.backing_store = WhenMapped;
+// xswa.backing_planes = ~0;
+// XChangeWindowAttributes(PIXDisplay(), XtWindow(XtWdg()), CWBackingPlanes|CWBackingStore, &xswa);
+XChangeWindowAttributes(PIXDisplay(), mwi, CWBackingStore, &xswa);
+
+// PIGraphic (Contexte graphique) associe a la fenetre
+if (!mWGrC) mWGrC = new PIGraphicX(this);   
+mWGrC->TerminateInit();
+} 
+
+/* --Methode-- */
+bool PIBaseWdgX::IsVisible()
+{
+return (finishDone && PIWdg::IsVisible() ); 
+}
+
+/* --Methode-- */
+void PIBaseWdgX::Refresh()
+{
+if (XtIsRealized(XtWdg())) {
+// if ( IsVisible() )  {
+//  EraseWindow();   --> Ne pas faire  Reza 12/98 
+  Draw(mWGrC, 0, 0, XSize(), YSize());
+  CallDrawers(mWGrC); 
+  CallDrawHandlers(0, 0, XSize(), YSize());
+  }
+return;
+}
+
+
+/* --Methode-- */
+void PIBaseWdgX::ActivatePtrCross()
+{
+XtAddEventHandler( XtWdg(), EnterWindowMask | LeaveWindowMask, 
+                   FALSE, event_handler_pixtbase, NULL);
+return;
+}
+
+
+/* --Methode-- */
+void PIBaseWdgX::ActivateButton(int bid)
+{
+#ifdef DEBUG_PIBWDGX
+printf("PIBaseWdgX::ActivateButton %d \n \n", bid);
+#endif
+if ( (bid < 1) && (bid > 3) ) return; 
+XtAddEventHandler( XtWdg(), ButtonPressMask | ButtonReleaseMask, 
+                   FALSE, event_handler_pixtbase, NULL);
+if (bid == 1)  ((PIXtBaseWidget)XtWdg())->pixtbase.myeventmask |= Button1Mask ;
+else if (bid == 2) ((PIXtBaseWidget)XtWdg())->pixtbase.myeventmask |= Button2Mask ;
+else if (bid == 3) ((PIXtBaseWidget)XtWdg())->pixtbase.myeventmask |= Button3Mask ;
+return;
+}
+
+/* --Methode-- */
+void PIBaseWdgX::ActivateMove(int bid)
+{
+#ifdef DEBUG_PIBWDGX
+printf("PIBaseWdgX::ActivateMove %d \n \n", bid);
+#endif
+unsigned long evtmask = 0;
+
+// bid == 0  -> PointerMove sans bouton 
+if ( (bid < 0) && (bid > 3) ) return; 
+
+if (bid == 0) evtmask = PointerMotionHintMask ;
+else if (bid == 1) evtmask = Button1MotionMask | PointerMotionHintMask ;
+else if (bid == 2) evtmask = Button2MotionMask | PointerMotionHintMask ;
+else if (bid == 3) evtmask = Button3MotionMask | PointerMotionHintMask ;
+XtAddEventHandler( XtWdg(), evtmask, FALSE, event_handler_pixtbase, NULL);
+return;
+}
+
+
+/* --Methode-- */
+void PIBaseWdgX::ActivateKeyboard()
+{
+XtAddEventHandler( XtWdg(), KeyPressMask, FALSE, event_handler_pixtbase, NULL);
+((PIXtBaseWidget)XtWdg())->pixtbase.myeventmask |= ShiftMask ;
+return;
+}
+
+
+/* --Methode-- */
+void PIBaseWdgX::SelPointerShape(PIPointer ptr)  
+{
+if (ptr == mPtrS)  return;
+if ( (ptr < 0) || (ptr >= NMAXCURS))  return;
+if ( XtIsRealized(XtWdg()) )
+  XDefineCursor(XtDisplay (XtWdg()), XtWindow(XtWdg()), curs[ptr]);
+mPtrS = ptr;
+return;
+}
+
+/* --Methode-- */
+void PIBaseWdgX::AssignKeyboard()
+{
+XSetInputFocus(XtDisplay (XtWdg()), XtWindow(XtWdg()), RevertToParent, PIXGetLastEventTime());
+}
+
+
+/* --Methode-- */
+PIPointer  PIBaseWdgX::GetPointerShape()
+{
+return (mPtrS);
+}
+
+/* --Methode-- */
+void PIBaseWdgX::GetLastEventInfo(PIKeyModifier& kmod, unsigned long& tm)
+{
+unsigned int st;
+Time t;
+PIXGetLastEventInfo(st, t);
+tm = t;
+kmod = PIKM_Blank;
+if  (st & ShiftMask)   kmod = (PIKeyModifier) (kmod | PIKM_Shift);
+if  (st & ControlMask) kmod = (PIKeyModifier) (kmod | PIKM_Cntl);
+if  (st & Mod1Mask)    kmod = (PIKeyModifier) (kmod | PIKM_Alt);
+return;
+}
+
+static bool fgbwdg = false ;
+
+/* --Methode-- */
+void PIBaseWdgX::Init()
+{
+int i;
+
+if (fgbwdg)  return;
+fgbwdg = true;
+
+Display *mdsp = PIXDisplay();
+int scr = XDefaultScreen(mdsp);
+
+colpixwhite = XWhitePixel(mdsp, scr);
+colpixblack = XBlackPixel(mdsp, scr);
+
+curs[0] = XCreateFontCursor(mdsp, XC_X_cursor);
+for(i=1; i<NMAXCURS; i++)  curs[i] = curs[0];
+
+curs[PI_ArrowPointer] =  XCreateFontCursor(mdsp, XC_arrow);
+curs[PI_CrossPointer] =  XCreateFontCursor(mdsp, XC_crosshair);
+curs[PI_HandPointer] =  XCreateFontCursor(mdsp, XC_hand2);
+curs[PI_TDLRArrowPointer] =  XCreateFontCursor(mdsp, XC_fleur);
+
+return;
+}
+
+/* --Methode-- */
+void PIBaseWdgX::eXposeProcess(int x0, int y0, int dx, int dy)                                 
+{ 
+// Appel depuis le PIXtBaseWidget uniquement (ExposeEvt de Xt )
+Draw(mWGrC, x0, y0, dx, dy);
+CallDrawers(mWGrC, x0, y0, dx, dy); 
+return;
+}
Index: /tags/V_Dec2002/SophyaPI/PI/pibwdgx.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pibwdgx.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pibwdgx.h	(revision 2309)
@@ -0,0 +1,58 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive      PIBaseWdg
+//                                    Reza  95-96
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PIBWDGX_H_SEEN
+#define PIBWDGX_H_SEEN
+
+#include "pisysdep.h"
+#include "pibwdggen.h"
+
+#include "pigraphx.h"
+            
+#include "pigraphps.h"
+
+class PIBaseWdgX : public PIBaseWdgGen
+{
+
+public:
+// Les methodes ...
+
+                     PIBaseWdgX(PIContainerGen *par, const char *nom,
+                                int sx=10, int sy=10, int px=0, int py=0);
+  virtual            ~PIBaseWdgX();
+
+  virtual void       FinishCreate();   // appele par la fenetre mere, apres XtRealize()
+
+//  Activation des evenements   
+  virtual void       ActivatePtrCross();
+  virtual void       ActivateButton(int bid);
+  virtual void       ActivateMove(int bid);
+  virtual void       ActivateKeyboard();
+
+//  Divers : couleur de fond, Effacement fenetre,  forme de la souris
+  virtual void       SelPointerShape(PIPointer ptr=PI_ArrowPointer);
+  virtual PIPointer  GetPointerShape();
+  virtual void       AssignKeyboard();
+
+// Acces aux caracteristiques du dernier evenement 
+  virtual void       GetLastEventInfo(PIKeyModifier& kmod, unsigned long& tm);
+
+// On redefinit IsVisible() pour tenir compte de l appel a FinsihCreate  
+  virtual bool       IsVisible();
+
+//  Fonction qui doit etre appelee pour rafraichir la fenetre 
+  virtual void       Refresh();
+
+//  Appel depuis le PIXtBaseWidget uniquement (ExposeEvt de Xt )
+  virtual void       eXposeProcess(int x0, int y0, int dx, int dy);
+ 
+protected:
+  void               Init();
+  PIPointer mPtrS;
+};
+
+typedef PIBaseWdgX PIBaseWdg;
+
+#endif /* PIBWDGX_H_SEEN */
Index: /tags/V_Dec2002/SophyaPI/PI/picmap.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/picmap.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/picmap.cc	(revision 2309)
@@ -0,0 +1,1771 @@
+// Module PI : Peida Interactive     PIColorMap
+// Gestion de table de couleurs        96
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "picmap.h"
+#include <iostream.h>
+
+//++
+// Class	PIColorMap
+// Lib		PI
+// include	picmap.h
+//
+//   	Classe fournissant les services de gestion des tables de couleur.
+//	Une hiérachie un peu complexe a été mise en place pour 
+//	l'implémentation des tables de couleurs pour chaque système
+//	(Mac, XWindow, ...) :
+//|	PIColorMapGen  -----  PIColorMapX     (=PIColorMapNative)
+//|	                 |--  PIColorMapMac   (=PIColorMapNative)
+//	et la gestion de table de couleurs standard partagée.
+//|	PIColorMapNative (=X,Mac,...) ----- PIColorMap.
+//	La seule classe à utiliser est *PIColorMap* qui fournit 
+//	l'ensemble des services de gestion de table de couleurs.
+//--
+
+#define  MXMAPIDS   22
+static   int    MapNCols[MXMAPIDS] = {256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
+                            256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256 };
+
+// Tables de couleurs :
+// 5 Standard PI , 32  couleurs
+// 4 Standard PI , 128 couleurs
+// 12 MIDAS , 256 couleurs
+// 1 Standard PI 16 couleurs
+
+static   const char*  MapNoms[MXMAPIDS]  = {
+                      "Grey32","InvGrey32","ColRJ32","ColBR32","ColRV32", 
+                      "Grey128","InvGrey128","ColRJ128","ColBR128",
+                      "MIDAS_Pastel","MIDAS_Heat","MIDAS_Rainbow3", 
+                      "MIDAS_BlueRed","MIDAS_BlueWhite","MIDAS_Stairs8",
+                      "MIDAS_Stairs9","MIDAS_StairCase","MIDAS_Color",
+                      "MIDAS_ManyCol","MIDAS_Idl14","MIDAS_Idl15",
+                      "Rainbow16"};
+
+static   CMapId MapIds[MXMAPIDS] = { 
+                      CMAP_GREY32, CMAP_GREYINV32, CMAP_COLRJ32, CMAP_COLBR32, CMAP_COLRV32, 
+                      CMAP_GREY128, CMAP_GREYINV128, CMAP_COLRJ128, CMAP_COLBR128,  
+                      CMAP_MIDAS_Pastel, CMAP_MIDAS_Heat, CMAP_MIDAS_Rainbow3, 
+                      CMAP_MIDAS_BlueRed, CMAP_MIDAS_BlueWhite, CMAP_MIDAS_Stairs8, 
+                      CMAP_MIDAS_Stairs9, CMAP_MIDAS_StairCase, CMAP_MIDAS_Color, 
+                      CMAP_MIDAS_ManyCol, CMAP_MIDAS_Idl14, CMAP_MIDAS_Idl15, 
+                      CMAP_COL16 } ;
+
+static   int mColTNums[8192];   // Max 8192 tables differentes pour le moment  
+static   int CTNum = 0;        //  Numero des tables ds mColTNum - s'incremente a chaque creation 
+
+static   int NMaxTableAuto = 0;
+static   PIColorMap* mMaps[MXMAPIDS] = {
+                                  NULL, NULL, NULL, NULL, NULL, 
+                                  NULL, NULL, NULL, NULL, NULL, 
+                                  NULL, NULL, NULL, NULL, NULL,
+                                  NULL  };
+
+int  PIColorMap::NumberStandardColorMaps()
+{
+  return ( MXMAPIDS );
+}
+
+CMapId PIColorMap::GetStandardColorMapId(int num)
+{
+  if ( (num < 0) || (num >= MXMAPIDS) )  num = 0;
+  return (MapIds[num]) ;
+}
+
+string PIColorMap::GetStandardColorMapName(int num)
+{
+  if ( (num < 0) || (num >= MXMAPIDS) )  num = 0;
+  return (MapNoms[num]) ;
+}
+
+int PIColorMap::ColorMapId2Num(PIColorMap const & cmap)
+{
+  for(int k=0; k<MXMAPIDS; k++) 
+    if (cmap.Type() == MapIds[k])  return(k);
+  return(-1);
+}
+
+
+//++
+// Titre	Constructeurs, méthodes
+//--
+//++
+// PIColorMap(CMapId id)
+//	Constructeur d'une table de couleur standard, identifiée par "CMapId id"
+//|	CMAP_GREY32     :  32 niveaux de gris
+//|	CMAP_GREYINV32  :  32 niveaux gris du blanc au noir
+//|	CMAP_COLRJ32    :  32 couleurs, du Rouge au Jaune/blanc
+//|	CMAP_COLBR32    :  32 couleurs du bleu au rouge (arcenciel)
+//|	CMAP_COLRV32    :  32 couleurs du rouge au violet
+//|	CMAP_GREY128    :  128 niveaux de gris
+//|	CMAP_GREYINV128 :  128 niveaux gris inversé
+//|	CMAP_COLRJ128   :  128 couleurs, du Rouge au Jaune/blanc
+//|	CMAP_COLBR128   :  128 couleurs du bleu au rouge (arcenciel)
+//|	CMAP_COL16      :  16 Couleurs arcenciel
+//|	CMAP_OTHER      :  Table non standard (Midas,Idl, ...)
+//	Toutes les tables de couleurs standard possèdent 256 cellules de couleurs,
+//	contenant 16 ou 32 ou 128 couleurs distinctes.
+//
+// PIColorMap(string const& nom, int nCol)
+//	Constructeur d'une table de "nCol" couleurs identifié par la chaîne "nom".
+// PIColorMap(PIColorMap&)
+//	Constructeur par copie.
+// int Type()
+//	Retourne le type de la table, correspondant à "CMapId id"
+// int NCol()
+//	Retourne le nombre de cellules de couleurs dans la table
+// string const& Nom()
+//	Renvoie le nom de la table.
+//--
+
+PIColorMap::PIColorMap(CMapId id)
+: PIColorMapNative()
+{
+   int k, kdx;
+   string mnom;
+
+   if (NMaxTableAuto == 0) { //  Il faut allouer les tables de depart
+     if ( TotNbColors() > 4096 ) NMaxTableAuto = MXMAPIDS-1;
+     else NMaxTableAuto = 3; 
+     //     for(k=0; k<NMaxTableAuto; k++)  { 
+     for(k=0; k<3; k++)  {   // On alloue les 3 tables de depart
+        mnom = MapNoms[k]; 
+	cout << " PIColorMap::PIColorMap(CMapId id) Allocating ColorMap " 
+	     << mnom << " ... " << endl;
+        mMaps[k] = new PIColorMap(MapIds[k], MapNCols[k], mnom);
+     }
+   }
+
+//  Protection pour valeur de Id  
+   for(kdx=0; kdx<MXMAPIDS; kdx++)  if (id == MapIds[kdx])  break;
+   if (kdx == MXMAPIDS)  { id = MapIds[0];  kdx = 0; }
+   for(k=0; k<NMaxTableAuto; k++) {
+     if ((MapIds[k] == id) && (mMaps[k] == NULL))  { //  Table pas encore alloue 
+       mnom = MapNoms[k]; 
+       cout << " PIColorMap::PIColorMap(CMapId id) Allocating ColorMap " 
+	     << mnom << " ... " << endl;
+       mMaps[k] = new PIColorMap(MapIds[k], MapNCols[k], mnom);
+     }
+     if (mMaps[k] && (id == mMaps[k]->Type()) ) {
+       CopyFrom(mMaps[k]);  
+       mCTId = mMaps[k]->mCTId;  mColTNums[mCTId]++;
+       break;
+     }
+   }
+   if (Type() != id)  {  // Table pas encore trouve dans la liste
+     k = NMaxTableAuto;
+     if (!mMaps[k] || mMaps[k]->Type() != id) {
+       if ( mMaps[k] ) {  
+         mColTNums[mMaps[k]->mCTId] = 1;  // Je force a liberer les couleurs 
+         delete mMaps[k] ;
+       }
+       mnom = MapNoms[kdx];
+       mMaps[k] = new PIColorMap(MapIds[kdx],  MapNCols[kdx], mnom); 
+     }
+    CopyFrom(mMaps[k]);  
+    mCTId = mMaps[k]->mCTId;  mColTNums[mCTId]++;
+   }
+}
+
+
+PIColorMap::PIColorMap(string const& nom, int nCol)
+: PIColorMapNative(CMAP_OTHER, nCol, nom)
+{
+  MakeColMap();
+  mCTId = CTNum;
+  mColTNums[mCTId] = 1;
+  CTNum++;
+}
+
+PIColorMap::PIColorMap(CMapId id, int nCol, string const& nom)
+: PIColorMapNative(id, nCol, nom)
+{
+  MakeColMap();
+  mCTId = CTNum;
+  mColTNums[mCTId] = 1;
+  CTNum++;
+//  printf("PIColorMap/Debug-Creation:  %d %d - %s ", Type(), NCol(), Nom().c_str());
+//  printf("  ..CRE.. %d %d \n", CTNum-1, mColTNums[CTNum-1]);
+}
+
+PIColorMap::PIColorMap(PIColorMap& cm)
+: PIColorMapNative()
+{
+  ReverseColorIndex(cm.IsColorIndexReversed());
+  CopyFrom(&cm);
+  mCTId = cm.mCTId;
+  mColTNums[mCTId]++;
+}
+
+PIColorMap::~PIColorMap()
+{
+//  printf("PIColorMap/Debug-Delete:  %d %d - %s ", Type(), NCol(), Nom().c_str());
+//  printf("...DEL.CTNum,mColTNums= %d %d (%d %d) ", 
+//        CTNum, mColTNums[CTNum], mCTId,mColTNums[mCTId] );
+  mColTNums[mCTId]--; 
+  if ( mColTNums[mCTId] == 0 )  { FreeColors();  mColTNums[mCTId] = 0; }
+//  printf("\n");
+}
+
+
+//++
+// Titre	Gestion des couleurs
+//	Une structure *PIColor* permet la manipulation des couleurs à 
+//	travers 3 champs de type "unsigned short: 0 ... 65535" définissant
+//	les intensité des couleurs de base: Rouge, Bleue, Vert.
+//|	struct PIColor {
+//|	  unsigned short red;
+//|	  unsigned short green;
+//|	  unsigned short blue; }
+//
+//--
+//++
+// PIColor GetColor(int n)	
+//	Renvoie la couleur de la cellule "n"
+// bool AllocColor(PIColor const& col, int index)
+//	Alloue la couleur définie par "col" dans la cellule numéro "index".
+//	Renvoie "true" si OK, "false" sinon.
+// void  FreeColors()
+//	Libère les couleurs allouées par la table
+// long  TotNbColors()
+//	Renvoie le nombre total de couleurs disponibles 
+//	(Ex 256 pour un système à 8 plans image, 65536 pour 16 plans, etc ...)
+// int  NbAllocColors()
+//	Renvoie le nombre total de couleurs déjà utilisée par l'application
+//--
+
+void PIColorMap::CleanColorMaps()
+{
+  int k;
+  for(k=0; k<MXMAPIDS; k++)  { 
+    if (!mMaps[k])  continue;
+    mMaps[k]->FreeColors();
+    delete mMaps[k];
+  }
+}
+
+/*  Definition d' une table de couleurs  R G B   */
+
+static float R_RGB1[16] =
+{0.0,0.00,0.0,0.0,0.0,0.00,0.0,0.6,0.8,1.0,1.00,1.0,0.75,1.0,0.85,1.0};
+static float G_RGB1[16] =
+{0.0,0.00,0.0,0.8,1.0,1.00,1.0,0.8,0.8,1.0,0.75,0.6,0.00,0.0,0.0,0.0};
+static float B_RGB1[16] =
+{0.0,0.75,1.0,1.0,1.0,0.75,0.0,0.0,0.0,0.0,0.00,0.5,0.75,1.0,0.0,0.0};
+
+
+
+void PIColorMap::MakeColMap()
+{
+  PIColor mycol;
+  int i,j,k;
+
+  switch (mType) {
+
+    case CMAP_GREY32 :
+      for(i=0; i<32; i++) {
+        mycol.red = mycol.green = mycol.blue = 3535+(i*62000/32);
+        for(k=0; k<8; k++)     AllocColor(mycol, i*8+k);
+      }
+      break;
+    
+
+    case CMAP_GREYINV32 :
+      for(i=0; i<32; i++) {
+        mycol.red = mycol.green = mycol.blue = 3535+(i*62000/32);
+        for(k=0; k<8; k++)     AllocColor(mycol, mNCol-(i*8+k)-1);
+      }
+      break;
+
+    case CMAP_COL16 :
+      for(i=0; i<16; i++) {
+        mycol.red = (int)(R_RGB1[i]*65535.);
+        mycol.green = (int)(G_RGB1[i]*65535.);
+        mycol.blue =(int)(B_RGB1[i]*65535.) ;
+        for(k=0; k<16; k++)     AllocColor(mycol, i*16+k);
+      }
+      break;
+
+    case CMAP_COLRJ32 :
+      for( i=0; i<32; i++) {
+        if (i < 12)  { 
+          mycol.green = mycol.blue = 0;  
+          mycol.red = 21535+(i*4000);  }
+        else if (i < 24) { 
+          mycol.blue = 0;   mycol.red = 65535;
+          mycol.green = 21535+(i-12)*4000;  }
+        else { 
+          mycol.green = mycol.red = 65535;
+          mycol.blue = 17535+(i-23)*6000; }
+        for(k=0; k<8; k++)   AllocColor(mycol, i*8+k); 
+        }
+      break;
+
+  case CMAP_COLBR32 :
+    for( i=0; i<32; i++) {
+      if (i < 5) { 
+        mycol.green = mycol.red = 0;    // Du bleu sombre au bleu clair
+        mycol.blue = 5535+i*15000; }
+      else if (i < 10) { 
+        mycol.blue = 65535;             // Plein bleu - On rajoute du vert -> bleu clair
+        mycol.green = 5535+(i-5)*9000;
+        mycol.red = 0;  }
+      else if (i < 15) { 
+        mycol.blue = 60000-(i-10)*15000;   // On passe au vert
+        mycol.green = 41535+(i-10)*6000;
+        mycol.red = 0;  }
+      else if (i < 21) { 
+        mycol.blue = 0;
+        mycol.green = 65535;               // Plein vert, on rajoute du rouge -> jaune
+        mycol.red = 5535+(i-15)*12000;  }
+      else if (i < 27) {  
+        mycol.blue = 0;                     //  On diminue vert -> Orange
+        mycol.green = 60000-(i-21)*12000;
+        mycol.red = 65535-(i-21)*2000;  }
+      else {
+        mycol.blue = 0;                     // Plein rouge
+        mycol.green = 0;
+        mycol.red = 57535+(i-27)*2000; }
+
+      for(k=0; k<8; k++)   AllocColor(mycol, i*8+k); 
+      }
+    break;
+
+  case CMAP_COLRV32 :
+    for( i=0; i<32; i++) {
+      if (i < 9) {
+        mycol.green = i*5000; mycol.blue = 0;  
+        mycol.red = i*6000; }
+      else if (i < 15) {
+	mycol.green = 40000;
+	mycol.blue = 0;  
+	mycol.red = 50000+(i-9)*1000;
+      }
+      else if (i < 21) {
+        mycol.green = 40000-(i-15)*8000;
+        mycol.blue = 0;
+        mycol.red = 57535+(i-15)*1600;  }
+      else { 
+        mycol.green = 0;  mycol.red = 65535;
+        mycol.blue = 15535+(i-21)*5000; }
+
+      for(k=0; k<8; k++)   AllocColor(mycol, i*8+k); 
+      }
+    break;
+
+    case CMAP_GREY128 :
+      for(i=0; i<128; i++) {
+        mycol.red = mycol.green = mycol.blue = 2035+(i*500);
+        for(k=0; k<2; k++)     AllocColor(mycol, i*2+k);
+      }
+      break;
+    
+
+    case CMAP_GREYINV128 :
+      for(i=0; i<128; i++) {
+        mycol.red = mycol.green = mycol.blue = 2035+(i*500);
+        for(k=0; k<2; k++)     AllocColor(mycol, mNCol-(i*2+k)-1);
+      }
+      break;
+
+    case CMAP_COLRJ128 :
+      for( i=0; i<128; i++) {
+        if (i < 48)  { 
+          mycol.green = mycol.blue = 0;  
+          mycol.red = 5375+(i*1280);  }
+        else if (i < 96) { 
+          mycol.blue = 0;   mycol.red = 65535;
+          mycol.green = 5375+((i-48)*1280);  }
+        else { 
+          mycol.green = mycol.red = 65535;
+          mycol.blue = 3535+(i-96)*2000; }
+        for(k=0; k<2; k++)   AllocColor(mycol, i*2+k); 
+        }
+      break;
+
+    case CMAP_COLBR128 :
+      for( i=0; i<128; i++) {
+        if (i < 20) { 
+          mycol.green = mycol.red = 0;  // Du bleu sombre au bleu clair
+          mycol.blue = 2835+i*3300; }
+        else if (i < 36) { 
+          mycol.blue = 65535;           // Plein bleu - On rajoute du vert -> bleu clair
+          mycol.green = 3000+(i-20)*2000;
+          mycol.red = 0;  }
+        else if (i < 56) { 
+          mycol.blue = 64600-(i-36)*3400;    // On passe au vert 
+          mycol.green = 32300+(i-36)*1700;
+          mycol.red = 0;  }
+        else if (i < 81) {         
+          mycol.blue = 0;              // Plein vert, on rajoute du rouge -> jaune
+          mycol.green = 65535;
+          mycol.red = 3135+(i-56)*2600;  }
+        else if (i < 96) { 
+          mycol.blue = 0;
+          mycol.green = 63535-(i-80)*2000;
+          mycol.red = 65535;  }
+        else if (i < 112) { 
+          mycol.blue = 0;
+          mycol.green = 30000-(i-96)*2000;
+          mycol.red = 65535-(i-96)*1000;  }
+        else {
+          mycol.blue = 0;
+          mycol.green = 0 ;
+          mycol.red = 50535+(i-112)*1000; }
+
+        for(k=0; k<2; k++)   AllocColor(mycol, i*2+k); 
+      }
+      break;
+
+  case CMAP_MIDAS_Pastel :   // pastel.lutlis
+   {
+float rgb_r[256] = {
+0.00000, 0.00000, 0.01961, 0.05490, 0.08627, 0.10980, 0.13725, 0.15686, 
+0.18039, 0.20000, 0.21569, 0.23529, 0.25098, 0.26275, 0.28235, 0.29412, 
+0.30588, 0.31765, 0.33333, 0.34118, 0.35294, 0.36078, 0.37255, 0.38431, 
+0.39216, 0.40000, 0.41176, 0.41961, 0.43137, 0.43529, 0.44314, 0.45098, 
+0.45882, 0.46667, 0.47059, 0.48235, 0.48627, 0.49412, 0.50196, 0.50588, 
+0.50980, 0.51765, 0.52157, 0.53333, 0.53725, 0.54118, 0.54902, 0.55294, 
+0.55686, 0.56078, 0.56471, 0.57255, 0.58039, 0.58431, 0.58824, 0.59216, 
+0.59608, 0.60000, 0.60392, 0.60784, 0.61176, 0.61569, 0.61961, 0.62745, 
+0.63137, 0.63529, 0.63922, 0.64314, 0.64706, 0.65098, 0.65490, 0.65490, 
+0.65882, 0.66275, 0.66667, 0.67059, 0.67843, 0.67843, 0.68235, 0.68627, 
+0.69020, 0.69020, 0.69412, 0.69804, 0.70196, 0.70196, 0.70588, 0.70980, 
+0.71373, 0.71373, 0.71765, 0.72157, 0.72157, 0.72941, 0.73333, 0.73333, 
+0.73725, 0.74118, 0.74118, 0.74510, 0.74510, 0.74902, 0.75294, 0.75294, 
+0.75686, 0.76078, 0.76078, 0.76471, 0.76471, 0.76863, 0.76863, 0.77255, 
+0.78039, 0.78039, 0.78431, 0.78431, 0.78824, 0.78824, 0.79216, 0.79216, 
+0.79608, 0.79608, 0.80000, 0.80000, 0.80392, 0.80392, 0.80784, 0.80784, 
+0.81176, 0.81176, 0.81569, 0.81569, 0.81961, 0.81961, 0.82745, 0.82745, 
+0.83137, 0.83137, 0.83529, 0.83529, 0.83922, 0.83922, 0.83922, 0.84314, 
+0.84314, 0.84706, 0.84706, 0.85098, 0.85098, 0.85490, 0.85490, 0.85490, 
+0.85882, 0.85882, 0.86275, 0.86275, 0.86275, 0.86667, 0.86667, 0.87059, 
+0.87059, 0.87059, 0.87843, 0.87843, 0.88235, 0.88235, 0.88235, 0.88627, 
+0.88627, 0.89020, 0.89020, 0.89020, 0.89412, 0.89412, 0.89412, 0.89804, 
+0.89804, 0.89804, 0.90196, 0.90196, 0.90588, 0.90588, 0.90588, 0.90980, 
+0.90980, 0.90980, 0.91373, 0.91373, 0.91373, 0.91765, 0.91765, 0.91765, 
+0.92157, 0.92157, 0.92157, 0.92941, 0.92941, 0.92941, 0.93333, 0.93333, 
+0.93333, 0.93725, 0.93725, 0.93725, 0.94118, 0.94118, 0.94118, 0.94118, 
+0.94510, 0.94510, 0.94510, 0.94902, 0.94902, 0.94902, 0.95294, 0.95294, 
+0.95294, 0.95686, 0.95686, 0.95686, 0.95686, 0.96078, 0.96078, 0.96078, 
+0.96471, 0.96471, 0.96471, 0.96471, 0.96863, 0.96863, 0.96863, 0.97255, 
+0.97255, 0.97255, 0.97255, 0.98039, 0.98039, 0.98039, 0.98039, 0.98431, 
+0.98431, 0.98431, 0.98824, 0.98824, 0.98824, 0.98824, 0.99216, 0.99216, 
+0.99216, 0.99216, 0.99608, 0.99608, 0.99608, 0.99608, 1.00000, 1.00000
+};
+float rgb_g[256] = {
+0.00000, 0.00000, 0.00000, 0.00000, 0.00392, 0.00392, 0.00392, 0.00392, 
+0.00392, 0.00784, 0.00784, 0.00784, 0.00784, 0.01176, 0.01176, 0.01176, 
+0.01176, 0.01176, 0.01569, 0.01569, 0.01569, 0.01569, 0.01961, 0.01961, 
+0.01961, 0.01961, 0.02353, 0.02353, 0.02353, 0.02745, 0.02745, 0.02745, 
+0.02745, 0.03137, 0.03137, 0.03137, 0.03529, 0.03529, 0.03529, 0.03529, 
+0.04314, 0.04314, 0.04314, 0.04706, 0.04706, 0.04706, 0.05098, 0.05098, 
+0.05098, 0.05490, 0.05490, 0.05490, 0.05882, 0.05882, 0.05882, 0.06275, 
+0.06275, 0.06275, 0.06667, 0.06667, 0.06667, 0.07059, 0.07059, 0.07451, 
+0.07451, 0.07451, 0.07843, 0.07843, 0.08235, 0.08235, 0.08235, 0.08627, 
+0.08627, 0.09020, 0.09020, 0.09020, 0.09412, 0.09412, 0.09804, 0.09804, 
+0.10196, 0.10196, 0.10588, 0.10588, 0.10980, 0.10980, 0.10980, 0.11765, 
+0.11765, 0.12157, 0.12157, 0.12549, 0.12549, 0.12941, 0.12941, 0.13333, 
+0.13725, 0.13725, 0.14118, 0.14118, 0.14510, 0.14510, 0.14902, 0.14902, 
+0.15294, 0.15686, 0.15686, 0.16078, 0.16078, 0.16471, 0.16863, 0.16863, 
+0.17255, 0.17255, 0.17647, 0.18039, 0.18039, 0.18431, 0.18824, 0.18824, 
+0.19608, 0.20000, 0.20000, 0.20392, 0.20784, 0.20784, 0.21176, 0.21569, 
+0.21961, 0.21961, 0.22353, 0.22745, 0.23137, 0.23137, 0.23529, 0.23922, 
+0.24314, 0.24314, 0.24706, 0.25098, 0.25490, 0.25882, 0.26275, 0.26275, 
+0.27059, 0.27451, 0.27843, 0.28235, 0.28627, 0.29020, 0.29412, 0.29804, 
+0.29804, 0.30196, 0.30588, 0.30980, 0.31373, 0.31765, 0.32157, 0.32549, 
+0.33333, 0.33725, 0.34118, 0.34510, 0.34902, 0.35294, 0.35686, 0.36078, 
+0.36471, 0.37255, 0.37647, 0.38039, 0.38431, 0.38824, 0.39216, 0.40000, 
+0.40392, 0.40784, 0.41176, 0.41961, 0.42353, 0.42745, 0.43529, 0.43922, 
+0.44314, 0.45098, 0.45490, 0.45882, 0.46667, 0.47059, 0.47843, 0.48235, 
+0.49020, 0.49412, 0.50196, 0.50588, 0.51373, 0.51765, 0.52549, 0.52941, 
+0.53725, 0.54118, 0.54902, 0.55686, 0.56078, 0.56863, 0.57647, 0.58039, 
+0.58824, 0.59608, 0.60000, 0.60784, 0.61569, 0.62353, 0.63137, 0.63529, 
+0.64314, 0.65098, 0.65882, 0.66667, 0.67451, 0.68235, 0.69020, 0.69804, 
+0.70588, 0.71373, 0.72157, 0.72941, 0.73725, 0.74510, 0.75294, 0.76078, 
+0.77255, 0.78039, 0.78824, 0.79608, 0.80392, 0.81569, 0.82353, 0.83137, 
+0.84314, 0.85098, 0.86275, 0.87059, 0.87843, 0.89020, 0.89804, 0.90980, 
+0.91765, 0.92941, 0.94118, 0.94902, 0.96078, 0.97255, 0.98039, 0.99216
+};
+float rgb_b[256] = {
+0.00000, 1.00000, 0.98039, 0.94510, 0.91373, 0.89020, 0.86275, 0.84314, 
+0.81961, 0.80000, 0.78431, 0.76471, 0.74902, 0.73725, 0.71765, 0.70588, 
+0.69412, 0.68235, 0.66667, 0.65882, 0.64706, 0.63922, 0.62745, 0.61569, 
+0.60784, 0.60000, 0.58824, 0.58039, 0.56863, 0.56471, 0.55686, 0.54902, 
+0.54118, 0.53333, 0.52941, 0.51765, 0.51373, 0.50588, 0.49804, 0.49412, 
+0.49020, 0.48235, 0.47843, 0.46667, 0.46275, 0.45882, 0.45098, 0.44706, 
+0.44314, 0.43922, 0.43529, 0.42745, 0.41961, 0.41569, 0.41176, 0.40784, 
+0.40392, 0.40000, 0.39608, 0.39216, 0.38824, 0.38431, 0.38039, 0.37255, 
+0.36863, 0.36471, 0.36078, 0.35686, 0.35294, 0.34902, 0.34510, 0.34510, 
+0.34118, 0.33725, 0.33333, 0.32941, 0.32157, 0.32157, 0.31765, 0.31373, 
+0.30980, 0.30980, 0.30588, 0.30196, 0.29804, 0.29804, 0.29412, 0.29020, 
+0.28627, 0.28627, 0.28235, 0.27843, 0.27843, 0.27059, 0.26667, 0.26667, 
+0.26275, 0.25882, 0.25882, 0.25490, 0.25490, 0.25098, 0.24706, 0.24706, 
+0.24314, 0.23922, 0.23922, 0.23529, 0.23529, 0.23137, 0.23137, 0.22745, 
+0.21961, 0.21961, 0.21569, 0.21569, 0.21176, 0.21176, 0.20784, 0.20784, 
+0.20392, 0.20392, 0.20000, 0.20000, 0.19608, 0.19608, 0.19216, 0.19216, 
+0.18824, 0.18824, 0.18431, 0.18431, 0.18039, 0.18039, 0.17255, 0.17255, 
+0.16863, 0.16863, 0.16471, 0.16471, 0.16078, 0.16078, 0.16078, 0.15686, 
+0.15686, 0.15294, 0.15294, 0.14902, 0.14902, 0.14510, 0.14510, 0.14510, 
+0.14118, 0.14118, 0.13725, 0.13725, 0.13725, 0.13333, 0.13333, 0.12941, 
+0.12941, 0.12941, 0.12157, 0.12157, 0.11765, 0.11765, 0.11765, 0.11373, 
+0.11373, 0.10980, 0.10980, 0.10980, 0.10588, 0.10588, 0.10588, 0.10196, 
+0.10196, 0.10196, 0.09804, 0.09804, 0.09412, 0.09412, 0.09412, 0.09020, 
+0.09020, 0.09020, 0.08627, 0.08627, 0.08627, 0.08235, 0.08235, 0.08235, 
+0.07843, 0.07843, 0.07843, 0.07059, 0.07059, 0.07059, 0.06667, 0.06667, 
+0.06667, 0.06275, 0.06275, 0.06275, 0.05882, 0.05882, 0.05882, 0.05882, 
+0.05490, 0.05490, 0.05490, 0.05098, 0.05098, 0.05098, 0.04706, 0.04706, 
+0.04706, 0.04314, 0.04314, 0.04314, 0.04314, 0.03922, 0.03922, 0.03922, 
+0.03529, 0.03529, 0.03529, 0.03529, 0.03137, 0.03137, 0.03137, 0.02745, 
+0.02745, 0.02745, 0.02745, 0.01961, 0.01961, 0.01961, 0.01961, 0.01569, 
+0.01569, 0.01569, 0.01176, 0.01176, 0.01176, 0.01176, 0.00784, 0.00784, 
+0.00784, 0.00784, 0.00392, 0.00392, 0.00392, 0.00392, 0.00000, 0.00000
+};
+    for(i=0; i<mNCol; i++) {
+      mycol.red = (rgb_r[i]*65535.); 
+      mycol.green = (rgb_g[i]*65535.); 
+      mycol.blue = (rgb_b[i]*65535.); 
+      AllocColor(mycol, i);      
+    }
+   }
+    break;
+  case CMAP_MIDAS_Heat :      //  heat.lutlis 
+   {
+float rgb_r[256] = {
+0.00000, 0.01176, 0.02353, 0.03529, 0.04706, 0.05882, 0.07059, 0.08235, 
+0.09412, 0.10588, 0.11765, 0.12941, 0.14118, 0.15294, 0.16471, 0.17647, 
+0.18824, 0.20000, 0.21176, 0.22353, 0.23529, 0.24706, 0.25882, 0.27059, 
+0.28235, 0.29412, 0.30588, 0.31765, 0.32941, 0.34118, 0.35294, 0.36471, 
+0.37647, 0.38824, 0.40000, 0.41176, 0.42353, 0.43529, 0.44706, 0.45882, 
+0.47059, 0.48235, 0.49412, 0.50588, 0.51765, 0.52941, 0.54118, 0.55294, 
+0.56471, 0.57647, 0.58824, 0.60000, 0.61176, 0.62353, 0.63529, 0.64706, 
+0.65882, 0.67059, 0.68235, 0.69412, 0.70588, 0.71765, 0.72941, 0.74118, 
+0.75294, 0.76471, 0.77647, 0.78824, 0.80000, 0.81176, 0.82353, 0.83529, 
+0.84706, 0.85882, 0.87059, 0.88235, 0.89412, 0.90588, 0.91765, 0.92941, 
+0.94118, 0.95294, 0.96471, 0.97647, 0.98824, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000
+};
+float rgb_g[256] = {
+0.00000, 0.00392, 0.00784, 0.01176, 0.01569, 0.01961, 0.02353, 0.02745, 
+0.03137, 0.03529, 0.03922, 0.04314, 0.04706, 0.05098, 0.05490, 0.05882, 
+0.06275, 0.06667, 0.07059, 0.07451, 0.07843, 0.08235, 0.08627, 0.09020, 
+0.09412, 0.09804, 0.10196, 0.10588, 0.10980, 0.11373, 0.11765, 0.12157, 
+0.12549, 0.12941, 0.13333, 0.13725, 0.14118, 0.14510, 0.14902, 0.15294, 
+0.15686, 0.16078, 0.16471, 0.16863, 0.17255, 0.17647, 0.18039, 0.18431, 
+0.18824, 0.19216, 0.19608, 0.20000, 0.20392, 0.20784, 0.21176, 0.21569, 
+0.21961, 0.22353, 0.22745, 0.23137, 0.23529, 0.23922, 0.24314, 0.24706, 
+0.25098, 0.25490, 0.25882, 0.26275, 0.26667, 0.27059, 0.27451, 0.27843, 
+0.28235, 0.28627, 0.29020, 0.29412, 0.29804, 0.30196, 0.30588, 0.30980, 
+0.31373, 0.31765, 0.32157, 0.32549, 0.32941, 0.33333, 0.33725, 0.34118, 
+0.34510, 0.34902, 0.35294, 0.35686, 0.36078, 0.36471, 0.36863, 0.37255, 
+0.37647, 0.38039, 0.38431, 0.38824, 0.39216, 0.39608, 0.40000, 0.40392, 
+0.40784, 0.41176, 0.41569, 0.41961, 0.42353, 0.42745, 0.43137, 0.43529, 
+0.43922, 0.44314, 0.44706, 0.45098, 0.45490, 0.45882, 0.46275, 0.46667, 
+0.47059, 0.47451, 0.47843, 0.48235, 0.48627, 0.49020, 0.49412, 0.49804, 
+0.50196, 0.50588, 0.50980, 0.51373, 0.51765, 0.52157, 0.52549, 0.52941, 
+0.53333, 0.53725, 0.54118, 0.54510, 0.54902, 0.55294, 0.55686, 0.56078, 
+0.56471, 0.56863, 0.57255, 0.57647, 0.58039, 0.58431, 0.58824, 0.59216, 
+0.59608, 0.60000, 0.60392, 0.60784, 0.61176, 0.61569, 0.61961, 0.62353, 
+0.62745, 0.63137, 0.63529, 0.63922, 0.64314, 0.64706, 0.65098, 0.65490, 
+0.65882, 0.66275, 0.66667, 0.67059, 0.67451, 0.67843, 0.68235, 0.68627, 
+0.69020, 0.69412, 0.69804, 0.70196, 0.70588, 0.70980, 0.71373, 0.71765, 
+0.72157, 0.72549, 0.72941, 0.73333, 0.73725, 0.74118, 0.74510, 0.74902, 
+0.75294, 0.75686, 0.76078, 0.76471, 0.76863, 0.77255, 0.77647, 0.78039, 
+0.78431, 0.78824, 0.79216, 0.79608, 0.80000, 0.80392, 0.80784, 0.81176, 
+0.81569, 0.81961, 0.82353, 0.82745, 0.83137, 0.83529, 0.83922, 0.84314, 
+0.84706, 0.85098, 0.85490, 0.85882, 0.86275, 0.86667, 0.87059, 0.87451, 
+0.87843, 0.88235, 0.88627, 0.89020, 0.89412, 0.89804, 0.90196, 0.90588, 
+0.90980, 0.91373, 0.91765, 0.92157, 0.92549, 0.92941, 0.93333, 0.93725, 
+0.94118, 0.94510, 0.94902, 0.95294, 0.95686, 0.96078, 0.96471, 0.96863, 
+0.97255, 0.97647, 0.98039, 0.98431, 0.98824, 0.99216, 0.99608, 1.00000
+};
+float rgb_b[256] = {
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.01176, 0.02353, 
+0.03529, 0.04706, 0.05882, 0.07059, 0.08235, 0.09412, 0.10588, 0.11765, 
+0.12941, 0.14118, 0.15294, 0.16471, 0.17647, 0.18824, 0.20000, 0.21176, 
+0.22353, 0.23529, 0.24706, 0.25882, 0.27059, 0.28235, 0.29412, 0.30588, 
+0.31765, 0.32941, 0.34118, 0.35294, 0.36471, 0.37647, 0.38824, 0.40000, 
+0.41176, 0.42353, 0.43529, 0.44706, 0.45882, 0.47059, 0.48235, 0.49412, 
+0.50588, 0.51765, 0.52941, 0.54118, 0.55294, 0.56471, 0.57647, 0.58824, 
+0.60000, 0.61176, 0.62353, 0.63529, 0.64706, 0.65882, 0.67059, 0.68235, 
+0.69412, 0.70588, 0.71765, 0.72941, 0.74118, 0.75294, 0.76471, 0.77647, 
+0.78824, 0.80000, 0.81176, 0.82353, 0.83529, 0.84706, 0.85882, 0.87059, 
+0.88235, 0.89412, 0.90588, 0.91765, 0.92941, 0.94118, 0.95294, 0.96471, 
+0.97647, 0.98824, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000
+};
+    for(i=0; i<mNCol; i++) {
+      mycol.red = (rgb_r[i]*65535.); 
+      mycol.green = (rgb_g[i]*65535.); 
+      mycol.blue = (rgb_b[i]*65535.); 
+      AllocColor(mycol, i);      
+    }
+   }
+    break;
+  case CMAP_MIDAS_Rainbow3 :  //  rainbow3.lutlis
+   {
+float rgb_r[256] = {
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.04706, 0.09412, 0.14118, 0.18824, 0.23529, 0.28235, 0.32941, 
+0.37647, 0.42353, 0.47059, 0.51765, 0.56471, 0.61176, 0.65882, 0.70588, 
+0.72549, 0.74510, 0.76471, 0.78431, 0.80392, 0.82353, 0.84314, 0.86275, 
+0.88235, 0.90196, 0.92157, 0.94118, 0.96078, 0.98039, 1.00000, 0.99608, 
+0.99608, 0.99608, 0.99608, 0.99608, 0.99216, 0.99216, 0.99216, 0.99216, 
+0.99216, 0.98824, 0.98824, 0.98824, 0.98824, 0.98824, 0.98824, 0.98824, 
+0.98824, 0.98824, 0.99216, 0.99216, 0.99216, 0.99216, 0.99216, 0.99608, 
+0.99608, 0.99608, 0.99608, 0.99608, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000
+};
+float rgb_g[256] = {
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.03137, 0.06275, 
+0.09412, 0.12549, 0.15686, 0.18824, 0.21961, 0.25490, 0.28627, 0.31765, 
+0.34902, 0.38039, 0.41176, 0.44314, 0.47843, 0.49804, 0.51765, 0.53725, 
+0.55686, 0.58039, 0.60000, 0.61961, 0.63922, 0.65882, 0.68235, 0.70196, 
+0.72157, 0.74118, 0.76078, 0.78431, 0.79608, 0.81176, 0.82745, 0.83922, 
+0.85490, 0.87059, 0.88235, 0.89804, 0.91373, 0.92549, 0.94118, 0.95686, 
+0.96863, 0.98431, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 0.98039, 
+0.96078, 0.94510, 0.92549, 0.90588, 0.89020, 0.87059, 0.85098, 0.83529, 
+0.81569, 0.79608, 0.78039, 0.76078, 0.74118, 0.72549, 0.70588, 0.69020, 
+0.67451, 0.65490, 0.63922, 0.62353, 0.60392, 0.58824, 0.57255, 0.55294, 
+0.53725, 0.52157, 0.50196, 0.48627, 0.47059, 0.43922, 0.40784, 0.37647, 
+0.34510, 0.31373, 0.28235, 0.25098, 0.21569, 0.18431, 0.15294, 0.12157, 
+0.09020, 0.05882, 0.02745, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.03529, 
+0.07059, 0.10588, 0.14118, 0.18039, 0.21569, 0.25098, 0.28627, 0.32549, 
+0.36078, 0.39608, 0.43137, 0.47059, 0.48627, 0.50588, 0.52157, 0.54118, 
+0.56078, 0.57647, 0.59608, 0.61176, 0.63137, 0.65098, 0.66667, 0.68627, 
+0.70588, 0.74510, 0.78824, 0.83137, 0.87059, 0.91373, 0.95686, 1.00000
+};
+float rgb_b[256] = {
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.03922, 0.07843, 0.11765, 
+0.15686, 0.20000, 0.23922, 0.27843, 0.31765, 0.35686, 0.40000, 0.43922, 
+0.47843, 0.51765, 0.55686, 0.60000, 0.63922, 0.67843, 0.71765, 0.75686, 
+0.80000, 0.83922, 0.87843, 0.91765, 0.95686, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 0.98039, 0.96078, 0.94118, 0.92157, 0.90196, 
+0.88235, 0.86275, 0.84314, 0.82353, 0.80392, 0.78431, 0.76471, 0.74510, 
+0.72549, 0.70588, 0.65882, 0.61176, 0.56471, 0.51765, 0.47059, 0.42353, 
+0.37647, 0.32549, 0.27843, 0.23137, 0.18431, 0.13725, 0.09020, 0.04314, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.04706, 0.09412, 0.14118, 0.18824, 0.23529, 
+0.28235, 0.32941, 0.37647, 0.42353, 0.47059, 0.51765, 0.56471, 0.61176, 
+0.65882, 0.70588, 0.72549, 0.74902, 0.77255, 0.79608, 0.81569, 0.83922, 
+0.86275, 0.88627, 0.90588, 0.92941, 0.95294, 0.97647, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000
+};
+    for(i=0; i<mNCol; i++) {
+      mycol.red = (rgb_r[i]*65535.); 
+      mycol.green = (rgb_g[i]*65535.); 
+      mycol.blue = (rgb_b[i]*65535.); 
+      AllocColor(mycol, i);      
+    }
+   }
+    break;
+  case CMAP_MIDAS_BlueRed :   //   idl11.lutlis
+   {
+float rgb_r[256] = {
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.01569, 0.03137, 0.04706, 0.06275, 0.07843, 0.09412, 0.10980, 
+0.12549, 0.14118, 0.15686, 0.17255, 0.18824, 0.20392, 0.21961, 0.23529, 
+0.25098, 0.26667, 0.28235, 0.29804, 0.31373, 0.33333, 0.34902, 0.36471, 
+0.38039, 0.39608, 0.41176, 0.42745, 0.44314, 0.45882, 0.47451, 0.49020, 
+0.50588, 0.52157, 0.53725, 0.55294, 0.56863, 0.58431, 0.60000, 0.61569, 
+0.63137, 0.64706, 0.66667, 0.68235, 0.69804, 0.71373, 0.72941, 0.74510, 
+0.76078, 0.77647, 0.79216, 0.80784, 0.82353, 0.83922, 0.85490, 0.87059, 
+0.88627, 0.90196, 0.91765, 0.93333, 0.94902, 0.96471, 0.98039, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000
+};
+float rgb_g[256] = {
+0.00000, 0.00392, 0.00784, 0.01176, 0.01569, 0.03137, 0.04706, 0.06275, 
+0.08235, 0.09804, 0.11373, 0.12941, 0.14902, 0.16471, 0.18039, 0.19608, 
+0.21569, 0.23137, 0.24706, 0.26275, 0.28235, 0.29804, 0.31373, 0.32941, 
+0.34902, 0.36471, 0.38039, 0.39608, 0.41569, 0.43137, 0.44706, 0.46275, 
+0.48235, 0.49804, 0.51373, 0.52941, 0.54902, 0.56471, 0.58039, 0.59608, 
+0.61569, 0.63137, 0.64706, 0.66275, 0.68235, 0.69804, 0.71373, 0.72941, 
+0.74902, 0.76471, 0.78039, 0.79608, 0.81569, 0.83137, 0.84706, 0.86275, 
+0.88235, 0.89804, 0.91373, 0.92941, 0.94902, 0.96471, 0.98039, 1.00000, 
+1.00000, 0.98431, 0.96863, 0.95294, 0.93725, 0.92157, 0.90588, 0.89020, 
+0.87451, 0.85882, 0.84314, 0.82745, 0.81176, 0.79608, 0.78039, 0.76471, 
+0.74902, 0.73333, 0.71765, 0.70196, 0.68627, 0.66667, 0.65098, 0.63529, 
+0.61961, 0.60392, 0.58824, 0.57255, 0.55686, 0.54118, 0.52549, 0.50980, 
+0.49412, 0.47843, 0.46275, 0.44706, 0.43137, 0.41569, 0.40000, 0.38431, 
+0.36863, 0.35294, 0.33333, 0.31765, 0.30196, 0.28627, 0.27059, 0.25490, 
+0.23922, 0.22353, 0.20784, 0.19216, 0.17647, 0.16078, 0.14510, 0.12941, 
+0.11373, 0.09804, 0.08235, 0.06667, 0.05098, 0.03529, 0.01961, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000
+};
+float rgb_b[256] = {
+0.00000, 0.00392, 0.00784, 0.01176, 0.01569, 0.03137, 0.04706, 0.06275, 
+0.08235, 0.09804, 0.11373, 0.12941, 0.14902, 0.16471, 0.18039, 0.19608, 
+0.21569, 0.23137, 0.24706, 0.26275, 0.28235, 0.29804, 0.31373, 0.32941, 
+0.34902, 0.36471, 0.38039, 0.39608, 0.41569, 0.43137, 0.44706, 0.46275, 
+0.48235, 0.49804, 0.51373, 0.52941, 0.54902, 0.56471, 0.58039, 0.59608, 
+0.61569, 0.63137, 0.64706, 0.66275, 0.68235, 0.69804, 0.71373, 0.72941, 
+0.74902, 0.76471, 0.78039, 0.79608, 0.81569, 0.83137, 0.84706, 0.86275, 
+0.88235, 0.89804, 0.91373, 0.92941, 0.94902, 0.96471, 0.98039, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 0.98431, 0.96863, 0.95294, 0.93725, 0.92157, 0.90588, 0.89020, 
+0.87451, 0.85490, 0.83922, 0.82353, 0.80784, 0.79216, 0.77647, 0.76078, 
+0.74510, 0.72941, 0.70980, 0.69412, 0.67843, 0.66275, 0.64706, 0.63137, 
+0.61569, 0.60000, 0.58431, 0.56471, 0.54902, 0.53333, 0.51765, 0.50196, 
+0.48627, 0.47059, 0.45490, 0.43922, 0.41961, 0.40392, 0.38824, 0.37255, 
+0.35686, 0.34118, 0.32549, 0.30980, 0.29412, 0.27451, 0.25882, 0.24314, 
+0.22745, 0.21176, 0.19608, 0.18039, 0.16471, 0.14902, 0.12941, 0.11373, 
+0.09804, 0.08235, 0.06667, 0.05098, 0.03529, 0.01961, 0.00000, 0.00000
+};
+    for(i=0; i<mNCol; i++) {
+      mycol.red = (rgb_r[i]*65535.); 
+      mycol.green = (rgb_g[i]*65535.); 
+      mycol.blue = (rgb_b[i]*65535.); 
+      AllocColor(mycol, i);      
+    }
+   }
+    break;
+  case CMAP_MIDAS_BlueWhite : //    blulut.lutlis
+   {
+float rgb_r[256] = {
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00001, 0.00001, 0.00001, 
+0.00002, 0.00002, 0.00002, 0.00003, 0.00004, 0.00005, 0.00006, 0.00007, 
+0.00008, 0.00009, 0.00011, 0.00013, 0.00015, 0.00017, 0.00019, 0.00022, 
+0.00025, 0.00028, 0.00032, 0.00035, 0.00040, 0.00044, 0.00049, 0.00055, 
+0.00061, 0.00067, 0.00074, 0.00081, 0.00089, 0.00097, 0.00106, 0.00115, 
+0.00126, 0.00136, 0.00148, 0.00160, 0.00173, 0.00187, 0.00201, 0.00216, 
+0.00233, 0.00250, 0.00268, 0.00287, 0.00307, 0.00327, 0.00349, 0.00373, 
+0.00397, 0.00422, 0.00449, 0.00477, 0.00506, 0.00536, 0.00568, 0.00601, 
+0.00636, 0.00672, 0.00709, 0.00748, 0.00789, 0.00831, 0.00875, 0.00921, 
+0.00969, 0.01018, 0.01069, 0.01122, 0.01177, 0.01235, 0.01294, 0.01355, 
+0.01418, 0.01484, 0.01552, 0.01622, 0.01694, 0.01769, 0.01847, 0.01926, 
+0.02009, 0.02094, 0.02181, 0.02272, 0.02365, 0.02461, 0.02560, 0.02662, 
+0.02767, 0.02875, 0.02986, 0.03100, 0.03218, 0.03338, 0.03463, 0.03590, 
+0.03721, 0.03856, 0.03994, 0.04136, 0.04282, 0.04432, 0.04585, 0.04743, 
+0.04904, 0.05070, 0.05239, 0.05413, 0.05591, 0.05774, 0.05961, 0.06153, 
+0.06349, 0.06549, 0.06755, 0.06965, 0.07180, 0.07400, 0.07625, 0.07856, 
+0.08091, 0.08331, 0.08577, 0.08829, 0.09086, 0.09348, 0.09616, 0.09890, 
+0.10169, 0.10455, 0.10746, 0.11044, 0.11347, 0.11657, 0.11973, 0.12296, 
+0.12624, 0.12960, 0.13302, 0.13651, 0.14007, 0.14369, 0.14739, 0.15116, 
+0.15500, 0.15891, 0.16289, 0.16695, 0.17109, 0.17530, 0.17959, 0.18395, 
+0.18840, 0.19292, 0.19753, 0.20222, 0.20699, 0.21185, 0.21679, 0.22182, 
+0.22693, 0.23213, 0.23742, 0.24280, 0.24827, 0.25384, 0.25949, 0.26524, 
+0.27109, 0.27703, 0.28307, 0.28920, 0.29544, 0.30178, 0.30821, 0.31476, 
+0.32140, 0.32815, 0.33500, 0.34196, 0.34903, 0.35621, 0.36350, 0.37090, 
+0.37841, 0.38603, 0.39377, 0.40163, 0.40960, 0.41769, 0.42590, 0.43423, 
+0.44268, 0.45126, 0.45996, 0.46878, 0.47773, 0.48681, 0.49601, 0.50535, 
+0.51482, 0.52442, 0.53415, 0.54402, 0.55403, 0.56417, 0.57445, 0.58487, 
+0.59543, 0.60613, 0.61698, 0.62798, 0.63911, 0.65040, 0.66184, 0.67342, 
+0.68516, 0.69705, 0.70909, 0.72129, 0.73365, 0.74616, 0.75883, 0.77167, 
+0.78466, 0.79782, 0.81115, 0.82464, 0.83830, 0.85213, 0.86612, 0.88029, 
+0.89464, 0.90915, 0.92385, 0.93872, 0.95377, 0.96899, 0.98441, 1.00000
+};
+float rgb_g[256] = {
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00001, 0.00001, 0.00001, 
+0.00002, 0.00002, 0.00002, 0.00003, 0.00004, 0.00005, 0.00006, 0.00007, 
+0.00008, 0.00009, 0.00011, 0.00013, 0.00015, 0.00017, 0.00019, 0.00022, 
+0.00025, 0.00028, 0.00032, 0.00035, 0.00040, 0.00044, 0.00049, 0.00055, 
+0.00061, 0.00067, 0.00074, 0.00081, 0.00089, 0.00097, 0.00106, 0.00115, 
+0.00126, 0.00136, 0.00148, 0.00160, 0.00173, 0.00187, 0.00201, 0.00216, 
+0.00233, 0.00250, 0.00268, 0.00287, 0.00307, 0.00327, 0.00349, 0.00373, 
+0.00397, 0.00422, 0.00449, 0.00477, 0.00506, 0.00536, 0.00568, 0.00601, 
+0.00636, 0.00672, 0.00709, 0.00748, 0.00789, 0.00831, 0.00875, 0.00921, 
+0.00969, 0.01018, 0.01069, 0.01122, 0.01177, 0.01235, 0.01294, 0.01355, 
+0.01418, 0.01484, 0.01552, 0.01622, 0.01694, 0.01769, 0.01847, 0.01926, 
+0.02009, 0.02094, 0.02181, 0.02272, 0.02365, 0.02461, 0.02560, 0.02662, 
+0.02767, 0.02875, 0.02986, 0.03100, 0.03218, 0.03338, 0.03463, 0.03590, 
+0.03721, 0.03856, 0.03994, 0.04136, 0.04282, 0.04432, 0.04585, 0.04743, 
+0.04904, 0.05070, 0.05239, 0.05413, 0.05591, 0.05774, 0.05961, 0.06153, 
+0.06349, 0.06549, 0.06755, 0.06965, 0.07180, 0.07400, 0.07625, 0.07856, 
+0.08091, 0.08331, 0.08577, 0.08829, 0.09086, 0.09348, 0.09616, 0.09890, 
+0.10169, 0.10455, 0.10746, 0.11044, 0.11347, 0.11657, 0.11973, 0.12296, 
+0.12624, 0.12960, 0.13302, 0.13651, 0.14007, 0.14369, 0.14739, 0.15116, 
+0.15500, 0.15891, 0.16289, 0.16695, 0.17109, 0.17530, 0.17959, 0.18395, 
+0.18840, 0.19292, 0.19753, 0.20222, 0.20699, 0.21185, 0.21679, 0.22182, 
+0.22693, 0.23213, 0.23742, 0.24280, 0.24827, 0.25384, 0.25949, 0.26524, 
+0.27109, 0.27703, 0.28307, 0.28920, 0.29544, 0.30178, 0.30821, 0.31476, 
+0.32140, 0.32815, 0.33500, 0.34196, 0.34903, 0.35621, 0.36350, 0.37090, 
+0.37841, 0.38603, 0.39377, 0.40163, 0.40960, 0.41769, 0.42590, 0.43423, 
+0.44268, 0.45126, 0.45996, 0.46878, 0.47773, 0.48681, 0.49601, 0.50535, 
+0.51482, 0.52442, 0.53415, 0.54402, 0.55403, 0.56417, 0.57445, 0.58487, 
+0.59543, 0.60613, 0.61698, 0.62798, 0.63911, 0.65040, 0.66184, 0.67342, 
+0.68516, 0.69705, 0.70909, 0.72129, 0.73365, 0.74616, 0.75883, 0.77167, 
+0.78466, 0.79782, 0.81115, 0.82464, 0.83830, 0.85213, 0.86612, 0.88029, 
+0.89464, 0.90915, 0.92385, 0.93872, 0.95377, 0.96899, 0.98441, 1.00000
+};
+float rgb_b[256] = {
+0.00000, 0.00392, 0.00784, 0.01176, 0.01569, 0.01961, 0.02353, 0.02745, 
+0.03137, 0.03529, 0.03922, 0.04314, 0.04706, 0.05098, 0.05490, 0.05882, 
+0.06275, 0.06667, 0.07059, 0.07451, 0.07843, 0.08235, 0.08627, 0.09020, 
+0.09412, 0.09804, 0.10196, 0.10588, 0.10980, 0.11373, 0.11765, 0.12157, 
+0.12549, 0.12941, 0.13333, 0.13725, 0.14118, 0.14510, 0.14902, 0.15294, 
+0.15686, 0.16078, 0.16471, 0.16863, 0.17255, 0.17647, 0.18039, 0.18431, 
+0.18824, 0.19216, 0.19608, 0.20000, 0.20392, 0.20784, 0.21176, 0.21569, 
+0.21961, 0.22353, 0.22745, 0.23137, 0.23529, 0.23922, 0.24314, 0.24706, 
+0.25098, 0.25490, 0.25882, 0.26275, 0.26667, 0.27059, 0.27451, 0.27843, 
+0.28235, 0.28627, 0.29020, 0.29412, 0.29804, 0.30196, 0.30588, 0.30980, 
+0.31373, 0.31765, 0.32157, 0.32549, 0.32941, 0.33333, 0.33725, 0.34118, 
+0.34510, 0.34902, 0.35294, 0.35686, 0.36078, 0.36471, 0.36863, 0.37255, 
+0.37647, 0.38039, 0.38431, 0.38824, 0.39216, 0.39608, 0.40000, 0.40392, 
+0.40784, 0.41176, 0.41569, 0.41961, 0.42353, 0.42745, 0.43137, 0.43529, 
+0.43922, 0.44314, 0.44706, 0.45098, 0.45490, 0.45882, 0.46275, 0.46667, 
+0.47059, 0.47451, 0.47843, 0.48235, 0.48627, 0.49020, 0.49412, 0.49804, 
+0.50196, 0.50588, 0.50980, 0.51373, 0.51765, 0.52157, 0.52549, 0.52941, 
+0.53333, 0.53725, 0.54118, 0.54510, 0.54902, 0.55294, 0.55686, 0.56078, 
+0.56471, 0.56863, 0.57255, 0.57647, 0.58039, 0.58431, 0.58824, 0.59216, 
+0.59608, 0.60000, 0.60392, 0.60784, 0.61176, 0.61569, 0.61961, 0.62353, 
+0.62745, 0.63137, 0.63529, 0.63922, 0.64314, 0.64706, 0.65098, 0.65490, 
+0.65882, 0.66275, 0.66667, 0.67059, 0.67451, 0.67843, 0.68235, 0.68627, 
+0.69020, 0.69412, 0.69804, 0.70196, 0.70588, 0.70980, 0.71373, 0.71765, 
+0.72157, 0.72549, 0.72941, 0.73333, 0.73725, 0.74118, 0.74510, 0.74902, 
+0.75294, 0.75686, 0.76078, 0.76471, 0.76863, 0.77255, 0.77647, 0.78039, 
+0.78431, 0.78824, 0.79216, 0.79608, 0.80000, 0.80392, 0.80784, 0.81176, 
+0.81569, 0.81961, 0.82353, 0.82745, 0.83137, 0.83529, 0.83922, 0.84314, 
+0.84706, 0.85098, 0.85490, 0.85882, 0.86275, 0.86667, 0.87059, 0.87451, 
+0.87843, 0.88235, 0.88627, 0.89020, 0.89412, 0.89804, 0.90196, 0.90588, 
+0.90980, 0.91373, 0.91765, 0.92157, 0.92549, 0.92941, 0.93333, 0.93725, 
+0.94118, 0.94510, 0.94902, 0.95294, 0.95686, 0.96078, 0.96471, 0.96863, 
+0.97255, 0.97647, 0.98039, 0.98431, 0.98824, 0.99216, 0.99608, 1.00000
+};
+    for(i=0; i<mNCol; i++) {
+      mycol.red = (rgb_r[i]*65535.); 
+      mycol.green = (rgb_g[i]*65535.); 
+      mycol.blue = (rgb_b[i]*65535.); 
+      AllocColor(mycol, i);      
+    }
+   }
+    break;
+  case CMAP_MIDAS_Stairs8 :  //  stairs8.lutlis
+   {
+float rgb_r[256] = {
+0.76471, 0.76471, 0.76471, 0.76471, 0.76471, 0.76471, 0.76471, 0.76471, 
+0.76471, 0.76471, 0.76471, 0.76471, 0.76471, 0.76471, 0.76471, 0.76471, 
+0.76471, 0.76471, 0.76471, 0.76471, 0.76471, 0.76471, 0.76471, 0.76471, 
+0.76471, 0.76471, 0.76471, 0.76471, 0.76471, 0.76471, 0.76471, 0.76471, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000
+};
+float rgb_g[256] = {
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 
+0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 
+0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 
+0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000
+};
+float rgb_b[256] = {
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000
+};
+    for(i=0; i<mNCol; i++) {
+      mycol.red = (rgb_r[i]*65535.); 
+      mycol.green = (rgb_g[i]*65535.); 
+      mycol.blue = (rgb_b[i]*65535.); 
+      AllocColor(mycol, i);      
+    }
+   }
+    break;
+  case CMAP_MIDAS_Stairs9 :  //    stairs9.lutlis
+   {
+float rgb_r[256] = {
+0.00000, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 
+0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 
+0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 
+0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 
+0.60784, 0.60784, 0.60784, 0.60784, 0.60784, 0.60784, 0.60784, 0.60784, 
+0.60784, 0.60784, 0.60784, 0.60784, 0.60784, 0.60784, 0.60784, 0.60784, 
+0.60784, 0.60784, 0.60784, 0.60784, 0.60784, 0.60784, 0.60784, 0.60784, 
+0.60784, 0.60784, 0.60784, 0.60784, 0.78431, 0.78431, 0.78431, 0.78431, 
+0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 
+0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 
+0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 
+0.92549, 0.92549, 0.92549, 0.92549, 0.92549, 0.92549, 0.92549, 0.92549, 
+0.92549, 0.92549, 0.92549, 0.92549, 0.92549, 0.92549, 0.92549, 0.92549, 
+0.92549, 0.92549, 0.92549, 0.92549, 0.92549, 0.92549, 0.92549, 0.92549, 
+0.92549, 0.92549, 0.92549, 0.92549, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000
+};
+float rgb_g[256] = {
+0.00000, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 
+0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 
+0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 
+0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.65490, 0.65490, 0.65490, 0.65490, 0.65490, 0.65490, 0.65490, 0.65490, 
+0.65490, 0.65490, 0.65490, 0.65490, 0.65490, 0.65490, 0.65490, 0.65490, 
+0.65490, 0.65490, 0.65490, 0.65490, 0.65490, 0.65490, 0.65490, 0.65490, 
+0.65490, 0.65490, 0.65490, 0.65490, 0.56863, 0.56863, 0.56863, 0.56863, 
+0.56863, 0.56863, 0.56863, 0.56863, 0.56863, 0.56863, 0.56863, 0.56863, 
+0.56863, 0.56863, 0.56863, 0.56863, 0.56863, 0.56863, 0.56863, 0.56863, 
+0.56863, 0.56863, 0.56863, 0.56863, 0.56863, 0.56863, 0.56863, 0.56863, 
+0.96471, 0.96471, 0.96471, 0.96471, 0.96471, 0.96471, 0.96471, 0.96471, 
+0.96471, 0.96471, 0.96471, 0.96471, 0.96471, 0.96471, 0.96471, 0.96471, 
+0.96471, 0.96471, 0.96471, 0.96471, 0.96471, 0.96471, 0.96471, 0.96471, 
+0.96471, 0.96471, 0.96471, 0.96471, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+0.69412, 0.69412, 0.69412, 0.69412, 0.69412, 0.69412, 0.69412, 0.69412, 
+0.69412, 0.69412, 0.69412, 0.69412, 0.69412, 0.69412, 0.69412, 0.69412, 
+0.69412, 0.69412, 0.69412, 0.69412, 0.69412, 0.69412, 0.69412, 0.69412, 
+0.69412, 0.69412, 0.69412, 0.69412, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000
+};
+float rgb_b[256] = {
+0.00000, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 
+0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 
+0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 
+0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 0.19608, 
+0.47451, 0.47451, 0.47451, 0.47451, 0.47451, 0.47451, 0.47451, 0.47451, 
+0.47451, 0.47451, 0.47451, 0.47451, 0.47451, 0.47451, 0.47451, 0.47451, 
+0.47451, 0.47451, 0.47451, 0.47451, 0.47451, 0.47451, 0.47451, 0.47451, 
+0.47451, 0.47451, 0.47451, 0.47451, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 
+0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 
+0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 
+0.37255, 0.37255, 0.37255, 0.37255, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000
+};
+    for(i=0; i<mNCol; i++) {
+      mycol.red = (rgb_r[i]*65535.); 
+      mycol.green = (rgb_g[i]*65535.); 
+      mycol.blue = (rgb_b[i]*65535.); 
+      AllocColor(mycol, i);      
+    }
+   }
+    break;
+  case CMAP_MIDAS_StairCase :  //    staircase.lutlis
+   {
+float rgb_r[256] = {
+0.00392, 0.00784, 0.01176, 0.01569, 0.01961, 0.02353, 0.02745, 0.03137, 
+0.03529, 0.03922, 0.04314, 0.04706, 0.05098, 0.05490, 0.05882, 0.06275, 
+0.06667, 0.07059, 0.07451, 0.07843, 0.08235, 0.08627, 0.09020, 0.09412, 
+0.09804, 0.10196, 0.10588, 0.10980, 0.11373, 0.11765, 0.12157, 0.12549, 
+0.12941, 0.13333, 0.13725, 0.14118, 0.14510, 0.14902, 0.15294, 0.15686, 
+0.16078, 0.16471, 0.16863, 0.17255, 0.17647, 0.18039, 0.18431, 0.18824, 
+0.19216, 0.19608, 0.20000, 0.20392, 0.20784, 0.21176, 0.21569, 0.21961, 
+0.22353, 0.22745, 0.23137, 0.23529, 0.23922, 0.24314, 0.24706, 0.25098, 
+0.25490, 0.25882, 0.26275, 0.26667, 0.27059, 0.27451, 0.27843, 0.28235, 
+0.28627, 0.29020, 0.29412, 0.29804, 0.30196, 0.30588, 0.30980, 0.31373, 
+0.31765, 0.32157, 0.32549, 0.32941, 0.33333, 0.00392, 0.00784, 0.01176, 
+0.01569, 0.01961, 0.02353, 0.02745, 0.03137, 0.03529, 0.03922, 0.04314, 
+0.04706, 0.05098, 0.05490, 0.05882, 0.06275, 0.06667, 0.07059, 0.07451, 
+0.07843, 0.08235, 0.08627, 0.09020, 0.09412, 0.09804, 0.10196, 0.10588, 
+0.10980, 0.11373, 0.11765, 0.12157, 0.12549, 0.12941, 0.13333, 0.13725, 
+0.14118, 0.14510, 0.14902, 0.15294, 0.15686, 0.16078, 0.16471, 0.16863, 
+0.17255, 0.17647, 0.18039, 0.18431, 0.18824, 0.19216, 0.19608, 0.20000, 
+0.20392, 0.20784, 0.21176, 0.21569, 0.21961, 0.22353, 0.22745, 0.23137, 
+0.23529, 0.23922, 0.24314, 0.24706, 0.25098, 0.25490, 0.25882, 0.26275, 
+0.26667, 0.27059, 0.27451, 0.27843, 0.28235, 0.28627, 0.29020, 0.29412, 
+0.29804, 0.30196, 0.30588, 0.30980, 0.31373, 0.31765, 0.32157, 0.32549, 
+0.32941, 0.33333, 0.31373, 0.31373, 0.31373, 0.31373, 0.31373, 0.31373, 
+0.31373, 0.31373, 0.31373, 0.31373, 0.31373, 0.31373, 0.31373, 0.31373, 
+0.31373, 0.31373, 0.47059, 0.47059, 0.47059, 0.47059, 0.47059, 0.47059, 
+0.47059, 0.47059, 0.47059, 0.47059, 0.47059, 0.47059, 0.47059, 0.47059, 
+0.47059, 0.47059, 0.62745, 0.62745, 0.62745, 0.62745, 0.62745, 0.62745, 
+0.62745, 0.62745, 0.62745, 0.62745, 0.62745, 0.62745, 0.62745, 0.62745, 
+0.62745, 0.62745, 0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 
+0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 
+0.78431, 0.78431, 0.94118, 0.94118, 0.94118, 0.94118, 0.94118, 0.94118, 
+0.94118, 0.94118, 0.94118, 0.94118, 0.94118, 0.94118, 0.94118, 0.94118, 
+0.94118, 0.94118, 0.94902, 0.96078, 0.97255, 0.98431, 0.99216, 1.00000
+};
+float rgb_g[256] = {
+0.00392, 0.00784, 0.01176, 0.01569, 0.01961, 0.02353, 0.02745, 0.03137, 
+0.03529, 0.03922, 0.04314, 0.04706, 0.05098, 0.05490, 0.05882, 0.06275, 
+0.06667, 0.07059, 0.07451, 0.07843, 0.08235, 0.08627, 0.09020, 0.09412, 
+0.09804, 0.10196, 0.10588, 0.10980, 0.11373, 0.11765, 0.12157, 0.12549, 
+0.12941, 0.13333, 0.13725, 0.14118, 0.14510, 0.14902, 0.15294, 0.15686, 
+0.16078, 0.16471, 0.16863, 0.17255, 0.17647, 0.18039, 0.18431, 0.18824, 
+0.19216, 0.19608, 0.20000, 0.20392, 0.20784, 0.21176, 0.21569, 0.21961, 
+0.22353, 0.22745, 0.23137, 0.23529, 0.23922, 0.24314, 0.24706, 0.25098, 
+0.25490, 0.25882, 0.26275, 0.26667, 0.27059, 0.27451, 0.27843, 0.28235, 
+0.28627, 0.29020, 0.29412, 0.29804, 0.30196, 0.30588, 0.30980, 0.31373, 
+0.31765, 0.32157, 0.32549, 0.32941, 0.33333, 0.31373, 0.31373, 0.31373, 
+0.31373, 0.31373, 0.31373, 0.31373, 0.31373, 0.31373, 0.31373, 0.31373, 
+0.31373, 0.31373, 0.31373, 0.31373, 0.31373, 0.47059, 0.47059, 0.47059, 
+0.47059, 0.47059, 0.47059, 0.47059, 0.47059, 0.47059, 0.47059, 0.47059, 
+0.47059, 0.47059, 0.47059, 0.47059, 0.47059, 0.62745, 0.62745, 0.62745, 
+0.62745, 0.62745, 0.62745, 0.62745, 0.62745, 0.62745, 0.62745, 0.62745, 
+0.62745, 0.62745, 0.62745, 0.62745, 0.62745, 0.78431, 0.78431, 0.78431, 
+0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 
+0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 0.94118, 0.94118, 0.94118, 
+0.94118, 0.94118, 0.94118, 0.94118, 0.94118, 0.94118, 0.94118, 0.94118, 
+0.94118, 0.94118, 0.94118, 0.94118, 0.94118, 0.95294, 0.96471, 0.97647, 
+0.98824, 1.00000, 0.00392, 0.00784, 0.01176, 0.01569, 0.01961, 0.02353, 
+0.02745, 0.03137, 0.03529, 0.03922, 0.04314, 0.04706, 0.05098, 0.05490, 
+0.05882, 0.06275, 0.06667, 0.07059, 0.07451, 0.07843, 0.08235, 0.08627, 
+0.09020, 0.09412, 0.09804, 0.10196, 0.10588, 0.10980, 0.11373, 0.11765, 
+0.12157, 0.12549, 0.12941, 0.13333, 0.13725, 0.14118, 0.14510, 0.14902, 
+0.15294, 0.15686, 0.16078, 0.16471, 0.16863, 0.17255, 0.17647, 0.18039, 
+0.18431, 0.18824, 0.19216, 0.19608, 0.20000, 0.20392, 0.20784, 0.21176, 
+0.21569, 0.21961, 0.22353, 0.22745, 0.23137, 0.23529, 0.23922, 0.24314, 
+0.24706, 0.25098, 0.25490, 0.25882, 0.26275, 0.26667, 0.27059, 0.27451, 
+0.27843, 0.28235, 0.28627, 0.29020, 0.29412, 0.29804, 0.30196, 0.30588, 
+0.30980, 0.31373, 0.39216, 0.52941, 0.66667, 0.80392, 0.80000, 1.00000
+};
+float rgb_b[256] = {
+0.31373, 0.31373, 0.31373, 0.31373, 0.31373, 0.31373, 0.31373, 0.31373, 
+0.31373, 0.31373, 0.31373, 0.31373, 0.31373, 0.31373, 0.31373, 0.31373, 
+0.47059, 0.47059, 0.47059, 0.47059, 0.47059, 0.47059, 0.47059, 0.47059, 
+0.47059, 0.47059, 0.47059, 0.47059, 0.47059, 0.47059, 0.47059, 0.47059, 
+0.62745, 0.62745, 0.62745, 0.62745, 0.62745, 0.62745, 0.62745, 0.62745, 
+0.62745, 0.62745, 0.62745, 0.62745, 0.62745, 0.62745, 0.62745, 0.62745, 
+0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 
+0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 
+0.94118, 0.94118, 0.94118, 0.94118, 0.94118, 0.94118, 0.94118, 0.94118, 
+0.94118, 0.94118, 0.94118, 0.94118, 0.94118, 0.94118, 0.94118, 0.94118, 
+0.95294, 0.96471, 0.97647, 0.98824, 1.00000, 0.00392, 0.00784, 0.01176, 
+0.01569, 0.01961, 0.02353, 0.02745, 0.03137, 0.03529, 0.03922, 0.04314, 
+0.04706, 0.05098, 0.05490, 0.05882, 0.06275, 0.06667, 0.07059, 0.07451, 
+0.07843, 0.08235, 0.08627, 0.09020, 0.09412, 0.09804, 0.10196, 0.10588, 
+0.10980, 0.11373, 0.11765, 0.12157, 0.12549, 0.12941, 0.13333, 0.13725, 
+0.14118, 0.14510, 0.14902, 0.15294, 0.15686, 0.16078, 0.16471, 0.16863, 
+0.17255, 0.17647, 0.18039, 0.18431, 0.18824, 0.19216, 0.19608, 0.20000, 
+0.20392, 0.20784, 0.21176, 0.21569, 0.21961, 0.22353, 0.22745, 0.23137, 
+0.23529, 0.23922, 0.24314, 0.24706, 0.25098, 0.25490, 0.25882, 0.26275, 
+0.26667, 0.27059, 0.27451, 0.27843, 0.28235, 0.28627, 0.29020, 0.29412, 
+0.29804, 0.30196, 0.30588, 0.30980, 0.31373, 0.31765, 0.32157, 0.32549, 
+0.32941, 0.33333, 0.00392, 0.00784, 0.01176, 0.01569, 0.01961, 0.02353, 
+0.02745, 0.03137, 0.03529, 0.03922, 0.04314, 0.04706, 0.05098, 0.05490, 
+0.05882, 0.06275, 0.06667, 0.07059, 0.07451, 0.07843, 0.08235, 0.08627, 
+0.09020, 0.09412, 0.09804, 0.10196, 0.10588, 0.10980, 0.11373, 0.11765, 
+0.12157, 0.12549, 0.12941, 0.13333, 0.13725, 0.14118, 0.14510, 0.14902, 
+0.15294, 0.15686, 0.16078, 0.16471, 0.16863, 0.17255, 0.17647, 0.18039, 
+0.18431, 0.18824, 0.19216, 0.19608, 0.20000, 0.20392, 0.20784, 0.21176, 
+0.21569, 0.21961, 0.22353, 0.22745, 0.23137, 0.23529, 0.23922, 0.24314, 
+0.24706, 0.25098, 0.25490, 0.25882, 0.26275, 0.26667, 0.27059, 0.27451, 
+0.27843, 0.28235, 0.28627, 0.29020, 0.29412, 0.29804, 0.30196, 0.30588, 
+0.30980, 0.31373, 0.39216, 0.52941, 0.66667, 0.80392, 0.80000, 1.00000
+};
+    for(i=0; i<mNCol; i++) {
+      mycol.red = (rgb_r[i]*65535.); 
+      mycol.green = (rgb_g[i]*65535.); 
+      mycol.blue = (rgb_b[i]*65535.); 
+      AllocColor(mycol, i);      
+    }
+   }
+    break;
+  case CMAP_MIDAS_Color :  //   color.lutlis
+   {
+float rgb_r[256] = {
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 
+0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 
+0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 
+0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 
+0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 
+0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 
+0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 
+0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 
+0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 
+0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 
+0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 
+0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 
+0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 
+0.62353, 0.62353, 0.62353, 0.62353, 0.62353, 0.62353, 0.62353, 0.62353, 
+0.62353, 0.62353, 0.62353, 0.62353, 0.62353, 0.62353, 0.62353, 0.62353, 
+0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 
+0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 
+0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 
+0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902
+};
+float rgb_g[256] = {
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 
+0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 
+0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 
+0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 
+0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 
+0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 
+0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 
+0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 
+0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 
+0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 
+0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 
+0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 
+0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 
+0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 
+0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 
+0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 
+0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 
+0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 
+0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 
+0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 
+0.62353, 0.62353, 0.62353, 0.62353, 0.62353, 0.62353, 0.62353, 0.62353, 
+0.62353, 0.62353, 0.62353, 0.62353, 0.62353, 0.62353, 0.62353, 0.62353, 
+0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 
+0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 
+0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 
+0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000
+};
+float rgb_b[256] = {
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 
+0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 0.18431, 
+0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 
+0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 0.37255, 
+0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 
+0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 0.56078, 
+0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 
+0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 
+0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 
+0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 
+0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 
+0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 0.93725, 
+0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 
+0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 0.74902, 
+0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 
+0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 0.49804, 
+0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 
+0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 
+0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980, 0.30980
+};
+    for(i=0; i<mNCol; i++) {
+      mycol.red = (rgb_r[i]*65535.); 
+      mycol.green = (rgb_g[i]*65535.); 
+      mycol.blue = (rgb_b[i]*65535.); 
+      AllocColor(mycol, i);      
+    }
+   }
+    break;
+  case CMAP_MIDAS_ManyCol :  //  manycol.lutlis
+   {
+float rgb_r[256] = {
+0.34902, 0.34902, 0.34902, 0.34902, 0.34902, 0.34902, 0.34902, 0.34902, 
+0.34902, 0.34902, 0.44706, 0.44706, 0.44706, 0.44706, 0.44706, 0.44706, 
+0.44706, 0.44706, 0.44706, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.72549, 0.72549, 0.72549, 0.72549, 0.72549, 0.72549, 0.72549, 0.72549, 
+0.72549, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 0.34902, 0.34902, 0.34902, 0.34902, 0.34902, 
+0.34902, 0.34902, 0.34902, 0.34902, 0.34902, 0.44706, 0.44706, 0.44706, 
+0.44706, 0.44706, 0.44706, 0.44706, 0.44706, 0.44706, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.72549, 0.72549, 0.72549, 0.72549, 0.72549, 
+0.72549, 0.72549, 0.72549, 0.72549, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 0.34902, 0.34902, 
+0.34902, 0.34902, 0.34902, 0.34902, 0.34902, 0.34902, 0.34902, 0.34902, 
+0.44706, 0.44706, 0.44706, 0.44706, 0.44706, 0.44706, 0.44706, 0.44706, 
+0.44706, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.72549, 0.72549
+};
+float rgb_g[256] = {
+0.34902, 0.34902, 0.34902, 0.34902, 0.34902, 0.34902, 0.34902, 0.34902, 
+0.34902, 0.34902, 0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 
+0.78431, 0.78431, 0.78431, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.69020, 0.69020, 0.69020, 0.69020, 
+0.69020, 0.69020, 0.69020, 0.69020, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.69020, 0.69020, 0.69020, 
+0.69020, 0.69020, 0.69020, 0.69020, 0.69020, 0.69020, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 0.88235, 
+0.88235, 0.88235, 0.88235, 0.88235, 0.88235, 0.88235, 0.88235, 0.88235, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 0.34902, 0.34902, 0.34902, 0.34902, 0.34902, 
+0.34902, 0.34902, 0.34902, 0.34902, 0.34902, 0.78431, 0.78431, 0.78431, 
+0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.69020, 
+0.69020, 0.69020, 0.69020, 0.69020, 0.69020, 0.69020, 0.69020, 0.69020, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.69020, 0.69020, 0.69020, 0.69020, 0.69020, 0.69020, 0.69020, 
+0.69020, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 0.88235, 0.88235, 0.88235, 0.88235, 0.88235, 0.88235, 
+0.88235, 0.88235, 0.88235, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 0.34902, 0.34902, 
+0.34902, 0.34902, 0.34902, 0.34902, 0.34902, 0.34902, 0.34902, 0.34902, 
+0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 0.78431, 
+0.78431, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.69020, 0.69020, 0.69020, 0.69020, 0.69020, 0.69020, 
+0.69020, 0.69020, 0.69020, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.69020, 0.69020, 0.69020, 0.69020, 
+0.69020, 0.69020, 0.69020, 0.69020, 0.69020, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 0.88235, 0.88235, 0.88235, 
+0.88235, 0.88235, 0.88235, 0.88235, 0.88235, 0.88235, 0.00000, 0.00000
+};
+float rgb_b[256] = {
+0.34902, 0.34902, 0.34902, 0.34902, 0.34902, 0.34902, 0.34902, 0.34902, 
+0.34902, 0.34902, 0.92549, 0.92549, 0.92549, 0.92549, 0.92549, 0.92549, 
+0.92549, 0.92549, 0.92549, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.72549, 0.72549, 0.72549, 0.72549, 0.72549, 0.72549, 0.72549, 0.72549, 
+0.72549, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 0.34902, 0.34902, 0.34902, 0.34902, 0.34902, 
+0.34902, 0.34902, 0.34902, 0.34902, 0.34902, 0.92549, 0.92549, 0.92549, 
+0.92549, 0.92549, 0.92549, 0.92549, 0.92549, 0.92549, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.72549, 0.72549, 0.72549, 0.72549, 0.72549, 
+0.72549, 0.72549, 0.72549, 0.72549, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 0.34902, 0.34902, 
+0.34902, 0.34902, 0.34902, 0.34902, 0.34902, 0.34902, 0.34902, 0.34902, 
+0.92549, 0.92549, 0.92549, 0.92549, 0.92549, 0.92549, 0.92549, 0.92549, 
+0.92549, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.72549, 0.72549
+};
+    for(i=0; i<mNCol; i++) {
+      mycol.red = (rgb_r[i]*65535.); 
+      mycol.green = (rgb_g[i]*65535.); 
+      mycol.blue = (rgb_b[i]*65535.); 
+      AllocColor(mycol, i);      
+    }
+   }
+    break;
+  case CMAP_MIDAS_Idl14 :  //  idl14.lutlis
+   {
+float rgb_r[256] = {
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.02745, 0.05882, 0.09020, 0.12157, 0.15294, 0.18431, 0.21569, 
+0.24706, 0.27451, 0.30588, 0.33725, 0.36863, 0.40000, 0.43137, 0.46275, 
+0.49412, 0.52549, 0.55686, 0.59216, 0.62353, 0.65882, 0.69020, 0.72157, 
+0.75686, 0.78824, 0.82353, 0.85490, 0.88627, 0.92157, 0.95294, 0.98824, 
+0.00000, 0.00392, 0.00784, 0.01176, 0.01569, 0.01961, 0.02353, 0.02745, 
+0.03137, 0.03529, 0.03922, 0.04314, 0.04706, 0.05490, 0.06275, 0.07059, 
+0.07843, 0.09020, 0.09804, 0.10588, 0.11373, 0.12549, 0.13333, 0.14118, 
+0.14902, 0.16078, 0.17255, 0.18431, 0.19608, 0.20784, 0.21961, 0.23137, 
+0.24706, 0.25882, 0.27059, 0.28235, 0.29412, 0.30588, 0.32157, 0.33333, 
+0.34902, 0.36471, 0.38039, 0.39608, 0.41176, 0.42353, 0.43922, 0.45490, 
+0.47059, 0.48627, 0.50196, 0.51373, 0.52941, 0.54510, 0.56078, 0.57647, 
+0.59216, 0.60784, 0.62353, 0.63922, 0.65490, 0.67059, 0.68627, 0.69804, 
+0.70980, 0.72549, 0.73725, 0.75294, 0.76471, 0.77647, 0.79216, 0.80392, 
+0.81961, 0.83137, 0.84706, 0.85490, 0.86275, 0.87451, 0.88235, 0.89020, 
+0.90196, 0.90980, 0.91765, 0.92941, 0.93725, 0.94510, 0.95686, 0.95686, 
+0.96078, 0.96471, 0.96863, 0.96863, 0.97255, 0.97647, 0.98039, 0.98039, 
+0.98431, 0.98824, 0.99216, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 
+0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 
+0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 0.99608, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 
+1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000
+};
+float rgb_g[256] = {
+0.00000, 0.16471, 0.33333, 0.49804, 0.66667, 0.83137, 1.00000, 0.96471, 
+0.92549, 0.88627, 0.84706, 0.80784, 0.77255, 0.73333, 0.69412, 0.65490, 
+0.61569, 0.58039, 0.54118, 0.50196, 0.46275, 0.42353, 0.38824, 0.34902, 
+0.30980, 0.27059, 0.23137, 0.19608, 0.15686, 0.11765, 0.07843, 0.03922, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 
+0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 
+0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 
+0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 
+0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 0.00784, 0.00784, 
+0.00784, 0.00784, 0.00784, 0.00784, 0.00784, 0.00784, 0.00784, 0.00784, 
+0.00784, 0.00784, 0.00784, 0.00392, 0.00392, 0.01176, 0.01961, 0.03137, 
+0.03922, 0.04706, 0.05882, 0.06667, 0.07451, 0.08627, 0.09412, 0.10196, 
+0.11373, 0.12157, 0.12941, 0.14118, 0.14118, 0.14902, 0.15686, 0.16471, 
+0.17647, 0.18824, 0.20000, 0.21176, 0.22745, 0.23922, 0.25098, 0.26275, 
+0.27451, 0.28627, 0.30196, 0.32157, 0.34118, 0.36078, 0.37647, 0.39216, 
+0.40784, 0.42353, 0.44314, 0.46667, 0.49020, 0.51373, 0.54118, 0.56471, 
+0.59216, 0.61569, 0.64314, 0.67059, 0.69804, 0.72549, 0.75686, 0.78431, 
+0.81569, 0.84314, 0.87451, 0.89804, 0.92157, 0.94902, 0.97255, 1.00000
+};
+float rgb_b[256] = {
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.03137, 0.06275, 0.09412, 0.12549, 0.16078, 0.19216, 0.22353, 
+0.25490, 0.29020, 0.32157, 0.35294, 0.38431, 0.41569, 0.45098, 0.48235, 
+0.51373, 0.54510, 0.58039, 0.61176, 0.64314, 0.67451, 0.70588, 0.74118, 
+0.77255, 0.80392, 0.83529, 0.87059, 0.90196, 0.93333, 0.96471, 1.00000, 
+0.00000, 0.01961, 0.03922, 0.05882, 0.08235, 0.10196, 0.12157, 0.14510, 
+0.16471, 0.18431, 0.20784, 0.22745, 0.24706, 0.27059, 0.29020, 0.30980, 
+0.33333, 0.34902, 0.36863, 0.38431, 0.40392, 0.42353, 0.43922, 0.45882, 
+0.47451, 0.49412, 0.51373, 0.52941, 0.54902, 0.56471, 0.58431, 0.60392, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 
+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00392, 0.00392, 
+0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 
+0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 
+0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 
+0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 0.00392, 
+0.00392, 0.00392, 0.00784, 0.00784, 0.00784, 0.00784, 0.00784, 0.00784, 
+0.00784, 0.00784, 0.00784, 0.00784, 0.00784, 0.00784, 0.00784, 0.00784, 
+0.00784, 0.00784, 0.00784, 0.00784, 0.00784, 0.00784, 0.00784, 0.00784, 
+0.00784, 0.00784, 0.00784, 0.00784, 0.00784, 0.00784, 0.00784, 0.00784, 
+0.00784, 0.00784, 0.00784, 0.00784, 0.00784, 0.00784, 0.00784, 0.00784, 
+0.00784, 0.00784, 0.00784, 0.00784, 0.00784, 0.01176, 0.01569, 0.01961, 
+0.02745, 0.03529, 0.04706, 0.05490, 0.06667, 0.07843, 0.09020, 0.10588, 
+0.11765, 0.13333, 0.15294, 0.17255, 0.19216, 0.21569, 0.23529, 0.25490, 
+0.27843, 0.29804, 0.32157, 0.34902, 0.38039, 0.40784, 0.43922, 0.47059, 
+0.50196, 0.53333, 0.56863, 0.60000, 0.63529, 0.67059, 0.70588, 0.74118, 
+0.77647, 0.81176, 0.85098, 0.87843, 0.90980, 0.93725, 0.96863, 1.00000
+};
+    for(i=0; i<mNCol; i++) {
+      mycol.red = (rgb_r[i]*65535.); 
+      mycol.green = (rgb_g[i]*65535.); 
+      mycol.blue = (rgb_b[i]*65535.); 
+      AllocColor(mycol, i);      
+    }
+   }
+    break;
+  case CMAP_MIDAS_Idl15 :  //  idl15.lutlis
+   {
+float rgb_r[256] = {
+0.00000, 0.07059, 0.14118, 0.21176, 0.28235, 0.35294, 0.42353, 0.49804, 
+0.56863, 0.63922, 0.70980, 0.78039, 0.85098, 0.92157, 0.99608, 0.97647, 
+0.95686, 0.93725, 0.91765, 0.89804, 0.87451, 0.85490, 0.83529, 0.81569, 
+0.79608, 0.77255, 0.75294, 0.73333, 0.71373, 0.69412, 0.67451, 0.65098, 
+0.63137, 0.61176, 0.59216, 0.57255, 0.54902, 0.52941, 0.50980, 0.49020, 
+0.47059, 0.45098, 0.42745, 0.40784, 0.38824, 0.36863, 0.34902, 0.32549, 
+0.30588, 0.28627, 0.26667, 0.24706, 0.22745, 0.20392, 0.18431, 0.16471, 
+0.14510, 0.12549, 0.10196, 0.08235, 0.06275, 0.04314, 0.02353, 0.00000, 
+0.25098, 0.25490, 0.25882, 0.26275, 0.26667, 0.27059, 0.27451, 0.27843, 
+0.28235, 0.28627, 0.29020, 0.29412, 0.29804, 0.30196, 0.30588, 0.30980, 
+0.31373, 0.31765, 0.32157, 0.32549, 0.32941, 0.33333, 0.33725, 0.34118, 
+0.34510, 0.34902, 0.35294, 0.35686, 0.36078, 0.36471, 0.36863, 0.37255, 
+0.37647, 0.38039, 0.38431, 0.38824, 0.39216, 0.39608, 0.40000, 0.40392, 
+0.40784, 0.41176, 0.41569, 0.41961, 0.42353, 0.42745, 0.43137, 0.43529, 
+0.43922, 0.44314, 0.44706, 0.45098, 0.45490, 0.45882, 0.46275, 0.46667, 
+0.47059, 0.47451, 0.47843, 0.48235, 0.48627, 0.49020, 0.49412, 0.49804, 
+0.50196, 0.50588, 0.50980, 0.51373, 0.51765, 0.52157, 0.52549, 0.52941, 
+0.53333, 0.53725, 0.54118, 0.54510, 0.54902, 0.55294, 0.55686, 0.56078, 
+0.56471, 0.56863, 0.57255, 0.57647, 0.58039, 0.58431, 0.58824, 0.59216, 
+0.59608, 0.60000, 0.60392, 0.60784, 0.61176, 0.61569, 0.61961, 0.62353, 
+0.62745, 0.63137, 0.63529, 0.63922, 0.64314, 0.64706, 0.65098, 0.65490, 
+0.65882, 0.66275, 0.66667, 0.67059, 0.67451, 0.67843, 0.68235, 0.68627, 
+0.69020, 0.69412, 0.69804, 0.70196, 0.70588, 0.70980, 0.71373, 0.71765, 
+0.72157, 0.72549, 0.72941, 0.73333, 0.73725, 0.74118, 0.74510, 0.74902, 
+0.75294, 0.75686, 0.76078, 0.76471, 0.76863, 0.77255, 0.77647, 0.78039, 
+0.78431, 0.78824, 0.79216, 0.79608, 0.80000, 0.80392, 0.80784, 0.81176, 
+0.81569, 0.81961, 0.82353, 0.82745, 0.83137, 0.83529, 0.83922, 0.84314, 
+0.84706, 0.85098, 0.85490, 0.85882, 0.86275, 0.86667, 0.87059, 0.87451, 
+0.87843, 0.88235, 0.88627, 0.89020, 0.89412, 0.89804, 0.90196, 0.90588, 
+0.90980, 0.91373, 0.91765, 0.92157, 0.92549, 0.92941, 0.93333, 0.93725, 
+0.94118, 0.94510, 0.94902, 0.95294, 0.95686, 0.96078, 0.96471, 0.96863, 
+0.97255, 0.97647, 0.98039, 0.98431, 0.98824, 0.99216, 0.99608, 1.00000
+};
+float rgb_g[256] = {
+0.00000, 0.00392, 0.00784, 0.01176, 0.01569, 0.01961, 0.02353, 0.02745, 
+0.03137, 0.03529, 0.03922, 0.04314, 0.04706, 0.05098, 0.05490, 0.05882, 
+0.06275, 0.06667, 0.07059, 0.07451, 0.07843, 0.08235, 0.08627, 0.09020, 
+0.09412, 0.09804, 0.10196, 0.10588, 0.10980, 0.11373, 0.11765, 0.12157, 
+0.12549, 0.12941, 0.13333, 0.13725, 0.14118, 0.14510, 0.14902, 0.15294, 
+0.15686, 0.16078, 0.16471, 0.16863, 0.17255, 0.17647, 0.18039, 0.18431, 
+0.18824, 0.19216, 0.19608, 0.20000, 0.20392, 0.20784, 0.21176, 0.21569, 
+0.21961, 0.22353, 0.22745, 0.23137, 0.23529, 0.23922, 0.24314, 0.24706, 
+0.25098, 0.25490, 0.25882, 0.26275, 0.26667, 0.27059, 0.27451, 0.27843, 
+0.28235, 0.28627, 0.29020, 0.29412, 0.29804, 0.30196, 0.30588, 0.30980, 
+0.31373, 0.31765, 0.32157, 0.32549, 0.32941, 0.33333, 0.33725, 0.34118, 
+0.34510, 0.34902, 0.35294, 0.35686, 0.36078, 0.36471, 0.36863, 0.37255, 
+0.37647, 0.38039, 0.38431, 0.38824, 0.39216, 0.39608, 0.40000, 0.40392, 
+0.40784, 0.41176, 0.41569, 0.41961, 0.42353, 0.42745, 0.43137, 0.43529, 
+0.43922, 0.44314, 0.44706, 0.45098, 0.45490, 0.45882, 0.46275, 0.46667, 
+0.47059, 0.47451, 0.47843, 0.48235, 0.48627, 0.49020, 0.49412, 0.49804, 
+0.50196, 0.50588, 0.50980, 0.51373, 0.51765, 0.52157, 0.52549, 0.52941, 
+0.53333, 0.53725, 0.54118, 0.54510, 0.54902, 0.55294, 0.55686, 0.56078, 
+0.56471, 0.56863, 0.57255, 0.57647, 0.58039, 0.58431, 0.58824, 0.59216, 
+0.59608, 0.60000, 0.60392, 0.60784, 0.61176, 0.61569, 0.61961, 0.62353, 
+0.62745, 0.63137, 0.63529, 0.63922, 0.64314, 0.64706, 0.65098, 0.65490, 
+0.65882, 0.66275, 0.66667, 0.67059, 0.67451, 0.67843, 0.68235, 0.68627, 
+0.69020, 0.69412, 0.69804, 0.70196, 0.70588, 0.70980, 0.71373, 0.71765, 
+0.72157, 0.72549, 0.72941, 0.73333, 0.73725, 0.74118, 0.74510, 0.74902, 
+0.75294, 0.75686, 0.76078, 0.76471, 0.76863, 0.77255, 0.77647, 0.78039, 
+0.78431, 0.78824, 0.79216, 0.79608, 0.80000, 0.80392, 0.80784, 0.81176, 
+0.81569, 0.81961, 0.82353, 0.82745, 0.83137, 0.83529, 0.83922, 0.84314, 
+0.84706, 0.85098, 0.85490, 0.85882, 0.86275, 0.86667, 0.87059, 0.87451, 
+0.87843, 0.88235, 0.88627, 0.89020, 0.89412, 0.89804, 0.90196, 0.90588, 
+0.90980, 0.91373, 0.91765, 0.92157, 0.92549, 0.92941, 0.93333, 0.93725, 
+0.94118, 0.94510, 0.94902, 0.95294, 0.95686, 0.96078, 0.96471, 0.96863, 
+0.97255, 0.97647, 0.98039, 0.98431, 0.98824, 0.99216, 0.99608, 1.00000
+};
+float rgb_b[256] = {
+0.00000, 0.00392, 0.01176, 0.01961, 0.02745, 0.03529, 0.04314, 0.05098, 
+0.05882, 0.06667, 0.07451, 0.08235, 0.09020, 0.09804, 0.10588, 0.11373, 
+0.12157, 0.12941, 0.13725, 0.14510, 0.15294, 0.16078, 0.16863, 0.17647, 
+0.18431, 0.19216, 0.20000, 0.20784, 0.21569, 0.22353, 0.23137, 0.23922, 
+0.24706, 0.25490, 0.26275, 0.27059, 0.27843, 0.28627, 0.29412, 0.30196, 
+0.30980, 0.31765, 0.32549, 0.33333, 0.34118, 0.34902, 0.35686, 0.36471, 
+0.37255, 0.38039, 0.38824, 0.39608, 0.40392, 0.41176, 0.41961, 0.42745, 
+0.43529, 0.44314, 0.45098, 0.45882, 0.46667, 0.47451, 0.48235, 0.49020, 
+0.49804, 0.50588, 0.51373, 0.52157, 0.52941, 0.53725, 0.54510, 0.55294, 
+0.56078, 0.56863, 0.57647, 0.58431, 0.59216, 0.60000, 0.60784, 0.61569, 
+0.62353, 0.63137, 0.63922, 0.64706, 0.65490, 0.66275, 0.67059, 0.67843, 
+0.68627, 0.69412, 0.70196, 0.70980, 0.71765, 0.72549, 0.73333, 0.74118, 
+0.74902, 0.75686, 0.76471, 0.77255, 0.78039, 0.78824, 0.79608, 0.80392, 
+0.81176, 0.81961, 0.82745, 0.83529, 0.84314, 0.85098, 0.85882, 0.86667, 
+0.87451, 0.88235, 0.89020, 0.89804, 0.90588, 0.91373, 0.92157, 0.92941, 
+0.93725, 0.94510, 0.95294, 0.96078, 0.96863, 0.97647, 0.98431, 0.99216, 
+1.00000, 0.98431, 0.96863, 0.95294, 0.93333, 0.91765, 0.90196, 0.88627, 
+0.86667, 0.85098, 0.83529, 0.81961, 0.80000, 0.78431, 0.76863, 0.75294, 
+0.73333, 0.71765, 0.70196, 0.68627, 0.66667, 0.65098, 0.63529, 0.61961, 
+0.60000, 0.58431, 0.56863, 0.55294, 0.53333, 0.51765, 0.50196, 0.48627, 
+0.46667, 0.45098, 0.43529, 0.41961, 0.40000, 0.38431, 0.36863, 0.35294, 
+0.33333, 0.31765, 0.30196, 0.28627, 0.26667, 0.25098, 0.23529, 0.21961, 
+0.20000, 0.18431, 0.16863, 0.15294, 0.13333, 0.11765, 0.10196, 0.08627, 
+0.06667, 0.05098, 0.03529, 0.01961, 0.00000, 0.01176, 0.02745, 0.04314, 
+0.05882, 0.07451, 0.08627, 0.10196, 0.11765, 0.13333, 0.14902, 0.16078, 
+0.17647, 0.19216, 0.20784, 0.22353, 0.23529, 0.25098, 0.26667, 0.28235, 
+0.29804, 0.30980, 0.32549, 0.34118, 0.35686, 0.37255, 0.38431, 0.40000, 
+0.41569, 0.43137, 0.44706, 0.45882, 0.47451, 0.49020, 0.50588, 0.52157, 
+0.53725, 0.54902, 0.56471, 0.58039, 0.59608, 0.61176, 0.62353, 0.63922, 
+0.65490, 0.67059, 0.68627, 0.69804, 0.71373, 0.72941, 0.74510, 0.76078, 
+0.77255, 0.78824, 0.80392, 0.81961, 0.83529, 0.84706, 0.86275, 0.87843, 
+0.89412, 0.90980, 0.92157, 0.93725, 0.95294, 0.96863, 0.98431, 1.00000
+};
+    for(i=0; i<mNCol; i++) {
+      mycol.red = (rgb_r[i]*65535.); 
+      mycol.green = (rgb_g[i]*65535.); 
+      mycol.blue = (rgb_b[i]*65535.); 
+      AllocColor(mycol, i);      
+    }
+   }
+    break;
+
+  default :
+    for(i=0; i<mNCol; i++) {
+      mycol.green = mycol.red = mycol.blue = 0;
+      AllocColor(mycol, i);
+    }
+    break;
+  }
+}
Index: /tags/V_Dec2002/SophyaPI/PI/picmap.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/picmap.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/picmap.h	(revision 2309)
@@ -0,0 +1,65 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive     PIColorMap
+// Gestion de table de couleurs        96
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PICMAP_H_SEEN
+#define PICMAP_H_SEEN
+
+#include "pisysdep.h"
+#include PICMAPNTV_H
+
+enum CMapId
+ {
+ CMAP_OTHER       = 0, 
+ CMAP_GREY32      = 1,     // 32 niveaux de gris                    * permanent
+ CMAP_GREYINV32   = 2,     // 32 niveaux gris du blan au noir       * permanent
+ CMAP_COLRJ32     = 3,     // 32 couleurs, du Rouge au Jaune/blanc  * permanent
+ CMAP_COLBR32     = 4,     // 32 couleurs du bleu au rouge
+ CMAP_COLRV32     = 5,     // 32 couleurs 
+ CMAP_GREY128     = 6,     // 128 couleurs  niveaux de gris
+ CMAP_GREYINV128  = 7,     //    "     "      "      " 
+ CMAP_COLRJ128    = 8,     // 128 couleurs du rouge au jaune/blanc
+ CMAP_COLBR128    = 9,     // 128 couleurs du bleu au rouge
+
+ // Tables de couleur importees de MIDAS   256 couleurs
+ CMAP_MIDAS_Pastel    = 101,  // Bleu-Violet-Rouge-Jaune (pastel.lutlis)
+ CMAP_MIDAS_Heat      = 102,  // Noir-Rouge-Orange-Blanc (heat.lutlis)
+ CMAP_MIDAS_Rainbow3  = 103,  // Noir-Bleu-Vert-Jaune-Rouge-Violet-Blanc (rainbow3.lutlis)
+ CMAP_MIDAS_BlueRed   = 104,  // Bleu-Violet-Rouge (idl11.lutlis)
+ CMAP_MIDAS_BlueWhite = 105,  // Noir-Bleu-Blanc (blulut.lutlis)
+ CMAP_MIDAS_Stairs8   = 106,  // escalier (stairs8.lutlis)
+ CMAP_MIDAS_Stairs9   = 107,  // escalier (stairs9.lutlis)
+ CMAP_MIDAS_StairCase = 108,  //          (staircase.lutlis)
+ CMAP_MIDAS_Color     = 109,  //          (color.lutlis)
+ CMAP_MIDAS_ManyCol   = 110,  // Repetition de motif (manycol.lutlis)
+ CMAP_MIDAS_Idl14     = 111,  //  (idl14.lutlis)
+ CMAP_MIDAS_Idl15     = 112,  //  (idl15.lutlis)
+
+ //  Table simple a 16 couleurs 
+ CMAP_COL16       = 999        // 16 Couleurs Arcenciel
+ };
+
+
+class PIColorMap : public PIColorMapNative {
+public:
+  PIColorMap(CMapId);
+  PIColorMap(string const& nom, int nCol); 
+  PIColorMap(PIColorMap&);
+  virtual ~PIColorMap();
+
+  static void CleanColorMaps();
+  static int  NumberStandardColorMaps();
+  static CMapId GetStandardColorMapId(int num);
+  static string GetStandardColorMapName(int num);
+  static int    ColorMapId2Num(PIColorMap const & cmap);
+
+protected:
+  PIColorMap(CMapId id, int nc, string const& nom);  // Fait l'allocation des couleurs     
+  void     MakeColMap();
+
+  int mCTId;    // Pour tenir trace de la derniere table qui doit liberer les couleurs 
+};
+
+#endif
+
Index: /tags/V_Dec2002/SophyaPI/PI/picmapgen.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/picmapgen.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/picmapgen.cc	(revision 2309)
@@ -0,0 +1,37 @@
+#include "picmapgen.h"
+#include <list>
+#include <algorithm>
+#include "pisysdep.h"
+#include PICMAPNTV_H
+#include PICMAP_H
+
+
+
+PIColorMapGen::PIColorMapGen()
+{
+  mNom = "";
+  mNCol = 0;
+  mType = -1;
+  ReverseColorIndex(false);
+}
+PIColorMapGen::PIColorMapGen(int id, int nc, string const& nom)
+{
+  mNom = nom;
+  mNCol = nc;
+  mType = id;
+  ReverseColorIndex(false);  
+}
+
+
+PIColorMapGen::~PIColorMapGen()
+{
+}
+
+void PIColorMapGen::CopyFromGen(PIColorMapGen* m)
+{
+  mNom = m->mNom;
+  mNCol = m->mNCol;
+  mType = m->mType;
+}
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/picmapgen.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/picmapgen.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/picmapgen.h	(revision 2309)
@@ -0,0 +1,47 @@
+#ifndef PICMAPBASE_H_SEEN
+#define PICMAPBASE_H_SEEN
+
+#include "pisysdep.h"
+#include <string>
+#include <string.h>
+
+ 
+struct PIColor {
+  unsigned short red;
+  unsigned short green;
+  unsigned short blue;
+};
+
+class PIColorMapGen {
+public:
+  PIColorMapGen();  
+  PIColorMapGen(int id, int nc, string const& nom);  
+  virtual ~PIColorMapGen();
+
+  int Type() const          {return mType;}
+  int NCol() const          {return mNCol;}
+  string const& Nom() const {return mNom;}
+
+  virtual PIColor GetColor(int n)=0;
+  inline void  ReverseColorIndex(bool fg=false)
+               { mFlagReversedIndex = fg; }
+  inline bool  IsColorIndexReversed() const
+               { return(mFlagReversedIndex); } 
+  virtual bool AllocColor(PIColor const& col, int index)=0;
+  virtual void FreeColors()=0;     // Desalloue les couleurs
+
+  virtual long  TotNbColors()=0;    // Donne le nombre total de couleurs disponibles
+  virtual int   NbAllocColors()=0;  // Nb de couleurs deja allouees 
+protected:
+  void CopyFromGen(PIColorMapGen*);
+  virtual void CopyFrom(PIColorMapGen*)=0;
+  
+
+  int    mNCol;
+  int    mType;
+  string mNom;
+  bool   mFlagReversedIndex;
+};
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/picmapmac.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/picmapmac.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/picmapmac.cc	(revision 2309)
@@ -0,0 +1,114 @@
+#include "picmapmac.h"
+#include <UDebugging.h>
+
+static int NTotAllocCol;
+
+
+PIColorMapMac::PIColorMapMac()
+: PIColorMapGen(), mPalette(NULL), mCTab(NULL)
+{
+}
+
+PIColorMapMac::PIColorMapMac(int id, int nc, string const& nom) 
+: PIColorMapGen(id, nc, nom)
+{
+    int n = nc+2;
+	mCTab = (CTabHandle) ::NewHandle(sizeof(long) + 
+				sizeof(short) + sizeof(short) + 
+				n*sizeof(ColorSpec));
+	(**mCTab).ctFlags = 0;
+	(**mCTab).ctSeed = GetCTSeed();
+	(**mCTab).ctSize = n;
+    ColorSpec* sp = (**mCTab).ctTable;
+    sp[0].rgb.red   = 0;
+    sp[0].rgb.green = 0;
+    sp[0].rgb.blue  = 0;
+    sp[0].value     = 0;
+    sp[1].rgb.red   = 65535;
+    sp[1].rgb.green = 65535;
+    sp[1].rgb.blue  = 65535;
+    sp[1].value     = 1;
+    for (int i=2; i<n; i++) {
+      sp[i].rgb.red   = 0;
+      sp[i].rgb.green = 0;
+      sp[i].rgb.blue  = 0;
+      sp[i].value     = i;
+    }
+  mPalette = NewPalette(mNCol,mCTab,pmTolerant,0);
+}
+
+PIColorMapMac::~PIColorMapMac()
+{
+  DisposePalette(mPalette);
+  DisposeHandle((Handle)mCTab);
+}
+
+/* --Methode-- */
+PIColor PIColorMapMac::GetColor(int n)
+{
+PIColor picr;
+picr.red = picr.green = picr.blue = 0;
+
+if ((n<0) || (n >= NCol()))   
+  return(picr);
+
+RGBColor qdCol;
+GetEntryColor(mPalette,n+2,&qdCol);
+
+picr.red   = qdCol.red;
+picr.green = qdCol.green;
+picr.blue  = qdCol.blue;
+
+return(picr);
+}
+
+
+bool PIColorMapMac::AllocColor(PIColor const& col, int index)
+{
+  if (!mPalette) return false;
+  if ((index < 0) || (index > mNCol))  return(false);
+  
+  RGBColor srcRGB;
+  srcRGB.red   = col.red;
+  srcRGB.green = col.green;
+  srcRGB.blue  = col.blue;
+  
+  SetEntryColor(mPalette,index+2,&srcRGB);
+  ((**mCTab).ctTable)[index+2].rgb = srcRGB;
+  NTotAllocCol++;
+  return true;    //  $CHECK$  retourne true si OK - Reza 01/12/97
+}
+
+long PIColorMapMac::TotNbColors()
+{
+   PixMapHandle pmh = ((CGrafPort*)qd.thePort)->portPixMap;
+   int depth = (**pmh).cmpSize * (**pmh).cmpCount;
+   long nbcol = 1;
+   for (int i=0; i<depth; i++)
+     nbcol *= 2;
+   return nbcol;
+}
+
+void PIColorMapMac::FreeColors()
+{
+  Assert_(mPalette);
+  DisposePalette(mPalette);
+  DisposeCTable(mCTab);
+}
+
+int PIColorMapMac::NbAllocColors()
+{
+return(NTotAllocCol);
+}
+
+
+void PIColorMapMac::CopyFrom(PIColorMapGen* x)
+{
+  CopyFromGen(x);
+  PIColorMapMac* y = (PIColorMapMac*) x;
+  mPalette = y->mPalette;
+  mCTab = y->mCTab;
+  HandToHand(&(Handle)mCTab);
+  HandToHand(&(Handle)mPalette);
+  Assert_(mPalette);
+}
Index: /tags/V_Dec2002/SophyaPI/PI/picmapmac.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/picmapmac.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/picmapmac.h	(revision 2309)
@@ -0,0 +1,34 @@
+#ifndef PICMAPMAC_H_SEEN
+#define PICMAPMAC_H_SEEN
+
+#include "picmapgen.h"
+#include <Palettes.h>
+
+
+class PIColorMapMac : public PIColorMapGen {
+public:
+  PIColorMapMac();
+  PIColorMapMac(int id, int nc, string const& nom);  
+  ~PIColorMapMac();
+  
+  virtual PIColor GetColor(int n);
+  virtual bool AllocColor(PIColor const& col, int index);   // $CHECK$  Reza 01/12/97(Modif)
+  virtual void FreeColors();
+
+  virtual long  TotNbColors();
+  virtual int   NbAllocColors();
+  
+  CTabHandle    GetCTab() {return mCTab;}
+protected:
+  void CopyFrom(PIColorMapGen*);
+  
+  CTabHandle    mCTab;
+  PaletteHandle mPalette;
+
+  friend class PIColorMapGen;
+  friend class PIPixmapMac;
+};
+
+typedef PIColorMapMac PIColorMapNative;
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/picmapview.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/picmapview.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/picmapview.cc	(revision 2309)
@@ -0,0 +1,181 @@
+// Module PI : Peida Interactive     PICMapView
+// Visualisation de table de couleur     R. Ansari  07/98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "picmapview.h"
+#include <math.h>
+
+//++
+// Class	PICMapView
+// Lib		PI
+// include	picmapview.h
+//
+//   	Classe permettant la visualisation d'une table de couleur.
+//--
+//++
+// Links	Parents
+// PIBaseWdg
+//--
+//++
+// Links	Voir aussi
+// PIColorMap
+//--
+
+//++
+// Titre	Constructeur
+//--
+//++
+//  PICMapView(PIContainerGen *par, char *nom, int sx=256, int sy=10, int px=0, int py=0);
+//	Constructeur - Le choix d'affichage (vertical ou horizontal) dépend
+//	du rapport des tailles "sx", "sy"
+//--
+
+
+/* --Methode-- */
+PICMapView::PICMapView(PIContainerGen *par, char *nom,
+                       int sx, int sy, int px, int py) 
+: PIBaseWdg(par, nom, sx, sy, px, py)
+
+{
+  cmap = NULL;
+  vmin = 1.;   vmax = -1.; 
+}
+
+
+/* --Methode-- */
+PICMapView::~PICMapView()
+{
+  if (cmap) delete cmap;
+}
+
+
+
+//++
+// Titre	Méthodes
+//--
+//++
+// long  kind()
+//	Retourne PICMapView::ClassId .
+// void   SetColMap(PIColorMap* cmp=NULL, double min=1., double max=-1., bool refr=true)
+//	Choix de la table de couleur et valeurs min et max. Si "refr==true",
+//	la méthode "Refresh()" est appelée.
+// void  SetColMapId(CMapId cmapid, double min=1., double max=-1., bool refr=true)
+//	Choix de la table de couleur en utilisant le "CMapId" et 
+//	définition des valeurs min et max. Si "refr==true",
+//	la méthode "Refresh()" est appelée.
+//--
+ 
+/* --Methode-- */
+void PICMapView::SetColMap(PIColorMap* cmp, double min, double max, bool refr)
+{
+  if (cmp == NULL)   { 
+    if (cmap) delete cmap;
+    cmap = NULL;
+    vmin = 1.;  vmax = -1.;
+    if (refr)  Refresh();  
+    return;
+    }
+  if ( cmap && (cmp->Type() == cmap->Type()) && (cmp->Type() != CMAP_OTHER)
+       && (cmp->IsColorIndexReversed() == cmap->IsColorIndexReversed())
+       && (fabs(vmin-min) < 1.e-69)  && (fabs(vmax-max) > -1.e-69) )  return;
+  if (cmap) delete cmap;
+  cmap = new PIColorMap(*cmp);
+  vmin = min;  vmax = max;
+  if (refr)  Refresh();  
+  return;
+}
+
+/* --Methode-- */
+void PICMapView::SetColMapId(CMapId cmapid, bool revidx, double min, double max, bool refr)
+{
+  if ( cmap && (cmapid == cmap->Type()) && (cmapid != CMAP_OTHER) &&
+       (cmap->IsColorIndexReversed() == revidx) &&
+       ((vmin-min) < 1.e-69) &&  ((vmin-min) > -1.e-69) &&
+       ((vmax-max) < 1.e-69) &&  ((vmax-max) > -1.e-69) )  return;
+  if (cmap) delete cmap;
+  cmap = new PIColorMap(cmapid);
+  cmap->ReverseColorIndex(revidx);
+  vmin = min;  vmax = max;
+  if (refr)  Refresh();  
+  return;
+}
+
+
+/* --Methode-- */
+void PICMapView::Draw(PIGraphicGen* g, int /*x0*/, int /*y0*/, int /*dx*/, int /*dy*/)
+{
+  if (!cmap) { 
+    EraseWindow(0, 0, XSize(), YSize());
+    return;
+    }
+  // On presente la table de couleur verticalement si SizeY > SizeX 
+  // ou horizontale  si SizeX > SizeY
+
+  int sx = XSize(); 
+  int sy = YSize(); 
+
+  int k;
+  if (sx > sy) {    // horizontal
+    int xc, dx;
+    xc = 0;
+    for(k=0; k<cmap->NCol(); k++) {
+      dx = (sx-xc)/(cmap->NCol()-k);
+      g->SelForeground((*cmap), k);
+      g->DrawFBox(xc, 0, dx+1, sy);
+      xc += dx;
+    }
+  }
+  else  {    // vertical
+    int yc, dy;
+    yc = sy;
+    for(k=0; k<cmap->NCol(); k++) {
+      dy = yc/(cmap->NCol()-k);
+      yc -= dy;
+      g->SelForeground((*cmap), k);
+      g->DrawFBox(0, yc, sx, dy+1);
+    }
+  }
+  if (vmin > vmax)   return;
+
+  if ( (cmap->Type() == CMAP_GREY32) || (cmap->Type() == CMAP_GREYINV32) ||
+       (cmap->Type() == CMAP_GREY128) || (cmap->Type() == CMAP_GREYINV128) )  g->SelForeground(PI_Red);
+  else g->SelForeground(PI_Green);
+
+  if (sx > sy) {    // horizontal
+    int fsz = (sy < 20) ? sy-6 : 14;
+    g->SelFontSzPt(fsz, PI_BoldFont);
+    char buff[32];
+    double av;
+    av = fabs(vmin);
+    if ( (av < 1.e6) && (av > 1.e-3) )  sprintf(buff, "%.2f", vmin);
+    else sprintf(buff, "%8.4g", vmin);
+    g->DrawString(4, sy-4, buff);
+    av = fabs(vmax);
+    if ( (av < 1.e6) && (av > 1.e-3) )  sprintf(buff, "%.2f", vmax);
+    else sprintf(buff, "%8.4g", vmax);
+    g->DrawString(sx-4-(int)g->CalcStringWidth(buff), sy-4, buff);
+    } 
+  else {   // vertical 
+    int fsz = (sx < 64) ? sx/4 : 14;
+    g->SelFontSzPt(fsz, PI_BoldFont);
+    char buff[32];
+    double av;
+    av = fabs(vmin);
+    if ( (av < 1.e6) && (av > 1.e-3) )  sprintf(buff, "%.2f", vmin);
+    else sprintf(buff, "%8.4g", vmin);
+    g->DrawString(4, sy-4, buff);
+    av = fabs(vmax);
+    if ( (av < 1.e6) && (av > 1.e-3) )  sprintf(buff, "%.2f", vmax);
+    else sprintf(buff, "%8.4g", vmax);
+    int fa, fd;
+    g->DrawString(4, g->GetFont().GetFontHeight(fa,fd)+4, buff);
+    } 
+    
+  return;
+}
+
+
+
+
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/picmapview.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/picmapview.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/picmapview.h	(revision 2309)
@@ -0,0 +1,41 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive     PICMapView
+// Visualisation de table de couleur     R. Ansari  07/98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PICMAPVIEW_H_SEEN
+#define PICMAPVIEW_H_SEEN
+
+#include "pisysdep.h"
+
+#include PIBWDG_H
+#include PICMAP_H
+
+class PICMapView : public PIBaseWdg
+{
+public:
+  enum {ClassId = 5150};
+
+                  PICMapView(PIContainerGen *par, char *nom,
+                             int sx=256, int sy=10, int px=0, int py=0);
+  virtual         ~PICMapView();
+
+  virtual long	  kind() {return ClassId; }
+
+  void            SetColMap(PIColorMap* cmp=NULL, double min=1., double max=-1., bool refr=true);
+  void            SetColMapId(CMapId cmapid, bool revidx, double min, double max, bool refr);
+  inline void     SetColMapId(CMapId cmapid, double min=1., double max=-1., bool refr=true)
+                  { SetColMapId(cmapid, false, min, max, refr); }
+
+// Traitement des evenements   
+
+  virtual void   Draw(PIGraphic* g, int x0, int y0, int dx, int dy);
+
+
+protected:
+  PIColorMap* cmap;
+  double vmin, vmax;
+};
+
+
+#endif 
Index: /tags/V_Dec2002/SophyaPI/PI/picmapx.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/picmapx.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/picmapx.cc	(revision 2309)
@@ -0,0 +1,193 @@
+#include <stdio.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+
+#include "piwdgx.h"
+#include "picmapx.h"
+
+/* --Methode-- */
+PIColorMapX::PIColorMapX()    
+: PIColorMapGen()
+{
+mColors = NULL;
+mColRGB = NULL;
+mNewCol = NULL;
+}
+
+/* --Methode-- */
+PIColorMapX::PIColorMapX(int id, int nc, string const& nom)    
+: PIColorMapGen(id, nc, nom)
+{
+
+int n = nc;
+mColors = new PIXColor[n];
+mColRGB = new PIColor[n];
+mNewCol = new bool[n];
+int i;
+for(i=0; i<n; i++)  
+  { mColors[i] = BlackPixel(PIXDisplay(), PIXScreen());
+  mColRGB[i].red = mColRGB[i].green = mColRGB[i].blue = 0; 
+  mNewCol[i] = false; }
+// printf("PIColorMapX::PIColorMapX(CMapId, int) %d %d \n", mNCol, Type());
+}
+
+
+/* --Methode-- */
+PIColorMapX::~PIColorMapX()
+{
+if (mColors)  delete[] mColors;
+if (mColRGB)  delete[] mColRGB;
+if (mNewCol)  delete[] mNewCol;
+}
+
+
+/* --Methode-- */
+PIColor PIColorMapX::GetColor(int n)
+{
+if ((n<0) || (n >= NCol()))   
+  {
+  PIColor picr;
+  picr.red = picr.green = picr.blue = 0;
+  return(picr);
+  }
+if (mFlagReversedIndex) return(mColRGB[NCol()-n-1]);
+else return(mColRGB[n]);
+}
+
+static  Colormap  defxcmap;
+static  int xinicmap = 0;
+static int NTotColors = 0;
+static int NTotAllocCol = 0;
+
+static int nerrallocol = 0;
+
+/* --Methode-- */
+bool PIColorMapX::AllocColor(PIColor const& col, int index)
+{
+XColor myxcol;
+
+if (!xinicmap)  
+  {
+  defxcmap = XDefaultColormap (PIXDisplay(), PIXScreen());
+  xinicmap = 1;
+  }
+
+if ( (index < 0) || (index >= mNCol) )  return(false);
+
+if ( (col.red == 0) && (col.green == 0) && (col.blue == 0) )
+  {
+  mColors[index] = BlackPixel(PIXDisplay(), PIXScreen());
+  mColRGB[index] = col; 
+  mNewCol[index] = false;
+  return(true);
+  }
+
+// Pour diminuer les requetes X, on verifie si la couleur 
+// ne se trouve pas deja dans la table    Reza 19/05/98
+int kc;
+for(kc=0; kc<mNCol; kc++) 
+  if ( (col.red == mColRGB[kc].red) && (col.green == mColRGB[kc].green) &&   (col.blue == mColRGB[kc].blue) )
+    { mColors[index] = mColors[kc];  mColRGB[index] = mColRGB[kc]; 
+    mNewCol[index] = false;  return(true); }
+
+ 
+myxcol.red = col.red; 
+myxcol.blue = col.blue;
+myxcol.green = col.green;
+
+
+if ( XAllocColor(PIXDisplay(), defxcmap, &myxcol) ) {
+  mColors[index] = myxcol.pixel;
+  mColRGB[index] = col; 
+  mNewCol[index] = true;
+//  printf("PIColorMapX::AllocColor()  RGB= %d %d %d \n",
+//         (int) col.red, (int) col.blue, (int) col.green);
+  NTotAllocCol++;  
+  return(true);
+  }
+else {
+  nerrallocol++;
+  if (nerrallocol < 21) printf("PIColorMapX::AllocColor() Error: Pb Allocation RGB= %d %d %d \n",
+         (int) col.red, (int) col.blue, (int) col.green);
+  if (nerrallocol == 20) printf("No more  PIColorMapX::AllocColor() Errors will be reported \n");
+  return(false);
+  }
+}
+
+/* --Methode-- 
+void PIColorMapX::MakeColMap()
+{
+}
+*/
+
+/* --Methode-- */
+void PIColorMapX::FreeColors()
+{
+PIXColor bpix;
+PIColor blc;
+
+if (!xinicmap)  
+  {
+  defxcmap = XDefaultColormap (PIXDisplay(), PIXScreen());
+  xinicmap = 1;
+  }
+
+for (int i=0; i<mNCol; i++)
+  if ( mNewCol[i] )    XFreeColors(PIXDisplay(), defxcmap, mColors+i, 1, 0);
+
+bpix = BlackPixel(PIXDisplay(), PIXScreen());
+blc.red = blc.green = blc.blue = 0;
+{for (int i=0; i<mNCol; i++)  
+  { mColors[i] = bpix;   mColRGB[i] = blc;  mNewCol[i] = false; }
+}
+// printf("PIColorMapX::FreeColors()  Type= %d mNCol= %d \n",
+//        Type(), NCol());
+
+}
+
+
+/* --Methode-- */
+long PIColorMapX::TotNbColors()
+{
+if (NTotColors > 0)  return(NTotColors);
+// Visual* vis;
+// DefaultVisual(PIXDisplay(),  PIXScreen() );
+int k,kk;
+// On calcule le nombre de couleurs a partir du nb de plans image
+kk = DefaultDepth(PIXDisplay(),  PIXScreen() );
+NTotColors = 1;
+for(k=0; k<kk; k++) NTotColors *= 2;
+/*
+ printf("PIColorMapX::TotNbColor() / Debug : Nb Tot Colors = %d - D=%d - NCol=%d NP= %d \n", NTotColors, 
+ DefaultDepth(PIXDisplay(),  PIXScreen()), 
+ DisplayCells(PIXDisplay(),  PIXScreen()), 
+ DisplayPlanes(PIXDisplay(),  PIXScreen()) );
+*/
+return(NTotColors);
+}
+
+/* --Methode-- */
+int PIColorMapX::NbAllocColors()
+{
+return(NTotAllocCol);
+}
+
+
+/* --Methode-- */
+void PIColorMapX::CopyFrom(PIColorMapGen* x)
+{
+  if (mColors)  delete mColors;
+  if (mColRGB)  delete mColRGB;
+  if (mNewCol)  delete mNewCol;
+  CopyFromGen(x);
+  mColors = new PIXColor[mNCol];
+  mColRGB = new PIColor[mNCol];
+  mNewCol = new bool[mNCol];
+  for (int i=0; i<mNCol; i++)  
+    { mColors[i] = ((PIColorMapX *)x)->mColors[i];
+    mColRGB[i] = ((PIColorMapX *)x)->mColRGB[i]; 
+// C'est la table de couleur originale qui est responsable de liberer les couleurs - Reza 8/2/98
+    mNewCol[i] = false; }  
+}
Index: /tags/V_Dec2002/SophyaPI/PI/picmapx.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/picmapx.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/picmapx.h	(revision 2309)
@@ -0,0 +1,37 @@
+#ifndef PICMAPX_H_SEEN
+#define PICMAPX_H_SEEN
+
+#include "picmapgen.h"
+
+typedef   unsigned long PIXColor ;
+
+
+class PIColorMapX : public PIColorMapGen {
+public:
+  PIColorMapX();  
+  PIColorMapX(int id, int nc, string const& nom);  
+  virtual ~PIColorMapX();
+
+  // Fonction Color() est definie afin de permettre l'optimisation - affichage d'image, etc...
+  inline PIXColor  Color(int index) 
+    { return (((index < mNCol)&&(index>=0)) ? 
+	      mColors[(mFlagReversedIndex)?mNCol-index-1:index] : 0); } ;
+
+  virtual PIColor GetColor(int n);
+  virtual bool AllocColor(PIColor const& col, int index);
+  virtual void FreeColors();
+
+  virtual long TotNbColors();
+  virtual int  NbAllocColors();
+
+protected:
+  virtual void CopyFrom(PIColorMapGen*);
+  
+  PIXColor  * mColors;     // La table des couleurs ...
+  PIColor   * mColRGB;     // Composantes RGB  
+  bool * mNewCol;          // Nouvelle couleur dans table ou pas
+};
+
+typedef PIColorMapX PIColorMapNative;
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/picolist.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/picolist.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/picolist.h	(revision 2309)
@@ -0,0 +1,22 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive     PIGraphic 
+// Liste de couleurs predefinies     R. Ansari 1997-2000
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PICOLIST_H_SEEN
+#define PICOLIST_H_SEEN
+
+
+enum PIColors  { PI_ColorFromMap = -4, PI_NotDefColor = -1, 
+                 PI_Black = 0, PI_White = 1,  PI_Grey = 2,
+                 PI_Red = 3, PI_Blue = 4, PI_Green = 5,  
+                 PI_Yellow = 6, PI_Magenta = 7, 
+                 PI_Cyan = 8, PI_Turquoise = 9, PI_NavyBlue = 10, 
+                 PI_Orange = 11, PI_SiennaRed = 12, PI_Purple = 13,  
+                 PI_LimeGreen = 14, PI_Gold = 15,
+		 PI_Violet = 16, PI_VioletRed = 17, 
+		 PI_BlueViolet = 18, PI_DarkViolet = 19, 
+		 PI_HighlightBlue = 20,
+                 PI_ColorAllBits0 = 21, PI_ColorAllBits1 = 22 };
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/picons.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/picons.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/picons.cc	(revision 2309)
@@ -0,0 +1,1012 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "pisysdep.h"
+#include PIMENU_H
+#include "picons.h"
+
+
+//++
+// Class	PIConsole
+// Lib		PI
+// include	picons.h
+//
+//   	Cette classe fournit une partie des services equivalentes
+//	a une console. Les sorties stdout et stderr peuvent etre 
+//	redirigees sur un objet *PIConsole* (Voir "PIApplication").
+//	La classe offre aussi la possibilite de gestion d'un ScrollBar,
+//	ainsi que la saisie et l'edition de commande, avec la gestion
+//	d'un buffer de rappel.
+//
+//	* Bouton-1 : Envoie le message "PIMsg_Active". Permet aussi 
+//	la selection d'un rectangle pour le copie/coller
+//	* Bouton-2 : Effectue l'operation Copier/*Coller* sur la ligne
+//	d'edition de commandes.
+//	de commande (convention Xt)
+//	* Bouton-3 : Affiche le menu des options d'affichage.
+//
+//	Gestion du clavier :
+//	* <Alt>O : Affiche le menu des options d'affichage.
+//	* <Alt>V : Copier/*Coller* Copie le texte depuis le buffer copier/coller
+//	sur la ligne d'edition de commande.
+//	* <Alt>A : Selectionne toute la fenetre pour *Copier*/Coller
+//	* <Alt>L : Liste des commandes dans le tampon de rappel.
+//
+//	Commandes d'edition : 
+//	* <Ctl>A : Debut de ligne.
+//	* <Ctl>E : Fin de ligne.
+//	* <Ctl>K : Effacement jusqu'en fin de ligne.
+//	* <Ctl>C : Effacement de la ligne.
+//	* Curseur gauche, droite : deplacement curseur
+//	* Cursur Haut,bas : rappel de commande
+//	* Backspace, del : effacement de caracteres
+//	* <Return> : Validation
+//--
+//++
+// Links	Parents
+// PIBaseWdg
+//--
+
+// #define DEBUG_PICONS 1
+
+//  Le menu qui va servir a changer de fontes, couleurs, ...
+// de bouton-3
+static PIMenu* opmc=NULL;
+static int nb_opmc = 0;
+
+static void ActivatePIConsOptionMenu(PIConsole* par)
+{
+  if (opmc)  delete opmc;
+  opmc = NULL;
+
+  opmc = new PIMenu(par, "OptCons", k_PopupMenu);
+  opmc->AppendItem("SmallFont", 3101);
+  opmc->AppendItem("NormalFont", 3102);
+  opmc->AppendItem("LargeFont", 3103);
+  opmc->AppendItem("25L x 132C", 3301);
+  opmc->AppendItem("20L x 80C", 3302);
+  opmc->AppendItem("10L x 80C", 3303);
+  opmc->AppendItem("5L x 60C", 3304);
+  opmc->AppendItem("Bkg White", 3201);
+  opmc->AppendItem("Bkg Black", 3202);
+  opmc->AppendItem("Black/Yellow", 3203);
+  
+  opmc->SetMsgParent((PIMsgHandler*)par);
+  opmc->Show(); 
+  
+}
+
+/*  --------------------------------------------------------------------------------- */
+/*  ---------  Classe PIConsole : I/O (Ecriture/lecture) texte standard  ------------ */
+/*  --------------------------------------------------------------------------------- */
+
+static int CmdStrLen = 256;
+static int PIVA_Select = 1 << 3;
+
+//  Gestion du scroll-bar
+static int Scb_Width = 14;
+
+
+//++
+// Titre	Constructeur
+//--
+//++
+// PIConsole(PIContainer* par, const char* nom, PIMessage msg, \
+//           int nl, int nc, int sx, int sy, int px, int py, bool scb)
+//	Creation d'un objet PIConsole, avec "nl" lignes et  "nc" colonnes.
+//	"sx,sy" indique la taille de la fenetre. Si "scb==true", un
+//	ScrollBar est cree associe a l'objet PIConsole.
+//--
+
+/* --Methode-- */
+PIConsole::PIConsole(PIContainer* par, const char* nom, PIMessage msg,
+                     int nl, int nc, int sx, int sy, int px, int py, bool scb) :
+PIBaseWdg(par, nom, ((scb)?sx-Scb_Width:sx), sy, px, py) 
+{
+mNL = (nl > 10) ? nl : 10;
+mNC = (nc > 30) ? nc : 30;
+mText = new char[mNL*mNC];
+mAtt = new unsigned char[mNL*mNC];
+mLPo = new int[mNL];
+mStrBuf = new char[mNC+1];
+mCmdStr = new char[CmdStrLen+1];
+mCCP = mCLC = 0;
+mDCOff = 0;
+mScb = NULL;
+
+SetMsg(msg);
+
+int i;
+for(i=0; i<mNL; i++) {
+  mLPo[i] = i*mNC;
+  ClearLine(i);
+  }
+
+mOffL = 0;
+mNCmdL = 0;
+mCmd = "";
+
+// Pile de rappel des commandes 
+mRStr = NULL;
+mNComm = NMxRecall = 0;
+mRCindx = mRindx = 0;
+mChangeFg = false;
+
+// Copier/coller
+mCPBuffer = NULL;
+mCPBufLen = 0;
+mCPbeginC =  mCPendC = -1;
+mCPbeginL = mCPendL = -1;
+
+SetPrompt("Cmd> ");
+ClrCmd();
+SelectFont();
+SelFgBgCol();
+mCurL = mNL-mWSzL-1; 
+mCurC = 0;
+
+
+// Pour ajouter un scroll-bar
+AssocScrollBar(par, nom, scb, sx, sy, px, py);
+
+
+ActivateKeyboard();  // Gestion de l'edition 
+ActivateButton(1);   //  Action selection / copier - coller 
+ActivateMove(1);     //      "    "     "  
+ActivateButton(2);   //      "    "     "  
+// ActivateButton(3);   Pour afficher le menu des options (Fontes/couleur)
+Manage();
+return;
+}
+
+/* --Methode-- */
+PIConsole::~PIConsole()
+{
+delete[] mText;
+delete[] mAtt;
+delete[] mLPo;
+delete[] mStrBuf;
+delete[] mCmdStr;
+if (mScb) delete mScb;
+if (opmc) { delete opmc;  opmc=NULL; }
+}
+
+
+//++
+// Titre	Méthodes
+//	Seule les méthodes les plus usuelles sont décrites ici. Se reporter
+//	au fichier .h pour la liste complete des méthodes
+//	le type "enum PIVAType" est utilise pour definir les attributs
+//	graphiques du texte affiche dans l'objet PIConsole. Les attributs 
+//	de texte et de couleur peuvent etre combine a l'aide de l'operateur
+//	ou logique (|)
+//|  PIVA_Def : Attribut par defaut
+//|  PIVA_Bold : Caracteres gras
+//|  PIVA_Ital : Caracteres italiques
+//|  PIVA_Reverse : Caracteres en video inverse
+//|  PIVA_DefCol : Couleur par defaut
+//|  PIVA_Red : couleur rouge 
+//|  PIVA_Blue : Couleur bleue 
+//|  PIVA_Green : Couleur verte 
+//|  PIVA_Yellow : couleur jaune
+//|  PIVA_Magenta : couleur mauve 
+//--  
+
+//++
+// void  AddChar(char c, unsigned char va= PIVA_Def, bool ref=true)
+//	Ajout d'un caractere a la position courante. si "ref==true", 
+//	la fenetre est rafraichie. le caractere newline declenche
+//	un retour a la ligne.
+// void  AddStr(const char* strg, unsigned char va= PIVA_Def, bool ref=true);
+//	Ajout d'une chaine de caracteres a partir de la position courante. 
+//	si "ref==true", la fenetre est rafraichie. le caractere newline declenche
+//	un retour a la ligne.
+// void  AcceptCmd(bool acc=true, int nrecmx=20)
+//	Active/desactive l'edition de commandes. "nrecmx" indique la profondeur
+//	du tampon de rappel de commandes. Le message associe a l'objet PIConsole
+//	avec la qualificatif "PIMsg_OK" est envoye lors de la validation de la
+//	commande.
+// string  GetCmdString()
+//	Renvoie la chaine de caractere correspondant a la ligne editee.
+//--
+
+/* --Methode-- */
+void PIConsole::AddChar(char c, unsigned char va, bool ref)
+{
+int l1, l2;
+if (mOffL != 0)  // Decalage d'affichage precedant -> Tout rafraichir 
+  { l1 = mNL-mWSzL-1; l2 = mNL-1;  SetDispOffset(-1); }
+else l1 = l2 = mCurL; 
+if (c == '\n') {
+  mCurC = 0;
+  mCurL++;   
+  }
+else {
+  mText[mLPo[mCurL]+mCurC] = c;
+  mAtt[mLPo[mCurL]+mCurC] = va;
+  if (++mCurC == mNC) {mCurC = 0;  mCurL++; }
+  }
+
+if (mCurL >= (mNL-mNCmdL) ) { // Il faut scroller 
+  ScrollUp();  
+  mCurL = mNL-mNCmdL-1;
+  l1 = mNL-mWSzL-1; 
+  }
+if (l2 < mCurL) l2 = mCurL;
+if (ref) DisplayLines(mWGrC, l1, l2);
+return;
+}
+
+
+/* --Methode-- */
+void PIConsole::AddStr(const char* strg, unsigned char va, bool ref)
+{
+int l1, l2;
+if (mOffL != 0)  // Decalage d'affichage precedant -> Tout rafraichir 
+  { l1 = mNL-mWSzL-1; l2 = mNL-1;  SetDispOffset(-1); }
+else l1 = l2 = mCurL; 
+
+char c;
+while ( (c = *strg) != '\0') {
+  if ( c != '\n' ) {
+    mText[mLPo[mCurL]+mCurC] = c;
+    mAtt[mLPo[mCurL]+mCurC] = va;
+    if (++mCurC == mNC) {mCurC = 0;  mCurL++; }
+    }
+  else { mCurL++; mCurC = 0; } 
+  if (mCurL >= (mNL-mNCmdL) ) { // Il faut scroller 
+    ScrollUp();  
+    mCurL = mNL-mNCmdL-1;
+    l1 = mNL-mWSzL-1; 
+    }
+  strg++;
+  }
+
+if (l2 < mCurL) l2 = mCurL;
+if (ref) DisplayLines(mWGrC, l1, l2);
+return;
+}
+
+/* --Methode-- */
+void PIConsole::SelectFont(PIFontSize sz)
+{
+int asc, desc;
+mWGrC->SelFont(sz);
+mFTaille = sz;
+mFHaut = mWGrC->GetFont().GetFontHeight(asc, desc);
+mFLarg = (int)mWGrC->CalcStringWidth("ABCDEFGHIJ")/10;
+mWSzL = YSize()/mFHaut - 1;
+mWSzC = XSize()/mFLarg - 2;
+mOffL = 0;
+if (mScb) {
+  mScb->SetMinMax(0, NbLines()-1);
+  mScb->SetSlSize(WindNbLines());
+  mScb->SetValue(0);
+  }
+}
+
+
+/* --Methode-- */
+void PIConsole::AutoSize(int nl, int nc)
+{
+if ( (nl < 1) || (nc < 1) ) {
+  nl = mWSzL;   nc = mNC;
+  }
+if (nc > mNC) nc = mNC;
+int dsz[2];
+dsz[0] = (nc+2)*mFLarg - XSize();
+dsz[1] = (nl+1)*mFHaut - YSize();
+Send(Msg(), PIMsg_ResizeRequest, dsz);
+
+mWSzL = YSize()/mFHaut - 1;
+mWSzC = XSize()/mFLarg - 2;
+/*
+if (mScb) {
+  mScb->SetMinMax(0, NbLines()-1);
+  mScb->SetSlSize(WindNbLines());
+  mScb->SetValue(0);
+  }
+  */
+mOffL = 0;
+}
+
+/* --Methode-- */
+void PIConsole::PreferedSize(int& sx, int& sy)
+{
+sx = (mNC+2)*mFLarg;
+sy = (mWSzL+1)*mFHaut;
+return;
+}
+
+/* --Methode-- */
+void PIConsole::AcceptCmd(bool acc, int nmxrec)
+{
+int l1, l2;
+if (acc) {
+  if (mNCmdL)  return;  // Pas de changement d'etat
+  if (mCurL == (mNL-1) ) { l1 = mNL-mWSzL-1; ScrollUp(); mCurL = (mNL-2); }
+  else l1 = mNL-1;
+  mNCmdL = 1;
+  ClrCmd();
+  UpdCmdLine();
+  l2 = mNL-1;
+  if (nmxrec > 0) {
+    NMxRecall = (nmxrec > 5) ? nmxrec : 5;
+    if (mRStr)  delete[] mRStr;
+    mRStr = new string[NMxRecall];
+    mNComm = mRCindx = mRindx = 0;
+    mRStr[0] = "";
+    }
+  }
+else {
+  if (mNCmdL == 0)  return;  // Pas de changement d'etat
+  mNCmdL = 0;
+  ClearLine(mNL-1);
+  ClrCmd();
+  l1 = l2 = mNL-1;
+  delete[] mRStr;
+  mRCindx = mRindx = 0;
+  }
+DisplayLines(mWGrC, l1, l2);
+return;
+}
+
+/* --Methode-- */
+void PIConsole::SetPrompt(const char* prompt)
+{
+strncpy(mPrompt, prompt, 31);  
+mPrompt[31] = '\0';
+return;
+}
+
+/* --Methode-- */
+void PIConsole::SetDispOffset(int ldeb)
+{
+if (ldeb < 0)    { 
+  if (mScb) mScb->SetValue(0); 
+  mOffL = 0;
+  }
+else mOffL = (ldeb < mNL-mWSzL-1) ? ldeb : mNL-mWSzL-1;
+}
+
+
+/* --Methode-- */
+void PIConsole::Resize()
+{
+mWSzL = YSize()/mFHaut - 1;
+mWSzC = XSize()/mFLarg - 2;
+if (mScb) {
+  mScb->SetMinMax(0, NbLines()-1);
+  mScb->SetSlSize(WindNbLines());
+  mScb->SetValue(0);
+  }
+mOffL = 0;
+}
+
+/* --Methode-- */
+void PIConsole::Draw(PIGraphicGen* g, int /*x0*/, int /*y0*/, int /*dx*/, int /*dy*/)
+{
+EraseWindow();
+DisplayLines(g, 0, mNL);
+}
+
+
+/* --Methode-- */
+void PIConsole::Keyboard(int key, PIKeyModifier kmod)
+{
+
+if (kmod == PIKM_Alt) {
+  if (key == 'O' || key == 'o') {   // Menu des options 
+    ActivatePIConsOptionMenu(this);
+    return;
+    }
+  else if (key == 'A' || key == 'a') {  // Pour tout selectionner
+    mCPbeginC = 0; mCPendC = XSize(); 
+    mCPbeginL = 0;  mCPendL = YSize(); 
+    SaveSelection();
+    return;
+    }
+  else if (key == 'L' || key == 'l') {  // Pour lister le buffer de rappel
+    int nmxrec = (mNComm < NMxRecall) ? mNComm : NMxRecall;
+    if (nmxrec < 1)  return;
+    AddStr("PIConsole - Command history : \n",  PIVA_Def, false);
+    int ridx = mRCindx+nmxrec;
+    int kk;
+    char strg[64];
+    for(kk=0; kk<nmxrec; kk++) {
+      sprintf(strg, "%d- ", mNComm-nmxrec+kk+1);
+      AddStr(strg, PIVA_Def, false);
+      AddStr(mRStr[ridx%nmxrec].c_str(), PIVA_Def, false);
+      AddChar('\n', PIVA_Def, false);
+      ridx++;
+      }
+    AddChar('\n', PIVA_Def, false);
+    Refresh();
+    return;
+    }
+  }
+
+if (mNCmdL < 1)  return;
+
+int k;
+bool fgfk = false;
+
+if (kmod == PIKM_Cntl) {
+  switch (key) {
+    case 1 :  // <Cntl> A  Debut de ligne
+      mCCP = 0;
+      break;
+    case 3 :  // <Cntl> C  On efface la ligne
+      mCCP = mCLC = 0;
+      mCmdStr[mCLC] = '\0';
+      mRindx = mRCindx;
+      mChangeFg = true;
+      break;
+    case 5 :  // <Cntl> E  Fin de ligne
+      mCCP = mCLC;
+      break;
+    case 11 :  // <Cntl> K  On efface jusqu'en fin de ligne
+      mCLC = mCCP;
+      break;
+    }
+  }
+
+else if (kmod == PIKM_Alt) {
+  if (key == 'V' || key == 'v') RequestSelection();  // Pour coller (copier/coller)
+  }
+
+else if (kmod == PIKM_Blank) {
+  switch (key) {
+    case PIK_Return :    
+    case PIK_Enter :
+      SendCmd();
+      break;
+
+    case PIK_BackSpace :
+    case 127 :    // Touche del
+    case 8 :      // Touche backspace
+      if (mCCP > 0)  { 
+        for(k=mCCP-1; k<mCLC-1; k++)  mCmdStr[k] = mCmdStr[k+1];
+        mCmdStr[mCLC-1] = ' ';   mCCP--;  mCLC--;
+        mChangeFg = true;
+        }
+      //      printf("Keyb()-Debug- Backspace CCP,CLC= %d %d CmdStr= %s (L=%d) \n", mCCP, mCLC, 
+      //      mCmdStr, strlen(mCmdStr));
+      break;
+      
+    case PIK_Up :
+    case PIK_Down :
+//      printf("Keyb()-Debug- CursorUp/Down(%d)  Index= %d %d  \n", key, mRindx, mRCindx);
+      if (mNComm > 0) {
+        if (mChangeFg) { 
+          mCmdStr[mCLC] = '\0';
+          mRStr[mRCindx] = mCmdStr;
+          mChangeFg = false;
+	  }
+        int nmxrec = ((mNComm+1) < NMxRecall) ? mNComm+1 : NMxRecall;
+        if (key == PIK_Up) { 
+           mRindx --;
+           if (mRindx < 0) mRindx += nmxrec;
+	   }
+        else mRindx++;
+        int ridx = mRindx%nmxrec;
+        mCLC = mCCP = mRStr[ridx].length();
+        for(k=0; k< mCLC; k++)  mCmdStr[k] =  mRStr[ridx][k];
+        mCmdStr[mCLC] = '\0';      
+        }      
+      break;
+
+    case PIK_Left :
+      if (mCCP > 0)  mCCP--;
+      //      printf("Keyb()-Debug- Left CCP,CLC= %d %d  \n", mCCP, mCLC);
+      break;
+    case PIK_Right :
+      if (mCCP < mCLC)  mCCP++;
+      //      printf("Keyb()-Debug- Right CCP,CLC= %d %d  \n", mCCP, mCLC);
+      break;
+    default :
+      fgfk = true;
+      break;
+    }
+  }
+if ( ( fgfk && (kmod == PIKM_Blank) ) || (kmod == PIKM_Shift)  ) CmdAddChar(key);
+UpdCmdLine();
+// DisplayLines(mNL-1, mNL-1);
+return;
+}
+
+
+/* --Methode-- */
+void PIConsole::But1Press(int x, int y)
+{
+Send(Msg(), PIMsg_Active);
+AssignKeyboard();
+mWGrC->SelGOMode(PI_GOXOR);
+mWGrC->SelForeground(PI_Grey);
+mCPbeginC = x;  mCPbeginL = y;
+mCPendC = mCPendL = -1;
+} 
+
+/* --Methode-- */
+void PIConsole::Ptr1Move(int x, int y)
+{
+if (mCPendC >= 0) mWGrC->DrawBox(mCPbeginC, mCPbeginL, mCPendC-mCPbeginC, mCPendL-mCPbeginL);
+mCPendC = x;  mCPendL = y;
+mWGrC->DrawBox(mCPbeginC, mCPbeginL, mCPendC-mCPbeginC, mCPendL-mCPbeginL);
+}
+ 
+/* --Methode-- */
+void PIConsole::But1Release(int x, int y)
+{
+if ( (mCPendC >= 0) && (mCPbeginC >= 0) ) { 
+  mWGrC->DrawBox(mCPbeginC, mCPbeginL, mCPendC-mCPbeginC, mCPendL-mCPbeginL);
+  mCPendC = x;  mCPendL = y;
+  }
+else { 
+  mCPbeginC =  mCPendC = -1;
+  mCPbeginL = mCPendL = -1;
+  }
+mWGrC->SelGOMode(PI_GOCopy);
+mWGrC->SelForeground(mFgC);
+SaveSelection();
+} 
+
+/* --Methode-- */
+void PIConsole::But2Press(int x, int y)
+{
+RequestSelection();  // Pour recuperer la selection = coller (copier/coller)
+} 
+
+/* --Methode-- */
+void PIConsole::But3Press(int x, int y)
+{
+ActivatePIConsOptionMenu(this);
+}
+
+/* --Methode-- */
+void PIConsole::PasteSelection(unsigned int typ, void *pdata, unsigned int l)
+{
+if (typ != PICP_string) return;
+int i;
+char *pc = (char *)pdata;
+for(i=0; i<l; i++) {
+  if ((i > 0) && (pc[i] == '\n'))  SendCmd();
+  else CmdAddChar(pc[i]);
+}
+UpdCmdLine();
+}
+
+/* --Methode-- */
+void PIConsole::SelectionLost()
+{
+// printf("Debug PIConsole::SelectionLost() %lx (L=%d)\n",(long)mCPBuffer, mCPBufLen);
+if (!mCPBuffer) return;
+delete[] mCPBuffer;  
+mCPBuffer = NULL;
+mCPBufLen = 0;
+mCPbeginC =  mCPendC = -1;
+mCPbeginL = mCPendL = -1;
+int i,j;
+int l1,l2;
+l1 = mNL+1; l2 = -1;
+for(i=0; i<mNL; i++)   // On enleve le bit select a tous les caracteres 
+  for(j=0; j<mNC; j++) 
+    if ( mAtt[mLPo[i]+j] & PIVA_Select) {
+      if (l1 > i)  l1 = i;
+      if (l2 < i)  l2 = i;
+      mAtt[mLPo[i]+j] &= ~PIVA_Select ;
+    }
+
+if (IsVisible() && l2 > -1)  DisplayLines(mWGrC, l1, l2);
+return;
+}
+
+/* --Methode-- */
+void PIConsole::SelectionTransferEnd()
+{
+// printf("Debug PIConsole::SelectionTransferEnd() -Rien- %lx (L=%d)\n",(long)mCPBuffer, mCPBufLen);
+}
+
+
+/* --Methode-- */
+void * PIConsole::ProvideSelection(unsigned int& typ, unsigned int& len)
+{
+typ = PICP_string;
+len = mCPBufLen;
+return(mCPBuffer);
+}
+
+/* ----------------------------------------------------------------------------- */
+/*    ---------------------- Methodes protected -------------------------        */
+/* ----------------------------------------------------------------------------- */
+
+
+/* --Methode-- 
+void PIConsole::DebugPrint(int lp)
+{
+printf("PIConsole::DebugPrint() - NL,NC= %d %d - WSzL,C= %d %d Cur= %d %d\n", mNL, mNC, 
+        mWSzL, mWSzC, mCurL, mCurC);
+printf(" OffL, NCmdL= %d %d - mCCP, mCLC= %d %d - LPo= %d %d \n", 
+        mOffL, mNCmdL, mCCP, mCLC, mLPo[mNL-2], mLPo[mNL-1]);
+
+if (lp == 0)  return;
+int i,j;
+for(j=0; j<mNL; j++) {
+  printf("Line[%d] (%d) = ", j, mLPo[j]);
+  for(i=0; i<mNC; i++)  putchar(mText[mLPo[j]+i]);
+  putchar('\n');
+  }
+return;
+}
+*/
+
+
+/* --Methode-- */
+void PIConsole::AssocScrollBar(PIContainer* par, const char* nom, bool scb, int sx, int sy, int px, int py)
+{
+if (!scb) {
+  mScb = NULL;
+  msgScb = 0;
+  SetBinding(PIBK_fixed, PIBK_fixed, PIBK_fixed, PIBK_fixed);
+  return;   
+}
+
+sx -= Scb_Width;
+// SetSize(sx, sy);
+SetBinding(PIBK_fixed, PIBK_fixed, PIBK_fixed, PIBK_fixed);
+char name[128];
+strcpy(name,"ScrollBar_");
+strncat(name, nom, 127);
+msgScb = Msg()+55;
+mScb = new PIScrollBar (par, name, msgScb, kSDirDownUp, Scb_Width, sy, px+sx, py);
+mScb->SetBinding(PIBK_free, PIBK_fixed, PIBK_fixed, PIBK_fixed);
+  
+mScb->SetMsgParent(this);
+mScb->SetMinMax(0, NbLines()-1);
+mScb->SetSlSize(WindNbLines());
+mScb->SetValue(0);
+mScb->ActivateDrag(true);
+}
+
+/* --Methode-- */
+void PIConsole::ScrollUp()
+{
+int i,l,kpo;
+l = mNL-1-mNCmdL;
+kpo = mLPo[0];
+for(i=0; i<mNL-mNCmdL-1; i++)   mLPo[i] = mLPo[i+1];
+mLPo[l] = kpo;
+ClearLine(l);
+return;
+}
+
+/* --Methode-- */
+void PIConsole::ClearLine(int l)
+{
+if ((l<0) || (l >= mNL)) return;
+int j;
+for(j=0; j<mNC; j++) {
+  mText[mLPo[l]+j] = ' ';
+  mAtt[mLPo[l]+j] = PIVA_Def;
+  }
+return;
+}
+
+/* --Methode-- */
+void PIConsole::DisplayLines(PIGraphicGen* g, int l1, int l2)
+{
+int j,l,k,l0;
+int x,y;
+
+// DBG printf("PIConsole::DisplayLines(%d %d ) -> %d - %lx \n ", l1, l2, 
+//            (int)IsVisible(), (long)XtWindow(XtWdg()));
+
+if (! IsVisible() )   return;
+
+int lva = -1;
+int ccol, cfnt;
+
+PIFontAtt vafat[8] = {PI_RomanFont, PI_BoldFont, PI_ItalicFont,
+                      PI_RomanFont, PI_RomanFont, PI_BoldFont, 
+                      PI_ItalicFont, PI_RomanFont};
+PIColors fgc, bgc, dbgc;
+PIColors col[6] = {PI_Black, PI_Red, PI_Blue, PI_Green, PI_Yellow, PI_Magenta};
+
+g->SelForeground(mFgC);
+g->SelBackground(mBgC);
+fgc =  col[0] = g->GetForeground();
+dbgc = bgc =  g->GetBackground();
+
+int dx = mFLarg;
+int dy = mFHaut/2;
+int dxo2 = dx/2;
+if (dxo2 > 3)  dxo2 = 3;
+int dyo2 = dy/2;
+if (dyo2 > 3)  dyo2 = 3;
+
+g->DrawBox(dxo2, dyo2, (mNC+2)*mFLarg-2*dxo2, (mWSzL+1)*mFHaut-dyo2);
+
+l0 = mNL-mWSzL-mOffL;
+if (l0 < 0) l0 = 0;
+if (l1 < l0) l1 = l0;
+if (++l2 > mNL-mOffL) l2 =  mNL-mOffL;
+
+for(l=l1; l<l2; l++) {
+ y = (l-l0+1)*mFHaut+dy;
+ k = 0;   x = dx;
+ for(j=0; j<mNC; j++) {
+   if (mAtt[mLPo[l]+j] != lva) {
+     if (k > 0) {
+       mStrBuf[k] = '\0';     
+       g->DrawOpaqueString(x, y, mStrBuf);
+       //     printf("l,J,K=%d %d %d - X,Y= %d %d - %s \n", l,j,k,x,y,mStrBuf);
+       x += k*mFLarg;  k = 0;  
+       }
+     lva = mAtt[mLPo[l]+j];
+     cfnt = lva & 15;   //  Index de fonte
+     ccol = lva >> 4;   //  Index de couleur
+     fgc = col[ccol];
+     if (cfnt & PIVA_Select) 
+       { bgc = PI_Grey;   g->SelFont(mFTaille, vafat[cfnt-PIVA_Select]); }
+     else { bgc = dbgc; g->SelFont(mFTaille, vafat[cfnt]); }
+     
+     if (cfnt & PIVA_Reverse) { 
+       g->SelForeground(bgc);
+       g->SelBackground(fgc);
+       }
+     else  { 
+       g->SelForeground(fgc);
+       g->SelBackground(bgc);
+       }
+     }
+   mStrBuf[k] = mText[mLPo[l]+j];
+   k++;
+   }
+   if (k > 0) {
+     mStrBuf[k] = '\0';     
+     g->DrawOpaqueString(x, y, mStrBuf);
+     //     printf("l,J,K=%d %d %d - X,Y= %d %d - %s \n", l,j,k,x,y,mStrBuf);
+   }
+ }
+
+g->SelForeground(fgc);
+g->SelBackground(dbgc);
+return;
+}
+
+/* --Methode-- */
+void PIConsole::UpdCmdLine()
+{
+//  char strg[260];  debug
+int l1,l2;
+l1 = l2 = mNL-1;
+if (mOffL != 0)  // Decalage d'affichage precedant -> Tout rafraichir 
+  { l1 = mNL-mWSzL-1; l2 = mNL-1;  SetDispOffset(-1); }
+
+ClearLine(mNL-1);
+int j1,j2,j,jj2;
+j1 = strlen(mPrompt);
+for(j=0; j<j1; j++) {
+  mText[mLPo[mNL-1]+j] = mPrompt[j];
+  mAtt[mLPo[mNL-1]+j] = PIVA_Def;
+//  strg[j] = mPrompt[j];    debug
+  }  
+jj2 = mWSzC-j1;
+if (mDCOff>=mCCP) mDCOff = 0;
+int koff = ((mCCP-mDCOff) >= jj2) ? mCCP-(jj2/2) : mDCOff;
+mDCOff = koff;
+int kmx = mCLC-koff;
+j2 = j1+kmx;
+if (j2 > mWSzC)  j2 = mWSzC;
+int k = koff;
+for(j=j1; j<j2; j++) {
+  mText[mLPo[mNL-1]+j] = mCmdStr[k];
+  mAtt[mLPo[mNL-1]+j] = PIVA_Bold;
+//  strg[j] = mCmdStr[k];   debug 
+  k++;
+  }  
+
+// strg[j] = '\0';   Debug
+// printf("UpdCmdLine() %d %d - %s (%d) \n [%d %d %d] %d\n", koff,kmx,strg,j1+mCCP-koff, mWSzC, j1, jj2, mCCP-(jj2/2));
+mAtt[mLPo[mNL-1]+j1+mCCP-koff] = PIVA_Reverse;    // Pour le curseur
+DisplayLines(mWGrC, l1, l2);
+}
+
+/* --Methode-- */
+void PIConsole::ClrCmd() 
+{ 
+mCCP = 0; mCLC = 0; mDCOff = 0;
+mCmdStr[0] = '\0'; 
+}  
+
+/* --Methode-- */
+void PIConsole::SendCmd() 
+{ 
+  mCmdStr[mCLC] = '\0';
+  //      printf("Keyb()-Debug- <CR/Enter> CmdStr= %s (L=%d)\n", mCmdStr, strlen(mCmdStr) );
+  // Gestion de rappel des commandes 
+  if (mCLC > 0) {
+    mRStr[mRCindx] = mCmdStr;
+    mRCindx++;  mNComm++;
+    if (mRCindx >= NMxRecall)  mRCindx = 0;
+    mRindx = mRCindx;
+  }
+  mChangeFg = false;
+  mCmd = mCmdStr;
+  ClrCmd();
+  Send( Msg(), PIMsg_OK, NULL);
+  return;
+}
+
+/* --Methode-- */
+void PIConsole::CmdAddChar(int key)
+{
+  int k, kmx;
+  if ( (mCCP < CmdStrLen) && isprint(key) ) {   // Ajout de caracteres
+    if (mCCP < mCLC)  { // Insertion au milieu de la chaine
+      kmx = (mCLC < CmdStrLen) ? mCLC : CmdStrLen-1;
+      //      printf(" ++DBG++ C=%d L=%d MX=%d KMX=%d\n", mCCP, mCLC, CmdStrLen,kmx);
+      for(k=kmx; k>mCCP; k--) mCmdStr[k] = mCmdStr[k-1];   mCLC = kmx+1;      
+      }
+    mCmdStr[mCCP] = key;  mCCP++; 
+    if (mCCP > mCLC)  mCLC = mCCP;
+    mChangeFg = true;
+    }
+}
+
+
+/* --Methode-- */
+void PIConsole::SelFgBgCol(PIColors fc, PIColors bc)
+{
+mFgC = fc; mBgC = bc;
+SetBackgroundColor(bc);
+}
+
+
+/* --Methode-- */
+void PIConsole::SaveSelection()
+{
+int i,j,k,l;
+int l1, l2, nl, nc;
+
+if (mCPbeginC > mCPendC) { j = mCPbeginC; mCPbeginC = mCPendC ; mCPendC = j; }
+if (mCPbeginL > mCPendL) { j = mCPbeginL; mCPbeginL = mCPendL ; mCPendL = j; }
+
+nc = (mCPendC-mCPbeginC)/mFLarg;
+nl = (mCPendL-mCPbeginL)/mFHaut;
+if (nl < 1) nl = 1;  // On selectionne au moins une ligne
+// printf("*DBG* NC=%d NL=%d \n",nc, nl); 
+l1 = mNL+1; l2 = -1;
+
+if (mCPBuffer) {
+  delete[] mCPBuffer;  
+  mCPBuffer = NULL;
+  mCPBufLen = 0;
+  for(i=0; i<mNL; i++)   // On enleve le bit select a tous les caracteres 
+    for(j=0; j<mNC; j++) 
+      if ( mAtt[mLPo[i]+j] & PIVA_Select) {
+        if (l1 > i)  l1 = i;
+        if (l2 < i)  l2 = i;
+        mAtt[mLPo[i]+j] &= ~PIVA_Select ;
+      }
+  }
+
+// printf("**DBG** Save: C= %d %d  L = %d %d \n", mCPbeginC, mCPendC, mCPbeginL, mCPendL);
+
+
+// On transforme la position sur la fenetre en position en caracteres ds les buffers
+
+mCPbeginC = mCPbeginC/mFLarg-1;
+mCPendC = (int) ( (float)mCPendC/(float)mFLarg-0.8 );
+mCPbeginL = (int) ( (float)mCPbeginL/(float)mFHaut-0.5 ) ;
+mCPendL = (int) ( (float)mCPendL/(float)mFHaut-0.5 ) ;
+if (mCPendL <= mCPbeginL) mCPendL = mCPbeginL+1;  // Au moins une ligne selectionnee
+// printf("..DBG.. C= %d %d  L = %d %d ", mCPbeginC, mCPendC, mCPbeginL, mCPendL);
+j = mNL-mWSzL-mOffL;
+mCPbeginL += j;  mCPendL += j;
+// printf(" -> %d %d \n", mCPbeginL, mCPendL);
+
+if (mCPbeginC < 0) mCPbeginC = 0;
+if (mCPendC > mNC) mCPendC = mNC;
+if (mCPbeginL < 0) mCPbeginL = 0;
+if (mCPendL > mNL) mCPendL = mNL;
+
+if ( (nc > 0) && (nl > 0) ) {
+if (!ClaimSelection()) { 
+  mCPbeginC = mCPendC = -1;
+  mCPbeginL = mCPendL = -1;
+  if (l2 > -1) DisplayLines(mWGrC, l1, l2);  
+  return;
+  }
+  l = (mCPendC-mCPbeginC+1) * (mCPendL-mCPbeginL);
+  if (l < 0) l = 0;
+  mCPBufLen = l;
+  mCPBuffer = new char[l+1];  
+  k = 0;  
+  for(j=mCPbeginL; j<mCPendL; j++) { 
+    for(i=mCPbeginC; i<mCPendC; i++)  { 
+      mAtt[mLPo[j]+i] |= PIVA_Select;
+      mCPBuffer[k] = mText[mLPo[j]+i]; k++; 
+      }
+    if (j<mCPendL-1) mCPBuffer[k] = '\n'; k++;
+    }
+  mCPBuffer[l] = '\0';
+  if (l1 > mCPbeginL) l1 = mCPbeginL;
+  if (l2 < (mCPendL-1))  l2 = mCPendL-1;
+  }
+else {  
+  l = 0;   
+  mCPbeginC =  mCPendC = mCPbeginL = mCPendL = -1; 
+  mCPBufLen = 0;
+  mCPBuffer = new char[10];  
+  mCPBuffer[0] = mCPBuffer[1] = '\0';
+  }
+
+//  printf("*DBG* Save_Display %d %d \n", l1, l2);
+
+if (l2 > -1) DisplayLines(mWGrC, l1, l2);
+}
+
+/* --Methode-- */
+void PIConsole::Process(PIMessage msg, PIMsgHandler* sender, void* data)
+{
+int off;
+// printf("PIConsole::Process() UserMsg()= %d ModMsg= %d \n", (int)UserMsg(msg), 
+//        (int)ModMsg(msg) );
+
+if (sender == opmc) { // Menu des options 
+  bool fgr = true;
+  switch (UserMsg(msg)) {
+    case 3101 :
+      SelectFont(PI_SmallSizeFont);
+      AutoSize();
+      break;
+    case 3102 :
+      SelectFont(PI_NormalSizeFont);
+      AutoSize();
+      break;
+    case 3103 :
+      SelectFont(PI_LargeSizeFont);
+      AutoSize();
+      break;
+    case 3201 :
+      SelFgBgCol(PI_Black, PI_White);
+      break;
+    case 3202 :
+      SelFgBgCol(PI_White, PI_Black);
+      break;
+    case 3203 :
+      SelFgBgCol(PI_Yellow, PI_Black);
+      break;
+    case 3301 :
+      AutoSize(25, 132);
+      break;
+    case 3302 :
+      AutoSize(20, 80);
+      break;
+    case 3303 :
+      AutoSize(10, 80);
+      break;      
+    case 3304 :
+      AutoSize(5, 60);
+      break;      
+    default :
+      fgr = false;
+      break;
+    }
+  if (fgr) Refresh();
+  delete opmc;  opmc = NULL;
+  }
+// Le traitement du scroll-bar
+else if (((ModMsg(msg) == PIMsg_DataChanged) || 
+	  (ModMsg(msg) == PIMsg_Drag) ) && (UserMsg(msg) == msgScb) ) {
+  off = * ((int *)data);
+//  printf(" PIConsole::Process() From ScrollBar : Off=%d \n ", off);
+  SetDispOffset(off);
+  Refresh();
+  }
+// Sinon, on retranmet le message
+else ReSend(msg, sender, data); 
+}
+
Index: /tags/V_Dec2002/SophyaPI/PI/picons.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/picons.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/picons.h	(revision 2309)
@@ -0,0 +1,120 @@
+// This may look like C code, but it is really -*- C++ -*-
+// composant graphique de type console (terminal) 
+//                    R. Ansari   12/97
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PICONSOLE_H
+#define PICONSOLE_H
+
+#include "pisysdep.h"
+#include <string>
+
+#include PISTDWDG_H 
+#include PICONT_H
+#include PIBWDG_H
+
+enum PIVAType {    
+  PIVA_Def = 0,
+  PIVA_Bold = 1 << 0,
+  PIVA_Ital = 1 << 1,
+  PIVA_Reverse = 1 << 2,
+//  Le 4eme bit (<<3) est reserve pour l'usage interne (PIVA_Select)
+  PIVA_DefCol = 0,
+  PIVA_Red = 1 << 4,
+  PIVA_Blue = 2 << 4, 
+  PIVA_Green = 3 << 4, 
+  PIVA_Yellow = 4 << 4,
+  PIVA_Magenta = 5 << 4
+};
+
+class PIConsole : public PIBaseWdg {
+public:
+                     PIConsole(PIContainer* par, const char* nom, PIMessage msg, int nl, int nc, 
+                               int sx=300, int sy=200, int px=0, int py=0, bool scb=true);
+                     ~PIConsole();
+
+// Interface d utilisation : 
+          void       AddChar(char c, unsigned char va= PIVA_Def, bool ref=true);
+          void       AddStr(const char* strg, unsigned char va= PIVA_Def, bool ref=true);
+
+          void       SelectFont(PIFontSize sz=PI_NormalSizeFont);
+          void       AutoSize(int nl=-1, int nc=-1);
+          void       PreferedSize(int& sx, int& sy);
+          void       AcceptCmd(bool acc=true, int nrecmx=20);
+          void       SetPrompt(const char* prompt); 
+  inline  void       SetPrompt(string const& pr) { SetPrompt(pr.c_str()); } 
+  inline  string     GetPrompt() const { return (string(mPrompt)); } 
+
+  inline  int        WindNbLines() { return mWSzL; }
+  inline  int        NbLines() { return mNL; }          
+  inline  string     GetCmdString() { return(mCmd); }
+
+// Gestion des evenements input/draw 
+  virtual void       Draw(PIGraphic* g, int x0, int y0, int dx, int dy);
+  virtual void       Resize();
+  virtual void       Keyboard(int key, PIKeyModifier kmod);
+  virtual void       But1Press(int x, int y);
+  virtual void       Ptr1Move(int x, int y);
+  virtual void       But1Release(int x, int y);
+  virtual void       But2Press(int x, int y);
+  virtual void       But3Press(int x, int y);
+
+// Gestion de copier/coller
+  virtual void       PasteSelection(unsigned int typ, void *pdata, unsigned int l);
+  virtual void*      ProvideSelection(unsigned int& typ, unsigned int& len);
+  virtual void       SelectionLost();
+  virtual void       SelectionTransferEnd();
+
+protected:
+          void       AssocScrollBar(PIContainer* par, const char* nom, bool scb, int sx, int sy, int px, int py);
+          void       ScrollUp();
+          void       SetDispOffset(int ldeb=-1);
+          void       ClearLine(int l);
+          void       DisplayLines(PIGraphicGen* g, int l1, int l2);
+          void       UpdCmdLine();
+          void       ClrCmd();
+          void       SendCmd();
+          void       CmdAddChar(int key);
+          void       SelFgBgCol(PIColors fc=PI_Black, PIColors bc=PI_White);
+          void       SaveSelection();  // Pour copier la selection dans un buffer
+
+  virtual void       Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+
+
+  int mNL, mNC;         // Nb de lignes, colonnes total de la console
+  int mCurL, mCurC;     // Numero de ligne, colonne courante
+  int mWSzL, mWSzC;     // Taille de fenetre en lignes, colonnes
+  int mOffL;            // Offset d affichage (lignes) 
+  int mNCmdL, mLCOff;   // Nb de lignes reserve a l entree des commandes
+  int mDCOff;           // Offset (en caractere) pour l affichage de la ligne de commande
+  char* mText;          // Contenu de la console
+  unsigned char* mAtt;  // Attributs du contenu (bold, ...)
+  int* mLPo;            // Adresse des lignes ds les tableaux mText, mAtt
+  char* mStrBuf;        // Buffer 
+  int mFHaut, mFLarg;   // Hauteur, Largeur des caracteres 
+  PIFontSize mFTaille;  // Taille des caracteres 
+  PIColors mFgC, mBgC;  // Couleur Avant - arriere plan
+  char  mPrompt[32];    // Le prompt
+  char* mCmdStr;        // La commande 
+  int mCCP, mCLC;       // Position du curseur, longeur de la commande
+  string mCmd;          // Le string de la derniere commande validee
+
+// Pour le rappel des commandes
+  int NMxRecall, mNComm;    // Profondeur de la pile de rappels, nb de commandes
+  string * mRStr;           // Stockage des chaines 
+  int mRCindx, mRindx;      // Index pour le rappel
+  bool mChangeFg;           // Texte modifie
+  
+// Gestion du buffer de copie
+  char* mCPBuffer;
+  unsigned int mCPBufLen;
+  int mCPbeginC, mCPbeginL;
+  int mCPendC, mCPendL;
+  
+// S il y a un scroll-bar associe
+  PIScrollBar* mScb;
+  PIMessage msgScb;
+};
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/picontainergen.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/picontainergen.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/picontainergen.cc	(revision 2309)
@@ -0,0 +1,291 @@
+//  Classe de base pour les conteneurs de PIWdg pour
+//  programmes graphiques interactives
+//
+//                  E.Aubourg , R. Ansari  96 - 98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include <stdio.h>
+
+#include "picontainergen.h"
+
+//++
+// Class	PIContainer
+// Lib		PI
+// include	picontainergen.h
+//
+//	Classe conteneur gérant un ensemble d'objets "PIWdg". Cette classe 
+//	organise la hiérarchie des objets "PIWdg" et donc aussi des "PIMsgHandler",
+//	contrôle la géométrie des objets "PIWdg" contenus, ainsi que leur 
+//	visibilité et activité. Le positionnement initial est controle par
+//	un objet *PILayoutMgr* qui peut eventuellement modifier la postion
+//	ou la taille de l'objet "PIWdg" ajouté. Les attributs d'attachement
+//	de l'objet ("PIWdg::SetBinding()") contrôle le repositionnement
+//	lors du changement de taille du "PIContainer".
+//	La classe "PIContainer" est une des 
+//	classes de PI qui ont une implementation dépendante du systeme utilisé
+//	(Mac, XWindow, ...). La classe "PIContainerGen" est la classe qui
+//	définit l'interface, et ne pas doit être instanciée directement
+//	(Méthodes virtuelles pures). Les objets instanciés sont de la 
+//	classes "PIContainer" et le fichier entête correspondant est "PICONT_H"
+//	défini dans "pisysdep.h"
+//--
+//++
+// Links	Parents
+// PIWdg
+//--
+//++
+// Links	Voir aussi
+// PILayoutMgr
+//--
+//++
+// Titre	Constructeur
+//--
+//++
+// PIContainer(PIContainerGen *par, const char *nom, int sx, int sy, int px, int py)
+//	Création d'un objet "PIContainer" dans le conteneur parent "par", de
+//	taille "sx,sy", se trouvant à la position "px,py" avec le nom "nom".
+//	Tous les widgets fils sont détruits (delete) par le destructeur
+//	(voir "SetAutoDelChilds()")
+// long kind()
+//	Renvoie le type de la classe de l'objet ("=PIContainerGen::ClassId") pour cette classe.
+//--
+//++
+// Titre	Méthodes
+//--
+//++
+// void SetLayoutMgr(PILayoutMgr* nlay)
+//	Permet de changer le gestionnaire de positions ("PILayoutMgr") du conteneur,
+//	et donc la stratégie de positionnement des objets "PIWdg" fils. 
+//	le LayoutMgr par défaut n'applique aucune contrainte sur la position
+//	ou la taille des objets ajoutés.
+//	Cette méthode ne peut être appelé que pour un conteneur vide (sans PIWdg fils).
+//	Il est conseillé de l'appeler juste après la création du "PIContainer"
+// PILayoutMgr* GetLayoutMgr()
+//	Retourne le gestionnaire de positions/tailles du conteneur.
+// void Show()
+//	Rend l'objet visible à l'écran. Tous les objets "PIWdg" contenus et qui sont dans 
+//	l'état actif sont visibles.
+// void Hide()
+//	Rend l'objet et tous les objets contenus invisibles.
+// void  PSPrint(PSFile *psf, int ofx=0, int ofy=0)
+//	Appelle la méthode "PSPrint()" pour tous les objets contenus.
+// void  SetAutoDelChilds(bool ad = true)
+//	Contrôle le comportement de l'objet conteneur vis à vis des objets
+//	contenus lors de la destruction. si "ad=true", les objets contenus 
+//	sont détruits lors de l'appel du destructeur de l'objet conteneur. 
+// int  NbChilds()
+//	Retourne le nombre de "PIWdg" contenus.
+// PIWdg* GetChild(int n)
+//	Retourne le "PIWdg" numéro "n" (0..NbChilds()-1) 
+//--
+//++
+// Titre 	Méthodes particulières
+//	Les méthodes ci-dessous ne doivent pas être appelées directement.
+//--
+//++
+// void ChildAdd(PIWdg* child)
+//	Méthode qui est appelée lors de l'attachement d'un nouvel objet (création)
+//	Appelle la méthode correspondante du "PILayoutMgr"
+// void ChildAdd(PIWdg* child)
+//	Méthode qui est appelée lors du détachement d'un objet (destruction)
+//	Appelle la méthode correspondante du "PILayoutMgr"	
+//--
+
+
+/* --Methode-- */
+PIContainerGen::PIContainerGen(PIContainerGen *par, const char *nom, 
+                               int sx, int sy, int px, int py)
+: PIWdg(par, nom, sx, sy, px, py)  
+{
+stvis = false;
+stfcr = false;
+layout = new PILayoutMgr;
+layout->SetContainer(this); 
+}
+
+
+/* --Methode-- */
+PIContainerGen::~PIContainerGen()
+{
+delete layout;
+}
+
+/* --Methode-- */
+void PIContainerGen::SetLayoutMgr(PILayoutMgr* nlay)
+{
+if (nlay == NULL) return;
+if (NbChilds() > 0) {
+  fprintf(stderr, "PIContainerGen::SetLayoutMgr()/ Error! Container has childs (N = %d) \n", NbChilds()); 
+  return;
+  }
+delete layout;
+layout = nlay;
+layout->SetContainer(this); 
+}
+
+/* --Methode-- */
+void PIContainerGen::PSPrint(PSFile *psf, int ofx, int ofy, double scale_x, double scale_y)
+{
+int i;
+if (!psf)  return;
+if (!Visible())  return;
+for(i=0; i<NbChilds(); i++)  
+  GetChild(i)->PSPrint(psf, ofx+XPos(), ofy+YPos(), scale_x, scale_y); 
+return;
+}
+
+/* --Methode-- */
+void PIContainerGen::Show()
+{
+stvis = true;
+Manage();
+return;
+}
+
+/* --Methode-- */
+void PIContainerGen::Hide()
+{
+stvis = false;
+UnManage();
+return;
+}
+
+/* --Methode-- */
+bool PIContainerGen::Visible()
+{
+if (Parent())  return(stvis && Parent()->Visible());
+else return(stvis && IsVisible());
+}
+
+/* --Methode-- */
+void PIContainerGen::ChildAdd(PIWdg* child)
+{
+layout->ChildAdd(child);
+// Reza 13/10/98 : il faut que child->FinishCreate() 
+// soit appele pour les PIWdg ajoute quand le  container est deja affiche et son FinishCreate() appele
+if (stfcr)  child->FinishCreate(); 
+return;
+}
+
+/* --Methode-- */
+void PIContainerGen::ChildDel(PIWdg* child)
+{
+layout->ChildDel(child);
+}
+
+/* --Methode-- */
+int PIContainerGen::NbChilds()
+{
+return(layout->NbChilds());
+}
+
+/* --Methode-- */
+PIWdg* PIContainerGen::GetChild(int n)
+{
+return(layout->GetChild(n));
+}
+
+/* --Methode-- */
+void PIContainerGen::SetAutoDelChilds(bool ad)
+{
+layout->SetAutoDelChilds(ad) ;
+}
+
+
+/* --Methode-- */
+void PIContainerGen::FinishCreate()
+{
+if (stfcr)  return;
+PIWdg::FinishCreate();    
+int k;
+for(k=0; k<NbChilds(); k++)  GetChild(k)->FinishCreate();
+stfcr = true;
+}
+
+
+// ------------------------------------------------------------------
+//  Classe PILayoutMgr (Gestionnaire de positions/tailles PIWdg fils
+// ------------------------------------------------------------------
+//++
+// Class	PILayoutMgr
+// Lib		PI
+// include	picontainergen.h
+//
+//	Classe de gestionnaire de positions/tailles initiales des "PIWdg"
+//	fils pour les "PIContainer".
+//	La classe de base n'impose aucune contrainte sur les positions/tailles.
+//--
+//++
+// Links	Voir
+// PIContainer
+//--
+
+//++
+// Titre	Constructeur, méthodes
+//--
+//++
+// PILayoutMgr()
+//	Constructeur
+// void ChildAdd(PIWdg* child)
+//	Méthode appelé lors de l'ajout d'un nouveau "PIWdg" au conteneur.
+// void ChildDel(PIWdg* child)
+//	Méthode appelé lors de la suppression d'un "PIWdg"
+// int  NbChilds() 
+//	Nombre de "PIWdg" gérés.
+// PIWdg* GetChild(int n)
+//	Retourne l'objet "PIWdg" numéro "n"
+//--
+
+#define NCHALGRP 8
+
+/* --Methode-- */
+PILayoutMgr::PILayoutMgr()
+{
+mNCh = 0;
+mACSup = false;   // Pas de Suppression automatique des widgets fils au delete
+mPaSup = false;
+mChilds = new (PIWdg* [NCHALGRP]);
+mMxCh = NCHALGRP;
+mCont = NULL;
+}
+
+/* --Methode-- */
+PILayoutMgr::~PILayoutMgr()
+{
+mPaSup = true;   // Pour prevenir ChildDel()
+if (mACSup)
+  for(int i=0; i<mNCh; i++)  delete mChilds[i];
+delete[] mChilds;
+}
+
+/* --Methode-- */
+void PILayoutMgr::ChildAdd(PIWdg* child)
+{
+if (child == NULL)  return;
+if (mNCh == mMxCh)
+  {
+  PIWdg ** och = mChilds;
+  mChilds = new (PIWdg * [mMxCh+NCHALGRP]);
+  for(int i=0; i<mNCh; i++)  mChilds[i] = och[i];
+  delete[] och;
+  mMxCh += NCHALGRP;
+  }  
+mChilds[mNCh] = child;   mNCh++; 
+return;
+}
+
+/* --Methode-- */
+void PILayoutMgr::ChildDel(PIWdg* child)
+{
+if (mPaSup) return;  // Ne rien faire si delete initie par Container-parent : Le LayoutMgr lui-meme
+if ((child == NULL) || (mNCh < 1))  return;
+for(int i=0; i<mNCh; i++)  
+  if (mChilds[i] == child)
+    {
+    mNCh--;
+    mChilds[i] = mChilds[mNCh];
+    break;
+    }
+return;
+}
+
Index: /tags/V_Dec2002/SophyaPI/PI/picontainergen.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/picontainergen.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/picontainergen.h	(revision 2309)
@@ -0,0 +1,73 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive    PIContainerGen
+//                  E.Aubourg , R. Ansari  96 - 98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PICONTAINERBASE_SEEN
+#define PICONTAINERBASE_SEEN
+
+#include "pisysdep.h"
+
+#include PIWDG_H
+
+class PIContainerGen;
+//  Classe gestionnaire du positionnement/tailles des PIWdg d'un PIContainer
+class PILayoutMgr {
+public:
+  			PILayoutMgr();
+  virtual 		~PILayoutMgr();
+
+  inline  void		SetContainer(PIContainerGen* pic) { mCont = pic; }
+
+  virtual void		ChildAdd(PIWdg* child);
+  virtual void		ChildDel(PIWdg* child);
+
+  inline  int		NbChilds() { return(mNCh); }
+  inline  PIWdg*	GetChild(int n) 
+                        { if ( (n < 0) || (n >= mNCh))  return(NULL);
+                        else return (mChilds[n]); }
+  inline  void		SetAutoDelChilds(bool ad = true) { mACSup = ad; } 
+
+protected:
+  PIWdg                ** mChilds;
+  int                  mNCh, mMxCh;
+  bool                 mPaSup, mACSup;
+  PIContainerGen*      mCont;   // Le PIContainer auquel on est attache
+};
+
+// Classe conteneur pour le regroupement hierarchique (Fenetre/MsgHandler) des PIWdg
+class PIContainerGen : public PIWdg 
+{
+public:
+  enum {ClassId = 1500};
+
+               PIContainerGen(PIContainerGen *par, const char *nom, 
+                              int sx=10, int sy=10, int px=0, int py=0);
+  virtual      ~PIContainerGen();
+
+  virtual long         kind() {return ClassId; }
+
+  virtual void	       SetLayoutMgr(PILayoutMgr* nlay);
+  inline  PILayoutMgr* GetLayoutMgr() { return(layout); }
+
+  virtual void         PSPrint(PSFile *psf, int ofx=0, int ofy=0,
+			       double scale_x=1., double scale_y=1.);
+
+  virtual void         Show();
+  virtual void         Hide();
+  virtual bool         Visible();
+
+  virtual void         ChildAdd(PIWdg* child);
+  virtual void         ChildDel(PIWdg* child);
+  virtual int          NbChilds();
+  virtual PIWdg*       GetChild(int n);
+          void         SetAutoDelChilds(bool ad = true);
+
+  virtual void	       FinishCreate(); // appelle FinishCreate() pour les descendants 
+
+protected:
+  bool                 stvis, stfcr;  // Statut visible ou pas, FinishCreate appele ou pas
+  PILayoutMgr*         layout;        // Gestionnaire de positionnement (/tailles) des PIWdg fils
+};
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/picontainermac.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/picontainermac.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/picontainermac.cc	(revision 2309)
@@ -0,0 +1,13 @@
+#include "picontainermac.h"
+
+PIContainerMac::PIContainerMac(PIContainerGen *par, char *nom,
+                         int sx, int sy, int px, int py)
+: PIContainerGen(par, nom, sx, sy, px, py)
+{
+  // Par dfaut, un container est invisible.
+  UnManage();
+}
+
+PIContainerMac::~PIContainerMac()
+{}
+
Index: /tags/V_Dec2002/SophyaPI/PI/picontainermac.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/picontainermac.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/picontainermac.h	(revision 2309)
@@ -0,0 +1,20 @@
+#ifndef PICONTAINERMAC_SEEN
+#define PICONTAINERMAC_SEEN
+
+#include "picontainergen.h"
+#include "pisysdep.h"
+#include <LView.h>
+
+class PIContainerMac : public PIContainerGen {
+public:
+                         PIContainerMac(PIContainerGen *par, char *nom,
+                                   int sx=10, int sy=10, int px=0, int py=0);
+  virtual                ~PIContainerMac();
+  
+protected:
+
+};
+
+typedef PIContainerMac PIContainer;
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/picontainerx.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/picontainerx.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/picontainerx.cc	(revision 2309)
@@ -0,0 +1,81 @@
+#include "picontainerx.h"
+
+#include <Xm/Form.h>
+
+/* *** ATTENTION *** La constante ci-dessous PIXMFORMFRACBASE
+   doit etre identique ds piwdgx.cc  picontainerx.cc et piwindowx.cc
+   ***************************************************************** */
+#define PIXMFORMFRACBASE 1000
+
+
+/* --Methode-- */
+PIContainerX::PIContainerX(PIContainerGen *par, const char *nom, 
+                           int sx, int sy, int px, int py) 
+: PIContainerGen(par, nom, sx, sy, px, py)
+{
+if ((sx > 0) && (sy > 0)) {
+  CreateXtWdg(nom, xmFormWidgetClass , NULL, sx, sy, px, py);
+  int fbase = PIXMFORMFRACBASE ;  // Valeur de XmNfractionBase des XmForm ds PIContainerX
+  Arg  wargs[5];
+  int n=0;
+  XtSetArg(wargs[n],XmNfractionBase, fbase);  n++;
+  XtSetArg(wargs[n],XmNhorizontalSpacing, 0);  n++;
+  XtSetArg(wargs[n],XmNverticalSpacing, 0);  n++;
+  XtSetValues(XtWdg(), wargs, n);
+  }
+//  CreateXtWdg(nom, xmBulletinBoardWidgetClass , NULL, sx, sy, px, py);
+mTopWdg = NULL;
+}
+
+// constructeur special a utiliser par PIApplicationX ...
+PIContainerX::PIContainerX(PIMsgHandler *par, PIWdgX *parwdg, const char *nom,  
+                           int sx, int sy, int px, int py) 
+: PIContainerGen(NULL, nom, sx, sy, px, py)
+{
+SetMsgParent(par);
+if ((sx > 0) && (sy > 0)) {
+  CreateXtWdg(nom, xmFormWidgetClass , parwdg->XtWdg(), sx, sy, px, py);
+  int fbase = PIXMFORMFRACBASE ;  // Valeur de XmNfractionBase des XmForm ds PIContainerX
+  Arg  wargs[5];
+  int n=0;
+  XtSetArg(wargs[n],XmNfractionBase, fbase);  n++;
+  XtSetArg(wargs[n],XmNhorizontalSpacing, 0);  n++;
+  XtSetArg(wargs[n],XmNverticalSpacing, 0);  n++;
+  XtSetValues(XtWdg(), wargs, n);
+  }
+mTopWdg = parwdg;
+}
+
+/* --Methode-- */
+PIContainerX::~PIContainerX()
+{}
+
+
+/* --Methode-- */
+void PIContainerX::Process(PIMessage msg, PIMsgHandler* sender, void* data)
+{
+// Traitement specifique pour le top-container de PIApplicationX
+if ((mTopWdg != NULL) && (ModMsg(msg) == PIMsg_ResizeRequest)) {
+  // On change la taille de la fenetre - data est un pointeur sur entier
+  // data[0] represente l'increment (positif ou negatif) en X, data[1] en Y
+  int* nsz = (int*) data;
+  mTopWdg->SetSize(mTopWdg->XSize()+nsz[0], mTopWdg->YSize()+nsz[1]);
+  return;
+  }  
+else ReSend(msg, sender, data);
+}
+
+/* --Methode-- 
+void PIContainerX::Show()
+{
+PIContainerGen::Show();
+Manage();
+}
+
+void PIContainerX::Hide()
+{
+PIContainerGen::Hide();
+UnManage();
+}
+
+*/
Index: /tags/V_Dec2002/SophyaPI/PI/picontainerx.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/picontainerx.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/picontainerx.h	(revision 2309)
@@ -0,0 +1,29 @@
+#ifndef PICONTAINERX_SEEN
+#define PICONTAINERX_SEEN
+
+#include "pisysdep.h"
+#include "picontainergen.h"
+
+
+class PIContainerX : public PIContainerGen 
+{
+public:
+	              PIContainerX(PIContainerGen *par, const char *nom,
+                           int sx=10, int sy=10, int px=0, int py=0);
+
+// Ce constructeur est a utiliser par PIApplicationX ...
+              	      PIContainerX(PIMsgHandler *par, PIWdgX *parwdg, const char *nom,
+                           int sx=10, int sy=10, int px=0, int py=0);
+
+  virtual  	      ~PIContainerX();
+
+// Pour traiter les Resize-Request si TopContainer de PIApplicationX
+  virtual void        Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+
+protected :
+  PIWdgX* mTopWdg;
+};
+
+typedef PIContainerX PIContainer;
+
+#endif  /* PICONTAINERX_SEEN */
Index: /tags/V_Dec2002/SophyaPI/PI/pidrawer.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pidrawer.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pidrawer.cc	(revision 2309)
@@ -0,0 +1,483 @@
+// Module PI : Peida Interactive     PIDrawer
+// Classe de traceurs pouvant être attachés à une PIBaseWdg
+//	      E. Aubourg , R.Ansari     96-98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "machdefs.h"
+#include <strings.h>
+#include <iostream.h>
+#include "pidrawer.h"
+#include "pidrwtools.h"
+
+#include "ucckprot.h"
+
+
+//++
+// Class	PIDrawer
+// Lib		PI
+// include	pidrawer.h
+//
+//	Classe pour la création d'objets, capables de se dessiner
+//	dans une composante graphique ("PIBaseWdg").
+//--
+//++
+// Links	Voir
+// PIBaseWdg
+// PIGraphicAtt
+// PIAxes
+//--
+
+//++
+// Titre	Constructeurs et méthodes
+//--
+
+//++
+// PIDawer()
+//	Constructeur.
+// ~PIDrawer()
+//	Destructeur
+// void  SetAutoDeleteOnDetach(bool fg)
+//	Si "fg==true", l'objet PIDrawer est détruit lorsqu'il est détaché du dernier 
+//	PIBaseWdg auquel il était attaché.
+// void  SetAutoRefreshOnDelete(bool fg)
+//	Si "fg==true", la méthode "Refresh()" est appelé sur les PIBaseWdg lors de 
+//	la destruction (delete) de l'objet PIDrawer.
+// void	 SetName(string const& name)
+//	Spécification d'un nom pour l'objet PIDrawer.
+// string  Nom()
+//	Renvoie le nom de l'objet.
+// string& Name()
+//	Renvoie le nom de l'objet (référence à). 
+//--
+
+PIDrawer::PIDrawer()
+{
+  mFgDeleteOnDetach = false;
+  mFgRefreshOnDelete = false;
+  mBWdg = NULL; 
+  mGrUC = NULL;
+  xW0 = yW0 = 0; xWd = yWd = 100; 
+  aXdir = false;  // Vrai si Axe X de Droite vers Gauche 
+  aYdir = false;  // Vrai si Axe Y de Haut vers Bas
+  aXlog = aYlog = false;   // Vrai -> echelle axe logarithmique
+  SetLimits(-1, 1, -1, 1, kAxeDirLtoR, kAxeDirDownUp);
+  limitsFixed = false;
+  SetAxesFlags(kAxesNone);   // Pas de trace d'axes par defaut 
+  SetAxesAutoFontSize();
+
+  mDndfg = false;  // Pour controle de l'appel de Detach() si delete
+
+  mFgHighLight = false;  // Flag de control d'affichage en mode HighLight
+
+
+  // Nom par defaut : Le nom de la classe
+  //  mName = typeid(*this).name();
+  mName = "PIDrawer";
+  // Par defaut, pas de fenetre de controle specifique
+  mFgSpecContWind = false;
+}
+
+PIDrawer::~PIDrawer()
+{
+  // Desactivation totale de la fenetre de controle specialise 
+  // ---> parametre d'appel PIBaseWdgGen* wdg=NULL
+  // DeactivateControlWindow(NULL);
+  // Il semble qu'a ce niveau d'appel du desctructeur,
+  // la table des fonctions virtuelles soit alterees et 
+  // la fonction virtuelle DeactivateControlWindow() pointe sur celle
+  // de base - DeactivateControlWindow(NULL) doit donc etre appele
+  // ds le destructeur de la classe derivee 
+  //                    Reza - Octobre 2002 
+
+  // Mise a jour eventuelle de la fenetre PIDrwTools
+  bool ckdeact = (PIDrwTools::GetActiveDrawer() == this) ? true : false;
+
+  list<DrwBWId>::iterator it;
+  mDndfg = true;
+  for(it = mBWdgList.begin(); it != mBWdgList.end(); it++) {
+    (*it).wdg->RemoveDrawer((*it).id);
+    if (mFgRefreshOnDelete) (*it).wdg->Refresh();
+  }
+  if (mGrUC)  delete mGrUC;
+  if (ckdeact) PIDrwTools::UpdateActiveDrawer();
+}
+
+//++
+// Titre	Gestion des axes et des limites
+//      Le tracé des axes 2D est pris en charge par la classe PIAxes.
+//--
+//++
+// void  SetLimits(double xmin, double xmax, double ymin, double ymax, -
+//                 int axrl=kAxeDirSame, int ayud=kAxeDirSame)
+//	Définit les limites du système de coordonnées.
+//|	kAxeDirSame , kAxeDirAuto
+//|	kAxeDirLtoR , kAxeDirRtoL  (Axe X)
+//|	kAxeDirDownUp , kAxeDirUpDown (Axe Y)	
+// void  UpdateLimits()
+//	Cette méthode doit calculer les limites (X/Y Min-Max) préferées par l'objet
+//	et doit appeler "SetLimits()". L'implementation par défaut ne fait rien.
+// bool  LimitsFixed()
+//	Renvoie la valeur du flag "limitsFixed". Le flag est mis à 
+//	"true" si la méthode "SetLimits()" a été appelée.
+// void  FreeLimits()
+//	Met le flag "limitsFixed" à "false".
+//
+// void  SetLogScale(bool logx, bool logy) 
+//	Choix d'échelle logarithmique pour les axes X,Y.
+// void  GetAxesConfig(int& xa, int& ya) 
+//	Renvoie la configuration des axes.
+//|	kAxeDirLtoR , kAxeDirRtoL  (Axe X)
+//|	kAxeDirDownUp , kAxeDirUpDown (Axe Y)	
+// bool  isLogScaleX()   isLogScaleY() 
+//	Renvoie "true" si échelle logarithmique pour axe X , Y
+// double XMin()  XMax()
+//	Limites de l'axe X
+// double YMin()  YMax()
+//	Limites de l'axe Y
+// void  SetAxesFlags(unsigned int flags=kAxesNone)
+//	Attributs de tracé d'axes (voir la classe *PIAxes*)
+//|	kStdAxes , kBoxAxes , kTicks , kIntTicks , kExtTicks 
+//|	kMajTicks , kMinTicks , kLabels , kGridOn
+//|	kAxesDflt , kAxesNone
+// void SetAxesAutoFontSize(bool fg=true)
+//	Si "fg==true", la taille de la fonte pour les labels d'axes (chiffres) est 
+//	choisie automatiquement, en s'adaptant à la taille de la zone de tracé - 
+//	sinon, taille de la fonte de l'objet PIDrawer.
+// unsigned int GetAxesFlags()
+//	Renvoie les attributs de tracé d'axes  
+// bool  isAxesAutoFontSize()
+//	Renvoie la valeur du flag de choix automatique de taille de fonte pour axes.
+// void  DrawAxes(PIGraphicUC* g)
+//	Méthode de tracé des axes (le tracé est pris en charge par la classe *PIAxes*)
+//--
+
+void
+PIDrawer::SetLimits(double xmin, double xmax, double ymin, double ymax,
+                    int axrl, int ayud)
+{
+  if (axrl == kAxeDirAuto) {
+    double ff;
+    if (xmax < xmin)  { axrl = kAxeDirRtoL;   ff=xmin;  xmin=xmax;  xmax=ff; }
+    else  axrl = kAxeDirLtoR;
+  }
+  if (ayud == kAxeDirAuto) {
+    double ff;
+    if (ymax < ymin)  { ayud = kAxeDirUpDown;   ff=ymin;  ymin=ymax;  ymax=ff; }
+    else  ayud = kAxeDirDownUp;
+  }
+//  if (xmax <= xmin || ymax <= ymin) {  
+//    cerr << "PIDrawer::SetLimits() Error - xmax <= xmin  || ymax <= ymin ! " << endl;
+//    return; 
+//    }
+  
+  if (!UC_CheckFinite(xmin, xmax) || !UC_CheckFinite(ymin, ymax)) {
+    cerr << "PIDrawer::SetLimits() Error - Non finite value for x/ymin-max ! " << endl;
+    return; 
+    }
+
+  if (axrl == kAxeDirLtoR)  aXdir = false;
+  else if (axrl == kAxeDirRtoL)  aXdir = true;
+  if (ayud == kAxeDirDownUp)  aYdir = false;
+  else if (ayud == kAxeDirUpDown)  aYdir = true;
+  //  cerr << " DBG-SetLimits xmax-xmin= " << xmax-xmin << " xmin,max=" 
+  //     << xmin << "," << xmax << endl;
+  UC_CheckMinMaxDiff(xmin, xmax);
+  //cerr << " DBG-SetLimits ymax-ymin= " << ymax-ymin << " ymin,max=" 
+  //     << ymin << "," << ymax << endl;
+  UC_CheckMinMaxDiff(ymin, ymax);
+  xMin = xmin;
+  xMax = xmax;
+  yMin = ymin;
+  yMax = ymax;
+  aXFlg = axrl;  aYFlg = ayud;
+  limitsFixed = true;
+}
+
+
+void
+PIDrawer::GetAxesConfig(int& xa, int& ya)
+{
+xa = (aXdir) ? kAxeDirRtoL : kAxeDirLtoR;
+ya = (aYdir) ? kAxeDirUpDown : kAxeDirDownUp;
+}
+
+//++
+// Titre	Gestion du tracé
+//--
+
+//++
+//  void  Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax)
+//	Méthode qui est appelé lorsquer l'objet PIDrawer doit rafraichir la zone
+//	définie par "xmin-xmax" , "ymin-ymax" dans le système de coordonnées du
+//	PIDrawer.
+//  void  Refresh()
+//	Rafraîchit le dessin du PIDrawer sur tous les PIBaseWdg auxquel il est attaché.
+//  void  HighLight(bool fgh)
+//      Rafraichit le dessin du PIDrawer sur tous les PIBaseWdg auxquel il est attaché,
+//	en mode "HighLight" si "fgh==true", en mode normal sinon.
+//--
+
+void
+PIDrawer::UpdateLimits()
+{
+// Ne fait rien !
+  return;
+}
+
+void
+PIDrawer::Refresh()
+{
+  list<DrwBWId>::iterator it;
+  for(it = mBWdgList.begin(); it != mBWdgList.end(); it++)
+         (*it).wdg->CallDrawer((*it).id);
+
+}
+void
+PIDrawer::HighLight(bool fgh)
+{
+  mFgHighLight = fgh;
+  Refresh();
+  mFgHighLight = false;
+}
+
+//++
+// Titre	Les attributs graphiques
+//	Les attributs graphiques des PIDrawer sont gérés par un objet *PIGraphicAtt*.
+//--
+//++
+// void  SetGraphicAtt(PIGraphicAtt const& att)
+//	Modifie le contenu de l'objet PIGraphicAtt associé au PIDrawer à partir de 
+//	"att" (opération d'affectation).
+// void  UpdateGraphicAtt(PIGraphicAtt const& att)
+//	Met à jour le contenu de l'objet PIGraphicAtt associé au PIDrawer à partir de "att".
+// PIGraphicAtt&  GetGraphicAtt()
+//	Renvoie l'objet PIGraphicAtt associé au PIDrawer.
+// void SelGraAtt(PIGraphicUC* g)
+//	Change les attributs graphiques de l'objet "PIGraphicUC* g" à partir des attributs 
+//	de l'objet PIGraphicAtt associé au PIDrawer.
+//--
+
+
+void 
+PIDrawer::SelGraAtt(PIGraphicUC* g)
+{
+  PIColors fcol = GetGraphicAtt().GetFgColor(); 
+  if (fcol != PI_NotDefColor)    g->SelForeground(fcol);
+  PIColors bcol = GetGraphicAtt().GetBgColor(); 
+  if (bcol != PI_NotDefColor)    g->SelBackground(bcol);
+  if (GetGraphicAtt().GetLineAtt() != PI_NotDefLineAtt)  
+    g->SelLine(GetGraphicAtt().GetLineAtt());
+  if ( (GetGraphicAtt().GetFontName() != PI_DefaultFont) ||
+       (GetGraphicAtt().GetFontAtt() != PI_NotDefFontAtt) )
+    g->SelFont(GetGraphicAtt().GetFont());
+  if (GetGraphicAtt().GetMarker() != PI_NotDefMarker) 
+    g->SelMarker(GetGraphicAtt().GetMarkerSize(), GetGraphicAtt().GetMarker());
+  if (GetGraphicAtt().GetArrowMarker() !=  PI_NotDefArrowMarker) 
+    g->SelArrowMarker(GetGraphicAtt().GetArrowMarkerSize(), 
+		      GetGraphicAtt().GetArrowMarker());
+}
+
+
+void
+PIDrawer::Attach(PIBaseWdgGen* wdg, int id)
+{
+  if (!wdg) return;
+  DrwBWId bwi;
+  bwi.id = id;  bwi.wdg = wdg;
+  mBWdgList.push_back(bwi);
+  return;
+}
+
+void
+PIDrawer::Detach(PIBaseWdgGen* wdg, int id)
+{
+  if (mDndfg) return;
+  if (!wdg) return;
+
+  // Desactivation de la fenetre de controle specialisee pour la 
+  // base-widget duquel on se detache 
+  DeactivateControlWindow(wdg);
+  
+  // Mise a jour eventuelle de la fenetre PIDrwTools
+  bool ckdeact = (PIDrwTools::GetActiveDrawer() == this) ? true : false;
+
+  list<DrwBWId>::iterator it;
+  for(it = mBWdgList.begin(); it != mBWdgList.end(); it++)
+     if ( ((*it).id == id) && ((*it).wdg == wdg) ) { mBWdgList.erase(it);  break; }
+  if (mFgDeleteOnDetach && (mBWdgList.size() == 0))  delete this;
+
+  if (ckdeact) PIDrwTools::UpdateActiveDrawer();
+  return;
+}
+
+//++
+// Titre	Fenêtre de contrôle spécialisé
+//	Les méthodes suivantes permettent de faciliter la gestion d'une fenêtre de contrôle 
+//	spécialisée pour un type de traceur donné.
+//|	ATTENTION 
+//|	Si fenetre de controle specilisee, il faut appeler explicitement 
+//|	DeactivateControlWindow(NULL) dans le destructeur.	
+//--
+//++
+// bool HasSpecificControlWindow() const 
+//	Renvoie "true" si le traceur possède une fenêtre de contrôle. l'attribut protégé booléan
+//	"mFgSpecContWind" doit être initialisé à si la méthode "ShowControlWindow" est redéfinie.
+// void ShowControlWindow(PIBaseWdgGen* wdg)
+//	Méthode effectuant l'affichage de la fenêtre de contrôle spécialisée. L'implémentation
+//	par défaut affiche la fenêtre *PIDrwTools*.
+//	L'argument "wdg" est le pointeur de l'objet PIBaseWdgGen qui a déclenché l'action.
+// void DeactivateControlWindow(PIBaseWdgGen* wdg)
+//	Méthode de désactivation de la la fenêtre de contrôle spécialisée.
+//	Appelée lors de la destruction du drawer, avec le paramètre "PIBaseWdgGen* wdg = NULL",
+//	ou lors du détachement du traceur. Dans ce dernier cas, le paramètre "PIBaseWdgGen* wdg"
+//	pointe vers le PIBaseWdg duquel le traceur (PIDrawer) est en cours de détachement.
+//	"DeactivateControlWindow(NULL)" doit être appelé dans le destructeur de la classe dérivée
+//	si celle-ci possède une fenêtre de contrôle spécialisée.
+//--
+
+void
+PIDrawer::ShowControlWindow(PIBaseWdgGen* wdg)
+{
+  // On affiche par defaut la fenetre de gestion des attributs graphiques
+   PIDrwTools::ShowPIDrwTools(wdg);
+}
+
+//--------------------------------------------------------------
+// Methode de desactivation de la fenetre de controle specialise
+// Cette methode est appellee dans deux cas :
+// 1/ lors de la destruction du drawer
+//    Dans ce cas, le parametre PIBaseWdgGen* wdg = NULL
+// 2/ Lorsque le drawer est detache d'un PIBaseWdg 
+//    Dans ce cas, le parametre PIBaseWdgGen* wdg pointe vers le 
+//    PIBaseWdg duquel le drawer est detache
+// Evidemment, "this" pointe toujours sur le drawer qui est 
+// en cours de destruction ou de detachement
+//--------------------------------------------------------------
+void
+PIDrawer::DeactivateControlWindow(PIBaseWdgGen* wdg)
+{
+  // La mise a jour eventuelle de PIDrwTools se fait 
+  // directement lors de Detach() ou delete 
+  // La methode par defaut ne fait donc rien 
+}
+
+//++
+// Titre	Décodage des options
+//--
+//++
+// int  DecodeOptionString(vector<string> & opt, bool rmdecopt=true)
+//	Effectue le décodage des options du traceur à partir de "opt". Si "rmdecopt==true"
+//	les options décodées sont supprimées du vecteur "opt". 
+//	Retourne le nombre d'options décodées.
+//	L'implémentation par défaut effectue le décodage des attributs graphiques en 
+//	utilisant la méthode *PIGraphicAtt::DecodeAttStrings()*
+// void	 GetOptionsHelpInfo(string& info)
+//	Ajoute au bout de la chaine "info" l'aide concernant le décodage des options du traceur.
+//--
+int
+PIDrawer::DecodeOptionString(vector<string> & opt, bool rmdecop)
+{
+  if (opt.size() < 1)  return(0);  
+  PIGraphicAtt gratt;
+  int ndec = gratt.DecodeAttStrings(opt, rmdecop);
+  UpdateGraphicAtt(gratt);
+  return(ndec);
+}
+
+void
+PIDrawer::GetOptionsHelpInfo(string& info)
+{
+  info += " ------- PIDrawer options help info ---------- \n";
+  info += ">> Colors: defcol black white grey red blue green yellow \n";
+  info += "           magenta cyan turquoise navyblue orange siennared purple \n";
+  info += "           limegreen gold violet violetred blueviolet darkviolet \n";
+  info += ">> Lines:  defline normalline thinline thickline dashedline thindashedline \n";
+  info += "           thickdashedline dottedline thindottedline thickdottedline \n";
+  info += ">> Font Att: deffontatt normalfont boldfont italicfont bolditalicfont  \n";
+  info += "             smallfont smallboldfont smallitalicfont smallbolditalicfont \n";
+  info += "             bigfont bigboldfont bigitalicfont bigbolditalicfont \n";
+  info += "             hugefont  hugeboldfont hugeitalicfont hugebolditalicfont \n";
+  info += ">> Font Names: deffont courierfont helveticafont timesfont symbolfont  \n";
+  info += ">> Marker: dotmarker<S>  plusmarker<S>  crossmarker<S> circlemarker <S> \n";
+  info += "           fcirclemarker<S> boxmarker<S> fboxmarker<S> trianglemarker<S> \n";
+  info += "           ftrianglemarker<S>  starmarker<S>  fstarmarker<S> \n";
+  info += "   with <S> = 1 3 5 7 9 , Example fboxmarker5 , plusmarker9 ... \n";
+  info += ">> ColorTables: defcmap  grey32  invgrey32  colrj32  colbr32 \n";
+  info += "                grey128  invgrey128  colrj128  colbr128 \n";
+  info += "                midas_pastel midas_heat midas_rainbow3 midas_bluered\n";
+  info += "                midas_bluewhite midas_redwhite \n";
+  info += "                rainbow16 \n";
+  info += "   revcmap : This flag reverses ColorMap indexing \n";
+  return;
+}
+
+PIGraphicUC*
+PIDrawer::SetDrwWdg(PIBaseWdgGen* drw, int x0, int y0, int dx, int dy, PIGraphicGen* g)
+{
+  mBWdg = drw;
+  xW0 = x0;   yW0 = y0;
+  xWd = dx;   yWd = dy;
+  if (mGrUC)  delete mGrUC;
+  mGrUC = new PIGraphicUC(g, x0, y0, dx, dy);
+  mGrUC->SetUCS(xMin, xMax, yMin, yMax, aXFlg, aYFlg);
+  if (aXlog || aYlog) mGrUC->SetLogScale(aXlog, aYlog);
+  if (mFgHighLight) mGrUC->SelGOMode(PI_GOInvert); // $CHECK$ A changer , Reza 07/2001
+  return(mGrUC);
+}
+
+void
+PIDrawer::SetAxesFlags(unsigned int flags)
+{
+  axesFlags = flags;
+  if (axesFlags & (kIntTicks | kExtTicks | kMajTicks | kMinTicks))
+    axesFlags |= kTicks;
+  if ((axesFlags & (kTicks | kIntTicks | kExtTicks)) == kTicks)
+    axesFlags |= kIntTicks | kExtTicks;
+  if ((axesFlags & (kTicks | kMajTicks | kMinTicks)) == kTicks)
+    axesFlags |= kMajTicks;
+}
+
+
+void
+PIDrawer::DrawAxes(PIGraphicUC* g)
+{
+  g->NoClip();
+  PIAxes axes;
+  axes.DrawXYAxes(g, mGrAtt, axesFlags, axesAFSz, XMin(), XMax(), YMin(), YMax()); 
+  g->Clip();
+}
+
+  
+
+void
+PIDrawer::Draw(PIGraphicUC* g, double /*xmin*/, double /*ymin*/, double /*xmax*/, double /*ymax*/)
+{
+}
+
+//++
+// Titre	Informations textuelles associées au drawer
+//	Les méthodes suivantes peuvent renvoyer une information textuelle correspondant à
+//	un point ou une zone dans l'espace de coordonnées de l'objet PIDrawer.
+//--
+//++
+// void  GetClickInfo(string& info,double x, double y, double x0=0.,double y0=0., bool fgdiff=false)
+//	Met à jour la chaine "info" avec l'information associée à la position "(x,y)".
+//	Si "fgdiff=true", une information d'écart par rapport à la position origine "(x0,y0)"
+//	peut aussi être fournie.
+//	L'implémentation par défaut ne fait rien.
+// void  AppendTextInfo(string& info, double xmin, double ymin, double xmax, double ymax)
+//	Met à jour la chaine "info avec l'information textuelle  associée a la zone 
+//	rectangulaire "(xmin,ymin) -- (xmax,ymax)". 
+//	L'implémentation par défaut ne fait rien.
+//--
+
+
+void
+PIDrawer::AppendTextInfo(string& info, double /*xmin*/, double /*ymin*/, double /*xmax*/, double /*ymax*/)
+{
+}
+
+void
+PIDrawer::GetClickInfo(string& info,double x,double y,double x0,double y0,bool fgdiff)
+{
+}
Index: /tags/V_Dec2002/SophyaPI/PI/pidrawer.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pidrawer.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pidrawer.h	(revision 2309)
@@ -0,0 +1,138 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Objets traceur qui peuvent etre attaches a un PIBaseWidget
+//                             R. Ansari  97-98
+// (C) LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+#ifndef PIDRAWER_H
+#define PIDRAWER_H
+
+#include "pibwdggen.h"
+#include "pigraphuc.h"
+#include "pigratt.h"
+#include "piaxes.h"
+
+
+class PIDrawer {
+public:
+                     PIDrawer();
+  virtual           ~PIDrawer();
+
+  // if true -> PIDrawer deleted when detached from last BaseWdg
+  inline  void       SetAutoDeleteOnDetach(bool fg)
+                       { mFgDeleteOnDetach = fg; }
+  // if true -> PIBaseWdg()->Refresh() when PIDrawer is deleted 
+  inline  void       SetAutoRefreshOnDelete(bool fg)
+                       { mFgRefreshOnDelete = fg; }
+
+  virtual void       SetLimits(double xmin, double xmax, double ymin, double ymax,
+                               int axrl=kAxeDirSame, int ayud=kAxeDirSame);
+  inline void	     SetLogScale(bool logx, bool logy) 
+                             { aXlog = logx; aYlog = logy; }
+
+  virtual void       SetAxesFlags(unsigned int flags=kAxesNone);
+  inline  void       SetAxesAutoFontSize(bool fg=true) { axesAFSz = fg; }
+
+  virtual void       DrawAxes(PIGraphicUC* g);
+
+  virtual void       Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax); 
+
+//  Rajoute l'information concernant la zone xmin,ymin ---> xmax,ymax au string info
+  virtual void       AppendTextInfo(string& info, double xmin, double ymin, double xmax, double ymax);
+
+// Renvoie une information liee au drawer pour une position x,y 
+  virtual void       GetClickInfo(string& info,double x,double y
+                                 ,double x0=0.,double y0=0.,bool fgdiff=false); 
+
+  virtual void       Refresh();      // Recalcule les limites et reaffiche
+  virtual void       UpdateLimits();   // Calcule et change les limites  
+
+  // Gestion d'affichage en mode HighLight : fgh=true -> highlight =false -> normal
+  virtual void	     HighLight(bool fgh);  
+
+  inline double      XMin() const {return xMin;}
+  inline double      XMax() const {return xMax;}
+  inline double      YMin() const {return yMin;}
+  inline double      YMax() const {return yMax;}
+
+  void               GetAxesConfig(int& xa, int& ya);
+  inline bool        isLogScaleX() { return aXlog; }
+  inline bool        isLogScaleY() { return aYlog; }
+
+  inline unsigned int GetAxesFlags() { return(axesFlags); }
+  inline  bool       isAxesAutoFontSize() { return axesAFSz; }
+
+  inline PIGraphicUC*    GetGraphicUC() { return(mGrUC); }
+
+  inline bool         LimitsFixed() const {return limitsFixed;}
+  inline void         FreeLimits() {limitsFixed = false;}
+
+  virtual void        SelGraAtt(PIGraphicUC* g);
+
+// Changement des attributs graphiques
+  inline void         SetGraphicAtt(PIGraphicAtt const& att) { mGrAtt = att; }
+  inline void         UpdateGraphicAtt(PIGraphicAtt const& att) 
+                      { mGrAtt.UpdateFrom(att); }
+
+// Acces aux attributs graphiques
+  inline PIGraphicAtt& GetGraphicAtt() { return(mGrAtt); }
+
+//  Methode permettant l'affichage d'une fenetre de controle specialisee 
+  virtual void       ShowControlWindow(PIBaseWdgGen* wdg);
+  inline  bool       HasSpecificControlWindow() const { return mFgSpecContWind; }
+  virtual void       DeactivateControlWindow(PIBaseWdgGen* wdg);
+
+//   Methode permettant de decoder des options a partir de chaines
+  virtual int        DecodeOptionString(vector<string> & opt, bool rmdecopt=true);
+//   Texte d'aide des options disponibles
+  virtual void	     GetOptionsHelpInfo(string& info);
+
+//   On peut donner un nom a un drawer (par defaut = nom de la classe)
+  inline string	     Nom() { return mName; } 
+  inline string&     Name() { return mName; }
+  inline void	     SetName(string const& name) { mName = name; } 
+
+//  Les objets/methodes suivants devraient etre protected     
+//  Pb avec acces depuis PIBaseWdgGen (Reza 11/07/97) 
+  virtual  PIGraphicUC*  SetDrwWdg(PIBaseWdgGen* drw, int x0, int y0, int dx, int dy, PIGraphicGen* g);
+
+//  Je declare en public a cause de cxx - Reza 11/07/97 
+  struct DrwBWId { int id; PIBaseWdgGen* wdg; };
+  
+protected:
+  friend class PIBaseWdgGen;
+  virtual void       Attach(PIBaseWdgGen*, int id);
+  virtual void       Detach(PIBaseWdgGen*, int id);
+
+
+  bool mFgDeleteOnDetach;         // si true -> delete drawer on detach
+                                  // from last BaseWdg
+  bool mFgRefreshOnDelete;        // si true -> On rafraichit le BaseWdg
+                                  // lors du delete ou Detach
+         
+  double xMin, xMax, yMin, yMax;  // Valeurs en unites user
+  int xW0, yW0, xWd, yWd;        // Origine/largeur ds la fenetre de trace
+  bool   aXdir, aYdir;           // Sens des axes horiz, vertical 
+  bool   aXlog, aYlog;           // Echelle log pour les axes horiz, vertical 
+  int aXFlg, aYFlg;
+
+  bool limitsFixed;
+  unsigned int axesFlags;
+  bool axesAFSz;
+  PIBaseWdgGen* mBWdg;
+  PIGraphicUC* mGrUC;
+
+// Flag de control d'affichage en mode HighLight
+  bool mFgHighLight;
+// Flag indiquant s'il y a une fenetre de controle specifique
+  bool mFgSpecContWind;
+// Nom du drawer
+  string mName;
+
+  list<DrwBWId>  mBWdgList;
+  bool mDndfg;
+
+//  Gestion d attributs graphiques associes a chaque drawer
+  PIGraphicAtt   mGrAtt;
+
+};
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pidrawwin.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pidrawwin.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pidrawwin.cc	(revision 2309)
@@ -0,0 +1,28 @@
+#include "pidrawwin.h"
+
+PIDrawWindow::PIDrawWindow(PIMsgHandler* par, const char *nom,
+                               PIWindowKind k, int sx, int sy, int px, int py)
+:PIWindow(par, nom, k, sx, sy, px, py)
+{
+   mDrawWdg = new PIScDrawWdg(this, nom, sx-20, sy-20, 10, 10);
+   mDrawWdg->SetBinding(PIBK_fixed, PIBK_fixed, PIBK_fixed, PIBK_fixed);   
+}
+
+
+PIDrawWindow::~PIDrawWindow()
+{
+  delete mDrawWdg;
+}
+
+void
+PIDrawWindow::AddScDrawer(PIDrawer* d, bool ad)
+{
+  mDrawWdg->AddScDrawer(d, ad);
+}
+
+void
+PIDrawWindow::SetAxesFlags(int flags)
+{
+  mDrawWdg->SetAxesFlags(flags);
+}
+
Index: /tags/V_Dec2002/SophyaPI/PI/pidrawwin.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pidrawwin.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pidrawwin.h	(revision 2309)
@@ -0,0 +1,26 @@
+#ifndef PIDRAWWIN_H
+#define PIDRAWWIN_H
+
+// Une fenetre qui contient un drawwdg...
+
+#include "pisysdep.h"
+#include PIWIN_H
+#include "piscdrawwdg.h"
+
+class PIDrawWindow : public PIWindow {
+public:
+                 PIDrawWindow(PIMsgHandler* par, const char *nom, 
+                                PIWindowKind k=PIWK_normal, int sx=10, int sy=10, 
+                                int px=0, int py=0);
+                ~PIDrawWindow();
+                
+ virtual void    AddScDrawer(PIDrawer*, bool ad=false);                
+ virtual void    SetAxesFlags(int flags=-1);
+ inline PIScDrawWdg * DrawWdg() { return mDrawWdg; }
+private:
+  PIScDrawWdg*   mDrawWdg;
+};
+
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pidrwtools.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pidrwtools.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pidrwtools.cc	(revision 2309)
@@ -0,0 +1,651 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Outils de manipulation des PIDrawer  R. Ansari 06/98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+// modifs pour 
+#include <stdlib.h>
+
+#include "pidrwtools.h"
+#include <iostream.h>
+#include "piscdrawwdg.h"
+#include "pi3dwdg.h"
+
+//++
+// Class	PIDrwTools
+// Lib		PI
+// include	pidrwtools.h
+//
+//	Classe de fenêtre de dialogue permettant de modifier interactivement
+//	Les attributs graphique des "Drawer" attachés aux "PIBaseWdg".
+//--
+// Links	Parents
+// PIWindow
+//--
+//++
+// Links	Voir aussi
+// PIDrawer
+// PIBaseWdg
+//--
+//++
+// Links	Ainsi que
+// PIScDrawWdg
+// PIImage
+// PIDraw3DWdg
+//--
+
+//++
+// Titre	Méthodes statiques
+//--
+//++
+// void  ShowPIDrwTools() 	
+//	Méthode statique permettant l'affichage de la fenêtre de contrôle des
+//	attributs graphiques des "Drawer". L'instance de la classe
+//	 "PIDrwTools" est créée si nécessaire.
+// void  HidePIDrwTools() 
+//	Désacative (cache) la fenêtre "PIDrwTools" (méthode statique).
+// void  SetCurrentBaseWdg(PIBaseWdgGen* cbw)
+//	Méthode statique permettant de sélectionner le "PIBaseWdg" courant.
+// PIBaseWdgGen*  GetCurrentBaseWdg()
+//	Retourne le "PIBaseWdg" courant (méthode statique).
+//--
+
+
+PIDrwTools* PIDrwTools::cwdrwt = NULL;
+PIBaseWdgGen* PIDrwTools::mCurBW = NULL;
+
+/* --Methode-- */
+void PIDrwTools::ShowPIDrwTools(PIBaseWdgGen* cbw) 
+{
+if (cwdrwt == NULL)  cwdrwt = new PIDrwTools(PIApplicationGetApp());
+mCurBW = cbw;
+cwdrwt->Show();
+}
+
+/* --Methode-- */
+void PIDrwTools::ShowPIDrwTools() 
+{
+if (cwdrwt == NULL)  cwdrwt = new PIDrwTools(PIApplicationGetApp());
+cwdrwt->Show();
+}
+
+/* --Methode-- */
+void PIDrwTools::HidePIDrwTools() 
+{
+if (cwdrwt == NULL)  return; 
+cwdrwt->Hide();
+}
+
+/* --Methode-- */
+void PIDrwTools::SetCurrentBaseWdg(PIBaseWdgGen* cbw)
+{
+if (mCurBW == cbw) return;
+mCurBW = cbw;
+if (cwdrwt != NULL)
+  cwdrwt->UpdateControlsFromDrawer(-9);
+}
+
+/* --Methode-- */
+PIBaseWdgGen* PIDrwTools::GetCurrentBaseWdg()
+{
+return(mCurBW);
+}
+
+/* --Methode-- */
+PIDrawer* PIDrwTools::GetActiveDrawer()
+{
+if ((cwdrwt == NULL) || (mCurBW == NULL) || (cwdrwt->mNDr < 0) )  
+  return(NULL);
+else return(mCurBW->GetDrawer(cwdrwt->mNDr));
+}
+
+/* --Methode-- */
+void PIDrwTools::UpdateActiveDrawer()
+{
+  if (cwdrwt && cwdrwt->IsVisible())  
+    cwdrwt->UpdateControlsFromDrawer(-9);
+}
+
+
+/* --Methode-- */
+PIDrwTools::PIDrwTools(PIApplication* par)
+: PIWindow((PIMsgHandler*)par, "PIDrawerTools", PIWK_normal, 240, 240, 150, 150)
+{
+int bsx, bsy, spx, spy;
+
+// On definit la taille a partir de la taille par defaut des composantes 
+// PIApplicationPrefCompSize(bsx, bsy);
+par->PrefCompSize(bsx, bsy);
+spx = bsx/10;
+spy = bsy/4;
+
+int wszx = 5*spx+3.5*bsx; 
+int wszy = (2+6*0.85)*bsy+(7+6*0.85)*spy;
+SetSize(wszx, wszy);
+
+//int cpx = spx*2;
+//int offy = cpy+bsy+spy*2;
+
+//  Option-Menu  Marker, Line, couleur, etc...
+int cpx = 2*spx;
+int cpy = 2*spy;
+
+int bsyo = bsy;  
+int spyo = spy; 
+bsy = 0.85*bsy;   spy = 0.85*spy;
+
+mOpt[0] = new PIOptMenu(this, "bwt-opt-0", bsx*1.75, bsy, cpx, cpy);
+mOpt[0]->AppendItem("Def.Col", 100);
+mOpt[0]->AppendItem("Black", 101);
+mOpt[0]->AppendItem("White", 102);
+mOpt[0]->AppendItem("Grey", 103);
+mOpt[0]->AppendItem("Red", 104);
+mOpt[0]->AppendItem("Blue", 105);
+mOpt[0]->AppendItem("Green", 106);
+mOpt[0]->AppendItem("Yellow", 107);
+mOpt[0]->AppendItem("Magenta", 108);
+mOpt[0]->AppendItem("Cyan", 109);
+mOpt[0]->AppendItem("Turquoise", 110);
+mOpt[0]->AppendItem("NavyBlue", 111);
+mOpt[0]->AppendItem("Orange", 112);
+mOpt[0]->AppendItem("SiennaRed", 113);
+mOpt[0]->AppendItem("Purple", 114);
+mOpt[0]->AppendItem("LimeGreen", 115);
+mOpt[0]->AppendItem("Gold", 116);
+mOpt[0]->AppendItem("Violet", 117);
+mOpt[0]->AppendItem("VioletRed", 118);
+mOpt[0]->AppendItem("BlueViolet", 119);
+mOpt[0]->AppendItem("DarkViolet", 120);
+mOpt[0]->SetValue(100);
+mOpt[0]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+
+cpx += spx+1.75*bsx; 
+mOpt[1] = new PIOptMenu(this, "bwt-opt-1", bsx*1.75, bsy, cpx, cpy);
+mOpt[1]->AppendItem("No.CMap", 200);
+int kcc;
+//  Groupement des tables de couleurs
+mCasc[0] = new PIMenu(mOpt[1]->Menu(), "PIStd-128Col");
+mCasc[1] = new PIMenu(mOpt[1]->Menu(), "MIDAS-CMap");
+
+int nsct1,nsct2,nsct3;
+//  D'abord les tables standard de PI  32 couleurs
+nsct1 = 5;   // Les 5 premieres tables
+for(kcc=0; kcc<nsct1; kcc++) 
+  mOpt[1]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(), 201+kcc);
+//  Ensuite les tables standard de PI  128 couleurs
+nsct2 = 9;   // Les 4 tables suivantes
+for(kcc=nsct1; kcc<nsct2; kcc++) 
+  mCasc[0]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(), 201+kcc);
+mOpt[1]->AppendPDMenu(mCasc[0]);
+//  Apres les tables importees de MIDAS
+nsct3 = PIColorMap::NumberStandardColorMaps()-1; // Les reste jusqu'a l'avant derniere
+for(kcc=nsct2; kcc<nsct3; kcc++) 
+  mCasc[1]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(), 201+kcc);
+mOpt[1]->AppendPDMenu(mCasc[1]);
+// Les tables qui restent ( Col16 , ... )
+for(kcc=nsct3; kcc<PIColorMap::NumberStandardColorMaps(); kcc++) 
+mOpt[1]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(), 201+kcc);
+
+mOpt[1]->SetValue(200);
+mOpt[1]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+
+
+cpx = 2*spx;
+cpy += spy+bsy;
+mOpt[2] = new PIOptMenu(this, "bwt-opt-2", bsx*1.75, bsy, cpx, cpy);
+mOpt[2]->AppendItem("Def.Mrk", 300);
+mOpt[2]->AppendItem("Mrk Dot(.)", 301);
+mOpt[2]->AppendItem("Mrk Plus(+)", 302);
+mOpt[2]->AppendItem("Mrk Cross(x)", 303);
+mOpt[2]->AppendItem("Mrk Circle", 304);
+mOpt[2]->AppendItem("Mrk FCircle", 305);
+mOpt[2]->AppendItem("Mrk Box", 306);
+mOpt[2]->AppendItem("Mrk FBox", 307);
+mOpt[2]->AppendItem("Mrk Triangle", 308);
+mOpt[2]->AppendItem("Mrk FTriangle", 309);
+mOpt[2]->AppendItem("Mrk Star", 310);
+mOpt[2]->AppendItem("Mrk FStar", 311);
+mOpt[2]->SetValue(300);
+mOpt[2]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+
+cpx += spx+1.75*bsx; 
+mOpt[3] = new PIOptMenu(this, "bwt-opt-3", bsx*1.75, bsy, cpx, cpy);
+mOpt[3]->AppendItem("Mrk 1 pt", 401);
+mOpt[3]->AppendItem("Mrk 3 pt", 403);
+mOpt[3]->AppendItem("Mrk 5 pt", 405);
+mOpt[3]->AppendItem("Mrk 7 pt", 407);
+mOpt[3]->AppendItem("Mrk 9 pt", 409);
+mOpt[3]->AppendItem("Mrk 11 pt", 411);
+mOpt[3]->AppendItem("Mrk 13 pt", 413);
+mOpt[3]->AppendItem("Mrk 15 pt", 415);
+mOpt[3]->SetValue(405);
+mOpt[3]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+
+cpx = 2*spx;
+cpy += spy+bsy;
+mOpt[4] = new PIOptMenu(this, "bwt-opt-4", bsx*1.75, bsy, cpx, cpy);
+mOpt[4]->AppendItem("Def.Font", 500);
+mOpt[4]->AppendItem("Courier", 501);
+mOpt[4]->AppendItem("Helvetica", 502);
+mOpt[4]->AppendItem("Times", 503);
+mOpt[4]->AppendItem("Symbol-Font", 504);
+mOpt[4]->SetValue(500);
+mOpt[4]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+
+cpx += spx+1.75*bsx; 
+mOpt[5] = new PIOptMenu(this, "bwt-opt-5", bsx*1.75, bsy, cpx, cpy);
+mOpt[5]->AppendItem("Def.Line", 600);
+mOpt[5]->AppendItem("Thin-Line", 601);
+mOpt[5]->AppendItem("Normal-Line", 602);
+mOpt[5]->AppendItem("Thick-Line", 603);
+mOpt[5]->AppendItem("ThinDashed", 604);
+mOpt[5]->AppendItem("Dashed-Line", 605);
+mOpt[5]->AppendItem("ThickDashed", 606);
+mOpt[5]->AppendItem("ThinDotted", 607);
+mOpt[5]->AppendItem("Dotted-Line", 608);
+mOpt[5]->AppendItem("ThickDotted", 609);
+mOpt[5]->AppendItem("ThinDashDott", 610);
+mOpt[5]->AppendItem("DashDot-Line", 611);
+mOpt[5]->AppendItem("ThickDashDott", 612);
+mOpt[5]->SetValue(600);
+mOpt[5]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+
+cpx = 2*spx;
+cpy += spy+bsy;
+mOpt[6] = new PIOptMenu(this, "bwt-opt-6", bsx*1.75, bsy, cpx, cpy);
+mOpt[6]->AppendItem("Def.FontAtt", 700);
+mOpt[6]->AppendItem("Roman-Font", 701);
+mOpt[6]->AppendItem("Bold-Font", 702);
+mOpt[6]->AppendItem("Italic-Font", 703);
+mOpt[6]->AppendItem("BoldItalic", 704);
+mOpt[6]->SetValue(700);
+mOpt[6]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+
+cpx += spx+1.75*bsx; 
+mOpt[7] = new PIOptMenu(this, "bwt-opt-7", bsx*1.75, bsy, cpx, cpy);
+mOpt[7]->AppendItem("Def.FontSz", 800);
+mOpt[7]->AppendItem("Tiny FontSz", 801);
+mOpt[7]->AppendItem("Small FontSz", 802);
+mOpt[7]->AppendItem("Normal FontSz", 803);
+mOpt[7]->AppendItem("Large FontSz", 804);
+mOpt[7]->AppendItem("Huge FontSz", 805);
+mOpt[7]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+
+cpx = 2*spx;
+cpy += spy+bsy;
+// OP 03/2002
+
+mOpt[8] = new PIOptMenu(this, "bwt-opt-8", bsx*1.75, bsy, cpx, cpy);
+mOpt[8]->AppendItem("Def.ArrowMrk", 900);
+mOpt[8]->AppendItem("Basic-Arrow", 901);
+mOpt[8]->AppendItem("Triangle-Arrow", 902);
+mOpt[8]->AppendItem("FTriangle-Arrow", 903);
+mOpt[8]->AppendItem("ShapedArrow", 904);
+mOpt[8]->AppendItem("FShapedArrow", 905);
+mOpt[8]->SetValue(900);
+mOpt[8]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+
+cpx += spx+1.75*bsx; 
+mOpt[9] = new PIOptMenu(this, "bwt-opt-9", bsx*1.75, bsy, cpx, cpy);
+mOpt[9]->AppendItem("Arrow-1pt  ", 951);
+mOpt[9]->AppendItem("Arrow-3pt ", 952);
+mOpt[9]->AppendItem("Arrow-5pt", 953);
+mOpt[9]->AppendItem("Arrow-7pt", 954);
+mOpt[9]->AppendItem("Arrow-9pt", 955);
+mOpt[9]->AppendItem("Arrow-11pt", 956);
+mOpt[9]->AppendItem("Arrow-13pt", 957);
+mOpt[9]->AppendItem("Arrow-15pt", 958);
+mOpt[9]->AppendItem("Arrow-17pt", 959);
+mOpt[9]->SetValue(952 );
+mOpt[9]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+
+cpx = 2*spx;
+cpy += spy+bsyo;
+
+// end OP
+int kb;
+bsy = bsyo; spy = spyo;
+mButdr[0] = new PIButton(this, "-", 1501, bsy, bsy, cpx, cpy);
+cpx += bsy+0.25*spy;
+mNlb = new PILabel(this,"NumDr", 1.2*bsy, bsy, cpx, cpy);
+mNlb->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+mNlb->SetLabel("");
+mNDr = 0;
+cpx += 1.2*bsy+0.25*spy;
+mButdr[1] = new PIButton(this, "+", 1502, bsy, bsy, cpx, cpy);
+mButdr[0]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+mButdr[1]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+for(kb=0; kb<2; kb++) {
+  mButdr[kb]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+  mButdr[kb]->SetUnSensitive();
+}
+cpx += bsy+2*spx; 
+mDrName = new PILabel(this,"DrName", wszx-2*spx-cpx, bsy, cpx, cpy);
+mDrName->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+mDrName->SetLabel("No-Drawer");
+mDrName->SetBorderWidth(1);
+
+cpy += bsy+spy;
+cpx = 2*spx;
+int butszx = 0.7*bsx;
+mButcf[0] = new PIButton(this, "GetAtt", 2500, butszx, bsy, cpx, cpy);
+cpx += butszx+spx;
+mButcf[1] = new PIButton(this, "SetAtt", 2600, butszx, bsy, cpx, cpy);
+cpx += butszx+spx;
+mButcf[2] = new PIButton(this, "Select", 2700, butszx, bsy, cpx, cpy);
+mButcf[2]->ActivatePress(true);
+cpx += butszx+spx;
+butszx = wszx-cpx-2*spx;
+mButcf[3] = new PIButton(this, "ShowControl", 2800, butszx, bsy, cpx, cpy);
+
+butszx = 1.4*bsx;
+cpx = (wszx-2*butszx-4*spx)/2;
+cpy += 2*spy+bsy;
+mButcf[4] = new PIButton(this, "Refresh", 3000, bsx*1.2, bsyo, cpx, cpy);
+cpx += butszx+2*spx;
+mButcf[5] = new PIButton(this, "Dismiss", 3777, butszx, bsyo, cpx, cpy);
+
+for(kb=0; kb<6; kb++) 
+  mButcf[kb]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+for(kb=0; kb<5; kb++) 
+  mButcf[kb]->SetUnSensitive();
+
+mButSens = 0;
+cwdrwt = this;
+
+}
+
+/* --Methode-- */
+PIDrwTools::~PIDrwTools()
+{
+if (cwdrwt == this)  cwdrwt = NULL;
+int i;
+for(i=0; i<6; i++) delete mButcf[i]; 
+for(i=0; i<2; i++) delete mButdr[i]; 
+for(i=0; i<10 ; i++)  delete mOpt[i];
+for(i=0; i<2; i++)  delete mCasc[i];
+delete mNlb;
+delete mDrName;
+}
+
+//  Declaration des differents attributs graphiques 
+#define MYNMXCOLORS 21
+static PIColors cols[MYNMXCOLORS] = { PI_NotDefColor, 
+                     PI_Black, PI_White, PI_Grey, 
+                     PI_Red, PI_Blue, PI_Green, 
+                     PI_Yellow, PI_Magenta, 
+                     PI_Cyan , PI_Turquoise, PI_NavyBlue, 
+                     PI_Orange, PI_SiennaRed, PI_Purple, 
+                     PI_LimeGreen, PI_Gold, PI_Violet, PI_VioletRed,
+                     PI_BlueViolet, PI_DarkViolet };
+
+static PIMarker mrk[12] = { PI_NotDefMarker, PI_DotMarker, 
+                            PI_PlusMarker, PI_CrossMarker,
+                            PI_CircleMarker, PI_FCircleMarker,
+                            PI_BoxMarker, PI_FBoxMarker,
+                            PI_TriangleMarker, PI_FTriangleMarker,
+                            PI_StarMarker, PI_FStarMarker };
+static PILineTypes line[13] = { PI_NotDefLineAtt, PI_ThinLine, PI_NormalLine, PI_ThickLine, 
+                              PI_ThinDashedLine, PI_DashedLine, PI_ThickDashedLine, 
+			      PI_ThinDashDottedLine, PI_DashDottedLine, PI_ThickDashDottedLine,
+                              PI_ThinDottedLine, PI_DottedLine, PI_ThickDottedLine };
+
+static PIFontName fntname[5] = { PI_DefaultFont, PI_CourierFont, PI_HelveticaFont, 
+				 PI_TimesFont, PI_SymbolFont};
+static PIFontAtt fntatt[5] = { PI_NotDefFontAtt, PI_RomanFont, PI_BoldFont, 
+			       PI_ItalicFont, PI_BoldItalicFont };
+static PIFontSize fntsz[6] = { PI_NotDefFontSize, PI_TinySizeFont, PI_SmallSizeFont, 
+			       PI_NormalSizeFont, PI_LargeSizeFont, PI_HugeSizeFont };
+
+static PIArrowMarker arrmrk[6]= { PI_NotDefArrowMarker, PI_BasicArrowMarker, 
+                     PI_TriangleArrowMarker, PI_FTriangleArrowMarker,
+                     PI_ArrowShapedArrowMarker, PI_FArrowShapedArrowMarker };
+
+
+/* --Methode-- */
+void PIDrwTools::Show()
+{
+PIWindow::Show();
+UpdateControlsFromDrawer(-9);
+UpdateAttFromDrawer();
+return;
+}
+
+/* --Methode-- */
+void PIDrwTools::UpdateControlsFromDrawer(int numdr)
+{
+  string lstr;
+  int kb;
+  int butsensnew = 0;
+
+  PIDrawer * dr = NULL;
+  
+  if (mCurBW != NULL) {
+    if (numdr < -1) { 
+      if (mCurBW->NbDrawers() > 0)  mNDr = mCurBW->GetActiveDrawerNum();
+      else mNDr = -1;
+    }
+    else { 
+      if (mCurBW->NbDrawers() > 0) {
+	mNDr = numdr;
+	if (mNDr < 0)  mNDr = 0;
+	else if (mNDr >= mCurBW->NbDrawers()) mNDr = mCurBW->NbDrawers()-1;
+      }
+      else mNDr = -1;
+    }
+    if (mNDr >= 0)   dr = mCurBW->GetDrawer(mNDr);
+    if (dr != NULL)  butsensnew = 2;
+    else butsensnew = 1;
+  }
+
+  if (butsensnew == 2) {
+    char strg[64];
+    sprintf(strg,"%d",mNDr);
+    mNlb->SetLabel(strg);
+    string wdrname = mCurBW->Nom()+":"+dr->Name();
+    mDrName->SetLabel(wdrname);
+    if ((dr != NULL) && dr->HasSpecificControlWindow()) 
+      mButcf[3]->SetSensitive(); 
+    else mButcf[3]->SetUnSensitive(); 	
+  }
+  else if (mButSens != butsensnew) {
+    if(mButSens == 2)  mNlb->SetLabel("");
+    if (butsensnew == 1)   mDrName->SetLabel(mCurBW->Nom());
+    else  mDrName->SetLabel("No-BaseWdg");
+  }
+
+  if (butsensnew != mButSens) {
+    if (butsensnew < 2) {
+      for(kb=0; kb<2;kb++)  mButdr[kb]->SetUnSensitive();
+      for(kb=0; kb<4;kb++)  mButcf[kb]->SetUnSensitive();
+      if (butsensnew == 0) mButcf[4]->SetUnSensitive();
+      else mButcf[4]->SetSensitive();
+    }
+    else { 
+      for(kb=0; kb<2;kb++)  mButdr[kb]->SetSensitive();
+      for(kb=0; kb<3;kb++)  mButcf[kb]->SetSensitive();
+      mButcf[4]->SetSensitive();
+    }
+  }
+  mButSens = butsensnew;
+}    
+
+/* --Methode-- */
+void PIDrwTools::UpdateAttFromDrawer()
+{
+
+PIDrawer* dr = NULL;
+
+mOpt[0]->SetValue(100);
+mOpt[1]->SetValue(200);
+mOpt[2]->SetValue(300);
+mOpt[3]->SetValue(405);
+mOpt[4]->SetValue(500);
+mOpt[5]->SetValue(600);
+mOpt[6]->SetValue(700);
+mOpt[7]->SetValue(800);
+
+if ( (mCurBW != NULL) && (mCurBW->NbDrawers() > 0) ) 
+  dr = mCurBW->GetDrawer(mNDr);
+
+if (!dr)  return;
+int ii,jj,kk;
+PIGraphicAtt const & gratt = dr->GetGraphicAtt();
+PIColors fc = gratt.GetFgColor();
+for(kk=0; kk<MYNMXCOLORS; kk++) 
+  if (fc == cols[kk])  { mOpt[0]->SetValue(100+kk);  break; }    
+CMapId cmi = gratt.GetColMapId();
+if (cmi == CMAP_OTHER)  mOpt[1]->SetValue(200);
+else for(kk=0; kk<PIColorMap::NumberStandardColorMaps(); kk++)
+  if (cmi == PIColorMap::GetStandardColorMapId(kk)) { mOpt[1]->SetValue(201+kk);  break; }  
+PIMarker mk = gratt.GetMarker();   
+for(kk=0; kk<12; kk++) 
+  if (mk == mrk[kk])   { mOpt[2]->SetValue(300+kk);  break; }
+kk = gratt.GetMarkerSz();
+if (kk < 1)  kk = 1;
+if (kk > 15) kk = 15;
+if (kk%2 == 0) kk++;
+mOpt[3]->SetValue(400+kk);
+PIFontName fnm = gratt.GetFontName();
+PIFontAtt fat = gratt.GetFontAtt();
+PIFontSize fsz = gratt.GetFontSz();
+
+for(ii=0; ii<5; ii++)
+  if (fnm ==  fntname[ii]) break;
+for(kk=0; kk<5; kk++)
+  if (fat ==  fntatt[kk]) break;
+for(jj=0; jj<5; jj++) 
+  if (fsz == fntsz[jj])  break;
+
+if (ii >= 5) ii = 1;
+if (kk >= 5) kk = 1;
+if (jj >= 6) jj = 3;
+mOpt[4]->SetValue(500+ii);
+mOpt[6]->SetValue(700+kk);
+mOpt[7]->SetValue(800+jj);
+
+PILineAtt lat = gratt.GetLineAtt();
+for(kk=0; kk<13; kk++)
+  if (lat == line[kk])   { mOpt[5]->SetValue(600+kk);  break; }
+
+PIArrowMarker arr = gratt.GetArrowMarker();
+for(kk=0 ; kk<6 ; kk++)
+  if(arr == arrmrk[kk]) {mOpt[8]->SetValue(900+kk);}
+     
+kk = gratt.GetArrowMarkerSize();
+if(kk<1) kk=1;
+if(kk>17) kk=17;
+ kk = (kk+1)/2;
+mOpt[9]->SetValue(950 + kk);
+
+return;
+}
+
+/* --Methode-- */
+void PIDrwTools::SetGraphicAtt(bool fgref)
+{
+  if (mCurBW == NULL)   return;
+  PIDrawer* drw = mCurBW->GetDrawer(mNDr);
+  if (drw == NULL)  return;
+  mCurBW->SetActiveDrawer(mNDr);
+  PIGraphicAtt gratt;
+  int k,ii,jj,kk;
+  k = mOpt[0]->GetValue()-100;
+  if ( (k < 0) || (k >= MYNMXCOLORS) )  k = 0;
+  gratt.SetColAtt(cols[k]);
+  k = mOpt[1]->GetValue()-200;
+  if (k == 0) gratt.SetColMapId(CMAP_OTHER);
+  else gratt.SetColMapId(PIColorMap::GetStandardColorMapId(k-1));
+  k =  mOpt[2]->GetValue()-300;
+  if ( (k < 0) || (k > 11) )  k = 0;
+  kk =  mOpt[3]->GetValue()-400;
+  if ( (kk < 1) || (kk > 27) )  kk = 1;
+  //  if ((k > 0) && (kk < 3)) {  // Protection contre Marker taille 1 autre que Dotmarker
+  //    mOpt[3]->SetValue(403);
+  //   kk = 3;
+  //  }
+  gratt.SetMarkerAtt(kk, mrk[k]);
+  ii =  (mOpt[4]->GetValue()-500);
+  jj =  (mOpt[6]->GetValue()-700);
+  kk =  (mOpt[7]->GetValue()-800);
+  gratt.SetFontAtt(fntname[ii], fntsz[kk], fntatt[jj]);
+
+  k =  mOpt[5]->GetValue()-600;
+  if ( (k < 0) || (k > 12) )  k = 0;
+  gratt.SetLineAtt(PILineAtt(line[k]));
+
+  ii=mOpt[8]->GetValue()-900;
+  jj=mOpt[9]->GetValue()-950;
+  
+  gratt.SetArrowMarkerAtt(2*jj-1,arrmrk[ii]);
+  
+  drw->SetGraphicAtt(gratt);
+
+  if (fgref)  mCurBW->Refresh();
+  else drw->Refresh();
+}
+
+/* --Methode-- */
+void PIDrwTools::Process(PIMessage msg, PIMsgHandler* /*sender*/, void* /*data*/)
+{
+
+  PIMessage mod = ModMsg(msg);
+  msg = UserMsg(msg);
+
+  switch (msg) {
+    case 1501 :
+    case 1502 :
+      if (mCurBW && (mCurBW->NbDrawers() > 0)) {
+	if (msg == 1501)  UpdateControlsFromDrawer(mNDr-1);
+	else UpdateControlsFromDrawer(mNDr+1);
+      }
+      break;
+
+    case 2500 :
+      UpdateAttFromDrawer();
+      break;
+
+    case 2600 :
+      SetGraphicAtt(false);
+      break;
+
+    case 2700 :
+      if ((mCurBW != NULL) && (mCurBW->GetDrawer(mNDr) != NULL) ) {
+	if (mod == PIMsg_Press)  { 
+	  mCurBW->GetDrawer(mNDr)->HighLight(true);
+	  mCurBW->SetActiveDrawer(mNDr);
+	}
+	else  mCurBW->GetDrawer(mNDr)->HighLight(false);
+      }
+      break;
+
+    case 2800 :
+      if ((mCurBW != NULL) && (mCurBW->GetDrawer(mNDr) != NULL) ) 
+	mCurBW->GetDrawer(mNDr)->ShowControlWindow(mCurBW);
+      break;
+
+    case 3000 :
+      SetGraphicAtt(true);
+      break;
+
+    case 3777 :
+      Hide();
+      break;
+
+      /*   On ne change pas les options choisies   Reza+cmv 2/10/98  
+	   mOpt[0]->SetValue(100);
+	   mOpt[1]->SetValue(200);
+	   mOpt[2]->SetValue(300);
+	   mOpt[3]->SetValue(405);
+	   mOpt[4]->SetValue(500);
+	   mOpt[5]->SetValue(600);
+    */
+      break;
+
+    default :
+      break;
+  }
+
+return;
+}
+
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/pidrwtools.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pidrwtools.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pidrwtools.h	(revision 2309)
@@ -0,0 +1,57 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Outils de manipulation des PIDrawer  R. Ansari 06/98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PIDRWTOOLS_H_SEEN
+#define PIDRWTOOLS_H_SEEN
+
+#include "pisysdep.h"
+#include PISTDWDG_H
+#include PIOPTMENU_H
+#include PIWIN_H
+#include PIAPP_H
+#include "pibwdggen.h"
+
+// --------- fenetre de dialogue pour modifs axes et options des Drawers ----------
+// --------------------------------------------------------------------------------
+
+
+class PIDrwTools : public PIWindow 
+{
+public :
+  PIDrwTools(PIApplication* par);
+  ~PIDrwTools();
+  virtual void  Show();
+
+  static void ShowPIDrwTools();
+  static void ShowPIDrwTools(PIBaseWdgGen* cbw);
+  static void HidePIDrwTools();
+  static void SetCurrentBaseWdg(PIBaseWdgGen* cbw);
+  static PIBaseWdgGen* GetCurrentBaseWdg();
+  static PIDrawer* GetActiveDrawer();
+  static void UpdateActiveDrawer();
+
+protected:
+  virtual void  UpdateControlsFromDrawer(int numdr);
+  virtual void  UpdateAttFromDrawer();
+  virtual void  SetGraphicAtt(bool fgref);
+  virtual void  Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+
+private:
+// Pour couleur, fontes, etc 
+  PIOptMenu* mOpt[10];
+  PIMenu* mCasc[5];
+  PILabel* mNlb;
+  PILabel* mDrName;
+  PIButton* mButdr[2];
+  PIButton* mButcf[6];
+  int mNDr;
+// mButSens  - Pour l'etat de sensibilite des boutons 
+// 0 NoBaseDrawer , 1 BaseDrawer - NoDrawer , 2= BaseDrawer+CurDrawer
+  int mButSens;  
+// ------------------------------------------------------
+  static PIBaseWdgGen* mCurBW;
+  static PIDrwTools* cwdrwt;
+};
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pieldrw.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pieldrw.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pieldrw.cc	(revision 2309)
@@ -0,0 +1,642 @@
+// Module PI : Peida Interactive     PIElDrawer
+//	      E. Aubourg , R.Ansari     96-02
+// (C) LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "machdefs.h"
+#include <strings.h>
+#include <iostream.h>
+
+#include "pieldrw.h"
+
+#include <math.h>
+
+/*  --------------------------------------------------------------  */
+/*  ------------------- Classe PIElDrwMgr ------------------------  */
+/*  --------------------------------------------------------------  */
+
+//++
+// Class	PIElDrwMgr
+// Lib		PI
+// include	pieldrw.h
+//
+//	Classe gestionnaire de tracé d'éléments. Utilisé par "PIElDrawer".
+//--
+//++
+// Links	Voir aussi
+// PIElDrawer
+//--
+//++
+// Titre	Constructeurs et méthodes
+//--
+
+/* --Methode-- */
+//++
+PIElDrwMgr::PIElDrwMgr()
+//	Constructeur
+//--
+{
+  mEn = 0;
+}
+
+/* --Methode-- */
+//++
+PIElDrwMgr::~PIElDrwMgr()
+//	destructeur
+//--
+{
+  ElDelAll();
+}
+
+/* Des macros pour passer des coord normalise aux coord graphique */
+#define CN_To_CG_X(x)  x0_g+dx_g*(double)x
+#define CN_To_CG_Y(y)  y0_g+dy_g*(double)y
+#define D_CN_To_CG_X(x)  dx_g*(double)x
+#define D_CN_To_CG_Y(y)  dy_g*(double)y
+#define CN_To_CG_R(r)  0.5*(dx_g+dy_g)*(double)r
+
+/* --Methode-- */
+//++
+void PIElDrwMgr::DrawElements(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax)
+//	Tracé des éléments
+//--
+{
+  DrwElList::iterator it;
+  g->SaveGraphicAtt();
+
+  PIGrCoord x1g,x2g,y1g,y2g,xg,yg;
+  double x0_g, dx_g, y0_g, dy_g;
+  g->GetGrSpace(x1g,x2g,y1g,y2g);
+  x0_g = x1g;  y0_g = y1g;
+  dx_g = (double)x2g-(double)x1g;
+  dy_g = (double)y2g-(double)y1g;
+
+  for (it = mElist.begin(); it != mElist.end(); it++)
+    {
+      PIColors fcol = (*it).gatt.GetFgColor(); 
+      if (fcol != PI_NotDefColor)    g->SelForeground(fcol);
+      PIColors bcol = (*it).gatt.GetBgColor(); 
+      if (bcol != PI_NotDefColor)    g->SelBackground(bcol);
+      if ((*it).gatt.GetLineAtt() != PI_NotDefLineAtt)  
+	g->SelLine((*it).gatt.GetLineAtt());
+      if ( ((*it).gatt.GetFontName() != PI_DefaultFont) ||
+	   ((*it).gatt.GetFontAtt() != PI_NotDefFontAtt) )
+	g->SelFont((*it).gatt.GetFont());
+      if ((*it).gatt.GetMarker() != PI_NotDefMarker) 
+	g->SelMarker((*it).gatt.GetMarkerSize(), (*it).gatt.GetMarker());
+      if ((*it).gatt.GetArrowMarker() !=  PI_NotDefArrowMarker) 
+	g->SelArrowMarker((*it).gatt.GetArrowMarkerSize(), 
+			  (*it).gatt.GetArrowMarker());
+
+      switch ( (*it).etyp )
+	{
+	case PIDEL_Line :
+	  if ((*it).scc)  // Coord specifie normalise 0..1
+	    g->DrawLine(CN_To_CG_X((*it).ex), CN_To_CG_Y((*it).ey), 
+			D_CN_To_CG_X((*it).edx), D_CN_To_CG_Y((*it).edy) ); 
+	  else g->DrawLine((*it).ex, (*it).ey, (*it).edx, (*it).edy ); 
+	  break;
+	case PIDEL_Mark :
+	  if ((*it).scc)  // Coord specifie normalise 0..1
+	    g->DrawMarker(CN_To_CG_X((*it).ex), CN_To_CG_Y((*it).ey));
+	  else g->DrawMarker((*it).ex, (*it).ey);
+	  break;
+	case PIDEL_Arrow :
+	  if ((*it).scc)  // Coord specifie normalise 0..1
+	    g->DrawArrowMarker(CN_To_CG_X((*it).ex), CN_To_CG_Y((*it).ey), 
+			       D_CN_To_CG_X((*it).edx), D_CN_To_CG_Y((*it).edy) );
+	  else g->DrawArrowMarker((*it).ex, (*it).ey, (*it).edx, (*it).edy, true); 
+	  break;
+	case PIDEL_Text :
+	  if ((*it).scc)  // Coord specifie normalise 0..1
+	    g->DrawString(CN_To_CG_X((*it).ex), CN_To_CG_Y((*it).ey),
+			  ((*it).es->txt.c_str()), (*it).es->txtpd ); 
+	  else g->DrawString((*it).ex, (*it).ey, ((*it).es->txt.c_str()), (*it).es->txtpd ); 
+	  break;
+	case PIDEL_CText :
+	  if ((*it).scc) { // Coord specifie normalise 0..1
+	    xg = CN_To_CG_X((*it).ex);
+	    yg = CN_To_CG_Y((*it).ey);
+	  }
+	  else {
+	    xg = (*it).ex;
+	    yg = (*it).ey;
+	  }
+	  if ((*it).es->attss) 
+	    g->DrawCompString(xg, yg, (*it).es->txt.c_str(), (*it).es->txt_up->c_str(),
+			      (*it).es->txt_dn->c_str(), (*it).es->attss->GetFont(), 
+			      (*it).es->txtpd );
+	  else 
+	    g->DrawCompString(xg, yg, (*it).es->txt.c_str(), (*it).es->txt_up->c_str(),
+			      (*it).es->txt_dn->c_str(), (*it).es->txtpd );
+
+	  break;
+	case PIDEL_Rect :
+	  if ((*it).scc)  // Coord specifie normalise 0..1
+	    g->DrawBox(CN_To_CG_X((*it).ex), CN_To_CG_Y((*it).ey), 
+		       D_CN_To_CG_X((*it).edx), D_CN_To_CG_Y((*it).edy) ); 
+	  else 	g->DrawBox((*it).ex, (*it).ey, (*it).edx, (*it).edy ); 
+	  break;
+	case PIDEL_FRect :
+	  if ((*it).scc)  // Coord specifie normalise 0..1
+	    g->DrawFBox(CN_To_CG_X((*it).ex), CN_To_CG_Y((*it).ey), 
+			D_CN_To_CG_X((*it).edx), D_CN_To_CG_Y((*it).edy) ); 
+	  else g->DrawFBox((*it).ex, (*it).ey, (*it).edx, (*it).edy ); 
+	  break;
+	case PIDEL_Circ :
+	  if ((*it).scc)  // Coord specifie normalise 0..1
+	    g->DrawCircle(CN_To_CG_X((*it).ex), CN_To_CG_Y((*it).ey), CN_To_CG_R((*it).er) );
+	  else  g->DrawCircle((*it).ex, (*it).ey, (*it).er ); 
+	  break;
+	case PIDEL_FCirc :
+	  if ((*it).scc)  // Coord specifie normalise 0..1
+	    g->DrawFCircle(CN_To_CG_X((*it).ex), CN_To_CG_Y((*it).ey), CN_To_CG_R((*it).er) );
+	  else g->DrawFCircle((*it).ex, (*it).ey, (*it).er ); 
+	  break;
+	case PIDEL_Arc :
+	  if ((*it).scc)  // Coord specifie normalise 0..1
+	    g->DrawArc(CN_To_CG_X((*it).ex), CN_To_CG_Y((*it).ey), CN_To_CG_R((*it).er),
+		       CN_To_CG_R((*it).er), (*it).edx, (*it).edy );
+	  else  g->DrawArc((*it).ex, (*it).ey, (*it).er, (*it).er, 
+			   (*it).edx, (*it).edy ); 
+	  break;
+	case PIDEL_FArc :
+	  if ((*it).scc)  // Coord specifie normalise 0..1
+	    g->DrawFArc(CN_To_CG_X((*it).ex), CN_To_CG_Y((*it).ey), CN_To_CG_R((*it).er),
+			CN_To_CG_R((*it).er), (*it).edx, (*it).edy );
+	  else  g->DrawFArc((*it).ex, (*it).ey, (*it).er, (*it).er, 
+			    (*it).edx, (*it).edy ); 
+	  break;
+	case PIDEL_Arc3P :
+	  if ((*it).scc)  // Coord specifie normalise 0..1
+	    g->Draw3PtArc(CN_To_CG_X((*it).xpol[0]), CN_To_CG_X((*it).xpol[1]), 
+			  CN_To_CG_X((*it).xpol[2]), CN_To_CG_Y((*it).ypol[0]),
+			  CN_To_CG_Y((*it).ypol[1]), CN_To_CG_Y((*it).ypol[1]) );
+	  else g->Draw3PtArc((*it).xpol[0], (*it).ypol[0], (*it).xpol[1], 
+			     (*it).ypol[1], (*it).xpol[2], (*it).ypol[2] );
+	  break;
+	case PIDEL_FArc3P :
+	  if ((*it).scc)  // Coord specifie normalise 0..1
+	    g->Draw3PtFArc(CN_To_CG_X((*it).xpol[0]), CN_To_CG_X((*it).xpol[1]), 
+			   CN_To_CG_X((*it).xpol[2]), CN_To_CG_Y((*it).ypol[0]),
+			   CN_To_CG_Y((*it).ypol[1]), CN_To_CG_Y((*it).ypol[1]) );
+	  else  g->Draw3PtFArc((*it).xpol[0], (*it).ypol[0], (*it).xpol[1], 
+			       (*it).ypol[1], (*it).xpol[2], (*it).ypol[2] );
+	  break;
+	case PIDEL_Poly :
+	case PIDEL_FPoly :
+	  if ((*it).scc) { // Coord specifie normalise 0..1
+	    PIGrCoord* grx = new PIGrCoord[(*it).npol];
+	    PIGrCoord* gry = new PIGrCoord[(*it).npol];
+	    for(int jk=0; jk<(*it).npol; jk++) {
+	      grx[jk] = CN_To_CG_X((*it).xpol[jk]);
+	      gry[jk] = CN_To_CG_Y((*it).ypol[jk]);
+	    }
+	    if ((*it).etyp == PIDEL_Poly) 
+	      g->DrawPolygon(grx, gry, (*it).npol, false ); 
+	    else  g->DrawFPolygon(grx, gry, (*it).npol, false );
+	    delete[] grx;
+	    delete[] gry;
+	  }
+	  else {
+	    if ((*it).etyp == PIDEL_Poly) 
+	      g->DrawPolygon((*it).xpol, (*it).ypol, (*it).npol, false ); 
+	    else g->DrawFPolygon((*it).xpol, (*it).ypol, (*it).npol, false ); 
+	  }
+	  break;
+	default :
+	  break;
+	}
+      g->RestoreGraphicAtt();
+    }
+}
+
+//++
+// int  ElAddText(double x, double y, const char* s, bool fgsc=false)
+// int  ElAddText(double x, double y, const char* s, PIGraphicAtt gatt,  \
+//                unsigned long tpd, bool fgsc=false)
+// int  ElAddText(double x, double y, string const & s, bool fgsc=false)
+// int  ElAddText(double x, double y, string const &  s, PIGraphicAtt gatt, \
+//                unsigned long tpd, bool fgsc=false)
+//	Ajout d'un élément texte (possibilité de spécification d'un attribut graphique
+//	et d'un attribut de direction et de positionnement de texte "tpd").
+//	si "fgsc==true", coordonnées spécifiées considerées normalisées entre 0 et 1.
+//	Renvoie le numéro identificateur de l'élément.
+// 
+// int  ElAddCompText(double x, double y, string const& s, PIGraphicAtt const & gatt, \
+//                    string const& s_up, string const& s_dn, \
+//                    unsigned long tpd=0, bool fgsc=false)
+// int  ElAddCompText(double x, double y, string const& s, PIGraphicAtt const & gatt, \
+//                    string const& s_up, string const& s_dn, \
+//                    unsigned long tpd=0, bool fgsc=false)
+// int  ElAddCompText(double x, double y, string const& s, PIGraphicAtt const & gatt, \
+//                    string const& s_up, string const& s_dn, PIGraphicAtt const & attss, \
+//                    unsigned long tpd=0, bool fgsc=false)
+//	Ajout d'un élément texte avec exposant ("s_up") et indice ("s_dn").
+//	Il est possible de spécifier un attribut graphique ("gatt"), attribut de 
+//	de direction et de positionnement de texte ("tpd"), ainsi qu'un attribut graphique
+//	(fonte en particulier) pour le texte en exposant/indice ("attss").
+//	si "fgsc==true", coordonnées spécifiées considerées normalisées entre 0 et 1.
+//	Renvoie le numéro identificateur de l'élément.
+//
+// int  ElAddLine(double x1, double y1, double x2, double y2, bool fgsc=false)
+// int  ElAddLine(double x1, double y1, double x2, double y2, PIGraphicAtt gatt, bool fgsc=false)
+//	Ajout d'un élément de ligne (possibilité de spécification d'un attribut graphique).
+//	si "fgsc==true", coordonnées spécifiées considerées normalisées entre 0 et 1.
+//	Renvoie le numéro identificateur de l'élément.
+//	
+// int  ElAddRect(double x, double y, double dx, double dy, bool fgsc=false)
+// int  ElAddRect(double x, double y, double dx, double dy, PIGraphicAtt gatt, bool fgsc=false)
+//	Ajout d'un élément de type rectangle (possibilité de spécification d'un attribut graphique).
+//	si "fgsc==true", coordonnées spécifiées considerées normalisées entre 0 et 1.
+//	Renvoie le numéro identificateur de l'élément.
+//
+// int  ElAddFRect(double x, double y, double dx, double dy, bool fgsc=false)
+// int  ElAddFRect(double x, double y, double dx, double dy,  PIGraphicAtt gatt, bool fgsc=false)
+//	Ajout d'un élément de type rectangle plein 
+//	(possibilité de spécification d'un attribut graphique).
+//	si "fgsc==true", coordonnées spécifiées considerées normalisées entre 0 et 1.
+//	Renvoie le numéro identificateur de l'élément.
+//
+// int  ElAddCirc(double x, double y, double r, bool fgsc=false)
+// int  ElAddCirc(double x, double y, double r, PIGraphicAtt gatt, bool fgsc=false)
+//	Ajout d'un élément de type cercle (possibilité de spécification d'un attribut graphique).
+//	si "fgsc==true", coordonnées spécifiées considerées normalisées entre 0 et 1.
+//	Renvoie le numéro identificateur de l'élément.
+//
+// int  ElAddFCirc(double x, double y, double r, bool fgsc=false)
+// int  ElAddFCirc(double x, double y, double r, PIGraphicAtt gatt, bool fgsc=false)
+//	Ajout d'un élément de type cercle plein avec un attribut de couleur.
+//	si "fgsc==true", coordonnées spécifiées considerées normalisées entre 0 et 1.
+//	Renvoie le numéro identificateur de l'élément.
+//
+// int  ElAddArc(double x, double y, double r, double a1, double da, bool fgsc=false)
+// int  ElAddArc(double x, double y, double r, double a1, double da, \
+//               PIGraphicAtt gatt, bool fgsc=false)
+//	Ajout d'un élément de type arc de cercle défini par un angle de départ "a1"
+//	et une extension angulaire "da". 
+//	Il est possible de spécifier un attribut graphique.
+//	si "fgsc==true", coordonnées spécifiées considerées normalisées entre 0 et 1.
+//	Renvoie le numéro identificateur de l'élément.
+//
+// int  ElAddFArc(double x, double y, double r, double a1, double da, bool fgsc=false)
+// int  ElAddFArc(double x, double y, double r, double a1, double da, \
+//                PIGraphicAtt gatt, bool fgsc=false)
+//	Ajout d'un élément de type arc de cercle plein défini par un angle de 
+//	départ "a1" et une extension angulaire "da". 
+//	Il est possible de spécifier un attribut graphique.
+//	si "fgsc==true", coordonnées spécifiées considerées normalisées entre 0 et 1.
+//	Renvoie le numéro identificateur de l'élément.
+//
+// int  ElAddArc(double x1, double y1, double x2, double y2 \
+//               double x3, double y3, bool fgsc=false)
+// int  ElAddArc(double x1, double y1, double x2, double y2 \
+//               double x3, double y3, PIGraphicAtt gatt, bool fgsc=false)
+//	Ajout d'un élément de type arc défini par trois points
+//	(possibilité de spécification d'un attribut graphique).
+//	si "fgsc==true", coordonnées spécifiées considerées normalisées entre 0 et 1.
+//	Renvoie le numéro identificateur de l'élément.
+//
+// int  ElAddFArc(double x1, double y1, double x2, double y2 \
+//                double x3, double y3, bool fgsc=false)
+// int  ElAddFArc(double x1, double y1, double x2, double y2 \
+//                double x3, double y3, PIGraphicAtt gatt, bool fgsc=false)
+//	Ajout d'un élément de type arc plein défini par trois points
+//	(possibilité de spécification d'un attribut graphique).
+//	si "fgsc==true", coordonnées spécifiées considerées normalisées entre 0 et 1.
+//	Renvoie le numéro identificateur de l'élément.
+//
+// int  ElAddPoly(vector<double>& x, vector<double>& y, bool fgsc=false)
+// int  ElAddPoly(vector<double>& x, vector<double>& y, PIGraphicAtt gatt, bool fgsc=false)
+//	Ajout d'un élément de type polygone (possibilité de spécification d'un attribut graphique).
+//	si "fgsc==true", coordonnées spécifiées considerées normalisées entre 0 et 1.
+//	Renvoie le numéro identificateur de l'élément.
+//
+// int  ElAddFPoly(vector<double>& x, vector<double>& y, bool fgsc=false)
+// int  ElAddFPoly(vector<double>& x, vector<double>& y, PIGraphicAtt gatt, bool fgsc=false)
+//	Ajout d'un élément de type polygone plein 
+//	(possibilité de spécification d'un attribut graphique).
+//	si "fgsc==true", coordonnées spécifiées considerées normalisées entre 0 et 1.
+//	Renvoie le numéro identificateur de l'élément.
+// 
+// void  ElDel(int id)
+//	Suppression de l'élément avec l'identificateur "id".
+// void  ElDelLast()
+//	Suppression du dernier élément ajouté.
+// void  ElDelAll()
+//	Suppression de tous les éléments de l'objet.
+//--
+
+
+/* --Methode-- */
+int PIElDrwMgr::ElAdd(int typ, double x, double  y, double dx, double dy, 
+		      const char* s, PIGraphicAtt const& att, 
+		      unsigned long tpd, bool fgsc, double r)
+{
+  DrwEl dre;
+  mEn++;
+  dre.eid = mEn;  dre.etyp = typ;
+  dre.ex = x;   dre.ey = y;
+  dre.edx = dx;  dre.edy = dy;
+  dre.er = r; 
+  dre.gatt = att;
+  if (s)  { 
+    dre.es = new TxtEl;
+    dre.es->txt = s;
+    dre.es->txtpd = tpd;
+    dre.es->txt_up = dre.es->txt_dn = NULL;
+    dre.es->attss = NULL;
+  }
+  else dre.es = NULL;
+  dre.xpol = dre.ypol = NULL;
+  dre.npol = 0;
+  dre.scc = fgsc;
+  mElist.push_back(dre);
+  return(mEn);
+}
+
+/* --Methode-- */
+int PIElDrwMgr::ElAdd(double x, double y, const char* s, PIGraphicAtt const & att, const char* s_up, 
+		      const char* s_dn, PIGraphicAtt const * gass, unsigned long tpd, bool fgsc)
+{
+  DrwEl dre;
+  mEn++;
+  dre.eid = mEn; dre.etyp = PIDEL_CText;
+  dre.ex = x;   dre.ey = y;
+  dre.edx = 0;  dre.edy = 0; 
+  dre.er = 0.;
+  dre.gatt = att;
+  dre.es = new TxtEl;
+  if (s) dre.es->txt = s;
+  dre.es->txtpd = tpd;
+  dre.es->txt_up = new string;
+  if (s_up) *(dre.es->txt_up) = s_up;
+  dre.es->txt_dn = new string;
+  if (s_dn) *(dre.es->txt_dn) = s_dn;
+  if (gass) dre.es->attss = new PIGraphicAtt(*gass);
+  else dre.es->attss = NULL;
+  dre.xpol = dre.ypol = NULL;
+  dre.npol = 0;
+  dre.scc = fgsc;
+  mElist.push_back(dre);
+  return(mEn);  
+}
+
+/* --Methode-- */
+int PIElDrwMgr::ElAdd(int typ, vector<double>& x, vector<double>& y, 
+		      PIGraphicAtt const& att, bool fgsc)
+{
+  DrwEl dre;
+  mEn++;
+  dre.eid = mEn;  dre.etyp = typ;
+  dre.ex = dre.ey = 0;
+  dre.edx = dre.edy = 0;
+  dre.er = 0.;
+  dre.gatt = att;
+  dre.es = NULL;
+  dre.xpol = dre.ypol = NULL;
+  dre.npol = (y.size() < x.size()) ? y.size() : x.size();
+  if (dre.npol > 0) {
+    dre.xpol = new PIGrCoord[dre.npol];
+    dre.ypol = new PIGrCoord[dre.npol];
+    for(int kk=0; kk<dre.npol; kk++) {
+      dre.xpol[kk] = x[kk];
+      dre.ypol[kk] = y[kk];
+    }
+  }
+  dre.scc = fgsc;
+  mElist.push_back(dre);
+  return(mEn);
+}
+
+/* --Methode-- */
+int PIElDrwMgr::ElAdd(int typ, double* x, double* y, int n,
+		      PIGraphicAtt const & att, bool fgsc)
+{
+  vector<double> vx, vy;
+  for(int k=0; k<n; k++) {
+    vx.push_back(x[k]);
+    vy.push_back(y[k]);
+  }
+  return ( ElAdd(typ, vx, vy, att, fgsc) );
+}
+
+
+/* --Methode-- */
+void  PIElDrwMgr::ElDel(int id)
+{
+  DrwElList::iterator it;
+  for (it = mElist.begin(); it != mElist.end(); it++) {
+    if ( (*it).eid == id) { 
+      if ( (*it).es ) { 
+        if ( (*it).es->txt_up ) delete (*it).es->txt_up;
+        if ( (*it).es->txt_dn ) delete (*it).es->txt_dn;
+        if ( (*it).es->attss ) delete (*it).es->attss;
+        delete (*it).es;
+      }
+      if ( (*it).xpol ) delete[] (*it).xpol;
+      if ( (*it).ypol ) delete[] (*it).ypol;
+      mElist.erase(it);   
+      break; 
+    }
+  }
+  return;
+}
+
+/* --Methode-- */
+void  PIElDrwMgr::ElDelAll()
+{
+  DrwElList::iterator it;
+  for (it = mElist.begin(); it != mElist.end(); it++) {
+    if ( (*it).es ) delete (*it).es;
+    if ( (*it).xpol ) delete[] (*it).xpol;
+    if ( (*it).ypol ) delete[] (*it).ypol;
+  }
+  mElist.erase(mElist.begin(), mElist.end());
+  return;
+}
+
+
+
+
+/*  --------------------------------------------------------------  */
+/*  ------------------- Classe PIElDrawer ------------------------  */
+/*  --------------------------------------------------------------  */
+
+//++
+// Class	PIElDrawer
+// Lib		PI
+// include	pieldrw.h
+//
+//	Classe de traceur ("Drawer") capable de gérer et de 
+//	tracer une liste d'éléments simples. Cette classe
+//	est utilisé pour le tracé des axes et des éléments de
+//	texte ds les "PIScDrawWdg", "PIDraw3DWdg" et "PIImage".
+//--
+//++
+// Links	Parents
+// PIDrawer
+//--
+//++
+// Links	Voir aussi
+// PIElDrwMgr
+//--
+
+//++
+// Titre	Constructeurs et méthodes
+//--
+
+//++
+// PIElDrawer(bool fgclip=true)
+//	Constructeur - Si "fgclip=false", appel a PIGraphicUC::NoClip() ds Draw()
+//--
+
+/* --Methode-- */
+PIElDrawer::PIElDrawer(bool fgclip)
+{
+fgClip = fgclip;
+ShowTitles();
+ShowAxesLabels();
+}
+
+/* --Methode-- */
+PIElDrawer::~PIElDrawer()
+{
+}
+
+
+//++
+//  void  SetTitles(string tt, string tb)
+//	Ajout de titres haut ("tt") et bas ("tb")
+//--
+
+
+/* --Methode-- */
+int PIElDrawer::DecodeOptionString(vector<string> & opt, bool rmdecopt)
+{
+  int nopt0 = opt.size();
+  if (nopt0 < 1)  return(0);  
+  int ndec1 = PIDrawer::DecodeOptionString(opt, rmdecopt);
+  if ((nopt0 - ndec1) < 1) return(ndec1);  // si tout a ete decode
+  vector<string> udopt;
+  unsigned int k = 0;
+  int ndec = opt.size();
+  for( k=0; k<opt.size(); k++ ) {
+    string opts = opt[k];
+    if ( (opts == "stdaxes") || (opts == "defaxes") || (opts == "boxaxes") )
+      SetAxesFlags(kBoxAxes | kExtTicks | kLabels);
+    else if (opts == "boxaxesgrid")
+      SetAxesFlags(kBoxAxes | kExtTicks | kLabels | kGridOn);
+    else if (opts == "fineaxes") 
+      SetAxesFlags(kBoxAxes | kTicks | kLabels | kMinTicks | kMajTicks);
+    else if (opts == "fineaxesgrid")
+      SetAxesFlags(kBoxAxes | kTicks | kLabels | kMinTicks | kMajTicks | kGridOn);
+    else if (opts == "centeredaxes")
+      SetAxesFlags(kStdAxes | kMajTicks | kLabels);
+    else if (opts == "finecenteredaxes")
+      SetAxesFlags(kStdAxes | kMajTicks | kMinTicks | kLabels);
+    else if (opts == "centeredaxesgrid")
+      SetAxesFlags(kStdAxes | kMajTicks | kLabels | kGridOn);
+    else if (opts == "finecenteredaxesgrid")
+      SetAxesFlags(kStdAxes | kMajTicks | kMinTicks | kLabels | kGridOn);
+    else if (opts == "axesnone")
+      SetAxesFlags(kAxesNone);
+    else if (opts == "labels")
+      SetAxesFlags(GetAxesFlags() | kLabels);
+    else if (opts == "nolabels")
+      SetAxesFlags(GetAxesFlags() & ~kLabels);
+    else if (opts == "ticks")
+      SetAxesFlags(GetAxesFlags() | kTicks);
+    else if (opts == "noticks")
+      SetAxesFlags(GetAxesFlags() & ~kTicks);
+    else if (opts == "minorticks")
+      SetAxesFlags(GetAxesFlags() | kMinTicks);
+    else if (opts == "nominorticks")
+      SetAxesFlags(GetAxesFlags() & ~kMinTicks);
+    else if (opts == "extticks")
+      SetAxesFlags(GetAxesFlags() | kExtTicks);
+    else if (opts == "intticks")
+      SetAxesFlags(GetAxesFlags() | kIntTicks);
+    else if (opts == "grid")
+      SetAxesFlags(GetAxesFlags() | kGridOn);
+    else if (opts == "nogrid")
+      SetAxesFlags(GetAxesFlags() & ~kGridOn);
+    else if (opts == "autofontsize")
+      SetAxesAutoFontSize(true);
+    else if (opts == "fixedfontsize")
+      SetAxesAutoFontSize(false);
+    else if (opts == "title" || opts == "tit") ShowTitles(true);
+    else if (opts == "notitle" || opts == "notit") ShowTitles(false);
+
+    else {
+      ndec--;
+      if (rmdecopt)  udopt.push_back(opts);
+    }
+  }  
+
+  if (rmdecopt)  opt = udopt;
+  return(ndec+ndec1);
+}
+
+/* --Methode-- */
+void  PIElDrawer::DrawAxes(PIGraphicUC* g)
+{
+  if (axesFlags == kAxesNone) return;
+  //  g->NoClip();
+  g->SaveGraphicAtt();
+  PIAxes axes;
+  axes.DrawXYAxes(g, mGrAtt, axesFlags, axesAFSz, XMin(), XMax(), YMin(), YMax()); 
+  g->RestoreGraphicAtt();
+  if (showAxesLabels) { 
+    axes.DrawXCaption(g, labelAtt, axesFlags, xLabel);
+    axes.DrawYCaption(g, labelAtt, axesFlags, yLabel);
+  }
+  //  g->Clip();
+  g->RestoreGraphicAtt(); 
+}
+
+/* --Methode-- */
+void  PIElDrawer::Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax)
+{
+SelGraAtt(g);   
+if (!fgClip) g->NoClip();
+DrawAxes(g);   // Trace des axes 
+// g->SelFont(PI_NormalSizeFont);
+
+
+// Trace des titres 
+if ( showTitles && ((titleT.length() > 0) || (titleB.length() > 0)) ) {
+  PIGraphicAtt grs = GetGraphicAtt();
+  UpdateGraphicAtt(titleAtt);
+  SelGraAtt(g); 
+
+  aXdir = false;  // Vrai si Axe X de Droite vers Gauche 
+  aYdir = false;  // Vrai si Axe Y de Haut vers Bas
+  double fx, fy, fh;
+  fx = g->DeltaUCX(XMin(), 0.5*(XMax()-XMin()));
+		   
+//  fh = g->GetFontHeightUC(gas, gds);
+  fh = 0.075*(YMax()-YMin());
+  if ( titleT.length() > 0) {
+    if (g->isAxeYDirUpDown()) fy = g->DeltaUCY(YMin(), -fh);
+    else fy = g->DeltaUCY(YMax(), fh);
+    g->DrawString(fx, fy, titleT.c_str(), PI_HorizontalCenter | PI_VerticalCenter);
+    //      printf(" PIElDrawer::Draw()/DBG (%g , %g) %s  - %g \n", fx, fy, titleT.c_str(), fh);
+  }
+  if ( titleB.length() > 0) {
+    fx = g->CalcStringWidth(titleB.c_str());
+    if(aXdir) fx = g->DeltaUCX(XMax(), -(XMax()-XMin()-fx)/2.);
+    else fx = g->DeltaUCX(XMin(), (XMax()-XMin()-fx)/2.);
+    if (g->isAxeYDirUpDown()) fy =  g->DeltaUCY(YMax(), fh*1.5);
+    else fy = g->DeltaUCY(YMin(), -fh*1.5);
+    g->DrawString(fx, fy, titleB.c_str(), PI_HorizontalCenter | PI_VerticalCenter);
+    //      printf(" PIElDrawer::Draw()/DBG (%g , %g) %s  - %g \n", fx, fy, titleT.c_str(), fh);
+  }
+  SetGraphicAtt(grs); 
+}
+ g->RestoreGraphicAtt();
+ SelGraAtt(g);
+ // Trace des elements
+ ElDrwMgr().DrawElements(g, xmin, ymin, xmax, ymax);
+
+}
+
Index: /tags/V_Dec2002/SophyaPI/PI/pieldrw.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pieldrw.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pieldrw.h	(revision 2309)
@@ -0,0 +1,256 @@
+// This may look like C code, but it is really -*- C++ -*-
+// PIElDrawer - 
+//                             R. Ansari  97-02
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+#ifndef PIELDRW_H
+#define PIELDRW_H
+
+#include "pidrawer.h"
+
+/*  ------------------- Classe PIElDrwMgr ------------------------  */
+//  Classe avec gerant d une liste d elements a tracer 
+
+class PIElDrwMgr
+{
+public:
+  enum { PIDEL_Line = 1, PIDEL_Text = 2,
+         PIDEL_Rect = 3, PIDEL_FRect = 4, 
+         PIDEL_Circ = 5, PIDEL_FCirc = 6,
+         PIDEL_Arc = 7,  PIDEL_FArc = 8,
+         PIDEL_Arc3P = 9,  PIDEL_FArc3P = 10,
+         PIDEL_Poly = 11, PIDEL_FPoly = 12,
+	 PIDEL_Mark = 13, PIDEL_Arrow = 14,
+         PIDEL_CText = 15  } ; 
+
+		PIElDrwMgr();
+  virtual	~PIElDrwMgr();
+
+  virtual void  DrawElements(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax);
+
+  // ---- Ajout de lignes
+  inline int    ElAddLine(double x1, double y1, double x2, double y2, bool fgsc=false)
+    { PIGraphicAtt gatt; return( ElAdd(PIDEL_Line, x1, y1, x2, y2, NULL, gatt, 0, fgsc) ); }  
+  inline int    ElAddLine(double x1, double y1, double x2, double y2, 
+			  PIGraphicAtt const & gatt, bool fgsc=false)
+    { return( ElAdd(PIDEL_Line, x1, y1, x2, y2, NULL, gatt, 0, fgsc) ); }  
+
+  // ---- Ajout de fleches 
+  inline int    ElAddArrow(double x1, double y1, double x2, double y2, bool fgsc=false)
+    { PIGraphicAtt gatt; return( ElAdd(PIDEL_Arrow, x1, y1, x2, y2, NULL, gatt, 0, fgsc) ); }  
+  inline int    ElAddArrow(double x1, double y1, double x2, double y2, 
+			   PIGraphicAtt const & gatt, bool fgsc=false)
+    { return( ElAdd(PIDEL_Arrow, x1, y1, x2, y2, NULL, gatt, 0, fgsc) ); }  
+
+  // ---- Ajout de marker 
+  inline int    ElAddMarker(double x, double y, bool fgsc=false)
+    { PIGraphicAtt gatt; return( ElAdd(PIDEL_Circ, x, y, 0, 0, NULL, gatt, 0, fgsc) ); }  
+  inline int    ElAddMarker(double x, double y, PIGraphicAtt const & gatt, bool fgsc=false)
+    { return( ElAdd(PIDEL_Mark, x, y, 0, 0, NULL, gatt, 0, fgsc) ); }  
+
+  // ---- Ajout de texte
+  inline int    ElAddText(double x, double y, const char* s, bool fgsc=false)
+    { PIGraphicAtt gatt; return( ElAdd(PIDEL_Text, x, y, 0, 0, s, gatt, 0, fgsc) ); }  
+  inline int    ElAddText(double x, double y, const char* s, 
+			  PIGraphicAtt const & gatt, unsigned long tpd, bool fgsc=false)
+    { return( ElAdd(PIDEL_Text, x, y, 0, 0, s, gatt, tpd, fgsc) ); }  
+  inline int    ElAddText(double x, double y, string const & s, bool fgsc=false)
+    { PIGraphicAtt gatt; return( ElAdd(PIDEL_Text, x, y, 0, 0, s.c_str(), gatt, 0, fgsc) ); }  
+  inline int    ElAddText(double x, double y, string const & s, 
+			  PIGraphicAtt const & gatt, unsigned long tpd, bool fgsc=false)
+    { return( ElAdd(PIDEL_Text, x, y, 0, 0, s.c_str(), gatt, tpd, fgsc) ); }  
+
+  // ---- Ajout de texte composite avec exposant - indice
+  inline int    ElAddCompText(double x, double y, string const& s, string const& s_up,
+			      string const& s_dn, unsigned long tpd=0, bool fgsc=false)
+    { PIGraphicAtt gatt; 
+      return( ElAdd(x, y, s.c_str(), gatt, s_up.c_str(), s_dn.c_str(), NULL, tpd, fgsc) ); } 
+  inline int    ElAddCompText(double x, double y, string const& s, PIGraphicAtt const & gatt,
+			      string const& s_up, string const& s_dn, 
+			      unsigned long tpd=0, bool fgsc=false)
+    { return( ElAdd(x, y, s.c_str(), gatt, s_up.c_str(), s_dn.c_str(), NULL, tpd, fgsc) ); } 
+  inline int    ElAddCompText(double x, double y, string const& s, PIGraphicAtt const & gatt,
+			      string const& s_up, string const& s_dn, PIGraphicAtt const & attss,
+			      unsigned long tpd=0, bool fgsc=false)
+    { return( ElAdd(x, y, s.c_str(), gatt, s_up.c_str(), s_dn.c_str(), &attss, tpd, fgsc) ); } 
+  
+
+  // ---- Ajout de rectangles 
+  inline int    ElAddRect(double x, double y, double dx, double dy, bool fgsc=false)
+    { PIGraphicAtt gatt; return( ElAdd(PIDEL_Rect, x, y, dx, dy, NULL, gatt, 0, fgsc) ); }  
+  inline int    ElAddRect(double x, double y, double dx, double dy, 
+			  PIGraphicAtt const & gatt, bool fgsc=false)
+    { return( ElAdd(PIDEL_Rect, x, y, dx, dy, NULL, gatt, 0, fgsc) ); }  
+
+  inline int    ElAddFRect(double x, double y, double dx, double dy, bool fgsc=false)
+    { PIGraphicAtt gatt; return( ElAdd(PIDEL_FRect, x, y, dx, dy, NULL, gatt, 0, fgsc) ); }  
+  inline int    ElAddFRect(double x, double y, double dx, double dy, 
+			   PIGraphicAtt const & gatt, bool fgsc=false)
+    { return( ElAdd(PIDEL_FRect, x, y, dx, dy, NULL, gatt, 0, fgsc) ); }  
+
+  // ---- Ajout de cercles
+  inline int    ElAddCirc(double x, double y, double r, bool fgsc=false)
+    { PIGraphicAtt gatt; 
+      return( ElAdd(PIDEL_Circ, x, y, 0., 360., NULL, gatt, 0, fgsc, r) ); }  
+  inline int    ElAddCirc(double x, double y, double r, 
+			  PIGraphicAtt const & gatt, bool fgsc=false)
+    { return( ElAdd(PIDEL_Circ, x, y, 0., 360., NULL, gatt, 0, fgsc, r) ); }  
+
+  inline int    ElAddFCirc(double x, double y, double r, bool fgsc=false)
+    { PIGraphicAtt gatt; 
+      return( ElAdd(PIDEL_FCirc, x, y, 0., 360., NULL, gatt, 0, fgsc, r) ); }  
+  inline int    ElAddFCirc(double x, double y, double r, 
+			   PIGraphicAtt const & gatt, bool fgsc=false)
+    { return( ElAdd(PIDEL_FCirc, x, y, 0., 360., NULL, gatt, 0, fgsc, r) ); }  
+
+  // ---- Ajout d' arcs specifies par deux angles
+  inline int    ElAddArc(double x, double y, double r, 
+			 double a, double da, bool fgsc=false)
+    { PIGraphicAtt gatt; 
+      return( ElAdd(PIDEL_Arc, x, y, a, da, NULL, gatt, 0, fgsc, r) ); }  
+  inline int    ElAddArc(double x, double y, double r, double a, double da, 
+			 PIGraphicAtt const & gatt, bool fgsc=false)
+    { return( ElAdd(PIDEL_Arc, x, y, a, da, NULL, gatt, 0, fgsc, r) ); }  
+
+  inline int    ElAddFArc(double x, double y, double r, 
+			  double a, double da, bool fgsc=false)
+    { PIGraphicAtt gatt; 
+      return( ElAdd(PIDEL_FArc, x, y, a, da, NULL, gatt, 0, fgsc, r) ); }  
+  inline int    ElAddFArc(double x, double y, double r, double a, double da, 
+			  PIGraphicAtt const & gatt, bool fgsc=false)
+    { return( ElAdd(PIDEL_FArc, x, y, a, da, NULL, gatt, 0, fgsc, r) ); }  
+
+  // ---- Ajout d' arcs specifies par 3 points
+  inline int    ElAddArc(double x1, double y1, double x2, double y2,
+			 double x3, double y3, bool fgsc=false)
+    { PIGraphicAtt gatt; double x[3], y[3]; 
+      x[0] = x1; x[1] = x2; x[2] = x3; 
+      y[0] = y1; y[1] = y2; y[2] = y3; 
+      return( ElAdd(PIDEL_Arc3P, x, y, 3, gatt, fgsc) ); }  
+
+  inline int    ElAddArc(double x1, double y1, double x2, double y2,
+			 double x3, double y3, PIGraphicAtt const & gatt, bool fgsc=false)
+    { double x[3], y[3]; 
+      x[0] = x1; x[1] = x2; x[2] = x3; 
+      y[0] = y1; y[1] = y2; y[2] = y3; 
+      return( ElAdd(PIDEL_Arc3P, x, y, 3, gatt, fgsc) ); }  
+
+  inline int    ElAddFArc(double x1, double y1, double x2, double y2,
+			  double x3, double y3, bool fgsc=false)
+    { PIGraphicAtt gatt; double x[3], y[3]; 
+      x[0] = x1; x[1] = x2; x[2] = x3; 
+      y[0] = y1; y[1] = y2; y[2] = y3; 
+      return( ElAdd(PIDEL_FArc3P, x, y, 3, gatt, fgsc) ); }  
+
+  inline int    ElAddFArc(double x1, double y1, double x2, double y2,
+			  double x3, double y3, PIGraphicAtt const & gatt, bool fgsc=false)
+    { double x[3], y[3]; 
+      x[0] = x1; x[1] = x2; x[2] = x3; 
+      y[0] = y1; y[1] = y2; y[2] = y3; 
+      return( ElAdd(PIDEL_FArc3P, x, y, 3, gatt, fgsc) ); }  
+
+  // ---- Ajout de polygones 
+  inline int    ElAddPoly(vector<double>& x, vector<double>& y, bool fgsc=false)
+    { PIGraphicAtt gatt; return( ElAdd(PIDEL_Poly, x, y, gatt, fgsc) ); }  
+  inline int    ElAddPoly(vector<double>& x, vector<double>& y, 
+			  PIGraphicAtt const & gatt, bool fgsc=false)
+    { return( ElAdd(PIDEL_Poly, x, y, gatt, fgsc) ); } 
+ 
+  inline int    ElAddFPoly(vector<double>& x, vector<double>& y, bool fgsc=false)
+    { PIGraphicAtt gatt; return( ElAdd(PIDEL_FPoly, x, y, gatt, fgsc) ); }  
+  inline int    ElAddFPoly(vector<double>& x, vector<double>& y, 
+			   PIGraphicAtt const & gatt, bool fgsc=false)
+
+    { return( ElAdd(PIDEL_FPoly, x, y, gatt, fgsc) ); }  
+
+  void               ElDel(int id);
+  inline void        ElDelLast() { ElDel(mEn); }
+  void               ElDelAll();
+
+protected:
+  int                ElAdd(int typ, double x, double y, double dx, double dy, 
+                           const char* s, PIGraphicAtt const & att,
+			   unsigned long txtposdir, bool fgsc, double r=0.);
+  int		     ElAdd(double x, double y, const char* s, PIGraphicAtt const & att, 
+			   const char* s_up, const char* s_dn, PIGraphicAtt const * gass, 
+			   unsigned long tpd, bool fgsc);
+
+  int                ElAdd(int typ, vector<double>& x, vector<double>& y, 
+			   PIGraphicAtt const & att, bool fgsc);
+  int                ElAdd(int typ, double* x, double* y, int n,
+			   PIGraphicAtt const & att, bool fgsc);
+
+  struct TxtEl {
+    string txt;
+    unsigned long txtpd;
+    string* txt_up;
+    string* txt_dn;
+    PIGraphicAtt* attss;
+  };
+
+  struct DrwEl{
+    int eid, etyp;
+    double ex,ey,er;
+    double edx,edy;
+    PIGraphicAtt gatt;
+    TxtEl* es;
+    PIGrCoord* xpol;
+    PIGrCoord* ypol;
+    int npol;
+    bool scc;  // true -> normalized coordinates ( 0..1 )
+  };
+
+  typedef list<DrwEl> DrwElList;
+  DrwElList mElist;
+  int mEn;
+  
+};
+
+/*  ------------------- Classe PIElDrawer ------------------------  */
+// Classe de Drawer capable de gerer une liste d'elements a tracer
+
+class PIElDrawer : public PIDrawer 
+{
+public:
+                     PIElDrawer(bool fgclip=true);
+  virtual           ~PIElDrawer();
+
+//   Methode de decodage des options
+  virtual int        DecodeOptionString(vector<string> & opt, bool rmdecopt=true);
+
+  virtual void       DrawAxes(PIGraphicUC* g); // Trace d'axes avec label axe X,Y
+
+  virtual void       Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax); 
+
+  inline PIElDrwMgr& ElDrwMgr()    { return eltsMgr; }
+
+  inline void        SetTitles(string tt, string tb)   { titleT = tt;  titleB = tb; }
+  inline void        SetTitles(string tt, string tb, PIGraphicAtt const& att) 
+                        { titleT = tt;  titleB = tb; titleAtt = att; }
+  inline void        ShowTitles(bool fg=true) { showTitles = fg; }
+
+  inline void        SetAxesLabels(string xl, string yl) { xLabel = xl;  yLabel = yl; }
+  inline void        SetAxesLabels(string xl, string yl, PIGraphicAtt const& att) 
+                        { xLabel = xl;  yLabel = yl; labelAtt = att; }
+  inline void        ShowAxesLabels(bool fg=true) { showAxesLabels = fg; }
+
+// -- Pour compatibilite avec l'interface precedente , Reza 08/2002 
+  inline void        ElDel(int id) { eltsMgr.ElDel(id); }
+  inline void        ElDelLast()   { eltsMgr.ElDelLast(); }
+  inline void        ElDelAll()    { eltsMgr.ElDelAll(); }
+  
+  inline int	     ElAddText(double x, double y, const char* s)
+                                   { return eltsMgr.ElAddText(x, y, s); }
+
+protected:
+  PIElDrwMgr eltsMgr;
+  string titleT, titleB;       // Titre Haut - Bas
+  PIGraphicAtt titleAtt;       // Attributs graphiques de trace de titre
+  bool showTitles;             // Affichage des titres si true
+  string xLabel, yLabel;       // Label x, label y
+  PIGraphicAtt labelAtt;       // Attributs graphiques de trace de label d'axes
+  bool showAxesLabels;         // Affichage des labels d'axes si true
+  bool fgClip;                 // Si true, appel a PIGraphicUC::Clip() ds Draw()
+};
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pierrdisp.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pierrdisp.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pierrdisp.cc	(revision 2309)
@@ -0,0 +1,105 @@
+#include "pierrdisp.h"
+#include "utils.h"
+
+
+PIErrorBox::PIErrorBox(PIContainerGen* par, int sx, int sy,
+	     int px, int py)
+: PIBaseWdg(par, "Error Message", sx, sy, px, py)
+{
+  currErrText = "";
+  state = 0;
+}
+
+PIErrorBox::~PIErrorBox()
+{
+}
+
+void
+PIErrorBox::Draw()
+{
+  if (currErrText == "") {
+    SelBackground();
+    EraseWindow();
+  } else {
+    switch(state) {
+    case 0:
+      EraseWindow();
+      SelForeground(PI_Red);
+      DrawFBox(0,0,1000,1000);
+      SelForeground(PI_Black);
+      break;
+    default:
+      SelBackground();
+      SelForeground();
+    }
+    SelFont(PI_BigSizeFont, PI_BoldFont);
+    DrawString(20,30,(char*)currErrText.c_str());
+  }
+}
+
+void
+PIErrorBox::Cycle()
+{
+  state = (state + 1) % 2;
+}
+
+
+
+
+PIErrorDisplay::PIErrorDisplay(PIContainerGen* par, int sx, int sy,
+			       int px, int py)
+: PIContainer(par, "Error Display", sx, sy, px, py), PIPeriodX(1)
+{
+  currErrId = 0;
+
+  errorBox  = new PIErrorBox(this, 150, 80, 0, 0);
+  ackButton = new PIButton(this, "OK", 5000, 40, 20, 155, 20);
+  updButton = new PIButton(this, "Upd", 5001, 40, 20, 155, 50);
+  Start();
+}
+
+PIErrorDisplay::~PIErrorDisplay()
+{
+  delete updButton;
+  delete ackButton;
+  delete errorBox;
+}
+
+void
+PIErrorDisplay::Process(PIMessage msg, PIMsgHandler *sender, void *data)
+{
+msg = UserMsg(msg);
+  switch(msg) {
+  case 5000:
+    // On valide
+    if (currErrId) 
+      AcqAckError(currErrId);
+    UpdData();
+    break;
+  case 5001:
+    UpdData();
+    break;
+    
+  default:
+    PIContainer::Process(msg, sender, data);
+  }
+}
+
+void
+PIErrorDisplay::UpdData()
+{
+  currErrId = 0;
+  char tache[80];
+  char msg[200];
+  int code;
+  int severite;
+  int rc = AcqGetNextError(&currErrId, tache, &code, &severite, msg);
+  if (rc)
+    errorBox->SetText("");
+  else
+    errorBox->SetText(string(tache) + " : (" + itos(code) + "/" +
+		     itos(severite) +") " + msg);
+  errorBox->Draw();
+}
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/pierrdisp.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pierrdisp.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pierrdisp.h	(revision 2309)
@@ -0,0 +1,48 @@
+// This may look like C code, but it is really -*- C++ -*-
+#ifndef PIERRDISP_H_SEEN
+#define PIERRDISP_H_SEEN
+
+#include "pisysdep.h"
+#include PIBWDG_H
+#include PISTDWDG_H
+#include PICONT_H
+#include PIPERIOD_H
+
+#include "errorhandlerc.h"
+
+class PIErrorBox : public PIBaseWdg {
+public:
+  PIErrorBox(PIContainerGen* par, int sx=100, int sy = 50,
+	     int px=0, int py=0);
+  ~PIErrorBox();
+
+  void Draw();
+  
+  void SetText(string const& txt) {currErrText = txt;}
+  void Cycle();
+
+protected:
+  string currErrText;
+  int           state;     // Cycle decoratif en couleurs violentes...  
+};
+
+class PIErrorDisplay : public PIContainer, public PIPeriodic {
+public:
+  
+  PIErrorDisplay(PIContainerGen* par, int sx=150, int sy=50,
+		 int px=0, int py=0);
+  virtual      ~PIErrorDisplay();
+  
+  void          UpdData();
+  void          Process(PIMessage msg, PIMsgHandler *sender, void *data);
+  void          DoPeriodic() {UpdData();}
+protected:
+  int           currErrId;
+
+  PIErrorBox*   errorBox;
+  PIButton*     ackButton;
+  PIButton*     updButton;   // TEMPORAIRE
+};
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pievthandler.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pievthandler.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pievthandler.cc	(revision 2309)
@@ -0,0 +1,141 @@
+// Module PI : Peida Interactive      PIEventHandler
+// Classe Gestionnaire d'evenements (Ecran/Clavier/Souris)
+//                                    R.Ansari  12/98 
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "pievthandler.h"
+
+//++
+// Class	PIEventHandler
+// Lib		PI
+// include	pievthandler.h
+//
+//	Classe fournissant les services nécessaires à la création de
+//	gestionnaire d'événements écran-clavier-souris.
+//--
+//++
+// Links	Parents
+// PIMsgHandler
+//--
+//++
+// Links	Voir aussi
+// PIWdg
+//--
+//++
+// Titre	Constructeur, méthodes
+//--
+//++
+// PIEventHandler(PIMsgHandler* par=NULL, PIMessage msg = 0)
+//	Constructeur. "par" est le gestionnaire de message parent, et
+//	"msg" le message associé.
+//
+// void	  SetMsg(PIMessage msg = 0)
+//	Modification du message associé.
+// PIMessage  Msg() 
+//	Renvoie le message associé.
+//--
+
+
+
+/* --Methode-- */
+PIEventHandler::PIEventHandler(PIMsgHandler* par, PIMessage msg)
+	: PIMsgHandler(par)
+{
+SetMsg(msg);
+curwdg = NULL;
+event = PIEvent_None;
+posx = posy = 0;
+key = 0;
+keymod = PIKM_Blank;
+evttime = 0;
+}
+
+/* --Methode-- */
+PIEventHandler::~PIEventHandler()
+{
+}
+
+//++
+// Titre	Traitement des événements
+//--
+//++
+// void Draw(PIGraphic* g, int x0, int y0, int dx, int dy)
+//	Méthode spécialisée appelée pour retracer le contenu 
+//	d'une partie de l'objet "PIWdg" auquel est attaché l'objet
+//	"PIEventHandler". "PIGraphic* g" fournit les services de 
+//	tracé graphique et "(x0, y0), "dx * dy" définissent le 
+//	rectangle à retracer. L'implementation par défaut ne 
+//	fait rien.
+//
+// void ProcessEvent()
+//	Cette méthode est appelée pour le traitement de tous 
+//	les autres types d'événements. L'implementation par défaut 
+//	ne fait rien. 
+//--
+
+
+/* --Methode-- */
+void PIEventHandler::Draw(PIGraphic*, int, int, int, int)
+{
+return;
+}
+
+/* --Methode-- */
+void PIEventHandler::ProcessEvent()
+{
+return;
+}
+
+/* --Methode-- */
+void PIEventHandler::SetCurrentWdg(PIWdg* wdg)
+{
+curwdg = wdg;
+}
+
+
+//++
+// Titre	Description de l'événement
+//--
+//++
+// PIWdg*  CurrentWdg()
+//	L'objet "PIWdg" source de l'événement.
+// PIEventMask EventType()
+//	Type de l'événement :
+//|	PIEvent_Draw 
+//|	PIEvent_Resize , PIEvent_Enter , PIEvent_Leave
+//|	PIEvent_ButxPress , PIEvent_ButxRelease  (x=1,2,3)
+//|	PIEvent_PtrMove , PIEvent_PtrxMove (x=1,2,3)
+//|	PIEvent_Keyboard
+//
+// int GetPosX()
+//	Position X de la souris
+// int GetPosY()
+//	Position Y de la souris
+// int GetKey()
+//	Code touche du clavier. Code ASCII des caractères ordinaires, ou l'une des constantes:
+//|	PIK_Return , PIK_Enter
+//|	PIK_BackSpace , PIK_Delete
+//|	PIK_Tab , PIK_Escape
+//|	PIK_Up , PIK_Down
+//|	PIK_Right , PIK_Left
+//|	PIK_Previous , PIK_Next
+//
+// PIKeyModifier GetKeyMod()
+//	Code d'une des touches <Shift>, <Alt>, <Cntl> si appuyée en même temps.
+//|	PIKM_Blank , PIKM_Shift , PIKM_Alt , PIKM_Cntl
+//
+// unsigned long GetEventTime()
+//	Temps de l'action en millisecondes.
+//--
+
+/* --Methode-- */
+void PIEventHandler::SetEventInfo(PIEventMask evt, int px, int py, 
+                                  int k, PIKeyModifier km, unsigned long tm)
+{
+event = evt;
+posx = px; posy = py;
+key = k;
+keymod = km;
+evttime = tm;
+}
+
Index: /tags/V_Dec2002/SophyaPI/PI/pievthandler.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pievthandler.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pievthandler.h	(revision 2309)
@@ -0,0 +1,85 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive      PIEventHandler
+// Classe Gestionnaire d'evenements (Ecran/Clavier/Souris) 
+//                                    R.Ansari  12/98 
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PIEVTHANDLER_H_SEEN
+#define PIEVTHANDLER_H_SEEN
+
+#include "pisysdep.h"
+#include "pimsghandler.h"
+#include PIWDG_H
+#include PIGRAPHIC_H
+
+
+// ....  KeyModifier (<Shift>, <Control> , <Alt>) and special key values ....
+enum PIKeyModifier { PIKM_Blank = 0, PIKM_Shift = 1, PIKM_Alt = 2, PIKM_Cntl = 4 } ; 
+
+enum PIKeyValues { PIK_Return = 0xFF0D, PIK_Enter = 0xFF8D , 
+                   PIK_BackSpace = 0xFF08, PIK_Delete = 0xFFFF,
+                   PIK_Tab = 0xFF09, PIK_Escape = 0xFF1B, 
+                   PIK_Up = 0xFF52, PIK_Down = 0xFF54, 
+                   PIK_Right = 0xFF53, PIK_Left = 0xFF51,
+                   PIK_Previous = 0xFF55, PIK_Next = 0xFF56  } ; 
+
+// .......... Event Mask values ..........
+enum PIEventMask {
+     PIEvent_None	  =  0,                  //
+     PIEvent_Draw         =  1 << 0,             // ReDraw window
+     PIEvent_Resize       =  1 << 1,             // window resized
+     PIEvent_Enter        =  1 << 2,             // Pointer entered window
+     PIEvent_Leave        =  1 << 3,             // Pointer leaved window
+     PIEvent_But1Press    =  1 << 4,             // Button-1 Press
+     PIEvent_But1Release  =  1 << 5,             // Button-1 Release
+     PIEvent_But2Press    =  1 << 6,             // Button-2 Press
+     PIEvent_But2Release  =  1 << 7,             // Button-2 Release
+     PIEvent_But3Press    =  1 << 8,             // Button-3 Press
+     PIEvent_But3Release  =  1 << 9,             // Button-3 Release
+     PIEvent_PtrMove      =  1 << 14,            // Pointer moved
+     PIEvent_Ptr1Move     =  1 << 15,            // Pointer moved with button-1
+     PIEvent_Ptr2Move     =  1 << 16,            // Pointer moved with button-2
+     PIEvent_Ptr3Move     =  1 << 17,            // Pointer moved with button-3
+     PIEvent_Keyboard     =  1 << 20             // key-pressed Keyboard
+} ;
+
+
+// -----------------  Class PIEventHandler  -----------------------
+class PIEventHandler : public PIMsgHandler
+{
+public:
+			PIEventHandler(PIMsgHandler* par=NULL, PIMessage msg = 0);
+			~PIEventHandler();
+
+  inline  void		SetMsg(PIMessage msg = 0) { myMsg=msg; }
+  inline  PIMessage	Msg() { return (myMsg); }
+
+  virtual void		Draw(PIGraphic* g, int x0, int y0, int dx, int dy);
+  virtual void		ProcessEvent();
+
+  virtual  void		SetCurrentWdg(PIWdg* wdg);
+  inline  PIWdg*	CurrentWdg() { return(curwdg); }
+
+  virtual void		SetEventInfo(PIEventMask evt, int px, int py, 
+                                     int k, PIKeyModifier km, unsigned long tm);
+  inline  PIEventMask	EventType() { return(event); }
+  inline  int		GetPosX() { return(posx); }  
+  inline  int		GetPosY() { return(posy); }  
+  inline  int		GetKey() { return(key); }
+  inline  PIKeyModifier GetKeyMod() { return(keymod); }
+  inline  unsigned long GetEventTime() { return(evttime); }
+
+protected:
+  PIMessage	myMsg;	       // associated user message
+
+  PIWdg*	curwdg;        // Current PIWdg, where event originated
+  PIEventMask	event;	       // event type
+  int		posx, posy;    // Pointer Position  
+  int		key;	       // Pressed key-code 
+  PIKeyModifier keymod;	       // Pressed key-modifier (shift, Cntl, ...)
+  unsigned long evttime;       // Event-time in ms  
+};
+
+
+
+#endif  
Index: /tags/V_Dec2002/SophyaPI/PI/pifilechogen.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pifilechogen.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pifilechogen.cc	(revision 2309)
@@ -0,0 +1,73 @@
+// Module PI : Peida Interactive     PIFileChooser
+// Selecteur de fichier                    96-97
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "pifilechogen.h"
+
+
+/************* PIFileChooserGen ************/
+
+//++
+// Class	PIFileChooser
+// Lib		PI
+// include	pifilechogen.h
+//
+//	Composant graphique de type sélecteur de fichier, permettant de choisir 
+//	un nom de fichier et de naviguer dans les répertoires.
+//	"PIFileChooserGen" définit l'interface (classe virtuelle pure). Les objets 
+//	instanciés doivent être de la classe "PIFileChooser" déclarée dans le fichier
+//	entête "PIFILECHO_H". Le message associé à l'objet est envoyé completé 
+//	avec "PIMsg_OK" si un nom de fichier a été choisi. la variable "data"
+//	est alors un pointeur sur une chaîne de caractères ("char *"), 
+//	contenant le nom complet du fichier. Si aucun fichier n'a été 
+//	sélectionné, le message de l'objet est completé avec "PIMsg_Cancel" et 
+//	le "data" contient le pointeur "NULL".
+//--
+//++
+// Links	Parents
+// PIWdg
+//--
+//++
+// Titre	Constructeur et méthodes
+//--
+//++
+// PIFileChooser(PIMsgHandler* par, const char* nom, PIMessage msg)
+//	Création d'un objet sélecteur de fichier, avec le message "msg".
+// void  Show()
+//	Affiche la fenêtre de sélection des fichiers
+// void  AcceptNewFile(bool acc)
+//	Active ("acc=true") ou désactive la possibilité de spécifier
+//	un nouveau fichier.
+// void  SetPath(string const&)
+//	Définit le chemin d'accès (répertoire) choisi par défaut
+// void  SetFileName(string const&) 
+//	Nom de fichier sélectionné par défaut
+// string  GetPath()
+//	Retourne le chemin d'accès. NON IMPLEMENTE EN X/MOTIF (06/98)
+// string  GetFileName()
+//	Retourne le nom complet du fichier sélectionné. 
+//--
+
+
+PIFileChooserGen::PIFileChooserGen(PIMsgHandler* par, const char* nom, PIMessage msg)
+: PIWdg(NULL, nom)
+{
+SetMsg(msg);
+SetMsgParent(par);
+}
+
+PIFileChooserGen::~PIFileChooserGen()
+{}
+
+void PIFileChooserGen::Show()
+{
+return;
+}
+
+
+void PIFileChooserGen::AcceptNewFile(bool)
+{
+return;
+}
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/pifilechogen.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pifilechogen.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pifilechogen.h	(revision 2309)
@@ -0,0 +1,34 @@
+#ifndef PIFILCHOGEN_H_SEEN
+#define PIFILCHOGEN_H_SEEN
+
+#include "pisysdep.h"
+#include PIWDG_H
+
+class PIFileChooserGen : public PIWdg {
+public:
+  enum {ClassId = 2100};
+
+                     PIFileChooserGen(PIMsgHandler* par, const char* nom, PIMessage msg);
+  virtual            ~PIFileChooserGen();
+
+  virtual void       Show();
+
+  virtual void       AcceptNewFile(bool acc);
+  virtual void       SetPath(string const&) = 0;
+  virtual void       SetFileName(string const&) = 0;
+
+  virtual string     GetPath() = 0;
+  virtual string     GetFileName() = 0;
+
+  virtual long       kind() {return ClassId; }
+
+protected:
+
+};
+
+
+#endif
+
+
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/pifilechomac.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pifilechomac.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pifilechomac.cc	(revision 2309)
@@ -0,0 +1,123 @@
+#include "pifilechomac.h"
+
+string PathNameFromDirID(long dirID, short vRefNum);
+
+string PIGetFileName(string dir);
+string PIGetExistingFileName(string dir);
+
+string PIGetFileName(string dir)
+{
+  StandardFileReply reply;
+  
+  
+  string fName;
+  int i = dir.rfind(':');
+  if (i == string::npos)
+    fName = dir;
+  else if (i == dir.length())
+    fName = "";
+  else
+    fName = dir.substr(i+1);
+    
+  LStr255 defaultName(fName.c_str());
+  
+  StandardPutFile("\pSave as:",defaultName,&reply);
+  
+  if (!reply.sfGood) return "";
+  
+  string directory = PathNameFromDirID(reply.sfFile.parID,reply.sfFile.vRefNum);
+  p2cstr(reply.sfFile.name);
+  
+//  return directory + '/' + (char*)reply.sfFile.name;
+  return directory + ':' + (char*)reply.sfFile.name;
+}
+
+string PIGetExistingFileName(string /*dir*/)
+{
+  StandardFileReply reply;
+  SFTypeList typeList;
+  
+  StandardGetFile(NULL,-1,typeList,&reply);
+  
+  if (!reply.sfGood) return "";
+  
+  string directory = PathNameFromDirID(reply.sfFile.parID,reply.sfFile.vRefNum);
+  p2cstr(reply.sfFile.name);
+  
+//  return directory + '/' + (char*)reply.sfFile.name;
+  return directory + ':' + (char*)reply.sfFile.name;
+}
+
+
+string PathNameFromDirID(long dirID, short vRefNum)
+{
+	DirInfo 	block;
+	Str255		directoryName;
+	OSErr		err;
+
+	string fullPathName = "";
+
+	block.ioDrParID = dirID;
+	block.ioNamePtr = directoryName;
+	do {
+			block.ioVRefNum = vRefNum;
+			block.ioFDirIndex = -1;
+			block.ioDrDirID = block.ioDrParID;
+			err = PBGetCatInfoSync(CInfoPBPtr(&block));
+			p2cstr(directoryName);
+			if (fullPathName != "") fullPathName = ':' + fullPathName;
+			fullPathName =  ((char*)directoryName + fullPathName);
+//			fullPathName = '/' + ((char*)directoryName + fullPathName);
+	} while (block.ioDrDirID != 2);
+	return fullPathName;
+}
+
+
+PIFileChooserMac::PIFileChooserMac(PIMsgHandler* par, char* nom, PIMessage msg)
+: PIFileChooserGen(par, nom, msg)
+{
+  mAccNew = false;
+  mFileName = "";
+}
+
+PIFileChooserMac::~PIFileChooserMac()
+{}
+
+void
+PIFileChooserMac::Show()
+{
+  if (mAccNew)
+    mFileName = PIGetFileName("");
+  else
+    mFileName = PIGetExistingFileName("");
+
+// Envoyer un message....
+  if (mFileName == "")
+    Send(Msg(), PIMsg_Cancel, NULL);
+  else
+    Send(Msg(), PIMsg_OK, (void *) (GetFileName().c_str()));
+}
+
+void
+PIFileChooserMac::AcceptNewFile(bool acc)
+{
+  mAccNew = acc;
+}
+
+void
+PIFileChooserMac::SetPath(string const& /*path*/) {}
+void
+PIFileChooserMac::SetFileName(string const& /*fname*/) {}
+
+string
+PIFileChooserMac::GetPath()
+{
+  return "";
+}
+
+string
+PIFileChooserMac::GetFileName()
+{
+  return mFileName;
+}
+
Index: /tags/V_Dec2002/SophyaPI/PI/pifilechomac.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pifilechomac.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pifilechomac.h	(revision 2309)
@@ -0,0 +1,33 @@
+#ifndef PIFILECHOMAC_H_SEEN
+#define PIFILECHOMAC_H_SEEN
+
+#include <string>
+#include "pisysdep.h"
+#include "pifilechogen.h"
+
+class PIFileChooserMac : public PIFileChooserGen {
+public:
+
+                   PIFileChooserMac(PIMsgHandler* par, char* nom, PIMessage msg);
+  virtual          ~PIFileChooserMac();
+
+  virtual void     Show();
+
+  virtual void     AcceptNewFile(bool acc);
+  virtual void     SetPath(string const& path);
+  virtual void     SetFileName(string const& fname);
+
+  virtual string   GetPath();
+  virtual string   GetFileName();
+
+protected:
+  bool             mAccNew;
+  string           mFileName;
+};
+
+typedef PIFileChooserMac     PIFileChooser ;
+
+#define FILESEP ':'
+
+#endif
+
Index: /tags/V_Dec2002/SophyaPI/PI/pifilechox.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pifilechox.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pifilechox.cc	(revision 2309)
@@ -0,0 +1,173 @@
+#include<stdio.h>
+#include<string.h>
+
+#include "pisysdep.h"
+
+#include "piapplx.h"
+#include "pifilechox.h"
+
+
+/************* PIFileChooserX ************/
+#include <X11/Shell.h>
+#include <Xm/FileSB.h>
+
+// Pour ces sal... de XmString  (ds piwdgx.cc)
+int CStrFrXmStr(XmString xms, char* buff, int nmx);
+
+// Fonctions privees (CallBack)
+//static void filesel_okact(Widget w, XtPointer *usd, XtPointer *calld);
+static void filesel_cancelact(Widget w, XtPointer *usd, XtPointer *calld);
+
+/* Nouvelle-Fonction */
+void  filesel_okact(Widget /*w*/, XtPointer *usd, 
+                    XmFileSelectionBoxCallbackStruct *calld)
+{
+PIFileChooserX *pif;
+pif = (PIFileChooserX *) usd ;
+pif->mSt = 1;
+pif->MWin()->UnManage();
+//pif->Send(pif->Msg(), (void *) (pif->GetFileName().c_str()));
+CStrFrXmStr(calld->value, pif->mFName, 512); 
+pif->Send( pif->Msg(), PIMsg_OK, (void *) pif->mFName);
+return;
+}
+
+/* Nouvelle-Fonction */
+void  filesel_cancelact(Widget /*w*/, XtPointer *usd, XtPointer */*calld*/)
+{
+PIFileChooserX *pif;
+pif = (PIFileChooserX *) usd ;
+pif->mSt = 0;
+pif->mFName[0] = '\0';
+pif->MWin()->UnManage();
+pif->Send(pif->Msg(), PIMsg_Cancel, NULL);
+return;
+}
+
+static int PIFC_SzX, PIFC_SzY;
+/* --Methode-- */
+PIFileChooserX::PIFileChooserX(PIMsgHandler* par, const char* nom, PIMessage msg)
+: PIFileChooserGen(par, nom, msg)
+{
+SysDWdg wdg;
+
+mWin = NULL;
+
+int sx, sy;
+PIApplicationPrefCompSize(sx, sy);
+PIFC_SzX = sx*6;  PIFC_SzY = sy*10;
+mWin = new PIWdgX(NULL, nom, PIFC_SzX, PIFC_SzY, 200, 200);
+mWin->CreateXtWdg(nom, topLevelShellWidgetClass, NULL, PIFC_SzX, PIFC_SzY, 200, 200);
+
+mSt = 0;
+mFName[0] = mFName[511] = '\0';
+
+CreateXtWdg(nom, xmFileSelectionBoxWidgetClass, mWin->XtWdg(), sx, sy, 0, 0);
+XtAddCallback(XtWdg(), XmNokCallback, 
+              (XtCallbackProc)filesel_okact, (XtPointer)this);
+XtAddCallback(XtWdg(), XmNcancelCallback, 
+              (XtCallbackProc)filesel_cancelact, (XtPointer)this);
+// Pour avoir une version simplifiee 
+/* wdg = XmFileSelectionBoxGetChild(XtWdg(),XmDIALOG_DIR_LIST);
+XtUnmanageChild(wdg);
+wdg = XmFileSelectionBoxGetChild(XtWdg(),XmDIALOG_DIR_LIST_LABEL);
+XtUnmanageChild(wdg);
+*/
+wdg = XmFileSelectionBoxGetChild(XtWdg(),XmDIALOG_HELP_BUTTON);
+XtUnmanageChild(wdg);
+
+fnl = XmFileSelectionBoxGetChild(XtWdg(),XmDIALOG_SELECTION_LABEL);
+fnw = XmFileSelectionBoxGetChild(XtWdg(),XmDIALOG_TEXT);
+
+Arg warg[2];
+XtSetArg(warg[0], XmNfileTypeMask, XmFILE_REGULAR);
+XtSetValues(XtWdg(), warg, 1);
+
+AcceptNewFile(false);
+Manage();
+}
+
+/* --Methode-- */
+PIFileChooserX::~PIFileChooserX()
+{
+delete mWin;
+}
+
+/* --Methode-- */
+void PIFileChooserX::AcceptNewFile(bool acc)
+{
+if (acc) 
+  {
+  mWin->SetSize( PIFC_SzX, PIFC_SzY*1.25);
+  XtManageChild(fnl);  XtManageChild(fnw); 
+  }
+else 
+  { 
+  mWin->SetSize( PIFC_SzX, PIFC_SzY*1.1);
+  XtUnmanageChild(fnl); XtUnmanageChild(fnw); 
+  }
+}
+
+/* --Methode-- */
+void PIFileChooserX::Show()
+{
+mWin->Manage();
+}
+
+/* --Methode-- */
+void PIFileChooserX::SetPath(string const& path)
+{
+XmString xmstr;
+xmstr = XmStringLtoRCreate((char *)path.c_str(), XmSTRING_DEFAULT_CHARSET);
+Arg warg[2];
+XtSetArg(warg[0], XmNdirectory, xmstr); 
+XtSetValues(XtWdg(), warg, 1);
+XmStringFree(xmstr);
+return;
+}
+
+/* --Methode-- */
+void PIFileChooserX::SetFileName(string const& fname)
+{
+XmString xmstr;
+xmstr = XmStringLtoRCreate((char *)fname.c_str(), XmSTRING_DEFAULT_CHARSET);
+Arg warg[2];
+XtSetArg(warg[0], XmNtextString, xmstr); 
+XtSetValues(XtWdg(), warg, 1);
+XmStringFree(xmstr);
+return;
+}
+
+
+/* --Methode-- */
+string PIFileChooserX::GetFileName()
+{
+
+if (mSt)
+  {
+  XmString xmstr;
+  Arg warg[2];
+
+  XtSetArg(warg[0], XmNtextString, &xmstr);
+  XtGetValues(XtWdg(), warg, 1);
+  CStrFrXmStr(xmstr, mFName, 512); 
+  string s(mFName);
+  XmStringFree(xmstr);
+  return(s);
+  }
+else
+  {
+  mFName[0] = '\0';
+  string s(mFName);
+  return(s);
+  }
+}
+
+/* --Methode-- */
+string PIFileChooserX::GetPath()
+{
+printf("PIFileChooserX::GetPath() not implemented ! \n");
+string s("");
+return(s);
+}
+
Index: /tags/V_Dec2002/SophyaPI/PI/pifilechox.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pifilechox.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pifilechox.h	(revision 2309)
@@ -0,0 +1,41 @@
+#ifndef PIFILCHOX_H_SEEN
+#define PIFILCHOX_H_SEEN
+
+#include "pisysdep.h"
+#include "pifilechogen.h"
+
+#include PIWIN_H
+
+class PIFileChooserX : public PIFileChooserGen {
+public:
+
+                   PIFileChooserX(PIMsgHandler* par, const char* nom, PIMessage msg);
+  virtual          ~PIFileChooserX();
+
+  virtual void     Show();
+
+  virtual void     AcceptNewFile(bool acc);
+  virtual void     SetPath(string const& path);
+  virtual void     SetFileName(string const& fname);
+
+  virtual string   GetPath();
+  virtual string   GetFileName();
+
+  inline PIWdg *   MWin() { return mWin; }
+
+//  Je les declare ici, en public, a cause des callback
+  int mSt;
+  char mFName[512];     
+
+protected:
+  PIWdg * mWin;
+  SysDWdg  fnw, fnl;
+};
+
+typedef PIFileChooserX     PIFileChooser ;
+
+#define FILESEP '/'
+
+
+#endif
+
Index: /tags/V_Dec2002/SophyaPI/PI/pifontgen.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pifontgen.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pifontgen.cc	(revision 2309)
@@ -0,0 +1,96 @@
+// Module PI : Peida Interactive     PIFontGen 
+// LAL (Orsay) / IN2P3-CNRS          R. Ansari  99
+
+// Classe generique de gestion de fonte - (Ne peut etre instancie)
+
+#include "pigraphgen.h"
+
+
+//++
+// Class	PIFont
+// Lib		PI
+// include	pifontgen.h
+//
+//	Classe de base fournissant les services de gestion de fontes
+//	La classe virtuelle pure PIFontGen définit l'interface. Les
+//	objets instanciés doivent être de la classe "PIFont"
+//	("PIFontX", "PIFontMac", ...)
+//
+//	Des constantes de type enum sont définies pour l'identification
+//	des types de fontes *PIFontName* , de l'attribut *PIFontAtt* 
+//	et de la taille *PIFontSize*.
+//	* PIFontName :
+//|	PI_DefaultFont , PI_CourierFont , PI_HelveticaFont, 
+//|	PI_TimesFont, PI_SymbolFont
+//	* PIFontSize :
+//|	PI_TinySizeFont, PI_SmallSizeFont , PI_NormalSizeFont , 
+//|	PI_LargeSizeFont, PI_VeryLargeSizeFont, PI_HugeSizeFont
+//	* PIFontAtt :	
+//|	PI_RomanFont , PI_BoldFont , PI_ItalicFont , PI_BoldItalicFont 
+//--
+//++
+// Links	Voir aussi
+// PIGraphic
+// PIGraphicAtt
+//--
+
+//++
+// Titre	Constructeurs
+//--
+//++
+// PIFont(PIFontName fn = PI_DefaultFont)
+//	Constructeur  pour fonte "fn". Constructeur par défaut.
+// PIFont(int npt, PIFontName fn = PI_DefaultFont, PIFontAtt fa = PI_RomanFont)
+//	Constructeur avec spécification de taille en points (pixels).
+// PIFont(PIFont const & fnt)
+//	Constructeur de copie
+// PIFont & operator = (PIFont const & fnt) 
+//	Opérateur égal (affectation).
+// bool operator == (PIFont const & fnt) 
+//	Opérateur test d'égalité.
+//--
+
+/* --Methode-- */
+PIFontGen::PIFontGen(PIFontName fn)
+{
+}
+
+/* --Methode-- */
+PIFontGen::PIFontGen(int npt, PIFontName fn, PIFontAtt fa)
+{
+}
+
+/* --Methode-- */
+PIFontGen::~PIFontGen()
+{
+}
+
+//++
+// Titre	Méthodes
+//--
+
+//++
+// void  SetFont(PIFontName fn)
+//	Changement de fonte.
+// void  SetFontAtt(PIFontAtt fa)
+//	Changement d'attribut de fonte
+// void  SetFontSz(PIFontSize fs)
+//	Changement de taille de fonte
+// void  SetFontSzPt(int npt)
+//	Changement de taille de fonte - Spécification de taille en points (pixels)
+// PIFontName  GetFontName()
+//	Retourne le type (nom) de fonte
+// PIFontAtt  GetFontAtt()
+//	Retourne l'attribut de fonte
+// PIFontSize  GetFontSz()
+//	Retourne la taille de fonte converti en enum PIFontSize
+// int  GetFontSzPt()
+//	Retourne la taille de fonte en points (pixels)
+// int  GetFontSeze()
+//	Retourne la taille de fonte en points (pixels) - idem GetFontSzPt()
+// int GetFontHeight(int& asc, int& desc) 
+//	Renvoie la hauteur des caractères, ainsi que la taille au dessus
+//	et en-dessous de la ligne de base ("asc , desc").
+// int GetStringWidth(char const* s)
+//	Renvoie la largeur occupé par le texte "char * s" en points/pixels
+//--
Index: /tags/V_Dec2002/SophyaPI/PI/pifontgen.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pifontgen.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pifontgen.h	(revision 2309)
@@ -0,0 +1,48 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive     PIFont 
+// LAL (Orsay) / IN2P3-CNRS              R. Ansari  99
+
+#ifndef PIFONTGEN_H_SEEN
+#define PIFONTGEN_H_SEEN
+
+#include "pisysdep.h"
+
+enum PIFontName { PI_DefaultFont = 0, PI_CourierFont = 1, PI_HelveticaFont = 2, 
+                  PI_TimesFont = 3, PI_SymbolFont = 4};
+
+enum PIFontSize { PI_NotDefFontSize = -1, 
+		  PI_TinySizeFont = 1,
+                  PI_SmallSizeFont = 2, PI_NormalSizeFont = 3, 
+                  PI_LargeSizeFont = 4, PI_VeryLargeSizeFont = 5,
+		  PI_HugeSizeFont = 6 };
+
+enum PIFontAtt { PI_NotDefFontAtt = -1,
+                 PI_RomanFont = 1, PI_BoldFont = 2, PI_ItalicFont = 4, 
+		 PI_BoldItalicFont = 6 };
+
+class PIFontGen
+{
+public:
+		PIFontGen(PIFontName fn = PI_DefaultFont);
+		PIFontGen(int npt, PIFontName fn = PI_DefaultFont, 
+                          PIFontAtt fa = PI_RomanFont);
+// PIFont doit avoir un constructeur de copie, et l'operateur egal de defini
+// ainsi que l'operateur test d'egalite
+  virtual	~PIFontGen();
+
+  virtual void		SetFont(PIFontName fn)		= 0;
+  virtual void		SetFontAtt(PIFontAtt fa)	= 0;
+  virtual void		SetFontSz(PIFontSize fs)	= 0;
+  virtual void		SetFontSzPt(int npt)		= 0;
+
+  virtual PIFontName    GetFontName()  const		= 0;
+  virtual PIFontAtt     GetFontAtt()  const		= 0;
+  virtual PIFontSize	GetFontSz() const	        = 0;
+  virtual int		GetFontSzPt() const		= 0;
+  inline  int		GetFontSize() const { return GetFontSzPt(); }
+
+  virtual int		GetFontHeight(int& asc, int& desc) const	= 0;
+  virtual int		GetStringWidth(char const* s) const		= 0;
+};
+
+#endif      // PIFONTGEN_H_SEEN
Index: /tags/V_Dec2002/SophyaPI/PI/pifontmac.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pifontmac.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pifontmac.cc	(revision 2309)
@@ -0,0 +1,185 @@
+// Module PI : Peida Interactive     PIFontMac
+// Gestion de fontes - Implementation Mac    
+// DAPNIA/SPP     E. Aubourg 1999
+
+#include <stdio.h>
+
+#include "pisysdep.h"
+#include "pifontmac.h"
+#include PIWDG_H
+
+#include "UDrawingState.h"
+
+/* --Methode-- */
+PIFontMac::PIFontMac(PIFontName fn)
+  : PIFontGen(fn)
+{
+  SelectFont(fn, PI_RomanFont, PI_NormalSizeFont);
+}
+
+/* --Methode-- */
+PIFontMac::PIFontMac(int npt, PIFontName fn, PIFontAtt fa)
+  : PIFontGen(npt, fn, fa)
+{
+  SelectFontPt(fn, fa, npt);
+}
+
+/* --Methode-- */
+PIFontMac::PIFontMac(PIFontMac const & fnt)
+  : PIFontGen(fnt.mFName)
+{
+  SelectFontPt(fnt.mFName, fnt.mFAtt, fnt.mFSize);
+}
+
+/* --Methode-- */
+PIFontMac::~PIFontMac()
+{
+}
+
+/* --Methode-- */
+PIFontMac & PIFontMac::operator = (PIFontMac const & fnt)
+{
+  SelectFontPt(fnt.mFName, fnt.mFAtt, fnt.mFSize);
+  return(*this);
+}
+
+/* --Methode-- */
+bool PIFontMac::operator == (PIFontMac const & fnt)
+{
+  if ((fnt.mFName == mFName) && (fnt.mFAtt == mFAtt) && (fnt.mFSize == mFSize)) 
+    return(true);
+  else 
+    return(false);
+}
+
+/* --Methode-- */
+void PIFontMac::SetFont(PIFontName fn)
+{
+  SelectFontPt(fn, mFAtt, mFSize);
+}
+
+/* --Methode-- */
+void PIFontMac::SetFontAtt(PIFontAtt fa)
+{
+  SelectFontPt(mFName, fa, mFSize);
+}
+
+/* --Methode-- */
+void PIFontMac::SetFontSz(PIFontSize fs)
+{
+  SelectFont(mFName, mFAtt, fs);
+}
+
+/* --Methode-- */
+void PIFontMac::SetFontSzPt(int npt)
+{
+  SelectFontPt(mFName, mFAtt, npt);
+}
+
+/* --Methode-- */
+PIFontName PIFontMac::GetFontName()
+{
+  return(mFName);
+}
+
+/* --Methode-- */
+PIFontAtt PIFontMac::GetFontAtt()
+{
+  return(mFAtt);
+}
+
+/* --Methode-- */
+int PIFontMac::GetFontSize()
+{
+  return(mFSize);
+}
+
+/* --Methode-- */
+void PIFontMac::Apply()
+{
+  ::TextFont(mFNum);
+  ::TextSize(mFSize);
+  ::TextFace(mFStyle);
+}
+
+/* --Methode-- */
+int PIFontMac::GetFontHeight(int& asc, int& desc)
+{
+  StTextState saver;
+  Apply();
+  ::FontInfo finfo;
+  GetFontInfo(&finfo);
+  asc = finfo.ascent;
+  desc = finfo.descent;
+  return(asc+desc);
+}
+
+/* --Methode-- */
+int PIFontMac::GetStringWidth(char const* s)
+{
+  StTextState saver;
+  Apply();
+  return(::TextWidth(s, 0, strlen(s)));
+}
+
+
+#define NMAXFONTSZ    7
+#define NMAXFONTATT   3
+#define NMAXFONTTYP   5
+
+/*  Variables globales pour la gestion des fontes  */
+static const int fontSizes[4] = {8,12,18,24};
+
+/* --Methode-- */
+void PIFontMac::SelectFont(PIFontName fn, PIFontAtt fa, PIFontSize fs)
+{
+  if (fs < 0 || fs >=4) fs = PI_NormalSizeFont;
+  int isz = fontSizes[fs];
+  SelectFontPt(fn, fa, isz);
+}
+
+/* --Methode-- */
+void PIFontMac::SelectFontPt(PIFontName fn, PIFontAtt fa, int npt)
+{
+  if ((fn == mFName) && (fa == mFAtt) && (npt == mFSize)) return;
+  mFName = fn;
+  mFAtt  = fa;
+  mFSize = npt;
+  
+  switch (fa) {
+    case PI_RomanFont :
+      mFStyle = 0;
+      break;
+    case PI_BoldFont :
+      mFStyle = bold;
+      break;
+    case PI_ItalicFont :
+      mFStyle = italic;
+      break;
+    default :
+      mFStyle = 0;
+      break;
+  }
+
+  switch (fn) {
+	  case PI_DefaultFont :
+	    mFNum = 0;
+	    break;
+	  case PI_CourierFont :
+	    GetFNum("\pCourier", &mFNum);
+	    break;
+	  case PI_HelveticaFont :
+	    GetFNum("\pHelvetica", &mFNum);
+	    break;
+	  case PI_TimesFont :
+	    GetFNum("\pTimes", &mFNum);
+	    break;
+	  case PI_SymbolFont :
+	    GetFNum("\pSymbol", &mFNum);
+	    break;
+	  default :
+	    mFNum = 0;
+	    break;
+  }
+}
+
Index: /tags/V_Dec2002/SophyaPI/PI/pifontmac.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pifontmac.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pifontmac.h	(revision 2309)
@@ -0,0 +1,51 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive     PIFontMac
+// DAPNIA/SPP          E. Aubourg  99
+
+#ifndef PIFONTMAC_H_SEEN
+#define PIFONTMAC_H_SEEN
+
+#include "pisysdep.h"
+#include "pifontgen.h"
+
+
+class PIFontMac : public PIFontGen 
+{
+public :
+		PIFontMac(PIFontName fn = PI_DefaultFont);
+		PIFontMac(int npt, PIFontName fn = PI_DefaultFont, 
+                        PIFontAtt fa = PI_RomanFont);
+		PIFontMac(PIFontMac const & fnt);
+  virtual	~PIFontMac();
+
+  virtual PIFontMac & operator = (PIFontMac const & fnt);
+  virtual bool operator == (PIFontMac const & fnt);
+
+  virtual void		SetFont(PIFontName fn);
+  virtual void		SetFontAtt(PIFontAtt fa);
+  virtual void		SetFontSz(PIFontSize fs);
+  virtual void		SetFontSzPt(int npt);
+
+  virtual PIFontName    GetFontName();
+  virtual PIFontAtt     GetFontAtt();
+  virtual int		GetFontSize();
+
+  virtual int		GetFontHeight(int& asc, int& desc);
+  virtual int		GetStringWidth(char const* s);
+  
+  virtual void      Apply();
+
+protected:
+  void           SelectFont(PIFontName fn, PIFontAtt fa, PIFontSize fs);
+  void           SelectFontPt(PIFontName fn, PIFontAtt fa, int npt);
+
+  PIFontName mFName;
+  PIFontAtt  mFAtt;
+  int        mFSize;
+  short      mFNum;
+  int        mFStyle;
+};
+
+typedef PIFontMac PIFont;
+
+#endif      // PIFONTMAC_H_SEEN
Index: /tags/V_Dec2002/SophyaPI/PI/pifontx.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pifontx.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pifontx.cc	(revision 2309)
@@ -0,0 +1,404 @@
+// Module PI : Peida Interactive     PIFontX
+// Gestion de fontes - Implementation X11    
+// LAL (Orsay) / IN2P3-CNRS     R. Ansari  97-99
+
+#include <stdio.h>
+
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+
+#include "pisysdep.h"
+#include "pifontx.h"
+#include PIWDG_H
+
+
+/* --Methode-- */
+PIFontX::PIFontX(PIFontName fn)
+  : PIFontGen(fn) , mFSize(-1) 
+{
+GlInit();
+SelectFont(fn, PI_RomanFont, PI_NormalSizeFont);
+}
+
+/* --Methode-- */
+PIFontX::PIFontX(int npt, PIFontName fn, PIFontAtt fa)
+  : PIFontGen(npt, fn, fa), mFSize(-1) 
+{
+GlInit();
+SelectFontPt(fn, fa, npt);
+}
+
+/* --Methode-- */
+PIFontX::PIFontX(PIFontX const & fnt)
+  : PIFontGen(fnt.mFName), mFSize(-1) 
+{
+GlInit();
+SelectFontPt(fnt.mFName, fnt.mFAtt, fnt.mFSize);
+}
+
+/* --Methode-- */
+PIFontX::~PIFontX()
+{
+}
+
+/* --Methode-- */
+PIFontX & PIFontX::operator = (PIFontX const & fnt)
+{
+SelectFontPt(fnt.mFName, fnt.mFAtt, fnt.mFSize);
+return(*this);
+}
+
+/* --Methode-- */
+bool PIFontX::operator == (PIFontX const & fnt)
+{
+if ((fnt.mFName == mFName) && (fnt.mFAtt == mFAtt) && (fnt.mFSize == mFSize)) 
+  return(true);
+else return(false);
+}
+
+/* --Methode-- */
+void PIFontX::SetFont(PIFontName fn)
+{
+SelectFontPt(fn, mFAtt, mFSize);
+}
+
+/* --Methode-- */
+void PIFontX::SetFontAtt(PIFontAtt fa)
+{
+SelectFontPt(mFName, fa, mFSize);
+}
+
+/* --Methode-- */
+void PIFontX::SetFontSz(PIFontSize fs)
+{
+SelectFont(mFName, mFAtt, fs);
+}
+
+/* --Methode-- */
+void PIFontX::SetFontSzPt(int npt)
+{
+SelectFontPt(mFName, mFAtt, npt);
+}
+
+/* --Methode-- */
+PIFontName PIFontX::GetFontName() const
+{
+return(mFName);
+}
+
+/* --Methode-- */
+PIFontAtt PIFontX::GetFontAtt() const
+{
+return(mFAtt);
+}
+
+/* --Methode-- */
+int PIFontX::GetFontSzPt() const
+{
+return(mFSize);
+}
+
+
+/* --Methode-- */
+int PIFontX::GetFontHeight(int& asc, int& desc) const
+{
+char a[2];
+XCharStruct  ovr;
+int hd, fa, fd;
+XTextExtents(mFSt, a, 0, &hd, &fa, &fd, &ovr);
+asc = fa; desc = fd; 
+return(fa+fd);
+}
+
+/* --Methode-- */
+int PIFontX::GetStringWidth(char const* s) const
+{
+return(XTextWidth(mFSt, s, strlen(s)));
+}
+
+
+#define NMAXFONTSZ    13
+#define NMAXFONTATT   4
+#define NMAXFONTTYP   5
+
+/*  Variables globales pour la gestion des fontes  */
+static XFontStruct * fntst[NMAXFONTSZ][NMAXFONTATT][NMAXFONTTYP];
+static int fntsz[NMAXFONTSZ] = {8,9,10,11,12,14,16,18,20,24,28,32,36};
+static int TinyFontIndex = 1; 
+static int SmallFontIndex = 3; 
+static int NormalFontIndex = 5;
+static int LargeFontIndex = 7;
+static int VeryLargeFontIndex = 9;
+static int HugeFontIndex = 11;
+static  PIFontAtt fntatt[NMAXFONTATT] = 
+        { PI_RomanFont, PI_BoldFont, PI_ItalicFont, PI_BoldItalicFont };
+static  PIFontName fntname[NMAXFONTTYP] = { PI_DefaultFont, PI_CourierFont, PI_HelveticaFont, 
+                                            PI_TimesFont, PI_SymbolFont};  
+static XFontStruct * defnt = NULL;
+
+/* --Methode-- */
+PIFontSize PIFontX::GetFontSz() const
+{
+  int fnidx[6],k;
+  fnidx[0] = TinyFontIndex;
+  fnidx[1] = SmallFontIndex;
+  fnidx[2] = NormalFontIndex;
+  fnidx[3] = LargeFontIndex;
+  fnidx[4] = VeryLargeFontIndex;
+  fnidx[5] = HugeFontIndex;
+  PIFontSize rfnsz[6] = {PI_TinySizeFont, PI_SmallSizeFont, PI_NormalSizeFont, 
+			 PI_LargeSizeFont, PI_VeryLargeSizeFont, PI_HugeSizeFont};
+  PIFontSize rs = PI_NormalSizeFont;
+  int diff = mFSize-fntsz[NormalFontIndex];
+  int diffsz = (diff < 0) ? -diff : diff;
+  for(k=0; k<6; k++) {
+    diff = mFSize-fntsz[fnidx[k]];
+    if (diff < 0)  diff = -diff;
+    if (diff < diffsz) {
+      diffsz = diff; 
+      rs = rfnsz[k];
+    }
+  }
+return(rs);
+}
+
+/* --Methode-- */
+void PIFontX::SelectFont(PIFontName fn, PIFontAtt fa, PIFontSize fs)
+{
+int isz;
+switch (fs) {
+  case PI_TinySizeFont:
+    isz = fntsz[TinyFontIndex];
+    break;
+  case PI_SmallSizeFont:
+    isz = fntsz[SmallFontIndex];
+    break;
+  case PI_NormalSizeFont:
+    isz = fntsz[NormalFontIndex];
+    break;
+  case PI_LargeSizeFont:
+    isz = fntsz[LargeFontIndex];
+    break;
+  case PI_VeryLargeSizeFont:
+    isz = fntsz[VeryLargeFontIndex];
+    break;
+  case PI_HugeSizeFont:
+    isz = fntsz[HugeFontIndex];
+    break;
+  default:
+    isz = fntsz[NormalFontIndex];
+    break;
+  }
+
+SelectFontPt(fn, fa, isz);
+return;
+}
+
+/* --Methode-- */
+void PIFontX::SelectFontPt(PIFontName fn, PIFontAtt fa, int npt)
+{
+if ( (mFSize > 0) && (fn == mFName) && (fa == mFAtt) && (npt == mFSize) )   return;
+int dsz,i,isel, j, k;
+isel = 0;
+dsz = 9999;
+for(i=0; i<NMAXFONTSZ; i++)
+  {
+  j = npt - fntsz[i];   if (j < 0)  j = -j;
+  if (j < dsz)  {  isel = i; dsz = j; }
+  }
+i = isel;
+j = 0;
+switch (fa) {
+  case PI_RomanFont :
+    j = 0;
+    break;
+  case PI_BoldFont :
+    j = 1;
+    break;
+  case PI_ItalicFont :
+    j = 2;
+    break;
+  case PI_BoldItalicFont :
+    j = 3;
+    break;   
+  default :
+    j = 0;
+    break;
+  }
+
+k = 0;
+switch (fn)
+ {
+  case PI_DefaultFont :
+    k = 0;
+    break;
+  case PI_CourierFont :
+    k = 1;
+    break;
+  case PI_HelveticaFont :
+    k = 2;
+    break;
+  case PI_TimesFont :
+    k = 3;
+    break;
+  case PI_SymbolFont :
+    k = 4;
+    break;
+  default :
+    k = 0;
+    break;
+  }
+LoadFontSt(i, j, k);
+return;
+}
+
+
+// Le bazar pour recuperer des resources de .Xdefault et autres 
+typedef struct 
+  {
+  String fntFam[5];
+  } myAppData;
+static myAppData  apd;
+
+static XtResource resources[] = {
+  { "fontFamilyName", "FontFamilyName", XtRString, sizeof(String),
+    /*XtOffset(apd, fntFam[0])*/ 0, XtRString, const_cast<char *>("*-courier") } ,
+  { "courierfontFamilyName", "CourierfontFamilyName", XtRString, sizeof(String),
+    sizeof(String) , XtRString, const_cast<char *>("*-courier") } ,
+  { "helveticafontFamilyName", "HelveticafontFamilyName", XtRString, sizeof(String),
+    2*sizeof(String) , XtRString, const_cast<char *>("*-helvetica") } ,
+  { "timesfontFamilyName", "TimesfontFamilyName", XtRString, sizeof(String),
+    3*sizeof(String) , XtRString, const_cast<char *>("*-times") } ,
+  { "symbolfontFamilyName", "SymbolfontFamilyName", XtRString, sizeof(String),
+    4*sizeof(String) , XtRString, const_cast<char *>("*-symbol") }
+};
+ 
+static char * fnbi_b[4] = { "medium-r-normal", "bold-r-normal", 
+                          "medium-o-normal", "bold-o-normal" };
+static char * fnbo_b[4] = { NULL, NULL, 
+                          "medium-i-normal", "bold-i-normal" };
+
+/* --Methode-- */
+void PIFontX::LoadFontSt(int isz, int jat, int kfn)
+{
+
+if (!fntst[isz][jat][kfn])  // Il faut charger la fonte
+  {
+  char buff[256];
+  int count,k;
+  Display * mdsp = PIXDisplay();
+  char **list;
+
+  for (k=0; k<5; k++)  {  // Recherche de la fonte pour tailles croissantes
+    sprintf(buff,"-%s-%s-*-%d-*-*-*-*-*-*-*", apd.fntFam[kfn], fnbi_b[jat], fntsz[isz]+k);
+    list = XListFonts(mdsp, buff, 10, &count);
+    XFreeFontNames(list);
+    if ((count <= 0) && (fnbo_b[jat] != NULL)) {
+      sprintf(buff,"-%s-%s-*-%d-*-*-*-*-*-*-*", apd.fntFam[kfn], fnbo_b[jat], fntsz[isz]+k);
+      list = XListFonts(mdsp, buff, 10, &count);
+      XFreeFontNames(list);
+    }
+    if (count > 0)  break;
+    }
+  // certaines fontes n'ont pas de version  bold ou italique
+  if ( (count == 0) && (jat > 0) ) {
+    for (k=0; k<5; k++)  {  // Recherche de la fonte pour tailles croissantes
+      sprintf(buff,"-%s-%s-*-%d-*-*-*-*-*-*-*", apd.fntFam[kfn], fnbi_b[0], fntsz[isz]+k);
+      list = XListFonts(mdsp, buff, 10, &count);
+      XFreeFontNames(list);
+      if (count > 0)  break;
+      }
+    }
+  if (count > 0) 
+    fntst[isz][jat][kfn] = XLoadQueryFont(mdsp, buff);
+  else
+    { printf("PIFontX::LoadFontSt/ Pb font %s - Using default \n", buff);    
+    fntst[isz][jat][kfn] = defnt; }
+  }
+
+mFAtt = fntatt[jat];
+mFSize = fntsz[isz];
+mFName = fntname[kfn];
+mFSt = fntst[isz][jat][kfn];
+return;
+}
+
+
+static bool fgfntinitdone = false ;   // Flag init done
+/* --Methode-- */
+void PIFontX::GlInit()
+{
+if (fgfntinitdone) return;
+fgfntinitdone = true;
+
+Display * mdsp = PIXDisplay();
+
+char buff[256];
+int i,j,k,count;
+char **list;
+
+
+XtGetApplicationResources(PIXtTopWdg(), &apd, resources, 
+                          XtNumber(resources), NULL, 0);
+sprintf(buff,"-%s-*-*-*-*-*-*-*-*-*-*-*-*", apd.fntFam[0]);
+list = XListFonts(mdsp, buff, 15, &count);
+XFreeFontNames(list);
+if (count < 5)
+  { 
+  printf("PIFontX::Init %d fonts found for %s , switching to courier\n",
+         count, apd.fntFam[0]);
+  apd.fntFam[0] = "*-courier";
+  }
+sprintf(buff,"-%s-%s-*-*-*-*-12-*-*-*-*", apd.fntFam[0], fnbi_b[0]);
+list = XListFonts(mdsp, buff, 10, &count);
+XFreeFontNames(list);
+if (count < 1) {
+  sprintf(buff,"-*-fixed-*-*-*-*-12-*-*-*-*-*-*-*");
+  list = XListFonts(mdsp, buff, 10, &count);
+  XFreeFontNames(list);
+  if (count < 1)   {  
+    sprintf(buff,"fixed");
+    list = XListFonts(mdsp, buff, 10, &count);
+    XFreeFontNames(list);
+  }
+  if (count < 1)   {  
+    strcpy(buff,"");
+    list = XListFonts(mdsp, buff, 10, &count);
+    XFreeFontNames(list);
+  }
+}
+if (count < 1) {  
+  printf("PIFontX::Init/ Erreur, no font found ... \n");
+  defnt = NULL;
+  }
+else defnt = XLoadQueryFont(mdsp, buff);
+
+for (i=0; i<NMAXFONTSZ; i++)
+  for (j=0; j<NMAXFONTATT; j++)  
+    for (k=0; k<NMAXFONTTYP; k++)  fntst[i][j][k] = NULL;
+
+// Choix des trois tailles de fontes standard en fonction de 
+// la taille de fonte par defaut des composantes standard
+int szx, szy, szf;
+PIXtAppCtx(szx, szy, szf);
+int kkk, kkj, kksel, kkdsz = 9999;  
+kksel = NMAXFONTSZ/2;
+for(kkk=NMAXFONTSZ-1; kkk>=0; kkk--) {
+  kkj = szf - fntsz[kkk];   if (kkj < 0)  kkj = -kkj;
+  if (kkj < kkdsz)  {  kksel = kkk;  kkdsz = kkj; }
+  }
+if (kksel == NMAXFONTSZ-1)  kksel = NMAXFONTSZ-2;
+NormalFontIndex = kksel;
+SmallFontIndex = (kksel > 1) ? kksel-2 : 0 ;
+TinyFontIndex = (kksel > 3) ? kksel-4 : 0 ;  
+LargeFontIndex =  (kksel < NMAXFONTSZ-2) ? kksel+2 :  NMAXFONTSZ-1;
+VeryLargeFontIndex =  (kksel < NMAXFONTSZ-4) ? kksel+4 :  NMAXFONTSZ-1;
+HugeFontIndex =  (kksel < NMAXFONTSZ-6) ? kksel+6 :  NMAXFONTSZ-1;
+// On garde HugeFontIndex et TinyFontIndex aux tailles extremes 
+// HugeFontIndex = NMAXFONTSZ-1;
+
+// printf("PIFontX::Init()-DBG- FontIndex= %d %d %d (SzF=%d) \n", 
+//       SmallFontIndex, NormalFontIndex, BigFontIndex, szf);
+
+return;
+}
Index: /tags/V_Dec2002/SophyaPI/PI/pifontx.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pifontx.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pifontx.h	(revision 2309)
@@ -0,0 +1,55 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive     PIFontX
+// LAL (Orsay) / IN2P3-CNRS          R. Ansari  99
+
+
+#ifndef PIFONTX_H_SEEN
+#define PIFONTX_H_SEEN
+
+#include "pisysdep.h"
+#include "pifontgen.h"
+
+
+class PIFontX : public PIFontGen 
+{
+public :
+		PIFontX(PIFontName fn = PI_DefaultFont);
+		PIFontX(int npt, PIFontName fn = PI_DefaultFont, 
+                        PIFontAtt fa = PI_RomanFont);
+		PIFontX(PIFontX const & fnt);
+  virtual	~PIFontX();
+
+  virtual PIFontX & operator = (PIFontX const & fnt);
+  virtual bool operator == (PIFontX const & fnt);
+
+  virtual void		SetFont(PIFontName fn);
+  virtual void		SetFontAtt(PIFontAtt fa);
+  virtual void		SetFontSz(PIFontSize fs);
+  virtual void		SetFontSzPt(int npt);
+
+  virtual PIFontName    GetFontName() const ;
+  virtual PIFontAtt     GetFontAtt() const ;
+  virtual PIFontSize    GetFontSz() const;
+  virtual int		GetFontSzPt() const ;
+
+  virtual int		GetFontHeight(int& asc, int& desc) const ;
+  virtual int		GetStringWidth(char const* s) const ;
+
+// En public pour PIGraphicX
+  inline Font		GetXFontId() { return(mFSt->fid); }
+
+protected:
+  void           SelectFont(PIFontName fn, PIFontAtt fa, PIFontSize fs);
+  void           SelectFontPt(PIFontName fn, PIFontAtt fa, int npt);
+  void           LoadFontSt(int isz, int jat, int kfn);
+  static void    GlInit();
+
+  PIFontName mFName;
+  PIFontAtt mFAtt;
+  int mFSize;
+  XFontStruct *mFSt;
+};
+
+typedef PIFontX PIFont;
+
+#endif      // PIFONTX_H_SEEN
Index: /tags/V_Dec2002/SophyaPI/PI/pigfname.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pigfname.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pigfname.h	(revision 2309)
@@ -0,0 +1,12 @@
+#ifndef PIGFNAME_H_SEEN
+#define PIGFNAME_H_SEEN
+
+#include "machdefs.h"
+#include <string>
+
+string PIGetFileName(string = "");
+string PIGetExistingFileName(string = "");
+
+
+#endif
+
Index: /tags/V_Dec2002/SophyaPI/PI/pigraph3d.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pigraph3d.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pigraph3d.cc	(revision 2309)
@@ -0,0 +1,491 @@
+// Module PI : Peida Interactive     PIGraphic3D
+// Trace graphiques 3D               R. Ansari  06/98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include <stdio.h>
+#include <math.h>
+#include "pigraph3d.h"
+
+#ifndef M_PI_2
+#define M_PI_2 (M_PI/2)
+#endif
+
+//++
+// Class	PIGraphic3D
+// Lib		PI
+// include	pigraph3d.h
+//
+//   	Classe fournissant les services de tracé graphique 
+//	en coordonnées utilisateur, et quelques primitives de tracé 3D
+//--
+//++
+// Links	Parent
+// PIGraphicUC
+//--
+
+//++
+// Titre	Constructeurs, méthodes
+//--
+//++
+// PIGraphic3D(PIGraphicGen* g, PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+//	Constructeur d'un objet "PIGraph3D" à partir d'un "PIGraphic* g". L'espace
+//	de travail du nouvel objet "PIGraphic" correspond au rectangle défini par
+//	"(x0,y0)" , "dx,dy" du "PIGraphic" de départ.
+// 
+// int  kind()
+//	Renvoie le type ("= PI_3DGraphics")
+//--
+
+/* --Methode-- */
+PIGraphic3D::PIGraphic3D(PIGraphicGen* g, PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+        : PIGraphicUC(g, x0, y0, dx, dy)
+{
+  int i,j;
+  for(i=0; i<3; i++) 
+    for(j=0; j<3; j++)  RE[i][j] = 0.;
+  RE[0][0] = RE[1][1] = RE[2][2] = 1.;
+  xO = yC = 0.; zO = -10.;
+  xC = yC = zC = 0.;
+  tO = fO = pO = 0.; 
+  daxO = dayO = 0.25;
+  lCO = 10.;  dlCO = 0.2;  
+  sO = false;
+}
+
+/* --Methode-- */
+PIGraphic3D::~PIGraphic3D()
+{
+}
+
+/* --Methode-- */
+int PIGraphic3D::kind() 
+{
+  return PI_3DGraphics; 
+}
+
+//++
+// Titre	Système de coordonnées 3D et projection
+//	Le système de coordonnées 3D est défini par la position de l'observateur (caméra),
+//	la direction de visée ou la position du centre du champ, 
+//	l'ouverture angulaire de la caméra selon les deux 
+//	axes de la projection (X,Y), eventuellement un angle correspondant à la rotation
+//	du plan image ("psi"). Les angles d'Euler ("teta", "phi", "psi" ) sont utilisés
+//	dans la définition du système de coordonnées et la projection est de type 
+//	perspective. 
+//
+//	Les coordonnées utilisateur définissant le plan image ("PIGraphicUC") vont de 
+//	X: "-dax , +dax"   Y : "-day , +day".  
+//--
+
+//++
+// void  Set3DCS_Obs(double xo, double yo, double zo, double teta, double phi, double psi, -
+//                  double dax, double day, double co, double dco=0.2)
+//	Définition du système de projection 3D à l'aide de la position de l'observateur 
+//	et de la direction de visée.
+//|	xo,yo,zo : Position de l'observateur (camera)
+//|	teta,phi : Direction de visee
+//|	psi : rotation du plan image
+//|	dax , day : Ouverture du plan image selon les deux axes = Xmax,Ymax / Z
+//|	co : distance au centre du champ
+//|	dco : profondeur de champ 
+//
+// void  Set3DCS(double xc, double yc, double zc, double xo, double yo, double zo, -
+//               double dax, double day, double dco=0.2, double psi=0.)
+//	Définition du système de projection 3D à partir de la position de l'observateur et 
+//	du centre du champ.
+//|	xc,yc,zc : Position du centre du champ
+//|	xo,yo,zo : Position de l'observateur (camera)
+//|	dax , day : Ouverture du plan image selon les deux axes = Xmax,Ymax / Z
+//|	dco : profondeur de champ 
+//|	psi : rotation du plan image
+//--
+
+#if defined(__KCC__) 
+#ifndef M_PI
+#define M_PI            3.14159265358979323846  /* pi */
+#endif
+#ifndef M_PI_2
+#define M_PI_2          1.57079632679489661923  /* pi/2 */
+#endif
+#endif
+
+static double deuxpi = 2*M_PI;
+
+/* --Methode-- */
+void PIGraphic3D::Set3DCS_Obs(double xo, double yo, double zo, double teta, double phi, double psi, 
+                              double dax, double day, double co, double dco)
+{
+  sO = true;
+  xO = xo;  yO = yo;  zO = zo;
+  while (teta < 0.)  teta += deuxpi;
+  while (teta > deuxpi)  teta -= deuxpi;
+  if (teta > M_PI)  { teta = M_PI-teta;  phi = phi+M_PI; }
+  while (phi < 0.)  phi += deuxpi;
+  while (phi > deuxpi) phi -= deuxpi;
+  tO = teta;  fO = phi;  pO = psi;
+  if (dax < 0.) dax = -dax;
+  if (day < 0.) day = -day;
+  daxO = dax;  dayO = day;
+  lCO = co;   dlCO = dco;
+// Si on ne met  kAxeDirLtoR, le repere semble etre ds le sens inverse -> kAxeDirRtoL  , Reza 16/10/98
+  SetUCS(-dax, dax, -day, day, kAxeDirRtoL, kAxeDirDownUp);
+  double ct = cos((double)tO);
+  double st = sin((double)tO);
+// (Teta,Phi) = Direction de visee 
+// Les angles d'Euler correspondants sont Teta, Phi+Pi/2
+// Le Pi/2 vient que les rotations d'euler se font dans l'ordre
+//  Autour de oZ d'angle Phi, autour de oN (nouvel axe X) d'angle Teta
+//  Autour du nouvel axe Z (x3) d'angle Psi
+  double cf = cos((double)fO+M_PI_2);
+  double sf = sin((double)fO+M_PI_2);
+  double cp = cos((double)pO);
+  double sp = sin((double)pO);
+  RE[0][0] = cf*cp-sf*ct*sp;     RE[0][1] = sf*cp+cf*ct*sp;      RE[0][2] = st*sp;
+  RE[1][0] = -cf*sp-sf*ct*cp;    RE[1][1] = -sf*sp+cf*ct*cp;     RE[1][2] = st*cp;
+  RE[2][0] = sf*st;              RE[2][1] = -cf*st;              RE[2][2] = ct;
+  cf = cos((double)fO);
+  sf = sin((double)fO);
+  zC = ct*lCO+zO;
+  xC = st*cf*lCO+xO;
+  yC = st*sf*lCO+yO;
+}
+
+/* --Methode-- */
+void PIGraphic3D::Set3DCS(double xc, double yc, double zc, double xo, double yo, double zo, 
+                          double dax, double day, double dco, double psi)
+{
+  sO = false;
+  xO = xo;  yO = yo;  zO = zo;
+  xC = xc;  yC = yc;  zC = zc;
+  double dx,dy,dz;
+// On calcule le vecteur  OC  Observateur -> Centre du champ, ca nous donne donc teta,phi de visee
+  dx = xc-xo;  dy = yc-yo;  dz = zc-zo;
+  if (dax < 0.) dax = -dax;
+  if (day < 0.) day = -day;
+  daxO = dax;  dayO = day;  
+// Si on ne met  kAxeDirLtoR, le repere semble etre ds le sens inverse -> kAxeDirRtoL  , Reza 16/10/98
+  SetUCS(-dax, dax, -day, day, kAxeDirRtoL, kAxeDirDownUp);
+  lCO = sqrt(dx*dx+dy*dy+dz*dz);
+  if (lCO < 1.e-6) {
+    printf("PIGraphic3D::Set3DCS()/Warning : Length(CO) = %g -> CS par defaut \n", lCO);
+    int i,j;
+    for(i=0; i<3; i++) 
+      for(j=0; j<3; j++)  RE[i][j] = 0.;
+    RE[0][0] = RE[1][1] = RE[2][2] = 1.;
+    xO = yC = 0.; zO = -10.;
+    xC = yC = zC = 0.;
+    tO = fO = pO = 0.; 
+    daxO = dayO = 0.25;
+    lCO = 10.;  dlCO = 0.2;      
+    return;
+  }
+  dlCO = dco;
+  double lxy = sqrt(dx*dx+dy*dy);
+  double ct,st,cf,sf;
+  ct = dz/lCO;
+  st = sqrt(1-ct*ct);
+  pO = psi;
+  tO = acos(ct);
+  if (lxy < 1.e-6) { fO = 0.;  cf = 0.;  }
+  else {  cf = dx/lxy;  fO = acos(cf);  if (dy < 0.)  fO = deuxpi-fO;   }
+// (Teta,Phi) = Direction de visee 
+// Les angles d'Euler correspondants sont Teta, Phi+Pi/2
+// Le Pi/2 vient que les rotations d'euler se font dans l'ordre
+//  Autour de oZ d'angle Phi, autour de oN (nouvel axe X) d'angle Teta
+//  Autour du nouvel axe Z (x3) d'angle Psi
+  cf = cos((double)fO+M_PI_2);
+  sf = sin((double)fO+M_PI_2);
+  double cp = cos((double)psi);
+  double sp = sin((double)psi);
+  RE[0][0] = cf*cp-sf*ct*sp;     RE[0][1] = sf*cp+cf*ct*sp;      RE[0][2] = st*sp;
+  RE[1][0] = -cf*sp-sf*ct*cp;    RE[1][1] = -sf*sp+cf*ct*cp;     RE[1][2] = st*cp;
+  RE[2][0] = sf*st;              RE[2][1] = -cf*st;              RE[2][2] = ct;
+}
+
+//++
+// bool Get3DCS(double& xc, double& yc, double& zc, double& xo, double& yo, double& zo, -
+//             double& teta, double& phi, double& psi, double& dax, double& day, double& co, double& dco);
+//	Renvoie les paramètres de définition du système de projection 3D.
+//	"Rc= true" si défini par  "Set3DCS_Obs()"
+//	
+// void  RotateObserver(double teta, double phi, double psi=0., bool rel=true)
+//	Positionne l'observateur (la caméra) en maintenant la position  
+//	du centre de champ fixe. Si "rel=false" : "teta, phi" determine la nouvelle
+//	direction de visée. Si "rel=false" : la direction de visée est tournée
+//	de l'angle "teta,phi". 
+// void  RotateObject(double teta, double phi, bool rel=true)
+//	Repostionne le centre du champ en maintenant la position de l'observateur fixe.
+//	Si "rel=false" : "teta, phi" determine la nouvelle direction de visée.
+//	Si "rel=false" : la direction de visée est tournée de l'angle "teta,phi". 
+// 
+// void  ZoomInOut(double fco, double fdax, double fday, bool rel=true)
+//	Eloigne ou approche l'observateur et modifie l'ouverture du plan image.
+//	si "real=true" : "fco, fdax, fday" sont des facteurs multiplicatifs
+//	par rapport aux valeurs actuelles, sinon des valeurs absolues. 
+//|	fco : distance observateur - centre du champ
+//|	fdax, fday : ouverture du plan image
+//--
+
+/* --Methode-- */
+bool PIGraphic3D::Get3DCS(double& xc, double& yc, double& zc, double& xo, double& yo, double& zo, 
+                          double& teta, double& phi, double& psi, double& dax, double& day, double& co, double& dco)
+{
+  xc = xC;  yc = yC;  zc = zC;
+  xo = xO;  yo = yO;  zo = zO;
+  teta = tO;  phi = fO;  psi = pO;
+  dax = daxO;   day = dayO;
+  co = lCO;     dco = dlCO;
+  return(sO);
+}
+
+
+/* --Methode-- */
+void PIGraphic3D::RotateObserver(double teta, double phi, double psi, bool rel)
+// Positionne l'observateur (la camera) de maniere a ce que la direction de 
+// visee soit tO=teta, pO=phi (rel=false) / tO+=teta pO+=phi (rel=true) 
+// en conservant le centre de champ fixe  
+{
+  if (rel) {
+    teta += tO;
+    phi += fO;
+    psi += pO;
+    }
+  while (teta < 0.)  teta += deuxpi;
+  while (teta > deuxpi)  teta -= deuxpi;
+  if (teta > M_PI)  { teta = M_PI-teta;  phi = phi+M_PI; }
+  double xo,yo,zo; 
+  zo = -cos((double)teta)*lCO+zC;
+  xo = -sin((double)teta)*cos((double)phi)*lCO+xC;
+  yo = -sin((double)teta)*sin((double)phi)*lCO+yC;
+  Set3DCS(xC,yC,zC, xo,yo,zo, daxO, dayO, dlCO, psi);
+}
+
+/* --Methode-- */
+void PIGraphic3D::RotateObject(double teta, double phi, bool rel)
+// Positionne l'objet (centre du champ) de maniere a ce que la direction de 
+// visee soit tO=teta, pO=phi (rel=false) / tO+=teta pO+=phi (rel=true) 
+// en conservant la position de l'observateur fixe.  
+{
+  if (rel) {
+    teta += tO;
+    phi += fO;
+    }
+  while (teta < 0.)  teta += deuxpi;
+  while (teta > deuxpi)  teta -= deuxpi;
+  if (teta > M_PI)  { teta = M_PI-teta;  phi = phi+M_PI; }
+  double xc,yc,zc; 
+  zc = cos((double)teta)*lCO+zO;
+  xc = sin((double)teta)*cos((double)phi)*lCO+xO;
+  yc = sin((double)teta)*sin((double)phi)*lCO+yO;
+  Set3DCS(xc,yc,zc, xO,yO,zO, daxO, dayO, dlCO, pO);
+}
+
+/* --Methode-- */
+void PIGraphic3D::ZoomInOut(double fco, double fdax, double fday, bool rel)
+{
+  if (fco < 0.001) fco = 1.;
+  if (fdax < 0.001) fdax = 1.;
+  if (fday < 0.001) fday = 1.;
+  double dl;
+  if (rel) {
+    dl = fco*lCO;  
+    fdax *= daxO;
+    fday *= dayO;
+  }
+  else dl = fco; 
+  double xo,yo,zo; 
+  if (dl < 1.e-5) dl = 1.e-5;
+  zo = zC-cos((double)tO)*dl;
+  xo = xC-sin((double)tO)*cos((double)fO)*dl;
+  yo = yC-sin((double)tO)*sin((double)fO)*dl;
+  Set3DCS(xC,yC,zC, xo,yo,zo, fdax, fday, dlCO, pO);
+//  Set3DCS_Obs(xo, yo, zo, tO, fO, pO, daxO*fda, dayO*fda, dl, dlCO);
+}
+
+/* --Methode-- */
+void PIGraphic3D::C3DC2ObsCS(double x, double y, double z, double& xp, double& yp, double& zp)
+{
+  double xc, yc, zc;
+  xc = x-xO;   yc = y-yO;    zc = z-zO;
+  xp = RE[0][0]*xc+RE[0][1]*yc+RE[0][2]*zc;
+  yp = -RE[1][0]*xc+RE[1][1]*yc+RE[1][2]*zc;  
+  zp = RE[2][0]*xc+RE[2][1]*yc+RE[2][2]*zc;
+}
+
+/* --Methode-- */
+void PIGraphic3D::Proj3DC2GrC(double x, double y, double z, double& xpix, double& ypix)
+{
+  double xc, yc, zc;
+  double xp, yp, zp;
+  xc = x-xO;   yc = y-yO;    zc = z-zO;
+  xp = RE[0][0]*xc+RE[0][1]*yc+RE[0][2]*zc;   
+  yp = RE[1][0]*xc+RE[1][1]*yc+RE[1][2]*zc;
+  zp = RE[2][0]*xc+RE[2][1]*yc+RE[2][2]*zc;
+  if ((zp>-1.e-6) && (zp < 1.e-6))   // Protection Divide/0
+    { xpix = ypix = 0.;   return; }
+  xpix = (double)(xOrg + (xp/zp)*xScale);
+  ypix = (double)(yOrg + (yp/zp)*yScale);
+//  printf("-DBG-Proj3DC2GrC() %g %g %g -> %g %g %g -> %g %g %g -> (%g %g)\n", x,y,z,xc,yc,zc,xp,yp,zp,xp/zp,yp/zp);
+//  printf("-DBG- ... (%g %g %g - %g %g) %g %g - %g %g -> %g %g \n", xO,yO,zO, tO,fO, xOrg, yOrg,xScale,yScale ,xpix,ypix);
+}
+
+//++
+// Titre	Primitives de tracé 3D
+//--
+//++
+// void  DrawString3D(PIGrCoord x0, PIGrCoord y0, PIGrCoord z0, char* s)
+//	Tracé de chaîne de caractères à la position "(x0,y0,z0)"
+// void  DrawOpaqueString3D(PIGrCoord x0, PIGrCoord y0, PIGrCoord z0, char* s)
+//	Tracé de chaîne opaque à la position "(x0,y0,z0)"
+// void  DrawLine3D(PIGrCoord x1, PIGrCoord y1, PIGrCoord z1, -
+//                  PIGrCoord x2, PIGrCoord y2, PIGrCoord z2)
+//	Tracé d'une ligne entre les deux points "(x1,y1,z1)" et "(x2,y2,z2)"
+// void  DrawPolygon3D(PIGrCoord *x, PIGrCoord *y, PIGrCoord *z, int n)
+//	Tracé de contour de polygone - sommets définis par le tableau 
+//	"(x[i],y[i],z[i])" , "i=0..n-1"
+// void  DrawFPolygon3D(PIGrCoord *x, PIGrCoord *y, PIGrCoord *z, int n)
+//	Tracé de polygone - "(x[i],y[i],z[i])" , "i=0..n-1"
+// void  DrawMarker3D(PIGrCoord x0, PIGrCoord y0, PIGrCoord z0)
+//	Tracé d'un signe (marker) au point "(x0,y0,z0)"
+// void  DrawMarkers3D(PIGrCoord *x, PIGrCoord *y, PIGrCoord *z, int n)
+//	Tracé de signes (marker) aux points "(x[i],y[i],z[i])" , "i=0..n-1"
+//--
+
+/* --Methode-- */
+void PIGraphic3D::DrawString3D(PIGrCoord x0, PIGrCoord y0, PIGrCoord z0, const char* s)
+{
+  if (!mGrC) return;
+  double xf, yf;
+  Proj3DC2GrC(x0, y0, z0, xf, yf);
+  mGrC->DrawString(xf, yf, s);
+  return;
+}
+
+/* --Methode-- */
+void PIGraphic3D::DrawOpaqueString3D(PIGrCoord x0, PIGrCoord y0, PIGrCoord z0, const char* s)
+{
+  if (!mGrC) return;
+  double xf, yf;
+  Proj3DC2GrC(x0, y0, z0, xf, yf);
+  mGrC->DrawOpaqueString(xf, yf, s);
+  return;
+}
+
+/* --Methode-- */
+void PIGraphic3D::DrawLine3D(PIGrCoord x1, PIGrCoord y1, PIGrCoord z1, 
+                             PIGrCoord x2, PIGrCoord y2, PIGrCoord z2)
+{
+  if (!mGrC) return;
+  double xf1, yf1, xf2, yf2;
+  Proj3DC2GrC(x1, y1, z1, xf1, yf1);
+  Proj3DC2GrC(x2, y2, z2, xf2, yf2);
+//  printf("-DBG-DrawLine3D() : %g %g %g -> %g %g | %g %g %g -> %g %g\n", 
+//         (double)x1, (double)y1, (double)z1, xf1, yf1, 
+//         (double)x2, (double)y2, (double)z2, xf2, yf2 );
+  mGrC->DrawLine(xf1, yf1, xf2, yf2);
+}
+
+#define NMXMULTP  30   // Pour multipoint sans new
+
+/* --Methode-- */
+void PIGraphic3D::DrawPolygon3D(PIGrCoord *x, PIGrCoord *y, PIGrCoord *z, int n)
+{
+  PIGrCoord xc[NMXMULTP], yc[NMXMULTP];
+  PIGrCoord *pxc, *pyc;
+  int i;
+  double xf, yf;
+ 
+  if (!mGrC) return;
+  if (n <= 0)  return;
+
+  if (n > NMXMULTP) { pxc = new PIGrCoord[n];  pyc = new PIGrCoord[n];  }
+  else { pxc = xc;  pyc = yc; }
+  for(i=0; i<n; i++) {
+    Proj3DC2GrC(x[i], y[i], z[i], xf, yf);
+    pxc[i] = xf;  pyc[i] = yf; 
+  }
+  mGrC->DrawPolygon(pxc, pyc, n, false);
+  if (n > NMXMULTP) { delete[] pxc;  delete[] pyc; }
+  return;
+}
+
+
+/* --Methode-- */
+void PIGraphic3D::DrawFPolygon3D(PIGrCoord *x, PIGrCoord *y, PIGrCoord *z, int n)
+{
+  PIGrCoord xc[NMXMULTP], yc[NMXMULTP];
+  PIGrCoord *pxc, *pyc;
+  int i;
+  double xf, yf;
+ 
+  if (!mGrC) return;
+  if (n <= 0)  return;
+
+  if (n > NMXMULTP) { pxc = new PIGrCoord[n];  pyc = new PIGrCoord[n];  }
+  else { pxc = xc;  pyc = yc; }
+  for(i=0; i<n; i++) {
+    Proj3DC2GrC(x[i], y[i], z[i], xf, yf);
+    pxc[i] = xf;  pyc[i] = yf; 
+  }
+  mGrC->DrawFPolygon(pxc, pyc, n, false);
+  if (n > NMXMULTP) { delete[] pxc;  delete[] pyc; }
+  return;
+}
+
+/* --Methode-- */
+void PIGraphic3D::DrawMarker3D(PIGrCoord x0, PIGrCoord y0, PIGrCoord z0)
+{
+  if (!mGrC) return;
+  double xf, yf;
+  Proj3DC2GrC(x0, y0, z0, xf, yf);
+  mGrC->DrawMarker(xf, yf);
+  return;
+}
+
+/* --Methode-- */
+void PIGraphic3D::DrawMarkers3D(PIGrCoord *x, PIGrCoord *y, PIGrCoord *z, int n)
+{
+  PIGrCoord xc[NMXMULTP], yc[NMXMULTP];
+  PIGrCoord *pxc, *pyc;
+  int i;
+  double xf, yf;
+ 
+  if (!mGrC) return;
+  if (n <= 0)  return;
+
+  if (n > NMXMULTP) { pxc = new PIGrCoord[n];  pyc = new PIGrCoord[n]; }
+  else { pxc = xc;  pyc = yc; }
+  for(i=0; i<n; i++) {
+    Proj3DC2GrC(x[i], y[i], z[i], xf, yf);
+    pxc[i] = xf;  pyc[i] = yf; 
+  }
+  mGrC->DrawMarkers(pxc, pyc, n);
+  if (n > NMXMULTP) { delete[] pxc;  delete[] pyc; }
+  return;
+}
+
+
+//  Methode pour debugger 
+/* --Methode-- */
+void PIGraphic3D::PrintCS()
+{
+if (sO)  printf("PIGraphic3D::PrintCS() : Set3DCS_Obs(...) \n");
+else  printf("PIGraphic3D::PrintCS() : Set3DCS(...) \n");
+printf("C: %g %g %g ->O: %g %g %g - T,P= %g %g %g lCO= %g %g  |  %g %g - %g %g \n", 
+        xC,yC,zC, xO, yO, zO, tO, fO, pO, lCO, dlCO, xOrg, xScale, yOrg, yScale ); 
+printf("RE[3][3]=  %g %g %g | %g %g %g | %g %g %g\n", 
+        RE[0][0], RE[0][1], RE[0][2], RE[1][0], RE[1][1], RE[1][2], RE[2][0], RE[2][1], RE[2][2]); 
+double x,y,z,xp,yp,zp, xpix, ypix;
+x = xC, y = yC, z= zC;
+C3DC2ObsCS(x, y, z, xp, yp, zp);
+Proj3DC2GrC(x, y, z, xpix, ypix);
+printf("C -> %g %g %g -> %g %g \n", xp, yp, zp, xpix, ypix); 
+x = xC+1, y = yC, z= zC;
+C3DC2ObsCS(x, y, z, xp, yp, zp);
+Proj3DC2GrC(x, y, z, xpix, ypix);
+printf("C+(1,0,0) -> %g %g %g -> %g %g ", xp, yp, zp, xpix, ypix); 
+x = xC, y = yC+1, z= zC+1;
+C3DC2ObsCS(x, y, z, xp, yp, zp);
+Proj3DC2GrC(x, y, z, xpix, ypix);
+printf("C+(0,1,1) -> %g %g %g -> %g %g \n", xp, yp, zp, xpix, ypix); 
+}
Index: /tags/V_Dec2002/SophyaPI/PI/pigraph3d.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pigraph3d.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pigraph3d.h	(revision 2309)
@@ -0,0 +1,56 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive     PIGraphic3D
+// Trace graphiques 3D               R. Ansari  06/98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PIGRAPHIC3D_H_SEEN
+#define PIGRAPHIC3D_H_SEEN
+
+#include "pisysdep.h"
+#include "pigraphuc.h"
+
+
+class PIGraphic3D : public PIGraphicUC 
+{
+public:
+                     PIGraphic3D(PIGraphicGen* g, PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy);
+  virtual           ~PIGraphic3D();
+
+  virtual int        kind();
+
+//  Definition du systeme de projection 3D-2D
+  virtual void       Set3DCS_Obs(double xo, double yo, double zo, double teta, double phi, double psi, 
+                                 double dax, double day, double co, double dco=0.2);
+  virtual void       Set3DCS(double xc, double yc, double zc, double xo, double yo, double zo, 
+                             double dax, double day, double dco=0.2, double psi=0.);
+  virtual bool       Get3DCS(double& xc, double& yc, double& zc, double& xo, double& yo, double& zo,  
+                             double& teta, double& phi, double& psi, double& dax, double& day, double& co, double& dco);
+
+  virtual void       PrintCS();  // Pour debugger
+  virtual void       RotateObserver(double teta, double phi, double psi=0., bool rel=true);
+  virtual void       RotateObject(double teta, double phi, bool rel=true);
+  virtual void       ZoomInOut(double fco, double fdax, double fday, bool rel=true);
+
+  virtual void       C3DC2ObsCS(double x, double y, double z, double& xp, double& yp, double& zp);
+  virtual void       Proj3DC2GrC(double x, double y, double z, double& xpix, double& ypix);
+  
+  virtual void       DrawString3D(PIGrCoord x0, PIGrCoord y0, PIGrCoord z0, const char* s);
+  virtual void       DrawOpaqueString3D(PIGrCoord x0, PIGrCoord y0, PIGrCoord z0, const char* s);
+  virtual void       DrawLine3D(PIGrCoord x1, PIGrCoord y1, PIGrCoord z1, 
+                                PIGrCoord x2, PIGrCoord y2, PIGrCoord z2);
+  virtual void       DrawPolygon3D(PIGrCoord *x, PIGrCoord *y, PIGrCoord *z, int n);  
+  virtual void       DrawFPolygon3D(PIGrCoord *x, PIGrCoord *y, PIGrCoord *z, int n);  
+  virtual void       DrawMarker3D(PIGrCoord x0, PIGrCoord y0, PIGrCoord z0);
+  virtual void       DrawMarkers3D(PIGrCoord *x, PIGrCoord *y, PIGrCoord *z, int n);
+  
+protected:
+  double xO, yO, zO;  // Position observateur = camera
+  double xC, yC, zC;  // Position centre du champ
+  double tO,fO,pO;    // Orientation observateur (Teta, Phi, Psi, Angles d Euler)
+  double daxO, dayO;  // Demi-ouverture de la camera suivant les deux axes de projection (xp/zp, yp/zp) 
+  double lCO, dlCO;   // Distance Camera-Centre du champ et profondeur de champ 
+  double RE[3][3];    // Matrice de rotation  
+  bool sO;            // Vrai si fait par Set3DCS_Obs()
+};
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pigraphgen.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pigraphgen.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pigraphgen.cc	(revision 2309)
@@ -0,0 +1,807 @@
+// Module PI : Peida Interactive     PIGraphic 
+// Primitives de trace graphiques    R. Ansari  97
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+// Classe generique de trace graphique de base (Ne peut etre instancie)
+
+#include "pigraphgen.h"
+#include <math.h>
+#include <iostream.h>
+#include "ucckprot.h"
+
+//++
+// Class	PIGraphic
+// Lib		PI
+// include	pigraphgen.h
+//
+//   	Classe de base fournissant les services de tracé graphique.
+//   	La classe PIGraphicGen définit l'interface à travers des méthodes
+//   	virtuelles pures. Les objets instanciés doivent être de la classe
+//   	"PIGraphicWin" ou "PIGraphicUC" ou ...
+//   	La classe "PIGraphicWin" a une implementation dépendante du système 
+//   	utilisé (Mac, XWindow, ...). 
+//   	Un type particulier *PIGrCoord* est défini pour la spécification 
+//	des coordonnées graphiques. 
+//--
+//++
+// Links	Classes derivees
+// PIGraphicUC
+// PIGraphic3D
+// PIGraphicPS
+//--
+//++
+// Links	Voir aussi
+// PIFont
+// PIColorMap
+//--
+//++
+// Links	et
+// PIGrCoord
+// PILineAtt
+// PIGraphicAtt
+//--
+
+//++
+// Titre	Constructeurs
+//--
+//++
+// PIGraphic()
+//	Constructeur utilisé par les classes dérivées.
+// PIGraphic(PIWdg* wdg)
+//	Constructeur pour les *PIGraphicWin*. Objet "PIGraphic" capable 
+//	de tracer dans un "PIWdg".
+// PIGraphic(PIScreenBuffer* grb)
+//	Constructeur pour objet "PIGraphic" capable de tracer dans un 
+//	buffer graphique.
+//--
+//++
+//--
+// Titre	Méthodes
+//++
+// int  kind()
+//	Renvoie le type de l'objet "PIGraphic" .
+//	* PI_UnknownGraphics : Objet PIGraphic de type inconnue.
+//	* PI_ScrBufferGraphics : Objet PIGraphic associé à un "GraphicBuffer"
+//	* PI_ScrWindowGraphics : Objet PIGraphic associé à une fenêtre sur l'écran (PIWdg)
+//	* PI_PSFileGraphics : Objet PIGraphic à un fichier PostScript (pour impression papier)
+//	* PI_UCGraphics : Objet PIGraphic travaillant dans un système de coordonnées utilisateur.
+//	* PI_3DGraphics : Objet PIGraphic fournissant des méthodes de tracé en coordonnées 3-D
+// void  GetGrSpace(PIGrCoord& xmin, PIGrCoord& xmax, PIGrCoord& ymin, PIGrCoord& ymax)
+//	Renvoie les limites de l'espace graphique - Coordonnées fenêtre pour un PIGraphicWin, 
+//	Limites définies par l'utilisateur pour un PIGraphicUC
+// void  Erase(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy) 
+//	Efface le rectangle défini par le coin "x0,y0", de longeur et de largeur "dx,dy"
+//	en utilisant la couleur d'arrière plan (Background)
+//--
+
+
+/* --Methode-- */
+PIGraphicGen::PIGraphicGen()
+{
+myWdg = NULL;
+myGrb = NULL;
+myLockFCol = false;
+SelArrowMarker();
+}
+
+/* --Methode-- */
+PIGraphicGen::PIGraphicGen(PIWdg* wdg)
+{
+myWdg = wdg;
+myGrb = NULL;
+myLockFCol = false;
+SelArrowMarker();
+}
+
+/* --Methode-- */
+PIGraphicGen::PIGraphicGen(PIScreenBuffer* grb)
+{
+myWdg = NULL;
+myGrb = grb;
+myLockFCol = false;
+SelArrowMarker();
+}
+
+/* --Methode-- */
+PIGraphicGen::~PIGraphicGen()
+{
+}
+/* --Methode-- */
+int PIGraphicGen::kind() 
+{
+return PI_UnknownGraphics ;
+}
+
+
+/* --Methode-- */
+void PIGraphicGen::GetGrSpace(PIGrCoord& xmin, PIGrCoord& xmax, PIGrCoord& ymin, PIGrCoord& ymax)
+{
+xmin = ymin = 0;  
+xmax = ymax = 0;
+if (myWdg) {
+  xmax = myWdg->XSize();
+  ymax = myWdg->YSize();
+  }
+}
+
+//++ 
+// Titre	Tracés de texte
+//--
+//++
+// void  DrawString(PIGrCoord x, PIGrCoord y, const char* s, unsigned long pos = 0)
+//	Trace la chaîne de caractères "s" à la position "x,y", 
+//	en utilisant la couleur d'avant-plan (Foreground)
+//	La chaine est trace avec une justification a gauche, ou droite,
+//	ou centree (horzontal) - bas, haut, milieu (vertical), en fonction de
+//	de la valeur du flag "pos"
+//|	PI_HorizontalLeft PI_HorizontalCenter PI_HorizontalRight
+//|	PI_VerticalBottom PI_VerticalCenter PI_VerticalTop
+// void  DrawOpaqueString(PIGrCoord x, PIGrCoord y, const char* s, int pos = 0) 
+//	Trace la chaîne de caractères "s" à la position "x,y" . La couleur d'
+//	arrière-plan est utilisée pour remplir la zone rectangulaire occupée par
+//	le tracé de texte.
+//	La chaine est trace avec une justification a gauche, ou droite,
+//	ou centree (horizontal) - bas, haut, milieu (vertical), en fonction de
+//	de la valeur du flag "pos"
+//|	PI_HorizontalLeft PI_HorizontalCenter PI_HorizontalRight
+//|	PI_VerticalBottom PI_VerticalCenter PI_VerticalTop
+// void  DrawCompString(PIGrCoord x, PIGrCoord y, const char* s, const char* s_up, \
+//       const char* s_dn, PIFont const & fntss, unsigned long pos = 0)
+//	Tracé d'une chaîne de caractères "s" avec une partie de texte en exposant "s_up"
+//	et une partie en indice "s_dn". Une fonte différente ("fntss") peut être 
+//	spécifiée pour la partie de texte en exposant et en indice. La taille 
+//	de la fonte exposant-indice est calculée automatiquement en fonction de 
+//	la taille de fonte courante. le positionnement s'effectue en fonction
+//	du flag "pos" :
+//|	PI_HorizontalLeft PI_HorizontalCenter PI_HorizontalRight
+//|	PI_VerticalBottom PI_VerticalCenter PI_VerticalTop
+// void  DrawCompString(PIGrCoord x, PIGrCoord y, const char* s, \
+//       const char* s_up, const char* s_dn, unsigned long pos = 0)
+//	Tracé d'une chaîne de caractères "s" avec une partie de texte en exposant "s_up"
+//	et une partie en indice "s_dn". Fonte exposant-indice identique à la fonte
+//	courante.
+//--
+
+/* --Methode-- */
+void 
+PIGraphicGen::DrawCompString(PIGrCoord x, PIGrCoord y, const char* s,
+			     const char* s_up, const char* s_dn, 
+			     PIFont const & fntss, unsigned long pos)
+{
+  if ((s_up == NULL) && (s_dn == NULL)) {
+    if (s != NULL)  DrawString(x,y,s,pos);
+    return;
+  }
+
+  int fh,fas,fds;
+  fh = myFont.GetFontHeight(fas, fds);
+  int sw_s = 0;
+  if (s != NULL) sw_s = myFont.GetStringWidth(s);
+
+  PIFont fnt_save(myFont);
+  PIFont fnt_ss(fntss);
+  fnt_ss.SetFontSzPt(2*myFont.GetFontSize()/3);
+
+  int sw_sup = 0;
+  if (s_up != NULL) sw_sup = fnt_ss.GetStringWidth(s_up);
+  int sw_sdn = 0;
+  if (s_dn != NULL) sw_sdn = fnt_ss.GetStringWidth(s_dn);
+
+  PIGrCoord xs,ys; 
+  int posh = pos & PI_HorizontalPosition;
+  int posv = pos & PI_VerticalPosition;
+
+  int dyu, dyd;
+  dyu = -fh/2;  dyd = fh/2-fh/5; 
+  if (posv == PI_VerticalBaseLine) {
+    dyu = -fh/2;  dyd = fh/2-fh/5; 
+    }
+  else if (posv == PI_VerticalBottom) { 
+    dyu = -fh/2-fds;  dyd = fh/2-fh/5-fds; 
+    }
+  else if (posv == PI_VerticalCenter) {
+    dyu = -fds;  dyd = fh-fh/5-fds; 
+  }
+  else if (posv == PI_VerticalTop) {
+    dyu = fh/2-fds;  dyd = 3*fh/2-fh/5-fds; 
+  }
+
+  int deltaposx = ((fh/8) > 0) ? fh/8 : 1;
+
+
+  if ((pos == 0) || ((posh == PI_HorizontalLeft) && (posv == PI_VerticalBaseLine))) {
+    xs = (int)x+sw_s;
+    if (s != NULL)  DrawString(xs, y, s, PI_HorizontalRight);
+    xs = (int)x+sw_s+deltaposx;
+    ys = (int)y+dyu;
+    SelFont(fnt_ss);
+    if (s_up != NULL) DrawString(xs, ys, s_up, PI_HorizontalLeft);
+    ys = (int)y+dyd;
+    if (s_dn != NULL) DrawString(xs, ys, s_dn, PI_HorizontalLeft);
+  }
+  else {
+    if (posh == PI_HorizontalRight) {
+      int sw_ss_max = ( sw_sup > sw_sdn ) ? sw_sup : sw_sdn;
+      xs = (int)x-sw_ss_max-deltaposx;
+      if (s != NULL)  DrawString(xs, y, s, PI_HorizontalRight | posv);
+      SelFont(fnt_ss);
+      xs = (int)xs+deltaposx;
+      ys = (int)y+dyu;
+      if (s_up != NULL) DrawString(xs, ys, s_up, PI_HorizontalLeft);
+      ys = (int)y+dyd;
+      if (s_dn != NULL) DrawString(xs, ys, s_dn, PI_HorizontalLeft);      
+    }
+    else if (posh == PI_HorizontalCenter) {
+      int sw_tot = sw_sup+sw_sdn+sw_s+deltaposx;
+      xs = (int)x-sw_tot/2+sw_s; 
+      if (s != NULL)  DrawString(xs, y, s, PI_HorizontalRight | posv);
+      SelFont(fnt_ss);
+      xs = (int)xs+deltaposx;
+      ys = (int)y+dyu;
+      if (s_up != NULL) DrawString(xs, ys, s_up, PI_HorizontalLeft);
+      ys = (int)y+dyd;
+      if (s_dn != NULL) DrawString(xs, ys, s_dn, PI_HorizontalLeft);            
+    }
+    else {
+      xs = (int)x+sw_s;
+      if (s != NULL)  DrawString(xs, y, s, PI_HorizontalRight | posv);
+      SelFont(fnt_ss);
+      xs = (int)x+sw_s+deltaposx;
+      ys = (int)y+dyu;
+      if (s_up != NULL) DrawString(xs, ys, s_up, PI_HorizontalLeft);
+      ys = (int)y+dyd;
+      if (s_dn != NULL) DrawString(xs, ys, s_dn, PI_HorizontalLeft);
+    }
+  }
+  SelFont(fnt_save);
+  return;
+}
+
+//++ 
+// Titre	Tracés de lignes et de figures géometriques
+//--
+//++
+// void  DrawLine(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2)
+//	Trace une ligne entre les points de coordonnées "(x1,y1)" et "(x2,y2)", 
+//	en utilisant la couleur d'avant-plan (Foreground)
+// void  DrawBox(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+//	Tracé du contour d'un rectangle défini par la position du coin "(x0,y0)"
+//	et de taille "dx,dy" avec la couleur d'avant-plan.
+// void  DrawFBox(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+//	Tracé d'un rectangle plein, défini par la position du coin "(x0,y0)"
+//	et de taille "dx,dy" avec la couleur d'avant-plan.
+// void  DrawCircle(PIGrCoord x0, PIGrCoord y0, PIGrCoord r)  
+//	Tracé du contour d'un cercle centré en "(x0,y0)", de rayon "r"
+// void  DrawFCircle(PIGrCoord x0, PIGrCoord y0, PIGrCoord r)  
+//	Tracé d'un cercle plein centré en "(x0,y0)", de rayon "r"
+// void  DrawOval(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+//	Tracé d'une ellipse centrée en "(x0,y0)" de demi-axes "dx,dy"
+// void  DrawFOval(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+//	Tracé d'une ellipse pleine centrée en "(x0,y0)" de demi-axes "dx,dy"
+// void  DrawPolygon(PIGrCoord *x, PIGrCoord *y, int n, bool cinc=true)
+//	Tracé du contour d'un polygone défini par le tableau des "n" points "x,y".
+//	Si "cinc==true", les coordonnées seront considérées comme relatives
+//	à la position du point "(x[0], y[0])". Dans le cas contraire, chaque couple
+//	"(x[i], y[i])" représentera les coordonnées absolues d'un coin du polygone.
+// void  DrawFPolygon(PIGrCoord *x, PIGrCoord *y, int n, bool cinc=true)
+//	Tracé d'un polygone plein de la couleur d'avant-plan.
+// void  DrawArc(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy, double degdeb, double degfin)
+//	Tracé d'un arc de cercle ou d'ellipse, centrée en "(x0,y0)" de demi-axes "dx,dy"
+//	L'arc couvre un angle "deltadeg" en degré, et commence au point défini
+//	par l'angle "degdeb". Le sens positif angulaire est celui de la rotation
+//	de l'axe X vers Y. Le point (0,1) a 90 deg. (-1,0) a 180 deg.
+// void  DrawFArc(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy, double degdeb, double degfin)
+//	Tracé d'un arc de cercle ou d'ellipse plein, centrée en "(x0,y0)" de demi-axes "dx,dy"
+//	L'arc couvre un angle "deltadeg" en degré, et commence au point défini
+//	par l'angle "degdeb". Le sens positif angulaire est celui de la rotation
+//	de l'axe X vers Y. Le point (0,1) a 90 deg. (-1,0) a 180 deg.
+//
+// Draw3PtArc(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2, \
+//            PIGrCoord x3, PIGrCoord y3)
+//	Tracé d'un arc de cercle spécifié par trois points "(x1,y1)", "(x2,y2)" et "(x3,y3)"
+// Draw3PtFArc(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2, \
+//             PIGrCoord x3, PIGrCoord y3)
+//	Tracé d'un arc de cercle plein spécifié par trois points "(x1,y1)", "(x2,y2)" et "(x3,y3)"
+//--
+//++
+// ComputeArcFrom3Pt(double x1, double y1, double x2, double y2, \
+//                   double x3, double y3, double& x0, double& y0, 
+//                   double& dx, double& dy, double& degdeb, double& deltadeg)
+//	Calcul des coordonnees du centre, du rayon, ainsi que l'extension
+//	angulaire d'un arc de cercle specifie par trois points. 
+//	*methode statique*
+//--
+
+
+/* --Methode-- */
+void PIGraphicGen::Draw3PtArc(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2,
+			      PIGrCoord x3, PIGrCoord y3)
+  // Trace d'un arc de cercle passant par 3 points
+{
+  double x0, y0;
+  double dx, dy;
+  double degdeb, degfin;
+  int rc;
+  rc = ComputeArcFrom3Pt(x1, y1, x2, y2, x3, y3, x0, y0, dx, dy, degdeb, degfin);
+  if (rc != 0) return;
+  DrawArc(x0, y0, dx, dy, degdeb, degfin);
+}
+
+/* --Methode-- */
+void PIGraphicGen::Draw3PtFArc(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2,
+			       PIGrCoord x3, PIGrCoord y3)
+  // Trace d'un arc de cercle passant par 3 points
+{
+  double x0, y0;
+  double dx, dy;
+  double degdeb, degfin;
+  int rc;
+  rc = ComputeArcFrom3Pt(x1, y1, x2, y2, x3, y3, x0, y0, dx, dy, degdeb, degfin);
+  if (rc != 0) return;
+  DrawFArc(x0, y0, dx, dy, degdeb, degfin);
+}
+
+/* --Methode-- */
+int PIGraphicGen::ComputeArcFrom3Pt(double x1, double y1, double x2, double y2,
+				    double x3, double y3, double& x0, double& y0, 
+				    double& dx, double& dy, double& degdeb, double& deltadeg)
+{
+  x0 = y0 = dx = dy = 0.;
+  degdeb = deltadeg = 0.;
+  double px[2], py[2];
+  //  cout << "DBG - Arc3Pt" << x1 << "," << y1 << " - "
+  //     << x2 << "," << y2 << " - " 
+  //     << x3 << "," << y3 << endl;
+
+  // Milieu de M1-M2
+  px[0] = (x1+x2)*0.5;
+  py[0] = (y1+y2)*0.5;
+  // Milieu de M2-M3
+  px[1] = (x2+x3)*0.5;
+  py[1] = (y2+y3)*0.5;
+  double delx, dely;
+  double a[2], b[2];
+  bool xcst[2];
+  for(int i=0; i<2; i++) {
+    if (i == 0) {
+      delx = x2-x1;
+      dely = y2-y1;
+    }
+    else {
+      delx = x3-x2;
+      dely = y3-y2;
+    }
+    if ((fabs(delx) > PETIT_DBLE) && (fabs(dely) > PETIT_DBLE)) {
+      // Direction perpendiculaire a M1-M2 , M2-M3
+      double alpha = atan2( dely, delx) + M_PI/2.;
+      a[i] = tan(alpha);
+      b[i] = py[i]-a[i]*px[i];
+      xcst[i] = false;
+    }
+    else if (fabs(delx) > PETIT_DBLE) {
+      a[i] = b[i] = px[i];
+      xcst[i] = true;
+    }
+    else if (fabs(dely) > PETIT_DBLE) {
+      a[i] = 0.; b[i] = py[i];
+      xcst[i] = false;
+    }
+    else { 
+      cerr << " PIGraphicGen::ComputeArcFrom3Pt()/Error - delx=" << delx 
+	   << " dely=" << dely << " (=0) for i=" << i << endl;
+      return(1);
+    }
+  }
+  if (xcst[0] && xcst[1]) {
+    cerr << " PIGraphicGen::ComputeArcFrom3Pt()/Error - xcst[0]&&xcst[1]" << endl; 
+    return(2);
+  }
+  double xc,yc;
+  double dela = a[1]-a[0];
+  if (xcst[0] || xcst[1]) {
+    if (xcst[0]) {
+      xc = px[0];  yc = a[1]*xc+b[1];
+    }
+    else {
+      xc = px[1];  yc = a[0]*xc+b[0];
+    }
+  }
+  else {
+    if (fabs(dela) < PETIT_DBLE) {
+      cerr << " PIGraphicGen::ComputeArcFrom3Pt()/Error - a[1]-a[0]=" << dela << " a[0]=" << a[0] << " a[1]=" << a[1] << endl; 
+      return(3);    
+    }
+    xc = (b[0]-b[1])/dela;  yc = a[0]*xc+b[0];
+  }
+  delx = x1-xc; 
+  dely = y1-yc; 
+  double r = sqrt(delx*delx+dely*dely);
+  double ang1 = atan2(dely, delx);
+  double delx2 = x3-xc; 
+  double dely2 = y3-yc; 
+  double ang2 = atan2(dely2, delx2);
+  // angle M1-O-M3 : Produit scalaire OM1 . OM3 
+  double cda = (delx*delx2+dely*dely2)/sqrt(delx*delx+dely*dely)/sqrt(delx2*delx2+dely2*dely2);
+  double dang = acos(cda);
+  double sda = 0.;
+  double daopi = 1;
+  if (fabs(dang-M_PI) < 1.e-19) {
+    delx2 = x2-xc;
+    dely2 = y2-yc;
+  // angle M1-O-M2 : Produit vectoriel OM1 X OM2 - Signe de l'angle deltaAngle
+    sda = (delx*dely2-dely*delx2);
+  }
+  else {
+  // angle M1-O-M3 : Produit vectoriel OM1 X OM3 - Signe de l'angle deltaAngle
+    sda = (delx*dely2-dely*delx2);
+  // Produit scalaire (OM1 + OM3) . OM2 : deltaAngle ou 2*PI-DeltaAngle
+    delx = (x1+x3)-2*xc; 
+    dely = (y1+y3)-2*yc;
+    daopi = (delx*delx2+dely*dely2)/sqrt(delx*delx+dely*dely)
+                                   /sqrt(delx2*delx2+dely2*dely2);
+  }
+  if (sda >= 0.) {
+    if (daopi < 0.) { 
+      degdeb = ang2*180./M_PI;    
+      deltadeg = (360.-dang*180./M_PI);
+    }
+    else {
+      degdeb = ang1*180./M_PI;    
+      deltadeg = dang*180./M_PI;
+    }
+  }
+  else {
+    if (daopi < 0.) { 
+      degdeb = ang1*180./M_PI;    
+      deltadeg = (360.-dang*180./M_PI);
+    }
+    else {
+      degdeb = ang2*180./M_PI;    
+      deltadeg = dang*180./M_PI;
+    }
+  }
+  while (degdeb < 0.) degdeb += 360.;
+  while (degdeb > 360.) degdeb -= 360.;
+  x0 = xc;
+  y0 = yc;
+  dx = dy = r;
+  //  cout << "DBG - Arc3Pt-2  " << xc << "," << yc << " R=" << r << " deg= "
+  //       << degdeb << " Delta= " << deltadeg << endl;
+  return(0);
+}
+
+//++ 
+// Titre	Tracés de signes et de flèches
+//--
+//++
+// void  DrawMarker(PIGrCoord x0, PIGrCoord y0)  
+//	Tracé d'un signe au point "(x0,y0)". Le choix du signe tracé s'effectue
+//	à travers la méthode "SelMarker()"
+// void  DrawMarkers(PIGrCoord *x, PIGrCoord *y, int n)
+//	Tracé de "n" signes aux points "(x[i],y[i])"
+// void DrawArrowMarker(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2, \
+//      bool fgline=true)
+//	Tracé d'un signe de type flèche orienté selon la droite "x1,y1" -> "x2,y2".
+//	Si "fgline==true", la ligne "(x1,y1) (x2,y2)" est aussi tracée.
+//--
+
+/* --Methode-- */
+void 
+PIGraphicGen::DrawArrowMarker(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2, bool fgline)
+{
+  double dx = (double)x2-(double)x1;
+  double dy = (double)y2-(double)y1;
+  double theta = atan2(dy, dx);
+
+  PIGrCoord x[5], y[5];
+  PIGrCoord x2l, y2l;
+  bool fgfill = false;
+  int npt = 3;
+  double t0,tp,tm,asz;
+
+  switch (myArrowMrk) {
+
+  case PI_BasicArrowMarker :
+    t0 = M_PI/4.;
+    asz = (double)myArrowMrkSz/cos(t0);
+    tp = theta+0.75*M_PI;
+    tm = theta-0.75*M_PI;
+    x[0] = (double)x2 + cos(tp)*asz;
+    y[0] = (double)y2 + sin(tp)*asz;
+    x[1] = x2;
+    y[1] = y2;
+    x[2] = (double)x2 + cos(tm)*asz;
+    y[2] = (double)y2 + sin(tm)*asz;
+    x2l = x2;  y2l =y2;
+    fgfill = false;
+    npt = 3;
+    break;
+
+  case PI_TriangleArrowMarker :
+  case PI_FTriangleArrowMarker :
+    t0 = M_PI/6.;
+    asz = (double)myArrowMrkSz/cos(t0);
+    tp = theta+5.*M_PI/6.;
+    tm = theta-5.*M_PI/6.;
+    x[0] = (double)x2 + cos(tp)*asz;
+    y[0] = (double)y2 + sin(tp)*asz;
+    x[1] = x2;
+    y[1] = y2;
+    x[2] = (double)x2 + cos(tm)*asz;
+    y[2] = (double)y2 + sin(tm)*asz;
+    x[3] = x[0];
+    y[3] = y[0];
+    x2l = (double)x2 - cos(theta)*myArrowMrkSz;
+    y2l = (double)y2 - sin(theta)*myArrowMrkSz;
+    npt = 4;
+    if (myArrowMrk == PI_FTriangleArrowMarker)  fgfill = true;
+    else  fgfill = false;
+    break;
+
+  case PI_ArrowShapedArrowMarker :
+  case PI_FArrowShapedArrowMarker :
+    t0 = M_PI/8.;
+    asz = 2.*(double)myArrowMrkSz*cos(t0);
+    tp = theta+7.*M_PI/8.;
+    tm = theta-7.*M_PI/8.;
+    x2l = (double)x2 - cos(theta)*myArrowMrkSz;
+    y2l = (double)y2 - sin(theta)*myArrowMrkSz;
+    x[0] = x2;  
+    y[0] = y2;
+    x[1] = (double)x2 + cos(tp)*asz;
+    y[1] = (double)y2 + sin(tp)*asz;
+    x[2] = x2l;
+    y[2] = y2l;
+    x[3] = (double)x2 + cos(tm)*asz;
+    y[3] = (double)y2 + sin(tm)*asz;
+    x[4] = x[0];
+    y[4] = y[0];
+    npt = 5;
+    if (myArrowMrk == PI_FArrowShapedArrowMarker)  fgfill = true;
+    else  fgfill = false;
+    break;
+    
+  default:
+    t0 = M_PI/4.;
+    asz = (double)myArrowMrkSz/cos(t0);
+    tp = theta+5.*M_PI/4.;
+    tm = theta-5.*M_PI/4.;
+
+    x[0] = (double)x2 + cos(tp)*asz;
+    y[0] = (double)y2 + sin(tp)*asz;
+    x[1] = x2;
+    y[1] = y2;
+    x[2] = (double)x2 + cos(tm)*asz;
+    y[2] = (double)y2 + sin(tm)*asz;
+    x[3] = x[0];
+    y[3] = y[0];
+    x2l = x2;  y2l =y2;
+    fgfill = false;
+    npt = 3;
+    break;
+  }
+
+  if (fgline)  DrawLine(x1, y1, x2l, y2l);
+
+  if (fgfill)  DrawFPolygon(x, y, npt, false);
+  else  DrawPolygon(x, y, npt, false);
+}
+
+//++
+// Titre	Tracé d'images (pixmap)
+//--
+//++
+// void  DrawPixmap(PIGrCoord x, PIGrCoord y, unsigned char *pix, int sx, int sy, PIColorMap* cmap)
+//	Tracé d'un pixmap dans un rectangle positionné en "(x,y)". Le tableau des pixels
+//	"pix", de taille "sx,sy" représente les index dans la table de couleur "cmap".
+//--
+
+//++
+// Titre	Modifications des attributs graphiques	
+//--
+//++
+// void  SelForeground(PIColors col=PI_Black)
+//	Choix de la couleur de tracé d'avant-plan
+//|	PI_Black , PI_White,  PI_Grey , PI_Red , PI_Blue , PI_Green ,  
+//|	PI_Yellow , PI_Magenta , PI_Cyan , PI_Turquoise , PI_NavyBlue , 
+//|	PI_Orange , PI_SiennaRed , PI_Purple , PI_LimeGreen , PI_Gold ,
+//|	PI_ColorAllBits0 , PI_ColorAllBits1
+// void  SelBackground(PIColors col=PI_White)
+//	Choix de la couleur d'arrière-plan
+// void  SelForeground(PIColorMap& cmap, int cid) 
+//	Choix de la couleur de tracé d'avant-plan: Couleur numéro "cid" de la table de couleur "cmap"
+// void  SelBackground(PIColorMap& cmap, int cid)
+//	Choix de la couleur d'arrière-plan: Couleur numéro "cid" de la table de couleur "cmap"
+// void  SelGOMode(PIGOMode mod=PI_GOCopy) 
+//	Choix du mode de tracé graphique: "PI_GOCopy" ou "PI_GOXOR" ou 	"PI_GOInvert"
+// void  SelLine(PILineAtt att=PI_NormalLine)
+//	Choix du type de ligne pour le tracé des lignes et contours
+//|	PI_NormalLine, PI_ThinLine , PI_ThickLine
+//|	PI_DashedLine, PI_ThinDashedLine, PI_ThickDashedLine
+//|	PI_DottedLine, PI_ThinDottedLine, PI_ThickDottedLine
+// void  SelMarker(int msz=3, PIMarker mrk=PI_DotMarker) 
+//	Choix de la taille et du type de signe pour "DrawMarker() / DrawMarkers()"
+//|	PI_DotMarker , PI_PlusMarker , PI_CrossMarker
+//|	PI_CircleMarker , PI_FCircleMarker
+//|	PI_BoxMarker , PI_FBoxMarker
+//|	PI_TriangleMarker , PI_FTriangleMarker
+//|	PI_StarMarker , PI_FStarMarker
+// void  SelArrowMarker(int arrsz=5, PIArrowMarker arrmrk=PI_BasicArrowMarker)
+//	Choix de la taille et du type de flèches.
+//|	PI_NotDefArrowMarker , PI_BasicArrowMarker
+//|	PI_TriangleArrowMarker , PI_FTriangleArrowMarker
+//|	PI_ArrowShapedArrowMarker , PI_FArrowShapedArrowMarker
+//--
+
+//++
+// Titre	Changement de fontes
+//--
+//++
+// void  SelFont(PIFont & fnt)
+//	Choix de fonte courant.
+// void  SelFont(PIFontSize sz=PI_NormalSizeFont, PIFontAtt att=PI_RomanFont)
+//	Changement de taille et attribut de fonte
+//|	PI_TinySizeFont, PI_SmallSizeFont , PI_NormalSizeFont 
+//|	PI_BigSizeFont, PI_VeryLargeSizeFont , PI_HugeSizeFont
+//|	PI_RomanFont , PI_BoldFont 
+//|	PI_ItalicFont , PI_BoldItalicFont
+// void  SelFontSzPt(int npt=12, PIFontAtt att=PI_RomanFont)
+//	Choix de taille de fonte avec spécification de taille en points 
+//	(pixels sur l'écran)
+// 
+//--
+
+void
+PIGraphicGen::SelArrowMarker(int arrsz, PIArrowMarker arrmrk)
+{
+  if (arrsz > 0) myArrowMrkSz = arrsz;
+  myArrowMrk = arrmrk;
+}
+
+//++
+// Titre	Sélection de la zone de tracé (clip)	
+//--
+//++
+// void  SetClipRectangle(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+//	Limite la zone de tracé permise au rectangle "(x0,y0)", "dx,dy"
+// void  ClearClipRectangle() 
+//	Supprime si nécéssaire la limitation de la zone de tracé.	
+//--
+
+//++
+// Titre	Accès aux attributs graphiques
+//--
+//++
+// PIColors  GetForeground()
+//	Renvoie la couleur de tracé d'avant-plan courante. 
+//	("PI_ColorFromMap" si défini à partir d'une table de couleur
+// PIColors  GetBackground()
+//	Renvoie la couleur d'arrière-plan courante.
+// PIGOMode  GetGOMode()
+//	Renvoie le mode de tracé graphique courante.
+// PIFontAtt GetFontAtt()
+//	Renvoie les attributs de la fonte courante.
+// int GetFontSize() 
+//	Renvoie la taille de la fonte courante.
+// PILineAtt GetLineAtt() 
+//	Renvoie le type de ligne courant
+// PIMarker  GetMarker() 
+//	Renvoie le type de signe (Marker) courant
+// int GetMarkerSize()
+//	Renvoie la taille des signes (Marker) pour le marker courant
+// PIFont  GetFont()
+//	Retourne une copie de l'objet "PIFont" courant.
+// PIGrCoord  GetFontHeight(PIGrCoord& asc, PIGrCoord& desc);
+//	Renvoie la hauteur des caractères, ainsi que la taille au dessus
+//	et en-dessous de la ligne de base ("asc , desc") pour la fonte courante
+//	dans le système de coordonnées courant (Fenêtre ou UC).
+// PIGrCoord CalcStringWidth(char const* s)
+//	Renvoie la largeur occupé par un texte s'il était affiché dans le 
+//	système de coordonnées courant (Fenêtre ou UC).
+// bool  CalcStringPositionShift(char const* s, unsigned long pos, \
+//       int& dx, int& dy)
+//	Renvoie le shift de position compte tenu du flag de positionnement "pos"
+//--
+
+/* --Methode-- */
+PIArrowMarker PIGraphicGen::GetArrowMarker()
+{
+  return(myArrowMrk);
+}
+
+/* --Methode-- */
+int PIGraphicGen::GetArrowMarkerSize()
+{
+  return(myArrowMrkSz);
+}
+
+/* --Methode-- */
+PIGrCoord PIGraphicGen::GetFontHeight(PIGrCoord& asc, PIGrCoord& desc)
+{
+int t,a,d;
+t = myFont.GetFontHeight(a, d);
+asc = a;   desc = d;
+return(t);
+}
+
+/* --Methode-- */
+PIGrCoord PIGraphicGen::CalcStringWidth(char const* s)
+{
+return (myFont.GetStringWidth(s));
+}
+
+/* --Methode-- */
+bool PIGraphicGen::CalcStringPositionShift(char const* s, unsigned long pos, 
+					   int& dx, int& dy)
+{
+  dx = 0;
+  dy = 0;
+  if (pos == 0) return(false);
+  else {
+    int posh = pos & PI_HorizontalPosition;
+    int posv = pos & PI_VerticalPosition;
+    if ( ((posh == 0) &&  (posv == PI_VerticalBaseLine)) || 
+	 ((posh == PI_HorizontalLeft) && (posv == 0)) ||
+	 ((posh == PI_HorizontalLeft) && (posv == PI_VerticalBaseLine)) )
+      return(false);
+    if (posh != PI_HorizontalLeft) {
+      int wx = myFont.GetStringWidth(s);
+      if (posh == PI_HorizontalCenter)  dx = wx/2;
+      else if (posh == PI_HorizontalRight)  dx = wx;
+      else wx = 0;
+    }
+    if (posv != PI_VerticalBaseLine) {
+      int asc,desc;
+      int wy = myFont.GetFontHeight(asc, desc);
+      if (posv == PI_VerticalBottom) dy = desc;
+      else if (posv == PI_VerticalCenter)  dy = -wy/2+desc;
+      else if (posv == PI_VerticalTop)  dy = -wy+desc;
+      else dy = 0;
+    }
+    return(true);
+  }
+}
+
+
+//++
+// Titre	Sauvegarde et rappel des attributs graphiques
+//--
+//++
+// void  SaveGraphicAtt()
+//	Sauvegarde des attributs graphiques courants
+// void  RestoreGraphicAtt()
+//	Utilisation de l'ensemble des attributs graphiques sauvegardés par un appel
+//	à "SaveGraphicAtt()"
+//--
+
+
+/* --Methode-- */
+void PIGraphicGen::SaveGraphicAtt()
+{
+  sFCol = GetForeground();
+  sBCol = GetBackground();
+  sGOm = GetGOMode();
+  sFont = GetFont();   
+  sLAtt = GetLineAtt();
+  sMrk = GetMarker();   
+  sMrkSz = GetMarkerSize();
+  sArrowMrk = GetArrowMarker();
+  sArrowMrkSz = GetArrowMarkerSize();
+  return;
+}
+
+/* --Methode-- */
+void PIGraphicGen::RestoreGraphicAtt()
+{
+  SelForeground(sFCol);
+  SelBackground(sBCol);
+  SelGOMode(sGOm);
+  SelFont(sFont);
+  SelLine(sLAtt);
+  SelMarker(sMrkSz, sMrk);
+  SelArrowMarker(sArrowMrkSz, sArrowMrk);
+  return;
+}
+
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/pigraphgen.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pigraphgen.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pigraphgen.h	(revision 2309)
@@ -0,0 +1,198 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive     PIGraphic 
+// Primitives de trace graphiques    R. Ansari  97
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PIGRAPHICGEN_H_SEEN
+#define PIGRAPHICGEN_H_SEEN
+
+#include "pisysdep.h"
+
+#include PIWDG_H
+#include PICMAP_H
+#include PIFONT_H
+
+#include "picolist.h"  // enum PIColors
+#include "pigrcoord.h"  // Class PIGrCoord
+
+#include "pilineatt.h"  // Class PILineAtt
+
+
+// Marker types
+enum PIMarker  { PI_NotDefMarker = -1,
+                 PI_DotMarker = 0, PI_PlusMarker=1, PI_CrossMarker=2,  
+                 PI_CircleMarker=3, PI_FCircleMarker=4,
+                 PI_BoxMarker=5, PI_FBoxMarker=6,
+                 PI_TriangleMarker=7, PI_FTriangleMarker=8,
+                 PI_StarMarker=9, PI_FStarMarker=10 };
+
+// ArrowMarker types (oriented markers)
+enum PIArrowMarker { PI_NotDefArrowMarker, PI_BasicArrowMarker, 
+		     PI_TriangleArrowMarker, PI_FTriangleArrowMarker,
+		     PI_ArrowShapedArrowMarker, PI_FArrowShapedArrowMarker };
+
+// Flag de positionnement 
+enum PIGrPosHorizontal // Flags de positionnement horizontal
+// PI_HorizontalPosition regroupe l'ensemble des bits utilisables
+     { PI_HorizontalLeft = 0x1, PI_HorizontalCenter = 0x2, 		 
+       PI_HorizontalRight = 0x3, PI_HorizontalPosition = 0xF };
+
+enum PIGrPosVertical  // Flags de positionnement vertical
+// PI_VerticalPosition regroupe l'ensemble des bits utilisables
+     { PI_VerticalBottom = 0x10, PI_VerticalBaseLine = 0x20, 
+       PI_VerticalCenter = 0x30, PI_VerticalTop = 0x40, 
+       PI_VerticalPosition = 0xF0 };
+
+// Orientation de trace de chaines 
+enum PIGrTextDirection  
+     { PI_TextDirectionHorizontal = 0, 
+       PI_TextDirectionVerticalUp = 0x100,
+       PI_TextDirectionVerticalDown = 0x200,
+       PI_TextDirection = 0xF00};
+
+// Les differents modes de trace graphique disponible
+enum PIGOMode { PI_GOCopy = 0, PI_GOXOR = 1, PI_GOInvert = 2 }; 
+
+
+
+// Les differents types de classes PIGraphic
+enum PIGraphicsType { PI_UnknownGraphics = 0, 
+                      PI_ScrWindowGraphics = 2, PI_ScrBufferGraphics = 3, 
+                      PI_PSFileGraphics = 8, 
+                      PI_UCGraphics = 32, PI_3DGraphics = 36 };
+
+// Classe generique de trace graphique de base :
+
+class PIGraphicGen
+{
+public:
+                     PIGraphicGen();
+                     PIGraphicGen(PIWdg* wdg);
+                     PIGraphicGen(PIScreenBuffer* grb);
+  virtual           ~PIGraphicGen();
+
+  virtual int        kind();
+
+//  Espace des coordonnees
+  virtual void       GetGrSpace(PIGrCoord& xmin, PIGrCoord& xmax, PIGrCoord& ymin, PIGrCoord& ymax); 
+
+//  Trace graphiques
+  virtual void       Erase(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)     = 0;
+
+  virtual void       DrawString(PIGrCoord x, PIGrCoord y, const char* s, unsigned long pos = 0) = 0;
+  virtual void       DrawOpaqueString(PIGrCoord x, PIGrCoord y, const char* s, unsigned long pos = 0) = 0;
+  virtual void       DrawCompString(PIGrCoord x, PIGrCoord y, const char* s, 
+                                    const char* s_up, const char* s_dn, 
+				    PIFont const & fntss, unsigned long pos = 0);
+  inline  void       DrawCompString(PIGrCoord x, PIGrCoord y, const char* s, 
+                                    const char* s_up, const char* s_dn, 
+				    unsigned long pos = 0)
+                     { DrawCompString(x, y, s, s_up, s_dn, GetFont(), pos); }
+
+  virtual void       DrawLine(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2)  = 0;
+  virtual void       DrawBox(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)   = 0;
+  virtual void       DrawFBox(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)  = 0;
+  virtual void       DrawCircle(PIGrCoord x0, PIGrCoord y0, PIGrCoord r)               = 0;
+  virtual void       DrawFCircle(PIGrCoord x0, PIGrCoord y0, PIGrCoord r)              = 0;
+  virtual void       DrawOval(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)  = 0;
+  virtual void       DrawFOval(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy) = 0;
+  virtual void       DrawPolygon(PIGrCoord *x, PIGrCoord *y, int n, bool cinc=true)    = 0;  
+  virtual void       DrawFPolygon(PIGrCoord *x, PIGrCoord *y, int n, bool cinc=true)   = 0;  
+  virtual void       DrawArc(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy,
+                             double degdeb, double deltadeg)                           = 0;
+  virtual void       DrawFArc(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy, 
+                              double degdeb, double deltadeg)                          = 0;
+
+  virtual void       Draw3PtArc(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2,
+				PIGrCoord x3, PIGrCoord y3);
+  virtual void       Draw3PtFArc(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2,
+				 PIGrCoord x3, PIGrCoord y3);
+  static  int        ComputeArcFrom3Pt(double x1, double y1, double x2, double y2,
+				       double x3, double y3, double& x0, double& y0, 
+				       double& dx, double& dy, double& degdeb, double& degfin);
+ 
+
+  virtual void       DrawMarker(PIGrCoord x0, PIGrCoord y0)                            = 0;
+  virtual void       DrawMarkers(PIGrCoord *x, PIGrCoord *y, int n)                    = 0;
+  virtual void       DrawArrowMarker(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2, 
+				     bool fgline=true);
+
+  virtual void       DrawPixmap(PIGrCoord x, PIGrCoord y, unsigned char *pix, 
+                                int sx, int sy, PIColorMap* cmap)              = 0;
+
+// Modifications attributs graphiques
+  virtual void       SelForeground(PIColors col=PI_Black)                      = 0;
+  virtual void       SelBackground(PIColors col=PI_White)                      = 0;
+  virtual void       SelForeground(PIColorMap& cmap, int cid)                  = 0;
+  virtual void       SelBackground(PIColorMap& cmap, int cid)                  = 0;
+  virtual void       SelGOMode(PIGOMode mod=PI_GOCopy)                         = 0;
+  virtual void       SelLine(PILineAtt const& att)                             = 0;
+  inline  void       SelLine(PILineTypes lt=PI_NormalLine) 
+                             { SelLine(PILineAtt(lt)); }
+  virtual void       SelMarker(int msz=3, PIMarker mrk=PI_DotMarker)           = 0;
+  virtual void       SelArrowMarker(int arrsz=5, 
+                                    PIArrowMarker arrmrk=PI_BasicArrowMarker);
+
+  inline  void       LockForegroundColor() { myLockFCol = true; }
+  inline  void       UnLockForegroundColor() { myLockFCol = false; }
+
+// Modifications de fonte
+  virtual void	     SelFont(PIFont & fnt)				       = 0; 
+  virtual void       SelFont(PIFontSize sz=PI_NormalSizeFont, 
+                             PIFontAtt att=PI_RomanFont)		       = 0;
+  virtual void       SelFontSzPt(int npt=12, PIFontAtt att=PI_RomanFont)       = 0; 
+
+// Selection de zone de trace (clip)
+  virtual void       SetClipRectangle(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)  = 0;
+  virtual void       ClearClipRectangle()                                      = 0;
+
+// Acces aux attributs graphiques 
+  virtual PIColors   GetForeground()    = 0;
+  virtual PIColors   GetBackground()    = 0;
+  virtual PIGOMode   GetGOMode()        = 0;
+  virtual PILineAtt  GetLineAtt()       = 0;
+  virtual PIMarker   GetMarker()        = 0;
+  virtual int        GetMarkerSize()    = 0;
+  virtual PIArrowMarker    GetArrowMarker();
+  virtual int        GetArrowMarkerSize();
+
+// Acces a la fonte et ses attributs
+  inline  PIFont     GetFont() { return (myFont) ; }
+  virtual PIGrCoord  GetFontHeight(PIGrCoord& asc, PIGrCoord& desc);
+  virtual PIGrCoord  CalcStringWidth(char const* s);
+  virtual bool       CalcStringPositionShift(char const* s, unsigned long pos,  
+					     int& dx, int& dy);
+
+// Sauvegarde des attributs graphiques 
+  virtual void       SaveGraphicAtt();
+  virtual void       RestoreGraphicAtt();
+
+protected:
+// Pour Save/Restore des attributs graphiques 
+  PIWdg* myWdg;
+  PIScreenBuffer* myGrb;
+
+  PIFont myFont;
+  PIArrowMarker myArrowMrk;
+  int myArrowMrkSz;
+  PIColors  sFCol, sBCol;
+  PIGOMode sGOm;
+  PIFont sFont;
+  PILineAtt sLAtt;
+  int sFSize;
+  PIMarker sMrk;
+  int sMrkSz;
+  PIArrowMarker sArrowMrk;
+  int sArrowMrkSz;
+  bool myLockFCol;
+};
+
+typedef PIGraphicGen PIGraphic;
+
+// hierarchie apparente
+//   PIGraphic               ( == Gen, mais pas visible de l'utilisateur).
+//     PIGraphicWin   ( == X ou Mac)
+//     PIGraphicPS
+//     PIGraphicUC
+
+#endif      // PIGRAPHGEN_H_SEEN
Index: /tags/V_Dec2002/SophyaPI/PI/pigraphics.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pigraphics.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pigraphics.h	(revision 2309)
@@ -0,0 +1,16 @@
+PIGraphics : = 0 sauf save et restore a reprendre de pibwdggen.cc
+
+Toutes methodes de trace et de selection.
+kind : retourne window, ps ou autre
+
+constructeur sans argument.
+
+->  PIGraphicsWinGen     rien de plus  sauf kind = window
+           constructeur prend un PIWdg
+     -> PIGraphicsWinMac 
+     -> PIGraphicsWinX
+
+->  PIGraphicsPS -> constructeur accepte un PSFile.
+
+
+=> toutes coords en float dans les draw
Index: /tags/V_Dec2002/SophyaPI/PI/pigraphmac.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pigraphmac.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pigraphmac.cc	(revision 2309)
@@ -0,0 +1,525 @@
+#include <stdio.h>
+
+#include "pigraphmac.h"
+#include "UDrawingState.h"
+
+
+
+// #define DEBUG_PIBWDGX     Flag pour impression de debug etc ...
+
+/* --Methode-- */
+PIGraphicMac::PIGraphicMac(PIWdg* wdg)
+: PIGraphicGen(wdg)
+{
+  mPane = wdg->mPane;
+}
+
+/* --Methode-- */
+PIGraphicMac::~PIGraphicMac()
+{
+}
+
+/* --Methode-- */
+void PIGraphicMac::Erase(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+{
+  if (mPane->FocusDraw()) {
+    Rect theRect = {(int)y0, (int)x0, (int)y0+(int)dy, (int)x0+(int)dx};
+    ::EraseRect(&theRect);
+  }
+}
+
+/* --Methode-- */
+void PIGraphicMac::DrawString(PIGrCoord x, PIGrCoord y, char const* s, int /*pos*/)
+{
+  if (!mPane->FocusDraw()) {
+    ::MoveTo(x, y);
+    LStr255 ps = s;
+    StTextState saver;
+    myFont.Apply();
+    ::DrawString(ps);
+  }
+}
+
+/* --Methode-- */
+void PIGraphicMac::DrawOpaqueString(PIGrCoord x, PIGrCoord y, char const* s, int /*pos*/)
+{
+  if (mPane->FocusDraw()) {
+    ::MoveTo(x, y);
+    LStr255 ps = s;
+    StTextState saver;
+    myFont.Apply();
+	Rect box;
+	box.left = x;
+	box.bottom = y;
+	int iWidth = TextWidth(s,0,strlen(s));
+	box.right = box.left + iWidth;
+	int z;
+	box.top = box.bottom + myFont.GetFontHeight(z,z);
+    ::TETextBox(s,strlen(s),&box,teForceLeft);
+  }
+}
+
+ 
+/* --Methode-- */
+void PIGraphicMac::DrawLine(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2)
+{
+  if (mPane->FocusDraw()) {
+    ::MoveTo(x1,y1);
+    ::LineTo(x2,y2);
+  }
+}
+
+
+/* --Methode-- */
+void PIGraphicMac::DrawBox(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+{
+  if (mPane->FocusDraw()) {
+    Rect r = {y0, x0, (int)y0+(int)dy, (int)x0+(int)dx};
+    if (r.top  > r.bottom) swap(r.top,  r.bottom);
+    if (r.left > r.right)  swap(r.left, r.right);
+    r.right++; r.bottom++;
+    ::FrameRect(&r);
+  }
+}
+
+/* --Methode-- */
+void PIGraphicMac::DrawFBox(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+{
+  if (mPane->FocusDraw()) {
+    Rect r = {y0, x0, (int)y0+(int)dy, (int)x0+(int)dx};
+    if (r.top  > r.bottom) swap(r.top,  r.bottom);
+    if (r.left > r.right)  swap(r.left, r.right);
+    r.right++; r.bottom++;
+    ::PaintRect(&r);
+  }
+}
+
+/* --Methode-- */
+void PIGraphicMac::DrawCircle(PIGrCoord x0, PIGrCoord y0, PIGrCoord r)
+{
+  if (mPane->FocusDraw()) {
+    Rect rr = {(int)y0-(int)r, (int)x0-(int)r, (int)y0+(int)r, (int)x0+(int)r};
+    if (rr.top  > rr.bottom) swap(rr.top,  rr.bottom);
+    if (rr.left > rr.right)  swap(rr.left, rr.right);
+    ::FrameOval(&rr);
+  }
+}
+
+/* --Methode-- */
+void PIGraphicMac::DrawFCircle(PIGrCoord x0, PIGrCoord y0, PIGrCoord r)
+{
+  if (mPane->FocusDraw()) {
+    Rect rr = {(int)y0-(int)r, (int)x0-(int)r, (int)y0+(int)r, (int)x0+(int)r};
+    if (rr.top  > rr.bottom) swap(rr.top,  rr.bottom);
+    if (rr.left > rr.right)  swap(rr.left, rr.right);
+    ::PaintOval(&rr);
+  }
+}
+
+/* --Methode-- */
+void PIGraphicMac::DrawOval(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+{
+  if (mPane->FocusDraw()) {
+    Rect rr = {(int)y0-(int)dy, (int)x0-(int)dx, (int)y0+(int)dy, (int)x0+(int)dx};
+    if (rr.top  > rr.bottom) swap(rr.top,  rr.bottom);
+    if (rr.left > rr.right)  swap(rr.left, rr.right);
+    ::FrameOval(&rr);
+  }
+}
+
+/* --Methode-- */
+void PIGraphicMac::DrawFOval(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+{
+  if (mPane->FocusDraw()) {
+    Rect rr = {(int)y0-(int)dy, (int)x0-(int)dx, (int)y0+(int)dy, (int)x0+(int)dx};
+    if (rr.top  > rr.bottom) swap(rr.top,  rr.bottom);
+    if (rr.left > rr.right)  swap(rr.left, rr.right);
+    ::PaintOval(&rr);
+  }
+}
+
+
+/* --Methode-- */
+void PIGraphicMac::DrawPolygon(PIGrCoord *x, PIGrCoord *y, int n, bool cinc)
+{
+  PolyHandle h = MakePoly(x,y,n);
+  if (h) {
+    ::FramePoly(h);
+    ::KillPoly(h);
+  }
+  
+}
+
+/* --Methode-- */
+void PIGraphicMac::DrawFPolygon(PIGrCoord *x, PIGrCoord *y, int n, bool cinc)
+{
+  PolyHandle h = MakePoly(x,y,n);
+  if (h) {
+    ::PaintPoly(h);
+    ::KillPoly(h);
+  }
+}
+
+
+/* --Methode-- */
+void PIGraphicMac::DrawArc(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy, 
+                         double degdeb, double deltadeg)
+{
+  if (mPane->FocusDraw()) {
+    Rect rr = {(int)y0-(int)dy, (int)x0-(int)dx, (int)y0+(int)dy, (int)x0+(int)dx};
+    if (rr.top  > rr.bottom) swap(rr.top,  rr.bottom);
+    if (rr.left > rr.right)  swap(rr.left, rr.right);
+    ::FrameArc(&rr, degdeb, deltadeg);
+  }
+}
+
+/* --Methode-- */
+void PIGraphicMac::DrawFArc(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy, 
+                         double degdeb, double deltadeg)
+{
+  if (mPane->FocusDraw()) {
+    Rect rr = {(int)y0-(int)dy, (int)x0-(int)dx, (int)y0+(int)dy, (int)x0+(int)dx};
+    if (rr.top  > rr.bottom) swap(rr.top,  rr.bottom);
+    if (rr.left > rr.right)  swap(rr.left, rr.right);
+    ::PaintArc(&rr, degdeb, deltadeg);
+  }
+}
+
+
+/* --Methode-- */
+PolyHandle PIGraphicMac::MakePoly(PIGrCoord *x, PIGrCoord *y, int n)
+{
+  if (mPane->FocusDraw()) {
+    PolyHandle h = ::OpenPoly();
+    ::MoveTo(x[0], y[0]);
+    for (int i=1; i<n; i++) {
+      ::LineTo(x[i], y[i]);
+    }
+    ::MoveTo(x[0], y[0]);
+    ClosePoly();
+    return h;
+  }
+  return NULL;
+}
+
+
+/* --Methode-- */
+void PIGraphicMac::DrawMarker(PIGrCoord x0, PIGrCoord y0)
+{
+int hmsz = mMrkSz/2;
+int dmsz = mMrkSz-hmsz;
+PIGrCoord x[4],y[4];
+PILineAtt clatt;
+
+if (mMrk == PI_DotMarker) {
+  ::MoveTo( x0, y0);
+  ::Line(0,0);
+}
+
+else
+  {
+  clatt = mLAtt;
+  SelLine(PI_ThinLine);
+  switch (mMrk)
+    {
+    case  PI_PlusMarker :
+      DrawLine((int)x0-hmsz, y0, (int)x0+dmsz, y0);
+      DrawLine(x0, (int)y0-hmsz, x0, (int)y0+dmsz);
+      break;
+    case  PI_CrossMarker :
+      DrawLine((int)x0-hmsz, (int)y0-hmsz, (int)x0+dmsz, (int)y0+dmsz);
+      DrawLine((int)x0-hmsz, (int)y0+dmsz, (int)x0+dmsz, (int)y0-hmsz);
+      break;  
+    case PI_CircleMarker :
+      DrawCircle(x0, y0, hmsz);
+      break;
+    case PI_FCircleMarker :
+      DrawFCircle(x0, y0, hmsz);
+      break;
+    case PI_BoxMarker :
+      DrawBox((int)x0-hmsz, (int)y0-hmsz, mMrkSz, mMrkSz);
+      break;
+    case PI_FBoxMarker :
+      DrawFBox((int)x0-hmsz, (int)y0-hmsz, mMrkSz, mMrkSz);
+      break;
+    case  PI_TriangleMarker :
+      x[1] = mMrkSz; y[1] = 0; x[2] = -hmsz; y[2] = -mMrkSz; 
+      x[3] = -dmsz; y[3] = +mMrkSz; x[0] = (int)x0-hmsz; y[0] = (int)y0+hmsz;  
+      DrawPolygon(x, y, 4);
+      break;
+    case  PI_FTriangleMarker :
+      x[1] = mMrkSz; y[1] = 0; x[2] = -hmsz; y[2] = -mMrkSz; 
+      x[3] = -dmsz; y[3] = +mMrkSz; x[0] = (int)x0-hmsz; y[0] = (int)y0+hmsz;  
+      DrawFPolygon(x, y, 4);
+      break;
+    default :
+      ::MoveTo( x0, y0);
+      ::Line(0,0);
+      break;
+    }
+  SelLine(clatt);
+  }
+return;
+}
+
+/* --Methode-- */
+void PIGraphicMac::DrawMarkers(PIGrCoord *x, PIGrCoord *y, int n)
+{
+int i;
+
+if (n <= 0)  return;
+for(i=0; i<n; i++) DrawMarker(x[i], y[i]);
+}
+
+
+/* --Methode-- */
+void PIGraphicMac::DrawPixmap(PIGrCoord x, PIGrCoord y, unsigned char *pix, 
+                            int sx, int sy, PIColorMap* cmap)
+{
+  Rect	frame;
+  SetRect(&frame, 0, 0, sx, sy);
+  Rect dstFrame;
+  SetRect(&dstFrame, x, y, sx, sy);
+  GWorldPtr gWorld;
+  ThrowIfOSErr_(NewGWorld(&gWorld, 8, &frame, cmap->GetCTab(), nil, 0));
+  PixMapHandle pmh = GetGWorldPixMap(gWorld);
+  ::LockPixels (pmh);
+  Ptr pmap = GetPixBaseAddr(pmh);
+  memcpy(pmap, pix, sx*sy);
+  ::ForeColor (blackColor);
+  ::BackColor (whiteColor);
+  ::CopyBits((BitMap *) (*pmh),
+				&mPane->GetMacPort()->portBits,
+				&frame, &dstFrame, srcCopy, nil);
+  ::UnlockPixels (pmh);
+  DisposeGWorld(gWorld);
+}
+
+
+
+/* --Methode-- */
+void PIGraphicMac::SelForeground(PIColors col)
+{
+  if (mPane->FocusDraw()) {
+    long color;
+    switch (col) {
+      case PI_Black:
+        color = blackColor;
+        break;
+      case PI_White:
+        color = whiteColor;
+        break;
+      case PI_Red:
+        color = redColor;
+        break;
+      case PI_Blue:
+        color = blueColor;
+        break;
+      case PI_Green:
+        color = greenColor;
+        break;
+      case PI_Yellow:
+        color = yellowColor;
+        break;
+      default:
+        color = blackColor;
+    }
+    ::ForeColor(color);
+    mFCol = col;
+  }
+}
+
+/* --Methode-- */
+void PIGraphicMac::SelBackground(PIColors col)
+{
+  if (mPane->FocusDraw()) {
+    long color;
+    switch (col) {
+      case PI_Black:
+        color = blackColor;
+        break;
+      case PI_White:
+        color = whiteColor;
+        break;
+      case PI_Red:
+        color = redColor;
+        break;
+      case PI_Blue:
+        color = blueColor;
+        break;
+      case PI_Green:
+        color = greenColor;
+        break;
+      case PI_Yellow:
+        color = yellowColor;
+        break;
+      default:
+        color = blackColor;
+    }
+    mBCol = col;
+    ::BackColor(color);
+  }
+}
+
+/* --Methode-- */
+void PIGraphicMac::SelForeground(PIColorMap& cmap, int cid)
+{
+  if (mPane->FocusDraw()) {
+    PIColor picol = cmap.GetColor(cid);
+    RGBColor qdCol;
+ 
+    qdCol.red   = picol.red;
+    qdCol.green = picol.green;
+    qdCol.blue  = picol.blue;
+
+    ::RGBForeColor(&qdCol);
+  }
+}
+
+/* --Methode-- */
+void PIGraphicMac::SelBackground(PIColorMap& cmap, int cid)
+{
+  if (mPane->FocusDraw()) {
+    PIColor picol = cmap.GetColor(cid);
+    RGBColor qdCol;
+ 
+    qdCol.red   = picol.red;
+    qdCol.green = picol.green;
+    qdCol.blue  = picol.blue;
+
+    ::RGBBackColor(&qdCol);
+  }
+}
+
+/* --Methode-- */
+void PIGraphicMac::SelGOMode(PIGOMode mod)
+{
+if (mod == mGOm)  return;
+  if (mPane->FocusDraw())
+    switch (mod)
+    {
+      case PI_GOCopy :
+        ::PenMode(patCopy);
+        mGOm = mod;
+        break;
+      case PI_GOXOR :
+        ::PenMode(patXor);
+        mGOm = mod;
+        break;
+    }
+return;
+}
+
+
+/* --Methode-- */
+void PIGraphicMac::SelFontSzPt(int npt, PIFontAtt att)
+{
+  myFont.SetFontSzPt(npt);
+  myFont.SetFontAtt(att);
+}
+
+/* --Methode-- */
+void PIGraphicMac::SelFont(PIFontSize sz, PIFontAtt att)
+{
+  myFont.SetFontSz(sz);
+  myFont.SetFontAtt(att);
+}
+
+/* --Methode-- */
+void PIGraphicMac::SelFont(PIFont & fnt)
+{
+  myFont = fnt;
+}
+
+
+/* --Methode-- */
+void PIGraphicMac::SelLine(PILineAtt const & att)
+{
+  if (mPane->FocusDraw()) {
+    switch(att) {
+      case PI_NormalLine:
+        ::PenSize(1,1);
+        break;
+      case PI_ThinLine:
+        ::PenSize(1,1);  // Mettre en pointille, ou bien commentaire pour Laser ?
+        break;
+      case PI_ThickLine:
+        ::PenSize(2,2);
+        break;
+    }
+  }
+  mLAtt = att;
+}
+
+
+/* --Methode-- */
+void PIGraphicMac::SelMarker(int msz, PIMarker mrk)
+{
+if (msz > 1)  { mMrk = mrk;  mMrkSz = msz; }
+else  { mMrk = PI_DotMarker;  mMrkSz = 1; }
+return;
+}
+
+
+/* --Methode-- */
+void PIGraphicMac::SetClipRectangle(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+{
+//$CHECK
+}
+
+/* --Methode-- */
+void PIGraphicMac::ClearClipRectangle()
+{ 
+//$CHECK
+}
+
+/* --Methode-- */
+PIColors  PIGraphicMac::GetForeground() 
+{
+return (mFCol);
+}
+
+/* --Methode-- */
+PIColors  PIGraphicMac::GetBackground() 
+{
+return (mBCol);
+}
+
+
+/* --Methode-- */
+PIGOMode   PIGraphicMac::GetGOMode()
+{
+return (mGOm);
+}
+
+/* --Methode-- */
+PIFontAtt  PIGraphicMac::GetFontAtt()
+{
+return (myFont.GetFontAtt());
+}
+
+/* --Methode-- */
+int        PIGraphicMac::GetFontSize()
+{
+return (myFont.GetFontSize());
+}
+
+/* --Methode-- */
+PILineAtt  PIGraphicMac::GetLineAtt()
+{
+return (mLAtt);
+}
+
+/* --Methode-- */
+PIMarker   PIGraphicMac::GetMarker()
+{
+return (mMrk);
+}
+
+/* --Methode-- */
+int        PIGraphicMac::GetMarkerSize()
+{
+return (mMrkSz);
+}
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/pigraphmac.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pigraphmac.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pigraphmac.h	(revision 2309)
@@ -0,0 +1,89 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive     PIGraphicMac
+// Trace graphiques- Implementation Mac  E. Aubourg 99
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PIGRAPHICMAC_H_SEEN
+#define PIGRAPHICMAC_H_SEEN
+
+#include "pisysdep.h"
+#include "pigraphgen.h"
+
+class PIGraphicMac : public PIGraphicGen
+{
+public:
+                     PIGraphicMac(PIWdg* wdg);
+  virtual           ~PIGraphicMac();
+
+//  Trace graphiques
+  virtual void       Erase(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy);
+  virtual void       DrawString(PIGrCoord x, PIGrCoord y, const char* s, int pos = 0);
+  virtual void       DrawOpaqueString(PIGrCoord x, PIGrCoord y, const char* s, int pos = 0);
+  virtual void       DrawLine(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2);
+  virtual void       DrawBox(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy);
+  virtual void       DrawFBox(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy);
+  virtual void       DrawCircle(PIGrCoord x0, PIGrCoord y0, PIGrCoord r);
+  virtual void       DrawFCircle(PIGrCoord x0, PIGrCoord y0, PIGrCoord r);
+  virtual void       DrawOval(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy);
+  virtual void       DrawFOval(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy);
+  virtual void       DrawPolygon(PIGrCoord *x, PIGrCoord *y, int n, bool cinc=true);  
+  virtual void       DrawFPolygon(PIGrCoord *x, PIGrCoord *y, int n, bool cinc=true);  
+  virtual void       DrawArc(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy,
+                             double degdeb, double deltadeg);
+  virtual void       DrawFArc(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy, 
+                              double degdeb, double deltadeg);
+  virtual void       DrawMarker(PIGrCoord x0, PIGrCoord y0);
+  virtual void       DrawMarkers(PIGrCoord *x, PIGrCoord *y, int n);
+  virtual void       DrawPixmap(PIGrCoord x, PIGrCoord y, unsigned char *pix, 
+                                int sx, int sy, PIColorMap* cmap);
+
+// Modifications attributs graphiques
+  virtual void       SelForeground(PIColors col=PI_Black);
+  virtual void       SelBackground(PIColors col=PI_White);
+  virtual void       SelForeground(PIColorMap& cmap, int cid);
+  virtual void       SelBackground(PIColorMap& cmap, int cid);
+  virtual void       SelGOMode(PIGOMode mod=PI_GOCopy);
+  virtual void	     SelFont(PIFont & fnt);
+  virtual void       SelFont(PIFontSize sz=PI_NormalSizeFont, 
+                             PIFontAtt att=PI_RomanFont);
+  virtual void       SelFontSzPt(int npt=12, PIFontAtt att=PI_RomanFont);
+  virtual void       SelLine(PILineAtt const& att);
+  virtual void       SelMarker(int msz=3, PIMarker mrk=PI_DotMarker);
+
+// Selection de zone de trace (clip)
+  virtual void       SetClipRectangle(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy);
+  virtual void       ClearClipRectangle();
+
+// Acces aux attributs graphiques 
+  virtual PIColors   GetForeground();
+  virtual PIColors   GetBackground();
+  virtual PIGOMode   GetGOMode();
+  virtual PIFontAtt  GetFontAtt();
+  virtual int        GetFontSize();
+  virtual PILineAtt  GetLineAtt();
+  virtual PIMarker   GetMarker();
+  virtual int        GetMarkerSize();
+
+  //virtual int        GetFontHeight(int& asc, int& desc);
+  //virtual PIGrCoord  CalcStringWidth(char const* s);
+
+// Sauvegarde des attributs graphiques 
+ // virtual void       SaveGraphicAtt();
+ // virtual void       RestoreGraphicAtt();
+
+protected:
+  LPane* mPane;
+  
+  PolyHandle         MakePoly(PIGrCoord *x, PIGrCoord *y, int n);
+
+  PIColors  mFCol, mBCol;
+  PIGOMode  mGOm;
+  PILineAtt mLAtt;
+  PIMarker  mMrk;
+  int       mMrkSz;
+
+};
+
+typedef PIGraphicMac PIGraphicWin;
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pigraphps.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pigraphps.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pigraphps.cc	(revision 2309)
@@ -0,0 +1,523 @@
+// Module PI : Peida Interactive     PIGraphicPS
+// Trace graphiques en PostScript    R. Ansari  97
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include <stdio.h>
+
+#include "pigraphps.h"
+
+//++
+// Class	PIGraphicPS
+// Lib		PI
+// include	pigraphps.h
+//
+//   	Classe les services de tracé graphique avec sortie PostScript
+//	Toutes les méthodes de tracé de "PIGraphic" sont redéfinies pour
+//	produire du PostScript 
+//--
+//++
+// Links	Parent
+// PIGraphic
+//--
+//++
+// Links	Voir aussi
+// PSFile
+//--
+
+//++
+// Titre	Constructeurs, méthodes
+//--
+//++
+// PIGraphicPS(PSFile * psf, double x0, double y0, double dx, double dy)
+//	Création d'un objet "PIGraphicPS" à partir d'un objet "PSFIle* psf".
+//	"(x0, y0)" détermine l'origine du nouveau bloc rectangulaire sur 
+//	la page et "dx, dy" l'extension du bloc. 
+// PIGraphicPS(PSFile * psf, PIWdg* wdg, double ofx, double ofy, double scale_x, double scale_y)
+//	Création d'un objet "PIGraphicPS" à partir d'un objet "PSFIle* psf"
+//|	x0 = wdg->XPos()+ofx    y0 = wdg->YPos()+ofy
+//|	Extension du bloc dans la page:
+//|	Tx = wdg->XSize()*scale_x    Ty = wdg->YSize()*scale_y
+//
+// int kind()
+//	 Renvoie le type ("= PI_PSFileGraphics")
+//--
+
+/* --Methode-- */
+PIGraphicPS::PIGraphicPS(PSFile * psf, PIWdg* wdg, double ofx, double ofy, 
+			 double scale_x, double scale_y)
+: PIGraphicGen()
+{
+BuildFromPSFile(psf, (double)wdg->XPos()+ofx, (double)wdg->YPos()+ofy, 
+		(double)wdg->XSize()*scale_x, (double)wdg->YSize()*scale_y, 
+		(double)wdg->XSize(), (double)wdg->YSize());
+}
+
+/* --Methode-- */
+PIGraphicPS::PIGraphicPS(PSFile * psf, double x0, double y0, double dx, double dy)
+: PIGraphicGen()
+{
+BuildFromPSFile(psf, x0, y0, dx, dy, dx, dy);
+}
+
+/* --Methode-- */
+PIGraphicPS::~PIGraphicPS()
+{
+mPSOut->EndBloc();
+}
+
+/* --Methode-- */
+int PIGraphicPS::kind()
+{
+return PI_PSFileGraphics; 
+}
+
+
+/* --Methode-- */
+void PIGraphicPS::BuildFromPSFile(PSFile * psf, double x0, double y0, double tx, double ty,
+				  double dx, double dy)
+{
+mPSOut = psf;
+
+mGOm = PI_GOCopy;
+
+mFCol = mBCol = PI_Grey;
+SelForeground(PI_Black);
+SelBackground(PI_White);
+mLAtt = PI_ThinLine;
+SelLine(PI_NormalLine);
+// mFAtt = PI_BoldFont;  mFSize = 0;  $CHECK$ Plus besoin 
+SelFont();
+SelMarker(1, PI_DotMarker);
+
+if (psf) psf->NewBloc(x0, y0, tx, ty, dx, dy);
+mXmin = mYmin = 0.;
+mXmax = dx;  mYmax = dy;
+mFCfMap.red = mFCfMap.blue = mFCfMap.blue = 0;
+mBCfMap = mFCfMap; 
+}
+
+/* --Methode-- */
+void PIGraphicPS::GetGrSpace(PIGrCoord& xmin, PIGrCoord& xmax, PIGrCoord& ymin, PIGrCoord& ymax)
+{
+xmin = ymin = 0;  
+xmax = mXmax; ymax = mYmax;
+}
+
+/* --Methode-- */
+void PIGraphicPS::Erase(PIGrCoord, PIGrCoord, PIGrCoord, PIGrCoord)
+{
+// A Faire ??? $CHECK$ 
+return;
+}
+
+/* --Methode-- */
+void PIGraphicPS::DrawString(PIGrCoord x, PIGrCoord y, const char* s, unsigned long pos)
+{
+if(mPSOut) {
+  unsigned long txtdir = pos&PI_TextDirection;
+  unsigned long posh = pos & PI_HorizontalPosition;
+  unsigned long posv = pos & PI_VerticalPosition;
+  int dx,dy;
+  double xd = x;
+  double yd = y;
+  bool fgcsps = CalcStringPositionShift(s, posv, dx, dy);
+  if (txtdir == PI_TextDirectionHorizontal) {
+    if (fgcsps) yd -= dy;
+  }
+  else {
+    if (txtdir == PI_TextDirectionVerticalDown) xd += dy; 
+    else xd -= dy; 
+  }
+  mPSOut->DrawString(xd, yd, s, mFCol, myFont.GetFontName(), myFont.GetFontAtt(),
+		     myFont.GetFontSize(), posh|txtdir); 
+}
+return;
+}
+
+/* --Methode-- */
+void PIGraphicPS::DrawOpaqueString(PIGrCoord x, PIGrCoord y, const char* s, unsigned long pos)
+{
+if(mPSOut) {
+  unsigned long txtdir = pos&PI_TextDirection;
+  unsigned long posh = pos & PI_HorizontalPosition;
+  unsigned long posv = pos & PI_VerticalPosition;
+  int dx,dy;
+  double xd = x;
+  double yd = y;
+  bool fgcsps = CalcStringPositionShift(s, posv, dx, dy);
+  if (txtdir == PI_TextDirectionHorizontal) {
+    if (fgcsps) yd -= dy;
+  }
+  else {
+    if (txtdir == PI_TextDirectionVerticalDown) xd += dy; 
+    else xd -= dy; 
+  }
+  mPSOut->DrawString(xd, yd, s, mFCol, myFont.GetFontName(), myFont.GetFontAtt(),
+		     myFont.GetFontSize(), posh|txtdir); 
+}
+return;
+}
+
+ 
+/* --Methode-- */
+void PIGraphicPS::DrawLine(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2)
+{
+if(mPSOut)
+  mPSOut->DrawLine((double)x1,(double)y1,(double)x2,(double)y2,mFCol,mLAtt);
+return;
+}
+
+
+/* --Methode-- */
+void PIGraphicPS::DrawBox(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+{
+if(mPSOut)
+  mPSOut->DrawBox((double)x0,(double)y0,(double)dx,(double)dy,mFCol,mLAtt);
+return;
+}
+
+/* --Methode-- */
+void PIGraphicPS::DrawFBox(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+{
+if(mPSOut)
+  mPSOut->DrawFBox((double)x0,(double)y0,(double)dx,(double)dy, mFCol, mFCol, mLAtt);
+return;
+}
+
+/* --Methode-- */
+void PIGraphicPS::DrawCircle(PIGrCoord x0, PIGrCoord y0, PIGrCoord r)
+{
+if(mPSOut)
+  mPSOut->DrawCircle((double)x0,(double)y0,(double)r,mFCol,mLAtt);
+return;
+}
+
+/* --Methode-- */
+void PIGraphicPS::DrawFCircle(PIGrCoord x0, PIGrCoord y0, PIGrCoord r)
+{
+if(mPSOut)
+  mPSOut->DrawFCircle((double)x0,(double)y0,(double)r,mFCol,mFCol);
+return;
+}
+
+/* --Methode-- */
+void PIGraphicPS::DrawOval(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+{
+if(mPSOut)
+  mPSOut->DrawArc((double)x0,(double)y0,(double)dx,(double)dy,0.,360.,mFCol,mLAtt);
+return;
+}
+
+/* --Methode-- */
+void PIGraphicPS::DrawFOval(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+{
+if(mPSOut)
+  mPSOut->DrawFArc((double)x0,(double)y0,(double)dx,(double)dy,0.,360.,mFCol,mFCol);
+return;
+
+}
+
+/* --Methode-- */
+void PIGraphicPS::DrawPolygon(PIGrCoord *x, PIGrCoord *y, int n, bool cinc)
+{
+int i;
+double *xtmp;
+double *ytmp;
+
+if(! mPSOut) return;
+
+xtmp = new double[n];
+ytmp = new double[n];
+for(i = 0 ; i < n ; i++) {xtmp[i] = (double)x[i] ; ytmp[i] = (double)y[i] ; }
+//double xoff,yoff;
+//if (cinc) { xoff=yoff=0.; }   // Coord en mode incremental
+//else { xoff = (double)x[0];  yoff = (double)y[0]; }   //   Coord en mode absolu
+//xtmp[0] = (double)x[0];
+//ytmp[0] = (double)y[0];
+//for(i=1;i<n;i++) {
+//  xtmp[i] = (double)x[i]-xoff;
+//  ytmp[i] = (double)y[i]-yoff;
+//}
+mPSOut->DrawPolygon(xtmp,ytmp,n,mFCol,mLAtt,cinc);
+delete[] xtmp;
+delete[] ytmp;
+
+return;
+}
+
+
+/* --Methode-- */
+void PIGraphicPS::DrawFPolygon(PIGrCoord *x, PIGrCoord *y, int n, bool cinc)
+{
+int i;
+double *xtmp;
+double *ytmp;
+
+if(! mPSOut) return;
+
+xtmp = new double[n];
+ytmp = new double[n];
+for(i = 0 ; i < n ; i++) {xtmp[i] = (double)x[i] ; ytmp[i] = (double)y[i] ; }
+//double xoff,yoff;
+//if (cinc) { xoff=yoff=0.; }   // Coord en mode incremental
+//else { xoff = (double)x[0];  yoff = (double)y[0]; }   //   Coord en mode absolu
+//xtmp[0] = (double)x[0];
+//ytmp[0] = (double)y[0];
+//for(i=1;i<n;i++) {
+//  xtmp[i] = (double)x[i]-xoff;
+//  ytmp[i] = (double)y[i]-yoff;
+//}
+mPSOut->DrawFPolygon(xtmp,ytmp,n,mFCol,mFCol,mLAtt,cinc);
+delete[] xtmp;
+delete[] ytmp;
+
+return;
+}
+
+/* --Methode-- */
+void PIGraphicPS::DrawArc(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy,double degdeb, double deltadeg)
+{
+if(mPSOut)
+  mPSOut->DrawArc((double)x0,(double)y0,(double)dx,(double)dy,degdeb,deltadeg,mFCol,mLAtt);
+return;
+}
+
+/* --Methode-- */
+void PIGraphicPS::DrawFArc(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy,double degdeb, double deltadeg)
+{
+if(mPSOut)
+  mPSOut->DrawFArc((double)x0,(double)y0,(double)dx,(double)dy,degdeb,deltadeg,mFCol,mFCol);
+return;
+}
+
+/* --Methode-- */
+void PIGraphicPS::DrawMarker(PIGrCoord x0, PIGrCoord y0)
+{
+if(mPSOut)
+  mPSOut->DrawMarker((double)x0,(double)y0,mMrk,mFCol,mMrkSz);
+return;
+}
+
+/* --Methode-- */
+void PIGraphicPS::DrawMarkers(PIGrCoord *x, PIGrCoord *y, int n)
+{
+int i;
+double *xtmp;
+double *ytmp;
+
+if( !mPSOut)  return;
+
+xtmp = new double[n];
+ytmp = new double[n];
+for(i=0;i<n;i++){
+  xtmp[i] = (double)x[i];
+  ytmp[i] = (double)y[i];
+}
+mPSOut->DrawMarkers(xtmp,ytmp,n,mMrk,mFCol, mMrkSz);
+delete[] xtmp;
+delete[] ytmp;
+
+return;
+}
+
+
+/* --Methode-- */
+void PIGraphicPS::DrawPixmap(PIGrCoord x, PIGrCoord y, unsigned char *pix, 
+                            int sx, int sy, PIColorMap* cmap)
+{
+if ( (sx < 1) || (sy < 1) )  return;
+if ((pix == NULL) || (cmap == NULL)) return;
+if(mPSOut) 
+  mPSOut->Image((double)x, (double)y, (double)sx, (double)sy, sx, sy, pix, cmap);
+return;
+}
+
+/* --Methode-- */
+void PIGraphicPS::SelForeground(PIColors col)
+{
+mFCol = col;
+return;
+}
+
+/* --Methode-- */
+void PIGraphicPS::SelBackground(PIColors col)
+{
+mBCol = col;
+return;
+}
+
+/* --Methode-- */
+void PIGraphicPS::SelForeground(PIColorMap& cmap, int cid)
+{
+// A Faire Voir Nicolas  
+mFCfMap = cmap.GetColor(cid);
+mFCol = PI_ColorFromMap;
+mPSOut->SelForeground(cmap, cid) ; 
+return;
+}
+
+/* --Methode-- */
+void PIGraphicPS::SelBackground(PIColorMap& cmap, int cid)
+{
+// A Faire Voir Nicolas  
+mBCfMap = cmap.GetColor(cid);
+mBCol = PI_ColorFromMap;
+return;
+}
+
+/* --Methode-- */
+void PIGraphicPS::SelGOMode(PIGOMode mod)
+{
+mGOm = mod;
+return;
+}
+/* --Methode-- */
+void PIGraphicPS::SelFont(PIFont & fnt)
+{
+//  $CHECK$   -  Reza 13/06/99
+if (myFont == fnt)  return;
+myFont = fnt;
+  // C'est peu-etre mieux 
+  // SelFontSzPt(fnt.GetFontSize(), fnt.GetFontAtt());
+}
+
+
+static int fntsz[5] = {8,10,12,14,16};
+
+/* --Methode-- */
+void PIGraphicPS::SelFont(PIFontSize sz, PIFontAtt att)
+{
+//  $CHECK$   -  Reza 13/06/99
+PIFont fnt(myFont.GetFontName());
+fnt.SetFontAtt(att);
+fnt.SetFontSz(sz);
+SelFont(fnt);
+return;
+}
+
+/* --Methode-- */
+void PIGraphicPS::SelFontSzPt(int npt, PIFontAtt att)
+{
+//  $CHECK$   -  Reza 13/06/99
+PIFont fnt(npt, myFont.GetFontName(), att);
+SelFont(fnt);
+}
+
+
+
+/* --Methode-- */
+void PIGraphicPS::SelLine(PILineAtt const& att)
+{
+mLAtt = att;
+return;
+}
+
+
+/* --Methode-- */
+void PIGraphicPS::SelMarker(int msz, PIMarker mrk)
+{
+if (msz > 1)  { mMrk = mrk;  mMrkSz = msz; }
+else  { mMrk = PI_DotMarker;  mMrkSz = 1; }
+return;
+}
+
+
+/* --Methode-- */
+void PIGraphicPS::SetClipRectangle(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+{
+  mPSOut->SetClipRectangle((double)x0, (double)y0, (double)dx, (double)dy);
+}
+
+/* --Methode-- */
+void PIGraphicPS::ClearClipRectangle()
+{ 
+  mPSOut->ClearClipRectangle();
+}
+
+/* --Methode-- */
+PIColors  PIGraphicPS::GetForeground() 
+{
+return (mFCol);
+}
+
+/* --Methode-- */
+PIColors  PIGraphicPS::GetBackground() 
+{
+return (mBCol);
+}
+
+
+/* --Methode-- */
+PIGOMode   PIGraphicPS::GetGOMode()
+{
+return (mGOm);
+}
+
+
+/* --Methode-- */
+PILineAtt  PIGraphicPS::GetLineAtt()
+{
+return (mLAtt);
+}
+
+/* --Methode-- */
+PIMarker   PIGraphicPS::GetMarker()
+{
+return (mMrk);
+}
+
+/* --Methode-- */
+int        PIGraphicPS::GetMarkerSize()
+{
+return (mMrkSz);
+}
+
+/* --Methode-- 
+int        PIGraphicPS::GetFontHeight(int& asc, int& desc)   
+{
+  $CHECK$  A refaire , voir Nicolas  
+asc = mFSize; desc = 0; 
+return(asc+desc);
+} 
+*/
+
+
+/* --Methode-- 
+PIGrCoord PIGraphicPS::CalcStringWidth(char const* s)
+{
+return((double)(mFSize*strlen(s)*0.5));   
+//  facteur 0.5 ad hoc $CHECK$  Voir Nicolas 
+}
+*/
+ 
+
+/* --Methode-- */
+void PIGraphicPS::SaveGraphicAtt()
+{  
+// Pour optimier l'implementation de PIBaseWdgGen
+sFCol = mFCol;    sBCol = mBCol;
+sGOm = mGOm;
+sFont = myFont; 
+sMrk = mMrk;   sMrkSz = mMrkSz;
+return;
+}
+
+
+/* --Methode-- */
+void PIGraphicPS::RestoreGraphicAtt()
+{
+  if (sFCol != PI_ColorFromMap) SelForeground(sFCol);  
+// else    A faire Nicolas  
+  if (sBCol != PI_ColorFromMap) SelBackground(sBCol);
+// else    A faire Nicolas  
+  SelGOMode(sGOm);
+  SelFont(sFont);
+  SelLine(sLAtt);
+  SelMarker(sMrkSz, sMrk);
+  return;
+}
+
+
+
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/pigraphps.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pigraphps.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pigraphps.h	(revision 2309)
@@ -0,0 +1,95 @@
+#ifndef PIGRAPHICPS_H_SEEN
+#define PIGRAPHICPS_H_SEEN
+
+#include "pisysdep.h"
+#include "pigraphgen.h"
+#include "psfile.h"
+
+class PIGraphicPS : public PIGraphicGen
+{
+public:
+                     PIGraphicPS(PSFile * psf, PIWdg* wdg, double ofx=0., double ofy=0.,
+				 double scale_x=1., double scale_y=1.);
+                     PIGraphicPS(PSFile * psf, double x0, double y0, double dx, double dy);
+  virtual           ~PIGraphicPS();
+
+  virtual int        kind();
+
+//  Espace des coordonnees
+  virtual void       GetGrSpace(PIGrCoord& xmin, PIGrCoord& xmax, PIGrCoord& ymin, PIGrCoord& ymax); 
+
+//  Trace graphiques
+  virtual void       Erase(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy);
+  virtual void       DrawString(PIGrCoord x, PIGrCoord y, const char* s, unsigned long pos = 0);
+  virtual void       DrawOpaqueString(PIGrCoord x, PIGrCoord y, const char* s, unsigned long pos = 0);
+  virtual void       DrawLine(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2);
+  virtual void       DrawBox(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy);
+  virtual void       DrawFBox(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy);
+  virtual void       DrawCircle(PIGrCoord x0, PIGrCoord y0, PIGrCoord r);
+  virtual void       DrawFCircle(PIGrCoord x0, PIGrCoord y0, PIGrCoord r);
+  virtual void       DrawOval(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy);
+  virtual void       DrawFOval(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy);
+  virtual void       DrawPolygon(PIGrCoord *x, PIGrCoord *y, int n, bool cinc=true);  
+  virtual void       DrawFPolygon(PIGrCoord *x, PIGrCoord *y, int n, bool cinc=true);  
+  virtual void       DrawArc(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy,
+                             double degdeb, double deltadeg);
+  virtual void       DrawFArc(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy, 
+                              double degdeb, double deltadeg);
+  virtual void       DrawMarker(PIGrCoord x0, PIGrCoord y0);
+  virtual void       DrawMarkers(PIGrCoord *x, PIGrCoord *y, int n);
+  virtual void       DrawPixmap(PIGrCoord x, PIGrCoord y, unsigned char *pix, 
+                                int sx, int sy, PIColorMap* cmap);
+
+// Modifications attributs graphiques
+  virtual void       SelForeground(PIColors col=PI_Black);
+  virtual void       SelBackground(PIColors col=PI_White);
+  virtual void       SelForeground(PIColorMap& cmap, int cid);
+  virtual void       SelBackground(PIColorMap& cmap, int cid);
+  virtual void       SelGOMode(PIGOMode mod=PI_GOCopy);
+  virtual void       SelLine(PILineAtt const& att);
+  virtual void       SelMarker(int msz=3, PIMarker mrk=PI_DotMarker);
+
+  virtual void       SelFont(PIFont & fnt);
+  virtual void       SelFont(PIFontSize sz=PI_NormalSizeFont, 
+                             PIFontAtt att=PI_RomanFont);
+  virtual void       SelFontSzPt(int npt=12, PIFontAtt att=PI_RomanFont);
+
+// Selection de zone de trace (clip)
+  virtual void       SetClipRectangle(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy);
+  virtual void       ClearClipRectangle();
+
+// Acces aux attributs graphiques 
+  virtual PIColors   GetForeground();
+  virtual PIColors   GetBackground();
+  virtual PIGOMode   GetGOMode();
+  virtual PILineAtt  GetLineAtt();
+  virtual PIMarker   GetMarker();
+  virtual int        GetMarkerSize();
+
+  //  virtual PIGrCoord  GetFontHeight(PIGrCoord& asc, PIGrCoord& desc);
+  //  virtual PIGrCoord  CalcStringWidth(char const* s);
+
+// Sauvegarde des attributs graphiques 
+  virtual void       SaveGraphicAtt();
+  virtual void       RestoreGraphicAtt();
+
+protected:
+  void           BuildFromPSFile(PSFile * psf, double x0, double y0, double tx, double ty,
+				 double dx, double dy);
+
+  PSFile * mPSOut;  /* Fichier PostScript */
+  double mXmin, mYmin;
+  double mXmax, mYmax;
+
+  PIColors  mFCol, mBCol;
+  PIColor  mFCfMap, mBCfMap;
+  PIGOMode mGOm;
+//  PIFontAtt mFAtt;  Plus besoin Reza + NR 07/08/99
+  PILineAtt mLAtt;
+//  int mFSize;    Plus besoin Reza + NR 07/08/99
+  PIMarker mMrk;
+  int mMrkSz;
+};
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pigraphuc.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pigraphuc.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pigraphuc.cc	(revision 2309)
@@ -0,0 +1,989 @@
+// Module PI : Peida Interactive     PIGraphicUC 
+// Trace graphiques User-Coordinates    R. Ansari  97
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "machdefs.h"
+#include <iostream.h>
+#include "pigraphuc.h"
+
+#include "ucckprot.h"
+
+
+//++
+// Class	PIGraphicUC
+// Lib		PI
+// include	pigraphuc.h
+//
+//   	Classe fournissant les services de tracé graphique 
+//	en coordonnées utilisateur.
+//	Toutes les méthodes de tracé de "PIGraphic" sont redéfinies pour 
+//	accepter les arguments en système de coordonnées utilisateur.
+//--
+//++
+// Links	Parent
+// PIGraphic
+//--
+
+// Pour echanger deux valeurs PIGrCoord
+static inline void dbl_swap(double& a, double& b) { double tmp = a; a = b; b = tmp; }
+
+//++
+// Titre	Constructeurs, méthodes
+//--
+//++
+// PIGraphicUC(PIGraphicGen* g, PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+//	Constructeur d'un objet "PIGraphUC" à partir d'un "PIGraphicGen* g". L'espace
+//	de travail du nouvel objet "PIGraphic" correspond au rectangle défini par
+//	"(x0,y0)" , "dx,dy" du "PIGraphic" de départ.
+// 
+// int  kind()
+//	Renvoie le type ("= PI_UCGraphics")
+// void SetBaseGraphic(PIGraphicGen* g, PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+//	Permet de modifier l'objet "PIGraphic" de départ et l'espace graphique correspondant.
+//
+// void  SelFontSz(PIGrCoord sz)
+//	Sélection de fonte avec la taille exprimée en coordonnées utilisateur
+// void  SelFontSz(PIGrCoord sz, PIFontAtt att)
+//	Sélection de fonte avec la taille exprimée en coordonnées utilisateur, avec 
+//	Spécification d'attribut de fonte
+// void  SelMarkerSz(PIGrCoord msz, PIMarker mrk=PI_DotMarker)
+//	Sélection de marker avec la taille exprimée en coordonnées utilisateur
+//--
+
+/* --Methode-- */
+PIGraphicUC::PIGraphicUC(PIGraphicGen* g, PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+  : PIGraphicGen()
+{
+  mGrC = g;
+  xW0 = x0;  yW0 = y0; 
+  xWd = dx;  yWd = dy; 
+  aXdir = false;  // Vrai si Axe X de Droite vers Gauche 
+  aYdir = false;  // Vrai si Axe Y de Haut vers Bas
+  aXlog = aYlog = false;   // Vrai -> Echelle log
+  aXYexchng = false;       // Vrai -> Echange axes X,Y UserX,Y --> WindowY, X
+  SetUCS(0., 1., 0., 1., kAxeDirLtoR, kAxeDirDownUp);
+  SetLogScale(false, false);
+  clip = true;  
+}
+
+/* --Methode-- */
+PIGraphicUC::~PIGraphicUC()
+{
+}
+
+/* --Methode-- */
+int PIGraphicUC::kind() 
+{
+return PI_UCGraphics; 
+}
+
+
+/* --Methode-- */
+void PIGraphicUC::SetBaseGraphic(PIGraphicGen* g, PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+{
+  mGrC = g;
+  xW0 = x0;  yW0 = y0; 
+  xWd = dx;  yWd = dy; 
+  SetUCS(xMin, xMax, yMin, yMax, kAxeDirSame, kAxeDirSame);
+}
+
+/* --Methode-- */
+void PIGraphicUC::GetGrSpace(PIGrCoord& xmin, PIGrCoord& xmax, PIGrCoord& ymin, PIGrCoord& ymax)
+{
+xmin = xMin;  ymin = yMin;  
+xmax = xMax;  ymax = yMax;
+}
+
+//++
+// Titre	Système de coordonnées utilisateur
+//--
+//++
+// void       SetUCS(double xmin, double xmax, double ymin, double ymax, -
+// int axrl=kAxeDirSame, int ayud=kAxeDirSame)
+//	Définit le système de coordonnées utilisateur. Axe X de "xmin" à "xmax" , 
+//	Axe Y de "ymin" à "ymax". "axrl", "ayud" définit le sens des axes 
+//	sur la fenêtre :
+//|	kAxeDirSame : Pas de changement de sens
+//|	kAxeDirLtoR : Axe X croissant de gauche à droite   
+//|	kAxeDirRtoL : Axe X croissant de droite à gauche 
+//|	kAxeDirDownUp : Axe Y croissant de Bas vers Haut
+//|	kAxeDirUpDown : Axe Y croissant de Haut vers Bas
+//|	kAxeDirAuto : Sens determine a partir de la valeur relative 
+//|	de xmin, xmax, ymin, ymax
+//|	      xmin < xmax : kAxeDirLtoR   -  xmax < xmin : kAxeDirRtoL
+//|	      ymin < ymax : kAxeDirDownUp -  ymax < ymin : kAxeDirUpDown
+//	Par défaut : "xmin=ymin=0." , "ymin=ymax=0." , "kAxeDirLtoR" , "kAxeDirDownUp"
+// 
+// void  SetLogScale(bool logx, bool logy)
+//	Définition d'échelle logarithmique pour l'axe X,Y (si X,Ymin max > 0).
+//	Si X,Ymin max sont modifiés par SetUCS par la suite, avec des 
+//	valeurs négatives, l'échelle est remise en linéaire.
+// bool  isLogScaleX()  
+// bool  isLogScaleY() 
+//	Renvoie "true" si échelle logarithmique pour l'axe X,Y
+// bool  isAxeXDirRtoL()
+//	Renvoie "true" si axe X de droite a gauche
+// bool  isAxeYDirUpDown()
+//	Renvoie "true" si axe Y de haut vers vbas.
+//	
+// void  UC2GrC(double x, double y, double& xpix, double& ypix)
+//	Transformation de coordonnées utilisateur "(x,y)" en coordoonnées 
+//	de l'espace graphic de départ "(xpix, ypix)"
+// void  GrC2UC(double xpix, double ypix, double& x, double& y)
+//	Transformation de coordonnées de l'espace graphic de départ. en coordonnées utilisateur.
+// void  DUC2GrC(double dx, double dy, double& dxpix, double& dypix)
+//	Transformation de distances selon X,Y en coordonnées utilisateur "dx, dy" en distance
+//	dans l'espace graphique de départ "dxpix , dypix".
+// void  DGrC2UC(double dxpix, double dypix, double& dx, double& dy)
+//	Transformation de distances selon X,Y dans l'espace graphique de départ en distance
+//	dans l'espace de  coordonnées utilisateur.
+//
+// void  LinUC2GrC(double x, double y, double& xpix, double& ypix)
+//	Transformation de coordonnées utilisateur "(x,y)" en coordoonnées 
+//	de l'espace graphic de départ "(xpix, ypix)", sans utilisation de 
+//	l'échelle logarithmique.
+// double  DeltaUCX(double x, double dx)
+//	Retourne la nouvelle coordonnée X, correspondant a "x" décalée de
+//	"dx", avec "dx" exprimé en échelle linéaire.
+// double  DeltaUCY(double y, double dy)
+//	Retourne la nouvelle coordonnée Y, coorespondant a "y" décalée de
+//	"dy", avec "dy" exprimé en échelle linéaire.
+//--
+
+/* --Methode-- */
+void PIGraphicUC::SetUCS(double xmin, double xmax, double ymin, double ymax,
+                         int axrl, int ayud, bool exchxy)
+{
+  if (axrl == kAxeDirAuto) {
+    double ff;
+    if (xmax < xmin)  { axrl = kAxeDirRtoL;   ff=xmin;  xmin=xmax;  xmax=ff; }
+    else  axrl = kAxeDirLtoR;
+  }
+  if (ayud == kAxeDirAuto) {
+    double ff;
+    if (ymax < ymin)  { ayud = kAxeDirUpDown;   ff=ymin;  ymin=ymax;  ymax=ff; }
+    else  ayud = kAxeDirDownUp;
+  }
+
+  UC_CheckMinMaxDiff(xmin, xmax);
+  UC_CheckMinMaxDiff(ymin, ymax);
+
+  if (!UC_CheckFinite(xmin, xmax) || !UC_CheckFinite(ymin, ymax)) {
+    cerr << "PIGraphicUC::SetUCS() Error - Non finite value for x/ymin-max ! " << endl;
+    return; 
+    }
+
+  if (axrl == kAxeDirLtoR)  aXdir = false;
+  else if (axrl == kAxeDirRtoL)  aXdir = true;
+  if (ayud == kAxeDirDownUp)  aYdir = false;
+  else if (ayud == kAxeDirUpDown)  aYdir = true;
+  xMin = xmin;
+  xMax = xmax;
+  yMin = ymin;
+  yMax = ymax;
+
+  xScale = UC_LimitProtectDouble(xWd/(xMax-xMin)); // Protection 
+  if (aXdir)  { 
+    xScale = -xScale;
+    xOrg   = -xMax * xScale;
+  }
+  else xOrg   = -xMin * xScale;
+  xOrg += xW0;
+
+  yScale = UC_LimitProtectDouble(yWd/(yMax-yMin)); // Protection  
+  if (!aYdir) {
+    yScale = -yScale;
+    yOrg   = -yMax  * yScale;
+    }
+  else yOrg   = -yMin * yScale;
+  yOrg += yW0;
+  if (aXlog || aYlog) SetLogScale(aXlog, aYlog);
+  return;
+}
+
+/* --Methode-- */
+void PIGraphicUC::SetLogScale(bool logx, bool logy)
+{
+if (logx) 
+  if (xMax < PETIT_DBLE) {
+    cerr<< "PIGraphicUC::SetLogScale() Warning - XLogScale not valid for XMax ="
+        << xMax<<" < "<<PETIT_DBLE<<endl;
+    logx = false;
+  }
+if (logy)
+  if (yMax < PETIT_DBLE) {
+    cerr<<"PIGraphicUC::SetLogScale() Warning - YLogScale not valid for YMax ="
+        <<yMax<<" < "<<PETIT_DBLE<<endl;
+    logy = false;
+  }
+
+aXlog = logx;
+aYlog = logy;
+
+if (aXlog) {     
+  xMinLog = (xMin > PETIT_DBLE) ? xMin : ( (1. < xMax/10.) ? 1. : xMax/10.);
+  xScaleLog = xWd*(xMax-xMinLog)/(xMax-xMin) / (log10(xMax)-log10(xMinLog));
+  xScaleLog = UC_LimitProtectDouble(xScaleLog); // Protection 
+  if (aXdir)  { 
+    xScaleLog = -xScaleLog;
+    xOrgLog   = -log10(xMax) * xScaleLog + (xOrg + xMax*xScale);
+  }
+  else xOrgLog   = -log10(xMinLog) * xScaleLog + (xOrg + xMinLog*xScale);
+  //  if (xMinLog > xMin) 
+  //    cerr << "PIGraphicUC::SetLogScale() Warning - Linear Scale for X < " << xMinLog << endl;
+}
+else {
+  xMinLog = 1.;
+  xScaleLog = xScale;
+  xOrgLog = xW0;
+}
+if (aYlog) {     
+  yMinLog = (yMin > PETIT_DBLE) ? yMin : ( (1. < yMax/10.) ? 1. : yMax/10.);
+  yScaleLog = yWd*(yMax-yMinLog)/(yMax-yMin) / (log10(yMax)-log10(yMinLog));
+  yScaleLog = UC_LimitProtectDouble(yScaleLog); // Protection 
+  if (!aYdir) {
+    yScaleLog = -yScaleLog;
+    yOrgLog   = -log10(yMax)  * yScaleLog + (yOrg + yMax*yScale);
+    }
+  else yOrgLog   = -log10(yMinLog) * yScaleLog + (yOrg + yMinLog*yScale);
+  //  if (yMinLog > yMin) 
+  //    cerr << "PIGraphicUC::SetLogScale() Warning - Linear Scale for Y < " << yMinLog << endl;
+}  
+else {
+  yMinLog = 1.;
+  yScaleLog = xScale;
+  yOrgLog = xW0;
+}
+return;
+}
+
+/* --Methode-- */
+void PIGraphicUC::UC2GrC(double x, double y, double& xpix, double& ypix)
+{
+  if (aXlog && (x > xMinLog))  xpix = xOrgLog + log10(x)*xScaleLog;  
+  else xpix = (double)(xOrg + x*xScale);  
+  if (aYlog && (y > yMinLog))  ypix = yOrgLog + log10(y)*yScaleLog; 
+  else ypix = (double)(yOrg + y*yScale);  
+}
+
+/* --Methode-- */
+void PIGraphicUC::GrC2UC(double xpix, double ypix, double& x, double& y)
+{
+  if (!aXlog)  x = (xpix-xOrg)/xScale;
+  else { 
+    if ( (aXdir && (xpix < (xOrg + xMinLog*xScale))) || 
+         (!aXdir && (xpix > (xOrg + xMinLog*xScale))) )     {
+      x = (xpix-xOrgLog)/xScaleLog;
+      x = pow(10., x);
+    }
+    else x = (xpix-xOrg)/xScale;
+  }
+       
+  if (!aYlog)  y = (ypix-yOrg)/yScale;
+  else { 
+    if ( (aYdir && (ypix > (yOrg + yMinLog*yScale))) || 
+         (!aYdir && (ypix < (yOrg + yMinLog*yScale))) )    {
+      y = (ypix-yOrgLog)/yScaleLog;
+      y = pow(10., y);
+    }
+    else y = (ypix-yOrg)/yScale;
+  }
+
+}
+
+/* --Methode-- */
+void PIGraphicUC::DUC2GrC(double dx, double dy, double& dxpix, double& dypix)
+{
+  dxpix = dx*xScale;
+  if (dxpix < 0)  dxpix = -dxpix;
+  dypix = dy*yScale;
+  if (dypix < 0)  dypix = -dypix;
+}
+
+/* --Methode-- */
+void PIGraphicUC::DGrC2UC(double dxpix, double dypix, double& dx, double& dy)
+{
+  dx = dxpix/xScale;
+  dy = dypix/yScale;
+  if (dx < 0.) dx = -dx;
+  if (dy < 0.) dy = -dy;
+}
+
+/* --Methode-- */
+void PIGraphicUC::LinUC2GrC(double x, double y, double& xpix, double& ypix)
+{
+  xpix = (double)(xOrg + x*xScale);  
+  ypix = (double)(yOrg + y*yScale);  
+}
+
+/* --Methode-- */
+double PIGraphicUC::DeltaUCX(double x, double dx)
+{
+  if (!aXlog) return(x+dx);
+  double xpix, dxpix, tmp, ret;
+  UC2GrC(x, yMin, xpix, tmp); 
+  DUC2GrC(dx, 0., dxpix, tmp);
+  if ( ((dx < 0.) && !aXdir) || ((dx >= 0.) && aXdir) )  dxpix = -dxpix;
+  GrC2UC(xpix+dxpix, yW0, ret, tmp);
+  return(ret);  
+}
+
+/* --Methode-- */
+double PIGraphicUC::DeltaUCY(double y, double dy)
+{
+  if (!aYlog) return(y+dy);
+  double ypix, dypix, tmp, ret;
+  UC2GrC(xMin, y, tmp, ypix); 
+  DUC2GrC(0, dy, tmp, dypix);
+  if ( ((dy < 0.) && aYdir) || ((dy >= 0.) && !aYdir) )  dypix = -dypix;
+  GrC2UC(xW0, ypix+dypix, tmp, ret);
+  return(ret);  
+}
+
+
+
+/* --Methode-- */
+void PIGraphicUC::Erase(PIGrCoord xc, PIGrCoord yc, PIGrCoord dxc, PIGrCoord dyc)
+{
+  if (!mGrC) return;
+  double x, y, dx, dy;
+  x = xc;  dx = dxc;
+  y = yc;  dy = dyc;
+  if (clip) {
+    if (dx < 0) {
+      x = x+dx;
+      dx = -dx;
+    }
+    if (dy < 0) {
+      y = y+dy;
+      dy = -dy;
+    }
+    if (x > xMax || x+dx < xMin || y > yMax || y+dy < yMin) return;
+    if (x < xMin) {
+      dx -= (xMin-x);
+      x = xMin;
+    }
+    if (y < yMin) {
+      dy -= (yMin-y);
+      y = yMin;
+    }
+    if (x+dx > xMax)
+      dx = (xMax-x);
+    if (y+dy > yMax)
+      dy = (yMax-y);
+  }
+
+  double xf, yf, xf2, yf2;
+  UC2GrC(x, y, xf, yf);
+  UC2GrC(x+dx, y+dy, xf2, yf2);
+  if (xf2 < xf)  dbl_swap(xf, xf2);
+  if (yf2 < yf)  dbl_swap(yf, yf2);
+  mGrC->Erase(xf, yf, xf2-xf, yf2-yf);
+}
+
+/* --Methode-- */
+void PIGraphicUC::DrawString(PIGrCoord x, PIGrCoord y, const char* s, unsigned long pos)
+{
+  if (!mGrC) return;
+  double xf, yf;
+  UC2GrC(x, y, xf, yf);
+  mGrC->DrawString(xf, yf, s, pos);  
+}
+
+/* --Methode-- */
+void PIGraphicUC::DrawOpaqueString(PIGrCoord x, PIGrCoord y, const char* s, unsigned long pos)
+{
+  if (!mGrC) return;
+  double xf, yf;
+  UC2GrC(x, y, xf, yf);
+  mGrC->DrawOpaqueString(xf, yf, s, pos);  
+}
+
+/* --Methode-- */
+void PIGraphicUC::DrawCompString(PIGrCoord x, PIGrCoord y, const char* s, 
+				 const char* s_up, const char* s_dn, 
+				 PIFont const & fntss, unsigned long pos)
+{
+  if (!mGrC) return;
+  double xf, yf;
+  UC2GrC(x, y, xf, yf);
+  mGrC->DrawCompString(xf, yf, s, s_up, s_dn, fntss, pos);
+}
+
+/* --Methode-- */
+void PIGraphicUC::DrawLine(PIGrCoord xc1, PIGrCoord yc1, PIGrCoord xc2, PIGrCoord yc2)
+{
+  
+  if (!mGrC) return;
+  double x1, y1, x2, y2;
+  x1 = xc1;  y1 = yc1;
+  x2 = xc2;  y2 = yc2;
+  if (clip) {
+    if (x2 < xMin && x1 < xMin) return;
+    if (x2 > xMax && x1 > xMax) return;
+    if (y1 < yMin && y2 < yMin) return;
+    if (y1 > yMax && y2 > yMax) return;
+    if (x2 < x1) {
+      dbl_swap(x1,x2);
+      dbl_swap(y1,y2);
+    }
+    if (x2>xMax) {
+      y2 = y1 + (y2-y1)/(x2-x1)*(xMax-x1);
+      x2 = xMax;
+    }
+    if (x1<xMin) {
+      y1 = y2 + (y1-y2)/(x1-x2)*(xMin-x2);
+      x1 = xMin;
+    }
+    if (y2 < y1) {
+      dbl_swap(x1,x2);
+      dbl_swap(y1,y2);
+    }
+    if (y2>yMax) {
+      x2 = x1 + (x2-x1)/(y2-y1)*(yMax-y1);
+      y2 = yMax;
+    }
+    if (y1<yMin) {
+      x1 = x2 + (x1-x2)/(y1-y2)*(yMin-y2);
+      y1 = yMin;
+    }
+  }
+
+  double xf1, yf1, xf2, yf2;
+  UC2GrC(x1, y1, xf1, yf1);
+  UC2GrC(x2, y2, xf2, yf2);
+  mGrC->DrawLine(xf1, yf1, xf2, yf2);
+
+}  
+
+
+/* --Methode-- */
+void PIGraphicUC::DrawBox(PIGrCoord xc, PIGrCoord yc, PIGrCoord dxc, PIGrCoord dyc)
+{
+  if (!mGrC) return;
+  double x, y, dx, dy;
+  x = xc;  dx = dxc;
+  y = yc;  dy = dyc;
+  if (clip) {
+    if (dx < 0) {
+      x = x+dx;
+      dx = -dx;
+    }
+    if (dy < 0) {
+      y = y+dy;
+      dy = -dy;
+    }
+    if (x > xMax || x+dx < xMin || y > yMax || y+dy < yMin) return;
+    if (x < xMin) {
+      dx -= (xMin-x);
+      x = xMin;
+    }
+    if (y < yMin) {
+      dy -= (yMin-y);
+      y = yMin;
+    }
+    if (x+dx > xMax)
+      dx = (xMax-x);
+    if (y+dy > yMax)
+      dy = (yMax-y);
+  }
+
+  double xf, yf, xf2, yf2;
+  UC2GrC(x, y, xf, yf);
+  UC2GrC(x+dx, y+dy, xf2, yf2);
+  if (xf2 < xf)  dbl_swap(xf, xf2);
+  if (yf2 < yf)  dbl_swap(yf, yf2);
+  mGrC->DrawBox(xf, yf, xf2-xf, yf2-yf);
+}  
+
+/* --Methode-- */
+void PIGraphicUC::DrawFBox(PIGrCoord xc, PIGrCoord yc, PIGrCoord dxc, PIGrCoord dyc)
+{
+  if (!mGrC) return;
+  double x, y, dx, dy;
+  x = xc;  dx = dxc;
+  y = yc;  dy = dyc;
+  if (clip) {
+    if (dx < 0) {
+      x = x+dx;
+      dx = -dx;
+    }
+    if (dy < 0) {
+      y = y+dy;
+      dy = -dy;
+    }
+    if (x > xMax || x+dx < xMin || y > yMax || y+dy < yMin) return;
+    if (x < xMin) {
+      dx -= (xMin-x);
+      x = xMin;
+    }
+    if (y < yMin) {
+      dy -= (yMin-y);
+      y = yMin;
+    }
+    if (x+dx > xMax)
+      dx = (xMax-x);
+    if (y+dy > yMax)
+      dy = (yMax-y);
+  }
+
+  double xf, yf, xf2, yf2;
+  UC2GrC(x, y, xf, yf);
+  UC2GrC(x+dx, y+dy, xf2, yf2);
+  if (xf2 < xf)  dbl_swap(xf, xf2);
+  if (yf2 < yf)  dbl_swap(yf, yf2);
+  mGrC->DrawFBox(xf, yf, xf2-xf, yf2-yf);
+}  
+
+/* --Methode-- */
+void PIGraphicUC::DrawCircle(PIGrCoord x, PIGrCoord y, PIGrCoord r)
+{
+  if (!mGrC) return;
+
+  double xf, yf, rf,rfy;
+  UC2GrC(x, y, xf, yf);
+  DUC2GrC(r,r,rf,rfy);
+  rf = 0.5*(rf+rfy);
+  mGrC->DrawCircle(xf, yf, rf);
+}  
+
+/* --Methode-- */
+void PIGraphicUC::DrawFCircle(PIGrCoord x, PIGrCoord y, PIGrCoord r)
+{
+  if (!mGrC) return;
+
+  double xf, yf, rf, rfy;
+  UC2GrC(x, y, xf, yf);
+  DUC2GrC(r,r,rf,rfy);
+  rf = 0.5*(rf+rfy);
+  mGrC->DrawFCircle(xf, yf, rf);
+}
+
+/* --Methode-- */
+void PIGraphicUC::DrawOval(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+{
+  if (!mGrC) return;
+
+  double xf, yf, dxf, dyf;
+  UC2GrC(x0, y0, xf, yf);
+  DUC2GrC(dx, dy, dxf, dyf);
+  mGrC->DrawOval(xf, yf, dxf, dyf);
+}
+
+/* --Methode-- */
+void PIGraphicUC::DrawFOval(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+{
+  if (!mGrC) return;
+
+  double xf, yf, dxf, dyf;
+  UC2GrC(x0, y0, xf, yf);
+  DUC2GrC(dx, dy, dxf, dyf);
+  mGrC->DrawFOval(xf, yf, dxf, dyf);
+}
+
+#define NMXMULTP  30   // Pour multipoint sans new
+
+/* --Methode-- */
+void PIGraphicUC::DrawPolygon(PIGrCoord *x, PIGrCoord *y, int n, bool cinc)
+{
+  PIGrCoord xc[NMXMULTP], yc[NMXMULTP];
+  PIGrCoord *pxc, *pyc;
+  int i;
+  double xf, yf;
+ 
+  if (!mGrC) return;
+  if (n <= 0)  return;
+
+  if (n > NMXMULTP) { pxc = new PIGrCoord[n];  pyc = new PIGrCoord[n]; }
+  else { pxc = xc;  pyc = yc; }
+  for(i=0; i<n; i++) {
+    UC2GrC(x[i], y[i], xf, yf);
+    pxc[i] = xf;  pyc[i] = yf; 
+  }
+  mGrC->DrawPolygon(pxc, pyc, n, cinc);
+  if (n > NMXMULTP) { delete[] pxc;  delete[] pyc; }
+  return;
+}
+  
+/* --Methode-- */
+void PIGraphicUC::DrawFPolygon(PIGrCoord *x, PIGrCoord *y, int n, bool cinc)
+{
+  PIGrCoord xc[NMXMULTP], yc[NMXMULTP];
+  PIGrCoord *pxc, *pyc;
+  int i;
+  double xf, yf;
+ 
+  if (!mGrC) return;
+  if (n <= 0)  return;
+
+  if (n > NMXMULTP) { pxc = new PIGrCoord[n];  pyc = new PIGrCoord[n]; }
+  else { pxc = xc;  pyc = yc; }
+  for(i=0; i<n; i++) {
+    UC2GrC(x[i], y[i], xf, yf);
+    pxc[i] = xf;  pyc[i] = yf; 
+  }
+  mGrC->DrawFPolygon(pxc, pyc, n, cinc);
+  if (n > NMXMULTP) { delete[] pxc;  delete[] pyc; }
+  return;
+}
+
+
+/* --Methode-- */
+void PIGraphicUC::DrawArc(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy,
+                          double degdeb, double deltadeg)
+{
+  if (!mGrC) return;
+
+  double xf, yf, dxf, dyf;
+  UC2GrC(x0, y0, xf, yf);
+  DUC2GrC(dx, dy, dxf, dyf);
+  // $CHECK$ - Reza Nov 2002 , Il faudra aussi tenir compte de l'axe X
+  if (!isAxeYDirUpDown()) degdeb = 360.-(degdeb+deltadeg);
+  mGrC->DrawArc(xf, yf, dxf, dyf, degdeb, deltadeg);
+}
+/* --Methode-- */
+void PIGraphicUC::DrawFArc(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy,
+                           double degdeb, double deltadeg)
+{
+  if (!mGrC) return;
+
+  double xf, yf, dxf, dyf;
+  UC2GrC(x0, y0, xf, yf);
+  DUC2GrC(dx, dy, dxf, dyf);
+  // $CHECK$ - Reza Nov 2002 , Il faudra aussi tenir compte de l'axe X
+  if (!isAxeYDirUpDown()) degdeb = 360.-(degdeb+deltadeg);
+  mGrC->DrawFArc(xf, yf, dxf, dyf, degdeb, deltadeg);
+}
+
+/* --Methode-- */
+void PIGraphicUC::Draw3PtArc(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2,
+			     PIGrCoord x3, PIGrCoord y3)
+  // Trace d'un arc de cercle passant par 3 points
+{
+  if (!mGrC) return;
+  double xf1, xf2, xf3;
+  double yf1, yf2, yf3;
+  UC2GrC(x1, y1, xf1, yf1);
+  UC2GrC(x2, y2, xf2, yf2);
+  UC2GrC(x3, y3, xf3, yf3);
+  mGrC->Draw3PtArc(xf1, yf1, xf2, yf2, xf3, yf3);
+}
+
+/* --Methode-- */
+void PIGraphicUC::Draw3PtFArc(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2,
+			      PIGrCoord x3, PIGrCoord y3)
+  // Trace d'un arc de cercle passant par 3 points
+{
+  if (!mGrC) return;
+  double xf1, xf2, xf3;
+  double yf1, yf2, yf3;
+  UC2GrC(x1, y1, xf1, yf1);
+  UC2GrC(x2, y2, xf2, yf2);
+  UC2GrC(x3, y3, xf3, yf3);
+  mGrC->Draw3PtFArc(xf1, yf1, xf2, yf2, xf3, yf3);
+}
+
+
+/* --Methode-- */
+void PIGraphicUC::DrawMarker(PIGrCoord x0, PIGrCoord y0)
+{
+  if (!mGrC) return;
+  double xf, yf;
+  UC2GrC(x0, y0, xf, yf);
+  mGrC->DrawMarker(xf, yf);
+  return;
+}
+
+/* --Methode-- */
+void PIGraphicUC::DrawMarkers(PIGrCoord *x, PIGrCoord *y, int n)
+{
+  PIGrCoord xc[NMXMULTP], yc[NMXMULTP];
+  PIGrCoord *pxc, *pyc;
+  int i;
+  double xf, yf;
+ 
+  if (!mGrC) return;
+  if (n <= 0)  return;
+
+  if (n > NMXMULTP) { pxc = new PIGrCoord[n];  pyc = new PIGrCoord[n]; }
+  else { pxc = xc;  pyc = yc; }
+  for(i=0; i<n; i++) {
+    UC2GrC(x[i], y[i], xf, yf);
+    pxc[i] = xf;  pyc[i] = yf; 
+  }
+  mGrC->DrawMarkers(pxc, pyc, n);
+  if (n > NMXMULTP) { delete[] pxc;  delete[] pyc; }
+  return;
+}
+
+/* --Methode-- */
+void PIGraphicUC::DrawArrowMarker(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2, bool fgline)
+{
+  if (!mGrC) return;
+  double xf1, yf1, xf2, yf2;
+  UC2GrC(x1, y1, xf1, yf1);
+  UC2GrC(x2, y2, xf2, yf2);
+  mGrC->DrawArrowMarker(xf1, yf1, xf2, yf2, fgline);
+}
+
+/* --Methode-- */
+void PIGraphicUC::DrawPixmap(PIGrCoord x, PIGrCoord y, unsigned char *pix,
+                        int sx, int sy, PIColorMap* cmap)
+{
+  if (!mGrC) return;
+  if ( (sx < 1) || (sy < 1) )  return;
+  if ((pix == NULL) || (cmap == NULL)) return; 
+  double xf,yf;
+  UC2GrC(x, y, xf, yf);
+  mGrC->DrawPixmap(xf, yf, pix, sx, sy, cmap);
+}
+
+
+
+/* --Methode-- */
+void PIGraphicUC::SelForeground(PIColors col)
+{
+  if (!mGrC) return;
+  mGrC->SelForeground(col);
+  return;  
+}
+
+
+/* --Methode-- */
+void PIGraphicUC::SelBackground(PIColors col)
+{
+  if (!mGrC) return;
+  mGrC->SelBackground(col);
+  return;  
+}
+
+/* --Methode-- */
+void PIGraphicUC::SelForeground(PIColorMap& cmap, int cid)
+{
+  if (!mGrC) return;
+  mGrC->SelForeground(cmap, cid);
+  return;  
+}
+
+
+/* --Methode-- */
+void PIGraphicUC::SelBackground(PIColorMap& cmap, int cid)
+{
+  if (!mGrC) return;
+  mGrC->SelBackground(cmap, cid);
+  return;  
+}
+
+/* --Methode-- */
+void PIGraphicUC::SelGOMode(PIGOMode mod)
+{
+  if (!mGrC) return;
+  mGrC->SelGOMode(mod);
+  return;  
+}
+
+/* --Methode-- */
+void PIGraphicUC::SelFont(PIFont & fnt)
+{
+  if (!mGrC) return;
+  mGrC->SelFont(fnt);
+  myFont = mGrC->GetFont();
+  return;  
+}
+
+/* --Methode-- */
+void PIGraphicUC::SelFont(PIFontSize sz, PIFontAtt att)
+{
+  if (!mGrC) return;
+  mGrC->SelFont(sz, att);
+  myFont = mGrC->GetFont();
+  return;  
+}
+
+/* --Methode-- */
+void PIGraphicUC::SelFontSzPt(int npt, PIFontAtt att)
+{
+  if (!mGrC) return;
+  mGrC->SelFontSzPt(npt, att);
+  myFont = mGrC->GetFont();
+  return;  
+}
+
+
+/* --Methode-- */
+void PIGraphicUC::SelLine(PILineAtt const& att)
+{
+  if (!mGrC) return;
+  mGrC->SelLine(att);
+  return;  
+}
+
+/* --Methode-- */
+void PIGraphicUC::SelMarker(int msz, PIMarker mrk)
+{
+  if (!mGrC) return;
+  mGrC->SelMarker( msz, mrk);
+}
+
+/* --Methode-- */
+void PIGraphicUC::SelArrowMarker(int arrsz, PIArrowMarker arrmrk)
+{
+  if (!mGrC) return;
+  mGrC->SelArrowMarker(arrsz, arrmrk);
+}
+
+/* --Methode-- */
+void PIGraphicUC::SelFontSz(PIGrCoord sz)
+{
+  if (!mGrC) return;
+  SelFontSz(sz, mGrC->GetFont().GetFontAtt());
+}
+
+/* --Methode-- */
+void PIGraphicUC::SelFontSz(PIGrCoord sz, PIFontAtt att)
+{
+  if (!mGrC) return;
+  double fx, fy;
+  DUC2GrC((double)sz, (double)sz, fx, fy);
+  int npt = (int)fy;
+  if (npt < 6) npt = 6;
+  if (npt > 127) npt = 127;
+  mGrC->SelFontSzPt(npt, att);
+  myFont = mGrC->GetFont();
+}
+
+
+/* --Methode-- */
+void PIGraphicUC::SelMarkerSz(PIGrCoord sz, PIMarker mrk)
+{
+  if (!mGrC) return;
+  double fx, fy;
+  DUC2GrC((double)sz, (double)sz, fx, fy);
+  int isz = int(0.5*(fx+fy+1));
+  mGrC->SelMarker( isz, mrk);
+}
+
+/* --Methode-- */
+void PIGraphicUC::SelArrowMarkerSz(PIGrCoord arrsz, PIArrowMarker arrmrk)
+{
+  if (!mGrC) return;
+  double fx, fy;
+  DUC2GrC((double)arrsz, (double)arrsz, fx, fy);
+  int asz = int(fy+0.5);
+  if (asz < 3) asz = 3;
+  if (asz > 127) asz = 127;
+  mGrC->SelArrowMarker(asz, arrmrk);
+}
+
+/* --Methode-- */
+void PIGraphicUC::SetClipRectangle(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+{
+  /* $CHECK$  A faire Reza 08/02/97  */
+return;
+}
+/* --Methode-- */
+void PIGraphicUC::ClearClipRectangle()
+{
+  /* $CHECK$  A faire Reza 08/02/97  */
+return;
+}
+
+/* --Methode-- */
+PIColors PIGraphicUC::GetForeground()
+{
+  if (!mGrC) return(PI_NotDefColor);
+  return(mGrC->GetForeground());
+}
+
+/* --Methode-- */
+PIColors PIGraphicUC::GetBackground()
+{
+  if (!mGrC) return(PI_NotDefColor);
+  return(mGrC->GetBackground());
+}
+
+/* --Methode-- */
+PIGOMode PIGraphicUC::GetGOMode()
+{
+  if (!mGrC) return(PI_GOCopy);
+  return(mGrC->GetGOMode());
+}
+
+
+/* --Methode-- */
+PILineAtt PIGraphicUC::GetLineAtt()
+{
+  if (!mGrC) return(PI_NotDefLineAtt);
+  return(mGrC->GetLineAtt());
+}
+
+/* --Methode-- */
+PIMarker PIGraphicUC::GetMarker()
+{
+  if (!mGrC) return(PI_NotDefMarker);
+  return(mGrC->GetMarker());
+}
+
+/* --Methode-- */
+int PIGraphicUC::GetMarkerSize()
+{
+  if (!mGrC) return(0);
+  return(mGrC->GetMarkerSize());
+}
+
+/* --Methode-- */
+PIArrowMarker PIGraphicUC::GetArrowMarker()
+{
+  if (!mGrC) return(PI_NotDefArrowMarker);
+  return(mGrC->GetArrowMarker());
+}
+
+/* --Methode-- */
+int PIGraphicUC::GetArrowMarkerSize()
+{
+  if (!mGrC) return(0);
+  return(mGrC->GetArrowMarkerSize());
+}
+
+
+/* --Methode-- */
+PIGrCoord PIGraphicUC::GetFontHeight(PIGrCoord& asc, PIGrCoord& desc)
+{
+  asc = desc = 0;
+  if (!mGrC) return(0);
+  int h,a,d;
+  double fh, fa, fd, x;
+  h = myFont.GetFontHeight(a, d) ;
+  DGrC2UC(0., h, x, fh);
+  DGrC2UC(0., a, x, fa);
+  DGrC2UC(0., d, x, fd);
+  asc = a;  desc = d;
+  return(fh);
+}
+
+
+/* --Methode-- */
+PIGrCoord PIGraphicUC::CalcStringWidth(char const* s)
+{
+  if (!mGrC) return(0.);
+  double dx = myFont.GetStringWidth(s);
+  double dxx, dxy;
+  DGrC2UC(dx, dx, dxx, dxy);
+  return(dxx);
+}
+
+
+/* --Methode-- */
+void PIGraphicUC::SaveGraphicAtt()
+{
+  if (!mGrC) return;
+  mGrC->SaveGraphicAtt();
+}
+
+/* --Methode-- */
+void PIGraphicUC::RestoreGraphicAtt()
+{
+  if (!mGrC) return;
+  mGrC->RestoreGraphicAtt();
+}
+
Index: /tags/V_Dec2002/SophyaPI/PI/pigraphuc.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pigraphuc.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pigraphuc.h	(revision 2309)
@@ -0,0 +1,161 @@
+// Module PI : Peida Interactive     PIGraphicUC 
+// Trace graphiques User-Coordinates    R. Ansari  97
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PIGRAPHICUC_H_SEEN
+#define PIGRAPHICUC_H_SEEN
+
+#include "pisysdep.h"
+#include "pigraphgen.h"
+
+enum {
+  kAxeDirSame     = 0,
+  kAxeDirLtoR     = 1,
+  kAxeDirRtoL     = 2,
+  kAxeDirDownUp   = 4,
+  kAxeDirUpDown   = 8,
+  kAxeDirAuto     = 255
+};
+
+class PIGraphicUC : public PIGraphicGen
+{
+public:
+                     PIGraphicUC(PIGraphicGen* g, PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy);
+  virtual           ~PIGraphicUC();
+
+  virtual int        kind();
+
+  virtual void       SetBaseGraphic(PIGraphicGen* g, PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy);
+
+//  Espace des coordonnees
+  virtual void       GetGrSpace(PIGrCoord& xmin, PIGrCoord& xmax, PIGrCoord& ymin, PIGrCoord& ymax);
+
+//  Definition des coordonnees utilisateur
+  virtual void       SetUCS(double xmin, double xmax, double ymin, double ymax,
+                            int axrl=kAxeDirSame, int ayud=kAxeDirSame,
+			    bool exchxy=false); 
+// Echelle logarithmique
+  virtual void	     SetLogScale(bool logx, bool logy);
+  inline  bool	     isLogScaleX() { return aXlog; }
+  inline  bool	     isLogScaleY() { return aYlog; }
+  inline  bool       isAxeXDirRtoL()   { return aXdir; }
+  inline  bool       isAxeYDirUpDown() { return aYdir; }
+  inline  bool       isAxeXYExchanged() { return aXYexchng; }
+
+//  Trace graphiques
+  virtual void       Erase(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy);
+  virtual void       DrawString(PIGrCoord x, PIGrCoord y, const char* s, unsigned long pos = 0);
+  virtual void       DrawOpaqueString(PIGrCoord x, PIGrCoord y, const char* s, unsigned long pos = 0);
+  virtual void       DrawCompString(PIGrCoord x, PIGrCoord y, const char* s, 
+                                    const char* s_up, const char* s_dn, 
+				    PIFont const & fntss, unsigned long pos = 0);
+  inline  void       DrawCompString(PIGrCoord x, PIGrCoord y, const char* s, 
+                                    const char* s_up, const char* s_dn, 
+				    unsigned long pos = 0)
+                     { DrawCompString(x, y, s, s_up, s_dn, GetFont(), pos); }
+
+  virtual void       DrawLine(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2);
+  virtual void       DrawBox(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy);
+  virtual void       DrawFBox(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy);
+  virtual void       DrawCircle(PIGrCoord x0, PIGrCoord y0, PIGrCoord r);
+  virtual void       DrawFCircle(PIGrCoord x0, PIGrCoord y0, PIGrCoord r);
+  virtual void       DrawOval(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy);
+  virtual void       DrawFOval(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy);
+  virtual void       DrawPolygon(PIGrCoord *x, PIGrCoord *y, int n, bool cinc=true);  
+  virtual void       DrawFPolygon(PIGrCoord *x, PIGrCoord *y, int n, bool cinc=true); 
+  virtual void       DrawArc(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy,
+                             double degdeb, double deltadeg);
+  virtual void       DrawFArc(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy, 
+                              double degdeb, double deltadeg);
+  virtual void       Draw3PtArc(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2,
+				PIGrCoord x3, PIGrCoord y3);
+  virtual void       Draw3PtFArc(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2,
+				 PIGrCoord x3, PIGrCoord y3);
+ 
+  virtual void       DrawMarker(PIGrCoord x0, PIGrCoord y0);
+  virtual void       DrawMarkers(PIGrCoord *x, PIGrCoord *y, int n);
+  virtual void       DrawArrowMarker(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2,
+				     bool fgline=true);
+
+  virtual void       DrawPixmap(PIGrCoord x, PIGrCoord y, unsigned char *pix, 
+                                int sx, int sy, PIColorMap* cmap);
+
+// Modifications attributs graphiques
+  virtual void       SelForeground(PIColors col=PI_Black);
+  virtual void       SelBackground(PIColors col=PI_White);
+  virtual void       SelForeground(PIColorMap& cmap, int cid);
+  virtual void       SelBackground(PIColorMap& cmap, int cid);
+  virtual void       SelGOMode(PIGOMode mod=PI_GOCopy);
+  virtual void       SelLine(PILineAtt const& att);
+  virtual void       SelMarker(int msz=3, PIMarker mrk=PI_DotMarker);
+  virtual void       SelArrowMarker(int arrsz=5, 
+				    PIArrowMarker arrmrk=PI_BasicArrowMarker);
+
+// Modification de fonte
+  virtual void       SelFont(PIFont & fnt);
+  virtual void       SelFont(PIFontSize sz=PI_NormalSizeFont, 
+                             PIFontAtt att=PI_RomanFont);
+  virtual void       SelFontSzPt(int npt=12, PIFontAtt att=PI_RomanFont);
+//  Fonctions specifiques a PIGraphicUC :
+  virtual void       SelFontSz(PIGrCoord sz);
+  virtual void       SelFontSz(PIGrCoord sz, PIFontAtt att);
+  virtual void       SelMarkerSz(PIGrCoord msz, PIMarker mrk=PI_DotMarker);
+  virtual void       SelArrowMarkerSz(PIGrCoord arrsz, 
+				      PIArrowMarker arrmrk=PI_BasicArrowMarker);
+
+// Selection de zone de trace (clip)
+  virtual void       SetClipRectangle(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy);
+  virtual void       ClearClipRectangle();
+
+// Acces aux attributs graphiques 
+  virtual PIColors   GetForeground();
+  virtual PIColors   GetBackground();
+  virtual PIGOMode   GetGOMode();
+  virtual PILineAtt  GetLineAtt();
+  virtual PIMarker   GetMarker();
+  virtual int        GetMarkerSize();
+  virtual PIArrowMarker    GetArrowMarker();
+  virtual int        GetArrowMarkerSize();
+
+
+  inline  PIFont     GetFont() { return (mGrC->GetFont()) ; }
+  virtual PIGrCoord  GetFontHeight(PIGrCoord& asc, PIGrCoord& desc);
+  virtual PIGrCoord  CalcStringWidth(char const* s);
+
+
+// Sauvegarde des attributs graphiques 
+  virtual void       SaveGraphicAtt();
+  virtual void       RestoreGraphicAtt();
+
+//  Transformation des ccordonnees
+  virtual void       UC2GrC(double x, double y, double& xpix, double& ypix);
+  virtual void       GrC2UC(double xpix, double ypix, double& x, double& y);
+  virtual void       DUC2GrC(double dx, double dy, double& dxpix, double& dypix);
+  virtual void       DGrC2UC(double dxpix, double dypix, double& dx, double& dy);
+  virtual void	     LinUC2GrC(double x, double y, double& xpix, double& ypix);
+  virtual double     DeltaUCX(double x, double dx);
+  virtual double     DeltaUCY(double y, double dy);
+
+  void   NoClip() {clip = false; }
+  void   Clip() {clip = true; }
+  inline PIGraphicGen*  BaseGraphic() { return(mGrC); }
+
+protected:
+  
+  PIGraphicGen* mGrC;
+
+  double xMin, xMax, yMin, yMax; // Valeurs en unites user
+  double xOrg, yOrg;             // Position en pixels de (0.0, 0.0)
+  double xScale, yScale;         // Pixels par unites graphiques
+  double xMinLog, yMinLog;       // Limite basse (>0,x,yMin) pour echelle log
+  double xOrgLog, yOrgLog;       // Position en pixels de log10(xyMinLog)
+  double xScaleLog, yScaleLog;   // Pixels par unites graphiques Echelle Log
+  double xW0, yW0, xWd, yWd;     // Origine/largeur ds la fenetre de trace
+  bool   aXdir, aYdir;           // Sens des axes horiz, vertical 
+  bool   aXlog, aYlog;		 // true-> Echelle logarithmique pour axe X,y 
+  bool   aXYexchng;              // true-> Echange X<>Y userX, Y ---> WindowY, X
+  bool   clip;
+};
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pigraphx.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pigraphx.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pigraphx.cc	(revision 2309)
@@ -0,0 +1,898 @@
+// Module PI : Peida Interactive     PIGraphicX
+// Trace graphiques- Implementation X11  R. Ansari  97
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include <stdio.h>
+#include <math.h>
+
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#include <X11/Xutil.h>
+
+#include "pigraphx.h"
+
+
+/*  Variables globales pour modifier les GC  */
+#define NMAXCOL  32
+static  PIXColor colpix[NMAXCOL];
+
+/*  GC pour DrawPixmap   
+    static GC dpxgc;   Pas utile ?? - Reza 02/05/2002 */
+
+// #define DEBUG_PIBWDGX     Flag pour impression de debug etc ...
+
+/* --Methode-- */
+PIGraphicX::PIGraphicX(PIWdg* wdg)
+: PIGraphicGen(wdg)
+{
+
+GlInit();
+
+if (MyWdg()) {
+  mDisp = XtDisplay(MyWdg());       // Structure Display X associe
+  mWId = XtWindow(MyWdg());   // Le drawable X
+  }
+else mDisp = PIXDisplay();       // Structure Display X associe
+
+XGCValues  xgv;
+xgv.function = GXcopy;
+xgv.plane_mask = ~0;
+mDefGC = XCreateGC (PIXDisplay(), XtWindow(PIXtTopWdg()), GCFunction | GCPlaneMask, &xgv);
+mMrkGC = XCreateGC (PIXDisplay(), XtWindow(PIXtTopWdg()), GCFunction | GCPlaneMask, &xgv);
+mFgMrkGCOK = false;
+Init();
+}
+
+/* --Methode-- */
+PIGraphicX::PIGraphicX(PIScreenBuffer* grb)
+: PIGraphicGen(grb)
+{
+GlInit();
+
+mDisp = PIXDisplay();       // Structure Display X associe
+mWId = grb->XScrBuffer();
+
+XGCValues  xgv;
+xgv.function = GXcopy;
+xgv.plane_mask = ~0;
+mDefGC = XCreateGC (mDisp, mWId, GCFunction | GCPlaneMask, &xgv);
+mMrkGC = XCreateGC (PIXDisplay(), XtWindow(PIXtTopWdg()), GCFunction | GCPlaneMask, &xgv);
+mFgMrkGCOK = false;
+Init();
+}
+
+
+/* --Methode-- */
+void PIGraphicX::Init()
+{
+mGOm = PI_GOCopy;
+mFCol = mBCol = PI_Grey;
+SelForeground(PI_Black);
+SelBackground(PI_White);
+mLAtt = PI_NotDefLineAtt;
+ XSetFont(mDisp, DefGC(), myFont.GetXFontId());  // Pour initialiser la fonte ds le GC 
+SelLine(PI_NormalLine);
+SelMarker(1, PI_DotMarker);  
+mFCfMap = colpix[PI_Black];  mBCfMap = colpix[PI_White];
+mFgMrkGCOK = false;
+}
+
+/* --Methode-- */
+PIGraphicX::~PIGraphicX()
+{
+XFreeGC(mDisp, mDefGC);
+XFreeGC(mDisp, mMrkGC);
+}
+
+/* --Methode-- */
+int PIGraphicX::kind()
+{
+if (myWdg != NULL) return (PI_ScrWindowGraphics);
+else if (myGrb != NULL) return (PI_ScrBufferGraphics);
+else return(PI_UnknownGraphics);
+}
+
+/* --Methode-- */
+void PIGraphicX::TerminateInit()
+{
+if (MyWdg() == NULL)  { fprintf(stderr, "BUG/PIGraphicX::TerminateInit() for NULL Wdg \n"); return; }
+mDisp = XtDisplay(MyWdg());       // Structure Display X associe
+mWId = XtWindow(MyWdg());   // Le drawable X
+}
+
+/* --Methode-- */
+void PIGraphicX::Erase(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+{
+XClearArea (mDisp,mWId, (int)x0, (int)y0, (int)dx, (int)dy, False );
+return;
+}
+
+/* --Methode-- */
+void PIGraphicX::DrawString(PIGrCoord x, PIGrCoord y, const char* s, unsigned long pos)
+{
+int dx, dy, xi, yi;
+xi = x;  yi = y;
+bool fgcsps = CalcStringPositionShift(s, pos, dx, dy);
+unsigned long txtdir = pos&PI_TextDirection;
+if (txtdir == PI_TextDirectionHorizontal) {
+  if (fgcsps) { xi -= dx;  yi -= dy; }
+  XDrawString (mDisp, mWId, DefGC(), xi, yi, s, strlen(s));
+}
+else { 
+  if (txtdir == PI_TextDirectionVerticalDown) { xi += dy; yi -= dx; }
+  else {   xi -= dy; yi += dx; }
+  DrawVerticalString(xi, yi, s, txtdir, false);
+}
+return;
+}
+
+/* --Methode-- */
+void PIGraphicX::DrawOpaqueString(PIGrCoord x, PIGrCoord y, const char* s, unsigned long pos)
+{
+int dx, dy, xi, yi;
+xi = x;  yi = y;
+bool fgcsps = CalcStringPositionShift(s, pos, dx, dy);
+unsigned long txtdir = pos&PI_TextDirection;
+if (txtdir == PI_TextDirectionHorizontal) {
+  if (fgcsps) { xi -= dx;  yi -= dy; }
+  XDrawImageString (mDisp, mWId, DefGC(), xi, yi, s, strlen(s));
+}
+else { 
+  if (txtdir == PI_TextDirectionVerticalDown) { xi += dy; yi -= dx; }
+  else {   xi -= dy; yi += dx; }
+  DrawVerticalString(xi, yi, s, txtdir, true);
+}
+return;
+}
+
+ 
+/* --Methode-- */
+void PIGraphicX::DrawLine(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2)
+{
+XDrawLine(mDisp, mWId, DefGC(), (int)x1, (int)y1, (int)x2, (int)y2);
+return;
+}
+
+
+/* --Methode-- */
+void PIGraphicX::DrawBox(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+{
+int ix0 = x0;
+int iy0 = y0;
+int idx = dx;
+int idy = dy;
+if (idx < 0)  { ix0 += idx;  idx = -idx; }
+if (idy < 0)  { iy0 += idy;  idy = -idy; }
+XDrawRectangle(mDisp, mWId, 
+               DefGC(), ix0, iy0, idx, idy);
+return;
+}
+
+/* --Methode-- */
+void PIGraphicX::DrawFBox(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+{
+int ix0 = x0;
+int iy0 = y0;
+int idx = dx;
+int idy = dy;
+if (idx < 0)  { ix0 += idx;  idx = -idx; }
+if (idy < 0)  { iy0 += idy;  idy = -idy; }
+XFillRectangle(mDisp, mWId, 
+               DefGC(), ix0, iy0, idx, idy);
+return;
+}
+
+/* --Methode-- */
+void PIGraphicX::DrawCircle(PIGrCoord x0, PIGrCoord y0, PIGrCoord r)
+{
+XDrawArc(mDisp, mWId, DefGC(),
+         (int)x0-(int)r, (int)y0-(int)r, 2*(int)r, 2*(int)r, 0, 360*64);
+return;
+}
+
+/* --Methode-- */
+void PIGraphicX::DrawFCircle(PIGrCoord x0, PIGrCoord y0, PIGrCoord r)
+{
+XFillArc(mDisp, mWId, DefGC(),
+         (int)x0-(int)r, (int)y0-(int)r, 2*(int)r, 2*(int)r, 0, 360*64);
+return;
+}
+
+/* --Methode-- */
+void PIGraphicX::DrawOval(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+{
+XDrawArc(mDisp, mWId, DefGC(),
+         (int)x0-(int)dx, (int)y0-(int)dy, (int)dx*2, (int)dy*2, 0, 360*64);
+return;
+}
+
+/* --Methode-- */
+void PIGraphicX::DrawFOval(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+{
+XFillArc(mDisp, mWId, DefGC(),
+         (int)x0-(int)dx, (int)y0-(int)dy, (int)dx*2, (int)dy*2, 0, 360*64);
+return;
+}
+
+// Pour les fonctions de trace avec un plusieurs coordonnees
+#define NMXXPOINTS  30 
+
+/* --Methode-- */
+void PIGraphicX::DrawPolygon(PIGrCoord *x, PIGrCoord *y, int n, bool cinc)
+{
+XPoint multipoint[NMXXPOINTS];
+XPoint *pxp;
+int i;
+
+if (n <= 0)  return;
+if (n > NMXXPOINTS)  pxp = new XPoint[n];
+else pxp = multipoint;
+for(i=0; i<n; i++)  { pxp[i].x = x[i];  pxp[i].y = y[i]; } 
+int mode = CoordModeOrigin;
+if (cinc) mode =  CoordModePrevious;
+XDrawLines(mDisp, mWId, DefGC(), pxp, n, mode);
+if (n > NMXXPOINTS)  delete[] pxp;
+
+return;
+}
+
+
+/* --Methode-- */
+void PIGraphicX::DrawFPolygon(PIGrCoord *x, PIGrCoord *y, int n, bool cinc)
+{
+XPoint multipoint[NMXXPOINTS];
+XPoint *pxp;
+int i;
+
+if (n <= 0)  return;
+if (n > NMXXPOINTS)  pxp = new XPoint[n];
+else pxp = multipoint;
+for(i=0; i<n; i++)  { pxp[i].x = x[i];  pxp[i].y = y[i]; } 
+int mode = CoordModeOrigin;
+if (cinc) mode =  CoordModePrevious;
+XFillPolygon(mDisp, mWId, DefGC(), pxp, n, 
+                        Complex, mode);
+if (n > NMXXPOINTS)  delete[] pxp;
+
+return;
+}
+
+
+/* --Methode-- */
+void PIGraphicX::DrawArc(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy, 
+                         double degdeb, double deltadeg)
+{
+// Convention X est ds le sens trigo inverse
+degdeb = 360. - (degdeb+deltadeg);
+XDrawArc(mDisp, mWId, DefGC(),
+         (int)x0-(int)dx, (int)y0-(int)dy, (int)dx*2, (int)dy*2, (int)(degdeb*64.), (int)(deltadeg*64.));
+return;
+}
+
+/* --Methode-- */
+void PIGraphicX::DrawFArc(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy, 
+                         double degdeb, double deltadeg)
+{
+degdeb = 360. - (degdeb+deltadeg);
+XFillArc(mDisp, mWId, DefGC(),
+         (int)x0-(int)dx, (int)y0-(int)dy, (int)dx*2, (int)dy*2, (int)(degdeb*64.), (int)(deltadeg*64.));
+return;
+}
+
+// Coordonnees pour tracer une etoile a 5 branches 
+static float starcoordx[10], starcoordy[10];
+
+/* --Methode-- */
+void PIGraphicX::DrawMarker(PIGrCoord x0, PIGrCoord y0)
+{
+
+if (mMrk == PI_DotMarker) {
+  XDrawPoint(mDisp, mWId, DefGC(), (int)x0, (int)y0);
+  return;
+}
+else  {
+  int x1,x2,y1,y2,r;
+  float hmsz = mMrkSz/2;
+  float dmsz = mMrkSz-hmsz;
+  XPoint pxp[12];
+  int k;
+  bool fgcgc = SetupMrkGC();
+  switch (mMrk) {
+    case  PI_PlusMarker :
+      x1 = (float)x0-hmsz;   y1 = y0;
+      x2 = (float)x0+dmsz;   y2 = y1;
+      XDrawLine(mDisp, mWId, mMrkGC, x1, y1, x2, y2);
+      x1 = x0;  y1 = (float)y0-hmsz;
+      x2 = x1;  y2 = (float)y0+dmsz;
+      XDrawLine(mDisp, mWId, mMrkGC, x1, y1, x2, y2);
+      break;
+    case  PI_CrossMarker :
+      x1 = (float)x0-hmsz;   y1 = (float)y0-hmsz;
+      x2 = (float)x0+dmsz;   y2 = (float)y0+dmsz;
+      XDrawLine(mDisp, mWId, mMrkGC, x1, y1, x2, y2);
+      XDrawLine(mDisp, mWId, mMrkGC, x1, y2, x2, y1);
+      break;  
+    case PI_CircleMarker :
+    case PI_FCircleMarker :
+      r = hmsz;
+      x1 = (int)x0-r;  y1 = (int)y0-r;
+      if (mMrk == PI_CircleMarker) 
+	XDrawArc(mDisp, mWId, mMrkGC, x1, y1, 2*r, 2*r, 0, 360*64);
+      else XFillArc(mDisp, mWId, mMrkGC, x1, y1, 2*r, 2*r, 0, 360*64);
+      break;
+    case PI_BoxMarker :
+    case PI_FBoxMarker :
+      pxp[0].x = (int)x0-hmsz;  pxp[0].y = (int)y0-hmsz;
+      pxp[1].x = (int)x0+hmsz;  pxp[1].y = (int)y0-hmsz;
+      pxp[2].x = (int)x0+hmsz;  pxp[2].y = (int)y0+hmsz;
+      pxp[3].x = (int)x0-hmsz;  pxp[3].y = (int)y0+hmsz;
+      pxp[4].x = (int)x0-hmsz;  pxp[4].y = (int)y0-hmsz;
+      if (mMrk == PI_BoxMarker) MrkDrawPolygon(pxp, 5, false);
+      else MrkDrawFPolygon(pxp, 5, false);
+      break;
+    case  PI_TriangleMarker :
+    case  PI_FTriangleMarker :
+      pxp[1].x = mMrkSz; pxp[1].y = 0; pxp[2].x = -hmsz; pxp[2].y = -mMrkSz;
+      pxp[3].x = -dmsz;  pxp[3].y = +mMrkSz; pxp[0].x = (float)x0-hmsz; pxp[0].y = (float)y0+hmsz;
+      if (mMrk == PI_TriangleMarker) MrkDrawPolygon(pxp, 4, true);
+      else MrkDrawFPolygon(pxp, 4, true);
+      break;
+    case  PI_StarMarker :
+    case  PI_FStarMarker :
+      for(k=0; k<10; k++) {
+        pxp[k].x = (int)(starcoordx[k]*hmsz+(float)x0+0.5);
+        pxp[k].y = (int)(starcoordy[k]*hmsz+(float)y0+0.5);
+        }
+      pxp[10].x = pxp[0].x;   pxp[10].y = pxp[0].y;
+      if (mMrk == PI_StarMarker)   MrkDrawPolygon(pxp, 11, false);
+      else  MrkDrawFPolygon(pxp, 11, false);
+      break;
+    default :
+      XDrawPoint(mDisp, mWId, DefGC(), x0, y0);
+      break;
+    }
+  if (fgcgc) mFgMrkGCOK = false;
+  }
+
+return;
+}
+
+/* --Methode-- */
+void PIGraphicX::DrawMarkers(PIGrCoord *x, PIGrCoord *y, int n)
+{
+int i;
+if (n <= 0)  return;
+if (mMrk == PI_DotMarker)
+  {
+  XPoint multipoint[NMXXPOINTS];
+  XPoint *pxp;
+  if (n > NMXXPOINTS)  pxp = new XPoint[n];
+  else pxp = multipoint;
+  for(i=0; i<n; i++)  { pxp[i].x = x[i];  pxp[i].y = y[i]; } 
+  XDrawPoints(mDisp, mWId, DefGC(), pxp, n, CoordModeOrigin);
+  if (n > NMXXPOINTS)  delete[] pxp;  
+  }
+else { 
+  SetupMrkGC();
+  for(i=0; i<n; i++) DrawMarker(x[i], y[i]);
+  mFgMrkGCOK = false;
+}
+return;
+}
+
+
+/* --Methode-- */
+void PIGraphicX::DrawPixmap(PIGrCoord x, PIGrCoord y, unsigned char *pix, 
+                            int sx, int sy, PIColorMap* cmap)
+{
+Window xw;
+Display * mdsp;
+int scr;
+int depth;
+int pad;
+int i,j;
+XImage * ximg;
+
+if ( (sx < 1) || (sy < 1) )  return;
+if ((pix == NULL) || (cmap == NULL)) return; 
+
+  
+xw = mWId;
+mdsp = PIXDisplay();
+scr = PIXScreen();
+
+depth = DefaultDepth(mdsp,scr);
+pad = (depth > 8) ? 32 : 8;
+ximg = XCreateImage (mdsp,DefaultVisual(mdsp,scr),
+                     depth,ZPixmap,0,NULL, sx, sy, pad,0);
+if (ximg == NULL)  return;
+ximg->data = new char [sy*ximg->bytes_per_line];
+if (ximg->data == NULL)  
+  { XFree(ximg); return; }
+
+for(j=0; j<sy; j++)
+  for(i=0; i<sx; i++)
+    { XPutPixel(ximg, i, j, cmap->Color(*pix) );  pix++; }
+
+XPutImage(mdsp, xw, DefGC(), ximg, 0, 0, (int)x, (int)y, sx, sy);
+
+delete[] ximg->data;
+XFree(ximg); 
+return;
+}
+
+/* --Methode-- */
+bool PIGraphicX::SetupMrkGC()
+{
+if (mFgMrkGCOK) return(false);
+XCopyGC(mDisp, DefGC(), GCFunction|GCForeground|GCBackground|GCPlaneMask, mMrkGC); 
+XSetLineAttributes(mDisp, mMrkGC, 1, LineSolid, CapButt, JoinMiter);
+mFgMrkGCOK = true;
+return true;
+}
+
+/* --Methode-- */
+void PIGraphicX::MrkDrawPolygon(XPoint *pxp, int n, bool cinc)
+{
+
+if (n <= 0)  return;
+int mode = CoordModeOrigin;
+if (cinc) mode =  CoordModePrevious;
+XDrawLines(mDisp, mWId, mMrkGC, pxp, n, mode);
+
+return;
+}
+
+
+/* --Methode-- */
+void PIGraphicX::MrkDrawFPolygon(XPoint *pxp, int n, bool cinc)
+{
+int mode = CoordModeOrigin;
+if (cinc) mode =  CoordModePrevious;
+XFillPolygon(mDisp, mWId, mMrkGC, pxp, n, 
+                        Complex, mode);
+return;
+}
+
+
+/* --Methode-- */
+void PIGraphicX::DrawVerticalString(int x, int y, const char* s, unsigned long pos, bool imgs)
+{
+  int fh, fasc, fdes;
+  fh = GetFont().GetFontHeight(fasc, fdes); 
+  int sw = GetFont().GetStringWidth(s);
+
+  Display * dsx = mDisp;
+  Window rw = DefaultRootWindow(dsx);
+  Pixmap pxm = XCreatePixmap(dsx, rw, sw, fh, 1 );
+
+  XGCValues  xgv;
+  xgv.function = GXcopy;
+  xgv.plane_mask = ~0;
+  GC gcbm = XCreateGC (dsx, pxm, GCFunction | GCPlaneMask, &xgv);
+  XSetForeground(dsx, gcbm, ~0); 
+  XSetBackground(dsx, gcbm, 0);
+  XSetFont(mDisp, gcbm, myFont.GetXFontId());
+  
+  XDrawImageString (dsx, pxm, gcbm, 0, fasc, s, strlen(s));
+  XImage* ximg = XGetImage(dsx, pxm, 0, 0, sw, fh, 0xFFFFFFFF, ZPixmap);
+
+  Pixmap pxm2 = XCreatePixmap(dsx, rw, fh, sw, 1 );
+  XImage* ximg2 =  XGetImage(dsx, pxm2, 0, 0, fh, sw, 0xFFFFFFFF, ZPixmap);
+  //  On recopie de ximg -> ximg2 en echangeant x,y
+  int i,j;
+  bool fgdown = ((pos&PI_TextDirection) == PI_TextDirectionVerticalDown);
+  if (fgdown) {
+    for(i=0; i<sw; i++)
+      for(j=0; j<fh; j++)
+	XPutPixel(ximg2, fh-j-1, i, XGetPixel(ximg, i, j));
+  }
+  else {
+    for(i=0; i<sw; i++)
+      for(j=0; j<fh; j++)
+	XPutPixel(ximg2, j, sw-i-1, XGetPixel(ximg, i, j));
+  }
+  XPutImage(dsx, pxm2, gcbm, ximg2, 0, 0, 0, 0, fh, sw);
+  GC gcvis;
+  GC gcvs = XCreateGC (dsx, mWId, GCFunction | GCPlaneMask, &xgv);
+  XCopyGC(dsx, DefGC(), ~0, gcvs); 
+  XSetStipple(dsx, gcvs, pxm2);
+  XSetFillStyle(dsx, gcvs, FillStippled);
+  if (imgs) {
+    gcvis = XCreateGC (dsx, mWId, GCFunction | GCPlaneMask, &xgv);
+    XCopyGC(dsx, DefGC(), ~0, gcvis); 
+    if (mBCol == PI_ColorFromMap)  XSetForeground(mDisp, gcvis, mBCfMap);
+    else  XSetForeground(mDisp, gcvis, colpix[mBCol]); 
+  }
+  if (fgdown) {
+    XSetTSOrigin(dsx, gcvs, x-fdes, y);
+    if (imgs)  XFillRectangle(dsx, mWId, gcvis, x-fdes, y, fh, sw);
+    XFillRectangle(dsx, mWId, gcvs, x-fdes, y, fh, sw);
+  }
+  else {
+    XSetTSOrigin(dsx, gcvs, x-fasc, y-sw);
+    if (imgs) XFillRectangle(dsx, mWId, gcvis, x-fasc, y-sw, fh, sw);
+    XFillRectangle(dsx, mWId, gcvs, x-fasc, y-sw, fh, sw);
+  }
+  // Cleaning  
+  XDestroyImage(ximg);
+  XDestroyImage(ximg2);
+  XFreeGC(dsx, gcbm);
+  XFreeGC(dsx, gcvs);
+  if (imgs) XFreeGC(dsx, gcvis);
+  XFreePixmap(dsx, pxm);			     
+  XFreePixmap(dsx, pxm2);			     
+  
+}
+
+
+/* --Methode-- */
+void PIGraphicX::SelForeground(PIColors col)
+{
+if (myLockFCol)  return;
+if (col == mFCol)  return;
+if ( (col < 0) || (col >= NMAXCOL))  return;
+XSetForeground(mDisp, DefGC(), colpix[col]); 
+mFCol = col;  
+return;
+}
+
+/* --Methode-- */
+void PIGraphicX::SelBackground(PIColors col)
+{
+if (col == mBCol)  return;
+if ( (col < 0) || (col >= NMAXCOL))  return;
+XSetBackground(mDisp, DefGC(), colpix[col]); 
+mBCol = col;  
+return;
+}
+
+/* --Methode-- */
+void PIGraphicX::SelForeground(PIColorMap& cmap, int cid)
+{
+if (myLockFCol)  return;
+SelectFCol(cmap.Color(cid));
+}
+
+/* --Methode-- */
+void PIGraphicX::SelBackground(PIColorMap& cmap, int cid)
+{
+SelectBCol(cmap.Color(cid));
+}
+
+/* --Methode-- */
+void PIGraphicX::SelGOMode(PIGOMode mod)
+{
+if (mod == mGOm)  return;
+switch (mod)
+  {
+  case PI_GOCopy :
+    XSetFunction(mDisp, DefGC(), GXcopy);
+    mGOm = mod;
+    break;
+  case PI_GOXOR :
+    XSetFunction(mDisp, DefGC(), GXxor);
+    mGOm = mod;
+    break;
+  case PI_GOInvert :
+    XSetFunction(mDisp, DefGC(), GXinvert);
+    mGOm = mod;
+    break;
+  }
+return;
+}
+
+
+/* --Methode-- */
+void PIGraphicX::SelFont(PIFont & fnt)
+{
+if (myFont == fnt)  return;
+myFont = fnt;
+XSetFont(mDisp, DefGC(), myFont.GetXFontId());
+}
+
+/* --Methode-- */
+void PIGraphicX::SelFont(PIFontSize sz, PIFontAtt att)
+{
+PIFont fnt(myFont.GetFontName());
+fnt.SetFontAtt(att);
+fnt.SetFontSz(sz);
+SelFont(fnt);
+}
+
+/* --Methode-- */
+void PIGraphicX::SelFontSzPt(int npt, PIFontAtt att)
+{
+PIFont fnt(npt, myFont.GetFontName(), att);
+SelFont(fnt);
+}
+
+
+
+/* --Methode-- */
+void PIGraphicX::SelLine(PILineAtt const& att)
+{
+
+if (att == mLAtt)  return;
+
+
+unsigned int lw = att.GetLineWidth();
+int lstyle=LineSolid;
+int dashlen = 2;
+char dash[4]= {3,3,3,3};   
+
+switch (att.GetLineDash()) {
+  case PI_LineSolid :
+    lstyle = LineSolid;
+     break;
+  case PI_LineDashed :
+    lstyle = LineOnOffDash;
+    dash[0] = dash[1] = 6;     
+    dashlen = 2;
+    break;
+  case PI_LineDotted :
+    lstyle = LineOnOffDash;
+    dash[0] = 2; dash[1] = 6;  
+    dashlen = 2;
+    break;
+  case PI_LineDashDotted :
+    lstyle = LineOnOffDash;
+    dash[0] = 2; dash[1] = 2;  
+    dash[2] = 4; dash[3] = 6;  
+    dashlen = 4;
+    break;
+  default :
+    lstyle = LineSolid;
+    break;
+  }
+if (lstyle != LineSolid)   
+  XSetDashes( mDisp, DefGC(), 0, dash, dashlen);
+
+
+int ljoin = JoinMiter;
+switch (att.GetLineJoin()) {
+ case PI_JoinMiter :
+   ljoin = JoinMiter;
+   break;
+ case PI_JoinRound :
+   ljoin = JoinRound;
+   break;
+ case PI_JoinBevel :
+   ljoin = JoinBevel;
+   break;
+ default :
+   ljoin = JoinMiter;
+   break;
+}
+
+int lcap = CapButt;
+switch (att.GetLineCap()) {
+ case PI_CapButt :
+   lcap = CapButt;
+   break;
+ case PI_CapRound :
+   lcap = CapRound;
+   break;
+ case PI_CapProjecting :
+   lcap = CapProjecting;
+   break;
+ default :
+   lcap = CapButt;
+   break;
+}
+
+XSetLineAttributes(mDisp, DefGC(), lw, lstyle, lcap, ljoin);
+mLAtt = att;
+return;
+}
+
+
+/* --Methode-- */
+void PIGraphicX::SelMarker(int msz, PIMarker mrk)
+{
+if (msz > 1)  { mMrk = mrk;  mMrkSz = msz; }
+else  { mMrk = PI_DotMarker;  mMrkSz = 1; }
+return;
+}
+
+
+/* --Methode-- */
+void PIGraphicX::SetClipRectangle(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
+{
+XRectangle xr;
+xr.x = x0;  xr.y = y0;
+xr.width = dx;  xr.height = dy;
+XSetClipRectangles(mDisp, DefGC(), 0, 0, &xr, 1, Unsorted);
+XSetClipRectangles(mDisp, mMrkGC, 0, 0, &xr, 1, Unsorted);
+return;
+}
+
+/* --Methode-- */
+void PIGraphicX::ClearClipRectangle()
+{ 
+XSetClipMask(mDisp, DefGC(), None);
+XSetClipMask(mDisp, mMrkGC, None);
+return;
+}
+
+/* --Methode-- */
+PIColors  PIGraphicX::GetForeground() 
+{
+return (mFCol);
+}
+
+/* --Methode-- */
+PIColors  PIGraphicX::GetBackground() 
+{
+return (mBCol);
+}
+
+
+/* --Methode-- */
+PIGOMode   PIGraphicX::GetGOMode()
+{
+return (mGOm);
+}
+
+/* --Methode-- */
+PIFontAtt  PIGraphicX::GetFontAtt()
+{
+return (mFAtt);
+}
+
+/* --Methode-- */
+int        PIGraphicX::GetFontSize()
+{
+return (mFSize);
+}
+
+/* --Methode-- */
+PILineAtt  PIGraphicX::GetLineAtt()
+{
+return (mLAtt);
+}
+
+/* --Methode-- */
+PIMarker   PIGraphicX::GetMarker()
+{
+return (mMrk);
+}
+
+/* --Methode-- */
+int        PIGraphicX::GetMarkerSize()
+{
+return (mMrkSz);
+}
+
+
+/* --Methode-- */
+void PIGraphicX::SaveGraphicAtt()
+{  
+// Pour optimier l'implementation de PIBaseWdgGen
+sFCol = mFCol;    sBCol = mBCol;
+sGOm = mGOm;
+sFont = myFont;   
+sMrk = mMrk;   sMrkSz = mMrkSz;
+sFCfMap = mFCfMap; sBCfMap = mBCfMap; 
+return;
+}
+
+/* --Methode-- */
+void PIGraphicX::RestoreGraphicAtt()
+{
+  if (sFCol != PI_ColorFromMap) SelForeground(sFCol);
+  else SelectFCol(sFCfMap);
+  if (sBCol != PI_ColorFromMap) SelBackground(sBCol);
+  else SelectBCol(sBCfMap);
+  SelGOMode(sGOm);
+  SelFont(sFont);
+  SelLine(sLAtt);
+  SelMarker(sMrkSz, sMrk);
+  return;
+}
+
+
+/* --Methode-- */
+unsigned long PIGraphicX::GetPixelValueforColor(PIColors col)
+{
+if ( (col < 0) || (col >= NMAXCOL))  return(0);
+GlInit();
+return(colpix[col]); 
+}
+
+
+static bool fggrcx = false ;  // Flag init done
+
+
+/* --Methode-- */
+void PIGraphicX::GlInit()
+{
+if (fggrcx)  return;
+fggrcx = true;
+
+Display *mdsp;
+int scr;
+XColor exact,mycol;
+Colormap  cmap;
+
+mdsp = PIXDisplay();
+scr = XDefaultScreen(mdsp);
+
+/*  Les couleurs  */
+cmap = XDefaultColormap (mdsp, scr);
+
+for(int i=0; i<NMAXCOL; i++)  colpix[i] = XWhitePixel(mdsp, scr);
+colpix[PI_Black] = XBlackPixel(mdsp, scr);
+colpix[PI_White] = XWhitePixel(mdsp, scr);
+colpix[PI_ColorAllBits0] = 0;
+colpix[PI_ColorAllBits1] = ~colpix[PI_ColorAllBits0];
+if ( XAllocNamedColor (mdsp, cmap, "LightGray", &mycol, &exact) )
+  colpix[PI_Grey] = mycol.pixel;
+if ( XAllocNamedColor (mdsp, cmap, "red", &mycol, &exact) )
+  colpix[PI_Red] = mycol.pixel;
+if ( XAllocNamedColor (mdsp, cmap, "blue", &mycol, &exact) )
+  colpix[PI_Blue] = mycol.pixel;
+if ( XAllocNamedColor (mdsp, cmap, "green", &mycol, &exact) )
+  colpix[PI_Green] = mycol.pixel;
+if ( XAllocNamedColor (mdsp, cmap, "yellow", &mycol, &exact) )
+  colpix[PI_Yellow] = mycol.pixel;
+if ( XAllocNamedColor (mdsp, cmap, "magenta", &mycol, &exact) )
+  colpix[PI_Magenta] = mycol.pixel;
+if ( XAllocNamedColor (mdsp, cmap, "cyan", &mycol, &exact) )
+  colpix[PI_Cyan] = mycol.pixel;
+if ( XAllocNamedColor (mdsp, cmap, "turquoise", &mycol, &exact) )
+  colpix[PI_Turquoise] = mycol.pixel;
+if ( XAllocNamedColor (mdsp, cmap, "NavyBlue", &mycol, &exact) )
+  colpix[PI_NavyBlue] = mycol.pixel;
+if ( XAllocNamedColor (mdsp, cmap, "orange", &mycol, &exact) )
+  colpix[PI_Orange] = mycol.pixel;
+if ( XAllocNamedColor (mdsp, cmap, "sienna", &mycol, &exact) )
+  colpix[PI_SiennaRed] = mycol.pixel;
+if ( XAllocNamedColor (mdsp, cmap, "purple", &mycol, &exact) )
+  colpix[PI_Purple] = mycol.pixel;
+if ( XAllocNamedColor (mdsp, cmap, "LimeGreen", &mycol, &exact) )
+  colpix[PI_LimeGreen] = mycol.pixel;
+if ( XAllocNamedColor (mdsp, cmap, "gold", &mycol, &exact) )
+  colpix[PI_Gold] = mycol.pixel;
+if ( XAllocNamedColor (mdsp, cmap, "violet", &mycol, &exact) )
+  colpix[PI_Violet] = mycol.pixel;
+if ( XAllocNamedColor (mdsp, cmap, "VioletRed", &mycol, &exact) )
+  colpix[PI_VioletRed] = mycol.pixel;
+if ( XAllocNamedColor (mdsp, cmap, "BlueViolet", &mycol, &exact) )
+  colpix[PI_BlueViolet] = mycol.pixel;
+if ( XAllocNamedColor (mdsp, cmap, "DarkViolet", &mycol, &exact) )
+  colpix[PI_DarkViolet] = mycol.pixel;
+
+mycol.red = 0;
+mycol.blue = 65000;
+mycol.green = 45000;
+if ( XAllocColor (mdsp, cmap, &mycol) )  colpix[PI_HighlightBlue] = mycol.pixel;
+
+/*  le GC pour DrawPixmap  */
+XGCValues  xgv;
+xgv.function = GXcopy;
+xgv.plane_mask = ~0;
+/* dpxgc = XCreateGC(mdsp, DefaultRootWindow(mdsp), 
+   GCFunction | GCPlaneMask, &xgv); Pas utile ?? - Reza 02/05/2002 */
+
+/* Coordonnees pour une etoile a 5 branches */
+double pio5 = M_PI/2.5;  
+double pio52 = pio5/2.;
+double cpi2 = M_PI/2.-pio5;  
+// Pentagone inscrit dans un cercle de rayon R1 = 1
+// les pointes de l'etoile seront inscrites dans un cercle 
+// de rayon R2 = 2.61803 
+double re = 1.;  // Rayon externe
+double ri = 0.38; //  rayon interne pour rext=1.2
+for(int k=0; k<5; k++) {
+  starcoordx[2*k] = cos(k*pio5+cpi2)*re;
+  starcoordy[2*k] = -sin(k*pio5+cpi2)*re;
+  starcoordx[2*k+1] = cos(k*pio5+pio52+cpi2)*ri;
+  starcoordy[2*k+1] = -sin(k*pio5+pio52+cpi2)*ri;
+  }
+
+}
+
+
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/pigraphx.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pigraphx.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pigraphx.h	(revision 2309)
@@ -0,0 +1,119 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive     PIGraphicX
+// Trace graphiques- Implementation X11  R. Ansari  97
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PIGRAPHICX_H_SEEN
+#define PIGRAPHICX_H_SEEN
+
+#include "pisysdep.h"
+#include "pigraphgen.h"
+
+class PIGraphicX : public PIGraphicGen
+{
+public:
+                     PIGraphicX(PIWdg* wdg);
+                     PIGraphicX(PIScreenBuffer* grb);
+  virtual           ~PIGraphicX();
+
+  virtual int        kind();
+
+//  Trace graphiques
+  virtual void       Erase(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy);
+  virtual void       DrawString(PIGrCoord x, PIGrCoord y, const char* s, unsigned long pos = 0);
+  virtual void       DrawOpaqueString(PIGrCoord x, PIGrCoord y, const char* s, unsigned long pos = 0);
+  virtual void       DrawLine(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2);
+  virtual void       DrawBox(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy);
+  virtual void       DrawFBox(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy);
+  virtual void       DrawCircle(PIGrCoord x0, PIGrCoord y0, PIGrCoord r);
+  virtual void       DrawFCircle(PIGrCoord x0, PIGrCoord y0, PIGrCoord r);
+  virtual void       DrawOval(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy);
+  virtual void       DrawFOval(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy);
+  virtual void       DrawPolygon(PIGrCoord *x, PIGrCoord *y, int n, bool cinc=true);  
+  virtual void       DrawFPolygon(PIGrCoord *x, PIGrCoord *y, int n, bool cinc=true);  
+  virtual void       DrawArc(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy,
+                             double degdeb, double deltadeg);
+  virtual void       DrawFArc(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy, 
+                              double degdeb, double deltadeg);
+  virtual void       DrawMarker(PIGrCoord x0, PIGrCoord y0);
+  virtual void       DrawMarkers(PIGrCoord *x, PIGrCoord *y, int n);
+  virtual void       DrawPixmap(PIGrCoord x, PIGrCoord y, unsigned char *pix, 
+                                int sx, int sy, PIColorMap* cmap);
+
+// Modifications attributs graphiques
+  virtual void       SelForeground(PIColors col=PI_Black);
+  virtual void       SelBackground(PIColors col=PI_White);
+  virtual void       SelForeground(PIColorMap& cmap, int cid);
+  virtual void       SelBackground(PIColorMap& cmap, int cid);
+  virtual void       SelGOMode(PIGOMode mod=PI_GOCopy);
+  virtual void       SelLine(PILineAtt const& att);
+  virtual void       SelMarker(int msz=3, PIMarker mrk=PI_DotMarker);
+
+// Modifications de fonte
+  virtual void	     SelFont(PIFont & fnt);
+  virtual void       SelFont(PIFontSize sz=PI_NormalSizeFont, 
+                             PIFontAtt att=PI_RomanFont);
+  virtual void       SelFontSzPt(int npt=12, PIFontAtt att=PI_RomanFont);
+
+// Selection de zone de trace (clip)
+  virtual void       SetClipRectangle(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy);
+  virtual void       ClearClipRectangle();
+
+// Acces aux attributs graphiques 
+  virtual PIColors   GetForeground();
+  virtual PIColors   GetBackground();
+  virtual PIGOMode   GetGOMode();
+  virtual PIFontAtt  GetFontAtt();
+  virtual int        GetFontSize();
+  virtual PILineAtt  GetLineAtt();
+  virtual PIMarker   GetMarker();
+  virtual int        GetMarkerSize();
+
+// Sauvegarde des attributs graphiques 
+  virtual void       SaveGraphicAtt();
+  virtual void       RestoreGraphicAtt();
+
+//  Pour initialiser mWId apres creation de fenetre
+  virtual void	     TerminateInit();
+
+//  Pour recuperer le pixcol d une couleur  (pour X) 
+  static PIXColor    GetPixelValueforColor(PIColors col);
+
+protected:
+  static void    GlInit();
+  void           Init();
+  void           SelectFont(int isz, int jat);
+  inline  GC     DefGC() { return mDefGC; }
+  inline SysDWdg MyWdg()  {return(myWdg->XtWdg()); }
+  inline void    SelectBCol(PIXColor col) 
+    {XSetBackground(mDisp, DefGC(), col);  mBCol = PI_ColorFromMap; mBCfMap = col; }
+  inline void    SelectFCol(PIXColor col) 
+    {XSetForeground(mDisp, DefGC(), col);  mFCol = PI_ColorFromMap; mFCfMap = col; }
+
+  bool           SetupMrkGC();
+  void           MrkDrawPolygon(XPoint* pxp, int n, bool cinc);
+  void           MrkDrawFPolygon(XPoint* pxp, int n, bool cinc);
+  void	         DrawVerticalString(int x, int y, const char* s, unsigned long pos, bool imgs=false);
+
+//  Structure et identificateur XWindow  associe
+  GC mDefGC;
+  GC mMrkGC;
+  bool mFgMrkGCOK;
+  Display* mDisp;  // Display X associe
+  Drawable mWId;   // Identificateur Window/Drawable X
+
+  PIColors  mFCol, mBCol;
+  PIGOMode mGOm;
+  PIFontAtt mFAtt;
+  PILineAtt mLAtt;
+  int mFSize;
+  XFontStruct *mFSt;
+  PIMarker mMrk;
+  int mMrkSz;
+  PIXColor mFCfMap, mBCfMap;
+  PIXColor sFCfMap, sBCfMap;
+};
+
+typedef PIGraphicX PIGraphicWin;
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pigratt.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pigratt.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pigratt.cc	(revision 2309)
@@ -0,0 +1,634 @@
+// Module PI : Peida Interactive     PIGraphicAtt 
+// PIGraphicAtt - Implementation     R. Ansari  2002
+// (C) LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "pigratt.h"
+
+#include <stdio.h>
+#include <map>
+
+//++
+// Class	PIGraphicAtt
+// Lib		PI
+// include	pigratt.h
+//
+//	Classe gestionnaire des attributs graphiques.
+//	(couleur, marker, lignes, ...)
+//--
+//++
+// Links	Voir aussi
+// PIGraphic
+// PIFont
+// PILineAtt
+//--
+
+//++
+// Titre	Constructeurs
+//--
+//++
+// PIGraphicAtt()
+//	Constructeur - Initialisation de tous les attributs aux valeurs par défaut.
+// PIGraphicAtt(PIGraphicAtt const & att)
+//	Constructeur de copie
+// PIGraphicAtt(vector<string> & att, bool rmdecatt)
+//	Cosntructeur avec décodage des attributs à partir d'un vecteur de string
+//	"att". Si "rmdecatt == true", les attributs décodés sont supprimés du
+//	vecteur de départ.
+//--
+
+PIGraphicAtt::PIGraphicAtt()
+{
+  InitGrAttStrings();   // Init attributes decoding maps
+  SetDefaultAtt();
+}
+
+PIGraphicAtt::PIGraphicAtt(PIGraphicAtt const & att)
+{
+  InitGrAttStrings();   // Init attributes decoding maps
+  CopyFrom(att);
+}
+
+PIGraphicAtt::PIGraphicAtt(vector<string> & att, bool rmdecatt)
+{
+  InitGrAttStrings();   // Init attributes decoding maps
+  // Initialize attributes
+  SetDefaultAtt();
+  // Decode attributes from strings 
+  DecodeAttStrings(att, rmdecatt);
+}
+
+PIGraphicAtt::~PIGraphicAtt()
+{
+}
+
+//++
+// Titre	Méthodes
+//--
+//++
+// void CopyFrom(PIGraphicAtt const & att)
+//	Copie les attributs à partir de l'objet "att".
+// bool Compare(PIGraphicAtt const & att)
+//	Comparison de deux objets de type PIGraphicAtt. Renvoie "true"
+//	si attributs identiques.
+// void	SetDefaultAtt()
+//	Initialise les attributs aux valeurs par défaut.
+// PIGraphicAtt& operator = (PIGraphicAtt const & att)
+//	Opérateur d'affectation. Appelle *CopyFrom()*
+// bool operator == (PIGraphicAtt const & att)
+//	Opérateur d'égalité. Appelle *Compare()*
+// bool operator != (PIGraphicAtt const & att)
+//	Opérateur d'inégalité. Appelle *Compare()*
+// void UpdateFrom(PIGraphicAtt const & att)
+//	Met à jour les attributs initialisés à partir de l'objet "att".
+// int  DecodeAttStrings(vector<string> & att, bool rmdecatt=true)
+//	Décode les attributs  à partir du vecteur de string "att".
+//	Si "rmdecatt == true", les attributs décodés sont supprimés du
+//	vecteur de départ.
+// unsigned long DecodeTextPosDirAtt(vector<string> & att, bool rmdecatt=true)
+//	Décode les attributs de direction et de positionnement de tracé de texte
+//	à partir du vecteur de string "att" (méthode statique).
+//	Si "rmdecatt == true", les attributs décodés sont supprimés du
+//	vecteur de départ. 
+//	Retourne le flag de positionnement.
+//--
+
+void PIGraphicAtt::SetDefaultAtt()
+{
+  SetColAtt();
+  SetLineAtt();
+  SetFontAtt();
+  mNotDefFnt = false;
+  SetMarkerAtt(1);
+  SetArrowMarkerAtt(5);
+  SetColMapId();
+}
+
+void PIGraphicAtt::CopyFrom(PIGraphicAtt const & att)
+{
+  mFCol = att.mFCol;
+  mBCol = att.mBCol;
+  mLAtt = att.mLAtt;
+  mFnt = att.mFnt;
+  mNotDefFnt = att.mNotDefFnt;
+  mMSz = att.mMSz;
+  mMrk = att.mMrk;
+  mArrowMrkSz = att.mArrowMrkSz;
+  mArrowMrk = att.mArrowMrk;
+  mCmapid = att.mCmapid;
+  mRevCmap = att.mRevCmap;
+}
+
+bool PIGraphicAtt::Compare(PIGraphicAtt const & att)
+{
+  if (mFCol != att.mFCol) return false;
+  if (mBCol != att.mBCol) return false;
+  if (mLAtt != att.mLAtt) return false;
+  bool fnteq = (mFnt == att.mFnt);
+  if (!fnteq)  return false;
+  if (mMSz != att.mMSz) return false;
+  if (mMrk != att.mMrk)  return false;
+  if (mArrowMrkSz != att.mArrowMrkSz) return false;
+  if (mArrowMrk != att.mArrowMrk) return false;
+  if (mCmapid != att.mCmapid) return false;
+  if (mRevCmap != att.mRevCmap) return false;
+
+  return true;
+}
+
+// PIGraphicAtt::DecodeAttStrings(vector<string> & att, bool rmdecatt)
+// Voir apres InitGrAttStrings()
+
+
+void PIGraphicAtt::UpdateFrom(PIGraphicAtt const & att)
+{
+  if (att.mFCol != PI_NotDefColor)  mFCol = att.mFCol;
+  if (att.mBCol != PI_NotDefColor)  mBCol = att.mBCol;
+  if (att.mLAtt != PI_NotDefLineAtt)  mLAtt = att.mLAtt;
+  if (att.mNotDefFnt) mFnt = att.mFnt;
+  //  if ( (att.mFnt.GetFontName() != PI_DefaultFont) || 
+  //       (att.mFnt.GetFontAtt() != PI_NotDefFontAtt) ||
+  //     (att.mFnt.GetFontSize() != PI_NotDefFontSize) )  mFnt = att.mFnt;
+  if (att.mMrk != PI_NotDefMarker) {
+    mMSz = att.mMSz;
+    mMrk = att.mMrk;
+  }
+  if (att.mArrowMrk != PI_NotDefArrowMarker) {
+    mArrowMrkSz = att.mArrowMrkSz;
+    mArrowMrk = att.mArrowMrk;
+  }
+  if (att.mCmapid != CMAP_OTHER) {
+    mCmapid = att.mCmapid;
+    mRevCmap = att.mRevCmap;
+  }
+
+}
+
+void PIGraphicAtt::SetFontAtt(PIFontSize fsz, PIFontAtt fat)
+{
+  mNotDefFnt = true;
+  mFnt.SetFontAtt(fat);
+  mFnt.SetFontSz(fsz);
+}
+
+void PIGraphicAtt::SetFontAtt(PIFontName fn, PIFontSize fsz, PIFontAtt fat)
+{
+  mNotDefFnt = true;
+  mFnt.SetFont(fn);
+  mFnt.SetFontAtt(fat);
+  mFnt.SetFontSz(fsz);
+}
+
+
+// -------------------------------------------------------------------- 
+// Variables globales pour decodage de chaines d'attributs graphiques
+// -------------------------------------------------------------------- 
+
+typedef map<string, PIColors, less<string> > GrAttColors;
+typedef map<string, PILineAtt, less<string> > GrAttLines;
+typedef map<string, PIFontName, less<string> > GrAttFontNames;
+struct gratt_fontatt {
+  PIFontAtt fatt;
+  PIFontSize fsz;
+};
+typedef map<string, gratt_fontatt, less<string> > GrAttFonts;
+struct gratt_marker {
+  PIMarker mrk;
+  int msz;
+};
+typedef map<string, gratt_marker, less<string> > GrAttMarkers;
+struct gratt_arrowmarker {
+  PIArrowMarker amrk;
+  int amsz;
+};
+typedef map<string, gratt_arrowmarker, less<string> > GrAttArrowMarkers;
+typedef map<string, CMapId, less<string> > GrAttColMaps;
+
+static bool gratt_init_done = false;
+static GrAttColors* GrAcolors = NULL;
+static GrAttLines* GrAlines = NULL;
+static GrAttFonts* GrAfonts = NULL;
+static GrAttFontNames* GrAfontNames = NULL;
+static GrAttMarkers* GrAmarkers = NULL;
+static GrAttArrowMarkers* GrAarrowMarkers = NULL;
+static GrAttColMaps* GrAcmaps = NULL;
+
+
+void PIGraphicAtt::InitGrAttStrings()
+{
+  if (gratt_init_done) return;
+
+  GrAcolors = new GrAttColors;
+  GrAttColors& GrAcol = *GrAcolors;
+  PIColors gic;
+  // Les couleurs
+  gic = PI_NotDefColor;
+  GrAcol["defcol"] = gic;
+  gic = PI_Black;
+  GrAcol["black"] = gic;
+  gic = PI_White;
+  GrAcol["white"] = gic;
+  gic = PI_Grey;
+  GrAcol["grey"] = gic;
+  gic = PI_Red;
+  GrAcol["red"] = gic;
+  gic = PI_Blue;
+  GrAcol["blue"] = gic;
+  gic = PI_Green;
+  GrAcol["green"] = gic;
+  gic = PI_Yellow;
+  GrAcol["yellow"] = gic;
+  gic = PI_Magenta;
+  GrAcol["magenta"] = gic;
+  
+  gic = PI_Cyan;
+  GrAcol["cyan"] = gic;
+  gic = PI_Turquoise;
+  GrAcol["turquoise"] = gic;
+  gic = PI_NavyBlue;
+  GrAcol["navyblue"] = gic;
+  gic = PI_Orange;
+  GrAcol["orange"] = gic;
+  gic = PI_SiennaRed;
+  GrAcol["siennared"] = gic;
+  gic = PI_Purple;
+  GrAcol["purple"] = gic;
+  gic = PI_LimeGreen;
+  GrAcol["limegreen"] = gic;
+  gic = PI_Gold;
+  GrAcol["gold"] = gic;
+  gic = PI_Violet;
+  GrAcol["violet"] = gic;
+  gic = PI_VioletRed;
+  GrAcol["violetred"] = gic;
+  gic = PI_BlueViolet;
+  GrAcol["blueviolet"] = gic;
+  gic = PI_DarkViolet;
+  GrAcol["darkviolet"] = gic;
+
+// Les attributs de lignes
+  PILineAtt gil;
+  GrAlines = new GrAttLines;
+  GrAttLines& GrAlin = *GrAlines;
+
+  gil = PI_NotDefLineAtt;
+  GrAlin["defline"] = gil;
+  gil = PI_NormalLine;
+  GrAlin["normalline"] = gil;
+  gil = PI_ThinLine;
+  GrAlin["thinline"] = gil;
+  gil = PI_ThickLine;
+  GrAlin["thickline"] = gil;
+  gil = PI_DashedLine;
+  GrAlin["dashedline"] = gil;
+  gil = PI_ThinDashedLine;
+  GrAlin["thindashedline"] = gil;
+  gil = PI_ThickDashedLine;
+  GrAlin["thickdashedline"] = gil;
+  gil = PI_DottedLine;
+  GrAlin["dottedline"] = gil;
+  gil = PI_ThinDottedLine;
+  GrAlin["thindottedline"] = gil;
+  gil = PI_ThickDottedLine;
+  GrAlin["thickdottedline"] = gil;
+  gil = PI_DashDottedLine;
+  GrAlin["dashdottedline"] = gil;
+  gil = PI_ThinDashDottedLine;
+  GrAlin["thindashdottedline"] = gil;
+  gil = PI_ThickDashDottedLine;
+  GrAlin["thickdashdottedline"] = gil;
+
+  // Noms de fontes
+  GrAfontNames = new GrAttFontNames;
+  GrAttFontNames& GrAfontnm = *GrAfontNames;
+  PIFontName gifn;
+  gifn = PI_DefaultFont;
+  GrAfontnm["deffont"] = gifn;
+  gifn = PI_CourierFont;
+  GrAfontnm["courierfont"] = gifn;
+  gifn = PI_HelveticaFont;
+  GrAfontnm["helveticafont"] = gifn;
+  gifn = PI_TimesFont;
+  GrAfontnm["timesfont"] = gifn;
+  gifn = PI_SymbolFont;
+  GrAfontnm["symbolfont"] = gifn;
+
+  // Attributs de fontes 
+  GrAfonts = new GrAttFonts;
+  GrAttFonts& GrAfnt = *GrAfonts;
+  gratt_fontatt gifa;
+
+  gifa.fsz = PI_NotDefFontSize;
+  gifa.fatt = PI_NotDefFontAtt;
+  GrAfnt["deffontatt"] = gifa;
+  gifa.fsz = PI_NormalSizeFont;
+  gifa.fatt = PI_RomanFont;
+  GrAfnt["normalfont"] = gifa;
+  gifa.fatt = PI_BoldFont;
+  GrAfnt["boldfont"] = gifa;
+  gifa.fatt = PI_ItalicFont;
+  GrAfnt["italicfont"] = gifa;
+  gifa.fatt = PI_BoldItalicFont;
+  GrAfnt["bolditalicfont"] = gifa;
+  gifa.fsz = PI_SmallSizeFont;
+  gifa.fatt = PI_RomanFont;
+  GrAfnt["smallfont"] = gifa;
+  gifa.fatt = PI_BoldFont;
+  GrAfnt["smallboldfont"] = gifa;
+  gifa.fatt = PI_ItalicFont;
+  GrAfnt["smallitalicfont"] = gifa;
+  gifa.fatt = PI_BoldItalicFont;
+  GrAfnt["smallbolditalicfont"] = gifa;
+  gifa.fsz = PI_LargeSizeFont;
+  gifa.fatt = PI_RomanFont;
+  GrAfnt["bigfont"] = gifa;
+  GrAfnt["largefont"] = gifa;
+  gifa.fatt = PI_BoldFont;
+  GrAfnt["bigboldfont"] = gifa;
+  gifa.fatt = PI_ItalicFont;
+  GrAfnt["bigitalicfont"] = gifa;
+  GrAfnt["largeitalicfont"] = gifa;
+  gifa.fatt = PI_BoldItalicFont;
+  GrAfnt["bigbolditalicfont"] = gifa;
+  GrAfnt["largebolditalicfont"] = gifa;
+  gifa.fsz = PI_HugeSizeFont;
+  gifa.fatt = PI_RomanFont;
+  GrAfnt["hugefont"] = gifa;
+  gifa.fatt = PI_BoldFont;
+  GrAfnt["hugeboldfont"] = gifa;
+  gifa.fatt = PI_ItalicFont;
+  GrAfnt["hugeitalicfont"] = gifa;
+  gifa.fatt = PI_BoldItalicFont;
+  GrAfnt["hugebolditalicfont"] = gifa;
+
+
+// Les markers 
+  GrAmarkers = new GrAttMarkers;
+  GrAttMarkers& GrAmrk = *GrAmarkers;
+  const char* mrkn[11] = {"dotmarker", "plusmarker", "crossmarker", 
+			  "circlemarker", "fcirclemarker", 
+			  "boxmarker", "fboxmarker", 
+			  "trianglemarker", "ftrianglemarker", 
+			  "starmarker", "fstarmarker"};
+  PIMarker mrk[11] = {PI_DotMarker, PI_PlusMarker, PI_CrossMarker, 
+		      PI_CircleMarker, PI_FCircleMarker, 
+		      PI_BoxMarker, PI_FBoxMarker, 
+		      PI_TriangleMarker, PI_FTriangleMarker, 
+		      PI_StarMarker, PI_FStarMarker};
+
+  
+  gratt_marker gim;
+  gim.msz = 1;
+  gim.mrk = PI_NotDefMarker;
+  GrAmrk["defmarker"] = gim;
+  int j;
+  for(j=0; j<11; j++) {
+    string smrk;
+    char buff[32];
+    for(int m=1; m<16; m+=2) {
+      sprintf(buff,"%d",m);
+      smrk = (string)mrkn[j] + (string)buff;
+      gim.mrk = mrk[j];  gim.msz = m;
+      GrAmrk[smrk] = gim;
+    }
+  }
+
+// Les fleches - ArrowMarkers 
+  GrAarrowMarkers = new GrAttArrowMarkers;
+  GrAttArrowMarkers& GrAarrmrk = *GrAarrowMarkers;
+  const char* arrmrkn[5] = {"basicarrow", 
+			    "trianglearrow", "ftrianglearrow", 
+			    "arrowshapedarrow", "farrowshapedarrow"};
+  PIArrowMarker arrmrk[5] = {PI_BasicArrowMarker, 
+			     PI_TriangleArrowMarker, PI_FTriangleArrowMarker, 
+			     PI_ArrowShapedArrowMarker, PI_FArrowShapedArrowMarker};
+  
+  gratt_arrowmarker giam;
+  giam.amsz = 7;
+  giam.amrk = PI_NotDefArrowMarker;
+  GrAarrmrk["defarrow"] = giam;
+ 
+  for(j=0; j<5; j++) {
+    string smrk;
+    char buff[32];
+    for(int m=5; m<17; m+=2) {
+      sprintf(buff,"%d",m);
+      smrk = (string)arrmrkn[j] + (string)buff;
+      giam.amrk = arrmrk[j];  giam.amsz = m;
+      GrAarrmrk[smrk] = giam;
+    }
+  }
+
+  // Les tables de couleurs 
+  GrAcmaps = new GrAttColMaps;
+  GrAttColMaps& GrAcmp = *GrAcmaps;
+  CMapId gicm;
+  gicm = CMAP_OTHER;
+  GrAcmp["defcmap"] = gicm;
+  for(int kcc=0; kcc<PIColorMap::NumberStandardColorMaps(); kcc++) {
+    gicm = PIColorMap::GetStandardColorMapId(kcc);
+    string colname = PIColorMap::GetStandardColorMapName(kcc);
+    for(unsigned int jll=0; jll<colname.length(); jll++)
+      colname[jll] = tolower(colname[jll]);
+    GrAcmp[colname] = gicm;
+  }
+
+
+  gratt_init_done = true;
+
+}
+
+int PIGraphicAtt::DecodeAttStrings(vector<string> & att, bool rmdecatt)
+{
+  if (att.size() == 0)  return(0);  
+  vector<string> udatt;
+  unsigned int k = 0;
+  int ndec = att.size();
+  for( k=0; k<att.size(); k++ ) {
+    string gratt = att[k];
+    // Valeurs par defaut 
+    if (gratt == "default") { 
+      SetDefaultAtt();  
+      continue;
+    }
+    // Inversion d'indexage de ColorMap
+    if (gratt == "revcmap")  { 
+      mRevCmap = true;  continue;
+    }
+    // Si c'est une couleur
+    GrAttColors& GrAcol = *GrAcolors;
+    GrAttColors::const_iterator itc = GrAcol.find(gratt);
+    if (itc != GrAcol.end())  { 
+      mFCol = (*itc).second;  continue; 
+    }
+    // Si c'est un attribut de lignes
+    GrAttLines& GrAlin = *GrAlines;
+    GrAttLines::const_iterator itl = GrAlin.find(gratt);
+    if (itl != GrAlin.end())  { 
+      mLAtt = (*itl).second;  continue; 
+    }
+    // Si c'est un nom de fontes
+    GrAttFontNames& GrAfontnm = *GrAfontNames;
+    GrAttFontNames::const_iterator itfn = GrAfontnm.find(gratt);
+    if (itfn != GrAfontnm.end()) { 
+      mFnt.SetFont((*itfn).second);  
+      mNotDefFnt = true;  continue; 
+    }
+    // Si c'est un attribut de fontes
+    GrAttFonts& GrAfnt = *GrAfonts;
+    GrAttFonts::const_iterator itfa = GrAfnt.find(gratt);
+    if (itfa != GrAfnt.end()) {
+      mFnt.SetFontAtt((*itfa).second.fatt);  
+      mFnt.SetFontSz((*itfa).second.fsz); 
+      mNotDefFnt = true;  continue; 
+    }
+    // Si c'est un attribut de markers
+    GrAttMarkers& GrAmrk = *GrAmarkers;
+    GrAttMarkers::const_iterator itm = GrAmrk.find(gratt);
+    if (itm != GrAmrk.end()) {
+      mMrk = (*itm).second.mrk;  
+      mMSz = (*itm).second.msz;  
+      continue; 
+    }
+    // Si c'est un attribut de ArrowMarker (fleche)
+    GrAttArrowMarkers& GrAarrmrk = *GrAarrowMarkers;
+    GrAttArrowMarkers::const_iterator itam = GrAarrmrk.find(gratt);
+    if (itam != GrAarrmrk.end()) {
+      mArrowMrk = (*itam).second.amrk;  
+      mArrowMrkSz = (*itam).second.amsz;  
+      continue; 
+    }
+    // Si c'est un colormap
+    GrAttColMaps& GrAcmp = *GrAcmaps;
+    GrAttColMaps::const_iterator itcm = GrAcmp.find(gratt);
+    if (itcm != GrAcmp.end())  { 
+      mCmapid = (*itcm).second;  
+      continue; 
+    }
+    ndec--;
+    if (rmdecatt)  udatt.push_back(gratt);
+  }
+  if (rmdecatt)  att = udatt;
+  return(ndec);
+}
+
+int PIGraphicAtt::DecodeTextPosDirAtt(vector<string> & att, unsigned long& tdirpos, 
+				   bool rmdecatt)
+{
+  if (att.size() == 0)  return(0);  
+  tdirpos = PI_HorizontalLeft | PI_VerticalBottom | PI_TextDirectionHorizontal;
+  int ndec = att.size();
+  vector<string> udopt;
+  int k;
+  for( k=0; k<att.size(); k++ ) {
+    string& opts = att[k];
+    if (opts == "horizleft")  { 
+      tdirpos &= (~PI_HorizontalPosition); 
+      tdirpos |= PI_HorizontalLeft;
+    }
+    else if (opts == "horizcenter") {
+      tdirpos &= (~PI_HorizontalPosition); 
+      tdirpos |= PI_HorizontalCenter;
+    }
+    else if (opts == "horizright") {
+      tdirpos &= (~PI_HorizontalPosition); 
+      tdirpos |= PI_HorizontalRight;
+    }
+    else if (opts == "vertbottom") {
+      tdirpos &= (~PI_VerticalPosition); 
+      tdirpos |= PI_VerticalBottom;
+    }
+    else if (opts == "vertcenter") {
+      tdirpos &= (~PI_VerticalPosition); 
+      tdirpos |= PI_VerticalCenter;
+    }
+    else if (opts == "verttop") {
+      tdirpos &= (~PI_VerticalPosition); 
+      tdirpos |= PI_VerticalTop;
+    }
+    else if (opts == "textdirhoriz") {
+      tdirpos &= (~PI_TextDirection); 
+    }
+    else if (opts == "textdirvertup") {
+      tdirpos &= (~PI_TextDirection); 
+      tdirpos |= PI_TextDirectionVerticalUp;
+    }
+    else if (opts == "textdirvertdown") {
+      tdirpos &= (~PI_TextDirection); 
+      tdirpos |= PI_TextDirectionVerticalDown;
+    }
+    else { 
+      ndec--;
+      if (rmdecatt)  udopt.push_back(opts);    
+    }
+  }
+  if (rmdecatt)  att = udopt;
+  return(ndec);
+  
+}
+//++
+// Titre	Changement des attributs graphiques
+//--
+//++
+// void  SetColAtt(PIColors fg=PI_NotDefColor, PIColors bg=PI_NotDefColor)
+//	Modifie la couleur d'avant-plan et de fond.
+// void  SetLineAtt(PILineAtt lat=PI_NotDefLineAtt)
+//	Modifie l'attribut type de ligne.
+// void  SetLineAtt(PILineTypes ltyp=PI_NotDefLineAtt)
+//	Modifie l'attribut type de ligne.
+// void  SetFont(PIFont const & fnt)
+//	Selection de fonte.
+// void  SetFontAtt(PIFontName fn, PIFontSize fsz=PI_NotDefFontSize, PIFontAtt fat=PI_NotDefFontAtt)
+//	Selection de type, taille et attribut de fonte
+// void  SetFontAtt(PIFontSize fsz=PI_NotDefFontSize, PIFontAtt fat=PI_NotDefFontAtt)
+//	Selection taille et attribut de fonte. 
+// void  SetMarkerAtt(int sz=-1, PIMarker mrk=PI_NotDefMarker)
+//	Modifie l'attribut type et taille de marker.
+// void  SetMarkerAtt(PIMarker mrk=PI_NotDefMarker)
+//	Modifie l'attribut type de marker.
+// void  SetArrowMarkerAtt(int sz, PIArrowMarker mrk=PI_NotDefArrowMarker)
+//	Modifie l'attribut type et taille de flèche.
+// void  SetArrowMarkerAtt(PIArrowMarker mrk=PI_NotDefArrowMarker)
+//	Modifie l'attribut type de flèche.
+// void  SetColMapId(CMapId cid=CMAP_OTHER, bool rev=false)
+//	L'attribut choix de la table de couleurs, et son flag d'inversion
+//-- 
+//++
+// Titre	Accès aux attributs graphiques
+//--
+//++
+// PIColors  GetColor() const
+// PIColors  GetFgColAtt() const
+//	Renvoie l'attribut de couleur d'avant-plan
+// PIColors  GetBgColAtt() const
+//	Renvoie l'attribut de couleur d'arrière-plan
+// PILineAtt  GetLineAtt() const
+// PILineAtt& GetLineAtt()
+//	Renvoie l'attribut de ligne.
+// PIFont  GetFont()  const
+// PIFont& GetFont()
+//	Renvoie l'attribut fonte.
+// PIFontSize GetFontSz() const
+//	Renvoie la taille de fonte
+// int  GetFontSzPt() const 
+// int  GetFontSize() const 
+//	Renvoie la taille de fonte en points/pixels.
+// PIFontAtt  GetFontAtt() const
+//	Renvoie l'attribut de type de fonte (roman/bold/italique/...)
+// PIFontName  GetFontName() const
+//	Renvoie l'attribut nom de fonte (courier/helvetica...)
+// int  GetMarkerSz() const
+// int  GetMarkerSize() const
+//	Renvoie la taille de marker.
+// PIMarker GetMarker() const
+//	Renvoie le type de marker.
+// int  GetArrowMarkerSz() const
+// int  GetArrowMarkerSize() const
+//	Renvoie la taille de flèche.
+// PIArrowMarker GetArrowMarker() const
+//	Renvoie le type de flèche.
+// CMapId GetColMapId()
+//	Renvoie l'attribut de type de table de couleur
+// CMapId GetColMapId(bool & rev)
+//	Renvoie l'attribut de type de table de couleur, 
+//	et le flag d'inversion de la table de couleur
+//--
Index: /tags/V_Dec2002/SophyaPI/PI/pigratt.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pigratt.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pigratt.h	(revision 2309)
@@ -0,0 +1,95 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive     PIGraphicAtt 
+// Classe de gestion des attributs graphiques  
+//                                        R. Ansari  2002
+// (C) LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PIGRAPHICATT_H_SEEN
+#define PIGRAPHICATT_H_SEEN
+
+#include "pisysdep.h"
+#include <string>
+#include <vector>
+#include "pigraphgen.h"
+
+class PIGraphicAtt {
+public:
+                 PIGraphicAtt();
+                 PIGraphicAtt(PIGraphicAtt const & att);
+                 PIGraphicAtt(vector<string> & att, bool rmdecatt=true);
+  virtual        ~PIGraphicAtt();
+
+  virtual void   CopyFrom(PIGraphicAtt const & att);
+  virtual bool   Compare(PIGraphicAtt const & att);
+  virtual void   SetDefaultAtt();
+
+  inline PIGraphicAtt& operator = (PIGraphicAtt const & att)
+                 { CopyFrom(att);  return(*this); }
+  inline bool operator == (PIGraphicAtt const & att)
+                 { return (Compare(att)); } 
+  inline bool operator != (PIGraphicAtt const & att)
+                 { return (!Compare(att)); } 
+
+  virtual void   UpdateFrom(PIGraphicAtt const & att);
+  virtual int    DecodeAttStrings(vector<string> & att, bool rmdecatt=true);
+  // decodage des attributs de positions et direction de trace de texte 
+  static  int    DecodeTextPosDirAtt(vector<string> & att, unsigned long& tdirpos, 
+				     bool rmdecatt=true);
+// Changement des attributs graphiques
+  inline void    SetColAtt(PIColors fg=PI_NotDefColor, 
+			   PIColors bg=PI_NotDefColor)  { mFCol = fg; mBCol = bg; }
+  inline void    SetLineAtt(PILineAtt const & lat)  { mLAtt = lat; }
+  inline void    SetLineAtt(PILineTypes ltyp=PI_NotDefLineAtt)  { mLAtt = ltyp; }
+  inline void    SetFont(PIFont const & fnt)  { mNotDefFnt = true; mFnt = fnt; } 
+         void    SetFontAtt(PIFontSize fsz=PI_NotDefFontSize,
+			    PIFontAtt fat=PI_NotDefFontAtt);
+         void	 SetFontAtt(PIFontName fn, PIFontSize fsz=PI_NotDefFontSize,
+			    PIFontAtt fat=PI_NotDefFontAtt);
+  inline void    SetMarkerAtt(int sz, PIMarker mrk=PI_NotDefMarker)
+                 { mMSz = (sz>0)?sz:mMSz;  mMrk = mrk; }
+  inline void    SetMarkerAtt(PIMarker mrk=PI_NotDefMarker)  { mMrk = mrk; }
+  inline void    SetArrowMarkerAtt(int sz, PIArrowMarker mrk=PI_NotDefArrowMarker)
+                 { mArrowMrkSz = (sz>2)?sz:mArrowMrkSz;  mArrowMrk = mrk; }
+  inline void    SetArrowMarkerAtt(PIArrowMarker mrk=PI_NotDefArrowMarker)
+                 { mArrowMrk = mrk; }
+  inline void    SetColMapId(CMapId cid=CMAP_OTHER, bool rev=false)
+                 { mCmapid = cid; mRevCmap = rev; }
+
+// Acces aux attributs graphiques
+  inline PIColors    GetColor() const { return(mFCol); }
+  inline PIColors    GetFgColor() const { return(mFCol); }
+  inline PIColors    GetBgColor() const { return(mBCol); }
+  inline PILineAtt   GetLineAtt()  const { return(mLAtt); }
+  inline PILineAtt&  GetLineAtt()  { return(mLAtt); }
+  inline PIFont      GetFont()  const  { return(mFnt);  }
+  inline PIFont&     GetFont()   { return(mFnt);  }
+  inline PIFontSize  GetFontSz() const   { return(mFnt.GetFontSz());  }
+  inline int         GetFontSzPt() const   { return(mFnt.GetFontSzPt());  }
+  inline int         GetFontSize() const   { return(mFnt.GetFontSize());  }
+  inline PIFontAtt   GetFontAtt() const  { return(mFnt.GetFontAtt()); }
+  inline PIFontName  GetFontName() const  { return(mFnt.GetFontName());} 
+  inline int         GetMarkerSz() const  { return(mMSz);  }
+  inline int         GetMarkerSize() const  { return(mMSz);  }
+  inline PIMarker    GetMarker() const   { return(mMrk);  } 
+  inline int         GetArrowMarkerSz() const  { return(mArrowMrkSz);  }
+  inline int         GetArrowMarkerSize() const  { return(mArrowMrkSz);  }
+  inline PIArrowMarker GetArrowMarker() const  { return(mArrowMrk);  } 
+  inline CMapId      GetColMapId() const { return(mCmapid); }
+  inline CMapId      GetColMapId(bool & rev) const { rev = mRevCmap; return(mCmapid); }
+
+protected:
+  void      InitGrAttStrings();   
+
+  PIColors           mFCol, mBCol;
+  PILineAtt          mLAtt;
+  PIFont             mFnt;
+  bool               mNotDefFnt;    // Si True --> Pas la fonte par defaut 
+  int                mMSz;
+  PIMarker           mMrk;  
+  int                mArrowMrkSz;
+  PIArrowMarker      mArrowMrk;
+  CMapId             mCmapid;
+  bool               mRevCmap;
+};
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pigrcoord.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pigrcoord.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pigrcoord.cc	(revision 2309)
@@ -0,0 +1,88 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive     PIGrCoord
+// Classe de gestion de coordonnees grpahique   R. Ansari  97
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "pigrcoord.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+
+//++
+// Class	PIGrCoord
+// Lib		PI
+// include	pigrcoord.h
+//
+//   	Classe utilisé pour la spécifiaction de coordonnées graphique.
+//	Des constructeurs et des méthodes de conversion à partir 
+//	et vers des "int", "float" et "double" sont définis.
+//	La valeur entiere d'un objet PIGrCoord construite à partir 
+//	d'une valeur flottante (ou suite à une affectation) correpond
+//	à l'entier le plus proche.
+// 
+//|	PIGrCoord gco = 3.14;
+//|	int ic = gco;     // ic -> 3
+//|	float fc = gco;   // fc -> 3.14
+//|	gco = 1.1;        // (int)gco -> 1
+//|	gco = 1.6;        // (int)gco -> 2
+//|	gco = -0.4;       // (int)gco -> 0
+//|	gco = -0.7;       // (int)gco -> -1
+//--
+//++
+// Links	Voir aussi
+// PIGraphic
+// PIGraphicAtt
+//--
+
+PIGrCoord::PIGrCoord(const char * sv)
+{
+  double a = atof(sv);
+  iv = (a>=0.)?(int)(a+0.5):(int)(a-0.5); dv = a;
+}
+
+//++
+// Titre	Constructeurs
+//--
+//++
+// 
+// PIGrCoord() 
+//	Constructeur par défaut ("intVal=floatVal=0")
+// PIGrCoord(int a)
+//	Constructeur à partir de l'entier "a"
+// PIGrCoord(float a) 
+//	Constructeur à partir de la valeur flottante "a"
+// PIGrCoord(double a) 
+//	Constructeur à partir de la valeur flottante double précision "a"
+// PIGrCoord(const char * sv) 
+//	Constructeur à partir d'une chaine de caracteres "sv".
+//--
+//++
+// Titre	Opérateurs de conversion
+//--
+//++
+// operator int() 
+//	Conversion en entier "int"
+// operator short() 
+//	Conversion en entier "short"
+// operator unsigned int() 
+//	Conversion en entier non signé "unsigned int"
+// operator unsigned short() 
+//	Conversion en entier non signé "unsigned short"
+// operator float() 
+//	Conversion en réél "float"
+// operator double() 
+//	Conversion en réél "double"
+//--
+//++
+// Titre	Opérateurs d'affectation
+//--
+//++
+// PIGrCoord& operator= (int a) 
+//	Affectation à partir de valeur entière "int"
+// PIGrCoord& operator= (float a) 
+//	Affectation à partir de valeur réélle "float"
+// PIGrCoord& operator= (double a) 
+//	Affectation à partir de valeur réélle double précision "double"
+//--
+
Index: /tags/V_Dec2002/SophyaPI/PI/pigrcoord.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pigrcoord.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pigrcoord.h	(revision 2309)
@@ -0,0 +1,40 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive     PIGrCoord
+// Classe de gestion de coordonnees grpahique   R. Ansari  97
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PIGRCOORD_H_SEEN
+#define PIGRCOORD_H_SEEN
+
+#include "pisysdep.h"
+
+
+//  Classe pour gerer indifferement des coordonnees double ou int 
+class PIGrCoord {
+public:
+  inline PIGrCoord() { iv = 0; dv = 0.;}
+  inline PIGrCoord(int a) { iv = a; dv = (double)a;}
+  inline PIGrCoord(float a) { iv = (a>=0.)?(int)(a+0.5):(int)(a-0.5); dv = (double)a;}
+  inline PIGrCoord(double a) { iv = (a>=0.)?(int)(a+0.5):(int)(a-0.5); dv = a;}
+  inline PIGrCoord(PIGrCoord const & gc) { iv = gc.iv;  dv = gc.dv; }
+  explicit PIGrCoord(const char * sv);
+
+  inline operator int() { return(iv); }
+  inline operator short() { return((short)iv); }
+  inline operator unsigned int() { return((unsigned int)iv); }
+  inline operator unsigned short() { return((unsigned short)iv); }
+  inline operator float() { return((float)dv); }
+  inline operator double() { return(dv); }
+  inline PIGrCoord& operator= (int a) { iv = a; dv = (double)a; return(*this); }
+  inline PIGrCoord& operator= (float a) 
+        { iv = (a>=0.)?(int)(a+0.5):(int)(a-0.5); dv = (double)a; return(*this); }
+  inline PIGrCoord& operator= (double a) 
+        { iv = (a>=0.)?(int)(a+0.5):(int)(a-0.5); dv = a; return(*this); }
+  inline PIGrCoord& operator= (PIGrCoord const & gc) { iv = gc.iv; dv = gc.dv;  return(*this); }
+protected:
+  int iv;
+  double dv;
+};
+
+
+#endif      // PIGRCOORD_H_SEEN
Index: /tags/V_Dec2002/SophyaPI/PI/piimage.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piimage.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piimage.cc	(revision 2309)
@@ -0,0 +1,1516 @@
+// Module PI : Peida Interactive     PIImage
+// Affichage d'image            R. Ansari  05/95
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+//                        Refonte   Reza   10/95
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "piimage.h"
+#include "piimgtools.h"
+#include "pidrwtools.h"
+#include "piscdrawwdg.h"
+#include "piyfxdrw.h"
+#include PIAPP_H
+
+#define PERC_GARDE 0.05
+
+//++
+// Class	PIImage
+// Lib		PI
+// include	piimage.h
+//
+//   	Classe pour la l'affichage et la manipulation d'images.
+//	Peut contrôler un PIPixmap pour l'affichage d'une zone
+//	agrandie (zoom) et un PIPixmap pour l'affichage de toute
+//	l'image (réduite). Peut aussi gerer une fenetre de coupes.
+//	Utilise les adaptateur de tableaux 2D manipuler le
+//	contenu des images ("P2DArrayAdapter").
+//
+//	* Bouton-1 : Envoie le message "PIMsg_Active" et affiche
+//	les coordonnées courantes et la valeur du pixel, 
+//	et positionne le pavé.
+//	* Bouton-2 : Permet de définir une zone de l'image et repositionne le pavé.
+//	* Bouton-3 : Permet de déplacer l'image dans la fenêtre
+//
+//	Gestion du clavier :
+//	* <Alt>O : Affichage de la fenêtre de contrôle des paramètres de visualisation.
+//	* <Alt>G : Affichage de la fenêtre de changement des attributs graphiques
+//	* <Alt>R : Rafraîchit l'affichage.
+//	* <Alt>V : Copier/*Coller* Ajout du texte du buffer copier/coller
+//	sur l'objet à la position courante.
+//	* <Alt>C : *Copier*/Coller Permet de copier le contenu de la zone sélectionnée
+//	de l'image sous forme texte.
+//	* <Alt>P : Active/désactive l'affichage de l'indicateur de la postion du pavé
+//	* <Alt>X : Active/désactive l'affichage des coupes X,Y
+//	* <Alt>Z : Supprime les élément graphiques ajoutés au dessin.
+//	* <Alt>E : Supprime le dernier élément graphique ajouté.
+//	* <Alt>+ <Cntl>+ : Augmentation du facteur de zoom
+//	* <Alt>- <Cntl>- : Diminution du facteur de zoom
+//	* Touches Curseurs : déplace la pavé.
+//--
+//++
+// Links	Parents
+// PIPixmap
+//--
+//++
+// Links	Voir aussi
+// PIColorMap
+// P2DArrayAdapter
+// PIImgTools
+// PIDrwTools
+//--
+
+//++
+// Titre	Constructeurs
+//--
+//++
+//  PIImage(PIContainerGen *par, const char *nom=NULL, int sx=0, int sy=0, int px=0, int py=0)
+//	Constructeur
+//  
+//--
+
+// --------------------------------------------------------------------------------
+// ----------------------------- Classe PIImage -----------------------------------
+// --------------------------------------------------------------------------------
+// Variable globale pour la gestion de l'image courante 
+PIImage* PIImage::cur_piimage = NULL;
+/* --Methode-- */
+PIImage* PIImage::CurrentPIImage() 
+{ 
+return(cur_piimage); 
+}
+
+/* --Methode-- */
+void PIImage::SetCurrentPIImage(PIImage* curimg) 
+{ 
+cur_piimage = curimg;
+}
+
+/* --Methode-- */
+PIImage::PIImage(PIContainerGen *par, const char *nom,
+   int sx, int sy, int px, int py) :
+  PIPixmap(par, nom, sx, sy, px, py)
+{
+
+img = NULL;
+aisup = false;
+curshow = true;
+winovis = true;     // $CHECK$ Reza A enlever si possible 17/6/96
+
+
+zow = NULL;   // Widget zoom
+gvw = NULL;   // widget vue globale
+cmvw = NULL;  // widget ColorMapView
+// Fenetre transient et Label pour affichage de l'info (texte PixVal)
+int tx, ty;
+PIApplicationPrefCompSize(tx, ty);
+tx *= 5;    ty = (int)(ty*0.8);
+trtw = new PIWindow(this, "PixVal", PIWK_transient, tx, ty, 0, 0);
+trtw->SetAutoDelChilds(true);
+trtlb = new PILabel(trtw, "PixVal", tx, ty, 0, 0);
+trtlb->SetBinding(PIBK_fixed,PIBK_fixed, PIBK_fixed,PIBK_fixed);
+ustrtw = atrtw = false;
+if ((sx < 300) || (sy < 150) ) atrtw = true;
+showinfo = false;
+
+// Fenetre et ScDrawWdg pour les coupes
+selcuts = 3;
+cutwin = NULL;
+cutscw = NULL; 
+
+gpixm = zpixm = pixm = NULL;
+xsgpxm = xszpxm = xspxm = 0;
+ysgpxm = yszpxm = yspxm = 0;
+lut = NULL; 
+offx = offy = 0;
+xpav = ypav = 0;
+xpv0 = ypv0 = 0;
+xszpav = yszpav = 1;
+xmv0 = ymv0 = -1;
+dxmv = dymv = 0;
+xcurs = ycurs = -1;
+cuhsz = 8;  cuvsz = 8;
+cucol = PI_Yellow; culat = PI_NormalLine; 
+zoom = 1;
+zmgv = 1;
+
+mdrw = new PIElDrawer(false);
+gvdrw = new PIElDrawer();
+AddDrawer(mdrw, true, false, false);
+
+SetLut(-9.e19, 9.e19, kLutType_Lin, 0, false);
+SetColMapId(CMAP_COLRJ32);
+// pour le copier-coller
+cpbuffer = NULL;
+cpbuflen = 0;
+
+SetBackgroundColor(PI_Black);
+
+ActivateKeyboard();
+ActivateButton(1);
+ActivateMove(1);
+ActivateButton(2);
+ActivateMove(2);
+ActivateButton(3);
+ActivateMove(3);
+
+cur_piimage = this;
+}
+
+/* --Methode-- */
+PIImage::~PIImage()
+{
+if (pixm) delete pixm;
+if (zpixm) delete zpixm;
+if (zow) 
+  {
+  zow->SetPixmap(NULL,0,0);
+  zow->EraseWindow();
+  }
+if (gpixm) delete gpixm;
+if (gvw) 
+  {
+  gvw->SetPixmap(NULL,0,0);
+  gvw->EraseWindow();
+  gvw->SetMsg(0); gvw->SetMsgParent(NULL); 
+  gvw->SetUserData(NULL, 0); 
+  }
+if (cmvw)  cmvw->SetColMap(NULL, 1., -1., true);
+if (cutwin)  delete cutwin;
+if (lut) delete lut;
+delete mdrw;
+delete gvdrw;
+if (aisup && img)  delete img;   // Suppression automatique d'image
+delete trtw;
+if (cpbuffer)  delete[] cpbuffer;
+if (this == cur_piimage)  cur_piimage = NULL;
+}
+
+/* --Methode-- */
+void PIImage::Process(PIMessage msg, PIMsgHandler* sender, void* data)
+{
+
+if ((ModMsg(msg) == PIMsg_Close) && (sender == cutwin)) {
+  cutwin->Hide();
+  delete cutwin;
+  cutwin = NULL;
+  cutscw = NULL;
+  }
+else if (UserMsg(msg) == (Msg()+626))
+  {
+  if (ModMsg(msg) == PIMsg_Click) 
+    { int* pxy=(int *)data;   SetPave(pxy[0]*zmgv, pxy[1]*zmgv); }
+  if (ModMsg(msg) == PIMsg_Resize)
+    { ComputeGloVPixmap();   SetGloVPixmap(); }
+  }
+else ReSend(msg, sender, data);
+return;
+}
+
+//++
+// Titre	Méthodes
+//      Seule les méthodes les plus usuelles sont décrites ici. Se reporter
+//      au fichier .h pour la liste complete des méthodes
+//--
+
+//++
+// void SetImage(P2DArrayAdapter* pim, bool ad = true, bool refr=true)
+//	Associe un tableau "P2DArrayAdapter* pim" a l'objet "PIImage"
+//	pour affichage. si "ad==true", la tableau "pim" est detruit
+//	(par delete) lors de la destruction de l'objet PIImage.
+//	Si "ref==true", la fenetre est rafraichie.
+// void SetZoomWin(PIPixmap * zw, bool refr=false)
+//	Associe une fenetre "(PIPixmap * zw)" pour l'affichage
+//	d'une portion d'image agrandie.
+//	Si "refr=="true", la fenetre de zoom est rafraichie
+// SetGloVWin(PIPixmap * zw, bool refr=false)
+//	Associe une fenetre "(PIPixmap * zw)" comme fenetre de vue globale
+//	de l'image.
+//	Si "refr=="true", la fenetre de vue globale est rafraichie
+// SetCMapWin(PICMapView * cw, bool refr=false)
+//	Associe un objet "PICMapView * cw" pour l'affichage de la table
+//	des couleurs.
+//	Si "refr=="true", la fenetre de la table des couleurs est rafraichie
+//--
+
+/* --Methode-- */
+void PIImage::SetImage(P2DArrayAdapter *pim, bool ad, bool refr)
+{
+
+offx = offy = 0;
+xpav = ypav = 0;
+xszpav = yszpav = 1;
+img = pim;
+if (gpixm) delete gpixm;
+gpixm = NULL;
+xsgpxm = ysgpxm = 0;
+zmgv = 1;
+
+if (img)  {
+//  SetSize(img->XSize(), img->YSize());
+  CenterPave();
+  double min=1., max=-1., moy, sig;
+  int nbnul, nbsat;
+  img->CheckDyn(min, max, moy, sig, nbnul, nbsat);
+  SetLut(min, max, kLutType_Lin, 1, refr);
+  aisup = ad;
+  }
+else aisup = false;
+return;
+}
+
+/* --Methode-- */
+void PIImage::ChangeAxesConfiguration(bool ix, bool iy, bool xy, bool refr)
+{
+if (!img) return;
+bool invx, invy, exy;
+img->GetAxesConfiguration(invx, invy, exy);
+if (ix)  invx = !invx;
+if (iy)  invy = !invy;
+if (xy)  exy = !exy;
+img->ConfigureAxes(invx, invy, exy);
+ComputeGloVPixmap();
+if (refr) Apply();
+}
+
+/* --Methode-- */
+void PIImage::SetZoomWin(PIPixmap * zw, bool refr) 
+{
+zow = zw;
+if (zow && refr && img)
+  ComputeZoomPixmap();
+return;
+}
+
+/* --Methode-- */
+void PIImage::SetGloVWin(PIPixmap * zw, bool refr) 
+{
+gvw = zw;
+if (gvw && img)  
+  { ComputeGloVPixmap();
+  if (refr) SetGloVPixmap(); } 
+return;
+}
+
+/* --Methode-- */
+void PIImage::SetCMapWin(PICMapView * cw, bool refr)
+{
+cmvw = cw;
+if (cmvw && refr) cmvw->SetColMap(cmap, Lut()->Min(), Lut()->Max(), true);
+}
+
+
+/* --Methode-- */
+void PIImage::UseInfoWin(bool trw)
+{
+ustrtw = trw;
+}
+
+/* --Methode-- */
+void PIImage::ShowInfo(bool si)
+{
+if (showinfo == si) return;
+showinfo = si;
+if (showinfo && img)  { 
+  char * ibuff = img->InfoString(xpav, ypav);
+  DrawInfo(mWGrC, ibuff);
+  }
+else DrawInfo(mWGrC, NULL);
+}
+
+/* --Methode-- */
+void PIImage::ShowCursor(bool sc)
+{
+if (curshow == sc) return;
+curshow = sc;
+if (curshow)  DrawCursor(mWGrC);
+else DrawCursor(mWGrC, -1, -1);
+return;
+}
+
+
+/* --Methode-- */
+void PIImage::ShowCuts(bool cuts)
+{
+if (cuts) {
+  if (cutwin) { cutwin->Show(); return; }
+  int tpx, tpy;
+  GetScreenPos(tpx, tpy);
+  string nom = Nom() + "-Cuts";
+  int sx, sy;
+  int ssx, ssy;
+  PIApplicationScreenSize(ssx, ssy);
+  if ( (ssx > 1000) && (ssy > 1000) ) { sx = 400;  sy = 250; }
+  else { sx = 300; sy = 200; }
+  cutwin = new PIWindow(this, nom.c_str(), PIWK_normal, sx, sy, tpx, tpy+YSize()+10);
+  cutwin->SetAutoDelChilds(true);
+  nom += "_ScWdg";
+  cutscw = new PIScDrawWdg(cutwin, nom.c_str(), sx, sy, 0, 0);
+  cutscw->SetBinding(PIBK_fixed, PIBK_fixed, PIBK_fixed, PIBK_fixed);
+  cutarrx = new PIImg1DArrAdapter();
+  cutarry = new PIImg1DArrAdapter();
+  cutarrd = new PIImg1DArrAdapter();
+  cutarra = new PIImg1DArrAdapter();
+  PIYfXDrawer * drw;
+  string dum = "";
+  drw = new PIYfXDrawer(cutarrx, NULL, true);
+    drw->GetGraphicAtt().SetColAtt(PI_Red);
+    drw->GetGraphicAtt().SetMarkerAtt(5, PI_CrossMarker);
+    drw->GetGraphicAtt().SetLineAtt(PI_ThinLine);
+    cutscw->AddScDrawer(drw, true);
+    dum += "Red: X, ";
+  drw = new PIYfXDrawer(cutarry, NULL, true);
+    drw->GetGraphicAtt().SetColAtt(PI_Blue);
+    drw->GetGraphicAtt().SetMarkerAtt(5, PI_TriangleMarker);
+    drw->GetGraphicAtt().SetLineAtt(PI_ThinLine);
+    cutscw->AddScDrawer(drw, true);
+    dum += "Blue: Y, ";
+  drw = new PIYfXDrawer(cutarrd, NULL, true);
+    drw->GetGraphicAtt().SetColAtt(PI_Green);
+    drw->GetGraphicAtt().SetMarkerAtt(5, PI_PlusMarker);
+    drw->GetGraphicAtt().SetLineAtt(PI_ThinLine);
+    cutscw->AddScDrawer(drw, true);
+    dum += "Green: XY, ";
+  drw = new PIYfXDrawer(cutarra, NULL, true);
+    drw->GetGraphicAtt().SetColAtt(PI_Orange);
+    drw->GetGraphicAtt().SetMarkerAtt(5, PI_BoxMarker);
+    drw->GetGraphicAtt().SetLineAtt(PI_ThinLine);
+    cutscw->AddScDrawer(drw, true);
+    dum += "Orange: -XY";
+  cutscw->SetTitles(dum, "");
+  UpdateCuts();
+  cutwin->Show();
+  }
+else {
+  if (!cutwin)  return;
+  cutwin->Hide();
+  delete cutwin;
+  cutwin = NULL;
+  cutscw = NULL;
+  }
+}
+
+/* --Methode-- */
+void PIImage::SelectCuts(unsigned xyda)
+// choix des cuts pour le display:
+// 1=axe des (X), 2=axe des (Y), 4=diag (X,Y), 8=anti-diag (X,-Y)
+{
+selcuts = xyda;
+if(!(selcuts&15)) selcuts = 3;
+UpdateCuts();
+}
+
+//++
+// SetLut(double min, double max, int typlut=kLutType_Lin, \
+//        int lauto=0, bool refr=true)
+//	Definit la LUT pour l'affichage
+//	Si "refr=="true", la fenetre est rafraichie
+// SetLut(LUT *clut, bool refr=true)
+//	Associe l'objet "LUT* clut", a l'objet PIImage. "clut" doit 
+//	etre construit avec new 
+// SetZoom(int zm, bool refr=true);
+//	Changement du facteur d'agrandissement - si zm Negatif, l'image
+//	sera reduit (taille d'affichage) du facteur 1/(-zm)
+//	Si "refr=="true", la fenetre est rafraichie
+// SetZoomF(float fzm, bool refr=true)
+//	Specification du facteur d'agrandissement en valeur flottante.
+// SetColMap(PIColorMap* cmp, bool refr=true)
+//	Specification d'une nouvelle table de couleur, "PIColorMap* cmp"
+//	qui doit etre obtenu par new.
+//	Si "refr=="true", la fenetre est rafraichie
+// SetColMapId(CMapId cmapid, bool refr=true)
+//	pecification d'une nouvelle table de couleur	
+//--
+
+/* --Methode-- */
+void PIImage::SetLut(double min, double max, int typlut, int lauto, bool refr)
+{
+if (lut) delete(lut);
+if (lauto && img) 
+  {
+  int nbsig = lauto;  
+  double fracmax = 1. - 0.05*nbsig;
+  int nbnul, nbsat;
+  double moy, sig;
+  img->CheckDyn(min, max, moy, sig, nbnul, nbsat);
+  img->ComputeLut_PicHisto(min, max, nbsig, fracmax);
+  }
+
+lut = new LUT(min, max, NbCol(), typlut);
+
+ComputeGloVPixmap();
+if (refr) Apply();
+return;
+}
+
+
+/* --Methode-- */
+void PIImage::SetLut(LUT *clut, bool refr)
+{
+LUT * olut = lut;
+lut = new LUT(clut->Min(), clut->Max(), NbCol(), clut->Type());
+if (olut) delete olut;
+
+ComputeGloVPixmap();
+if (refr) Apply();
+return;
+}
+
+/* --Methode-- */
+void PIImage::SetZoomF(float fzm, bool refr)
+{
+int zm;
+
+if (fzm < 0.001) return;
+if (fzm < 1.)  zm = (int)(-(1./fzm));
+else zm = (int)(fzm+0.25);
+SetZoom(zm, refr);
+return;
+}
+
+/* --Methode-- */
+void PIImage::SetZoom(int zm, bool refr)
+{
+if ((zm == 0) || (zm == -1) )  zoom = 1;
+else if (zm > 128)  zoom = 128;
+else if (zm < -128) zoom = -128;
+else zoom = zm;
+if (img)
+  { SetOffsetFromPave();
+  if (refr) Apply(); }
+return;
+}
+
+/* --Methode-- */
+float PIImage::GetZoomF() const 
+{
+if (zoom >= 1)  return((float)zoom);
+else return(-1./(float)zoom);
+}
+
+
+/* --Methode-- */
+void PIImage::SetOffset(int ox, int oy, bool refr)
+{
+if (img == NULL)  {offx = offy = 0;  return; }
+if (ox < 0)  ox = 0;
+if (ox >= (img->XSize()-1))  ox = img->XSize()-2;
+if (oy < 0)  oy = 0;
+if (oy >= (img->YSize()-1))  oy = img->YSize()-2;
+offx = ox;  offy = oy;
+CenterPave();
+if (refr) Apply();
+return;
+}
+
+
+/* --Methode-- */
+int PIImage::DecodeOptionString(vector<string> & opt, bool rmdecopt)
+{
+  vector<string> udopt;
+  unsigned int k = 0;
+  int ndec = opt.size();
+  bool fgcmapid=false, revcmapid=false; CMapId cmapid=CMAP_COLRJ32;
+  for( k=0; k<opt.size(); k++ ) {
+    string opts = opt[k];
+    // Facteur de zoom
+    if (opts.substr(0,5) == "zoomx") {
+      int zf = atoi(opts.substr(5).c_str());
+      SetZoom(zf, false);
+      continue;
+    }
+    if (opts.substr(0,5) == "zoom/") {
+      int zf = -atoi(opts.substr(5).c_str());
+      SetZoom(zf, false);
+      continue;
+    }
+    // Reverse table de couleur
+    if (opts == "revcmap") {
+      revcmapid = true;
+      continue;
+    }
+    // Table de couleur
+    bool fgcmap = false;
+    for(int kcc=0; kcc<PIColorMap::NumberStandardColorMaps(); kcc++) {
+      string colname = PIColorMap::GetStandardColorMapName(kcc);
+      for(unsigned int jll=0; jll<colname.length(); jll++)
+	colname[jll] = tolower(colname[jll]);
+      if (opts == colname) {
+	fgcmapid = fgcmap = true;
+        cmapid = PIColorMap::GetStandardColorMapId(kcc);
+	break;
+      }
+    }
+    if (fgcmap) continue;
+    // Position du centre d'image
+    if (opts.substr(0,12) == "imagecenter=") {
+      int xc = XPave();  
+      int yc = YPave();
+      sscanf(opts.substr(12).c_str(),"%d,%d",&xc, &yc);
+      SetPave(xc, yc, false, true);
+      continue;
+    }
+    // lut lineaire
+    if (opts.substr(0,4) == "lut=") {
+      double min = Lut()->Min();
+      double max = Lut()->Max();
+      size_t q = opts.find(',');
+      if (q < opts.length()-1)
+	sscanf(opts.substr(q+1).c_str(),"%lg,%lg",&min, &max);
+      int typlut=kLutType_Lin;      ;
+      if (opts.substr(4,3) == "lin")  typlut=kLutType_Lin;
+      else if (opts.substr(4,3) == "log")  typlut=kLutType_Log;
+      else if (opts.substr(4,4) == "sqrt")  typlut=kLutType_Sqrt;
+      else if (opts.substr(4,6) == "square")  typlut=kLutType_Square;
+      SetLut(min, max, typlut, 0, false);
+      continue;
+    }
+    ndec--;
+    if (rmdecopt)  udopt.push_back(opts);
+  }
+  // Set color map if requested
+  if(fgcmapid || revcmapid) SetColMapId(cmapid,revcmapid,false);
+
+  if (rmdecopt)  opt = udopt;
+  return(ndec);
+}
+
+
+/* --Methode-- */
+void PIImage::SetPave(int x, int y, bool refr, bool cent)
+{
+int xc, yc;
+
+if (img == NULL)  
+  { offx = offy = 0; 
+  xpav = ypav = 0; 
+  return; }
+
+if ( (x >= (img->XSize()-1)) || ( x < 0)  ||
+     (y >= (img->YSize()-1)) || ( y < 0)  ) return;
+
+if ( (x == xpav) && (y == ypav) )  return;
+xpav = x;  ypav = y;
+
+if ( PosImg2W(xpav,ypav,&xc, &yc) || cent)  // Il faut recenter l'image
+  { SetOffsetFromPave();  
+  if (refr) Apply(true);  }
+else if (refr)
+  { Apply(false);  if (curshow)  DrawCursor(mWGrC);  }
+
+return;
+}
+
+/* --Methode-- */
+void PIImage::SetColMap(PIColorMap* cmp, bool refr)
+{
+if (!cmp)  return;
+int cmapid = cmp->Type();
+if ( (cmapid == CMAP_GREY32) || (cmapid == CMAP_GREYINV32) || 
+     (cmapid == CMAP_GREY128) || (cmapid == CMAP_GREYINV128))  mdrw->GetGraphicAtt().SetColAtt(PI_Red);
+else mdrw->GetGraphicAtt().SetColAtt(PI_Turquoise);
+PIPixmap::SetColMap(cmp, refr);
+if (refr) { xcurs =  ycurs = -1; }
+if (zow)  zow->SetColMap(cmp, refr);
+if (gvw)  gvw->SetColMap(cmp, refr);
+if (cmvw) cmvw->SetColMap(cmap, Lut()->Min(), Lut()->Max(), refr);
+return;
+}
+
+/* --Methode-- */
+void PIImage::SetColMapId(CMapId cmapid, bool revidx, bool refr)
+{
+if ( (cmapid == CMAP_GREY32) || (cmapid == CMAP_GREYINV32) || 
+     (cmapid == CMAP_GREY128) || (cmapid == CMAP_GREYINV128))  mdrw->GetGraphicAtt().SetColAtt(PI_Red);
+else mdrw->GetGraphicAtt().SetColAtt(PI_Turquoise);
+PIPixmap::SetColMapId(cmapid, revidx, refr);
+if (zow)  zow->SetColMapId(cmapid, revidx, refr);
+if (gvw)  gvw->SetColMapId(cmapid, revidx, refr);
+if (cmvw) cmvw->SetColMapId(cmapid, revidx, Lut()->Min(), Lut()->Max(), refr);
+return;
+}
+
+
+/* --Methode-- */
+void PIImage::Apply(bool mw)
+{
+if (img == NULL)  return;
+if (mw)  {  
+  ComputePixmap();
+  Send(Msg(), PIMsg_Active);
+  cur_piimage = this;
+  PIDrwTools::SetCurrentBaseWdg(this);
+  }
+else {
+  char * ibuff = img->InfoString(xpav, ypav);
+  if (ustrtw || atrtw)  trtlb->SetLabel((string)ibuff);
+  else DrawInfo(mWGrC, ibuff);
+  }
+if (zow != NULL)   ComputeZoomPixmap();
+if (cutwin) UpdateCuts();
+if (gvw != NULL)
+  if ( (gvw->UserData() != this) || (mw) )  SetGloVPixmap();
+if (cmvw) cmvw->SetColMap(cmap, Lut()->Min(), Lut()->Max(), true);
+  
+return;
+}
+
+/* --Methode-- */
+void PIImage::Resize()
+{
+//printf("PIImage::Resize\n");
+// On bascule sur la fenetre transient pour l'affichage des valeurs si fenetre trop petite
+if ((XSize() < 300) || (YSize() < 150) ) atrtw = true;  
+else atrtw = false;
+PIPixmap::Resize();
+CenterPave();
+Apply();
+return;
+}
+
+/* --Methode-- */
+void PIImage::Draw(PIGraphic* g, int x0, int y0, int dx, int dy)
+{
+PIPixmap::Draw(g, x0, y0, dx, dy);
+xcurs = ycurs = -1;
+winovis = false;    // $CHECK$ Reza A enlever si possible 17/6/96
+if (curshow) {
+  int xc,yc;
+  PosImg2W(xpav, ypav, &xc, &yc);
+  if ((xc >= x0) && (xc < x0+dx) && 
+      (yc >= y0) && (yc < y0+dy) )  DrawCursor(g, xc, yc);
+  }
+
+if (showinfo && img) {
+  char * ibuff = img->InfoString(xpav, ypav);
+  DrawInfo(mWGrC, ibuff); 
+  }
+
+return;
+}
+
+/* --Methode-- */
+void PIImage::Keyboard(int key, PIKeyModifier kmod)
+{
+cur_piimage = this;
+if (kmod & PIKM_Alt) {
+  if      (key == 'R' || key == 'r') Apply(true);  // Pour tout rafraichir  
+  else if (key == 'V' || key == 'v') RequestSelection();  // Pour coller (copier/coller)  
+  else if (key == 'Z' || key == 'z') { mdrw->ElDelAll();  Refresh(); } // Pour supprimer tous les signes 
+  else if (key == 'E' || key == 'e') { mdrw->ElDelLast();  Refresh(); } // Pour supprimer le dernier element ajoute
+  else if (key == 'O' || key == 'o') PIImgTools::ShowPIImgTools();   // Fentre LUT et options 
+  else if (key == 'G' || key == 'g') {   // Fentre attributs graphiques 
+    PIDrwTools::SetCurrentBaseWdg(this);
+    PIDrwTools::ShowPIDrwTools();   // Fentre axes et options de trace
+    }
+  else if (key == 'P' || key == 'p') {   // Activation/desactivation affichage curseur
+    bool sc = !curshow;
+    ShowCursor(sc);
+    }
+  else if (key == 'X' || key == 'x') {   // Activation/desactivation affichage coupes X,Y 
+    bool cut = (cutwin == NULL) ? true : false; 
+    ShowCuts(cut);
+    }
+  else if (key == '+') {   // Zoom in (Augmentation du facteur de zoom)
+    //    cout << " ++Changing zoom factor " << GetZoomF() << " ---> " 
+    //	 << 2*GetZoomF() << endl;
+    SetZoomF(GetZoomF()*2., true);
+    }
+  else if (key == '-') {   // Zoom out (diminution du facteur de zoom)
+    //    cout << " --Changing zoom factor " << GetZoomF() << " ---> " 
+    //	 << 0.5*GetZoomF() << endl;
+    SetZoomF(GetZoomF()*0.5, true);
+    }
+// ----  Le copier ---- 
+  else if ((key == 'C' || key == 'c') && img) { 
+    // On limite la taille a 48x48
+    int i1 = XPave();  
+    int i2 = ( XSzPave() < 48 ) ? i1+XSzPave() : i1+48;
+    int j1 = YPave();  
+    int j2 = ( YSzPave() < 48 ) ? j1+YSzPave() : i1+48;
+    if ( ( (i2-i1) < 1 ) || ((j2-j1) < 1) ) return;
+    if (!ClaimSelection())  return;  // On n'a pas pu prendre possession de la zone d'echange
+    if (cpbuffer)  delete[] cpbuffer;
+    cpbuflen = (j2-j1)*(i2-i1+2)*12+(j2-j1)+128;
+    cpbuffer = new char[cpbuflen];
+    sprintf(cpbuffer,"PIImage: Pave(%dx%d) en (%d, %d) MaxCopie= 48x48 \n", 
+            XSzPave(), YSzPave(), i1, j1);
+    int i,j;
+    int l = strlen(cpbuffer);
+    for(j=j1; j<j2; j++) {
+      sprintf(cpbuffer+l,"L %3d:",j);
+      l += 6;
+      for(i=i1; i<i2; i++) { sprintf(cpbuffer+l," %10g", (*img)(i, j));  l += 11; }
+      cpbuffer[l] = '\n';  l++;
+      }
+    cpbuffer[l] = '\0';
+    cpbuflen = l+1;
+    }
+  }
+else if (kmod & PIKM_Cntl) {
+  if (key == '+') {   // Zoom in (Augmentation du facteur de zoom)
+    SetZoomF(GetZoomF()*2., true);
+    }
+  else if (key == '-') {   // Zoom out (diminution du facteur de zoom)
+    SetZoomF(GetZoomF()*0.5, true);
+    }
+}
+else if (kmod == PIKM_Blank) {
+  switch (key) {
+    case PIK_Up :
+      SetPave(xpav, ypav-1, true, false);
+      break;
+    case PIK_Down :
+      SetPave(xpav, ypav+1, true, false);
+      break;
+    case PIK_Left :
+      SetPave(xpav-1, ypav, true, false);
+      break;
+    case PIK_Right :
+      SetPave(xpav+1, ypav, true, false);
+      break;
+    default :
+      break;
+  }
+}
+
+}
+
+
+/* --Methode-- */
+void PIImage::But1Press(int x, int y)
+{
+int xp, yp;
+
+Send(Msg(), PIMsg_Active);
+cur_piimage = this;
+PIDrwTools::SetCurrentBaseWdg(this);
+if (img == NULL)  return;
+if ( PosW2Img(x, y, &xp, &yp) )  return;
+SelPointerShape(PI_CrossPointer);
+xpav = xp;  ypav = yp;
+if (ustrtw || atrtw) ShowTrTxW();
+Apply(false);
+if (curshow)  DrawCursor(mWGrC, -1,-1);
+return;
+}
+
+
+/* --Methode-- */
+void PIImage::Ptr1Move(int x, int y)
+{
+int xp, yp;
+if (img == NULL)  return;
+if ( PosW2Img(x, y, &xp, &yp) )  return;
+xpav = xp;  ypav = yp;
+Apply(false);
+return;
+}
+
+
+/* --Methode-- */
+void PIImage::But1Release(int /*x*/,  int /*y*/)
+{
+SelPointerShape(PI_ArrowPointer);
+if (curshow)  DrawCursor(mWGrC);
+if (ustrtw || atrtw) trtw->Hide();
+else if (!showinfo) DrawInfo(mWGrC, NULL);
+return;
+}
+
+
+/* --Methode-- */
+void PIImage::But2Press(int x, int y)
+{
+
+Send(Msg(), PIMsg_Active);
+cur_piimage = this;
+PIDrwTools::SetCurrentBaseWdg(this);
+if (img == NULL)  return;
+if ( PosW2Img(x, y, &xpv0, &ypv0) )  {  xmv0 = -1;  return; }
+xmv0 = x;  ymv0 = y;  dxmv = dymv = 0;
+if (curshow)  DrawCursor(mWGrC,-1,-1);
+mWGrC->SelGOMode(PI_GOXOR);
+PIColors xc;
+if ((GetColMapId() == CMAP_COLRJ32) || (GetColMapId() == CMAP_COLRJ128))  xc = PI_Yellow;
+else  xc = PI_ColorAllBits1;
+mWGrC->SelForeground(xc);
+mWGrC->SelLine(PI_NormalLine);
+if (ustrtw || atrtw) ShowTrTxW();
+return;
+}
+
+/* --Methode-- */
+void PIImage::Ptr2Move(int x, int y)
+{
+int xp, yp;
+if (img == NULL)  return;
+if (xmv0 < 0)  return;
+if ( PosW2Img(x, y, &xp, &yp) )  return;
+mWGrC->DrawBox(xmv0, ymv0, dxmv, dymv);
+dxmv = x-xmv0;  dymv = y-ymv0;
+mWGrC->DrawBox(xmv0, ymv0, dxmv, dymv);
+
+ {
+  char * ibuff = img->InfoString((xp+xpv0)/2, (yp+ypv0)/2 );
+ if (ustrtw || atrtw) trtlb->SetLabel((string)ibuff);
+ else DrawInfo(mWGrC, ibuff);
+ }
+
+return;
+}
+
+/* --Methode-- */
+void PIImage::But2Release(int x, int y)
+{
+int xp2, yp2;
+
+if (img == NULL)  return;
+if (xmv0 < 0)  return;
+mWGrC->DrawBox(xmv0, ymv0, dxmv, dymv);
+mWGrC->SelGOMode(PI_GOCopy);
+mWGrC->SelForeground(PI_White);
+if ( PosW2Img(x, y, &xp2, &yp2) )  
+  PosW2Img(xmv0+dxmv, ymv0+dymv, &xp2, &yp2);
+xpav = (xpv0+xp2)/2;
+ypav = (ypv0+yp2)/2;
+xszpav = xp2-xpv0;
+yszpav = yp2-ypv0;
+if (xszpav < 0)  xszpav = -xszpav;
+if (yszpav < 0)  yszpav = -yszpav;
+
+Apply(false);
+if (curshow)  DrawCursor(mWGrC);
+if (ustrtw || atrtw) trtw->Hide();
+else if (!showinfo) DrawInfo(mWGrC, NULL);
+return;
+}
+
+
+/* --Methode-- */
+void PIImage::But3Press(int x, int y)
+{
+int xp, yp;
+
+Send(Msg(), PIMsg_Active);
+cur_piimage = this;
+PIDrwTools::SetCurrentBaseWdg(this);
+if (img == NULL)  return;
+if ( PosW2Img(x, y, &xp, &yp) )  { xmv0 = -1;  return; }
+if (curshow)  DrawCursor(mWGrC,-1,-1);
+if (ustrtw || atrtw) ShowTrTxW();
+SelPointerShape(PI_TDLRArrowPointer);
+xmv0 = xp;
+ymv0 = yp;
+return;
+}
+
+
+/* --Methode-- */
+void PIImage::Ptr3Move(int x, int y)
+{
+int xp, yp;
+if (img == NULL)  return;
+if (xmv0 < 0)  return;
+if ( PosW2Img(x, y, &xp, &yp) )  return;
+
+char buff[256];
+sprintf(buff," DelX= %d , DelY= %d    ", xp-xmv0, yp-ymv0);
+if (ustrtw || atrtw) trtlb->SetLabel((string)buff);
+else DrawInfo(mWGrC, buff);
+}
+
+/* --Methode-- */
+void PIImage::But3Release(int x, int y)
+{
+int xp, yp;
+
+SelPointerShape(PI_ArrowPointer);
+if (ustrtw || atrtw) trtw->Hide();
+if (img == NULL)  return;
+if (xmv0 < 0)  return;
+if ( PosW2Img(x, y, &xp, &yp) )  return;
+
+offx -= (xp-xmv0);
+offy -= (yp-ymv0);
+
+if (offx < 0)  offx = 0;
+if (offy < 0)  offy = 0;
+if (offx >= img->XSize())  offx = img->XSize();
+if (offy >= img->YSize())  offy = img->YSize();
+xpav = xmv0;  ypav = ymv0;
+xmv0 = ymv0 = -1;
+Apply();
+return;
+}
+
+
+/* --Methode-- */
+void PIImage::PasteSelection(unsigned int typ, void *pdata, unsigned int l)
+{
+if (!img) return;
+if (typ != PICP_string) return;
+int ll = (l<256) ? l+1 : 256;
+char pc[256];
+strncpy(pc, (char*)pdata, ll-1);  pc[ll-1] = '\0';
+double fx, fy;
+img->Coord(xpav, ypav, fx, fy); 
+mdrw->ElAddText(fx, fy, pc );
+mdrw->Refresh();
+}
+
+/* --Methode-- */
+void * PIImage::ProvideSelection(unsigned int& typ, unsigned int& len)
+{
+typ = PICP_string;
+len = cpbuflen;
+return(cpbuffer);
+}
+
+/* --Methode-- */
+void PIImage::SelectionLost()
+{
+if (cpbuffer)  delete[] cpbuffer;
+cpbuffer = NULL;
+cpbuflen = 0;
+return;
+}
+
+
+
+/* --Methode-- */
+void PIImage::ComputePixmap()
+{
+unsigned int xwsz, ywsz;
+
+if (img == NULL)  return;
+xwsz = XSize();
+ywsz = YSize();
+
+pixm = img->ComputePixmap(lut, offx, offy, zoom, xwsz, ywsz, pixm, &xspxm, &yspxm);
+int xw1, yw1, xw2, yw2;
+xw1 = (xwsz-xspxm)/2;
+if (xw1 < 0) xw1 = 0;
+yw1 = (ywsz-yspxm)/2;
+if (yw1 < 0) yw1 = 0;
+xw2 = xspxm+xw1;
+yw2 = yspxm+yw1;
+SetDefaultDrawRectangle(xw1, yw1, xw2, yw2, false);
+// printf("--DBG-- ComputePixmap() %d %d $ %d %d :: %d %d , %d %d \n", xwsz, ywsz, xspxm, yspxm, xw1, yw1, xw2, yw2);
+int x1,y1, x2,y2;
+ofx = xw1;  ofy = yw1;
+PosW2Img(xw1, yw1, &x1, &y1);
+PosW2Img(xw2, yw2, &x2, &y2);
+double fx1,fy1, fx2, fy2; 
+img->Coord(x1,y1, fx1, fy2);  // fy1 et fy2 echange expres pour utiliser kAxeDirAuto  
+img->Coord(x2,y2, fx2, fy1);  // En effet Image de haut vers bas, Axes de bas vers haut par defaut 
+SetDefaultDrawerLimits(fx1, fx2, fy1, fy2, kAxeDirAuto, kAxeDirAuto);
+// printf("--DBG2-- ComputePixmap() %g %g  %g %g  \n", fx1, fx2, fy1, fy2);
+xcurs = ycurs = -1;
+SetPixmap(pixm, xspxm, yspxm, true, xw1, yw1); 
+// Refresh();
+return; 
+}
+
+
+/* --Methode-- */
+void PIImage::ComputeZoomPixmap()
+{
+unsigned int xwsz, ywsz;
+int lofx, lofy;
+int zm;
+
+if (zow == NULL)  return;
+if (img == NULL)  return;
+
+xwsz = zow->XSize();
+ywsz = zow->YSize();
+
+zm = zoom+4;
+// Calcul du facteur de zoom pour la petite fenetre de zoom
+float fzm = 1.0;
+if (zoom < 0) fzm = -1./(float)zoom;
+else  fzm = zoom;
+
+if (fzm < 0.25) zm = (-1./(fzm*4.0))-0.1;
+else if (fzm < 3.5)  zm = fzm*4.+0.1;
+else if (fzm < 7.5) zm = fzm*3.+0.1;
+
+if ( (zm==-1) || (zm == 0) ) zm = 1;
+if (zm > 0)
+  {
+  lofx = xpav-(xwsz/2/zm);
+  lofy = ypav-(ywsz/2/zm);
+  }
+else 
+  {
+  lofx = xpav-(-((int)xwsz)*zm/2);
+  lofy = ypav-(-((int)ywsz)*zm/2);
+  }
+if (lofx < 0)  lofx = 0;
+if (lofy < 0)  lofy = 0;
+
+zpixm = img->ComputePixmap(lut, lofx, lofy, zm, xwsz, ywsz, zpixm, &xszpxm, &yszpxm);
+zow->SetColMap(cmap, false);
+zow->SetPixmap(zpixm, xszpxm, yszpxm); 
+zow->SetUserData((void *)this, 0);
+// zow->Refresh();
+return; 
+
+}
+
+
+/* --Methode-- */
+void PIImage::ComputeGloVPixmap()
+{
+unsigned int xwsz, ywsz;
+int zmx,zmy;
+
+if (gvw == NULL)  return;
+if (img == NULL)  return;
+
+xwsz = gvw->XSize();
+ywsz = gvw->YSize();
+
+zmx = img->XSize()/xwsz;
+zmy = img->YSize()/ywsz;
+
+if (zmx < zmy)   zmx = zmy;
+if (zmx < 1)  zmx = 1;
+zmgv = zmx;
+if (zmx > 1)  zmx = -zmx;
+gpixm = img->ComputePixmap(lut, 0, 0, zmx, xwsz, ywsz, gpixm, &xsgpxm, &ysgpxm);
+// printf("DEBUG-ComputeGloVPixmap()  %d-%d , (%d,%d) , %d-%d \n", xwsz, ywsz, zmx, zmy, xsgpxm, ysgpxm);
+return;
+}
+
+/* --Methode-- */
+void PIImage::SetGloVPixmap()
+{
+float zm;
+int x,y, dx,dy;
+
+int xw1, yw1, xw2, yw2;
+xw1 = (gvw->XSize()-xsgpxm)/2;
+if (xw1 < 0) xw1 = 0;
+yw1 = (gvw->YSize()-ysgpxm)/2;
+if (yw1 < 0) yw1 = 0;
+xw2 = xsgpxm+xw1;
+yw2 = ysgpxm+yw1;
+
+if (zoom > 0) zm = zmgv*zoom;
+else zm = (float)zmgv/(float)(-zoom);
+x = offx/zmgv+1+xw1;
+y = offy/zmgv+1+yw1;
+dx =  (int) ( (float)XSize()/zm-1. );  
+dy =  (int) ( (float)YSize()/zm-1. );  
+
+gvw->DeleteDrawers();
+gvdrw->ElDelAll();
+gvdrw->SetLimits(xw1, xw2, yw1, yw2, kAxeDirLtoR, kAxeDirUpDown);
+int cmapid = cmap->Type();
+PIGraphicAtt gatt;
+if ( (cmapid == CMAP_GREY32) || (cmapid == CMAP_GREYINV32) || 
+     (cmapid == CMAP_GREY128) || (cmapid == CMAP_GREYINV128)) 
+  gatt.SetColAtt(PI_Red); 
+else gatt.SetColAtt(PI_Turquoise);
+gatt.SetLineAtt(PI_NormalLine);
+gvdrw->ElDrwMgr().ElAddRect(x,y,dx,dy,gatt);
+gvw->AddDrawer(gvdrw, xw1, yw1, xw2, yw2, false); 
+gvw->SetColMap(cmap, false);
+gvw->SetPixmap(gpixm, xsgpxm, ysgpxm, true, xw1, yw1); 
+gvw->SetUserData((void *)this, 0);
+gvw->SetMsg(Msg()+626);
+gvw->SetMsgParent(this);
+
+return; 
+}
+
+/* --Methode-- */
+void PIImage::UpdateCuts()
+{
+if (!cutwin || !img) return;
+
+int hsx, hsy, hsmin;
+P2DArrayAdapter * img0=NULL;
+hsx = XSzPave()/2;
+hsy = YSzPave()/2;
+hsmin = (hsx<hsy)? hsx: hsy;
+if(selcuts&1) img0=img; else img0=NULL;
+  cutarrx->SetData(img0, 1, 2*hsx+1, XPave(), YPave());
+if(selcuts&2) img0=img; else img0=NULL;
+  cutarry->SetData(img0, 2, 2*hsy+1, XPave(), YPave());
+if(selcuts&4) img0=img; else img0=NULL;
+  cutarrd->SetData(img0, 4, 2*hsmin+1, XPave(), YPave());
+if(selcuts&8) img0=img; else img0=NULL;
+  cutarra->SetData(img0, 8, 2*hsmin+1, XPave(), YPave());
+
+double x1,y1,x2,y2;
+img->Coord(XPave()-hsx, YPave()-hsy, x1, y1);
+img->Coord(XPave()+hsx, YPave()+hsy, x2, y2);
+  if(x1<x2) cutarrx->DefineXCoordinate(-cutarrx->Size()/2,  1.);
+    else    cutarrx->DefineXCoordinate( cutarrx->Size()/2, -1.);
+  if(y1<y2) cutarry->DefineXCoordinate(-cutarry->Size()/2,  1.);
+    else    cutarry->DefineXCoordinate( cutarry->Size()/2, -1.);
+img->Coord(XPave()-hsmin, YPave()-hsmin, x1, y1);
+img->Coord(XPave()+hsmin, YPave()+hsmin, x2, y2);
+  if(x1<x2) cutarrd->DefineXCoordinate(-cutarrd->Size()/2,  1.);
+    else    cutarrd->DefineXCoordinate( cutarrd->Size()/2, -1.);
+  if(x1<x2) cutarra->DefineXCoordinate(-cutarra->Size()/2,  1.);
+    else    cutarra->DefineXCoordinate( cutarra->Size()/2, -1.);
+
+// On calcule les limites :
+double xmin=0., xmax=0., ymin=0., ymax=0.; bool vue=false;
+if(cutarrx->Size()) {
+  if(!vue) vue=true;
+  xmax=cutarrx->Size()/2.+1.; xmin=-xmax; 
+}
+if(cutarry->Size()) {
+  if(!vue)
+    {vue=true; xmax=cutarry->Size()/2.+1.; xmin=-xmax;}
+  else if(cutarry->Size()>xmax)
+    {xmax=cutarry->Size()/2.+1.; xmin=-xmax;}
+}
+if(cutarrd->Size()) {
+  if(!vue)
+    {vue=true; xmax=cutarrd->Size()/2.+1.; xmin=-xmax;}
+  else if(cutarrd->Size()>xmax)
+    {xmax=cutarrd->Size()/2.+1.; xmin=-xmax;}
+}
+if(cutarra->Size()) {
+  if(!vue)
+    {vue=true; xmax=cutarra->Size()/2.+1.; xmin=-xmax;}
+  else if(cutarra->Size()>xmax)
+    {xmax=cutarra->Size()/2.+1.; xmin=-xmax;}
+}
+
+int i; double cv; vue = false;
+if(cutarrx->Size()) {
+  vue=true; ymax=ymin=cutarrx->Value(0);
+  for(i=0; i<cutarrx->Size(); i++) {
+    cv = cutarrx->Value(i);
+    if (cv < ymin)  ymin = cv;
+    if (cv > ymax)  ymax = cv;
+  }
+}
+if(cutarry->Size()) {
+  if(!vue) {vue=true; ymax=ymin=cutarry->Value(0);}
+  for(i=0; i<cutarry->Size(); i++) {
+    cv = cutarry->Value(i);
+    if (cv < ymin)  ymin = cv;
+    if (cv > ymax)  ymax = cv;
+  }
+}
+if(cutarrd->Size()) {
+  if(!vue) {vue=true; ymax=ymin=cutarrd->Value(0);}
+  for(i=0; i<cutarrd->Size(); i++) {
+    cv = cutarrd->Value(i);
+    if (cv < ymin)  ymin = cv;
+    if (cv > ymax)  ymax = cv;
+  }
+}
+if(cutarra->Size()) {
+  if(!vue) {vue=true; ymax=ymin=cutarra->Value(0);}
+  for(i=0; i<cutarra->Size(); i++) {
+    cv = cutarra->Value(i);
+    if (cv < ymin)  ymin = cv;
+    if (cv > ymax)  ymax = cv;
+  }
+}
+ymin -= PERC_GARDE*(ymax-ymin);
+ymax += PERC_GARDE*(ymax-ymin);
+cutscw->SetLimits(xmin, xmax, ymin, ymax);
+//cutscw->UpdateLimits();
+cutscw->Refresh();
+//printf("UpdateCuts()-DBG X: %d  -> %g  , Y: %d -> %g \n", cutarrx->Size(), cutarrx->Value(0),
+//       cutarry->Size(), cutarry->Value(0));
+}
+
+/* --Methode-- */
+void PIImage::DrawCursor(PIGraphic* g) 
+{
+int xc, yc;
+if (PosImg2W(xpav, ypav, &xc, &yc)) DrawCursor(g, -1, -1);
+else DrawCursor(g, xc, yc);
+return;
+}
+
+ 
+/* --Methode-- */
+void PIImage::DrawCursor(PIGraphic* g, int xc, int yc)
+{
+
+if (winovis)  return;      // $CHECK$ Reza A enlever si possible 17/6/96
+//printf("DBG-DrawCursor(g, %d, %d) \n", xc, yc);
+int cmapid = cmap->Type();
+if ( (xcurs>=0) && (ycurs>=0) ) {
+  if (g->kind() == PI_PSFileGraphics ) {
+    g->SelGOMode(PI_GOCopy);
+    if ( (cmapid == CMAP_GREY32) || (cmapid == CMAP_GREYINV32) ||
+         (cmapid == CMAP_GREY128) || (cmapid == CMAP_GREYINV128) )  g->SelForeground(PI_Red);
+    else  g->SelForeground(PI_Turquoise);
+    }
+  else  {
+    g->SelGOMode(PI_GOXOR);
+    //    g->SelGOMode(PI_GOInvert);
+    g->SelForeground(cucol);
+    }
+  g->SelLine(culat);
+  //  On efface le curseur precedant ou on le trace ds le postscript
+  g->DrawLine(xcurs-cuhsz, ycurs, xcurs-4, ycurs);
+  g->DrawLine(xcurs+4, ycurs, xcurs+cuhsz, ycurs);
+  g->DrawLine(xcurs, ycurs-cuvsz, xcurs, ycurs-4);
+  g->DrawLine(xcurs, ycurs+4, xcurs, ycurs+cuvsz);
+  //  printf("DrawCursor/Erase() %d %d - %d %d -> %d %d \n", xcurs, ycurs, cuhsz, cuvsz, xc, yc);
+  }
+
+if (g->kind() == PI_PSFileGraphics )  { 
+  g->SelLine(PI_NormalLine);
+  g->SelForeground(PI_White);  
+  return;
+  }
+
+if ((xc >= 0) && (yc >= 0)) 
+  {
+  g->SelGOMode(PI_GOXOR);
+  //  g->SelGOMode(PI_GOInvert);
+  // Nouvelle epaisseur de trait du curseur
+  if (zoom < -2) culat = PI_ThinLine;
+  else if (zoom < 4) culat = PI_NormalLine;
+  else culat = PI_ThickLine;
+  g->SelLine(culat);
+
+  // couleur  de trait du curseur
+  if ((cmapid == CMAP_COLRJ32) || (cmapid == CMAP_COLRJ128))  cucol = PI_Yellow;
+  else  cucol = PI_ColorAllBits1;
+  g->SelForeground(cucol);
+
+  // Nouveau taille du curseur
+  cuhsz = xszpav/2;  cuvsz = yszpav/2;
+  if (zoom > 0)  { cuhsz = xszpav*zoom/2;  cuvsz = yszpav*zoom/2; }
+  else { cuhsz = xszpav/(-zoom*2);  cuvsz = yszpav/(-zoom*2); }
+  if ( cuhsz < 10) cuhsz = 10;
+  if ( cuvsz < 10) cuvsz = 10;
+
+  xcurs = xc;   ycurs = yc;
+
+  g->DrawLine(xcurs-cuhsz, ycurs, xcurs-4, ycurs);
+  g->DrawLine(xcurs+4, ycurs, xcurs+cuhsz, ycurs);
+  g->DrawLine(xcurs, ycurs-cuvsz, xcurs, ycurs-4);
+  g->DrawLine(xcurs, ycurs+4, xcurs, ycurs+cuvsz);
+  //  printf("DrawCursor() %d %d - %d %d \n", xcurs, ycurs, cuhsz, cuvsz);
+  }
+else { 
+  xcurs = ycurs = -1; cuhsz = cuvsz = 10; 
+  cucol = PI_Yellow; culat = PI_NormalLine; 
+  }
+
+g->SelGOMode(PI_GOCopy);
+g->SelLine(PI_NormalLine);
+g->SelForeground(PI_White);
+return;
+}
+
+ 
+/* --Methode-- */
+void PIImage::DrawInfo(PIGraphic* g, char* txt)
+{
+g->SelFont(PI_NormalSizeFont, PI_RomanFont);
+if (txt) { 
+  PIColors fgc = g->GetForeground();
+  PIGOMode gm = g->GetGOMode();
+  g->SelGOMode(PI_GOCopy);
+  int cmapid = cmap->Type();
+  if ( (cmapid == CMAP_GREY32) || (cmapid == CMAP_GREYINV32) || 
+       (cmapid == CMAP_GREY128) || (cmapid == CMAP_GREYINV128))  g->SelForeground(PI_Red);
+  else g->SelForeground(PI_Turquoise);
+//  g->SelForeground(PI_White);
+  g->SelBackground(PI_Black);
+  g->DrawOpaqueString(20, YSize()-5, txt);
+  g->SelGOMode(gm);
+  g->SelForeground(fgc);
+  }
+else {
+  int a,d,h;
+  h = g->GetFont().GetFontHeight(a, d);
+  if (g->kind() != PI_PSFileGraphics )   PIPixmap::Draw(g, 0, YSize()-10-h, XSize(), h+10); 
+  }
+return;
+}
+
+/* --Methode-- */
+void PIImage::ShowTrTxW()
+{
+if (trtw) 
+  {
+  int tpx, tpy;
+  GetScreenPos(tpx, tpy);
+  tpy -= (trtw->YSize()+5);
+  if (tpy < 0)  tpy = 0;
+  trtw->SetPos(tpx, tpy);
+  trtw->Show();  
+  }
+
+return;
+}
+
+/* --Methode-- */
+int PIImage::PosW2Img(int xiw, int yiw, int * xp, int * yp)
+{
+if (!img) { *xp = *yp = 0;  return(1); }
+xiw -= ofx;  yiw -= ofy;   // Offset d'affichage du pixmap
+if (zoom > 0)
+  {
+  *xp = xiw/zoom+offx;
+  *yp = yiw/zoom+offy;
+  }
+else
+  {
+  *xp = offx-xiw*zoom;
+  *yp = offy-yiw*zoom;
+  }
+
+if ( (*xp >= 0) && (*xp < img->XSize() ) &&
+     (*yp >= 0) && (*yp < img->YSize() )  )   return(0);
+else return(1);
+}
+
+
+/* --Methode-- */
+int PIImage::PosImg2W(int xp, int yp, int * xiw, int * yiw)
+{
+if (!img) { *xiw = *yiw = -1;  return(1); }
+if (zoom > 0)
+  {
+  *xiw = (xp-offx)*zoom+(zoom/2);
+  *yiw = (yp-offy)*zoom+(zoom/2);
+  }
+else
+  {
+  *xiw = (offx-xp)/zoom;
+  *yiw = (offy-yp)/zoom;
+  }
+
+*xiw += ofx;  *yiw += ofy;    // Offset d'affichage du pixmap
+if (*xiw > XSize())  *xiw = -1;
+if (*yiw > YSize())  *yiw = -1;
+
+if ((*xiw < 0) || (*yiw < 0))  return(1);
+else return(0);
+}
+
+
+/* --Methode-- */
+void PIImage::SetOffsetFromPave()
+{
+if (!img) { offx = offy = 0; return; }
+if (zoom > 0)
+  {
+  offx = xpav-XSize()/2/zoom;
+  offy = ypav-YSize()/2/zoom;
+  }
+else
+  {
+  offx = xpav+XSize()/2*zoom;
+  offy = ypav+YSize()/2*zoom;
+  }
+
+if (offx < 0)  offx = 0;
+if (offx >= (img->XSize()-1))  offx = img->XSize()-2;
+if (offy < 0)  offy = 0;
+if (offy >= (img->YSize()-1))  offy = img->YSize()-2;
+
+return;
+}
+
+/* --Methode-- */
+void PIImage::CenterPave()
+{
+int xwsz, ywsz;
+
+if (zoom > 0)
+  { xwsz = XSize()/zoom;  
+  ywsz = YSize()/zoom;  }
+else
+  { xwsz = -(XSize()*zoom); 
+  ywsz = -(YSize()*zoom); }
+
+if (img) {   
+  if (xwsz > (img->XSize()-offx)) xwsz = (img->XSize()-offx);
+  if (ywsz > (img->YSize()-offy)) ywsz = (img->YSize()-offy);
+  }
+xpav = offx+xwsz/2; 
+ypav = offx+ywsz/2;
+xszpav = ((xwsz+ywsz)/15) ;
+if (xszpav < 1) xszpav = 1;
+yszpav = xszpav; 
+
+return;
+}
+
+
+//---------------------------------------------------------------------------------
+//-------  On definit une classe ArrayAdapter pour les donnees des coupes  --------
+//---------------------------------------------------------------------------------
+
+/* --Methode-- */
+PIImage::PIImg1DArrAdapter::PIImg1DArrAdapter() : P1DArrayAdapter(0) 
+{
+data = NULL;
+fgaxyda = 1;
+off1 = off2 = 0;
+}
+
+/* --Methode-- */
+void PIImage::PIImg1DArrAdapter::SetData(P2DArrayAdapter* d, unsigned short axyda
+                                        ,int sz,int o1,int o2)
+// axyda&1 axe (X), axyda&2 axe (Y), axyda&4 diag (X,Y), axyda&8 anti-diag (X,-Y)
+{
+data = d; mSize = 0;
+fgaxyda = axyda;
+if(!data) return;
+if (o1 < 0)  o1 = 0;
+if (o2 < 0)  o2 = 0;
+if (o1 >= d->XSize()) o1 = d->XSize()-1; 
+if (o2 >= d->YSize()) o2 = d->YSize()-1; 
+off1 = o1;
+off2 = o2;
+if ((sz%2) == 0)  sz++;
+if (sz < 0) sz = 1;
+mSize = sz;
+}
+
+/* --Methode-- */
+double PIImage::PIImg1DArrAdapter::Value(int i)
+{
+if (!data) return(0.);
+int j,k;
+if (fgaxyda&1) {          // Axe X
+  j = off1-mSize/2+i;
+  if (j<0) j=0; if(j>=data->XSize()) j=data->XSize()-1;
+  return((*data)(j,off2));
+  }
+else if (fgaxyda&2) {     // Axe Y
+  k = off2-mSize/2+i;
+  if(k<0) k=0; if(k>=data->YSize()) k=data->YSize()-1;
+  return((*data)(off1,k));
+  }
+else if (fgaxyda&4) {     // Axe XY
+  j = off1-mSize/2+i;
+  k = off2-mSize/2+i;
+  if(j<0) j=0; if(j>=data->XSize()) j=data->XSize()-1;
+  if(k<0) k=0; if(k>=data->YSize()) k=data->YSize()-1;
+  return((*data)(j,k));
+  }
+else if (fgaxyda&8) {     // Axe -XY
+  j = off1-mSize/2+i;
+  k = off2+mSize/2-i;
+  if(j<0) j=0; if(j>=data->XSize()) j=data->XSize()-1;
+  if(k<0) k=0; if(k>=data->YSize()) k=data->YSize()-1;
+  return((*data)(j,k));
+  }
+return(0.);
+}
Index: /tags/V_Dec2002/SophyaPI/PI/piimage.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piimage.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piimage.h	(revision 2309)
@@ -0,0 +1,202 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive     PIImage
+// Affichage d image            R. Ansari  05/95
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PIIMAGE_H_SEEN
+#define PIIMAGE_H_SEEN
+
+#include "parradapter.h"
+
+#include "pisysdep.h"
+
+#include "pieldrw.h"
+#include PIPIXMAP_H
+#include PISTDWDG_H
+#include PIWIN_H
+#include "picmapview.h"
+
+class PIScDrawWdg;
+
+class PIImage : public PIPixmap
+{
+
+public:
+  enum {ClassId = 5150};
+
+//  Les methodes 
+
+  PIImage(PIContainerGen *par, const char *nom=NULL, 
+           int sx=0, int sy=0, int px=0, int py=0);
+  ~PIImage();
+
+  virtual long    kind() {return ClassId; }
+
+//  Tableau des pixels et changement de configuration des axes 
+  void SetImage(P2DArrayAdapter* pim, bool ad = true, bool refr=true);
+  void ChangeAxesConfiguration(bool ix, bool iy, bool xy, bool refr=true);
+  inline void   SetDrawAxesFlags(unsigned int flags=kBoxAxes | kExtTicks | kLabels)
+                       { mdrw->SetAxesFlags(flags); mdrw->Refresh(); }
+
+// Fenetre de Zoom, Vue globale, ColorMap, text, ...
+  void SetZoomWin(PIPixmap * zw, bool refr=false);
+  void SetGloVWin(PIPixmap * zw, bool refr=false);
+  void SetCMapWin(PICMapView * cw, bool refr=false);
+
+  void UseInfoWin(bool trw=false);
+  void ShowInfo(bool si=true); 
+  void ShowCursor(bool sc=true); 
+
+  void ShowCuts(bool cuts=true);
+  void SelectCuts(unsigned xyda=3);
+
+//  Gestion du choix de LUT, facteur d agrandissement, table de couleur
+  void SetLut(double min, double max, int typlut=kLutType_Lin,
+              int lauto=0, bool refr=true);
+  void SetLut(LUT *clut, bool refr=true);
+
+  void SetZoom(int zm, bool refr=true);
+  void SetZoomF(float fzm, bool refr=true);
+  float GetZoomF() const ;
+  inline int GetZoom() const { return (zoom); }
+
+// Changement de table de couleur
+  virtual void SetColMap(PIColorMap* cmp, bool refr=true);
+  virtual void SetColMapId(CMapId cmapid, bool revidx, bool refr);
+  inline  void SetColMapId(CMapId cmapid, bool refr=true)
+               { SetColMapId(cmapid, false, refr); }
+
+// Positionnement image - pave
+  void SetOffset(int ox, int oy, bool refr=true);
+  void SetPave(int x, int y, bool refr=true, bool cent=true);
+
+//   Methode permettant de decoder des options a partir de chaines
+  virtual int  DecodeOptionString(vector<string> & opt, bool rmdecopt=true);
+
+// Acces aux informations
+  inline P2DArrayAdapter * Image() { return(img); }
+  inline LUT *     Lut() { return(lut); }
+  inline int XPave() { return(xpav); } ;
+  inline int YPave() { return(ypav); } ;
+
+  inline int XSzPave() { return(xszpav); }
+  inline int YSzPave() { return(yszpav); }
+
+  inline PIElDrawer* MyElDrawer() { return (mdrw); }
+  inline PIElDrawer* BaseDrawer() { return (mdrw); }
+
+// Rafraichissement des widgets auxiliaires (zoom, ...)
+  void Apply(bool mw=true);
+
+// Gestion du trace et des evenements 
+  virtual void Resize();
+  virtual void Draw(PIGraphic* g, int x0, int y0, int dx, int dy);
+
+  virtual void Keyboard(int key, PIKeyModifier kmod);
+  virtual void But1Press(int x, int y);
+  virtual void But1Release(int x, int y);
+  virtual void Ptr1Move(int x, int y);
+  virtual void But2Press(int x, int y);
+  virtual void But2Release(int x, int y);
+  virtual void Ptr2Move(int x, int y);
+  virtual void But3Press(int x, int y);
+  virtual void But3Release(int x, int y);
+  virtual void Ptr3Move(int x, int y);
+
+// Gestion du copier-coller
+  virtual void   PasteSelection(unsigned int typ, void *pdata, unsigned int l);
+  virtual void*  ProvideSelection(unsigned int& typ, unsigned int& len);
+  virtual void   SelectionLost();
+
+//  Pour acces par les ImgTools (LutWind, ...)
+  static PIImage* CurrentPIImage();
+  static void SetCurrentPIImage(PIImage* curimg);
+
+//  On definit une classe ArrayAdapter pour les donnees des coupes 
+  class PIImg1DArrAdapter : public P1DArrayAdapter {
+  public :
+	             PIImg1DArrAdapter();
+     virtual double  Value(int i);
+     virtual void    SetData(P2DArrayAdapter* d, unsigned short axyda, int sz, int o1, int o2);
+  protected :
+    P2DArrayAdapter* data;
+    unsigned short fgaxyda;
+    int off1, off2;
+  };
+
+protected:
+  virtual void    Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+  void ComputePixmap();
+  void ComputeZoomPixmap();
+  void ComputeGloVPixmap();
+  void SetGloVPixmap();
+  void UpdateCuts();
+
+  void DrawCursor(PIGraphic* g);
+  void DrawCursor(PIGraphic* g, int xc, int yc);
+  void DrawInfo(PIGraphic* g, char* txt);
+
+  void ShowTrTxW();
+
+  int PosW2Img(int xiw, int yiw, int * xp, int * yp);
+  int PosImg2W(int xp, int yp, int * xiw, int * yiw);
+
+  void SetOffsetFromPave();
+  void CenterPave();
+
+// Les donnees 
+  P2DArrayAdapter * img;
+  bool aisup;     // Flag de suppression automatique de img
+  bool curshow;
+  bool winovis;   // $CHECK$ Reza A enlever si possible 17/6/96
+// Tableau des pixels principal  
+  unsigned char * pixm;
+  int xspxm, yspxm;
+  LUT * lut;
+  int offx, offy;
+  PIElDrawer* mdrw;
+// Fenetre de zoom
+  int zoom;
+  PIPixmap * zow;
+  unsigned char * zpixm;
+  int xszpxm, yszpxm;
+// Fenetre pour l'image entiere  
+  int zmgv;
+  PIPixmap * gvw;
+  unsigned char * gpixm;
+  int xsgpxm, ysgpxm;
+  PIElDrawer* gvdrw;
+// Fenetre d'affichage du ColMap
+  PICMapView* cmvw;
+// Fenetre/champ de texte
+  PILabel * trtlb;
+  PIWindow * trtw;
+  bool ustrtw, atrtw;
+  bool showinfo;
+// Le pave et le curseur
+  int xpav, ypav;
+  int xpv0, ypv0;
+  int xmv0, ymv0;
+  int dxmv, dymv;
+  int xcurs, ycurs;  // Position curseur
+  int cuhsz, cuvsz;  // Taille vertical, horizontal curseur
+  PILineAtt culat;   // Attribut de ligne du curseur  
+  PIColors cucol;    // Attribut de couleur du curseur
+  int xszpav, yszpav;
+// Pour gerer une fenetre pour les coupes en X,Y
+  unsigned short selcuts;
+  PIWindow * cutwin;
+  PIScDrawWdg * cutscw;
+  PIImg1DArrAdapter * cutarrx; 
+  PIImg1DArrAdapter * cutarry; 
+  PIImg1DArrAdapter * cutarrd; 
+  PIImg1DArrAdapter * cutarra; 
+
+// buffer pour copier-coller
+  char* cpbuffer;
+  int cpbuflen;
+//  PIImage courante 
+  static PIImage* cur_piimage;
+};
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/piimgtools.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piimgtools.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piimgtools.cc	(revision 2309)
@@ -0,0 +1,494 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Outils de manipulation des PIImage  R. Ansari 06/98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include <stdlib.h>
+
+#include "piimgtools.h"
+#include "piimage.h"
+
+//++
+// Class	PIImgTools
+// Lib		PI
+// include	piimgtools.h
+//
+//	Classe de fenêtre de dialogue permettant de modifier interactivement
+//	Les différents attributs de visualisation pour les *PIImage* .
+//--
+//++
+// Links	Parents
+// PIWindow
+//--
+//++
+// Links	Voir aussi
+// PIImage
+//--
+
+//++
+// Titre	Méthodes statiques
+//--
+//++
+// void  ShowPIImgTools() 	
+//	Méthode statique permettant l'affichage de la fenêtre de contrôle des
+//	paramètres de visualisation des images. L'instance de la classe
+//	 "PIImgTools" est créée si nécessaire.
+// void  HidePIImgTools() 
+//	Désacative (cache) la fenêtre "PIImgTools" (méthode statique).
+//--
+
+// ------ Menu des options et fenetre de dialogue pour changement de LUT --------
+
+
+PIImgTools* PIImgTools::curlutw = NULL;
+/* --Methode-- */
+void PIImgTools::ShowPIImgTools() 
+{
+if (curlutw == NULL)  curlutw = new PIImgTools(PIApplicationGetApp());
+curlutw->Show();
+}
+
+/* --Methode-- */
+void PIImgTools::HidePIImgTools() 
+{
+if (curlutw == NULL)  return;
+curlutw->Hide();
+}
+
+/* --Methode-- */
+PIImgTools::PIImgTools(PIApplication* par)
+: PIWindow((PIMsgHandler*)par, "PIImageTools", PIWK_normal, 240, 240, 150, 150)
+{
+int bsx, bsy, spx, spy;
+
+// On definit la taille a partir de la taille par defaut des composantes 
+// PIApplicationPrefCompSize(bsx, bsy);
+par->PrefCompSize(bsx, bsy);
+spx = bsx/10;
+spy = bsy/4;
+
+// int wszx = 8*spx+3*bsx+2*bsy; 
+int wszx = 8*spx+3.5*bsx; 
+int wszy = (10+4)*spy+9*bsy;
+SetSize(wszx, wszy);
+
+int cpx = spx*2;
+int cpy = spy*2;
+int csx = cpx;
+int csy = cpy;
+mLab[0] = new PILabel(this, "MinPixel", bsx, bsy, cpx, cpy);
+cpy += spy+bsy; 
+mLab[1] = new PILabel(this, "MaxPixel", bsx, bsy, cpx, cpy);
+mLab[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+mLab[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+cpy = spy*2;
+cpx += spx+bsx; 
+mText[0] = new PIText(this, "MinVal", 1.5*bsx, bsy, cpx, cpy);
+mText[0]->SetText("1");
+cpy += spy+bsy; 
+mText[1] = new PIText(this, "MaxVal", 1.5*bsx, bsy, cpx, cpy);
+mText[1]->SetText("32000");
+mText[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+mText[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpy += spy+bsy; 
+cpx = spx*2;
+mOlb[0] = new PILabel(this, "LutType", bsx, bsy, cpx, cpy);
+mOlb[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += spx+bsx; 
+mOpt[0] = new PIOptMenu(this, "imglut-opt-1", 1.5*bsx, bsy, cpx, cpy);
+mOpt[0]->AppendItem("Linear", 1100);
+mOpt[0]->AppendItem("Log.", 1101);
+mOpt[0]->AppendItem("Sqrt", 1102);
+mOpt[0]->AppendItem("Square", 1103);
+mOpt[0]->SetValue(1100);
+mOpt[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+cpy += spy+bsy; 
+cpx = spx*2;
+mOlb[1] = new PILabel(this, "AutoLut", bsx, bsy, cpx, cpy);
+mOlb[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += spx+bsx; 
+mOpt[1] = new PIOptMenu(this, "imglut-opt-2", 1.5*bsx, bsy, cpx, cpy);
+mOpt[1]->AppendItem("+3 Sig", 1203);
+mOpt[1]->AppendItem("+2 Sig", 1202);
+mOpt[1]->AppendItem("+1 Sig", 1201);
+mOpt[1]->AppendItem("NoAuto", 1200);
+mOpt[1]->AppendItem("-1 Sig", 1199);
+mOpt[1]->AppendItem("-2 Sig", 1198);
+mOpt[1]->AppendItem("-3 Sig", 1197);
+mOpt[1]->SetValue(1202);
+mOpt[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+cpy += 2*spy+bsy; 
+cpx = 3*spx+0.2*bsx;
+mBut[0] = new PIButton(this, "Apply", 2500, bsx*1.6, bsy, cpx, cpy);
+// mBut[0] = new PIButton(this, "Apply", 2500, bsx, bsy, cpx, cpy);
+mBut[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += bsx*1.6+2*spx;
+// cpx += bsx+2*spx;
+mBut[1] = new PIButton(this, "Dismiss", 2600,  bsx*1.6, bsy, cpx, cpy);
+// mBut[1] = new PIButton(this, "Dismiss", 2600, bsx, bsy, cpx, cpy);
+mBut[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+int offy = cpy+bsy+spy*3;
+// printf("-DBG- PIImgTools()  SzX,Y= %d %d , ButPos= %d %d (off=%d)\n", wszx, wszy, cpx, cpy, offy);
+
+// cpx = 4*spx+2.75*bsx;
+cpx = wszx-bsx-3*spx;
+cpy = 2*spy;
+mSc[0] = new PIScale(this, "sc-offset-lut", 2700, kSDirDownUp, 0.5*bsx, 4.5*bsy, cpx, cpy); 
+cpx += 0.50*bsx+spx;
+mSc[1] = new PIScale(this, "sc-dyn-lut", 2800, kSDirDownUp, 0.55*bsx, 4.5*bsy, cpx, cpy); 
+mSc[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+mSc[0]->SetMinMax(-50, 50);
+mSc[0]->SetValue(0);
+mSc[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+mSc[1]->SetMinMax(-50, 50);
+mSc[1]->SetValue(0);
+
+//  Option-Menu  Couleur/Zoom
+cpx = 3*spx;
+cpy = offy;
+mOptzc[0] = new PIOptMenu(this, "imglut-opt-3", bsx*1.75, bsy, cpx, cpy);
+int kcc;
+//  Groupement des tables de couleurs
+mCasc[0] = new PIMenu(mOptzc[0]->Menu(), "PIStd-128Col");
+mCasc[1] = new PIMenu(mOptzc[0]->Menu(), "MIDAS-CMap");
+
+int nsct1,nsct2,nsct3;
+//  D'abord les tables standard de PI  32 couleurs
+nsct1 = 5;   // Les 5 premieres tables
+for(kcc=0; kcc<nsct1; kcc++) 
+  mOptzc[0]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(), 201+kcc);
+//  Ensuite les tables standard de PI  128 couleurs
+nsct2 = 9;   // Les 4 tables suivantes
+for(kcc=nsct1; kcc<nsct2; kcc++) 
+  mCasc[0]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(), 201+kcc);
+mOptzc[0]->AppendPDMenu(mCasc[0]);
+//  Apres les tables importees de MIDAS
+nsct3 = PIColorMap::NumberStandardColorMaps()-1; // Les reste jusqu'a l'avant derniere
+for(kcc=nsct2; kcc<nsct3; kcc++) 
+  mCasc[1]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(), 201+kcc);
+mOptzc[0]->AppendPDMenu(mCasc[1]);
+// Les tables qui restent ( Col16 , ... )
+for(kcc=nsct3; kcc<PIColorMap::NumberStandardColorMaps(); kcc++) 
+mOptzc[0]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(), 201+kcc);
+// On ajoute un CheckItem pour inverser les index de table de couleur
+mOptzc[0]->Menu()->AppendSeparator();
+mOptzc[0]->Menu()->AppendCheckItem("Reverse CMap", 299);
+
+mOptzc[0]->SetValue(203);  mLastCol = 203;
+mOptzc[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+cpx += bsx*1.75+2*spx;
+mOptzc[1] = new PIOptMenu(this, "imglut-opt-4", bsx*1.75, bsy, cpx, cpy);
+mOptzc[1]->AppendItem("Agr. x10", 110);
+mOptzc[1]->AppendItem("Agr. x 8", 108);
+mOptzc[1]->AppendItem("Agr. x 6", 106);
+mOptzc[1]->AppendItem("Agr. x 5", 105);
+mOptzc[1]->AppendItem("Agr. x 4", 104);
+mOptzc[1]->AppendItem("Agr. x 3", 103);
+mOptzc[1]->AppendItem("Agr. x 2", 102);
+mOptzc[1]->AppendItem("Zoom x 1", 101);
+mOptzc[1]->AppendItem("Red. / 2", 98);
+mOptzc[1]->AppendItem("Red. / 3", 97);
+mOptzc[1]->AppendItem("Red. / 4", 96);
+mOptzc[1]->AppendItem("Red. / 5", 95);
+mOptzc[1]->AppendItem("Red. / 6", 94);
+mOptzc[1]->AppendItem("Red. / 8", 92);
+mOptzc[1]->AppendItem("Red. /10", 90);
+mOptzc[1]->SetValue(101);
+mOptzc[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+cpy += spy+bsy;
+cpx = 4*spx+0.875*bsx;
+mOptCut = new PIOptMenu(this, "Cut", bsx*1.75, bsy, cpx, cpy);
+mOptCut->AppendItem("Cut X",301);
+mOptCut->AppendItem("Cut Y",302);
+mOptCut->AppendItem("CutXY",303);
+mOptCut->AppendItem("Cut D",304);
+mOptCut->AppendItem("Cut A",308);
+mOptCut->AppendItem("CutDA",312);
+mOptCut->AppendItem("CutAll",315);
+mOptCut->SetValue(303);
+mOptCut->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+int pbsx = 0.45*bsx;
+int pbsy = bsy;
+int pspx = spy/2;
+int pspy = spy;
+
+cpx = spx;
+cpy += bsy+spy;
+mButsz[0] = new PIButton(this, "1x1", 3201,  pbsx, pbsy, cpx, cpy);
+mButsz[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += pbsx+pspx;
+mButsz[1] = new PIButton(this, "1x2", 3202,  pbsx, pbsy, cpx, cpy);
+mButsz[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += pbsx+pspx;
+mButsz[2] = new PIButton(this, "1x4", 3204,  pbsx, pbsy, cpx, cpy);
+mButsz[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += pbsx+pspx;
+mButsz[3] = new PIButton(this, "1/2", 3198,  pbsx, pbsy, cpx, cpy);
+mButsz[3]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += pbsx+pspx;
+mButsz[4] = new PIButton(this, "1/4", 3196,  pbsx, pbsy, cpx, cpy);
+mButsz[4]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+//cpx += pbsx+10*pspx;
+cpx = wszx-3.0*pbsx-spx-pspx;
+mButoa[0] = new PIButton(this, "+Info", 5311,  1.5*pbsx, pbsy, cpx, cpy);
+mButoa[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += 1.5*pbsx+pspx;
+mButoa[1] = new PIButton(this, "-Info", 5312,  1.5*pbsx, pbsy, cpx, cpy);
+mButoa[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+
+cpx = spx;
+cpy += pbsy+pspy;
+mButcax[0] = new PIButton(this, "-X", 5201,  pbsx, pbsy, cpx, cpy);
+mButcax[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += pbsx+pspx;
+mButcax[1] = new PIButton(this, "-Y", 5202,  pbsx, pbsy, cpx, cpy);
+mButcax[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += pbsx+pspx;
+mButcax[2] = new PIButton(this, "X-Y", 5203, pbsx, pbsy, cpx, cpy);
+mButcax[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+// cpx += 1.5*pbsx+pspx+10*pspx;
+cpx = wszx-4.5*pbsx-spx-2*pspx;
+mButoa[2] = new PIButton(this, "-All", 5300,  1.5*pbsx, pbsy, cpx, cpy);
+mButoa[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += 1.5*pbsx+pspx;
+mButoa[3] = new PIButton(this, "+Curs", 5321,  1.5*pbsx, pbsy, cpx, cpy);
+mButoa[3]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += 1.5*pbsx+pspx;
+mButoa[4] = new PIButton(this, "+Axe", 5331,  1.5*pbsx, pbsy, cpx, cpy);
+mButoa[4]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+curlutw = this;
+
+}
+
+/* --Methode-- */
+PIImgTools::~PIImgTools()
+{
+if (curlutw == this)  curlutw = NULL;
+int i;
+for(i=0; i<2; i++)
+  {
+  delete mLab[i];
+  delete mBut[i];
+  delete mText[i];
+  delete mOpt[i];
+  delete mOlb[i];
+  delete mSc[i];
+  delete mOptzc[i];
+  }
+for(i=0; i<2; i++)  delete mCasc[i];
+for(i=0; i<5; i++)  delete mButsz[i];
+for(i=0; i<3; i++)  delete mButcax[i];
+for(i=0; i<5; i++)  delete mButoa[i];
+delete mOptCut;
+}
+
+/* --Methode-- */
+void PIImgTools::Show()
+{
+char buff[32];
+PIImage *mpii;
+PIWindow::Show();
+mpii = PIImage::CurrentPIImage();
+if (mpii == NULL) {
+  mOptzc[0]->Menu()->SetStateMsg(299, false);
+  mOptzc[0]->SetValue(203);  mLastCol = 203;
+  mOptzc[1]->SetValue(101);
+  mOptCut->SetValue(303);
+  return;
+}
+min_lut = mpii->Lut()->Min();
+max_lut = mpii->Lut()->Max();
+sprintf(buff,"%g", min_lut);
+mText[0]->SetText(buff);
+sprintf(buff,"%g", max_lut);
+mText[1]->SetText(buff);
+if     ( (mpii->Lut())->Type() == kLutType_Lin )    mOpt[0]->SetValue(1100);
+else if( (mpii->Lut())->Type() == kLutType_Log )    mOpt[0]->SetValue(1101);
+else if( (mpii->Lut())->Type() == kLutType_Sqrt )   mOpt[0]->SetValue(1102);
+else if( (mpii->Lut())->Type() == kLutType_Square ) mOpt[0]->SetValue(1103);
+else                                                mOpt[0]->SetValue(1100);
+string s("NoAuto");
+mOpt[1]->SetValueStr(s);
+mSc[0]->SetValue(0);
+mSc[1]->SetValue(0);
+
+// Pour mettre a jour le menu de la table de couleur
+mOptzc[0]->Menu()->SetStateMsg(299, mpii->GetColMap()->IsColorIndexReversed());
+int cmnum = PIColorMap::ColorMapId2Num(mpii->GetColMapId());
+mLastCol =  (cmnum < 0) ? 203 : 201+cmnum;
+mOptzc[0]->SetValue(mLastCol);
+
+// Pour le facteur de zoom
+mOptzc[1]->SetValue(mpii->GetZoom()+100);
+
+mOptCut->SetValue(303);
+return;
+}
+
+
+/* --Methode-- */
+void PIImgTools::Process(PIMessage msg, PIMsgHandler* /*sender*/, void* /*data*/)
+{
+double min, max, del;
+int lauto, typ;
+int typlut[4] = {kLutType_Lin, kLutType_Log, kLutType_Sqrt, kLutType_Square} ; 
+
+msg = UserMsg(msg);
+
+if (msg == 2600)  { this->Hide();  return; }
+PIImage* mpii = PIImage::CurrentPIImage();
+if (mpii == NULL)  return;
+
+switch (msg)
+  {
+  case 2500:
+  case 2700 :
+  case 2800 :
+    {
+    if (mText[0]->GetText().length() > 0)   
+      min = atof(mText[0]->GetText().c_str());
+    else min = mpii->Lut()->Min();
+    if (mText[1]->GetText().length() > 0)   
+      max = atof(mText[1]->GetText().c_str());
+    else max = mpii->Lut()->Max();
+
+    if (msg == 2700) {
+      del = max_lut-min_lut;
+      min = min_lut+(double)mSc[0]->GetValue()/100*del;
+      max = max_lut+(double)mSc[0]->GetValue()/100*del;
+    }
+    if (msg == 2800) {
+      del = max_lut-min_lut;
+      min = min_lut-(double)mSc[1]->GetValue()/100.*del*0.5;
+      max = max_lut+(double)mSc[1]->GetValue()/100.*del*0.5;
+    }
+    if ( (msg == 2700) || (msg == 2800) ) {
+      char buff[92];
+      sprintf(buff,"%g", min);
+      mText[0]->SetText(buff);
+      sprintf(buff,"%g", max);
+      mText[1]->SetText(buff);
+      lauto = 0;
+    }
+    else lauto = mOpt[1]->GetValue() - 1200;
+    typ = mOpt[0]->GetValue() - 1100;
+    if ( (typ < 0) || (typ > 3) )  typ = 0;
+    (PIImage::CurrentPIImage())->SetLut(min, max, typlut[typ], lauto);
+    if (msg == 2500) { 
+      min_lut = min;   max_lut = max;
+      mSc[0]->SetValue(0);
+      mSc[1]->SetValue(0);
+      }
+//    ((PIImage::CurrentPIImage())->Lut())->Print();
+    }
+    break;
+
+  case 3201 :
+  case 3202 :
+  case 3204 :
+  case 3198 :
+  case 3196 :
+    {
+    PIImage* pimg = PIImage::CurrentPIImage();
+    int zm = msg-3200;
+    pimg->SetZoom(zm, false);
+    int sx, sy, snx, sny;
+    sx = pimg->XSize();
+    sy = pimg->YSize();
+    if (zm > 0)
+      {
+      snx = pimg->Image()->XSize()*zm;
+      sny = pimg->Image()->YSize()*zm;
+      }
+    else 
+      {
+      snx = pimg->Image()->XSize()/(-zm);
+      sny = pimg->Image()->YSize()/(-zm);
+      }
+    if ((snx != sx) || (sny != sy))
+      {
+      int szinc[2];
+      pimg->SetOffset(0, 0, false);
+      szinc[0] = snx-sx;   szinc[1] = sny-sy;
+      pimg->Send(pimg->Msg(), PIMsg_ResizeRequest, szinc);  
+      }
+    else   pimg->SetOffset(0, 0);
+    
+    }
+    break;
+
+  case 5201 :
+    mpii->ChangeAxesConfiguration(true, false, false);
+    break;
+  case 5202 :
+    mpii->ChangeAxesConfiguration(false, true, false);
+    break;
+  case 5203 :
+    mpii->ChangeAxesConfiguration(false, false, true);
+    break;
+
+
+  case 5300 :
+    mpii->SetDrawAxesFlags(kAxesNone);
+    mpii->ShowCursor(false);
+    mpii->MyElDrawer()->ElDelAll();
+    mpii->Refresh();
+    break;
+
+  case 5311 :
+    mpii->ShowInfo(true);
+    break;
+
+  case 5312 :
+    mpii->ShowInfo(false);
+    break;
+
+  case 5321 :
+    mpii->ShowCursor(true);
+    break;
+
+  case 5331 :
+    mpii->SetDrawAxesFlags();
+    break;
+
+  default:
+//    printf("PIImgTools::Process Msg %d received \n", (int)msg);
+    break;
+  }
+
+
+if ((msg <= 110) && (msg >= 90))  // Zoom
+  PIImage::CurrentPIImage()->SetZoom((int)(msg-100), true);
+else if (msg == 299) { // Revert CMap index 
+  mOptzc[0]->SetValue(mLastCol);
+}
+else if ((msg > 200) && (msg < 299)) { // Changement de couleur 
+  //  bool irev = PIImage::CurrentPIImage()->GetColMap()->IsColorIndexReversed();
+  bool revidx = mOptzc[0]->Menu()->GetStateMsg(299);
+  //  cout << " DBG PIImgTools::Process() revidx= " ;
+  //  if (revidx) cout << " TRUE " ;
+  //  else cout << " FALSE " ;
+  //  if (irev) cout << " Img::RevIdx= TRUE " << endl;
+  //  else cout << " Img::RevIdx= FALSE " << endl;
+  PIImage::CurrentPIImage()->SetColMapId(PIColorMap::GetStandardColorMapId(msg-201), revidx, true);
+  mLastCol = msg;
+}
+
+// Cuts
+if(301<=msg && msg<=315) {
+  PIImage::CurrentPIImage()->SelectCuts((unsigned short) (msg-300));
+}
+
+return;
+}
+
Index: /tags/V_Dec2002/SophyaPI/PI/piimgtools.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piimgtools.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piimgtools.h	(revision 2309)
@@ -0,0 +1,55 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Outils de manipulation des PIImage  R. Ansari 06/98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PIIMGTOOLS_H_SEEN
+#define PIIMGTOOLS_H_SEEN
+
+#include "pisysdep.h"
+#include PISTDWDG_H
+#include PIOPTMENU_H
+#include PIWIN_H
+#include PIAPP_H
+
+// ------ fenetre de dialogue pour changement de LUT et options de PIImage --------
+// --------------------------------------------------------------------------------
+
+class PIImgTools : public PIWindow {
+public :
+  PIImgTools(PIApplication* par);
+  ~PIImgTools();
+  virtual void  Show();
+
+  static PIImgTools* curlutw;
+  static void ShowPIImgTools();
+  static void HidePIImgTools();
+protected:
+  virtual void  Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+
+private:
+// Pour changer la LUT
+  PILabel* mLab[2];
+  PIButton* mBut[2];
+  PIText* mText[2];
+  PIOptMenu* mOpt[2];
+  PILabel* mOlb[2];
+  PIScale* mSc[2];
+  double min_lut,max_lut;
+// Pour la couleur et le zoom
+  PIOptMenu* mOptzc[2];
+  PIMenu* mCasc[5];
+  PIMessage mLastCol;
+
+// Pour expand et compress
+  PIButton* mButsz[5];
+// Config axes 
+  PIButton* mButcax[3];
+// Options show/hide
+  PIButton* mButoa[5];
+// Options Cuts
+  PIOptMenu* mOptCut;
+};
+
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pilineatt.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pilineatt.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pilineatt.cc	(revision 2309)
@@ -0,0 +1,157 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive     PILineAtt 
+// Gestionnaire d'attributs de ligne   R. Ansari  2002
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "pilineatt.h"
+#include <math.h>
+
+//++
+// Class	PILineAtt
+// Lib		PI
+// include	pilineatt.h
+//--
+//++
+// Links	Voir aussi
+// PIGraphic
+// PIGraphicAtt
+//--
+//++
+// Titre	Constructeurs
+//--
+//++
+// explicit PILineAtt(int width=1, PILineDash dash=PI_LineSolid, \
+//          PILineJoin join=PI_JoinMiter, PILineCap cap=PI_CapButt)
+//	Constructeur avec possibilité de spécification de tous les 
+//	attributs de ligne.
+//
+//	enum PILineDash :
+//|	PI_LineSolid, PI_LineDashed
+//|	PI_LineDotted, PI_LineDashDotted
+//
+//	enum  PILineJoin :
+//|	PI_JoinMiter, PI_JoinRound, PI_JoinBevel
+//	enum  PILineCap :
+//|	PI_CapButt, PI_CapRound, PI_CapProjecting
+//
+// explicit PILineAtt(double width, PILineDash dash=PI_LineSolid, \
+//          PILineJoin join=PI_JoinMiter, PILineCap cap=PI_CapButt)
+//	Constructeur. 
+//
+// PILineAtt(PILineAtt const& b)
+//	Constructeur de copie.
+//
+// PILineAtt(PILineTypes ltyp)
+//	Constructeur à partir de l'enum *PILineTypes*
+//|	PI_NotDefLineAtt
+//|	PI_NormalLine, PI_ThinLine, PI_ThickLine
+//|	PI_DashedLine, PI_ThinDashedLine, PI_ThickDashedLine
+//|	PI_DottedLine, PI_ThinDottedLine, PI_ThickDottedLine
+//|	PI_DashDottedLine, PI_ThinDashDottedLine, PI_ThickDashDottedLine
+//--
+
+/* --Methode-- */
+PILineAtt::PILineAtt(PILineTypes ltyp)
+{
+  _lwidth = 2*8;
+  _ldash=PI_LineSolid; 
+  _ljoincap = PI_JoinMiter*PI_CapButt*256;
+  switch (ltyp) {
+    case PI_NotDefLineAtt :
+      _lwidth = 0; _ldash=PI_LineSolid; 
+      break;
+    case PI_NormalLine : 
+      _lwidth = 2*8; _ldash=PI_LineSolid; 
+      break;
+    case PI_ThinLine : 
+      _lwidth = 8; _ldash=PI_LineSolid; 
+      break;
+    case PI_ThickLine : 
+      _lwidth = 8*4; _ldash=PI_LineSolid; 
+      break;
+    case PI_DashedLine : 
+      _lwidth = 2*8; _ldash=PI_LineDashed; 
+      break;
+    case PI_ThinDashedLine : 
+      _lwidth = 8; _ldash=PI_LineDashed; 
+      break;
+    case PI_ThickDashedLine : 
+      _lwidth = 8*4; _ldash=PI_LineDashed; 
+      break;
+    case PI_DottedLine : 
+      _lwidth = 2*8; _ldash=PI_LineDotted; 
+      break;
+    case PI_ThinDottedLine : 
+      _lwidth = 8; _ldash=PI_LineDotted; 
+      break;
+    case PI_ThickDottedLine : 
+      _lwidth = 8*4; _ldash=PI_LineDotted; 
+      break;
+    case PI_DashDottedLine : 
+      _lwidth = 2*8; _ldash=PI_LineDashDotted; 
+      break;
+    case PI_ThinDashDottedLine : 
+      _lwidth = 8; _ldash=PI_LineDashDotted; 
+      break;
+    case PI_ThickDashDottedLine : 
+      _lwidth = 8*4; _ldash=PI_LineDashDotted; 
+      break;
+    default :
+      _lwidth = 0; _ldash=PI_LineSolid; 
+      break;
+    
+  }
+}
+
+//++
+// Titre	Opérateurs 
+//--
+
+//++
+// PILineAtt& operator = (PILineAtt const& b)
+//	Opérateur d'affectation à partir d'un PILineAtt.
+// PILineAtt& operator = (PILineTypes ltyp)
+//	Opérateur d'affectation à partir d'un PILineTypes.
+// bool operator == (PILineAtt const& b) const
+//	Opérateur test d'égalité avec un PILineAtt
+// bool operator == (PILineTypes ltyp)
+//	Opérateur test d'égalité avec un PILineTypes
+// bool operator != (PILineAtt const& b) const
+//	Opérateur test d'inégalité avec un PILineAtt
+// bool operator != (PILineTypes ltyp)
+//	Opérateur test d'inégalité avec un PILineTypes
+//--
+
+//++
+// Titre	Méthodes
+//--
+
+//++
+// int GetLineWidth() const
+//	Retourne l'épaisseur de ligne (en pixels).
+// int GetLineWidthx8() const
+//	Retourne l'épaisseur de ligne (en 1/8 pixels ou points).
+// double GetLineWidthD() const
+//	Retourne l'épaisseur de ligne (valeur flottante en pixels/points).
+// PILineDash GetLineDash()
+//	Retourne le type de ligne pointillé
+// PILineJoin GetLineJoin()
+//	Retourne le type de jointure de lignes
+// PILineCap  GetLineCap()
+//	Retourne le type de terminaison de lignes
+// void SetLineWidth(int lw)
+//	Définit l'épaisseur de ligne (en pixels/points).
+// void SetLineWidth(double lw)
+//	Définit l'épaisseur de ligne (valeur flottante en pixels/points).
+// void SetLineDash(PILineDash ld)
+//	Définit le type de ligne pointillé - enum PILineDash :
+//|	PI_LineSolid, PI_LineDashed
+//|	PI_LineDotted, PI_LineDashDotted
+//
+// void SetLineJoin(PILineJoin lj)
+//	Définit le type jointure de lignes - enum  PILineJoin :
+//|	PI_JoinMiter, PI_JoinRound, PI_JoinBevel
+// void SetLineCap(PILineCap lc) 
+//	Définit le type terminaison de lignes - enum  PILineCap :
+//|	PI_CapButt, PI_CapRound, PI_CapProjecting
+//--
Index: /tags/V_Dec2002/SophyaPI/PI/pilineatt.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pilineatt.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pilineatt.h	(revision 2309)
@@ -0,0 +1,74 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive     PILineAtt 
+// Gestionnaire d'attributs de ligne   R. Ansari  2002
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PILINEATT_H_SEEN
+#define PILINEATT_H_SEEN
+
+#include "pisysdep.h"
+
+
+// Line drawing attributes
+enum PILineJoin { PI_JoinMiter=0, PI_JoinRound=1, PI_JoinBevel=2};
+enum PILineCap  { PI_CapButt=0, PI_CapRound=1, PI_CapProjecting=2};
+enum PILineDash { PI_LineSolid, PI_LineDashed, PI_LineDotted, 
+		  PI_LineDashDotted};
+// Predefined line types
+enum PILineTypes { PI_NotDefLineAtt,
+		   PI_NormalLine, PI_ThinLine, PI_ThickLine,
+		   PI_DashedLine, PI_ThinDashedLine, PI_ThickDashedLine,
+		   PI_DottedLine, PI_ThinDottedLine, PI_ThickDottedLine,
+                   PI_DashDottedLine, PI_ThinDashDottedLine, PI_ThickDashDottedLine};
+
+
+// Classe pour gerer les attributs de lignes
+class PILineAtt {
+public:
+  explicit inline PILineAtt(int width=1, PILineDash dash=PI_LineSolid, 
+			    PILineJoin join=PI_JoinMiter, PILineCap cap=PI_CapButt)
+  {_lwidth = (width>0)?width*8:8; _ldash=dash; _ljoincap=join+cap*256; }
+  explicit inline PILineAtt(double width, PILineDash dash=PI_LineSolid, 
+			    PILineJoin join=PI_JoinMiter, PILineCap cap=PI_CapButt)
+  { _lwidth = (width>0)?(unsigned short)(width*8.):8; _ldash=dash; _ljoincap=join+cap*256; } 
+  inline PILineAtt(PILineAtt const& b)
+  { _lwidth=b._lwidth; _ldash=b._ldash; _ljoincap=b._ljoincap; }
+ 
+  PILineAtt(PILineTypes ltyp);
+
+  inline ~PILineAtt() {}
+
+  inline PILineAtt& operator = (PILineAtt const& b)
+  { _lwidth=b._lwidth; _ldash=b._ldash; _ljoincap=b._ljoincap; return(*this); }  
+  inline PILineAtt& operator = (PILineTypes ltyp)
+  { *this=PILineAtt(ltyp);  return(*this); }
+   
+  inline bool operator == (PILineAtt const& b) const
+  { return ((_lwidth==b._lwidth)&&(_ldash==b._ldash)&&(_ljoincap==b._ljoincap)); }
+  inline bool operator == (PILineTypes ltyp) const
+  { return ((*this) == PILineAtt(ltyp)); }
+  inline bool operator != (PILineAtt const& b) const
+  { return ((_lwidth!=b._lwidth)||(_ldash!=b._ldash)||(_ljoincap!=b._ljoincap)); }
+  inline bool operator != (PILineTypes ltyp) const
+  { return ((*this) != PILineAtt(ltyp)); }
+
+  inline int GetLineWidth() const { return ((_lwidth>0)?_lwidth/8:1); }
+  inline int GetLineWidthx8() const { return (_lwidth); }
+  inline double GetLineWidthD() const { return ((_lwidth>0)?(double)_lwidth/8.:1.); }
+  inline PILineDash GetLineDash() const { return _ldash; }
+  inline PILineJoin GetLineJoin() const { return (PILineJoin)(_ljoincap%256); }
+  inline PILineCap  GetLineCap() const { return (PILineCap)(_ljoincap/256); }
+
+  inline void SetLineWidth(int lw) { _lwidth = lw*8; }
+  inline void SetLineWidth(double lw) { _lwidth = (unsigned short)(lw*8.); }
+  inline void SetLineDash(PILineDash ld)  { _ldash = ld; }
+  inline void SetLineJoin(PILineJoin lj)  { _ljoincap = lj+(_ljoincap&0xFF00); }
+  inline void SetLineCap(PILineCap lc)  { _ljoincap = lc*256+(_ljoincap&0x00FF); }
+
+protected:
+  unsigned short _lwidth;  // en 1/8 de pixels (ou points)
+  unsigned short _ljoincap;
+  PILineDash _ldash;  
+};
+
+#endif      // PILINEATT_H_SEEN
Index: /tags/V_Dec2002/SophyaPI/PI/pilistgen.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pilistgen.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pilistgen.cc	(revision 2309)
@@ -0,0 +1,82 @@
+// Module PI : Peida Interactive     PIList
+// Liste                                     96-97
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "pilistgen.h"
+
+//++
+// Class	PIList
+// Lib		PI
+// include	pilistgen.h
+//
+//	Composant graphique de type liste, permettant d'afficher une liste 
+//	d'éléments, qui peuvent être sélectionnés à l'aide du pointeur (souris). 
+//	"PIListGen" définit l'interface (classe virtuelle pure). Les objets 
+//	instanciés doivent être de la classe "PIList" déclarée dans le fichier
+//	entête "PILIST_H". Lors de la sélection d'un des éléments, 
+//	le message correspondant complété par "PIMsg_Select" est envoyé.
+//	Le modifier "PIMsg_ClearSel" est appliqué lorsque d'une dé-sélection.
+//--
+//++
+// Links	Parents
+// PIWdg
+//--
+
+//++
+// Titre	Constructeur
+//--
+//++
+// PIListGen(PIContainerGen* par, const char* nom, int sx=100, int sy=100, int px=0, int py=0)
+//	Création d'un objet liste (PIList). 
+//--
+
+//++
+// Titre	Ajout et suppression d'éléments
+//--
+//++
+// void  AppendItem(char* nom, PIMessage msg)
+//	Ajoute un élément à la liste.
+// void  DeleteItem(const char *item)
+//	Supprime l'élément "item" de la liste.
+// void  DeleteItemMsg(PIMessage msg)
+//	Supprime l'élément identifié par le message "msg" de la liste.
+// void  DeleteAllItems()
+//	Supprime tous les éléments
+// int	GetNbItems()
+//	Renvoie le nombre d'éléments de la liste
+// PIMessage  GetItemMsg(int n)
+//	Renvoie le message de l'élément "n"
+// string  GetItem(int n)
+//	Renvoie le texte de l'élément "n"
+//--
+//++
+// Titre	Gestion des sélections
+//--
+//++
+// void  SetMultipleSelect(bool ms=false)
+//	Active ("ms=true") ou désactive la possibilité de sélection multiple.
+// int   GetNbSelection()
+//	Renvoie le nombre d'éléments sélectionnés.
+// PIMessage  GetSelection(int num=0)
+//	Renvoie le message correspondant à la sélection numéro "n". L'ordre 
+//	dans lequel les sélections sont retournées est indéfini.
+// string   GetSelectionStr(int num=0)
+//	Renvoie la chaîne de caractères correspondant à l'élément sélectionné 
+//	numéro "n".
+// void  SelectItem(const char* item)
+//	Permet de sélectionner l'élément "item".
+// void  SelectItemMsg(PIMessage msg)
+//	Permet de sélectionner l'élément identifié par le message "msg".
+// void  ClearSelItem(const char* item)
+//	Efface la sélection pour l'élément "item".
+// void  ClearSelItemMsg(PIMessage msg)
+//	Efface la sélection pour l'élément identifié par le message "msg".
+//--
+
+PIListGen::PIListGen(PIContainerGen *par, const char *nom,
+                     int sx, int sy, int px, int py)
+: PIWdg(par, nom, sx, sy, px, py)
+{}
+
+PIListGen::~PIListGen()
+{}
Index: /tags/V_Dec2002/SophyaPI/PI/pilistgen.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pilistgen.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pilistgen.h	(revision 2309)
@@ -0,0 +1,42 @@
+#ifndef PILISTGEN_H_SEEN
+#define PILISTGEN_H_SEEN
+
+#include "pisysdep.h"
+#include PIWDG_H
+
+
+class PIListGen : public PIWdg {
+public:
+  enum {ClassId = 1110};
+
+	             PIListGen(PIContainerGen* par, const char* nom,
+                               int sx=100, int sy=100, int px=0, int py=0);
+	             ~PIListGen();
+				   
+  virtual void	     AppendItem(const char * item, PIMessage msg)=0;
+  virtual void       DeleteItem(const char *item)=0;
+  virtual void       DeleteItemMsg(PIMessage msg)=0;
+  virtual void	     DeleteAllItems()=0;
+  
+  virtual int	     GetNbItems()=0;
+  virtual PIMessage  GetItemMsg(int n)=0;
+  virtual string     GetItem(int n)=0;
+
+  virtual void       SetMultipleSelect(bool ms=false)=0;
+
+  virtual int        GetNbSelection()=0;
+  virtual PIMessage  GetSelection(int num=0)=0;
+  virtual string     GetSelectionStr(int num=0)=0;
+
+  virtual void       SelectItem(const char * item)=0;
+  virtual void       SelectItemMsg(PIMessage msg)=0;
+  virtual void       ClearSelItem(const char * item)=0;
+  virtual void       ClearSelItemMsg(PIMessage msg)=0;
+
+  virtual long       kind() {return ClassId; }
+
+protected:
+}; 
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pilistmac.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pilistmac.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pilistmac.cc	(revision 2309)
@@ -0,0 +1,92 @@
+#include<stdio.h>
+
+#include "pilistmac.h"
+
+
+
+
+/* --Methode-- */
+PIListMac::PIListMac(PIContainerGen* par, char* nom,
+                 int sx, int sy, int px, int py)
+: PIListGen(par, nom, sx, sy, px, py)
+{
+  delete mPane;
+  mPane = mPIPPList = new PIPPList(mPaneInfo, mViewInfo, this);
+  Manage();
+}
+
+/* --Methode-- */
+PIListMac::~PIListMac()
+{
+}
+
+
+/* --Methode-- */
+void PIListMac::AppendItem(const char * item, PIMessage msg)
+{
+  mPIPPList->AppendItem(item, msg);
+}
+
+/* --Methode-- */
+void PIListMac::DeleteItem(const char * item)
+{
+  mPIPPList->DeleteItem(item);
+}
+
+/* --Methode-- */
+void PIListMac::DeleteItemMsg(PIMessage msg)
+{
+  mPIPPList->DeleteItem(msg);
+}
+
+
+/* --Methode-- */
+void PIListMac::SetMultipleSelect(bool ms)
+{
+  mPIPPList->SetMultipleSelect(ms);
+}
+
+/* --Methode-- */
+int PIListMac::GetNbSelection()
+{
+  return mPIPPList->GetNbSel();
+}
+
+/* --Methode-- */
+PIMessage PIListMac::GetSelection(int num)
+{
+  return mPIPPList->GetSelMsg(num);
+}
+
+/* --Methode-- */
+string PIListMac::GetSelectionStr(int num)
+{
+  return mPIPPList->GetSelStr(num);
+}
+
+/* --Methode-- */
+void PIListMac::SelectItem(const char * item)
+{
+  mPIPPList->SelectItem(item);
+}
+
+/* --Methode-- */
+void PIListMac::SelectItemMsg(PIMessage msg)
+{
+  mPIPPList->SelectItem(msg);
+}
+
+
+/* --Methode-- */
+void PIListMac::ClearSelItem(const char * item)
+{
+  mPIPPList->ClearSelItem(item);
+}
+
+/* --Methode-- */
+void PIListMac::ClearSelItemMsg(PIMessage msg)
+{
+  mPIPPList->ClearSelItem(msg);
+}
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/pilistmac.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pilistmac.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pilistmac.h	(revision 2309)
@@ -0,0 +1,40 @@
+#ifndef PILISTMAC_H_SEEN
+#define PILISTMAC_H_SEEN
+
+#include "pilistgen.h"
+#include "pipplist.h"
+
+class PIListMac : public PIListGen {
+public:
+	             PIListMac(PIContainerGen* par, char* nom,
+                             int sx=100, int sy=100, int px=0, int py=0);
+	             ~PIListMac();
+				   
+  virtual void	     AppendItem(const char * item, PIMessage msg);
+  virtual void       DeleteItem(const char *item);
+  virtual void       DeleteItemMsg(PIMessage msg);
+  virtual void	     DeleteAllItems();
+
+  virtual int	       GetNbItems();
+  virtual PIMessage  GetItemMsg(int n);
+  virtual string     GetItem(int n);
+
+  virtual void       SetMultipleSelect(bool ms=false);
+
+  virtual int        GetNbSelection();
+  virtual PIMessage  GetSelection(int num=0);
+  virtual string     GetSelectionStr(int num=0);
+
+  virtual void       SelectItem(const char * item);
+  virtual void       SelectItemMsg(PIMessage msg);
+  virtual void       ClearSelItem(const char * item);
+  virtual void       ClearSelItemMsg(PIMessage msg);
+
+
+protected:
+  PIPPList* mPIPPList;
+};
+
+typedef PIListMac        PIList;
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pilistx.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pilistx.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pilistx.cc	(revision 2309)
@@ -0,0 +1,422 @@
+#include<stdio.h>
+
+#include "pilistx.h"
+#include "picontainerx.h"
+
+#include <Xm/Xm.h>
+#include <Xm/List.h>
+
+
+/************* PIListX ************/
+
+// Pour ces sal... de XmString  (ds piwdgx.cc)
+int CStrFrXmStr(XmString xms, char* buff, int nmx);
+
+// Fonction prive (CallBack)
+static void list_action(Widget w, XtPointer *usd, XmListCallbackStruct *isel);
+
+/* Nouvelle-Fonction */
+void  list_action(Widget /*w*/, XtPointer *usd, XmListCallbackStruct *isel)
+{
+PIListX *pil;
+
+pil = (PIListX *)usd ;
+//  printf("list_action/Debug: reason=%d itemPos= %d \n", 
+//          isel->reason, isel->item_position);
+pil->ToggleSel(isel->item_position-1, true);
+return;
+}
+
+
+#define NBITEMB  20
+#define NBISELB  5
+
+
+/* --Methode-- */
+PIListX::PIListX(PIContainerGen* par, const char* nom,
+                 int sx, int sy, int px, int py)
+: PIListGen(par, nom, sx, sy, px, py)
+{
+
+mNItem = mNItemMax = 0;
+mMess = NULL;  mSel = NULL;
+mNbSel = mNSelMax = 0;
+mSelNum = NULL;
+ 
+Arg  warg[7];
+int n = 0;
+XtSetArg(warg[n], XmNlistSizePolicy, XmCONSTANT);  n++;
+XtSetArg(warg[n], XmNscrollBarDisplayPolicy, XmAS_NEEDED);  n++;
+// **ATTENTION** Il vaut mieux creer avec les bonnes tailles au depart Reza 09/99 
+//     .....   C'est fait par CreateXtWdg( ... )
+XtSetArg(warg[n],XmNwidth,sx);  n++;
+XtSetArg(warg[n],XmNheight,sy);  n++;
+XtSetArg(warg[n],XmNx,px);  n++;
+XtSetArg(warg[n],XmNy,py);  n++;
+mlist = XmCreateScrolledList(((PIWdgX *)par)->XtWdg(), (char *)nom, warg, n);  // const_cast
+XtManageChild(mlist);
+XtWdg() = XtParent(mlist);
+wmis = k_wmi_normal ;
+stmng = 0;
+
+// **ATTENTION** A ne pas oublier , fait par CreateXtWdg Reza 09/99 
+SetBinding(PIBK_free, PIBK_free, PIBK_free, PIBK_free);
+par->ChildAdd(this);
+
+//XtAddCallback(mlist, XmNdefaultActionCallback,
+//              list_action, (XtPointer)this);
+XtAddCallback(mlist, XmNmultipleSelectionCallback,
+              (XtCallbackProc)list_action, (XtPointer)this);
+XtAddCallback(mlist, XmNsingleSelectionCallback,
+              (XtCallbackProc)list_action, (XtPointer)this);
+
+SetMultipleSelect(false);
+Manage();
+}
+
+/* --Methode-- */
+PIListX::~PIListX()
+{
+
+if (mNItemMax > 0)  
+  {
+    //  XtFree((char *)mItems);
+  delete[] mMess;
+  delete[] mSel;
+  }  
+if (mNSelMax > 0)  delete[] mSelNum;
+}
+
+
+/* --Methode-- */
+void PIListX::AppendItem(const char * item, PIMessage msg)
+{
+
+if (mNItem >= mNItemMax)
+  {
+  PIMessage *mso;
+  bool *slo;
+  int i;
+
+  mso = mMess;
+  slo = mSel;
+  mNItemMax += NBITEMB;
+  mMess = new PIMessage[mNItemMax];
+  mSel = new bool[mNItemMax];
+  for(i=0; i<mNItem; i++)   
+    {  mMess[i] = mso[i];  mSel[i] = slo[i]; }
+
+  delete[] mso;
+  delete[] slo;
+  }
+
+mMess[mNItem] = msg;
+mSel[mNItem] = false;
+mNItem++;
+
+#if defined(__DECCXX) || defined(__KCC__) || defined(__aCC__)
+XmString xms = XmStringCreate(const_cast<char *>(item), XmSTRING_DEFAULT_CHARSET);
+#else
+XmString xms = XmStringCreate((char *)(item), XmSTRING_DEFAULT_CHARSET);
+#endif
+XmListAddItem(mlist, xms, 0);
+XmStringFree(xms);
+return;
+}
+
+/* --Methode-- */
+void PIListX::DeleteItem(const char * item)
+{
+int n;
+if ((n=GetNumItem(item)) < 0)  return;
+DelItem(n);
+return;
+}
+
+/* --Methode-- */
+void PIListX::DeleteItemMsg(PIMessage msg)
+{
+int n;
+if ((n=GetNumItemMsg(msg)) < 0)  return;
+DelItem(n);
+return;
+}
+
+/* --Methode-- */
+void PIListX::DeleteAllItems()
+{
+int nmax = mNItem;
+bool mng = IfManaged();
+if (mng) UnManage();
+for(int i=0; i<nmax; i++) DelItem(0);
+if (mng) Manage();
+}
+
+/* --Methode-- */
+int PIListX::GetNbItems()
+{
+return(mNItem);
+}
+
+/* --Methode-- */
+PIMessage PIListX::GetItemMsg(int n)
+{
+return(ItemMsg(n));
+}
+
+/* --Methode-- */
+string PIListX::GetItem(int n)
+{
+return(ItemStr(n));
+}
+
+/* --Methode-- */
+void PIListX::SetMultipleSelect(bool ms)
+{
+Arg  warg[2];
+
+mMultSel = ms;
+if (ms)
+  XtSetArg(warg[0], XmNselectionPolicy, XmMULTIPLE_SELECT);  
+else
+  XtSetArg(warg[0], XmNselectionPolicy, XmSINGLE_SELECT);  
+
+XtSetValues(mlist, warg, 1);
+}
+
+/* --Methode-- */
+int PIListX::GetNbSelection()
+{
+return(mNbSel);
+}
+
+/* --Methode-- */
+PIMessage PIListX::GetSelection(int num)
+{
+if ( (num < 0) || (num >= mNbSel) ) return(0); 
+return(ItemMsg(mSelNum[num]));
+}
+
+/* --Methode-- */
+string PIListX::GetSelectionStr(int num)
+{
+if ( (num < 0) || (num >= mNbSel) ) return(""); 
+string s(ItemStr(mSelNum[num]));
+return(s);
+}
+
+/* --Methode-- */
+void PIListX::SelectItem(const char * item)
+{
+int n;
+if ((n=GetNumItem(item)) < 0)  return;
+if ((!mMultSel) && (mNbSel > 0))
+  if  (mSelNum[0] != n)  ClrSItem(mSelNum[0], false, true);  
+SelItem(n, false, true);
+return;
+}
+
+/* --Methode-- */
+void PIListX::SelectItemMsg(PIMessage msg)
+{
+int n;
+if ((n=GetNumItemMsg(msg)) < 0)  return;
+if ((!mMultSel) && (mNbSel > 0))
+  if  (mSelNum[0] != n)  ClrSItem(mSelNum[0], false, true);  
+SelItem(n, false, true);
+return;
+}
+
+
+/* --Methode-- */
+void PIListX::ClearSelItem(const char * item)
+{
+int n;
+if ((n=GetNumItem(item)) < 0)  return;
+ClrSItem(n, false, true);
+return;
+}
+
+/* --Methode-- */
+void PIListX::ClearSelItemMsg(PIMessage msg)
+{
+int n;
+if ((n=GetNumItemMsg(msg)) < 0)  return;
+ClrSItem(n, false, true);
+return;
+}
+
+
+/* --Methode-- */
+void PIListX::ToggleSel(int n, bool smg)
+{
+if ( (n < 0) || (n >= mNItem))  return;
+if (mSel[n])  ClrSItem(n,smg); 
+else
+  {
+  if ((!mMultSel) && (mNbSel > 0))  ClrSItem(mSelNum[0], smg);
+  SelItem(n, smg);
+  }
+}
+
+
+/* --Methode-- */
+PIMessage PIListX::ItemMsg(int n)
+{
+if ( (n < 0) || (n >= mNItem))  return(0);
+else return(mMess[n]);
+}
+
+/* --Methode-- */
+char * PIListX::ItemStr(int n)
+{
+Arg  warg[2];
+XmString *xmst=NULL;
+
+if ( (n < 0) || (n >= mNItem))  { mSItem[0] = '\0'; return(mSItem); }
+mSItem[0] = '\0';
+XtSetArg(warg[0], XmNitems, &xmst);  
+XtGetValues(mlist, warg, 1);
+CStrFrXmStr(xmst[n], mSItem, 320);
+return(mSItem);
+}
+
+/* --Methode-- */
+int PIListX::GetNumItem(const char *it)
+{
+for(int i=0; i<mNItem; i++)
+  if (strcmp(ItemStr(i), it) == 0)  return(i);
+return(-1);
+}
+
+/* --Methode-- */
+int PIListX::GetNumItemMsg(PIMessage msg)
+{
+for(int i=0; i<mNItem; i++)
+  if (mMess[i] == msg)   return(i);  
+return(-1);
+}
+
+
+
+/* --Methode-- */
+void PIListX::DelItem(int n)
+{
+int i;
+
+if ((n < 0) || (n > mNItem))  return;
+
+ClrSItem(n);
+for(i=n; i<mNItem-1; i++)
+  { mMess[i] = mMess[i+1];  mSel[i] = mSel[i+1]; }
+mNItem--;
+
+if (mNItem < (mNItemMax-NBITEMB-1))
+  {
+    //  XmString *ito;
+  PIMessage *mso;
+  bool *slo;
+
+  //  ito = mItems;
+  mso = mMess;
+  slo = mSel;
+  mNItemMax -= NBITEMB;
+  mMess = new PIMessage[mNItemMax];
+  mSel = new bool[mNItemMax];
+  //  mItems = (XmString *) XtMalloc(sizeof(XmString)*mNItemMax);
+  for(i=0; i<mNItem; i++)   
+    { // mItems[i] = ito[i];
+    mMess[i] = mso[i];  mSel[i] = slo[i]; }
+
+  //  XtFree((char *)mItems);
+  delete[] mso;
+  delete[] slo;
+  }
+
+XmListDeletePos(mlist, n+1);
+return;
+}
+
+
+/* --Methode-- */
+bool PIListX::SelItem(int n, bool smg, bool cxw)
+{
+int i;
+
+if ((n < 0) || (n > mNItem))  return(false);
+if (mSel[n])  return(false);
+
+mSel[n] = true;
+if (mNbSel >= mNSelMax)
+  {
+  int * osel;
+  osel = mSelNum;
+  mNSelMax += NBISELB;
+  mSelNum = new int[mNSelMax];
+  for(i=0; i<mNbSel; i++)  mSelNum[i] = osel[i];
+  if (osel)  delete[] osel;
+  }
+
+mSelNum[mNbSel] = n; 
+mNbSel++;
+if (smg)  
+  Send(mMess[n], PIMsg_Select); 
+if (cxw)
+  XmListSelectPos(mlist, n+1, FALSE);
+return(true);
+}
+
+
+
+
+/* --Methode-- */
+bool PIListX::ClrSItem(int n, bool smg, bool cxw)
+{
+int i;
+if ((n < 0) || (n > mNItem))  return(false);
+if (!mSel[n])  return(false);
+mSel[n] = false;
+
+mNbSel --;
+if (smg)  
+  Send(mMess[n], PIMsg_ClearSel); 
+if (cxw)
+  XmListDeselectPos(mlist, n+1);
+
+if (mSelNum) delete[] mSelNum;
+if (mNbSel <= 0)
+  { mNSelMax = mNbSel = 0;  mSelNum = NULL; }
+else
+  {
+  mNSelMax = (mNbSel+NBISELB)/NBISELB;
+  mSelNum = new int[mNSelMax];
+  mNbSel =  0;
+  for(i=0; i<mNItem; i++)
+    if (mSel[i]) { mSelNum[mNbSel] = i; mNbSel++; }
+  }
+
+return(true);
+} 
+
+
+/* --Methode-- 
+    A Supprimer .....
+void PIListX::ChangeSel()
+{
+XmString *xmst;
+int n;
+
+n=0;
+XtSetArg(warg[n], XmNselectedItems, &xmst);  n++;
+XtGetValues(mlist, warg, n);
+if (xmst)  XtFree(xmst);
+xmst =  (XmString *) XtMalloc(sizeof(XmString)*mNbSel);
+for(i=0; i<mNbSel; i++)
+  xmst[i] = mItems[mSelNum[i]];
+n=0;
+XtSetArg(warg[n], XmNselectedItems, xmst);  n++;
+XtSetArg(warg[n], XmNselectedItemCount, mNbSel);  n++;
+XtSetValues(mlist, warg, n);
+return;
+}
+   .....  */
Index: /tags/V_Dec2002/SophyaPI/PI/pilistx.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pilistx.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pilistx.h	(revision 2309)
@@ -0,0 +1,57 @@
+#ifndef PILISTX_H_SEEN
+#define PILISTX_H_SEEN
+
+#include "pilistgen.h"
+
+class PIListX : public PIListGen {
+public:
+	             PIListX(PIContainerGen* par, const char* nom,
+                             int sx=100, int sy=100, int px=0, int py=0);
+	             ~PIListX();
+				   
+  virtual void	     AppendItem(const char * item, PIMessage msg);
+  virtual void       DeleteItem(const char *item);
+  virtual void       DeleteItemMsg(PIMessage msg);
+  virtual void	     DeleteAllItems();
+
+  virtual int	     GetNbItems();
+  virtual PIMessage  GetItemMsg(int n);
+  virtual string     GetItem(int n);
+
+  virtual void       SetMultipleSelect(bool ms=false);
+
+  virtual int        GetNbSelection();
+  virtual PIMessage  GetSelection(int num=0);
+  virtual string     GetSelectionStr(int num=0);
+
+  virtual void       SelectItem(const char * item);
+  virtual void       SelectItemMsg(PIMessage msg);
+  virtual void       ClearSelItem(const char * item);
+  virtual void       ClearSelItemMsg(PIMessage msg);
+
+// Mis en public pour Callback Xt
+  virtual void       ToggleSel(int n, bool smg=false);
+
+protected:
+  PIMessage          ItemMsg(int n);
+  char *             ItemStr(int n);
+  int                GetNumItem(const char * nom);
+  int                GetNumItemMsg(PIMessage msg);
+  void               DelItem(int n);
+  bool               SelItem(int n, bool smg=false, bool cxw=false);
+  bool               ClrSItem(int n, bool smg=false, bool cxw=false);
+
+int mNItem, mNItemMax;
+PIMessage * mMess;
+bool * mSel;
+int mNbSel, mNSelMax;
+int * mSelNum;
+bool mMultSel;
+char mSItem[320];
+
+SysDWdg mlist;
+};
+
+typedef PIListX        PIList;
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pimak
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pimak	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pimak	(revision 2309)
@@ -0,0 +1,143 @@
+CC := gcc
+CXX := g++
+# General setup GNU Makefile for EROS. To be included in all makefiles.  
+# Define  makefile variables according to CPU
+# MACHEROSD = `uname | sed 's/-//'`   i.e. { AIX HPUX OSF1 ULTRIX }
+# 
+# Makefile variables set are:
+# - Path to Exec, Include, Libs, Objs directories (from EROSBASEREP env. var.)
+#     i.e. variables LIB, OBJ, EXE, INC 
+#---------------------------------------------------------------------------
+
+# define MACHEROS from uname
+MACHEROS := $(shell echo `uname`)
+# define the -D option
+MACHEROSD := $(shell echo `uname | sed 's/-//'`)
+
+#-
+#-     Optimization option different for HP...
+ifeq (${MACHEROS},HP-UX)
+  O := +O
+else
+  O := -O
+endif
+#-
+#-   Define Makefile paths
+#-  
+ PP  := ${EROSBASEREP}/${MACHEROS}/
+ LIB := ${PP}/Libs/
+ SLB := ${PP}/ShLibs/
+ OBJ := ${PP}/Objs/
+ EXE := ${PP}/Exec/
+ INC := ${EROSBASEREP}/Include/
+ CCI := ${INC}/CInc/
+ CXI := ${INC}/CxxInc/
+#--
+
+#-
+#-    Define default compilation flags
+#--
+ifeq (${MACHEROS},HP-UX)                                    
+  CFLAGS   :=  -Aa
+  FFLAGS   :=  -Aa -I${INC} -D${MACHEROSD}  
+  CPPFLAGS :=  -I${INC} -D${MACHEROSD} \
+               -D_INCLUDE_POSIX_SOURCE -D_INCLUDE_XOPEN_SOURCE
+else
+  FFLAGS   :=  -I${INC} -D${MACHEROSD}  
+  CPPFLAGS :=  -I${INC} -D${MACHEROSD}
+endif
+AR       := ar
+ARFLAGS  := -rcs
+
+ifeq ($(CC), gcc)
+CFLAGS       := -g -O -Wall -Wpointer-arith \
+                -Wmissing-prototypes -Wsynth -I$(INC)
+//CXXFLAGS     := $(CFLAGS) -fno-implicit-templates -I$(CXI)
+CXXFLAGS     := $(CFLAGS) -I$(CXI)
+endif
+
+#- redefine implicit rule. Les .o sont dans $(OBJ).
+$(OBJ)%.o:%.c
+	$(COMPILE.c) -o $@ $<
+
+$(OBJ)%.o:%.cc
+	$(COMPILE.cc) -o $@ $<
+
+$(OBJ)%.o:%.f
+	$(COMPILE.f) -o $@ $< 
+
+#OSF1
+#LDFC est f77
+#LDFCFLAGS est rien
+
+#parfois
+#LDFC est cc
+#LDFCFLAGS est -ltruc
+
+#------------------------------------------------- End of Makefile.h ------- 
+all : piapp piapp_nosh
+
+piapp : $(EXE)piapp $(SLB)piup.so 
+ 
+piapp_nosh : $(EXE)piapp_nosh
+ 
+
+$(EXE)piapp  : $(OBJ)pidemo.o $(SLB)libPI.so $(SLB)libOuIm.so \
+               $(SLB)liberosc.so $(SLB)libStarReco.so 
+	cc -call_shared -o $(EXE)piapp $(OBJ)pidemo.o \
+              -L$(SLB) -lPI -lOuIm -lerosc -lStarReco \
+              -lgcxx -lXm -lXt -lX11 -lm  
+
+$(EXE)piapp_nosh  : $(OBJ)pidemo_nosh.o $(LIB)libPI.a $(LIB)libStarReco.a  \
+               $(LIB)libOutils.a $(LIB)libImages.a $(LIB)libmath.a $(LIB)libdiv.a 
+	g++ -o $(EXE)piapp_nosh $(OBJ)pidemo_nosh.o \
+              -L$(LIB) -lPI -lStarReco -lImages -lOutils -lmath -ldiv \
+              -lXm -lXt -lX11 -lm 
+ 
+$(SLB)piup.so : $(OBJ)piup_def.o \
+                $(SLB)libOuIm.so $(SLB)liberosc.so 
+	ld -shared -o $(SLB)piup.so -all $(OBJ)piup_def.o \
+        -none -L$(SLB) -lOuIm -lerosc -lgcxx -lm -lc
+
+$(OBJ)pidemo_nosh.o: pidemo.cc pidemo.h
+	g++ -g -O -c -Wall -Wpointer-arith \
+            -Wmissing-prototypes -Wsynth -I$(INC) -I$(CXI) \
+            -D C_NO_SHLIBS -o $(OBJ)pidemo_nosh.o pidemo.cc
+
+$(OBJ)pidemo.o: ./pidemo.cc \
+ $(INC)perrors.h \
+ $(INC)exceptions.h \
+ $(INC)defs.h \
+ $(INC)fitsimage.h \
+ $(INC)cimage.h \
+ $(INC)rzimage.h \
+ $(INC)rzvect.h \
+ $(INC)machine.h \
+ $(INC)datatypes.h \
+ $(INC)fitsheader.h \
+ $(INC)fitskeys.h pidemo.h \
+ pisysdep.h piapplx.h piapplgen.h pimsghandler.h picontainerx.h \
+ picontainergen.h piwdgx.h piwdggen.h pimenubarx.h pimenubargen.h \
+ pimenux.h pimenugen.h piwindowx.h piwindowgen.h pioptmenux.h \
+ pioptmenugen.h pistdwdgx.h pistdwdggen.h pifilechox.h pifilechogen.h \
+ piimage.h $(INC)lut.h \
+ pipixmapx.h pipixmapgen.h pibwdgx.h pibwdggen.h picmap.h picmapx.h \
+ picmapgen.h pihisto.h piscdrawwdg.h \
+ $(INC)histos.h \
+ $(INC)peida.h \
+ $(INC)utils.h pidrawwin.h \
+ $(INC)piup.h
+$(OBJ)piup_def.o: piup_def.cc  piup.h \
+ $(INC)perrors.h \
+ $(INC)exceptions.h \
+ $(INC)defs.h \
+ $(INC)fitsimage.h \
+ $(INC)cimage.h \
+ $(INC)rzimage.h \
+ $(INC)rzvect.h \
+ $(INC)machine.h \
+ $(INC)datatypes.h \
+ $(INC)fitsheader.h \
+ $(INC)fitskeys.h \
+ $(INC)utils.h $(INC)peida.h 
+
Index: /tags/V_Dec2002/SophyaPI/PI/pimenubargen.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pimenubargen.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pimenubargen.cc	(revision 2309)
@@ -0,0 +1,54 @@
+// Module PI : Peida Interactive     PIMenubar
+// Barre de menu                        96-97
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "pimenubargen.h"
+
+#include PIAPP_H
+
+//++
+// Class	PIMenubar
+// Lib		PI
+// include	pimenubargen.h
+//
+//	Composant graphique de type Barre des menus . 
+//	"PIMenubarGen" définit l'interface (classe virtuelle pure). Les objets 
+//	instanciés doivent être de la classe "PIMenubar" déclarée dans le fichier
+//	entête "PIMENUBAR_H". 
+//--
+//++
+// Links	Parents
+// PIWdg
+//--
+//++
+// Links	Voir aussi
+// PIMenu
+//--
+
+//++
+// Titre	Constructeur, méthodes
+//--
+//++
+// PIMenubar(PIApplicationGen* par, const char* nom)
+//	Création d'un objet Menubar.
+// void  AppendMenu(PIMenu* pdm)
+//	Rajoute un menu à la barre de menu. Le menu sera affiché avec un titre identique à son nom.
+// void  RemoveMenu(PIMenu* pdm)
+//	Supprime le menu "pdm" de la barre de menu, sans le détruire (delete).
+// void  SetSensitivity(PIMenu* pdm, bool sens=true)
+//	Permet de rendre sensible ("sens=true") ou insensible un menu. Le titre d'un menu
+//	insensible est affiché, mais ne peut être séléctionné.
+// bool  IsSensitive(PIMenu* pdm)
+//	Indique si le menu "pdm" est sensible ou pas.
+//--
+
+PIMenubarGen::PIMenubarGen(PIApplicationGen* par, const char* nom)
+: PIWdg(NULL, nom)
+{
+SetMsgParent(par);
+}
+
+PIMenubarGen::~PIMenubarGen()
+{}
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/pimenubargen.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pimenubargen.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pimenubargen.h	(revision 2309)
@@ -0,0 +1,24 @@
+#ifndef PIMBARGEN_H_SEEN
+#define PIMBARGEN_H_SEEN
+
+#include "pisysdep.h"
+#include PIMENU_H
+
+class PIApplicationGen;
+
+class PIMenubarGen : public PIWdg {
+public:
+  enum {ClassId = 2600};
+
+	            PIMenubarGen(PIApplicationGen* par, const char* nom);
+	            ~PIMenubarGen();
+				   
+  virtual void      AppendMenu(PIMenu *pdm)=0;
+  virtual void      RemoveMenu(PIMenu *pdm)=0;
+  virtual void      SetSensitivity(PIMenu *pdm, bool sens=true)=0;
+  virtual bool      IsSensitive(PIMenu *pdm)=0;
+
+  virtual long      kind() {return ClassId; }
+};
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pimenubarmac.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pimenubarmac.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pimenubarmac.cc	(revision 2309)
@@ -0,0 +1,36 @@
+#include "pimenubarmac.h"
+#include "pippmenubar.h"
+#include <LMenuBar.h>
+
+PIMenubarMac::PIMenubarMac(PIApplicationGen* par, char* nom)
+:PIMenubarGen(par, nom)
+{
+	new PIPPMenuBar();
+}
+
+PIMenubarMac::~PIMenubarMac()
+{}
+
+void
+PIMenubarMac::AppendMenu(PIMenu *pdm)
+{
+  LMenuBar::GetCurrentMenuBar()->InstallMenu(pdm->macMenu, InstallMenu_AtEnd);
+}
+
+void
+PIMenubarMac::RemoveMenu(PIMenu *pdm)
+{
+  LMenuBar::GetCurrentMenuBar()->RemoveMenu(pdm->macMenu);
+}
+
+void
+PIMenubarMac::SetSensitivity(PIMenu *pdm, bool sens)
+{
+
+}
+
+bool
+PIMenubarMac::IsSensitive(PIMenu *pdm)
+{
+  return true;
+}
Index: /tags/V_Dec2002/SophyaPI/PI/pimenubarmac.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pimenubarmac.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pimenubarmac.h	(revision 2309)
@@ -0,0 +1,20 @@
+#ifndef PIMBARMAC_H_SEEN
+#define PIMBARMAC_H_SEEN
+
+#include "pimenubargen.h"
+
+class PIMenubarMac : public PIMenubarGen {
+ public:
+	            PIMenubarMac(PIApplicationGen* par, char* nom);
+	           ~PIMenubarMac();
+	           
+  virtual void      AppendMenu(PIMenu *pdm);
+  virtual void      RemoveMenu(PIMenu *pdm);
+  virtual void      SetSensitivity(PIMenu *pdm, bool sens=true);
+  virtual bool      IsSensitive(PIMenu *pdm);
+
+};
+
+typedef PIMenubarMac   PIMenubar;
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pimenubarx.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pimenubarx.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pimenubarx.cc	(revision 2309)
@@ -0,0 +1,112 @@
+#include<stdio.h>
+
+#include "pimenubarx.h"
+#include PIAPP_H
+
+#include <Xm/Xm.h>
+#include <Xm/RowColumn.h>
+#include <Xm/PushB.h>
+#include <Xm/ToggleB.h>
+#include <Xm/CascadeB.h>
+
+/************* PIMenubarX ************/
+
+#define NBITEMB  10
+
+/* --Methode-- */
+PIMenubarX::PIMenubarX(PIApplicationGen* par, const char* nom)
+: PIMenubarGen(par, nom)
+{
+mNItem = 0;  mNItemMax = NBITEMB; 
+mMbb = new _pimbxit_[mNItemMax];
+
+Arg warg[3];
+int n = 0;
+
+XtSetArg(warg[n],XmNx,0);  n++;
+XtSetArg(warg[n],XmNy,0);  n++;
+
+XtWdg() = XmCreateMenuBar( ((PIApplicationX *)par)->MBCont()->XtWdg(), 
+                           (char *)nom, warg, n);   // const_cast
+
+wmis = k_wmi_normal ;
+stmng = 0;
+
+// SetPos(0,0);
+SetBinding(PIBK_fixed, PIBK_fixed, PIBK_fixed, PIBK_free);
+((PIApplicationX *)par)->MBCont()->ChildAdd(this);
+
+Manage();
+}
+
+
+/* --Methode-- */
+PIMenubarX::~PIMenubarX()
+{
+for(int i=0; i<mNItem; i++)
+  XtDestroyWidget(mMbb[i].itb);
+delete[] mMbb ;
+}
+
+/* --Methode-- */
+void PIMenubarX::AppendMenu(PIMenu *pdm)
+{
+_pimbxit_ *buto;
+Arg  wargs[2];
+
+if (mNItem >= mNItemMax)
+  {
+  buto = mMbb;
+  mNItemMax += NBITEMB;
+  mMbb = new _pimbxit_[mNItemMax];
+  for(int i=0; i<mNItem; i++)   mMbb[i] = buto[i];
+  delete[] buto;
+  }
+XtSetArg(wargs[0], XmNsubMenuId, pdm->XtWdg());
+mMbb[mNItem].itb = XtCreateManagedWidget(pdm->Nom().c_str(), xmCascadeButtonWidgetClass, 
+                                         this->XtWdg(), wargs, 1) ;
+mMbb[mNItem].pdm = pdm;
+mNItem++;
+
+pdm->SetMsgParent(this);
+return;
+}
+
+/* --Methode-- */
+void PIMenubarX::RemoveMenu(PIMenu *pdm)
+{
+int i,j;
+for(i=0; i<mNItem; i++) 
+  if ( mMbb[i].pdm == pdm ) { 
+    XtDestroyWidget(mMbb[i].itb);
+    for(j=i; j<mNItem-1; j++) mMbb[j] = mMbb[j+1]; 
+    mNItem--;  break;  
+    }
+return;
+}
+
+/* --Methode-- */
+void PIMenubarX::SetSensitivity(PIMenu *pdm, bool sens)
+{
+int i;
+for(i=0; i<mNItem; i++) 
+  if ( mMbb[i].pdm == pdm ) { 
+    if (sens) XtSetSensitive(mMbb[i].itb, TRUE);
+    else XtSetSensitive(mMbb[i].itb, FALSE);
+    break;  
+    }
+return;
+}
+
+/* --Methode-- */
+bool PIMenubarX::IsSensitive(PIMenu *pdm)
+{
+int i;
+for(i=0; i<mNItem; i++) 
+  if ( mMbb[i].pdm == pdm ) { 
+    if (XtIsSensitive(mMbb[i].itb) == TRUE)  return(true);
+    else return(false);
+    break; 
+    }
+return(false);
+}
Index: /tags/V_Dec2002/SophyaPI/PI/pimenubarx.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pimenubarx.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pimenubarx.h	(revision 2309)
@@ -0,0 +1,32 @@
+#ifndef PIMBARX_H_SEEN
+#define PIMBARX_H_SEEN
+
+#include "pimenubargen.h"
+
+struct _pimbxit_ 
+{
+SysDWdg itb;
+PIMenu *pdm;
+};
+
+class PIMenubarX : public PIMenubarGen {
+ public:
+	            PIMenubarX(PIApplicationGen* par, const char* nom);
+	            ~PIMenubarX();
+
+  virtual void	    AppendMenu(PIMenu *pdm);
+  virtual void      RemoveMenu(PIMenu *pdm);
+  virtual void      SetSensitivity(PIMenu *pdm, bool sens=true);
+  virtual bool      IsSensitive(PIMenu *pdm);
+
+ protected:
+
+int mNItem, mNItemMax;
+_pimbxit_ *mMbb;
+};
+
+
+typedef PIMenubarX     PIMenubar;
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pimenugen.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pimenugen.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pimenugen.cc	(revision 2309)
@@ -0,0 +1,123 @@
+// Module PI : Peida Interactive     PIMenu
+// Menu                                     96-97
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "pimenugen.h"
+
+//++
+// Class	PIMenu
+// Lib		PI
+// include	pimenugen.h
+//
+//	Composant graphique de type menu. 
+//	"PIMenuGen" définit l'interface (classe virtuelle pure). Les objets 
+//	instanciés doivent être de la classe "PIMenu" déclarée dans le fichier
+//	entête "PIMENUBAR_H". Lors de la séléction d'une des options du menu
+//	Le message correspondant complété par "PIMsg_Click" est envoyé à l'objet
+//	par "SendSelf()".
+//--
+//++
+// Links	Parents
+// PIWdg
+//--
+//++
+// Links	Voir aussi
+// PIMenubar
+//--
+
+
+
+//++
+// Titre	Constructeur
+//--
+//++
+// PIMenu(PIWdg* par, const char* nom, PIMenuType pdpu=k_UTMenu)
+//	Création d'un objet Menubar. "pdpu" peut prendre les valeurs
+//	"k_UTMenu", "k_PopupMenu", "k_PulldownMenu". Un menu de type
+//	"PulldownMenu" est destiné à être accroché à un Menubar ou
+//	comme sous-menu d'un autre menu. Si l'objet parent est de type
+//	"PIMenu" ou "PIMenubar", un PulldownMenu est créé par défaut. Un 
+//	menu de type PopupMenu est créé dans les autres cas.
+// PIMenuType MType() 
+//	Renvoie le type du menu : "k_PopupMenu" ou  "k_PulldownMenu".
+//--
+
+//++
+// Titre	Ajout et suppression des options du menu
+//--
+//
+//++
+// void  AppendItem(const char* nom, PIMessage msg, char* sc=NULL)
+//	Permet d'ajouter une option au menu. Un raccourci clavier peut être spécifié
+//	par "sc".
+// void  AppendCheckItem(const char* nom, PIMessage msg, char* sc=NULL)
+//	Permet d'ajouter une option avec état ON/OFF au menu.
+// void	 AppendPDMenu(PIMenu* pdm, char* sc=NULL)
+//	Ajoute un menu déroulant comme sous-menu.
+// void  DeleteItem(const char* nom)
+//	Permet de supprimer une option du menu identifiée par le titre ("nom").
+//	Si le nom désigne un menu déroulant, celui-ci n'est pas détruit (par "delete").
+// void  DeleteItemMsg(PIMessage msg)
+//	Permet de supprimer une option du menu identifiée par le message ("msg").
+// void  DeleteItemNum(int n)
+//	Suppression de l'option numéro "n".
+//--
+//++
+// Titre	Gestion des options 
+//--
+//++
+// void  SetSensitivity(const char* nom, bool sens=true)
+//	Rend sensible ("sens=true") ou insensible l'option du menu identifiée par "nom".
+//	Une option insensible est affichée, mais ne peut être sélectionnée.
+// void  SetSensitivityMsg(PIMessage msg, bool sens=true)
+//	Rend sensible ("sens=true") ou insensible l'option du menu identifiée par le message "msg".
+// void  SetSensitivityNum(int n, bool sens=true)
+//	Rend sensible ("sens=true") ou insensible l'option numéro "n".
+// bool  IsSensitive(const char* nom)
+//	Indique si l'option "nom" est sensible ou pas.
+// bool  IsSensitiveMsg(PIMessage msg)
+//	Indique si l'option identifiée par le message "msg" est sensible ou pas.
+// bool  IsSensitiveNum(int n)
+//	Indique si l'option numéro "n" est sensible ou pas.
+//--
+//++
+// Titre	Options à état (CheckItem)
+//	Le champ "data" de "Send()/SendSelf()" contient un pointeur sur une variable
+//	de type bool, indiquant l'état (On/Off) de l'option, lors de la séléction des
+//	options à état ("CheckItem"). Les méthodes suivantes ne s'appliquent qu'aux 
+//	options de type CheckItem.
+//--
+//++
+// void  SetState(const char* nom, bool st=false)
+//	Change l'état de l'option "nom".
+// void  SetStateMsg(PIMessage msg, bool st=false)
+//	Change l'état de l'option identifiée par le message "msg".
+// void  SetStateNum(int n, bool st=false)
+//	Change l'état de l'option numéro "n".
+// bool GetState(const char* nom)
+//	Renvoie l'état de l'option "nom".
+// bool GetStateMsg(PIMessage msg)
+//	Renvoie l'état de l'option identifiée par le message "msg".
+// bool GetStateNum(int n)
+//	Renvoie l'état de l'option numéro "n".
+//--
+
+//++
+// Titre	Affichage des PopupMenu
+//--
+//++
+// void  Show()
+//	Affiche le menu (de type "k_PopupMenu" uniquement) à la position courante du pointeur.
+// void  Show(PIWdg* w, int px, int py)
+//	Affiche le menu (de type "k_PopupMenu" uniquement) à la position "px,py" de l'objet "w". 
+//--
+
+PIMenuGen::PIMenuGen(PIWdg* par, const char* nom, PIMenuType pdpu)
+: PIWdg(NULL, nom) , mMTyp(pdpu)
+{
+SetMsgParent(par);
+}
+
+PIMenuGen::~PIMenuGen()
+{}
+
Index: /tags/V_Dec2002/SophyaPI/PI/pimenugen.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pimenugen.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pimenugen.h	(revision 2309)
@@ -0,0 +1,53 @@
+#ifndef PIMENUGEN_H_SEEN
+#define PIMENUGEN_H_SEEN
+
+#include "pisysdep.h"
+#include PIWDG_H
+
+enum PIMenuType { k_UTMenu = 0, k_PopupMenu = 1, k_PulldownMenu = 2 };
+
+
+class PIMenuGen : public PIWdg {
+public:
+  enum {ClassId = 2500};
+
+	          PIMenuGen(PIWdg* par, const char* nom, PIMenuType pdpu=k_UTMenu);
+	          ~PIMenuGen();
+				   
+  virtual void	  AppendItem(const char* nom, PIMessage msg, char* sc=NULL)=0;
+  virtual void	  AppendCheckItem(const char* nom, PIMessage msg, char* sc=NULL)=0;
+  virtual void	  AppendPDMenu(PIMenuGen *pdm, char* sc=NULL)=0;
+  virtual void	  AppendSeparator()=0;
+
+  virtual void    DeleteItem(const char *nom)=0;
+  virtual void    DeleteItemMsg(PIMessage msg)=0;
+  virtual void    DeleteItemNum(int n)=0;
+
+  virtual void    SetSensitivity(const char *nom, bool sens=true)=0; 
+  virtual void    SetSensitivityMsg(PIMessage msg, bool sens=true)=0; 
+  virtual void    SetSensitivityNum(int n, bool sens=true)=0;
+
+  virtual bool    IsSensitive(const char *nom)=0;
+  virtual bool    IsSensitiveMsg(PIMessage msg)=0;
+  virtual bool    IsSensitiveNum(int n)=0;
+
+  virtual void    SetState(const char *nom, bool st=false)=0; 
+  virtual void    SetStateMsg(PIMessage msg, bool st=false)=0; 
+  virtual void    SetStateNum(int n, bool st=false)=0;
+ 
+  virtual bool    GetState(const char *nom)=0; 
+  virtual bool    GetStateMsg(PIMessage msg)=0; 
+  virtual bool    GetStateNum(int n)=0; 
+
+  virtual void    Show()=0;
+  virtual void    Show(PIWdg *w, int px, int py)=0;
+
+  virtual long    kind() {return ClassId; }
+  virtual PIMenuType MType() { return  mMTyp; }
+
+protected:
+  PIMenuType mMTyp;
+}; 
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pimenumac.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pimenumac.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pimenumac.cc	(revision 2309)
@@ -0,0 +1,215 @@
+#include <LString.h>
+#include "pimenumac.h"
+#include <algorithm>
+#include <iostream>
+
+int PIMenuMac::lastId = 1024;
+vector<PIMenuMac::menuInfo> mMenuInfos;
+
+/* --Methode-- */
+PIMenuMac::PIMenuMac(PIWdg* par, const char *nom, PIMenuType pdpu) 
+: PIMenuGen(par, nom, pdpu)
+{
+   macMenu = new LMenu(lastId, LStr255(nom));
+   menuInfo info;
+   info.mId = lastId;
+   info.pimenu = this;
+   mMenuInfos.push_back(info);
+   lastId++;
+}
+
+
+/* --Methode-- */
+PIMenuMac::~PIMenuMac()
+{
+  LMenuBar::GetCurrentMenuBar()->RemoveMenu(macMenu);
+  mMenuInfos.erase(mMenuInfos.begin() + GetMenuNum());
+  delete macMenu;
+}
+
+/* --Methode-- */
+void PIMenuMac::AppendItem(const char* nom, PIMessage msg, char* sc)
+{
+  AddItem(nom, msg, 0, sc, NULL);
+}
+
+/* --Methode-- */
+void PIMenuMac::AppendCheckItem(const char* nom, PIMessage msg, char* sc)
+{
+  AddItem(nom, msg, 1, sc, NULL);
+}
+
+/* --Methode-- */
+void PIMenuMac::AppendPDMenu(PIMenuGen *pdm, char* sc)
+{
+  if (pdm->MType() !=  k_PulldownMenu) {
+    cerr << "PIMenuX::AppendPDMenu()/Erreur: PullDownMenu seulement ... " << endl;
+    return;
+  }
+  AddItem(NULL, pdm->Msg(), 2, sc, (PIMenuMac*)pdm);
+}
+
+/* --Methode-- */
+void PIMenuMac::AddItem(const char* nom, PIMessage msg, int tog, char* sc, PIMenuMac *pdm)
+{
+  macMenu->InsertCommand("\ptemp", -2000, 1000);
+  MenuHandle mh = GetMacMenuHandle();
+  short i = ::CountMenuItems(mh);
+  LStr255 titre(nom);
+  ::SetMenuItemText(mh, i, titre);
+
+  // Gestion menus hiérarchiques
+  if (tog == 2 && pdm != NULL) {
+    ::SetItemCmd(mh, i, hMenuCmd);
+    ::SetItemMark(mh, i, pdm->GetMacMenuID());
+  }
+  // Le menu hierarchique sera "insere" au moment de l'insertion dans la
+  // menubar...
+  
+  itemInfo info;
+  info.pimsg  = msg;
+  info.name   = nom;
+  mItemInfos.push_back(info);
+}
+
+/* --Methode-- */
+int PIMenuMac::GetItemNum(const char *nom)
+{
+  int j=0;
+  for (vector<itemInfo>::iterator i = mItemInfos.begin(); i != mItemInfos.end(); i++,j++)
+    if ((*i).name == nom) return j;
+  return(-1);
+}
+
+/* --Methode-- */
+int PIMenuMac::GetItemNumMsg(PIMessage msg)
+{
+  int j=0;
+  for (vector<itemInfo>::iterator i = mItemInfos.begin(); i != mItemInfos.end(); i++,j++)
+    if ((*i).pimsg == msg) return j;
+  return(-1);
+}
+
+/* --Methode-- */
+int PIMenuMac::GetMenuNum()
+{
+  int j=0;
+  for (vector<menuInfo>::iterator i = mMenuInfos.begin(); i != mMenuInfos.end(); i++,j++)
+    if ((*i).pimenu == this) return j;
+  return(-1);
+}
+
+/* --Methode-- */
+int PIMenuMac::GetMenuNum(short menuId)
+{
+  int j=0;
+  for (vector<menuInfo>::iterator i = mMenuInfos.begin(); i != mMenuInfos.end(); i++,j++)
+    if ((*i).mId == menuId) return j;
+  return(-1);
+}
+
+/* --Methode-- */
+PIMenu* PIMenuMac::GetMenu(short menuId)
+{
+  int j=0;
+  for (vector<menuInfo>::iterator i = mMenuInfos.begin(); i != mMenuInfos.end(); i++,j++)
+    if ((*i).mId == menuId) return (*i).pimenu;
+  return(NULL);
+}
+
+
+/* --Methode-- */
+void
+PIMenuMac::SetStateNum(int n, bool st)
+{
+  if (n<0 || n >= mItemInfos.size()) return; // $CHECK$ exception ?
+  ::CheckItem(macMenu->GetMacMenuH(), n, st);
+}
+
+/* --Methode-- */
+void
+PIMenuMac::SetStateMsg(PIMessage msg, bool st)
+{
+  int i = GetItemNumMsg(msg);
+  if (i>=0)
+    SetStateNum(i, st);
+}
+
+/* --Methode-- */
+void
+PIMenuMac::SetState(const char* nom, bool st)
+{
+  int i = GetItemNum(nom);
+  if (i>=0)
+    SetStateNum(i, st);
+}
+
+void
+PIMenuMac::DeleteItemNum(int n)
+{
+  if (n<0 || n >= mItemInfos.size()) return; // $CHECK$ exception ?
+  macMenu->RemoveItem(n+1);
+  mItemInfos.erase(mItemInfos.begin()+n);
+}
+
+void
+PIMenuMac::DeleteItemMsg(PIMessage msg)
+{
+  int i = GetItemNumMsg(msg);
+  if (i>=0)
+    DeleteItemNum(i);
+}
+
+void
+PIMenuMac::DeleteItem(const char* nom)
+{
+  int i = GetItemNum(nom);
+  if (i>=0)
+    DeleteItemNum(i);
+}
+
+void
+PIMenuMac::ItemSelected(int item)
+{
+  if (item<0 || item >= mItemInfos.size()) return; // $CHECK$ exception ?
+  Send(mItemInfos[item].pimsg, PIMsg_Click, (void*) mItemInfos[item].name.c_str());
+}
+
+string
+PIMenuMac::GetMenuItemText(int item)
+{
+  if (item<0 || item >= mItemInfos.size()) return ""; // $CHECK$ exception ?
+  return mItemInfos[item].name;
+}
+
+PIMessage
+PIMenuMac::GetMenuItemMsg(int item)
+{
+  if (item<0 || item >= mItemInfos.size()) return -1; // $CHECK$ exception ?
+  return mItemInfos[item].pimsg;
+}
+
+
+
+void
+PIMenuMac::Show()
+{}
+
+void
+PIMenuMac::Show(PIWdg *w, int px, int py)
+{}
+
+
+MenuHandle
+PIMenuMac::GetMacMenuHandle()
+{
+  return macMenu->GetMacMenuH();
+}
+
+ResIDT
+PIMenuMac::GetMacMenuID()
+{
+  return macMenu->GetMenuID();
+}
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/pimenumac.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pimenumac.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pimenumac.h	(revision 2309)
@@ -0,0 +1,78 @@
+#ifndef PIMENUMAC_H_SEEN
+#define PIMENUMAC_H_SEEN
+
+#include "pimenugen.h"
+#include <LMenu.h>
+#include <vector>
+#include <list>
+
+// Menu general
+class PIMenuMac : public PIMenuGen {
+public:
+					PIMenuMac(PIWdg* par, const char* nom, PIMenuType pdpu=k_UTMenu);
+				   ~PIMenuMac();
+				   
+  virtual void	  AppendItem(const char* nom, PIMessage msg, char* sc=NULL);
+  virtual void	  AppendCheckItem(const char* nom, PIMessage msg, char* sc=NULL);
+  virtual void	  AppendPDMenu(PIMenuGen *pdm, char* sc=NULL);
+
+  virtual void    DeleteItem(const char *nom);
+  virtual void    DeleteItemMsg(PIMessage msg);
+  virtual void    DeleteItemNum(int n);
+
+  virtual void    SetSensitivity(const char *nom, bool sens=true); 
+  virtual void    SetSensitivityMsg(PIMessage msg, bool sens=true); 
+  virtual void    SetSensitivityNum(int n, bool sens=true);
+
+  virtual bool    IsSensitive(const char *nom);
+  virtual bool    IsSensitiveMsg(PIMessage msg);
+  virtual bool    IsSensitiveNum(int n);
+
+  virtual void    SetState(const char *nom, bool st=false); 
+  virtual void    SetStateMsg(PIMessage msg, bool st=false); 
+  virtual void    SetStateNum(int n, bool st=false);
+ 
+  virtual bool    GetState(const char *nom); 
+  virtual bool    GetStateMsg(PIMessage msg); 
+  virtual bool    GetStateNum(int n); 
+
+  virtual void    Show();
+  virtual void    Show(PIWdg *w, int px, int py);
+
+  LMenu*          GetPPMenu() {return macMenu;}
+  void            ItemSelected(int item);
+  string          GetMenuItemText(int item);
+  PIMessage       GetMenuItemMsg(int item);	
+protected:
+	LMenu*          macMenu;
+	struct menuInfo {
+	  short      mId;
+	  PIMenuMac* pimenu;
+	};
+	struct itemInfo {
+	  PIMessage  pimsg;
+	  string     name;
+	};
+	static vector<menuInfo> mMenuInfos;
+	vector<itemInfo> mItemInfos;
+	static int      lastId;
+	
+	friend class    PIMenubarMac;
+	friend class    PIOptMenuMac;
+	friend class    PIPPOptMenu;
+	friend class    PIPPMenuBar;
+	MenuHandle      GetMacMenuHandle();
+	ResIDT          GetMacMenuID();
+	
+    int             GetItemNum(const char* nom);
+	int             GetItemNumMsg(PIMessage msg);
+	int             GetMenuNum();
+	static int      GetMenuNum(short menuId);
+	static PIMenuMac*  GetMenu(short menuId);
+    void            AddItem(const char* nom, PIMessage msg, int tog, char* sc, PIMenuMac *pdm);
+};
+
+
+typedef PIMenuMac      PIMenu;
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pimenux.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pimenux.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pimenux.cc	(revision 2309)
@@ -0,0 +1,495 @@
+#include<stdio.h>
+#include<iostream.h>
+
+#include "pisysdep.h"
+#include PIMENUBAR_H
+
+#include <Xm/Xm.h>
+#include <Xm/RowColumn.h>
+#include <Xm/PushB.h>
+#include <Xm/ToggleB.h>
+#include <Xm/CascadeB.h>
+#include <Xm/Separator.h>
+
+/************* PIMenuX ************/
+
+// Quand on cree les menus comme fils du Top-Widget, ca rentre en 
+// conflit avec certaains Window-Manager ...
+// La fonction suivante permet de bypasser ce probleme- Le createur d'application
+// X doit donc appeler la fonction ci-dessous pour initialiser menuXTopWdg
+//                                               Reza 4/11/97
+static SysDWdg menuXTopWdg = NULL;
+void SetTopWdgForMenuX(SysDWdg mtw) {
+  menuXTopWdg = mtw;
+}
+
+// Pour ces sal... de XmString  (ds piwdgx.cc)
+int CStrFrXmStr(XmString xms, char* buff, int nmx);
+
+
+// Fonction prive (CallBack)
+static void menu_action(Widget w, XtPointer usd, XtPointer calld);
+static void menu_toggle_action(Widget w, XtPointer usd, XmToggleButtonCallbackStruct* calld);
+
+/* Nouvelle-Fonction */
+void  menu_action(Widget /*w*/, XtPointer usd, XtPointer /*calld*/)
+{
+PIMenuX *pim;
+_pimxit_ *cusd;
+
+cusd = ( _pimxit_ *)usd ;
+pim = (PIMenuX *) (cusd->pmen);
+// pim->Hide();
+pim->SendSelf(cusd->msg, PIMsg_Click );
+#ifdef DEBUG_PIMenuX
+printf("%%%Debug_menu_action: Msg= %d  %lx\n", (int)cusd->msg, (long)pim);
+#endif
+return;
+}
+
+// Variable globale pour Toggle Item's  Send(..., ..., data); 
+static bool toggmenbut = false;
+
+/* Nouvelle-Fonction */
+void  menu_toggle_action(Widget /*w*/, XtPointer usd, XmToggleButtonCallbackStruct* calld)
+{
+PIMenuX *pim;
+_pimxit_ *cusd;
+
+cusd = ( _pimxit_ *)usd ;
+pim = (PIMenuX *) (cusd->pmen);
+if (calld->set == True)  cusd->togstate = toggmenbut = true;
+else  cusd->togstate = toggmenbut = false;
+pim->SendSelf(cusd->msg, PIMsg_DataChanged, (void *)(&toggmenbut));
+return;
+}
+
+
+
+#define NBITEMB  10
+
+/* --Methode-- */
+PIMenuX::PIMenuX(PIWdg* par, const char *nom, PIMenuType pdpu) 
+: PIMenuGen(par, nom, pdpu)
+{
+mNItem = 0;  mNItemMax = NBITEMB; 
+mNSep = 0;
+mBut = new _pimxit_[mNItemMax];
+
+SysDWdg tw;
+if (par == NULL) { 
+  tw = menuXTopWdg;
+  if (tw == NULL) tw = PIXtTopWdg(); 
+}
+else  tw = par->XtWdg();
+// Si le type de menu pdpu n'est pas specifie, on le decide 
+// en fonction du type de l'objet parent 
+if (pdpu == k_UTMenu) {
+  if  ( (par->kind() == PIMenu::ClassId) || (par->kind() == PIMenubar::ClassId) )  pdpu = k_PulldownMenu ;
+  else pdpu = k_PopupMenu ;
+}
+if (pdpu == k_PopupMenu)
+  XtWdg() = XmCreatePopupMenu( tw, (char *)nom, NULL, 0);   // const_cast
+else 
+  XtWdg() = XmCreatePulldownMenu( tw, (char *)nom, NULL, 0); // const_cast
+
+mMTyp = pdpu;
+wmis = k_wmi_normal ;
+stmng = 0;
+}
+
+/* --Methode-- */
+PIMenuX::~PIMenuX()
+{
+// for(int i=0; i<mNItem; i++)
+//  XtDestroyWidget(mBut[i].itb); Le destroy est fait par le widget menu lui-meme
+delete[] mBut ;
+}
+
+
+/* --Methode-- */
+void PIMenuX::AppendItem(const char* nom, PIMessage msg, char* sc)
+{
+AddItem(nom, msg, 0, sc, NULL);
+}
+
+/* --Methode-- */
+void PIMenuX::AppendCheckItem(const char* nom, PIMessage msg, char* sc)
+{
+AddItem(nom, msg, 1, sc, NULL);
+}
+
+/* --Methode-- */
+void PIMenuX::AppendPDMenu(PIMenuGen *pdm, char* sc)
+{
+if (pdm->MType() !=  k_PulldownMenu) {
+  cerr << "PIMenuX::AppendPDMenu()/Erreur: PullDownMenu seulement ... " << endl;
+  return;
+  }
+AddItem(NULL, pdm->Msg(), 2, sc, (PIMenuX*)pdm);
+}
+
+/* --Methode-- */
+void PIMenuX::AppendSeparator()
+{
+  Arg warg[3];
+  int na = 0;
+  XtSetArg(warg[na], XmNorientation, XmHORIZONTAL); na++;
+  XtSetArg(warg[na], XmNseparatorType, XmSHADOW_ETCHED_IN); na++;
+
+  char buff[64];
+  sprintf(buff, "%s_sep_%d", this->Nom().substr(0, 32).c_str(), mNSep); 
+  Widget sep = XmCreateSeparator(this->XtWdg(), buff, warg, na);
+  XtManageChild(sep);
+  mNSep++;
+  //  cout << " DBG PIMenuX::AppendSeparator() : " << buff << endl;
+}
+
+/* --Methode-- */
+void PIMenuX::DeleteItem(const char *nom)
+{
+DeleteItemNum(GetNumItem(nom));
+}
+
+/* --Methode-- */
+void PIMenuX::DeleteItemMsg(PIMessage msg)
+{
+DeleteItemNum(GetNumItemMsg(msg));
+}
+
+/* --Methode-- */
+void PIMenuX::SetSensitivity(const char *nom, bool sens)
+{
+SetSensitivityNum(GetNumItem(nom), sens);
+}
+
+/* --Methode-- */
+void PIMenuX::SetSensitivityMsg(PIMessage msg, bool sens)
+{
+SetSensitivityNum(GetNumItemMsg(msg), sens);
+}
+
+/* --Methode-- */
+bool PIMenuX::IsSensitive(const char *nom)
+{
+return(IsSensitiveNum(GetNumItem(nom)) );
+}
+
+/* --Methode-- */
+bool PIMenuX::IsSensitiveMsg(PIMessage msg)
+{
+return(IsSensitiveNum(GetNumItemMsg(msg)) ); 
+}
+
+/* --Methode-- */
+bool PIMenuX::IsSensitiveNum(int n)
+{
+if ((n < 0) || (n >= mNItem))  return(false);
+if (XtIsSensitive(mBut[n].itb) == TRUE)  return(true);
+else return(false);
+}
+
+/* --Methode-- */
+void PIMenuX::SetSensitivityNum(int n, bool sens)
+{
+if ((n < 0) || (n >= mNItem))  return;
+if (sens) XtSetSensitive(mBut[n].itb, TRUE);
+else XtSetSensitive(mBut[n].itb, FALSE);
+}
+
+/* --Methode-- */
+void PIMenuX::DeleteItemNum(int n)
+{
+if ((n < 0) || (n >= mNItem))  return;
+XtDestroyWidget(mBut[n].itb);
+for(int i=n; i<mNItem-1; i++)
+  {
+  String cbckn;
+  XtCallbackProc cbproc;
+  if (mBut[i+1].toggpdm < 2) {
+    if (mBut[i+1].toggpdm == 1)    // ToggleItem 
+      { cbckn = XmNvalueChangedCallback;  cbproc = (XtCallbackProc)menu_toggle_action; }
+    else { cbckn = XmNactivateCallback;  cbproc = menu_action; }
+
+    XtRemoveCallback(mBut[i+1].itb, cbckn, cbproc, (XtPointer)(mBut+i+1));
+    mBut[i] = mBut[i+1];
+    XtAddCallback(mBut[i].itb, cbckn, cbproc, (XtPointer)(mBut+i));
+    }
+  else mBut[i] = mBut[i+1]; 
+  }
+mNItem--;
+}
+
+
+/* --Methode-- */
+void PIMenuX::SetState(const char *nom, bool st)
+{
+SetStateNum(GetNumItem(nom), st);
+}
+
+/* --Methode-- */
+void PIMenuX::SetStateMsg(PIMessage msg, bool st)
+{
+SetStateNum(GetNumItemMsg(msg), st);
+}
+
+/* --Methode-- */
+void PIMenuX::SetStateNum(int n, bool st)
+{
+if ((n < 0) || (n >= mNItem))  return;
+if (mBut[n].toggpdm != 1 ) return;  // Pas un toggle-item
+Arg warg[2];
+if (st) XtSetArg(warg[0],XmNset, True);
+else XtSetArg(warg[0],XmNset, False);
+XtSetValues(mBut[n].itb, warg, 1);
+mBut[n].togstate = st;
+return;
+}
+
+/* --Methode-- */
+bool PIMenuX::GetState(const char *nom)
+{
+return( GetStateNum(GetNumItem(nom)) );
+}
+
+/* --Methode-- */
+bool PIMenuX::GetStateMsg(PIMessage msg)
+{
+return( GetStateNum(GetNumItemMsg(msg)) );
+}
+
+/* --Methode-- */
+bool PIMenuX::GetStateNum(int n) 
+{
+if ((n < 0) || (n >= mNItem))  return(false);
+if (mBut[n].toggpdm != 1 ) return(false); 
+return(mBut[n].togstate); 
+}
+
+
+
+
+/* --Methode-- */
+char* PIMenuX::ItemName(int n)
+{
+if ( (n < 0) || (n >= mNItem))  { mSItem[0] = '\0'; return(mSItem); }
+else return (ItemNameWdg(mBut[n].itb));
+}
+
+
+/* --Methode-- */
+char* PIMenuX::ItemNameWdg(SysDWdg itw)
+{
+XmString xmstr;
+Arg warg[2];
+
+XtSetArg(warg[0], XmNlabelString, &xmstr);
+XtGetValues(itw, warg, 1);
+if (xmstr)
+  {
+  CStrFrXmStr(xmstr, mSItem, 96);
+  XmStringFree(xmstr);
+  }
+else mSItem[0] = '\0';
+
+return(mSItem);
+}
+
+
+/* --Methode-- */
+PIMessage PIMenuX::ItemMsg(int n)
+{
+if ( (n < 0) || (n >= mNItem))  return(0);
+else return(mBut[n].msg);
+}
+
+
+
+/* --Methode-- */
+int PIMenuX::GetNumItem(const char *nom)
+{
+
+for(int i=0; i<mNItem; i++)
+  if (strcmp(ItemName(i),nom) == 0)  return(i);
+return(-1);
+}
+
+/* --Methode-- */
+int PIMenuX::GetNumItemMsg(PIMessage msg)
+{
+for(int i=0; i<mNItem; i++)
+  if (mBut[i].msg == msg)   return(i);  
+return(-1);
+}
+
+/* --Methode-- */
+SysDWdg PIMenuX::GetItemWdg(int n)
+{
+if ((n<0) || (n>=mNItem))  return(NULL);
+else return(mBut[n].itb);
+}
+
+
+/* --Methode-- */
+void PIMenuX::AddItem(const char* nom, PIMessage msg, int tog, char* sc, PIMenuX *pdm)
+{
+_pimxit_ *buto;
+SysDWdgClass wdgcl;
+String cbckn;
+XtCallbackProc cbproc;
+Arg  warg[2];
+int n=0;
+
+
+if (mNItem >= mNItemMax)  {
+  buto = mBut;
+  mNItemMax += NBITEMB;
+  mBut = new _pimxit_[mNItemMax];
+  for(int i=0; i<mNItem; i++)    {
+    if (buto[i].toggpdm < 2) {  // Pas de Cascade Menu
+      if (buto[i].toggpdm == 1)  // ToggleItem
+        { cbckn = XmNvalueChangedCallback;  cbproc = (XtCallbackProc)menu_toggle_action; }
+      else { cbckn = XmNactivateCallback;  cbproc = menu_action; }
+      XtRemoveCallback(buto[i].itb, cbckn, cbproc, (XtPointer)(buto+i));
+      mBut[i] = buto[i];
+      XtAddCallback(mBut[i].itb, cbckn, cbproc, (XtPointer)(mBut+i));
+      }
+    else mBut[i] = buto[i]; 
+    }
+  delete[] buto;
+  }
+
+if (tog < 2) {  // Pas de Cascade Menu
+  if (tog == 1) {   // Toggle-Item 
+    cbckn = XmNvalueChangedCallback;  cbproc = (XtCallbackProc)menu_toggle_action;
+    wdgcl = xmToggleButtonWidgetClass;  
+    XtSetArg(warg[0],XmNset, False); n = 1; }
+  else {
+    cbckn = XmNactivateCallback;  cbproc = menu_action;
+    wdgcl = xmPushButtonWidgetClass;  n = 0; }
+
+  mBut[mNItem].itb = XtCreateManagedWidget(nom, wdgcl, this->XtWdg(), warg, n) ; 
+  XtAddCallback(mBut[mNItem].itb, cbckn, cbproc, (XtPointer)(mBut+mNItem));
+  }
+else {    // Creation Cascade-Menu
+  XtSetArg(warg[0], XmNsubMenuId, pdm->XtWdg());
+  mBut[mNItem].itb = XtCreateManagedWidget(pdm->Nom().c_str(), xmCascadeButtonWidgetClass, 
+                                           XtWdg(), warg, 1) ;
+  pdm->SetMsgParent(this);
+  }
+
+if (sc)  // Raccourci clavier 
+  {
+  char acc[16];
+  XmString xmstr;
+  n=0;
+  sprintf(acc,"Ctrl/%c", sc[0]);
+  xmstr = XmStringLtoRCreate(acc, XmSTRING_DEFAULT_CHARSET);
+  XtSetArg(warg[n], XmNacceleratorText, xmstr); n++;
+  sprintf(acc,"Ctrl<Key>%c", sc[0]);
+  XtSetArg(warg[n], XmNaccelerator, acc); n++;
+  XtSetValues(mBut[mNItem].itb, warg, n);  
+  XmStringFree(xmstr);
+  }
+
+#ifdef DEBUG_PIMenuX
+printf("DBG>> %d (%d) %lx \n", mNItem, mNItemMax, (long)(mBut+mNItem));
+#endif
+mBut[mNItem].pmen = this;
+mBut[mNItem].msg = msg;
+mBut[mNItem].toggpdm = tog;
+mBut[mNItem].togstate = false;
+mNItem++;
+return;
+}
+
+
+
+/* --Methode-- 
+void PIMenuX::Check()
+{
+printf("#Debug_CHECK: %d %d %d %d \n",XSize(), YSize(), XPos(), YPos() );  
+for(int i=0; i<mNItem; i++)
+  printf("##Debug_CHECK: %d %d %ld %lx %lx %lx \n", i, (int)mBut[i].toggpdm, 
+         (long) mBut[i].msg, (long) mBut[i].itb, 
+         (long) mBut[i].pmen, long (mBut+i));
+return;
+}
+*/
+
+
+
+
+void PIMenuX::Show()
+{
+if (MType() !=  k_PopupMenu) {
+  cerr << "PIMenuX::Show()/Erreur: PopupMenu seulement ... " << endl;
+  return;
+  }
+
+// XEvent  mevt;
+XButtonEvent evt;
+
+// XPeekEvent(PIXDisplay(), &mevt);
+// evt = mevt.xbutton; 
+evt.type = ButtonPress;
+evt.display = PIXDisplay();
+evt.window = XtWindow(PIXtTopWdg());
+evt.root = DefaultRootWindow(evt.display);
+evt.serial = PIXGetLastEventSerial(); 
+evt.time = PIXGetLastEventTime();
+evt.send_event = False;
+evt.same_screen = XQueryPointer(evt.display, evt.window, &(evt.root), 
+                    &(evt.subwindow), &(evt.x_root), &(evt.y_root), 
+                    &(evt.x), &(evt.y), &(evt.state));
+ 
+#ifdef DEBUG_PIMenuX
+printf("XXDbg_Show : %d %d %d - %d %d \n", (int)evt.same_screen, 
+       (int)evt.x_root, (int)evt.y_root, (int)evt.x, (int)evt.y);
+#endif
+
+if (evt.same_screen) XmMenuPosition(XtWdg(), &evt);
+Manage();     
+}
+
+/* --Methode-- */
+void PIMenuX::Show(PIWdg *w, int px, int py)
+{
+if (MType() !=  k_PopupMenu) {
+  cerr << "PIMenuX::Show(w, px, py)/Erreur: PopupMenu seulement ... " << endl;
+  return;
+  }
+// This method should only be used by a button press ...
+int xr, yr;
+Window cw, sw, rw;
+SysDWdg xtw;
+Display *dsp;
+XButtonEvent evt;
+
+xtw =  w->XtWdg();
+dsp = XtDisplay(xtw);
+sw = XtWindow(xtw);
+rw = DefaultRootWindow(dsp);
+XTranslateCoordinates(dsp, sw, rw, px, py, &xr, &yr, &cw);
+
+evt.type = ButtonPress;
+evt.display = dsp;
+evt.window = sw;
+evt.root = rw;
+evt.x_root = xr;
+evt.y_root = yr; 
+evt.x = px;
+evt.y = py;
+evt.serial = PIXGetLastEventSerial(); 
+evt.time = PIXGetLastEventTime();
+evt.send_event = False;
+evt.same_screen = True;
+XmMenuPosition(XtWdg(), &evt);
+// SetPos(xr, yr);
+Manage();
+return;    
+}
+
+
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/pimenux.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pimenux.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pimenux.h	(revision 2309)
@@ -0,0 +1,75 @@
+#ifndef PIMENUX_H_SEEN
+#define PIMENUX_H_SEEN
+
+#include "pimenugen.h"
+
+
+class PIMenuX ;
+
+struct _pimxit_ 
+{
+SysDWdg itb;
+PIMenuX *pmen;
+PIMessage msg;
+int toggpdm;      // 0= Normal Item, 1, Toggle Item,  2= PDMenu
+bool togstate;    // true , false pour toggle items  
+};
+
+
+
+class PIMenuX : public PIMenuGen {
+public:
+	          PIMenuX(PIWdg* par, const char* nom, PIMenuType pdpu=k_UTMenu);
+	          ~PIMenuX();
+				   
+  virtual void	  AppendItem(const char* nom, PIMessage msg, char* sc=NULL);
+  virtual void	  AppendCheckItem(const char* nom, PIMessage msg, char* sc=NULL);
+  virtual void	  AppendPDMenu(PIMenuGen *pdm, char* sc=NULL);
+  virtual void	  AppendSeparator();
+
+  virtual void    DeleteItem(const char *nom);
+  virtual void    DeleteItemMsg(PIMessage msg);
+  virtual void    DeleteItemNum(int n);
+
+  virtual void    SetSensitivity(const char *nom, bool sens=true); 
+  virtual void    SetSensitivityMsg(PIMessage msg, bool sens=true); 
+  virtual void    SetSensitivityNum(int n, bool sens=true);
+
+  virtual bool    IsSensitive(const char *nom);
+  virtual bool    IsSensitiveMsg(PIMessage msg);
+  virtual bool    IsSensitiveNum(int n);
+
+  virtual void    SetState(const char *nom, bool st=false); 
+  virtual void    SetStateMsg(PIMessage msg, bool st=false); 
+  virtual void    SetStateNum(int n, bool st=false);
+ 
+  virtual bool    GetState(const char *nom); 
+  virtual bool    GetStateMsg(PIMessage msg); 
+  virtual bool    GetStateNum(int n); 
+
+  virtual void    Show();
+  virtual void    Show(PIWdg *w, int px, int py);
+
+
+// Pour usage prive et par OptionMenu, ...
+  PIMessage       ItemMsg(int n);
+  int             GetNumItem(const char *nom);
+  int             GetNumItemMsg(PIMessage msg);
+  SysDWdg         GetItemWdg(int n);
+  char*           ItemName(int n);
+  char*           ItemNameWdg(SysDWdg itw);
+
+protected:
+        void      AddItem(const char* nom, PIMessage msg, int tog, char* sc, PIMenuX *pdm);
+
+int mNItem, mNItemMax;
+int mNSep;
+_pimxit_  * mBut;
+char mSItem[96];
+};
+
+
+typedef PIMenuX        PIMenu;
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pimsghandler.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pimsghandler.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pimsghandler.cc	(revision 2309)
@@ -0,0 +1,101 @@
+//  Classe de gestionnaire de message pour programme graphique interactive
+//
+//                  E.Aubourg , R. Ansari  01-06/96
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "pimsghandler.h"
+
+//++
+// Class	PIMsgHandler
+// Lib		PI
+// include	pimsghandler.h
+//
+//   	Classe de gestionnaire de message de Peida Interactive (PI)
+//	Les message ("PIMessage") sont des entiers non signés
+//	("unsigned long"). 
+//	Chaque PIMsgHandler se trouve dans une organisation 
+//	hiérarchique où il dépend d'un
+//	PIMsgHandler père à qui il reporte les messages, et peut
+//	avoir lui-même un ou plusieurs PIMsgHandler qui sont sous sa 
+//	dépendance. Un message ("PIMessage") est constitué de deux 
+//	parties, une partie à la disposition de l'utilisateur ("UserMsg()")
+//	et une partie sous contrôle du code PI ("ModMsg()"), 
+//	qui peut spécifie si nécéssaire la raison de déclenchement 
+//	d'envoi du message. 
+//--
+
+//++
+// Titre	Constructeur
+//--
+//++
+// PIMsgHandler(PIMsgHandler* par=NULL)
+//	Création d'un PIMsgHandler dépendant hiérarchiquement du parent "par"
+//--
+
+PIMsgHandler::PIMsgHandler(PIMsgHandler* par)
+: msgParent(par)
+{}
+
+PIMsgHandler::~PIMsgHandler()
+{}
+
+
+//++
+// Titre	Traitement des messages
+//--
+
+//++
+// PIMessage  UserMsg(PIMessage msg)
+//	Décode et renvoie la partie utilisateur d'un PIMessage
+// PIMessage  ModMsg(PIMessage msg)
+//	Décode et renvoie la partie *modifier* d'un PIMessage
+// PIMessage  BuildMsg(PIMessage um, PIMsgMod mm) 
+//	Code les deux parties (user "um", modifier "mm") d'un message
+//	dans un PIMessage.
+// void  SetMsgParent(PIMsgHandler* par)
+//	Modifie l'organisation hiérarchique, en assignant un nouveau père.
+// void	 Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL)
+//	Cette méthode virtuelle est appelée quand un message "msg"
+//	est reçue par l'objet gestionnaire. "sender" est l'expéditeur
+//	du message, et "data" est un argument optionnel supplémentaire.
+//	La signification et contenu de "data" dépend de l'expéditeur
+//	et du contexte. Par défaut, la méthode "Process(...)" renvoie
+//	le message au PIMsgHandler père, sans altérer l'identité
+//	de l'expéditeur. (méthode "ReSend(...)"). C'est une méthode 
+//	non public (protected) destinée être redéfinie par les classes
+//	héritières.
+// void  Send(PIMessage msg, PIMsgMod mm=0, void* data=NULL)
+//	Envoie le message "msg" avec le modifier "mm", et l'argument 
+//	optionnel "data" au parent, déclenchant ainsi l'execution
+//	de la méthode "Process(...)" du père.
+// void  SendSelf(PIMessage msg, PIMsgMod mm=0, void* data=NULL)
+//	Envoie le message "msg" avec le modifier "mm", et l'argument 
+//	optionnel "data" à l'objet lui-même, déclenchant ainsi l'execution
+//	de la méthode "Process(...)" de l'objet.
+//--
+
+void
+PIMsgHandler::Process(PIMessage msg, PIMsgHandler* sender, void* data)
+{
+	ReSend(msg, sender, data);
+}
+
+void
+PIMsgHandler::Send(PIMessage msg, PIMsgMod mm,  void* data)
+{
+//	Process(msg, this, data);  $CHECK$  Reza 12/06/96
+// Send par defaut appelle le process du parent $CHECK$
+if (msgParent)
+  msgParent->Process(BuildMsg(msg, mm), this, data);
+
+}
+
+void
+PIMsgHandler::ReSend(PIMessage msg, PIMsgHandler* sender, void* data)
+{
+  if (msgParent)
+    msgParent->Process(msg, sender, data);
+}
+
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/pimsghandler.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pimsghandler.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pimsghandler.h	(revision 2309)
@@ -0,0 +1,67 @@
+#ifndef PIMSGHANDLER_H_SEEN
+#define PIMSGHANDLER_H_SEEN
+
+/* Classe de gestion de messages */
+
+#include "machdefs.h"
+#include <stdlib.h>
+
+
+enum {
+ // Les messages reserves systeme (PI)   les 8 premiers bits
+ // Messages user, les bits restants
+	PIMsg_Active        = 1,
+        PIMsg_Close         = 2,
+        PIMsg_Resize        = 3,
+        PIMsg_ResizeRequest = 4,
+
+	PIMsg_Click         = 21,
+        PIMsg_Press         = 22,
+        PIMsg_Release       = 23,
+        PIMsg_Drag          = 24,
+        PIMsg_Drop          = 25,
+        PIMsg_Copy          = 26,
+        PIMsg_Paste         = 27,
+        PIMsg_Cut           = 28,
+
+	PIMsg_OK            = 21,
+	PIMsg_Cancel        = 22,
+	PIMsg_Help          = 23,
+
+	PIMsg_DataChanged   = 31,
+        PIMsg_Select        = 32,
+        PIMsg_ClearSel      = 33
+
+};
+
+
+// Definition de type pour les messages - Il est peu probable que le typedef change ...
+//                                      Reza 17/10/96
+typedef unsigned long PIMessage;
+typedef unsigned char PIMsgMod;
+
+class PIMsgHandler {
+public:
+			     PIMsgHandler(PIMsgHandler* par=NULL);
+	virtual 	     ~PIMsgHandler();
+	
+	virtual void	     SetMsgParent(PIMsgHandler* par) {msgParent = par;}
+
+	virtual void         Send(PIMessage msg, PIMsgMod mm=0, void* data=NULL);
+	inline  void         SendSelf(PIMessage msg, PIMsgMod mm=0, void* data=NULL)
+                                  { Process(BuildMsg(msg, mm), this, data); }
+
+        inline  PIMessage    UserMsg(PIMessage msg) { return (msg >> 8); }
+        inline  PIMessage    ModMsg(PIMessage msg) { return (msg & 0xFF); }
+	inline  PIMessage    BuildMsg(PIMessage um, PIMsgMod mm) 
+                        	  { return ((um << 8) | mm); }
+
+protected:
+	virtual void	ReSend(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+	virtual void	Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+
+private:
+	PIMsgHandler*     msgParent;
+};
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pimsgmac.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pimsgmac.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pimsgmac.h	(revision 2309)
@@ -0,0 +1,8 @@
+#include <PP_Types.h>
+
+const MessageT msg_Btn1    msg_Click;
+const MessageT msg_Btn2    10001;
+const MessageT msg_Btn3    10002;
+const MessageT msg_Move1   10003;
+const MessageT msg_Move2   10004;
+const MessageT msg_Move3   10005;
Index: /tags/V_Dec2002/SophyaPI/PI/pioptmenugen.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pioptmenugen.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pioptmenugen.cc	(revision 2309)
@@ -0,0 +1,66 @@
+// Module PI : Peida Interactive     PIOptMenu
+// Menu a option                                96-97
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "pioptmenugen.h"
+
+//++
+// Class	PIOptMenu
+// Lib		PI
+// include	pioptmenugen.h
+//
+//	Composant graphique de type menu à options. 
+//	"PIOptMenuGen" définit l'interface (classe virtuelle pure). Les objets 
+//	instanciés doivent être de la classe "PIOptMenu" déclarée dans le fichier
+//	entête "PIOPTMENU_H". Lors de la séléction d'une des options du menu
+//	Le message correspondant complété par "PIMsg_Click" est envoyé à l'objet
+//	par "SendSelf()".
+//--
+//--
+//++
+// Links	Parents
+// PIWdg
+//--
+//++
+// Links	Voir aussi
+// PIMenu
+//--
+
+//++
+// Titre	Constructeurs
+//--
+//++
+// PIOptMenuGen(PIContainerGen* par, const char* nom, int sx=50, int sy=15, int px=0, int py=0)
+//	Constructeur.
+//--
+
+PIOptMenuGen::PIOptMenuGen(PIContainerGen* par, const char* nom, int sx, int sy, int px, int py)
+: PIWdg(par, nom, sx, sy, px, py) // Attention au const !
+{
+}
+
+PIOptMenuGen::~PIOptMenuGen()
+{}
+
+//++
+// Titre	Méthodes
+//--
+
+//++
+// long  kind()
+//	Retourne PIOptMenuGen::ClassId
+// PIMenu*  Menu()
+//	Retourne le menu associé.
+// void  AppendItem(const char* nom, PIMessage msg)
+//	Permet d'ajouter une option au menu.
+// string  GetValueStr()
+//	Retourne la chaine de caracteres correspondant au choix courant.
+// PIMessage  GetValue()
+//	Retourne le message correspondant au choix courant.
+// void  SetValueStr(string & s) 
+//	Permet de sélectionner l'option correspondant a la chaine "s".
+// void  SetValue(PIMessage msg)
+//	Permet de sélectionner l'option correspondant au message "msg".
+//--
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/pioptmenugen.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pioptmenugen.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pioptmenugen.h	(revision 2309)
@@ -0,0 +1,32 @@
+#ifndef PIOPTMENGEN_H_SEEN
+#define PIOPTMENGEN_H_SEEN
+
+#include "pisysdep.h"
+#include PIMENU_H
+
+class PIOptMenuGen : public PIWdg {
+public:
+  enum {ClassId = 1100};
+
+	             PIOptMenuGen(PIContainerGen* par, const char* nom, int sx=50, int sy=15, int px=0, int py=0);
+	             ~PIOptMenuGen();
+				   
+  virtual long       kind() {return ClassId; }
+
+  inline  PIMenu*    Menu() {return mMen; }     // Renvoie un pointeur sur le menu associe 
+  inline  void       AppendItem(const char* nom, PIMessage msg) 
+                                   { mMen->AppendItem(nom, msg); }
+
+  virtual void       AppendPDMenu(PIMenu* pdm) = 0;
+
+  virtual string     GetValueStr() = 0;         // Option choisie
+  virtual PIMessage  GetValue() = 0;            // Message correspondant a l option choisie
+  virtual void       SetValueStr(string & s) = 0;
+  virtual void       SetValue(PIMessage msg) = 0;
+
+protected:
+  PIMenu* mMen;
+
+};
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pioptmenumac.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pioptmenumac.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pioptmenumac.cc	(revision 2309)
@@ -0,0 +1,85 @@
+#include "pioptmenumac.h"
+#include "pippoptmenu.h"
+
+/* --Methode-- */
+PIOptMenuMac::PIOptMenuMac(PIContainerGen* par, char const* nom,
+                     int sx, int sy, int px, int py)
+: PIOptMenuGen(par, nom, sx, sy, px, py)
+{
+  delete mPane;
+  
+  char buff[128];
+  strncpy(buff, nom, 64);
+  strcat(buff,"_Menu");
+  mMen = new PIMenu((PIWdg*)par, buff, k_PopupMenu);
+  mMen->SetMsgParent(this);
+  LStr255 titre("");
+  
+  StTextState textState;
+  ::TextFont(systemFont);
+  ::TextSize(12);
+  ::TextFace(0);
+  int titleWidth = ::StringWidth(titre);
+  
+  mPane = new PIPPOptMenu(mPaneInfo, msg_Click, 0, 200, titleWidth+5, popupMenuProc/*+popupVariableWidth*/, 130, titre, 0, 1);
+  
+  ((PIPPOptMenu*)mPane)->SetMenu(mMen);
+  ((LStdPopupMenu*)mPane)->AddListener(this);
+  
+  Manage();
+}
+
+/* --Methode-- */
+PIOptMenuMac::~PIOptMenuMac()
+{
+  delete mMen;
+}
+
+/* --Methode-- */
+void PIOptMenuMac::Process(PIMessage msg, PIMsgHandler* sender, void* data)
+{
+if (sender == mMen)   {
+  SetValue(UserMsg(msg));
+  ReSend(msg, this, NULL);
+}
+return;
+}
+
+void
+PIOptMenuMac::ListenToMessage(MessageT /*inMessage*/, void *)
+{
+//  if (inMessage == msg_Click)
+  int n = ((LStdPopupMenu*)mPane)->GetValue()-1;
+  mMen->ItemSelected(n);
+  mStext = mMen->GetMenuItemText(n);
+  mSmsg  = mMen->GetMenuItemMsg(n);
+}
+
+/* --Methode-- */
+void PIOptMenuMac::SetValueStr(string & s)
+{
+  int n;
+  n=mMen->GetItemNum((char *)s.c_str());
+  if (n < 0)  return;  
+
+  StopListening();
+  ((LStdPopupMenu*)mPane)->SetValue(n+1);
+  StartListening();
+  mStext = s;
+  mSmsg  = mMen->GetMenuItemMsg(n);
+}
+
+/* --Methode-- */
+void PIOptMenuMac::SetValue(PIMessage msg)
+{
+  int n;
+  n=mMen->GetItemNumMsg(msg);
+  if (n < 0)  return;
+  
+  StopListening();
+  ((LStdPopupMenu*)mPane)->SetValue(n+1);
+  StartListening();
+  mStext = mMen->GetMenuItemText(n);
+  mSmsg  = msg;
+}
+
Index: /tags/V_Dec2002/SophyaPI/PI/pioptmenumac.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pioptmenumac.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pioptmenumac.h	(revision 2309)
@@ -0,0 +1,29 @@
+#ifndef PIOPTMENMAC_H_SEEN
+#define PIOPTMENMAC_H_SEEN
+
+#include "pioptmenugen.h"
+
+class PIOptMenuMac : public PIOptMenuGen {
+public:
+	                PIOptMenuMac(PIContainerGen* par, const char* nom,  
+                               int sx=10, int sy=10, int px=0, int py=0);
+	               ~PIOptMenuMac();
+
+  virtual void      Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+				   
+  virtual void	    ListenToMessage(MessageT inMessage, void *ioParam);
+  virtual string    GetValueStr() { return(mStext); }
+  virtual PIMessage GetValue()    { return(mSmsg); } 
+  virtual void      SetValueStr(string & s);
+  virtual void      SetValue(PIMessage msg);
+  
+
+protected:
+  string    mStext;
+  PIMessage mSmsg;
+};
+
+
+typedef PIOptMenuMac  PIOptMenu ;
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pioptmenux.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pioptmenux.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pioptmenux.cc	(revision 2309)
@@ -0,0 +1,179 @@
+#include<stdio.h>
+
+#include <Xm/Xm.h>
+#include <Xm/PushB.h>
+
+#include "pisysdep.h"
+#include "pioptmenux.h"
+#include "piapplx.h"
+
+
+/************* PIOptionMenuX ************/
+static int rsx=0, rsy=0;
+
+/* Nouvelle-Fonction */
+static void mouse_handler_optmenux (Widget wdgp, XtPointer ud, 
+                                    XEvent* evt, Boolean* cont){
+*cont = FALSE ; 
+// printf("---  mouse_handler_optmenux ud = %lx ----- EvtType=%d (%d) \n", (long)ud, evt->type, Expose );
+if ( evt->type == Expose ) {
+  PIOptMenuX* opm = (PIOptMenuX*) ud;
+  Display* dis = PIXDisplay();
+  Window w = XtWindow(opm->XtWdg()) ;
+  XFillRectangle(dis, w, opm->myGC(), rsy, (opm->YSize()-rsy)/2, rsy, rsy); 
+  }
+else if ( (evt->type == ButtonPress) && (evt->xbutton.button == 1))  { 
+  PIXSetLastEventTimeSerial(evt->xbutton.time,  evt->xbutton.serial);
+  PIOptMenuX* opm = (PIOptMenuX*) ud;
+  opm->Menu()->Show(opm, rsy/2, opm->YSize());
+  }
+}
+
+
+/* --Methode-- */
+PIOptMenuX::PIOptMenuX(PIContainerGen* par, const char* nom, int sx, int sy, int px, int py)
+: PIOptMenuGen(par, nom, sx, sy, px, py)
+{
+mSmsg = 0;
+mStext = "";
+
+if (rsx == 0) { 
+  PIApplicationPrefCompSize(rsx, rsy);
+  rsy = rsy/3-2; 
+  }
+Arg warg[10];
+int n = 0;
+CreateXtWdg(nom, xmPushButtonWidgetClass, NULL, sx, sy, px, py);
+XtSetArg(warg[n],XmNhighlightThickness, 0);  n++;
+XtSetArg(warg[n], XmNrecomputeSize, FALSE); n++;
+XtSetArg(warg[n],XmNnavigationType,XmNONE);  n++;
+XtSetArg(warg[n],XmNtraversalOn,FALSE);  n++;
+XtSetArg(warg[n],XmNmarginLeft,rsy*3);  n++;
+XtSetValues(XtWdg(), warg, n);
+XtTranslations trans = XtParseTranslationTable( 
+      "<Btn1Down>: \n <Btn1Up>: \n <Btn2Down>: \n <Btn2Up>: \n <Btn3Down>: \n <Btn3Up>:");
+XtOverrideTranslations(XtWdg(), trans);
+XtAddEventHandler( XtWdg(), ButtonPressMask|ExposureMask, FALSE, mouse_handler_optmenux, this);
+mgc = 0;
+char buff[128];
+strncpy(buff, nom, 64);
+strcat(buff,"_Menu");
+mMen = new PIMenu((PIWdg*)par, buff, k_PopupMenu);
+mMen->SetMsgParent(this);
+Manage();
+}
+
+
+/* --Methode-- */
+PIOptMenuX::~PIOptMenuX()
+{
+delete mMen;
+}
+
+/* --Methode-- */
+void PIOptMenuX::FinishCreate()
+{
+PIWdgX::FinishCreate();
+// printf("PIOptMenuX::FinishCreate()/DBG  %s \n", Nom().c_str());
+if (mSmsg == 0)  SetValue(mMen->ItemMsg(0)); 
+}
+
+/* --Methode-- */
+void PIOptMenuX::AppendPDMenu(PIMenu* pdm)
+{
+  if (pdm == NULL)  return;
+  Menu()->AppendPDMenu(pdm);
+  mPDMList.push_back(pdm);
+}
+
+/* --Methode-- */
+void PIOptMenuX::Process(PIMessage msg, PIMsgHandler* sender, void* data)
+{
+// printf("PIOptMenuX::Process Msg= %d Sender= %lx \n", (int)msg, (long)sender);
+  // if (sender == mMen)   {    Ca peut venir d'un cascade menu !!
+  SetValue(UserMsg(msg));
+  ReSend(msg, this, NULL);
+  //}
+return;
+}
+
+
+/* --Methode-- */
+void PIOptMenuX::SetValueStr(string & s)
+{
+int n;
+Arg warg[2];
+n=mMen->GetNumItem((char *)s.c_str());
+if (n < 0)  { // On verifie si c'est ds les PD Menu
+  list<PIMenu *>::iterator it;
+  for(it = mPDMList.begin(); it != mPDMList.end(); it++) 
+    if ((n= (*it)->GetNumItem((char *)s.c_str())) >= 0) {
+      mStext = s;
+      mSmsg  = (*it)->ItemMsg(n);
+      SetLabel(mStext);
+      break;
+    }
+return;
+}
+else {
+  XtSetArg(warg[0], XmNmenuHistory, mMen->GetItemWdg(n));
+  XtSetValues(XtWdg(), warg, 1);
+  mStext = s;
+  mSmsg  = mMen->ItemMsg(n);
+  SetLabel(mStext);
+}
+return;
+}
+
+/* --Methode-- */
+void PIOptMenuX::SetValue(PIMessage msg)
+{
+int n;
+Arg warg[2];
+
+n=mMen->GetNumItemMsg(msg);
+if (n < 0)  { // On verifie si c'est ds les PD Menu
+  list<PIMenu *>::iterator it;
+  for(it = mPDMList.begin(); it != mPDMList.end(); it++) 
+    if ((n= (*it)->GetNumItemMsg(msg)) >= 0) {
+      mStext = (*it)->ItemName(n);
+      mSmsg  = msg;
+      SetLabel(mStext);
+      break;
+    }
+return;
+}
+else {  
+  XtSetArg(warg[0], XmNmenuHistory, mMen->GetItemWdg(n));
+  XtSetValues(XtWdg(), warg, 1);
+  mSmsg  = msg;
+  mStext = mMen->ItemName(n);
+  SetLabel(mStext);
+}
+return;
+}
+
+/* --Methode-- */
+void PIOptMenuX::SetLabel(string const& lab)
+{
+XmString xmstr;
+xmstr = XmStringLtoRCreate((char *)lab.c_str(), XmSTRING_DEFAULT_CHARSET);
+int n=0;
+Arg warg[2];
+
+XtSetArg(warg[n], XmNlabelString, xmstr); n++;
+XtSetValues(XtWdg(), warg, n);
+XmStringFree(xmstr);
+return;
+}
+
+/* --Methode-- */
+void PIOptMenuX::createmygc()
+{
+unsigned long fgc = 0;
+Arg warg[2];
+XtSetArg(warg[0], XmNforeground, &fgc);
+XtGetValues(XtWdg(), warg, 1);
+mgc = XCreateGC(PIXDisplay(), XtWindow(XtWdg()), 0, NULL); 
+XSetForeground(PIXDisplay(), mgc, fgc);
+}
Index: /tags/V_Dec2002/SophyaPI/PI/pioptmenux.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pioptmenux.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pioptmenux.h	(revision 2309)
@@ -0,0 +1,43 @@
+#ifndef PIOPTMENX_H_SEEN
+#define PIOPTMENX_H_SEEN
+
+#include "pisysdep.h"
+#include <list>
+#include "pioptmenugen.h"
+
+#include PISTDWDG_H
+
+class PIOptMenuX : public PIOptMenuGen {
+public:
+	            PIOptMenuX(PIContainerGen* par, const char* nom, int sx=50, int sy=15, int px=0, int py=0);
+	            ~PIOptMenuX();
+
+  virtual void	    FinishCreate(); 
+
+  virtual void      AppendPDMenu(PIMenu* pdm);
+
+  virtual void      Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+				   
+  virtual string    GetValueStr() { return(mStext); }
+  virtual PIMessage GetValue()    { return(mSmsg); } 
+  virtual void      SetValueStr(string & s);
+  virtual void      SetValue(PIMessage msg);
+
+
+//  Pour utilisation privee dans call-back, .... 
+  virtual void       SetLabel(string const&);
+  inline  GC        myGC() {if (mgc == 0) createmygc();  return(mgc); }  
+
+protected:
+  string   mStext;
+  PIMessage mSmsg;
+  list<PIMenu*> mPDMList;
+//  SysDWdg mLabel;
+  GC mgc;
+  void              createmygc();
+};
+
+
+typedef PIOptMenuX  PIOptMenu ;
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/piperiodmac.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piperiodmac.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piperiodmac.cc	(revision 2309)
@@ -0,0 +1,36 @@
+#include "piperiodmac.h"
+
+
+
+/* --Methode-- */
+PIPeriodMac::PIPeriodMac(int dt, UsPeriodicAction act, void * usp)
+: Periodic(dt, act, usp), mLastTick(-1)
+{
+}
+
+/* --Methode-- */
+PIPeriodMac::~PIPeriodMac()
+{
+}
+
+/* --Methode-- */
+void PIPeriodMac::Start(int dt)
+{
+  StartRepeating();
+  if (dt > 0)  { mDt = dt; mDtms = 1000*dt;}
+}
+
+/* --Methode-- */
+void PIPeriodMac::Stop()
+{
+  StopRepeating();
+}
+
+/* --Methode-- */
+void PIPeriodMac::SpendTime(const EventRecord&)
+{
+  long ticks = ::TickCount();
+  if ((ticks - mLastTick) * 1000. / 60. < mDtms) return;
+  mLastTick = ticks;
+  DoPeriodic();
+}
Index: /tags/V_Dec2002/SophyaPI/PI/piperiodmac.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piperiodmac.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piperiodmac.h	(revision 2309)
@@ -0,0 +1,22 @@
+// This may look like C code, but it is really -*- C++ -*-
+#ifndef PIPERIODMAC_H
+#define PIPERIODMAC_H
+
+#include "periodic.h"
+#include "LPeriodical.h"
+
+class PIPeriodMac : public Periodic, public LPeriodical {
+public:
+  PIPeriodMac(int dt, UsPeriodicAction act=NULL, void * usp=NULL);
+  ~PIPeriodMac();
+
+  virtual void Start(int dt=-1);
+  virtual void Stop();
+  virtual void SpendTime(const EventRecord&);
+protected:
+  long mLastTick;
+};
+
+typedef PIPeriodMac PIPeriodic;
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/piperiodx.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piperiodx.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piperiodx.cc	(revision 2309)
@@ -0,0 +1,81 @@
+// Module PI : Peida Interactive     PIPeriodX
+// Classe d'objets periodiques - X11 - R. Ansari 96-98
+// LAL (Orsay) / IN2P3-CNRS    DAPNIA/CEA (Saclay)      
+
+#include "piwdgx.h"
+#include "piperiodx.h"
+
+//++
+// Class	PIPeriodic
+// Lib		PI
+// include	piperiodx.h
+//
+//	Classe d'objets avec une méthode "DoPeriodic()" appelée périodiquement
+//	à intrevalle régulier. Implémentation de la classe "Periodic" compatible
+//	avec la boucle d'événements.
+//--
+//++
+// Links	Parents
+// Periodic
+//--
+
+//++
+// Titre	Constructeur
+//	Voir la classe "Periodic" pour les méthodes.
+//--
+//++
+//  Periodic(int dt, UsPeriodicAction act=NULL, void * usp=NULL)
+//	Constructeur avec un intervalle de temps en secondes "dt".
+//	Il est possible de spécifier une fonction "UsPeriodicAction" avec
+//	un argument "usp" qui sera appelée régulierement.
+//--
+
+/* Nouvelle-Fonction */
+static void xttimer_action(XtPointer usd, XtIntervalId * /*tid*/)
+{
+PIPeriodX * pip;
+XtIntervalId id;
+pip = (PIPeriodX *)usd;
+pip->DoPeriodic();
+int szx, szy, szf;
+XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
+id = XtAppAddTimeOut(*appctx, pip->Intervalms(), xttimer_action, pip);
+pip->SetTimerId(id);
+return;
+}
+
+
+/* --Methode-- */
+PIPeriodX::PIPeriodX(int dt, UsPeriodicAction act, void * usp)
+: Periodic(dt, act, usp)
+{
+}
+
+/* --Methode-- */
+PIPeriodX::~PIPeriodX()
+{
+if (mFgact) Stop();
+}
+
+/* --Methode-- */
+void PIPeriodX::Start(int dt)
+{
+if (mFgact) return;
+if (dt > 0)  { mDt = dt;  mDtms = dt*1000; }
+
+int szx,szy,szf;
+XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
+mTId = XtAppAddTimeOut(*appctx, Intervalms(), xttimer_action, this);
+mFgact = true;
+return;
+}
+
+void
+PIPeriodX::Stop()
+{
+if(mFgact)
+  XtRemoveTimeOut(mTId);
+mFgact = false;
+return;
+}
+
Index: /tags/V_Dec2002/SophyaPI/PI/piperiodx.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piperiodx.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piperiodx.h	(revision 2309)
@@ -0,0 +1,24 @@
+// This may look like C code, but it is really -*- C++ -*-
+#ifndef PIPERIODX_H
+#define PIPERIODX_H
+
+#include <X11/Intrinsic.h>
+#include "periodic.h"
+
+class PIPeriodX : public Periodic {
+public:
+  PIPeriodX(int dt, UsPeriodicAction act=NULL, void * usp=NULL);
+  virtual ~PIPeriodX();
+
+  virtual void Start(int dt=-1);
+  virtual void Stop();
+
+  inline void SetTimerId(XtIntervalId id) {mTId=id; }
+
+protected:
+XtIntervalId mTId;
+};
+
+typedef PIPeriodX PIPeriodic;
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pipixmapgen.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pipixmapgen.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pipixmapgen.cc	(revision 2309)
@@ -0,0 +1,155 @@
+// Module PI : Peida Interactive     PIPixmap
+// Classe de base pour affichage de pixmap  Reza 96
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "pipixmapgen.h"
+
+// --------- Methodes de la classe PIPixMap  ----------
+//++
+// Class	PIPixmap
+// Lib		PI
+// include	pipixmapgen.h
+//
+//   	Classe pour la gestion optimisée des pixmap.
+//	Un pixmap est un tableau d'index dans une table de couleurs.
+//	Cette classe gére actuellement des pixmaps avec des index
+//	codés sur 8 bits (256 couleurs).
+//	Pour des raisons d'optimisation, cette classe a une 
+//	implémentation spécifique pour chaque plateforme.
+//	La classe "PIPixmapGen" définit l'interface, et ne doit pas 
+//	être instanciée directement.  Les objets instanciés sont de la 
+//	classes "PIPixmap" et le fichier entête correspondant est "PIPIXMAP_H"
+//	défini dans "pisysdep.h".
+//--
+//++
+// Links	Parents
+// PIBaseWdg
+//--
+//++
+// Links	Voir aussi
+// PIColorMap
+//--
+
+//++
+// Titre	Constructeur, Pixmap
+//--
+//++
+// PIPixmapGen(PIContainerGen *par, const char *nom, int sx=10, int sy=10, int px=0, int py=0)
+//	Constructeur - Création d'un "PIPIxmap".
+// long  kind() 
+//	Retourne le type ("=PIPixmap::ClassId")
+// void  SetPixmap(unsigned char *pix, int sx, int sy, bool refr=true, int ox=0, int oy=0)
+//	Associe un tableau d'index "pix" de taille "sx * sy".
+//	(ox,oy)" définissent  l'offset d'affichage.
+//	Si "refr=true", la méthode "Refresh()" est appelée.
+//--
+//++
+// Titre	Gestion de la table de couleur
+//--
+//++
+// void  SetColMap(PIColorMap* cmp, bool refr=true)
+//	Change la table de couleur associée.
+//	Si "refr=true", la méthode "Refresh()" est appelée.
+// void  SetColMapId(CMapId cmapid, bool refr=true)
+//	Change la table de couleur associée, à l'aide d'un identificateur
+//	de table de couleur standard. ("CMapId cmapid").
+//	Si "refr=true", la méthode "Refresh()" est appelée.
+// PIColorMap* GetColMap()
+//	Retourne la table de couleur associée.
+// CMapId GetColMapId() 
+//	Retourne l'identificateur de la table de couleur associée.
+// int NbCol()
+//	Retourne le nombre de couleurs de la table de couleur associée.
+//--
+
+//++
+// Titre	Actions
+//--
+//++
+// void  But1Press(int x, int y)
+//	L'action sur le bouton 1 déclenche l'envoi d'un message
+//	avec le modifier PIMsg_Click. La position du bouton-press
+//	est stocké. (- Offset affichage)
+// int  XPPos() 
+//	Position X du click - Offset Affichage pixmap
+// int  YPPos() 
+//	Position Y du click - Offset Affichage pixmap
+//--
+
+/* --Methode-- */
+PIPixmapGen::PIPixmapGen(PIContainerGen  *par, const char *nom,
+                     int sx, int sy, int px, int py) :
+PIBaseWdg(par, nom, sx, sy, px, py)
+{
+pixmap = NULL;
+nx = ny = 0;
+ofx = ofy = 0;
+mPpos[0] = mPpos[0] = 0;
+cmap = new PIColorMap(CMAP_GREY32);
+ActivateButton(1);
+}
+
+
+/* --Methode-- */
+PIPixmapGen::~PIPixmapGen()
+{
+delete cmap;
+}
+
+/* --Methode-- */
+void PIPixmapGen::SetPixmap(unsigned char *pix, int sx, int sy, bool refr, int ox, int oy)
+{
+pixmap = pix; 
+if (pixmap)
+  {
+  if (sx < 0)  sx = 0;
+  if (sy < 0)  sy = 0;
+  if (ox < 0)  ox = 0;
+  if (oy < 0)  oy = 0;
+  nx = sx; ny = sy;
+  ofx = ox;  ofy = oy;
+  }
+else { ofx = ofy = nx = ny = 0; }
+if (refr) Refresh();   
+}
+
+/* --Methode-- */
+void PIPixmapGen::SetColMap(PIColorMap* cmp, bool refr)
+{
+if (!cmp)  return;
+if ( (cmp->Type() == cmap->Type()) && (cmp->Type() != CMAP_OTHER) 
+     && (cmp->IsColorIndexReversed() == cmap->IsColorIndexReversed()) ) return;
+if (cmap) delete cmap;
+cmap = new PIColorMap(*cmp);
+if (refr)  Refresh();  
+}
+
+/* --Methode-- */
+void PIPixmapGen::SetColMapId(CMapId cmapid, bool revidx, bool refr)
+{
+if (!cmap || (cmap->Type() != cmapid) || (cmapid == CMAP_OTHER) 
+    || (cmap->IsColorIndexReversed() != revidx) ) {  
+  if (cmap) delete cmap;
+  cmap = new PIColorMap(cmapid);
+  cmap->ReverseColorIndex(revidx);
+  }
+if (refr)  Refresh();  
+}
+
+
+/* --Methode-- */
+void  PIPixmapGen::But1Press(int x, int y)
+{
+mPpos[0] = x-ofx;  mPpos[1] = y-ofy;  
+if (Msg())  Send(Msg(), PIMsg_Click, mPpos);
+return;
+}
+
+
+
+// Fin des methodes de la classe 
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/pipixmapgen.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pipixmapgen.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pipixmapgen.h	(revision 2309)
@@ -0,0 +1,54 @@
+/* Fonctions interface XWindow pour affichage d'images */
+
+#ifndef PIPIXMAP_H_SEEN
+#define PIPIXMAP_H_SEEN
+
+#include "pisysdep.h"
+
+#include PIBWDG_H
+#include PICMAP_H
+
+#include <list>
+
+class PIPixmapGen : public PIBaseWdg
+{
+public:
+  enum {ClassId = 5100};
+
+                PIPixmapGen(PIContainerGen *par, const char *nom,
+                         int sx=10, int sy=10, int px=0, int py=0);
+  virtual       ~PIPixmapGen();
+
+  virtual long  kind() {return ClassId; }
+
+  virtual void  SetPixmap(unsigned char *pix, int sx, int sy, 
+                          bool refr=true, int ox=0, int oy=0);
+
+  virtual void  SetColMap(PIColorMap* cmp, bool refr=true);
+  virtual void  SetColMapId(CMapId cmapid, bool revidx, bool refr);
+  inline  void  SetColMapId(CMapId cmapid, bool refr=true)
+                { SetColMapId(cmapid, false, refr); }
+
+  inline PIColorMap* GetColMap() { return cmap; }
+  inline CMapId GetColMapId() { return ((CMapId)cmap->Type()); }; 
+  inline int    NbCol() { return(cmap->NCol()); };
+
+  virtual void  But1Press(int x, int y);
+  inline  int   XPPos() { return mPpos[0]; }
+  inline  int   YPPos() { return mPpos[1]; }
+
+protected:
+  unsigned char *pixmap;
+  int nx, ny;
+  int ofx, ofy;
+  PIColorMap* cmap;
+
+  int mPpos[2];
+};  
+  
+
+
+
+#endif   /* PIPIXMAP_H_SEEN */
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/pipixmapmac.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pipixmapmac.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pipixmapmac.cc	(revision 2309)
@@ -0,0 +1,102 @@
+#include "pipixmapmac.h"
+
+PIPixmapMac::PIPixmapMac(PIContainerGen *par, char *nom,
+                         int sx, int sy, int px, int py)
+: PIPixmapGen(par,nom,sx,sy,px,py), mGWorld(NULL)
+{}
+
+
+PIPixmapMac::~PIPixmapMac()
+{}
+
+
+/* --Methode-- */
+void PIPixmapMac::SetPixmap(unsigned char *pix, int sx, int sy, bool refr, int ox, int oy)
+{
+  if (nx != sx || ny != sy)
+    if (mGWorld) {
+      DisposeGWorld(mGWorld);
+      mGWorld = NULL;
+    }
+  PIPixmapGen::SetPixmap(pix, sx, sy, refr);
+}
+
+void
+PIPixmapMac::Resize()
+{
+  Refresh();
+}
+
+void
+PIPixmapMac::Refresh()
+{
+	PIPixmapGen::Refresh();
+}
+
+void
+PIPixmapMac::DrawOff()
+{
+  if (mGWorld) {
+    DisposeGWorld(mGWorld);
+    mGWorld = NULL;
+  }
+  
+  if (!cmap) return;
+  if (!pixmap) return;
+  if (nx == 0 || ny == 0) return;
+  
+  Rect	frame;
+  SetRect(&frame, 0, 0, XSize(), YSize());
+
+  
+  ThrowIfOSErr_(NewGWorld(&mGWorld, 8, &frame, cmap->mCTab, nil, 0));
+
+    // Lock down Pixels that we are drawing to so that memory will not
+	// move
+	::LockPixels (mGWorld->portPixMap);
+
+ 	// Draw
+	PixMapHandle	pMap;
+	unsigned char	*pixP;
+	
+	pMap = GetGWorldPixMap(mGWorld);
+	for (int y=frame.top; y<frame.bottom; y++) {
+		pixP = (unsigned char *) GetPixBaseAddr(pMap) + y * ((**pMap).rowBytes & 0x7FFF);
+		for(int x = frame.left ; x < frame.right ; x++)
+			pixP[x] = (x<nx && y<ny) ? pixmap[x + y*nx]+2 : 0;
+	}
+			
+	// Now unlock Pixels.
+	::UnlockPixels (mGWorld->portPixMap);
+	
+	mPane->FocusDraw();
+//	SetPalette(mPane->GetMacPort(),cmap->mPalette, true);
+//	PIPixmapGen::Refresh();
+}
+
+void
+PIPixmapMac::Draw(PIGraphic* g,int,int,int,int)
+{
+  Draw(g);
+}
+
+void
+PIPixmapMac::Draw(PIGraphic* g)
+{
+  DrawOff();
+  if (!mGWorld) return;
+  mPane->FocusDraw();
+  Rect	paneFrame;
+  mPane-> CalcLocalFrameRect(paneFrame);
+  Rect	offsFrame;
+  SetRect(&offsFrame, 0, 0, paneFrame.right-paneFrame.left, paneFrame.bottom-paneFrame.top);
+  ::LockPixels (mGWorld->portPixMap);
+  ::ForeColor (blackColor);
+  ::BackColor (whiteColor);
+  ::CopyBits((BitMap *) (*(GetGWorldPixMap(mGWorld))),
+				&mPane->GetMacPort()->portBits,
+				&offsFrame, &paneFrame, srcCopy, nil);
+  ::UnlockPixels (mGWorld->portPixMap);
+  DisposeGWorld(mGWorld);
+  mGWorld = 0;
+}
Index: /tags/V_Dec2002/SophyaPI/PI/pipixmapmac.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pipixmapmac.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pipixmapmac.h	(revision 2309)
@@ -0,0 +1,26 @@
+#ifndef PIPIXMAPMAC_H_SEEN
+#define PIPIXMAPMAC_H_SEEN
+
+#include "pipixmapgen.h"
+
+class PIPixmapMac : public PIPixmapGen {
+
+public:
+                PIPixmapMac(PIContainerGen *par, char *nom,
+                         int sx=10, int sy=10, int px=0, int py=0);
+  virtual      ~PIPixmapMac();
+
+  virtual void  SetPixmap(unsigned char *pix, int sx, int sy, bool refr=true, int ox=0, int oy=0);
+  virtual void  Draw(PIGraphic* g);
+  virtual void  Draw(PIGraphic* g, int x0, int y0, int dx, int dy);
+  virtual void	Refresh();
+  virtual void	DrawOff();
+  virtual void  Resize();
+protected:
+  GWorldPtr 	mGWorld;
+};
+
+typedef PIPixmapMac PIPixmap;
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pipixmapx.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pipixmapx.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pipixmapx.cc	(revision 2309)
@@ -0,0 +1,174 @@
+#include <stdio.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+
+#include "pipixmapx.h"
+
+static  GC    mygc;
+
+/* --Methode-- */
+PIPixmapX::PIPixmapX(PIContainerGen *par, const char *nom,
+                         int sx, int sy, int px, int py)
+: PIPixmapGen(par,nom,sx,sy,px,py) 
+{
+Init();
+AllocXImg();
+}
+
+
+/* --Methode-- */
+PIPixmapX::~PIPixmapX()
+{
+delete[] myximg->data;
+XFree(myximg); 
+}
+
+/* --Methode-- */
+void PIPixmapX::Refresh()
+{
+int i,j;
+unsigned char *pp;
+
+if (pixmap)
+  {
+  for(j=0; j<ny; j++)
+    {
+    pp = pixmap+j*nx;
+    for(i=0; i<nx; i++)
+      { XPutPixel(myximg, i, j, cmap->Color(*pp) );  pp++; }
+    }
+  }
+
+for(j=ny; j<YSize(); j++)
+  for(i=nx; i<XSize(); i++)
+     XPutPixel(myximg, i, j, 0 );
+
+PIBaseWdgX::Refresh();
+}
+
+
+/* --Methode-- */
+void PIPixmapX::Resize()
+{
+delete[] myximg->data;
+XFree(myximg); 
+AllocXImg();
+if (Msg())  Send(Msg(), PIMsg_Resize, mPpos);
+}
+
+/*DEL07 --Methode-- 
+void PIPixmapX::Draw(PIGraphicGen* g)
+{
+if (!pixmap)  return;
+if (!g) return; 
+if (g->kind() == PI_PSFileGraphics ) {
+    g->DrawPixmap(ofx, ofy, pixmap, nx, ny, cmap);
+    //  Il faut faire quelque chose Sinon ??! 
+  }
+else  Draw(g, 0, 0, XSize(), YSize());
+}
+*/
+
+/* --Methode-- */
+void PIPixmapX::Draw(PIGraphic* g, int x0, int y0, int dx, int dy)
+{
+
+if (!g) return; 
+if ((myximg == NULL) || (cmap == NULL)) return;
+
+if (g->kind() == PI_PSFileGraphics ) {
+  if (pixmap) g->DrawPixmap(ofx, ofy, pixmap, nx, ny, cmap);
+  return;
+  }
+
+Window xw = XtWindow(XtWdg());
+Display * mdsp = PIXDisplay();
+
+int mx, my, ox, oy;
+
+if (x0 < 0)  x0 = 0;
+if (y0 < 0)  y0 = 0;
+mx = nx+ofx;   my = ny+ofy;
+if (dx > (XSize()-x0)) dx = XSize()-x0;
+if (dy > (YSize()-y0)) dy = YSize()-y0;
+if ((dx <= 0) || (dy <= 0))  return;
+
+if ( (mx < x0 ) || (my < y0) )
+  { XClearArea(mdsp, xw, x0, y0, dx, dy, False);  return; }
+
+ox = oy = 0;  
+
+if (ofx > x0)
+  { XClearArea(mdsp, xw, x0, y0, ofx-x0, dy, False);   
+  dx -= (ofx-x0);  x0 = ofx;  ox = 0; }
+else  ox = x0-ofx;
+if (ofy > y0)
+  { XClearArea(mdsp, xw, x0, y0, dx, ofy-y0, False);  
+  dy -= (ofy-y0);  y0 = ofy;  oy = 0; }
+else  oy = y0-ofy;
+ 
+if (mx < (x0+dx))
+  { XClearArea(mdsp, xw, mx, y0, x0+dx-mx, dy, False);  dx = mx-x0; }
+if (my < (y0+dy))
+  { XClearArea(mdsp, xw, x0, my, dx, y0+dy-my, False);  dy = my-y0; }
+ 
+XPutImage(mdsp, xw, mygc, myximg, ox, oy, x0, y0, dx, dy);
+XFlush(mdsp);
+return;
+ 
+}
+
+static bool fgxpxm = false;
+
+
+/* --Methode-- */
+void PIPixmapX::Init()
+{
+XGCValues       values;
+XtGCMask        mask;
+
+if (fgxpxm)  return; 
+fgxpxm = true;
+
+
+mask = GCFunction | GCPlaneMask;
+// mask = GCForeground | GCBackground;
+values.function = GXcopy;
+values.plane_mask = ~0;
+// values.foreground = WhitePixel(mdsp, scr);
+// values.background = BlackPixel(mdsp, scr);
+mygc = XtGetGC(XtWdg(), mask, &values);
+
+return;
+}
+
+
+/* --Methode-- */
+void PIPixmapX::AllocXImg()
+{
+Display * mdsp;
+int scr;
+int depth;
+int pad;
+int i,j;
+
+mdsp = PIXDisplay();
+scr = PIXScreen();
+
+depth = DefaultDepth(mdsp,scr);
+pad = (depth > 8) ? 32 : 8;
+myximg = XCreateImage (mdsp,DefaultVisual(mdsp,scr),
+           depth,ZPixmap,0,NULL, XSize(), YSize(), pad,0);
+if (myximg == NULL)  return;
+myximg->data = new char [YSize()*myximg->bytes_per_line];
+if (myximg->data == NULL)  
+  { XFree(myximg); myximg = NULL;  return; } 
+
+for(j=0; j<YSize(); j++)
+  for(i=0; i<XSize(); i++)
+    XPutPixel(myximg, i, j, 0 );
+
+return;
+}
Index: /tags/V_Dec2002/SophyaPI/PI/pipixmapx.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pipixmapx.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pipixmapx.h	(revision 2309)
@@ -0,0 +1,27 @@
+#ifndef PIPIXMAPX_H_SEEN
+#define PIPIXMAPX_H_SEEN
+
+#include "pipixmapgen.h"
+
+class PIPixmapX : public PIPixmapGen {
+
+public:
+                PIPixmapX(PIContainerGen *par, const char *nom,
+                         int sx=10, int sy=10, int px=0, int py=0);
+  virtual      ~PIPixmapX();
+
+  virtual void  Refresh();
+  virtual void  Resize();
+  virtual void  Draw(PIGraphic* g, int x0, int y0, int dx, int dy);
+
+
+protected:
+  void          Init();
+  void          AllocXImg();
+  XImage * myximg;  
+};
+
+typedef PIPixmapX PIPixmap;
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pippapplmac.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pippapplmac.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pippapplmac.cc	(revision 2309)
@@ -0,0 +1,41 @@
+#include "pippapplmac.h"
+#include "piupdattachment.h"
+#include "pippmenubar.h"
+#include "pippwindowmac.h"
+#include <LClipboard.h>
+
+PIPPApplMac::PIPPApplMac()
+:LApplication()
+{
+  RegisterClass_(PIPPWindowMac);
+  AddAttachment(new LClipboard);
+}
+
+
+PIPPApplMac::~PIPPApplMac()
+{}
+
+void
+PIPPApplMac::AdjustCursor(const EventRecord &inMacEvent)
+{
+  PIUpdAttachment::hit = false;
+  LApplication::AdjustCursor(inMacEvent);
+  if (!PIUpdAttachment::hit) {
+    if (PIUpdAttachment::lastCursPane)
+       PIUpdAttachment::lastCursPane->myWdg->Leave();
+    PIUpdAttachment::lastCursPane = NULL;
+  }   
+}
+
+void
+PIPPApplMac::MakeMenuBar()
+{
+	//new PIPPMenuBar();
+}
+
+
+
+// $CHECK$
+// Gerer AllowSubRemoval, qui envoie un evenement a l'application PI.
+// Eventuellement avoir des fenetres qui se cachent lors d'un close et d'autres
+// qui se detruisent ??
Index: /tags/V_Dec2002/SophyaPI/PI/pippapplmac.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pippapplmac.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pippapplmac.h	(revision 2309)
@@ -0,0 +1,11 @@
+#include <LApplication.h>
+
+class PIPPApplMac : public LApplication {
+public:
+						PIPPApplMac();
+	virtual				~PIPPApplMac();
+
+	void MakeMenuBar();
+	virtual void			AdjustCursor	(const EventRecord &inMacEvent);
+};
+
Index: /tags/V_Dec2002/SophyaPI/PI/pipplist.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pipplist.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pipplist.cc	(revision 2309)
@@ -0,0 +1,198 @@
+#include "pipplist.h"
+#include <LTableMonoGeometry.h>
+#include <LTableSingleSelector.h>
+#include <LTableMultiSelector.h>
+#include <LTableArrayStorage.h>
+#include <LComparator.h>
+
+class CellMsgComparator : public LComparator {
+public:
+	virtual Int32		Compare(
+								const void*			inItemOne,
+								const void* 		inItemTwo,
+								Uint32				/*inSizeOne*/,
+								Uint32				/*inSizeTwo*/) const
+	{return ((PIPPListCell*)inItemOne)->msg == ((PIPPListCell*)inItemTwo)->msg;}
+};
+
+static CellMsgComparator cellMsgComparator;
+
+class CellStrComparator : public LComparator {
+public:
+	virtual Int32		Compare(
+								const void*			inItemOne,
+								const void* 		inItemTwo,
+								Uint32				/*inSizeOne*/,
+								Uint32				/*inSizeTwo*/) const
+	{return ((PIPPListCell*)inItemOne)->str == ((PIPPListCell*)inItemTwo)->str;}
+};
+
+static CellStrComparator cellStrComparator;
+
+
+PIPPList::PIPPList(PIMsgHandler* h)
+: mHndl(h)
+{
+  InitPPList();
+}
+
+PIPPList::PIPPList(
+    const SPaneInfo& inPaneInfo,
+    const SViewInfo& inViewInfo,
+    PIMsgHandler* h)
+: LTableView(inPaneInfo, inViewInfo), mHndl(h)
+{
+  InitPPList();
+}
+
+void PIPPList::InitPPList()
+{
+  SetTableGeometry(new LTableMonoGeometry(this, 10, 16));
+  SetTableSelector(tss=new LTableSingleSelector(this)); 
+  mArray = new LArray(sizeof(PIPPListCell)),
+  SetTableStorage(new LTableArrayStorage(this, mArray));
+  tms = new LTableMultiSelector(this);
+  LTableView::InsertCols(1, 0, nil, 0, Refresh_No);
+}
+
+PIPPList::~PIPPList()
+{
+  SetTableSelector(nil);
+  delete tss;
+  delete tms;
+}
+
+
+void PIPPList::AppendItem(string const& str, PIMessage msg)
+{
+  PIPPListCell cell;
+  cell.str=str;
+  cell.msg=msg;
+  InsertRows(1, -1, &cell, sizeof(cell), Refresh_Yes);
+}
+
+STableCell PIPPList::FindStr(string const& str)
+{
+  PIPPListCell cell;
+  cell.str = str;
+  cell.msg = 0;
+  mArray->SetComparator(&cellStrComparator);
+  STableCell tcell;
+  FindCellData(tcell, &cell, sizeof(cell));
+  return tcell;
+}
+
+STableCell PIPPList::FindMsg(PIMessage msg)
+{
+  PIPPListCell cell;
+  cell.str = "";
+  cell.msg = msg;
+  mArray->SetComparator(&cellMsgComparator);
+  STableCell tcell;
+  FindCellData(tcell, &cell, sizeof(cell));
+  return tcell;
+}
+
+void PIPPList::DeleteItem(string const& str)
+{
+  STableCell tcell = FindStr(str);
+  RemoveRows(1, tcell.row, Refresh_Yes);
+}
+
+void PIPPList::DeleteItem(PIMessage msg)
+{
+  STableCell tcell = FindMsg(msg);
+  RemoveRows(1, tcell.row, Refresh_Yes);
+}
+
+
+void PIPPList::SetMultipleSelect(bool ms);
+  
+int PIPPList::GetNbSel()
+{
+  int n = 0;
+  for (TableIndexT j=1; j<=mRows; j++) {
+    STableCell cell;
+    cell.row = j;
+    cell.col = 1;
+    if (CellIsSelected(cell)) n++;
+  }
+  return n; 
+}
+
+PIMessage PIPPList::GetSelMsg(int i)
+{
+  int n = 0;
+  for (TableIndexT j=1; j<=mRows; j++) {
+    STableCell cell;
+    cell.row = j;
+    cell.col = 1;
+    if (CellIsSelected(cell)) n++;
+    if (n == i) {
+       PIPPListCell ppcell;
+       UInt32 sz = sizeof(ppcell);
+       GetCellData(cell, &ppcell, sz);
+       return ppcell.msg;
+    }
+  }
+  return 0; 
+}
+
+string PIPPList::GetSelStr(int i)
+{
+  int n = 0;
+  for (TableIndexT j=1; j<=mRows; j++) {
+    STableCell cell;
+    cell.row = j;
+    cell.col = 1;
+    if (CellIsSelected(cell)) n++;
+    if (n == i) {
+       PIPPListCell ppcell;
+       UInt32 sz = sizeof(ppcell);
+       GetCellData(cell, &ppcell, sz);
+       return ppcell.str;
+    }
+  }
+  return ""; 
+}
+void PIPPList::SelectItem(string const& str)
+{
+  STableCell cell = FindStr(str);
+  SelectCell(cell);
+}
+
+void PIPPList::SelectItem(PIMessage msg)
+{
+  STableCell cell = FindMsg(msg);
+  SelectCell(cell);
+}
+
+void PIPPList::ClearSelItem(string const& str)
+{
+  STableCell cell = FindStr(str);
+  UnselectCell(cell);
+}
+
+void PIPPList::ClearSelItem(PIMessage msg)
+{
+  STableCell cell = FindMsg(msg);
+  UnselectCell(cell);
+}
+
+void PIPPList::SetMultipleSelect(bool ms)
+{
+  if (ms)
+    SetTableSelector(tms);
+  else
+    SetTableSelector(tss); 
+}
+
+void
+PIPPList::ClickCell(
+	const STableCell&		inCell,
+	const SMouseDownEvent&	inMouseDown)
+{
+  if (GetClickCount() == 2) {
+	
+  }
+}
Index: /tags/V_Dec2002/SophyaPI/PI/pipplist.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pipplist.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pipplist.h	(revision 2309)
@@ -0,0 +1,52 @@
+#pragma once
+
+#include <string>
+#include <LTableView.h>
+#include "pimsghandler.h"
+
+class LArray;
+
+struct PIPPListCell {
+   string 	   str;
+   PIMessage   msg;
+};
+
+class PIPPList : public LTableView {
+public:
+
+  PIPPList(PIMsgHandler* hndl);
+  PIPPList(
+    const SPaneInfo& inPaneInfo,
+    const SViewInfo& inViewInfo,
+    PIMsgHandler* hndl);
+  virtual ~PIPPList();
+
+  void       AppendItem(string const& str, PIMessage msg);
+  void       DeleteItem(string const& str);
+  void       DeleteItem(PIMessage msg);  
+
+  void       SetMultipleSelect(bool ms);
+  
+  int        GetNbSel();
+  PIMessage  GetSelMsg(int i);
+  string     GetSelStr(int i);
+  
+  void       SelectItem(string const& str);
+  void       SelectItem(PIMessage msg);
+  void       ClearSelItem(string const& str);
+  void       ClearSelItem(PIMessage msg);
+  
+protected:
+  LTableSelector* tss;
+  LTableSelector* tms;
+  LArray*         mArray;
+  PIMsgHandler*   mHndl;
+
+  virtual void    ClickCell(
+                       const STableCell        &inCell,
+                       const SMouseDownEvent   &inMouseDown);
+
+  void InitPPList();
+  STableCell  FindMsg(PIMessage msg);
+  STableCell  FindStr(string const& str);
+};
Index: /tags/V_Dec2002/SophyaPI/PI/pippmenubar.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pippmenubar.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pippmenubar.cc	(revision 2309)
@@ -0,0 +1,44 @@
+#include "pippmenubar.h"
+
+PIPPMenuBar::PIPPMenuBar()
+: LMenuBar(MBAR_Initial)
+{
+
+}
+
+PIPPMenuBar::~PIPPMenuBar()
+{}
+
+CommandT
+PIPPMenuBar::MenuCommandSelection(
+	const EventRecord	&inMouseEvent,
+	Int32				&outMenuChoice) const
+{
+	outMenuChoice = ::MenuSelect(inMouseEvent.where);
+	
+	int menuId = HiWord(outMenuChoice);
+	int menuItem = LoWord(outMenuChoice)-1; // Dans PI les menu items commencent a 0
+	
+	PIMenuMac* menu = PIMenuMac::GetMenu(menuId);
+	if (menu)
+	  menu->ItemSelected(menuItem);
+	
+	return cmd_Nothing;
+}
+
+CommandT
+PIPPMenuBar::FindKeyCommand(
+	const EventRecord	&inKeyEvent,
+	Int32				&outMenuChoice) const
+{
+	char	theChar = inKeyEvent.message & charCodeMask;
+	outMenuChoice = ::MenuKey(theChar);
+	int menuId = HiWord(outMenuChoice);
+	int menuItem = LoWord(outMenuChoice)-1; // Dans PI les menu items commencent a 0
+	
+	PIMenuMac* menu = PIMenuMac::GetMenu(menuId);
+	if (menu)
+	  menu->ItemSelected(menuItem);
+	
+	return cmd_Nothing;
+}
Index: /tags/V_Dec2002/SophyaPI/PI/pippmenubar.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pippmenubar.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pippmenubar.h	(revision 2309)
@@ -0,0 +1,21 @@
+#ifndef PIPPMENUBAR_H_SEEN
+#define PIPPMENUBAR_H_SEEN
+
+#include <LMenuBar.h>
+#include "pimenumac.h"
+
+class PIPPMenuBar : public LMenuBar {
+public:
+                           PIPPMenuBar();
+                          ~PIPPMenuBar();
+
+	virtual CommandT	   MenuCommandSelection(const EventRecord &inMouseEvent,
+								Int32 &outMenuChoice) const;
+
+	virtual CommandT	FindKeyCommand(
+								const EventRecord	&inKeyEvent,
+								Int32				&outMenuChoice) const;
+};
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pippoptmenu.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pippoptmenu.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pippoptmenu.cc	(revision 2309)
@@ -0,0 +1,67 @@
+#include "pippoptmenu.h"
+
+PIPPOptMenu::PIPPOptMenu(
+	const SPaneInfo	&inPaneInfo,
+	MessageT		inValueMessage,
+	Int16			inTitleOptions,
+	ResIDT			inMENUid,
+	Int16			inTitleWidth,
+	Int16			inPopupVariation,
+	ResIDT			inTextTraitsID,
+	Str255			inTitle,
+	OSType			inResTypeMENU,
+	Int16			inInitialMenuItem)
+		: LStdPopupMenu(inPaneInfo, inValueMessage, inTitleOptions,
+				inMENUid, inTitleWidth, inPopupVariation, inTextTraitsID,
+				inTitle, inResTypeMENU, inInitialMenuItem)
+{
+}
+
+
+
+PIPPOptMenu::PIPPOptMenu(
+	const SPaneInfo	&inPaneInfo,
+	MessageT		inValueMessage,
+	Int32			inMaxValue,
+	ResIDT			inTextTraitsID,
+	ControlHandle	inMacControlH)
+		: LStdPopupMenu(inPaneInfo, inValueMessage, inMaxValue,
+						inTextTraitsID, inMacControlH)
+{
+}
+
+
+
+PIPPOptMenu::PIPPOptMenu(
+	LStream	*inStream)
+		: LStdPopupMenu(inStream)
+{	
+}
+
+void
+PIPPOptMenu::HotSpotResult(
+	Int16	inHotSpot)
+{
+		BroadcastMessage(msg_ThumbDragged, (void*) this);
+}
+
+void
+PIPPOptMenu::SetMenu(PIMenu* pdm)
+{
+  // On va changer la resource de menu au passage...
+  InsertMenu(pdm->GetMacMenuHandle(), hierMenu);
+  PopupPrivateDataHandle	dataH =
+		(PopupPrivateDataHandle) (**GetMacControl()).contrlData;
+  (**dataH).mHandle = pdm->GetMacMenuHandle();
+  (**dataH).mID = pdm->GetMacMenuID();
+  
+  //InitStdPopupMenu(1);
+  
+  mValue = 1;
+  mMinValue = 1;
+  mMaxValue = ::CountMItems(pdm->GetMacMenuHandle());
+
+  ::SetControlValue(mMacControlH, mValue);
+  ::SetControlMinimum(mMacControlH, mMinValue);
+  ::SetControlMaximum(mMacControlH, mMaxValue);
+}
Index: /tags/V_Dec2002/SophyaPI/PI/pippoptmenu.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pippoptmenu.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pippoptmenu.h	(revision 2309)
@@ -0,0 +1,36 @@
+#include "LStdControl.h"
+#include "pisysdep.h"
+#include PIMENU_H
+
+// Redefinir HotSpotResult pour envoyer un message au PIOptMenuMac (qui est un listener)
+// qui va envoyer une action.
+
+class PIPPOptMenu : public LStdPopupMenu {
+public:
+	enum { class_ID = 'PPop' };
+					PIPPOptMenu(
+							const SPaneInfo		&inPaneInfo,
+							MessageT			inValueMessage,
+							Int16				inTitleOptions,
+							ResIDT				inMENUid,
+							Int16				inTitleWidth,
+							Int16				inPopupVariation,
+							ResIDT				inTextTraitsID,
+							Str255				inTitle,
+							OSType				inResTypeMENU,
+							Int16				inInitialMenuItem);
+					PIPPOptMenu(
+							const SPaneInfo		&inPaneInfo,
+							MessageT			inValueMessage,
+							Int32				inMaxValue,
+							ResIDT				inTextTraitsID,
+							ControlHandle		inMacControlH);
+					PIPPOptMenu(
+							LStream				*inStream);
+							
+					void SetMenu(PIMenu* pdm);
+protected:
+	virtual void		HotSpotResult(
+								Int16			inHotSpot);
+
+};
Index: /tags/V_Dec2002/SophyaPI/PI/pippviewadapter.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pippviewadapter.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pippviewadapter.cc	(revision 2309)
@@ -0,0 +1,128 @@
+#include "pippviewadapter.h"
+#include "piupdattachment.h"
+
+
+PIPPViewAdapter::PIPPViewAdapter()	
+:LView()
+{
+	::SetRect(&piBindings, 0, 0, 0, 0);
+}
+
+PIPPViewAdapter::PIPPViewAdapter(	
+	const PIPPViewAdapter& inOriginal)
+:LView(inOriginal)
+{
+	::SetRect(&piBindings, 0, 0, 0, 0);
+}
+PIPPViewAdapter::PIPPViewAdapter(
+	const SPaneInfo		&inPaneInfo,
+	const SViewInfo		&inViewInfo)
+:LView(inPaneInfo, inViewInfo)
+{
+	::SetRect(&piBindings, 0, 0, 0, 0);
+}
+
+void PIPPViewAdapter::SetBinding(PIBindingKind left, PIBindingKind top, 
+                                  PIBindingKind right, PIBindingKind bottom)
+{
+  piBindings.left   = left;
+  piBindings.right  = right;
+  piBindings.top    = top;
+  piBindings.bottom = bottom;
+}
+
+bool PIPPViewAdapter::GetBinding(PIBindingKind& left, PIBindingKind& top, 
+                                  PIBindingKind& right, PIBindingKind& bottom)
+{
+  left   = (PIBindingKind)piBindings.left;
+  right  = (PIBindingKind)piBindings.right;
+  top    = (PIBindingKind)piBindings.top;
+  bottom = (PIBindingKind)piBindings.bottom;
+  
+  return false;
+}
+
+
+void PIPPViewAdapter::AdaptToSuperFrameSize(
+	Int32				inSurrWidthDelta,
+	Int32				inSurrHeightDelta,
+	Boolean				inRefresh)
+{
+  SDimension16 parSize;
+  GetSuperView()->GetFrameSize(parSize);
+  
+  SDimension16 oldParSize = parSize;
+  oldParSize.width -= inSurrWidthDelta;
+  oldParSize.height -= inSurrHeightDelta;
+  
+  SPoint32 myLoc;
+  GetFrameLocation(myLoc);
+  SPoint32	superImageLoc = {0, 0};
+	
+  if (mSuperView != nil) {
+    mSuperView->GetImageLocation(superImageLoc);
+  }
+  myLoc.h -= superImageLoc.h;
+  myLoc.v -= superImageLoc.v;
+  
+  SDimension16 mySize;
+  GetFrameSize(mySize);
+    
+  SPoint32 myXLoc = myLoc;
+  myXLoc.h += mySize.width;
+  myXLoc.v += mySize.height;
+  
+  if (piBindings.left == PIBK_elastic) {
+     myLoc.h = parSize.width * ((float)myLoc.h / (float)oldParSize.width);
+  }
+ 
+  if (piBindings.top == PIBK_elastic) {
+     myLoc.v = parSize.height * ((float)myLoc.v / (float)oldParSize.height);
+  }
+  
+  if (piBindings.right == PIBK_fixed) {
+     myXLoc.h += inSurrWidthDelta;
+  } else
+  if (piBindings.right == PIBK_elastic) {
+     myXLoc.h = parSize.width * ((float)myXLoc.h / (float)oldParSize.width);
+  }  
+ 
+  if (piBindings.bottom == PIBK_fixed) {
+     myXLoc.v += inSurrHeightDelta;
+  } else
+  if (piBindings.bottom == PIBK_elastic) {
+     myXLoc.v = parSize.height * ((float)myXLoc.v / (float)oldParSize.height);
+  }
+  
+  
+  if (piBindings.left == PIBK_free) {
+    myLoc.h = myXLoc.h - mySize.width;
+  }   
+  if (piBindings.top == PIBK_free) {
+    myLoc.v = myXLoc.v - mySize.height;
+  }   
+  if (piBindings.right == PIBK_free) {
+    myXLoc.h = myLoc.h + mySize.width;
+  }   
+  if (piBindings.bottom == PIBK_free) {
+    myXLoc.v = myLoc.v + mySize.height;
+  }
+  
+  mySize.width = myXLoc.h - myLoc.h;
+  mySize.height = myXLoc.v - myLoc.v;
+  
+  ResizeFrameTo(mySize.width, mySize.height, inRefresh);
+  ResizeFrameTo(mySize.width, mySize.height, inRefresh);
+  PlaceInSuperImageAt(myLoc.h, myLoc.v, inRefresh);
+}
+
+void
+PIPPViewAdapter::ResizeFrameBy(
+	Int16		inWidthDelta,
+	Int16		inHeightDelta,
+	Boolean		inRefresh)
+{
+  LView::ResizeFrameBy(inWidthDelta,inHeightDelta,inRefresh);
+  ExecuteAttachments(msg_Resize, NULL);
+}
+
Index: /tags/V_Dec2002/SophyaPI/PI/pippviewadapter.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pippviewadapter.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pippviewadapter.h	(revision 2309)
@@ -0,0 +1,30 @@
+#pragma once
+
+#include <LView.h>
+#include "piwdggen.h"
+
+class PIPPViewAdapter : public LView {
+public:
+						PIPPViewAdapter();
+						PIPPViewAdapter(	
+								const PIPPViewAdapter	&inOriginal);
+						PIPPViewAdapter(
+								const SPaneInfo		&inPaneInfo,
+								const SViewInfo		&inViewInfo);
+
+	virtual void        SetBinding(PIBindingKind left, PIBindingKind top, 
+                                   PIBindingKind right, PIBindingKind bottom);
+	bool                GetBinding(PIBindingKind& left, PIBindingKind& top, 
+                                   PIBindingKind& right, PIBindingKind& bottom);
+	virtual void		AdaptToSuperFrameSize(
+								Int32				inSurrWidthDelta,
+								Int32				inSurrHeightDelta,
+								Boolean				inRefresh);
+	virtual void		ResizeFrameBy(
+								Int16				inWidthDelta,
+								Int16				inHeightDelta,
+								Boolean				inRefresh);
+								
+protected:
+	Rect				piBindings;
+};
Index: /tags/V_Dec2002/SophyaPI/PI/pippwindowmac.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pippwindowmac.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pippwindowmac.cc	(revision 2309)
@@ -0,0 +1,107 @@
+#include "pippwindowmac.h"
+
+
+// ---------------------------------------------------------------------------
+//		¥ PIPPWindowMac
+// ---------------------------------------------------------------------------
+//	Default Constructor
+
+PIPPWindowMac::PIPPWindowMac()
+{
+  myPIWindow = NULL;
+}
+
+
+// ---------------------------------------------------------------------------
+//		¥ PIPPWindowMac(SWindowInfo&)
+// ---------------------------------------------------------------------------
+//	Construct Window from the data in a struct
+
+PIPPWindowMac::PIPPWindowMac(
+	const SWindowInfo	&inWindowInfo)
+:LWindow(inWindowInfo)
+{
+  myPIWindow = NULL;
+}
+
+
+// ---------------------------------------------------------------------------
+//		¥ PIPPWindowMac(ResIDT, Uint32, LCommander*)
+// ---------------------------------------------------------------------------
+//	Construct a Window from a WIND Resource with the specified attributes
+//	and SuperCommander
+
+PIPPWindowMac::PIPPWindowMac(
+	ResIDT		inWINDid,
+	Uint32		inAttributes,
+	LCommander	*inSuperCommander)
+:LWindow(inWINDid, inAttributes, inSuperCommander)
+{
+  myPIWindow = NULL;
+}
+
+
+// ---------------------------------------------------------------------------
+//		¥ PIPPWindowMac
+// ---------------------------------------------------------------------------
+//	Construct a Window from input parameters
+
+PIPPWindowMac::PIPPWindowMac(
+	LCommander		*inSuperCommander,
+	const Rect		&inGlobalBounds,
+	ConstStringPtr	inTitle,
+	Int16			inProcID,
+	Uint32			inAttributes,
+	WindowPtr		inBehind,
+	void			*inStorage)
+:LWindow(inSuperCommander, inGlobalBounds, inTitle,
+inProcID, inAttributes, inBehind, inStorage)
+{
+  myPIWindow = NULL;
+}
+
+
+// ---------------------------------------------------------------------------
+//		¥ PIPPWindowMac(LStream*)
+// ---------------------------------------------------------------------------
+//	Construct Window from the data in a stream
+
+PIPPWindowMac::PIPPWindowMac(
+	LStream	*inStream)
+:LWindow(inStream)
+{
+  myPIWindow = NULL;
+}
+
+
+// ---------------------------------------------------------------------------
+//		¥ ~PIPPWindowMac
+// ---------------------------------------------------------------------------
+//	Destructor
+
+PIPPWindowMac::~PIPPWindowMac()
+{
+}
+
+void
+PIPPWindowMac::AttemptClose()
+{
+  myPIWindow->Process(myPIWindow->BuildMsg(myPIWindow->Msg(),PIMsg_Close), myPIWindow, NULL) ;
+}
+
+
+const MessageT	msg_Resize			= 817;
+const MessageT	msg_Move			= 818;
+
+void PIPPWindowMac::DoSetPosition(Point inPosition)
+{
+    ExecuteAttachments(msg_Move, NULL);
+    LWindow::DoSetPosition(inPosition);
+}
+
+void PIPPWindowMac::DoSetBounds(const Rect &inBounds)
+{
+    ExecuteAttachments(msg_Resize, NULL);
+    LWindow::DoSetBounds(inBounds);
+}
+
Index: /tags/V_Dec2002/SophyaPI/PI/pippwindowmac.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pippwindowmac.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pippwindowmac.h	(revision 2309)
@@ -0,0 +1,37 @@
+#include <LWindow.h>
+#include "piwindowmac.h"
+
+class PIPPWindowMac : public LWindow {
+public:
+	enum { class_ID = 'pwin' };
+	
+						PIPPWindowMac();
+						PIPPWindowMac(
+								const SWindowInfo	&inWindowInfo);
+						PIPPWindowMac(
+								ResIDT				inWINDid,
+								Uint32				inAttributes,
+								LCommander			*inSuperCommander);
+								
+						PIPPWindowMac(
+								LCommander			*inSuperCommander,
+								const Rect			&inGlobalBounds,
+								ConstStringPtr		inTitle,
+								Int16				inProcID,
+								Uint32				inAttributes,
+								WindowPtr			inBehind,
+								void				*inStorage = nil);
+								
+						PIPPWindowMac(
+								LStream				*inStream);
+	virtual				~PIPPWindowMac();
+
+	virtual void		DoSetPosition(
+								Point				inPosition);
+	virtual void		DoSetBounds(
+								const Rect			&inBounds);
+								
+	virtual void		AttemptClose();
+								
+	PIWindow* myPIWindow;
+};
Index: /tags/V_Dec2002/SophyaPI/PI/piscdrawwdg.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piscdrawwdg.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piscdrawwdg.cc	(revision 2309)
@@ -0,0 +1,672 @@
+// Module PI : Peida Interactive     PIScDrawWdg
+// Gestionnaire Drawer-2D  E.Aubourg, R. Ansari  96-98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "machdefs.h"
+#include <math.h>
+#include <iostream.h>
+
+#include "piscdrawwdg.h"
+#include "pidrwtools.h"
+#include "piaxes.h"
+#include "piaxestools.h"
+
+#define PETIT_DBLE 1.e-100
+#define PREC_DBLE  1.e-16
+
+
+//++
+// Class	PIScDrawWdg
+// Lib		PI
+// include	piscdrawwdg.h
+//
+//   	Classe pour la l'affichage et la manipulation d'un ensemble
+//	de *Drawer* avec la gestion de zoom (agrandissement).
+//	* Bouton-1 : Envoie le message "PIMsg_Active" et affiche
+//	les coordonnées courantes (User-Coordinates)
+//	* Bouton-2 : Permet de définir un rectangle pour le zoom.
+//	* Bouton-3 : Permet de définir un rectangle pour le texte info.
+//
+//	Gestion du clavier :
+//	* <Alt>O : Active/Affiche les  contrôles de paramètres spécifiques 
+//	(Par défaut, action identique à <Alt>G)
+//	* <Alt>G : Affichage de la fenêtre de changement des attributs graphiques
+//	* <Alt>R : Rafraîchit l'affichage.
+//	* <Alt>M : Active/Désactive l'affichage d'une réticule de mesure (Bouton-1)
+//	* <Alt>V : Copier/*Coller* Ajout du texte du buffer copier/coller
+//	sur l'objet à la position courante.
+//	* <Alt>I : Affiche et met a jour la fenetre Texte-Info .
+//	* <Alt>Z : Supprime les élément graphiques ajoutés au dessin.
+//	* <Alt>E : Supprime le dernier élément graphique ajouté.
+//      * <Alt>P : fenetre des options de drawing des contours 
+//--
+//++
+// Links	Parents
+// PIBaseWdg
+//--
+//++
+// Links	Voir aussi
+// PIDrawer
+//--
+
+static inline void dbl_swap(double& a, double& b) { double tmp = a; a = b; b = tmp;  } 
+
+//++
+// Titre	Constructeurs, méthodes
+//	Seule les méthodes les plus usuelles sont décrites ici. Se reporter
+//	au fichier .h pour la liste complete des méthodes
+//--
+//++
+//  PIScDrawWdg(PIContainerGen *par, const char *nom, int sx=100, int sy=100, int px=0, int py=0)
+//	Constructeur. Contient uniquement le traceur de base, responsable du tracé
+//	des axes et des éléments ajoutés (textes, ...)
+// long  kind()
+//	Renvoie le type ("=PIScDrawWdg::ClassId")
+// void SetLimits(double xmin, double xmax, double ymin, double ymax, -
+//           int axrl=kAxeDirSame, int ayud=kAxeDirSame, bool tmp=false)
+//	Définit les limites de coordonnées.
+// void	 UpdateLimits()
+//	Recalcule les limites de coordonnées à partir du premier Drawer.
+// void  SetAxesFlags(unsigned int flags=kAxesDflt)
+//	Définit les attributs des axes.
+// int  AddScDrawer(PIDrawer*, bool ad=false)
+//	Ajoute un Drawer.
+//--
+
+
+PIScDrawWdg::PIScDrawWdg(PIContainerGen *par, const char *nom,
+                         int sx, int sy, int px, int py)
+:PIBaseWdg(par, nom, sx, sy, px, py)
+{
+  mFgReticule = false;
+  mCPosX = mCPosY = 0;
+  mPPos[0] = mPPos[1] = 0.;
+  mPSz[0] = mPSz[1] = 0.;
+  mFormatOpt[0] = "%-g"; mFormatOpt[1] = "%-g";
+  mFgDeltaPos = false;
+  mPosForDelta[0] = mPosForDelta[1] = 0.;
+  mPosFDX = mPosFDY = 0;
+
+  mBDrw = new PIElDrawer(false);
+  mBDrw->SetName("AxesDrw");
+  SetLimits(-1.,1.,-1.,1.,kAxeDirLtoR,kAxeDirDownUp);
+  // SetDefaultDrawRectangle(0.12, 0.12, 0.88, 0.88, true); fait par SetAxesFlags() - Reza Mai 2002
+  SetAxesFlags(kBoxAxes | kExtTicks | kLabels);  
+  FreeLimits();
+  xEndDrag = yEndDrag = xBegDrag = yBegDrag = 0;
+  AddDrawer(mBDrw, true, false, false);
+
+//  Pour afficher les coordonnees courante (click-bouton-1)  
+  mTrlb = mTxw = NULL;
+  mTrW = NULL;
+  SetTextWin(NULL);
+
+//  Affichage eventuelle d'infos-texte
+  mInfoW = NULL;
+  mInfoTxt = NULL;
+
+  ActivateKeyboard();
+  ActivateButton(1);    // Pour pouvoir activer la fenetre et coordonnees
+  ActivateMove(1);      //    "         "         "        "
+  ActivateButton(2);    //  Pour gerer le zoom
+  ActivateMove(2);      //    "         "
+  ActivateButton(3);    //  Pour definir la zone info-texte
+  ActivateMove(3);      //    "         "
+
+}
+
+PIScDrawWdg::~PIScDrawWdg()
+{
+  delete mBDrw;
+  if (mTrW)  delete mTrW;
+  if (mInfoW) delete mInfoW;
+  if (PIAxesTools::GetCurrentScDrawWdg() == this) 
+    PIAxesTools::SetCurrentScDrawWdg(NULL);
+  // Pour PIDrwTools, c'est fait par le destructeur de PIBaseWdgGen
+}
+
+void PIScDrawWdg::Keyboard(int key, PIKeyModifier kmod)
+{
+if (kmod == PIKM_Alt) {
+  if      (key == 'R' || key == 'r')  Refresh(); // rafraichir l'affichage
+  else if (key == 'M' || key == 'm') mFgReticule = !mFgReticule; // reticule de mesure 
+  else if (key == 'K' || key == 'k') UpdatePosForDeltaMarker(true);
+  else if (key == 'L' || key == 'l') UpdatePosForDeltaMarker(false);
+  else if (key == 'V' || key == 'v') RequestSelection();  // Pour coller (copier/coller)  
+  else if (key == 'Z' || key == 'z') { mBDrw->ElDelAll();  Refresh(); } // Pour supprimer tous les signes 
+  else if (key == 'E' || key == 'e') { mBDrw->ElDelLast();  Refresh(); } // Pour supprimer le dernier element ajoute
+  else if (key == 'O' || key == 'o') { // fenetre des options de controle du drawer actif
+    PIDrawer* actdrw = GetActiveDrawer();
+    if (actdrw != NULL) actdrw->ShowControlWindow(this);
+  }
+  else if (key == 'G' || key == 'g') // Fenetre des options graphiques de trace
+    PIDrwTools::ShowPIDrwTools(this);   
+  
+  else if (key == 'A' || key == 'a') { 
+    PIAxesTools::SetCurrentScDrawWdg(this);
+    PIAxesTools::ShowPIAxesTools();  // Fenetre de gestion des axes
+  }
+  
+  else if (key == 'I' || key == 'i') UpdateInfoWindow();  // Fenetre Text-Info 
+  }
+}
+void 
+PIScDrawWdg::PasteSelection(unsigned int typ, void *pdata, unsigned int l)
+{
+if (typ != PICP_string) return;
+int ll = (l<256) ? l+1 : 256;
+char pc[256];
+strncpy(pc, (char*)pdata, ll-1);  pc[ll-1] = '\0';
+mBDrw->ElAddText(mPPos[0], mPPos[1], pc );
+mBDrw->Refresh();
+}
+
+void
+PIScDrawWdg::SetLimits(double xmin, double xmax, double ymin, double ymax,
+                       int axrl, int ayud, bool tmp)
+{
+//  if (xmax <= xmin || ymax <= ymin) {
+//    cerr << "PIScDrawWdg::SetLimits() Error - xmax <= xmin or ymax <= ymin !" << endl;
+//    return; 
+//    }
+  double xym;
+  xym = fabs(xmax+xmin); xym = (xym > PETIT_DBLE) ? xym : PETIT_DBLE;
+  if ((xmax-xmin)/xym < PREC_DBLE) { xmin = xmin - PREC_DBLE/2.*xym;  xmax = xmin + PREC_DBLE*xym; }
+  xym = fabs(ymax+ymin); xym = (xym > PETIT_DBLE) ? xym : PETIT_DBLE;
+  if ((ymax-ymin)/xym < PREC_DBLE) { ymin = ymin - PREC_DBLE/2.*xym;  ymax = ymin + PREC_DBLE*xym; }
+
+  SetDefaultDrawerLimits(xmin, xmax, ymin, ymax, axrl, ayud);
+  mBDrw->SetLimits(xmin, xmax, ymin, ymax, axrl, ayud);
+  mPPos[0] = 0.5*(XMin()+XMax());
+  mPPos[1] = 0.5*(YMin()+YMax());
+  mPSz[0] = 0.05*(XMax()+XMin());
+  mPSz[1] = 0.05*(YMax()+YMin());
+  if (!tmp) {
+    xMinS = xmin;
+    xMaxS = xmax;
+    yMinS = ymin;
+    yMaxS = ymax;
+  }
+  mFormatOpt[0] = SetFormatOpt(xmin,xmax);
+  mFormatOpt[1] = SetFormatOpt(ymin,ymax);
+  UpdatePosForDeltaMarker(false, true);
+}
+  
+void
+PIScDrawWdg::UpdateLimits()
+{
+  if (NbDrawers() < 2)  return;
+  PIDrawer* d = GetDrawer(1);
+  if (d == NULL) return;
+  // Le calcul de limites peut dependre du flag AxeLog Yes/No
+  // pour le calcul de la marge de garde en particulier. On met 
+  // donc les flags AxeLog a jour avant UpdateLimits() Reza+CMV 07/2002
+  d->SetLogScale(isDefaultDrawerLogScaleX(), isDefaultDrawerLogScaleY());
+  d->UpdateLimits();
+  SetLimits(d->XMin(), d->XMax(), d->YMin(), d->YMax(), mDXdir, mDYdir); 
+  Refresh();
+  return;  
+}
+
+void
+PIScDrawWdg::SetAxesFlags(unsigned int flags)
+{
+  mBDrw->SetAxesFlags(flags);
+  if ((flags & kBoxAxes) == kBoxAxes) 
+    SetDefaultDrawRectangle(0.13, 0.09, 0.93, 0.89, true);
+  else 
+    SetDefaultDrawRectangle(0.06, 0.06, 0.94, 0.94, true);
+}
+
+int 
+PIScDrawWdg::DecodeOptionString(vector<string> & opt, bool rmdecopt)
+{
+  if (opt.size() == 0)  return(0);  
+  unsigned int aflg = BaseDrawer()->GetAxesFlags();
+  int ndec1 = BaseDrawer()->DecodeOptionString(opt, rmdecopt);
+  if (aflg != BaseDrawer()->GetAxesFlags())
+    SetAxesFlags(BaseDrawer()->GetAxesFlags());
+  vector<string> udopt;
+  unsigned int k = 0;
+  int ndec = opt.size();
+  bool fglinlog = false;
+  bool fglogx = isLogScaleX();
+  bool fglogy = isLogScaleY();
+
+  for( k=0; k<opt.size(); k++ ) {
+    string opts = opt[k];
+    // Limites en x,y
+    if (opts.substr(0,9) == "xylimits=") {
+      double xmin = XMin();
+      double ymin = YMin();
+      double xmax = XMax();
+      double ymax = YMax();
+      sscanf(opts.substr(9).c_str(),"%lg,%lg,%lg,%lg",&xmin, &xmax,&ymin,&ymax);
+      SetLimits(xmin, xmax, ymin, ymax);
+      continue;
+    }
+    if (opts.substr(0,10) == "defdrrect=") {
+      double x1 = 0.1;
+      double y1 = 0.1;
+      double x2 = 0.9;
+      double y2 = 0.9;
+      sscanf(opts.substr(10).c_str(),"%lg,%lg,%lg,%lg",&x1, &x2,&y1,&y2);
+      SetDefaultDrawRectangle(x1, y1, x2, y2, true);
+      continue;
+    }
+    if (opts == "linx") {
+      fglinlog = true;  fglogx = false;
+      continue;
+    }
+    if (opts == "logx") {
+      fglinlog = true;  fglogx = true;
+      continue;
+    }
+    if (opts == "liny") {
+      fglinlog = true;  fglogy = false;
+      continue;
+    }
+    if (opts == "logy") {
+      fglinlog = true;  fglogy = true;
+      continue;
+    }
+    /*
+    les attributs d'axes sont decodes par PIElDrawer
+    if (opts == "simpleaxes")  {
+      SetAxesFlags(kAxesDflt);
+      continue;
+    }
+    if ( (opts == "stdaxes")  || (opts == "boxaxes") ) {
+      SetAxesFlags(kBoxAxes | kExtTicks | kLabels);
+      continue;
+    }
+    if (opts == "boxaxesgrid")  {
+      SetAxesFlags(kBoxAxes | kExtTicks | kLabels | kGridOn);
+      continue;
+    }
+    if (opts == "fineaxes")  {
+      SetAxesFlags(kBoxAxes | kTicks | kLabels | kMinTicks | kMajTicks);
+      continue;
+    }
+    if (opts == "fineaxesgrid")  {
+      SetAxesFlags(kBoxAxes | kTicks | kLabels | kMinTicks | kMajTicks | kGridOn);
+      continue;
+    }
+    */
+
+    ndec--;
+    if (rmdecopt)  udopt.push_back(opts);
+  }  
+
+  if (fglinlog) SetLogScale(fglogx, fglogy);
+
+  if (rmdecopt)  opt = udopt;
+  return(ndec+ndec1);
+}
+
+int 
+PIScDrawWdg::AddScDrawer(PIDrawer* d, bool ad)
+{
+  if (d == NULL)  return(-1);
+  if (! LimitsFixed() ) {  //  On met a jour les limites 
+    // Le calcul de limites peut dependre du flag AxeLog Yes/No
+    // pour le calcul de la marge de garde en particulier. On met 
+    // donc les flags AxeLog a jour avant UpdateLimits() Reza+CMV 07/2002
+    d->SetLogScale(isDefaultDrawerLogScaleX(), isDefaultDrawerLogScaleY());
+    d->UpdateLimits();
+    SetLimits(d->XMin(), d->XMax(), d->YMin(), d->YMax(), mDXdir, mDYdir);
+  }
+  return(AddDrawer(d, true, true, ad));
+}
+
+
+void
+PIScDrawWdg::SetTextWin(PILabel * tw, bool trw, int tx, int ty)
+{
+mTxw = tw;
+if (trw)
+  {
+  if (mTrW)  mTrW->SetSize(tx, ty);
+  else
+    {
+    mTrW = new PIWindow(this, "Point", PIWK_transient, tx, ty, 0, 0);
+    mTrW->SetAutoDelChilds(true);
+    mTrlb = new PILabel(mTrW, "PointCoord", tx, ty, 0, 0);
+    mTrlb->SetBinding(PIBK_fixed,PIBK_fixed, PIBK_fixed,PIBK_fixed);
+    }
+  }
+else
+  if (mTrW) { delete mTrW; mTrW = NULL;  mTrlb = NULL; }
+
+return;
+}
+
+
+
+// Gestion affichage coordonnees du point 
+
+void
+PIScDrawWdg::GetClickText(string& info, double x, double y) 
+// Donne le texte a afficher pour position x,y  
+{
+  char buff[64];
+  PIDrawer*  dr = GetActiveDrawer();
+
+  info+="X=";  sprintf(buff,mFormatOpt[0].c_str(),x); info += buff;
+  info+=" Y="; sprintf(buff,mFormatOpt[1].c_str(),y); info += buff;
+  if(mFgDeltaPos) {
+    sprintf(buff," (dX=%g, dY=%g)",x-mPosForDelta[0],y-mPosForDelta[1]); 
+    info += buff;
+  }
+
+  if (dr) {
+    info += " ";  // info += dr->Name();
+    dr->GetClickInfo(info,x,y,mPosForDelta[0],mPosForDelta[1],mFgDeltaPos);
+  }
+  return;
+}
+
+void
+PIScDrawWdg::ActivateSpecializedControls()
+// Par défaut affiche la fenetres des attributs graphiques et axes
+{
+  PIDrwTools::SetCurrentBaseWdg(this);
+  PIDrwTools::ShowPIDrwTools();   // Fentre axes et options de trace
+}
+
+void
+PIScDrawWdg::UpdateInfoWindow()
+{
+
+if (mInfoW == NULL) { // Creation de la fenetre info
+  string nom = Nom() + "-Info";
+  int tpx, tpy;
+  GetScreenPos(tpx, tpy);
+  int sx, sy;
+  int ssx, ssy;
+  PIApplicationScreenSize(ssx, ssy);
+  if ( (ssx > 1000) && (ssy > 1000) ) { sx = 400;  sy = 200; }
+  else { sx = 300; sy = 160; }
+  mInfoW = new PIWindow(this, nom.c_str(), PIWK_normal,  sx, sy, tpx, tpy+YSize()+10);
+  mInfoW->SetAutoDelChilds(true);
+  nom = Nom() + "-InfoText";
+  mInfoTxt = new PIText(mInfoW, nom.c_str(), true, true, sx, sy, 0, 0);
+  mInfoTxt->SetBinding(PIBK_fixed, PIBK_fixed, PIBK_fixed, PIBK_fixed);
+  mInfoTxt->SetMutiLineMode(true);
+  mInfoTxt->SetTextEditable(false);
+  }
+
+//  Boucle sur tous les drawers :
+vector<BWDrwId>::iterator it;
+char buff[128];
+sprintf(buff, "Info: NDrawer= %d - Pos=%g %g  (Sz=%g,%g) \n", (int)mDrwList.size()-1, 
+        mPPos[0], mPPos[1], mPSz[0], mPSz[1] );
+double xmin, ymin, xmax, ymax;
+xmin = mPPos[0] - 0.5*mPSz[0];
+xmax = mPPos[0] + 0.5*mPSz[0];
+ymin = mPPos[1] - 0.5*mPSz[1];
+ymax = mPPos[1] + 0.5*mPSz[1];
+
+string info = buff;
+int k=0;
+for(it = mDrwList.begin(); it != mDrwList.end(); it++) {
+  if ((*it).drw == mBDrw )  continue;
+  k++;
+  sprintf(buff," --------- Drawer %d ----------- \n", k); 
+  info += buff; 
+  (*it).drw->AppendTextInfo(info, xmin, ymin, xmax, ymax);
+  }
+
+mInfoW->Show();
+mInfoTxt->Manage();
+mInfoTxt->SetText(info);
+}
+
+// .............................
+// Bouton-1 : Position courante 
+
+void
+PIScDrawWdg::But1Press(int x, int y)
+{
+  UpdateText(x, y);
+  if (mTrW)
+    { 
+    int tpx, tpy;
+    GetScreenPos(tpx, tpy);       
+    tpy -= (mTrW->YSize()+5);
+    if (tpy < 0)  tpy = 0;
+    mTrW->SetPos(tpx, tpy);
+    mTrW->Show();
+    }
+  if (mFgReticule || mFgDeltaPos) { // On trace une reticule
+    cForCol = mWGrC->GetForeground();
+    cGOmod  = mWGrC->GetGOMode();
+    cLatt = mWGrC->GetLineAtt();
+    mWGrC->SelForeground(PI_Magenta);
+    mWGrC->SelGOMode(PI_GOXOR);
+    mWGrC->SelLine(PI_ThinLine);
+  }
+  if (mFgReticule)  DrawReticule(x,y,0);
+  else SelPointerShape(PI_CrossPointer);
+  if (mFgDeltaPos)  DrawDeltaPosMarker();
+
+  Send(Msg(), PIMsg_Active);
+  PIDrwTools::SetCurrentBaseWdg(this);
+  PIAxesTools::SetCurrentScDrawWdg(this);
+}
+
+void
+PIScDrawWdg::Ptr1Move(int x, int y)
+{
+  UpdateText(x, y);  // Met a jour mPPos
+  if (mFgReticule)  DrawReticule(x,y,1);
+}
+
+void
+PIScDrawWdg::But1Release(int x, int y)
+{
+  UpdateText(x, y);
+  if (mFgReticule)  DrawReticule(x,y,2);
+  else SelPointerShape(PI_ArrowPointer);
+  if (mFgDeltaPos)  DrawDeltaPosMarker();
+  if (mFgReticule || mFgDeltaPos) {
+    mWGrC->SelForeground(cForCol);
+    mWGrC->SelGOMode(cGOmod);
+    mWGrC->SelLine(cLatt);
+  }
+  if (mTrW)  mTrW->Hide();
+}
+
+void
+PIScDrawWdg::UpdateText(int xp, int yp)
+{
+  double dx, dy;
+  mBDrw->GetGraphicUC()->GrC2UC(xp, yp, dx, dy); 
+  mPPos[0] = dx;  mPPos[1] = dy; 
+  
+  string ctxt;
+  GetClickText(ctxt, dx, dy);
+//DEBUG  char buff[32];    sprintf(buff, " %d:%d",xp,yp); ctxt += buff;
+  if (mTxw)
+    mTxw->SetLabel(ctxt);
+  if (mTrlb)
+    mTrlb->SetLabel(ctxt);
+  return;
+
+}
+
+void
+PIScDrawWdg::UpdatePosForDeltaMarker(bool fg, bool fgupd)
+{
+  if (!fgupd)   mFgDeltaPos = fg;
+  if (mFgDeltaPos) {
+    mPosForDelta[0] = mPPos[0];  
+    mPosForDelta[1] = mPPos[1];  
+    double pfdx, pfdy;
+    mBDrw->GetGraphicUC()->UC2GrC(mPosForDelta[0], mPosForDelta[1], 
+				 pfdx, pfdy); 
+    mPosFDX = (int)pfdx;  mPosFDY = (int)pfdy;
+  }
+  return;
+}
+
+
+void
+PIScDrawWdg::DrawReticule(int x, int y, int op)
+{
+  if (!mFgReticule) return;
+  //  int pos = (x>XSize()/2) ? PI_HorizontalRight: PI_HorizontalLeft;
+  //  char buff[128];
+  //  string format1 = "X= "; format1 += mFormatOpt[0].c_str();
+  //  string format2 = "Y= "; format2 += mFormatOpt[1].c_str();
+  if (op > 0) { // on efface le precedent 
+    mWGrC->DrawLine(mCPosX, 0, mCPosX, YSize());
+    mWGrC->DrawLine(0, mCPosY, XSize(), mCPosY);
+    //    sprintf(buff,format1.c_str(), mPPos[0]);
+    //    mWGrC->DrawString(mCPosX+10, mCPosY-10, buff, pos); 
+    //    sprintf(buff,format2.c_str(), mPPos[1]);
+    //    mWGrC->DrawString(mCPosX+10, mCPosY+20, buff, pos); 
+  }
+  if (op < 2) {
+    mWGrC->DrawLine(x, 0, x, YSize());
+    mWGrC->DrawLine(0, y, XSize(), y);
+    mCPosX = x;   mCPosY = y;
+  }  
+}
+
+void
+PIScDrawWdg::DrawDeltaPosMarker()
+{
+  if (mFgDeltaPos) {
+    mWGrC->DrawLine(mPosFDX-14., mPosFDY, mPosFDX+14, mPosFDY);
+    mWGrC->DrawLine(mPosFDX, mPosFDY-14, mPosFDX, mPosFDY+14);
+  }  
+}
+
+// .............................
+// Bouton-2 Gestion du zoom 
+
+void
+PIScDrawWdg::But2Press(int x, int y)
+{
+  xEndDrag = xBegDrag = x;
+  yEndDrag = yBegDrag = y;
+  cForCol = mWGrC->GetForeground();
+  cGOmod  = mWGrC->GetGOMode();
+  cPointer = GetPointerShape();
+  cLatt = mWGrC->GetLineAtt();
+  SelPointerShape(PI_CrossPointer);
+  mWGrC->SelForeground(PI_Magenta);
+  mWGrC->SelGOMode(PI_GOXOR);
+  mWGrC->SelLine(PI_ThinLine);
+  Send(Msg(), PIMsg_Active);
+  PIDrwTools::SetCurrentBaseWdg(this);
+  PIAxesTools::SetCurrentScDrawWdg(this);
+}
+
+void
+PIScDrawWdg::But2Release(int /*x*/, int /*y*/)
+{
+
+  mWGrC->DrawBox(xBegDrag, yBegDrag, xEndDrag-xBegDrag, yEndDrag-yBegDrag);
+
+  mWGrC->SelForeground(cForCol);
+  mWGrC->SelGOMode(cGOmod);
+  SelPointerShape(cPointer); 
+  mWGrC->SelLine(cLatt); 
+
+  //  Pour rendre le changement de zoom moins delicat $REZA - 05/99$  
+  int dxd = xEndDrag-xBegDrag;
+  if (dxd < 0) dxd = -dxd;
+  int dyd = yEndDrag-yBegDrag;
+  if (dyd < 0) dyd = -dyd;
+  //  if (xBegDrag == xEndDrag || yBegDrag == yEndDrag) // $REZA - 05/99$  
+  if ( (dxd < 5) || (dyd < 5) )    // $REZA - 05/99$  
+    SetLimits(xMinS, xMaxS, yMinS, yMaxS, kAxeDirSame, kAxeDirSame );
+  else {
+    double xl,yl,xh,yh;
+    mBDrw->GetGraphicUC()->GrC2UC(xBegDrag, yBegDrag, xl, yl);
+    mBDrw->GetGraphicUC()->GrC2UC(xEndDrag, yEndDrag, xh, yh);
+    if (xl > xh) dbl_swap(xl, xh);
+    if (yl > yh) dbl_swap(yl, yh);
+    SetLimits(xl,xh,yl,yh, kAxeDirSame, kAxeDirSame, true);
+  }
+  
+  Refresh();
+}
+
+void
+PIScDrawWdg::Ptr2Move(int x, int y)
+{
+  mWGrC->DrawBox(xBegDrag, yBegDrag, xEndDrag-xBegDrag, yEndDrag-yBegDrag);
+  xEndDrag = x;
+  yEndDrag = y;
+  mWGrC->DrawBox(xBegDrag, yBegDrag, xEndDrag-xBegDrag, yEndDrag-yBegDrag);
+}
+
+
+// .............................
+// Bouton-3 : Gestion de definition de la taille de rectangle Text-Info
+
+void
+PIScDrawWdg::But3Press(int x, int y)
+{
+  xEndDrag = xBegDrag = x;
+  yEndDrag = yBegDrag = y;
+  cForCol = mWGrC->GetForeground();
+  cGOmod  = mWGrC->GetGOMode();
+  cPointer = GetPointerShape();
+  cLatt = mWGrC->GetLineAtt();
+  SelPointerShape(PI_CrossPointer);
+  mWGrC->SelForeground(PI_Magenta);
+  mWGrC->SelGOMode(PI_GOXOR);
+  mWGrC->SelLine(PI_ThinLine);
+  Send(Msg(), PIMsg_Active);
+  PIDrwTools::SetCurrentBaseWdg(this);
+  PIAxesTools::SetCurrentScDrawWdg(this);
+}
+
+void
+PIScDrawWdg::But3Release(int /*x*/, int /*y*/)
+{
+
+  mWGrC->DrawBox(xBegDrag, yBegDrag, xEndDrag-xBegDrag, yEndDrag-yBegDrag);
+
+  mWGrC->SelForeground(cForCol);
+  mWGrC->SelGOMode(cGOmod);
+  SelPointerShape(cPointer); 
+  mWGrC->SelLine(cLatt); 
+
+  double xl,yl,xh,yh;
+  mBDrw->GetGraphicUC()->GrC2UC(xBegDrag, yBegDrag, xl, yl);
+  mBDrw->GetGraphicUC()->GrC2UC(xEndDrag, yEndDrag, xh, yh);
+  if (xl > xh) dbl_swap(xl, xh);
+  if (yl > yh) dbl_swap(yl, yh);
+  mPPos[0] = 0.5*(xl+xh);
+  mPPos[1] = 0.5*(yl+yh);
+  mPSz[0] = xh-xl;
+  mPSz[1] = yh-yl;
+  mCPosX =  0.5*(xBegDrag+xEndDrag);
+  mCPosY =  0.5*(yBegDrag+yEndDrag);
+
+  return;
+}
+
+void
+PIScDrawWdg::Ptr3Move(int x, int y)
+{
+  mWGrC->DrawBox(xBegDrag, yBegDrag, xEndDrag-xBegDrag, yEndDrag-yBegDrag);
+  xEndDrag = x;
+  yEndDrag = y;
+  mWGrC->DrawBox(xBegDrag, yBegDrag, xEndDrag-xBegDrag, yEndDrag-yBegDrag);
+}
+
+string
+PIScDrawWdg::SetFormatOpt(double xmin,double xmax)
+{
+  string format = "%-g";
+  double xm = (fabs(xmax)>fabs(xmin)) ? fabs(xmax): fabs(xmin);
+  double dx = fabs(xmax-xmin)/500.;
+  PIAxes::BonFormatAxes(xm,xm+dx,dx,format,0,1);
+  return format;
+}
Index: /tags/V_Dec2002/SophyaPI/PI/piscdrawwdg.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piscdrawwdg.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piscdrawwdg.h	(revision 2309)
@@ -0,0 +1,130 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive  PIScDrawWdg 
+// Gestionnaire Drawer-2D  E.Aubourg, R. Ansari  96-98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PISCDRAWWDG_H
+#define PISCDRAWWDG_H
+
+#include "pisysdep.h"
+#include PIBWDG_H
+#include PISTDWDG_H
+#include PIWIN_H
+#include "pidrawer.h"
+#include "pieldrw.h"
+
+
+// PIScDrawWdg, Gestionnaire de traceur 2D 
+
+class PIScDrawWdg : public PIBaseWdg {
+public:
+  enum {ClassId = 5300};
+
+                     PIScDrawWdg(PIContainerGen *par, const char *nom,
+                                   int sx=100, int sy=100, int px=0, int py=0);
+  virtual            ~PIScDrawWdg();
+
+  virtual long       kind() {return ClassId; }
+  
+  virtual void       SetLimits(double xmin, double xmax, double ymin, double ymax, 
+                               int axrl=kAxeDirSame, int ayud=kAxeDirSame, bool tmp=false);
+  inline  void	     SetLogScale(bool logx, bool logy)	
+                           { SetDefaultDrawerLogScale(logx, logy); }
+  inline  bool       isLogScaleX() { return(mDXlog); }
+  inline  bool       isLogScaleY() { return(mDYlog); }
+
+  virtual void	     UpdateLimits();  // Calcule et change les limites a partir de Drawer-No-1 
+
+  virtual void       SetAxesFlags(unsigned int flags=kBoxAxes | kExtTicks | kLabels);
+
+  inline void        SetTitles(string tt, string tb) 
+                            { mBDrw->SetTitles(tt, tb); }
+  inline void        SetTitles(string tt, string tb, PIGraphicAtt const& att) 
+                            { mBDrw->SetTitles(tt, tb, att); }
+
+//   Methode permettant de decoder des options a partir de chaines
+  virtual int        DecodeOptionString(vector<string> & opt, bool rmdecopt=true);
+
+// Ajoute un Drawer en auto 
+  int                AddScDrawer(PIDrawer*, bool ad=false);   
+
+  inline PIElDrawer* BaseDrawer() { return mBDrw; };
+
+// Configuration et limites des axes 
+  inline unsigned int GetAxesFlags() { return(mBDrw->GetAxesFlags()); }
+  inline void         GetAxesConfig(int& xa, int& ya) { mBDrw->GetAxesConfig(xa, ya); }
+
+  inline double XMin() const {return mBDrw->XMin();}
+  inline double XMax() const {return mBDrw->XMax();}
+  inline double YMin() const {return mBDrw->YMin();}
+  inline double YMax() const {return mBDrw->YMax();}
+
+  inline double XPPos() const { return mPPos[0]; }
+  inline double YPPos() const { return mPPos[1]; }
+
+  bool   LimitsFixed() const {return mBDrw->LimitsFixed();}
+  void   FreeLimits() { mBDrw->FreeLimits(); }
+    
+
+  virtual void       GetClickText(string& info, double x, double y); // Donne le texte a afficher pour position x,y
+  virtual void	     ActivateSpecializedControls();   // Pour activer des controles specifiques
+
+  virtual void       UpdateInfoWindow();    // Affiche et met a jour la fenetre info texte
+                                            // concernant le petit pave autour de la pos. courante 
+
+  void               SetTextWin(PILabel * tw, bool trw=true, int tx=600, int ty=30);
+
+  virtual void       But1Press(int x, int y);
+  virtual void       But1Release(int x, int y);
+  virtual void       Ptr1Move(int x, int y);
+
+  virtual void       But2Press(int x, int y);
+  virtual void       But2Release(int x, int y);
+  virtual void       Ptr2Move(int x, int y);
+  
+  virtual void       But3Press(int x, int y);
+  virtual void       But3Release(int x, int y);
+  virtual void       Ptr3Move(int x, int y);
+
+  virtual void       Keyboard(int key, PIKeyModifier kmod);
+  virtual void       PasteSelection(unsigned int typ, void *pdata, unsigned int l);
+
+  static  string     SetFormatOpt(double xmin,double xmax);
+  
+protected:
+  double xMinS, xMaxS, yMinS, yMaxS; // Sauvegarde pour zoom
+  double mPPos[2];        // Position courante (user coordinates)
+  double mPSz[2];         // Taille courant du pave info 
+  int mCPosX, mCPosY;     // Position click souris X,Y (pour trace de reticule)
+  bool mFgDeltaPos;       // affichage de l'ecart par rapport a la position memorisee
+  double mPosForDelta[2];     // Position memorisee - Pour affichage d'ecart
+  int mPosFDX, mPosFDY;       // Position (coord fenetre memorise)
+  bool mFgReticule;       // Controle l'affiche d'une réticule (Bouton-1)
+  string mFormatOpt[2];   // Format optimal d'impression des textes
+
+  PIElDrawer* mBDrw;
+  
+  int xBegDrag, yBegDrag;
+  int xEndDrag, yEndDrag;
+  PIColors cForCol;
+  PIGOMode cGOmod;  
+  PIPointer cPointer;
+  PILineAtt cLatt;
+  PILabel * mTxw;  
+  PILabel * mTrlb;
+  PIWindow * mTrW;
+
+// Fenetre pour l'affichage des informations 
+  PIWindow * mInfoW;
+  PIText * mInfoTxt;
+
+private:
+  void  UpdateText(int xp, int yp);
+  void  UpdatePosForDeltaMarker(bool fg, bool fgupd=false);
+  void  DrawReticule(int x, int y, int op);
+  void  DrawDeltaPosMarker();
+};
+
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pistdwdggen.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pistdwdggen.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pistdwdggen.cc	(revision 2309)
@@ -0,0 +1,287 @@
+#include "pistdwdggen.h"
+
+/************* PILabelGen ************/
+
+//++
+// Class	PILabel
+// Lib		PI
+// include	pistdwdggen.h
+//
+//	Composant graphique simple permettant d'afficher une étiquette (texte).
+//	"PILabelGen" définit l'interface (classe virtuelle pure). Les objets 
+//	instanciés doivent être de la classe "PILabel" déclarée dans le fichier
+//	entête "PISTDWDG_H".
+//--
+//++
+// Links	Parents
+// PIWdg
+//--
+
+//++
+// Titre	Constructeur, méthodes
+//--
+//++
+// PILabel(PIContainerGen* par, const char* nom, int sx=10, int sy=10, int px=0, int py=0)
+//	Création d'un objet PILabel ayant un contenu (étiquette) identique à "nom".
+// void SetLabel(string const& lab)
+//	Modifie l'étiquette affichée par l'objet 
+//--
+
+
+
+
+PILabelGen::PILabelGen(PIContainerGen *par, const char *nom,
+                         int sx, int sy, int px, int py)
+: PIWdg(par, nom, sx, sy, px, py)
+{}
+
+PILabelGen::~PILabelGen()
+{}
+
+/************* PIButtonGen ************/
+//++
+// Class	PIButton
+// Lib		PI
+// include	pistdwdggen.h
+//
+//	Composant graphique de type bouton .
+//	"PIButtonGen" définit l'interface (classe virtuelle pure). Les objets 
+//	instanciés doivent être de la classe "PIButton" déclarée dans le fichier
+//	entête "PISTDWDG_H". Lors de l'activation, le message de l'objet complété
+//	par le modifier "PIMsg_Click" est envoyé ("Send()"). Le champ "data" 
+//	contient le pointeur "NULL".
+//--
+//++
+// Links	Parents
+// PIWdg
+//--
+
+//++
+// Titre	Constructeur, méthodes
+//--
+//++
+// PIButton(PIContainerGen* par, const char* nom, PIMessage msg, int sx=10, int sy=10, int px=0, int py=0)
+//	Création d'un objet PIButton avec une étiquette identique à "nom".
+// void SetLabel(string const& lab)
+//	Modifie l'étiquette affichée par l'objet bouton.
+//--
+
+
+
+PIButtonGen::PIButtonGen(PIContainerGen *par, const char *nom, PIMessage msg,
+                         int sx, int sy, int px, int py)
+: PIWdg(par, nom, sx, sy, px, py)
+{
+SetMsg(msg);
+}
+
+PIButtonGen::~PIButtonGen()
+{}
+
+
+
+/************* PITextGen ************/
+//++
+// Class	PIText
+// Lib		PI
+// include	pistdwdggen.h
+//
+//	Composant graphique de type champ texte.
+//	"PITextGen" définit l'interface (classe virtuelle pure). Les objets 
+//	instanciés doivent être de la classe "PIText" déclarée dans le fichier
+//	entête "PISTDWDG_H". Si un message non nul a été associé a l'objet 
+//	par "PIWdg::SetMsg(PIMessage msg)", le message correspondant complété
+//	par le modifier "PIMsg_DataChanged" est envoyé ("Send()") lors de 
+//	de la validation du champ texte (touche Retour-Chariot). Le champ "data" 
+//	contient le pointeur "NULL".
+//--
+//++
+// Links	Parents
+// PIWdg
+//--
+
+//++
+// Titre	Constructeur, méthodes
+//--
+//++
+//  PIText(PIContainerGen* par, const char* nom, int sx=10, int sy=10, int px=0, int py=0)
+//	Création d'un objet PIText.
+//  PIText(PIContainerGen* par, const char* nom, bool vsb, bool hsb, -
+//  int sx=10, int sy=10, int px=0, int py=0)
+//	Création d'un objet PIText multiligne, muni d'ascenseurs 
+//	Vertical si "vsb == true", horizontal si "hsb == true".
+// void SetText(string const& txt)
+//	Modifie  le contenu du champ texte.
+// string  GetText() const
+//	Renvoie le contenu du champ texte.
+// void  SetMutiLineMode(bool mlm=false)
+//	Active ("mlm=true") ou désactive ("mlm=false") la possibilité d'édition multiligne.
+// void  SetTextEditable(bool te=true)
+//	Permet de rendre le contenu du champ texte non-éditable ("te=false")
+//--
+
+PITextGen::PITextGen(PIContainerGen *par, const char *nom,
+                         int sx, int sy, int px, int py)
+: PIWdg(par, nom, sx, sy, px, py)
+{}
+
+PITextGen::PITextGen(PIContainerGen *par, const char *nom, bool vsb, bool hsb, 
+                         int sx, int sy, int px, int py)
+: PIWdg(par, nom, sx, sy, px, py)
+{}
+
+PITextGen::~PITextGen()
+{}
+
+
+
+
+/************* PICheckBoxGen ************/
+
+PICheckBoxGen::PICheckBoxGen(PIContainerGen *par, const char *nom, PIMessage msg,
+                         int sx, int sy, int px, int py)
+: PIWdg(par, nom, sx, sy, px, py)
+{
+SetMsg(msg);
+}
+
+PICheckBoxGen::~PICheckBoxGen()
+{}
+
+//++
+// Class	PICheckBox
+// Lib		PI
+// include	pistdwdggen.h
+//
+//	Composant graphique de type CheckBox.
+//	"PICheckBoxGen" définit l'interface (classe virtuelle pure). Les objets 
+//	instanciés doivent être de la classe "PICheckBox" déclarée dans le fichier
+//	entête "PISTDWDG_H". Lors du changement d'état, le message de l'objet  
+//	complété par le modifier "PIMsg_DataChanged" est envoyé ("Send()").
+//	Le champ "data" contient un pointeur sur une variable de type "bool"
+//	qui contient l'état de l'objet lors de l'appel à "Send()".
+//--
+//++
+// Links	Parents
+// PIWdg
+//--
+
+//++
+// Titre	Constructeur, méthodes
+//--
+//++
+// PICheckBox(PIContainerGen* par, const char* nom,  PIMessage msg, int sx=10, int sy=10, int px=0, int py=0);
+//	Création d'un objet PICheckBox.
+// void SetState(bool st=false)
+//	Modifie l'état de l'objet.
+// bool GetState()
+//	Renvoie l'état de l'objet.
+//--
+
+
+/************* PIScaleGen ************/
+//++
+// Class	PIScale
+// Lib		PI
+// include	pistdwdggen.h
+//
+//	Composant graphique de type échelle ou curseur. (La valeur représentée 
+//	par l'objet peut être modifiée à l'aide d'un curseur).
+//	"PIScaleGen" définit l'interface (classe virtuelle pure). Les objets 
+//	instanciés doivent être de la classe "PIScale" déclarée dans le fichier
+//	entête "PISTDWDG_H". Lors du changement de valeur, le message de l'objet  
+//	complété par le modifier "PIMsg_DataChanged" est envoyé ("Send()").
+//	Le champ "data" contient un pointeur sur une variable de type "int"
+//	qui contient la valeur associée  à l'objet lors de l'appel à "Send()".
+//--
+//++
+// Links	Parents
+// PIWdg
+//--
+
+//++
+// Titre	Constructeur, méthodes
+//--
+//++
+// PIScale(PIContainerGen* par, const char* nom, PIMessage msg, int dir=kSDirLtoR, int sx=100, int sy=10, int px=0, int py=0)
+//	Création d'un objet PIScale. "dir" indique la direction et le sens d'affichage et peut
+//	prendre les valeurs "kSDirLtoR" (gauche à droite), "kSDirRtoL" (droite à gauche),
+//	"kSDirDownUp" (bas vers haut) et "kSDirUpDown" (de haut en bas).
+// void  SetMinMax(int min, int max)
+//	Modifie les valeurs extrêmes de l'échelle. L'objet est créé avec des bornes par défaut de 1 à 100.
+// void GetMinMax(int& min, int& max)
+//	Renvoie les valeurs extrêmes de l'échelle.
+// void SetValue(int v)
+//	Modifie la valeur courante de l'échelle.
+// int GetValue()
+//	Renvoie la valeur courante de l'échelle.
+//--
+
+
+PIScaleGen::PIScaleGen(PIContainerGen *par, const char *nom, PIMessage msg, 
+                       int /*dir*/, int sx, int sy, int px, int py)
+: PIWdg(par, nom, sx, sy, px, py) 
+{
+SetMsg(msg);
+}
+
+PIScaleGen::~PIScaleGen()
+{}
+
+/************* PIScrollBarGen ************/
+//++
+// Class	PIScrollBar
+// Lib		PI
+// include	pistdwdggen.h
+//
+//	Composant graphique de type ascenseur. 
+//	"PIScrollBarGen" définit l'interface (classe virtuelle pure). Les objets 
+//	instanciés doivent être de la classe "PIScrollBar" déclarée dans le fichier
+//	entête "PISTDWDG_H". Lors du changement de valeur, le message de l'objet  
+//	complété par le modifier "PIMsg_DataChanged" est envoyé ("Send()").
+//	La méthode "ActivateDrag()" permet d'activer l'envoi de message en 
+//	cours de déplacement du curseur. Dans ce cas, le modifier 
+//	"PIMsg_Drag" est appliqué.
+//	Le champ "data" contient un pointeur sur une variable de type "int"
+//	qui contient la position courante du curseur.
+//--
+//++
+// Links	Parents
+// PIWdg
+//--
+
+//++
+// Titre	Constructeur, méthodes
+//--
+//++
+// PIScrollBar(PIContainerGen* par, const char* nom, PIMessage msg, int dir=kSDirUpDown, int sx=10, int sy=100, int px=0, int py=0)
+//	Création d'un objet PIScrollBar. "dir" indique la direction et le sens d'affichage et peut
+//	prendre les valeurs "kSDirLtoR" (gauche à droite), "kSDirRtoL" (droite à gauche),
+//	"kSDirDownUp" (bas vers haut) et "kSDirUpDown" (de haut en bas).
+// void  ActivateDrag(bool acd=false)
+//	Active ("acd=true") ou désactive ("mlm=false") l'envoi de messages lors du mouvement du curseur.
+// void SetMinMax(int min, int max)
+//	Modifie les valeurs extrêmes de l'ascenseur. L'objet est créé avec des bornes par défaut de 1 à 100.
+//	La valeur "max" correspond à la position extrême taille du curseur comprise ("max=posmax+taille").
+// void GetMinMax(int& min, int& max)
+//	Renvoie les valeurs extrêmes de l'ascenseur. 
+// void SetValue(int v)
+//	Modifie la position courante de l'ascenseur.
+// int GetValue()
+//	Renvoie la position courante de l'ascenseur.
+// void  SetSlSize(int sz)
+//	Modifie la taille de l'ascenseur.
+// int  GetSlSize()
+//	Renvoie la taille de l'ascenseur.
+//--
+
+PIScrollBarGen::PIScrollBarGen(PIContainerGen *par, const char *nom, PIMessage msg, 
+                       int /*dir*/, int sx, int sy, int px, int py)
+: PIWdg(par, nom, sx, sy, px, py) 
+{
+SetMsg(msg);
+}
+
+PIScrollBarGen::~PIScrollBarGen()
+{}
+
Index: /tags/V_Dec2002/SophyaPI/PI/pistdwdggen.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pistdwdggen.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pistdwdggen.h	(revision 2309)
@@ -0,0 +1,135 @@
+#ifndef PISTDWDGGEN_H_SEEN
+#define PISTDWDGGEN_H_SEEN
+
+
+#include "pisysdep.h"
+#include PIWDG_H
+
+class PILabelGen : public PIWdg {
+public:
+  enum {ClassId = 1001};
+
+                     PILabelGen(PIContainerGen* par, const char* nom,
+                                 int sx=10, int sy=10, int px=0, int py=0);
+  virtual            ~PILabelGen();
+
+  virtual long       kind() {return ClassId; }
+  virtual void       SetLabel(string const&)=0;
+};
+
+//  Les differents types de boutons avec un signe dessus ... 
+// enum PIBtnSign {  PIBtn_Label=0, PIBtn_ArrowUp=1, PIBtn_ArrowDown=2,  
+//                                 PIBtn_ArrowLeft=3, PIBtn_ArrowRight=4 };
+
+class PIButtonGen : public PIWdg
+{
+public:
+  enum {ClassId = 1010};
+
+                     PIButtonGen(PIContainerGen* par, const char* nom, 
+                                 PIMessage msg = PIMsg_Click,
+                                 int sx=10, int sy=10, int px=0, int py=0);
+  virtual            ~PIButtonGen();
+
+  virtual long       kind() {return ClassId; }
+  virtual void       SetLabel(string const&)=0;
+  virtual void       ActivatePress(bool acp=false)=0;
+
+};
+
+
+class PITextGen : public PIWdg
+{
+public:
+
+  enum {ClassId = 1020};
+
+  		     PITextGen(PIContainerGen* par, const char* nom,
+         		       int sx=10, int sy=10, int px=0, int py=0);
+  		     PITextGen(PIContainerGen* par, const char* nom, bool vsb, bool hsb,
+         		       int sx=100, int sy=100, int px=0, int py=0);
+  virtual	     ~PITextGen();
+  virtual void       SetText(string const&) = 0;
+  virtual string     GetText() const = 0;
+
+  virtual void       SetMutiLineMode(bool mlm=false) = 0;
+  virtual void       SetTextEditable(bool te=true) = 0;
+
+  virtual long       kind() {return ClassId; }
+};
+
+
+
+class PICheckBoxGen : public PIWdg
+{
+public:
+
+  enum {ClassId = 1030};
+
+                     PICheckBoxGen(PIContainerGen* par, const char* nom, 
+                                  PIMessage msg = PIMsg_Click,
+                                  int sx=10, int sy=10, int px=0, int py=0);
+  virtual            ~PICheckBoxGen()=0;
+  virtual void       SetState(bool st=false)=0;
+  virtual bool       GetState()=0;
+  
+  virtual long       kind() {return ClassId; }
+
+protected:
+
+};
+
+// Definition choix de la direction et sens pour Scale et Scroll-bar
+enum {
+  kSDirLtoR     = 1,
+  kSDirRtoL     = 2,
+  kSDirDownUp   = 4,
+  kSDirUpDown   = 8
+};
+
+class PIScaleGen : public PIWdg
+{
+public:
+  enum {ClassId = 1040};
+
+                     PIScaleGen(PIContainerGen* par, const char* nom, 
+                                PIMessage msg = PIMsg_DataChanged, int dir=kSDirLtoR, 
+                                int sx=100, int sy=10, int px=0, int py=0);
+  virtual            ~PIScaleGen();
+
+  virtual void       SetMinMax(int min, int max) = 0;
+  virtual void       GetMinMax(int& min, int& max) = 0;
+  virtual void       SetValue(int val) = 0;
+  virtual int        GetValue() = 0; 
+
+  virtual long       kind() {return ClassId; }
+
+protected:
+
+};
+
+class PIScrollBarGen : public PIWdg
+{
+public:
+  enum {ClassId = 1050};
+
+                     PIScrollBarGen(PIContainerGen* par, const char* nom, 
+                                    PIMessage msg=PIMsg_DataChanged, int dir=kSDirUpDown,
+                                    int sx=10, int sy=100, int px=0, int py=0);
+  virtual            ~PIScrollBarGen();
+
+  virtual void       ActivateDrag(bool acd=false) = 0;
+  virtual void       SetMinMax(int min, int max) = 0;
+  virtual void       GetMinMax(int& min, int& max) = 0;
+  virtual void       SetValue(int val) = 0;
+  virtual int        GetValue() = 0; 
+  virtual void       SetSlSize(int sz) = 0;
+  virtual int        GetSlSize() = 0;
+
+  virtual long       kind() {return ClassId; }
+
+protected:
+
+};
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pistdwdgmac.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pistdwdgmac.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pistdwdgmac.cc	(revision 2309)
@@ -0,0 +1,344 @@
+#include "pistdwdgmac.h"
+#include <LString.h>
+#include <PP_Messages.h>
+
+/************* PILabelMac ************/
+#include <LCaption.h>
+
+PILabelMac::PILabelMac(PIContainerGen *par, char *nom,
+                         int sx, int sy, int px, int py)
+: PILabelGen(par, nom, sx, sy, px, py)
+{
+  delete mPane;
+  LStr255 titre(nom);
+  mPane = new LCaption(mPaneInfo, titre, 130);
+}
+
+PILabelMac::~PILabelMac()
+{}
+
+
+/************* PIButtonMac ************/
+#include <LStdControl.h>
+
+PIButtonMac::PIButtonMac(PIContainerGen *par, char *nom, PIMessage msg,
+                         int sx, int sy, int px, int py)
+: PIButtonGen(par, nom, msg, sx, sy, px, py)
+{
+  delete mPane;
+  LStr255 titre(nom);
+  mPane = new LStdButton(mPaneInfo, msg_Click, 130, titre);
+  ((LStdButton*)mPane)->AddListener(this);
+}
+
+PIButtonMac::~PIButtonMac()
+{}
+
+void
+PIButtonMac::SetLabel(string const& str)
+{
+  LStr255 sstr(str.c_str());
+  ((LStdButton*)mPane)->SetDescriptor(sstr);
+}
+
+
+void
+PIButtonMac::ListenToMessage(MessageT inMessage, void *)
+{
+  if (inMessage == msg_Click)
+    Send(myMsg, PIMsg_Press);
+}
+
+
+/************* PITextMac ************/
+#include <LEditField.h>
+
+PITextMac::PITextMac(PIContainerGen *par, const char *nom,
+                         int sx, int sy, int px, int py)
+: PITextGen(par, nom, sx, sy, px, py)
+{
+  delete mPane;
+  LStr255 titre(nom);
+  mPane = new LEditField(mPaneInfo, titre, 130, 255, true, true, NULL, LCommander::GetTopCommander());
+}
+
+PITextMac::PITextMac(PIContainerGen *par, const char *nom,
+                     bool vsb, bool hsb,
+                     int sx, int sy, int px, int py)
+: PITextGen(par, nom, vsb, hsb, sx, sy, px, py)
+{
+  delete mPane;
+  LStr255 titre(nom);
+  mPane = new LEditField(mPaneInfo, titre, 130, 255, true, true, NULL, LCommander::GetTopCommander());
+}
+
+
+PITextMac::~PITextMac()
+{}
+
+void
+PITextMac::SetText(string const& s)
+{
+  SetLabel(s);
+}
+
+string
+PITextMac::GetText() const
+{
+  Str255 desc;
+  mPane->GetDescriptor(desc);
+  p2cstr(desc);
+  return (char*) desc;
+}
+
+/* --Methode-- */
+void PITextMac::SetMutiLineMode(bool /*mlm*/)
+{
+return;
+}
+
+/* --Methode-- */
+void PITextMac::SetTextEditable(bool te)
+{
+if (te)
+  { mPane->Enable(); }
+else
+  { mPane->Disable(); }
+return;
+}
+
+/************* PIScaleMac ************/
+static ControlActionUPP	sSBarAction = nil;
+
+
+PIScaleMac::PIScaleMac(PIContainerGen* par, char* nom, PIMessage msg,
+                       bool horiz, int sx, int sy, int px, int py)
+: PIScaleGen(par, nom, msg, horiz, sx, sy, px, py)
+{
+  delete mPane;
+  LStr255 titre(nom);
+  mPane = new LStdControl(mPaneInfo, msg_Click, 1, 1, 10,
+						  scrollBarProc, 130, titre, (Int32) this);
+  ((LStdControl*)mPane)->AddListener(this);
+  
+  if (sSBarAction == nil) {	// Allocate UPP if necessary
+	sSBarAction = NewControlActionProc((ProcPtr) SBarAction);
+  }
+  ((LStdControl*)mPane)->SetActionProc(sSBarAction);
+}
+
+PIScaleMac::~PIScaleMac()
+{}
+
+void
+PIScaleMac::ListenToMessage(MessageT inMessage, void *)
+{
+  if (inMessage == msg_ThumbDragged)
+    Send(myMsg, PIMsg_DataChanged);
+}
+
+void
+PIScaleMac::SetMinMax(int min, int max)
+{
+  ((LStdControl*)mPane)->SetMinValue(min);
+  ((LStdControl*)mPane)->SetMaxValue(max);
+}
+
+void
+PIScaleMac::GetMinMax(int &min, int &max)
+{
+  min = ((LStdControl*)mPane)->GetMinValue();
+  max = ((LStdControl*)mPane)->GetMaxValue();
+}
+
+void
+PIScaleMac::SetValue(int val)
+{
+  StopListening();
+  ((LStdControl*)mPane)->SetValue(val);
+  StartListening();
+}
+
+int
+PIScaleMac::GetValue()
+{
+  return ((LStdControl*)mPane)->GetValue();
+}
+
+pascal void
+PIScaleMac::SBarAction(
+	ControlHandle	inMacControl,
+	Int16			inPart)
+{
+	PIScaleMac		*theScroller =
+							(PIScaleMac *) GetControlReference(inMacControl);
+	theScroller->HandleScroll(inPart);
+}
+
+void
+PIScaleMac::HandleScroll(
+	const Int16		inPart)
+{
+    int delta;
+	switch (inPart) {				// Determine how much to scroll
+	
+		case kControlUpButtonPart:	// Scroll left one unit
+			delta = -1;
+			break;
+			
+		case kControlDownButtonPart:	// Scroll right one unit
+			delta = 1;
+			break;
+			
+		case kControlPageUpPart:		// Scroll left by Frame width
+										//   less one unit of overlap
+			delta = -10;
+			break;
+			
+		case kControlPageDownPart:		// Scroll right by Frame width
+										//   less one unit of overlap
+			delta = 10;
+			break;
+	}
+	
+	if (delta != 0) {
+	    SetValue(GetValue()+delta);
+	}
+}
+
+/************* PIScrollBarMac ************/
+static ControlActionUPP	sSBarAction2 = nil;
+
+
+PIScrollBarMac::PIScrollBarMac(PIContainerGen* par, char* nom, PIMessage msg,
+                       bool vert, int sx, int sy, int px, int py)
+: PIScrollBarGen(par, nom, msg, vert, sx, sy, px, py)
+{
+  delete mPane;
+  LStr255 titre(nom);
+  mPane = new LStdControl(mPaneInfo, msg_Click, 1, 1, 10,
+						  scrollBarProc, 130, titre, (Int32) this);
+  ((LStdControl*)mPane)->AddListener(this);
+  
+  if (sSBarAction2 == nil) {	// Allocate UPP if necessary
+	sSBarAction2 = NewControlActionProc((ProcPtr) SBarAction);
+  }
+  ((LStdControl*)mPane)->SetActionProc(sSBarAction2);
+}
+
+PIScrollBarMac::~PIScrollBarMac()
+{}
+
+void
+PIScrollBarMac::ListenToMessage(MessageT inMessage, void *)
+{
+  if (inMessage == msg_ThumbDragged)
+    Send(myMsg, PIMsg_DataChanged);
+}
+
+void
+PIScrollBarMac::SetMinMax(int min, int max)
+{
+  ((LStdControl*)mPane)->SetMinValue(min);
+  ((LStdControl*)mPane)->SetMaxValue(max);
+}
+
+void
+PIScrollBarMac::GetMinMax(int &min, int &max)
+{
+  min = ((LStdControl*)mPane)->GetMinValue();
+  max = ((LStdControl*)mPane)->GetMaxValue();
+}
+
+
+void
+PIScrollBarMac::SetValue(int val)
+{
+  StopListening();
+  ((LStdControl*)mPane)->SetValue(val);
+  StartListening();
+}
+
+int
+PIScrollBarMac::GetValue()
+{
+  return ((LStdControl*)mPane)->GetValue();
+}
+
+pascal void
+PIScrollBarMac::SBarAction(
+	ControlHandle	inMacControl,
+	Int16			inPart)
+{
+	PIScrollBarMac		*theScroller =
+							(PIScrollBarMac *) GetControlReference(inMacControl);
+	theScroller->HandleScroll(inPart);
+}
+
+void
+PIScrollBarMac::HandleScroll(
+	const Int16		inPart)
+{
+    int delta;
+	switch (inPart) {				// Determine how much to scroll
+	
+		case kControlUpButtonPart:	// Scroll left one unit
+			delta = -1;
+			break;
+			
+		case kControlDownButtonPart:	// Scroll right one unit
+			delta = 1;
+			break;
+			
+		case kControlPageUpPart:		// Scroll left by Frame width
+										//   less one unit of overlap
+			delta = -10;
+			break;
+			
+		case kControlPageDownPart:		// Scroll right by Frame width
+										//   less one unit of overlap
+			delta = 10;
+			break;
+	}
+	
+	if (delta != 0) {
+	    SetValue(GetValue()+delta);
+	}
+}
+
+/************* PICheckBoxMac ************/
+#include <LStdControl.h>
+
+PICheckBoxMac::PICheckBoxMac(PIContainerGen *par, char *nom, PIMessage msg,
+                         int sx, int sy, int px, int py)
+: PICheckBoxGen(par, nom, msg, sx, sy, px, py)
+{
+  delete mPane;
+  LStr255 titre(nom);
+  mPane = new LStdCheckBox(mPaneInfo, msg_Click, 0, 130, titre);
+  ((LStdCheckBox*)mPane)->AddListener(this);
+}
+
+PICheckBoxMac::~PICheckBoxMac()
+{}
+
+void
+PICheckBoxMac::ListenToMessage(MessageT inMessage, void *)
+{
+  if (inMessage == msg_Click)
+    Send(myMsg, PIMsg_DataChanged);
+}
+
+void
+PICheckBoxMac::SetState(bool st)
+{
+  StopListening();
+  ((LStdCheckBox*)mPane)->SetValue(st ? 1 : 0);
+  StartListening();
+}
+ 
+bool
+PICheckBoxMac::GetState()
+{
+  return ((LStdCheckBox*)mPane)->GetValue();
+}
Index: /tags/V_Dec2002/SophyaPI/PI/pistdwdgmac.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pistdwdgmac.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pistdwdgmac.h	(revision 2309)
@@ -0,0 +1,109 @@
+#ifndef PISTDWDGMAC_H_SEEN
+#define PISTDWDGMAC_H_SEEN
+
+#include "pistdwdggen.h"
+
+
+class PILabelMac : public PILabelGen
+{
+public:
+                     PILabelMac(PIContainerGen *par, char *nom,
+                                 int sx=10, int sy=10, int px=0, int py=0);
+  virtual           ~PILabelMac();
+  virtual void       SetLabel(string const&);
+};
+
+class PIButtonMac : public PIButtonGen
+{
+public:
+                     PIButtonMac(PIContainerGen *par, char *nom, PIMessage msg = PIMsg_Click,
+                                 int sx=10, int sy=10, int px=0, int py=0);
+  virtual           ~PIButtonMac();
+  virtual void       SetLabel(string const&);
+  virtual void	     ListenToMessage(MessageT inMessage, void *ioParam);
+  virtual void       ActivatePress(bool=false) {}
+};
+
+class PITextMac : public PITextGen
+{
+public:
+                     PITextMac(PIContainerGen *par, const char *nom,
+                               int sx=10, int sy=10, int px=0, int py=0);
+                     PITextMac(PIContainerGen *par, const char *nom,
+                               bool vsb, bool hsb,
+                               int sx=10, int sy=10, int px=0, int py=0);
+  virtual           ~PITextMac();
+
+  virtual void       SetMutiLineMode(bool mlm=false);
+  virtual void       SetTextEditable(bool te=true);
+
+  virtual void       SetText(string const&);
+  virtual string     GetText() const;
+};
+
+class PIScaleMac : public PIScaleGen
+{
+public:
+                     PIScaleMac(PIContainerGen* par, char* nom, 
+                                PIMessage msg=PIMsg_DataChanged, bool horiz=true,
+                                int sx=100, int sy=10, int px=0, int py=0);
+                    ~PIScaleMac();
+
+  virtual void       SetMinMax(int min, int max);
+  virtual void       GetMinMax(int& min, int& max);
+  virtual void       SetValue(int val);
+  virtual int        GetValue(); 
+  virtual void	     ListenToMessage(MessageT inMessage, void *ioParam);
+  virtual void	     HandleScroll(const Int16 inPart);
+  
+protected:
+  static pascal void SBarAction(ControlHandle inMacControl,
+								Int16 inPart);
+};
+
+class PIScrollBarMac : public PIScrollBarGen
+{
+public:
+                     PIScrollBarMac(PIContainerGen* par, char* nom, 
+                                PIMessage msg=PIMsg_DataChanged, bool vert=true,
+                                int sx=100, int sy=10, int px=0, int py=0);
+                    ~PIScrollBarMac();
+
+  virtual void       ActivateDrag(bool /*acd*/=false) {};
+  virtual void       SetMinMax(int min, int max);
+  virtual void       GetMinMax(int& min, int& max);
+  virtual void       SetValue(int val);
+  virtual int        GetValue(); 
+  virtual void	     ListenToMessage(MessageT inMessage, void *ioParam);
+  virtual void	     HandleScroll(const Int16 inPart);
+  virtual void       SetSlSize(int sz) {msz = sz;}
+  virtual int        GetSlSize() {return msz;}
+protected:
+  static pascal void SBarAction(ControlHandle inMacControl,
+								Int16 inPart);
+  int msz;
+};
+
+
+class PICheckBoxMac : public PICheckBoxGen
+{
+public:
+                     PICheckBoxMac(PIContainerGen* par, char* nom, 
+                                   PIMessage msg = PIMsg_Click,
+                                   int sx=10, int sy=10, int px=0, int py=0);
+  virtual           ~PICheckBoxMac();
+  virtual void	     ListenToMessage(MessageT inMessage, void *ioParam);
+  virtual void       SetState(bool st=false);
+  virtual bool       GetState();
+};
+
+
+ 
+typedef PILabelMac   PILabel;
+typedef PIButtonMac  PIButton;
+typedef PITextMac    PIText;
+typedef PIScaleMac   PIScale;
+typedef PIScrollBarMac PIScrollBar;
+typedef PICheckBoxMac PICheckBox;
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pistdwdgx.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pistdwdgx.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pistdwdgx.cc	(revision 2309)
@@ -0,0 +1,706 @@
+#include<stdlib.h>
+#include<string.h>
+
+#include "pisysdep.h"
+#include PISTDWDG_H
+
+#include "picontainerx.h"
+
+// ------- Pb de gestion du focus-keyboard  Motif-PIBaseWdg -------
+// ** Note du 26/02/98 - Reza 
+// Je desactive pour le moment XmNnavigationType et XmNtraversalOn
+// afin d'ameliorer la gestion du focus-keyboard entre Widget Motif
+// et objet Peida - Cela semble avoir un effet secondaire - 
+// Il faut que la souris reste dans le widget Text pour taper dedans
+// ** Note du 30/04/98 - Reza
+// J'ai modifie le mecanisme de gestion des evenements pour PIBaseWdg
+// en passant par un EventHandler - Le probleme de gestion du 
+// focus-keyboard n'a pour autant pas ete resolu
+// Je reactive XmNtraversalOn pour les PIText - Le probleme 
+// d'attribution du focus-keyboard au PIBaseWdg reste si on 
+// met PIText et un PIBaseWdg ds un meme conteneur
+
+
+/************* PILabelX ************/
+#include <Xm/Label.h>
+
+
+/* --Methode-- */
+PILabelX::PILabelX(PIContainerGen *par, const char *nom,
+                   int sx, int sy, int px, int py)
+: PILabelGen(par, nom, sx, sy, px, py)
+{
+Arg warg[3];
+int n = 0;
+CreateXtWdg(nom, xmLabelWidgetClass, NULL, sx, sy, px, py);
+SetBorderWidth(0);
+XtSetArg(warg[n], XmNrecomputeSize, FALSE); n++;
+XtSetArg(warg[n],XmNnavigationType,XmNONE);  n++;
+XtSetArg(warg[n],XmNtraversalOn,FALSE);  n++;
+XtSetValues(XtWdg(), warg, n);
+Manage();
+}
+
+/* --Methode-- */
+PILabelX::~PILabelX()
+{}
+
+/* --Methode-- */
+void PILabelX::SetLabel(string const& lab)
+{
+XmString xmstr;
+xmstr = XmStringLtoRCreate((char *)lab.c_str(), XmSTRING_DEFAULT_CHARSET);
+int n=0;
+Arg warg[2];
+
+XtSetArg(warg[n], XmNlabelString, xmstr); n++;
+XtSetValues(XtWdg(), warg, n);
+XmStringFree(xmstr);
+return;
+}
+
+
+/************* PIButtonX ************/
+#include <Xm/PushB.h>
+#include <Xm/ArrowB.h>
+
+// Fonctions privees (CallBack)
+static void button_action(Widget w, XtPointer *usd, XtPointer *calld);
+static void button_press(Widget w, XtPointer *usd, XmAnyCallbackStruct *calld);
+
+/* Nouvelle-Fonction */
+void  button_action(Widget , XtPointer *usd, XtPointer *)
+{
+PIButtonX *pib;
+pib = (PIButtonX *) usd ;
+pib->Send(pib->Msg(),PIMsg_Click,NULL);
+return;
+}
+
+/* Nouvelle-Fonction */
+void  button_press(Widget, XtPointer *usd, XmAnyCallbackStruct *calld)
+{
+PIButtonX *pib;
+pib = (PIButtonX *) usd ;
+pib->Send(pib->Msg(),PIMsg_Press,NULL);
+pib->myevt = *(calld->event);
+pib->myevt.type = pib->myevt.xbutton.type = ButtonRelease;
+pib->myevt.xbutton.serial += 10;
+PIXSetLastEventTimeSerial(calld->event->xbutton.time,  calld->event->xbutton.serial);
+
+return;
+}
+
+
+/* --Methode-- */
+PIButtonX::PIButtonX(PIContainerGen *par, const char *nom, PIMessage msg, 
+                     int sx, int sy, int px, int py)
+: PIButtonGen(par, nom, msg, sx, sy, px, py)
+{
+
+Arg  warg[6];
+int n = 0;
+
+XtSetArg(warg[n],XmNhighlightThickness, 0);  n++;
+XtSetArg(warg[n], XmNrecomputeSize, FALSE);  n++;
+XtSetArg(warg[n],XmNnavigationType,XmNONE);  n++;
+XtSetArg(warg[n],XmNtraversalOn,FALSE);  n++;
+CreateXtWdg(nom, xmPushButtonWidgetClass, NULL, sx, sy, px, py);
+
+/*
+if (bsgn == PIBtn_Label)
+  CreateXtWdg(nom, xmPushButtonWidgetClass, NULL, sx, sy, px, py);
+else
+  {
+  CreateXtWdg(nom, xmArrowButtonWidgetClass, NULL, sx, sy, px, py);
+  switch (bsgn)
+    {
+    case PIBtn_ArrowUp :
+      XtSetArg(warg[n], XmNarrowDirection, XmARROW_UP);  n++;
+      break;
+    case PIBtn_ArrowDown :
+      XtSetArg(warg[n], XmNarrowDirection, XmARROW_DOWN);  n++;
+      break;
+    case PIBtn_ArrowLeft :
+      XtSetArg(warg[n], XmNarrowDirection, XmARROW_LEFT);  n++;
+      break;
+    case PIBtn_ArrowRight :
+      XtSetArg(warg[n], XmNarrowDirection, XmARROW_RIGHT);  n++;
+      break;
+    }
+  }
+*/
+XtSetValues(XtWdg(), warg, n);
+XtAddCallback(XtWdg(), XmNactivateCallback, 
+              (XtCallbackProc)button_action, (XtPointer)this);
+
+mAcP = false;
+SetBorderWidth(0);
+Manage();
+}
+
+/* --Methode-- */
+PIButtonX::~PIButtonX()
+{}
+
+/* --Methode-- */
+void PIButtonX::SetLabel(string const& lab)
+{
+XmString xmstr;
+xmstr = XmStringLtoRCreate((char *)lab.c_str(), XmSTRING_DEFAULT_CHARSET);
+int n=0;
+Arg warg[2];
+
+XtSetArg(warg[n], XmNlabelString, xmstr); n++;
+XtSetValues(XtWdg(), warg, n);
+XmStringFree(xmstr);
+return;
+}
+
+/* --Methode-- */
+void PIButtonX::ActivatePress(bool acp)
+{
+if (mAcP == acp)  return; 
+    
+if (mAcP)
+  XtRemoveCallback(XtWdg(), XmNarmCallback, 
+                   (XtCallbackProc)button_press, (XtPointer)this);
+else 
+  XtAddCallback(XtWdg(), XmNarmCallback, 
+                (XtCallbackProc)button_press, (XtPointer)this);
+mAcP = acp;
+return;
+}       
+
+
+/* --Methode-- */
+void PIButtonX::ReleaseButton()
+{
+XPutBackEvent(myevt.xbutton.display, &myevt);
+return;
+}
+
+
+/************* PITextX ************/
+#include <Xm/Text.h>
+
+/* --Methode-- */
+PITextX::PITextX(PIContainerGen *par, const char *nom,
+                 int sx, int sy, int px, int py)
+: PITextGen(par, nom, sx, sy, px, py)
+{
+Arg warg[3];
+int n = 0;
+CreateXtWdg(nom, xmTextWidgetClass, NULL, sx, sy, px, py);
+mtext = XtWdg();
+XtSetArg(warg[n],XmNnavigationType,XmNONE);  n++;
+// XtSetArg(warg[n],XmNtraversalOn,FALSE);  n++;
+XtSetValues(mtext, warg, n);
+SetMutiLineMode(false);
+SetTextEditable(true);
+Manage();
+}
+
+/* --Methode-- */
+PITextX::PITextX(PIContainerGen *par, const char *nom, bool vsb, bool hsb,
+                 int sx, int sy, int px, int py)
+: PITextGen(par, nom, vsb, hsb, sx, sy, px, py)
+{
+Arg warg[10];
+int n = 0;
+XtSetArg(warg[n],XmNeditMode, XmMULTI_LINE_EDIT);  n++; 
+XtSetArg(warg[n],XmNscrollBarDisplayPolicy, XmSTATIC); n++;
+XtSetArg(warg[n],XmNnavigationType,XmNONE);  n++;
+if (vsb) 
+  XtSetArg(warg[n],XmNscrollHorizontal, True); n++;
+if (hsb)
+  XtSetArg(warg[n],XmNscrollVertical, True); n++;
+
+// **ATTENTION** Il vaut mieux creer avec les bonnes tailles au depart Reza 09/99 
+//     .....   C'est fait par CreateXtWdg( ... )
+
+XtSetArg(warg[n],XmNwidth,sx);  n++;
+XtSetArg(warg[n],XmNheight,sy);  n++;
+XtSetArg(warg[n],XmNx,px);  n++;
+XtSetArg(warg[n],XmNy,py);  n++;
+
+// XtSetArg(warg[n],XmNtraversalOn,FALSE);  n++;
+
+mtext = XmCreateScrolledText(((PIWdgX *)par)->XtWdg(), (char *)nom, warg, n);   // const_cast
+XtManageChild(mtext);
+XtWdg() = XtParent(mtext); 
+
+// XtWdg() = mtext;   Modif Reza 09/99
+// SetSize(sx, sy);
+// SetPos(px, py);
+
+wmis = k_wmi_normal ;
+stmng = 0;
+
+// **ATTENTION** A ne pas oublier , fait par CreateXtWdg Reza 09/99 
+SetBinding(PIBK_free, PIBK_free, PIBK_free, PIBK_free);
+par->ChildAdd(this);
+
+SetTextEditable(true);
+Manage();
+}
+
+/* --Methode-- */
+PITextX::~PITextX()
+{}
+
+/* --Methode-- */
+void PITextX::SetText(string const& s)
+{
+XmTextSetString(mtext, (char *)s.c_str());
+return;
+}
+
+/* --Methode-- */
+string PITextX::GetText() const
+{
+char *txtb;
+txtb = XmTextGetString(mtext);
+string s(txtb);
+XtFree(txtb);
+return(s);
+}
+
+/* --Methode-- */
+void PITextX::SetMutiLineMode(bool mlm)
+{
+Arg  warg[2];
+int n = 0;
+
+if (mlm)
+  { XtSetArg(warg[n],XmNeditMode, XmMULTI_LINE_EDIT);  n++; }
+else
+  { XtSetArg(warg[n],XmNeditMode, XmSINGLE_LINE_EDIT);  n++; }
+
+XtSetValues(mtext, warg, n);
+return;
+}
+
+/* --Methode-- */
+void PITextX::SetTextEditable(bool te)
+{
+Arg  warg[2];
+int n = 0;
+
+if (te)
+  { XtSetArg(warg[n],XmNeditable, TRUE);  n++; }
+else
+  { XtSetArg(warg[n],XmNeditable, FALSE);  n++; }
+
+XtSetValues(mtext, warg, n);
+return;
+}
+
+// Fonction privee (CallBack)
+static void text_action(Widget w, XtPointer *usd, XtPointer *calld);
+
+void  text_action(Widget, XtPointer *usd, XtPointer *)
+{
+PIText *pit;
+
+pit = (PIText *) usd ;
+pit->Send(pit->Msg(), PIMsg_DataChanged, NULL);
+}
+
+
+/* --Methode-- */
+void PITextX::SetMsg(PIMessage msg)
+{
+
+if (Msg() && !msg)
+  XtRemoveCallback(mtext, XmNactivateCallback, 
+                   (XtCallbackProc)text_action, (XtPointer)this);
+if (!Msg() && msg)
+  XtAddCallback(mtext, XmNactivateCallback, 
+                (XtCallbackProc)text_action, (XtPointer)this);
+
+PIWdg::SetMsg(msg);
+}
+
+
+/************* PICheckBoxX ************/
+#include <Xm/ToggleB.h>
+
+// Fonction prive (CallBack)
+static void toggb_action(Widget w, XtPointer *usd, XmToggleButtonCallbackStruct* calld);
+
+//  Variable globale d'etat de checkbox pour Send(...)
+static bool toggb_state = false;
+
+/* Nouvelle-Fonction */
+void  toggb_action(Widget , XtPointer *usd, XmToggleButtonCallbackStruct* calld)
+{
+PICheckBoxX *picb;
+picb = (PICheckBoxX *) usd ;
+if (calld->set == True)   picb->mSt = true;
+else picb->mSt = false;
+toggb_state = picb->mSt;
+picb->Send(picb->Msg(), PIMsg_DataChanged, (void *)(&toggb_state));
+return;
+}
+
+/* --Methode-- */
+PICheckBoxX::PICheckBoxX(PIContainerGen *par, const char *nom, PIMessage msg,
+                         int sx, int sy, int px, int py)
+: PICheckBoxGen(par, nom, msg, sx, sy, px, py)
+{
+CreateXtWdg(nom, xmToggleButtonWidgetClass, NULL, sx, sy, px, py);
+XtAddCallback(XtWdg(), XmNvalueChangedCallback,
+             (XtCallbackProc) toggb_action, (XtPointer)this);
+Arg warg[4];
+int n = 0;
+XtSetArg(warg[n],XmNhighlightThickness, 0); n++;
+XtSetArg(warg[n],XmNnavigationType,XmNONE);  n++;
+XtSetArg(warg[n],XmNtraversalOn,FALSE);  n++;
+XtSetValues(XtWdg(), warg, n);
+SetState(false);
+Manage();
+}
+
+
+/* --Methode-- */
+PICheckBoxX::~PICheckBoxX()
+{}
+
+
+/* --Methode-- */
+void PICheckBoxX::SetState(bool st)
+{
+Arg warg[2];
+mSt = st;
+if (st) XtSetArg(warg[0],XmNset, True);
+else XtSetArg(warg[0],XmNset, False);
+XtSetValues(XtWdg(), warg, 1);
+return;
+}
+
+/* --Methode-- */
+bool PICheckBoxX::GetState()
+{
+return(mSt);
+}
+
+
+/************* PIScaleX ************/
+#include <Xm/Scale.h>
+
+// Fonction prive (CallBack)
+static void scale_action(Widget w, XtPointer *usd, 
+                         XmScaleCallbackStruct *calld);
+// Variable globale pour contenir valeur de Scale a l'appel de Send;
+static int scale_value=0;
+ 
+void  scale_action(Widget, XtPointer *usd, 
+                         XmScaleCallbackStruct *calld)
+{
+PIScale *pis;
+
+pis = (PIScale *) usd ;
+pis->CBSetVal(calld->value);
+scale_value = calld->value;
+pis->Send(pis->Msg(), PIMsg_DataChanged, (void *)(&scale_value));
+return;
+}
+
+/* --Methode-- */
+PIScaleX::PIScaleX(PIContainerGen *par, const char *nom, PIMessage msg,
+                   int dir, int sx, int sy, int px, int py)
+: PIScaleGen(par, nom, msg, dir, sx, sy, px, py)
+{
+int n=0;
+Arg warg[8];
+XtSetArg(warg[n], XmNshowValue, TRUE); n++;
+XtSetArg(warg[n],XmNnavigationType,XmNONE);  n++;
+XtSetArg(warg[n],XmNtraversalOn,FALSE);  n++;
+if (dir == kSDirLtoR) {
+  XtSetArg(warg[n], XmNorientation, XmHORIZONTAL); n++;
+  XtSetArg(warg[n], XmNprocessingDirection, XmMAX_ON_RIGHT); n++;
+  }
+else if (dir == kSDirRtoL) {
+  XtSetArg(warg[n], XmNorientation, XmHORIZONTAL); n++;
+  XtSetArg(warg[n], XmNprocessingDirection, XmMAX_ON_LEFT); n++;
+  }
+else if (dir == kSDirDownUp) {
+  XtSetArg(warg[n], XmNorientation, XmVERTICAL); n++;
+  XtSetArg(warg[n], XmNprocessingDirection, XmMAX_ON_TOP); n++;
+  }
+else { // kSDirUpDown
+  XtSetArg(warg[n], XmNorientation, XmVERTICAL); n++;
+  XtSetArg(warg[n], XmNprocessingDirection, XmMAX_ON_BOTTOM); n++;
+  }
+// Il ne faut pas attribuer une valeur a XmNscaleWidth et XmNscaleHeight
+// Elles sont calculees automatiquement et repondent alors correctement aux resize
+// (Il faut laisser donc leur valeur par defaut=0)   Reza 28/10/98 
+// XtSetArg(warg[n], XmNscaleWidth, sx); n++;
+// XtSetArg(warg[n], XmNscaleHeight, sy); n++;
+// XtSetArg(warg[n], XmNstringDirection, XmSTRING_DIRECTION_R_TO_L); n++;
+CreateXtWdg(nom, xmScaleWidgetClass, NULL, sx, sy, px, py, warg, n);
+
+SetMinMax(1, 100);
+SetValue(1);
+
+XtAddCallback(XtWdg(), XmNvalueChangedCallback, 
+             (XtCallbackProc) scale_action, (XtPointer)this);
+Manage();
+}
+
+/* --Methode-- */
+PIScaleX::~PIScaleX()
+{}
+
+/* --Methode-- */
+void PIScaleX::SetMinMax(int min, int max)
+{
+if (min >= max)  max = min+10;
+if (mVal < min)  mVal = min;
+if (mVal > max)  mVal = max;
+int n=0;
+Arg warg[3];
+XtSetArg(warg[n], XmNminimum, min); n++;
+XtSetArg(warg[n], XmNmaximum, max); n++;
+XtSetArg(warg[n], XmNvalue, mVal); n++;
+XtSetValues(XtWdg(), warg, n);
+mMin = min;   mMax = max;
+return;
+}
+
+/* --Methode-- */
+void PIScaleX::GetMinMax(int& min, int& max)
+{
+min = mMin;   max = mMax;
+return;
+}
+
+/* --Methode-- */
+void PIScaleX::SetValue(int val)
+{
+int n=0;
+if (val < mMin)  val = mMin;
+if (val > mMax)  val = mMax;
+Arg warg[2];
+XtSetArg(warg[n], XmNvalue, val); n++;
+XtSetValues(this->sdw, warg, n);
+return;
+}
+
+/* --Methode-- */
+int  PIScaleX::GetValue()
+{
+int val;
+int n=0;
+Arg warg[2];
+XtSetArg(warg[n], XmNvalue, &val); n++;
+XtGetValues(this->sdw, warg, n);
+mVal = val;
+return(mVal);
+}
+
+/* --Methode-- */
+void  PIScaleX::CBSetVal(int val)
+{
+mVal = val;
+return;
+}
+
+
+
+/************* PIScrollBarX ************/
+
+#include <Xm/ScrollBar.h>
+
+// Fonction prive (CallBack)
+static void scrollbar_action(Widget w, XtPointer *usd, 
+                             XmScrollBarCallbackStruct *calld);
+static void scrollbar_drag(Widget w, XtPointer *usd, 
+                           XmScrollBarCallbackStruct *calld);
+// Variable globale pour contenir valeur de Scale a l'appel de Send;
+static int scroll_value=0;
+
+void  scrollbar_action(Widget, XtPointer *usd, 
+                       XmScrollBarCallbackStruct *calld)
+{
+PIScrollBar *pis;
+
+pis = (PIScrollBar *) usd ;
+pis->CBSetVal(calld->value);
+pis->Send(pis->Msg(), PIMsg_DataChanged, (void *)(&scroll_value));
+return;
+}
+
+void  scrollbar_drag(Widget, XtPointer *usd, 
+                       XmScrollBarCallbackStruct *calld)
+{
+PIScrollBar *pis;
+
+pis = (PIScrollBar *) usd ;
+pis->CBSetVal(calld->value);
+pis->Send(pis->Msg(), PIMsg_Drag, (void *)(&scroll_value));
+return;
+}
+
+/* --Methode-- */
+PIScrollBarX::PIScrollBarX(PIContainerGen *par, const char *nom, PIMessage msg,
+                           int dir, int sx, int sy, int px, int py)
+: PIScrollBarGen(par, nom, msg, dir, sx, sy, px, py)
+{
+int n=0;
+Arg warg[6];
+
+XtSetArg(warg[n],XmNnavigationType,XmNONE);  n++;
+XtSetArg(warg[n],XmNtraversalOn,FALSE);  n++;
+if (dir == kSDirLtoR) {
+  XtSetArg(warg[n], XmNorientation, XmHORIZONTAL); n++;
+  XtSetArg(warg[n], XmNprocessingDirection, XmMAX_ON_RIGHT); n++;
+  }
+else if (dir == kSDirRtoL) {
+  XtSetArg(warg[n], XmNorientation, XmHORIZONTAL); n++;
+  XtSetArg(warg[n], XmNprocessingDirection, XmMAX_ON_LEFT); n++;
+  }
+else if (dir == kSDirDownUp) {
+  XtSetArg(warg[n], XmNorientation, XmVERTICAL); n++;
+  XtSetArg(warg[n], XmNprocessingDirection, XmMAX_ON_TOP); n++;
+  }
+else { // kSDirUpDown
+  XtSetArg(warg[n], XmNorientation, XmVERTICAL); n++;
+  XtSetArg(warg[n], XmNprocessingDirection, XmMAX_ON_BOTTOM); n++;
+  }
+CreateXtWdg(nom, xmScrollBarWidgetClass, NULL, sx, sy, px, py, warg, n);
+mAcD = false;
+mVal = -1;
+mMin = mMax = 0;
+mSz = 10;
+mDir = dir;
+SetMinMax(1, 100);
+SetSlSize(10);
+SetValue(1);
+XtAddCallback(XtWdg(), XmNvalueChangedCallback, 
+             (XtCallbackProc) scrollbar_action, (XtPointer)this);
+Manage();
+}
+
+/* --Methode-- */
+PIScrollBarX::~PIScrollBarX()
+{}
+
+
+/* --Methode-- */
+void PIScrollBarX::ActivateDrag(bool acd)
+{
+if (mAcD == acd)  return; 
+    
+if (mAcD)
+  XtRemoveCallback(XtWdg(), XmNdragCallback, 
+                   (XtCallbackProc)scrollbar_drag, (XtPointer)this);
+else 
+  XtAddCallback(XtWdg(), XmNdragCallback, 
+                (XtCallbackProc)scrollbar_drag, (XtPointer)this);
+mAcD = acd;
+return;
+}       
+
+/* --Methode-- */
+void PIScrollBarX::SetMinMax(int min, int max)
+{
+if (min >= max)  max = min+100;
+if (mVal < min)  mVal = min;
+if (mVal > max-mSz)  mVal = max-mSz;
+//DBG printf("PIScrollBarX::SetMinMax(%d %d )  %d  Sz=%d \n", min, max, mVal, mSz);
+int n=0;
+Arg warg[3];
+XtSetArg(warg[n], XmNminimum, min); n++;
+XtSetArg(warg[n], XmNmaximum, max); n++;
+XtSetArg(warg[n], XmNvalue, mVal); n++;
+XtSetValues(XtWdg(), warg, n);
+mMin = min;   mMax = max;
+//DBG printf("--OUT-OF-- PIScrollBarX::SetMinMax(%d %d )  %d  Sz=%d \n", min, max, mVal, mSz);
+return;
+}
+
+/* --Methode-- */
+void PIScrollBarX::GetMinMax(int& min, int& max)
+{
+min = mMin;   max = mMax;
+return;
+}
+
+/* --Methode-- */
+void PIScrollBarX::SetValue(int val)
+{
+int n=0;
+if (val < mMin)  val = mMin;
+if (val > mMax-mSz)  val = mMax-mSz;
+Arg warg[2];
+//DBG printf("PIScrollBarX::SetValue(%d -> %d) \n", val, val0);
+XtSetArg(warg[n], XmNvalue, val); n++;
+XtSetValues(this->sdw, warg, n);
+mVal = val;
+//DBG printf("--OUT-OF---PIScrollBarX::SetValue(%d -> %d) \n", val, val0);
+return;
+}
+
+/* --Methode-- */
+int  PIScrollBarX::GetValue()
+{
+int val;
+int n=0;
+Arg warg[2];
+XtSetArg(warg[n], XmNvalue, &val); n++;
+XtGetValues(this->sdw, warg, n);
+mVal = val;
+return(mVal);
+}
+
+/* --Methode-- */
+void PIScrollBarX::SetSlSize(int sz)
+{
+int n=0;
+Arg warg[4];
+int szl;
+
+szl = mMax-mMin;
+if (sz > szl)  sz = szl;
+szl /= 100;
+if (szl < 1)  szl = 1;
+if (sz < szl)  sz = szl;
+szl = sz/10;
+if (szl < 1)  szl = 1;
+//DBG printf("PIScrollBarX::SetSlSize(%d ) \n", sz);
+XtSetArg(warg[n], XmNsliderSize, sz); n++;
+XtSetArg(warg[n], XmNpageIncrement, sz); n++;
+XtSetArg(warg[n], XmNincrement, szl); n++;
+if (mVal < mMin)  mVal = mMin;
+if (mVal > mMax-sz)  mVal = mMax-sz;
+XtSetArg(warg[n], XmNvalue, mVal); n++;
+XtSetValues(this->sdw, warg, n);
+//DBG printf("---OUT-OF---PIScrollBarX::SetSlSize(%d ) -> mVal= %d (cv1,2=%d %d)\n", sz,mVal, cv1, cv2);
+mSz = sz;
+return;
+}
+
+/* --Methode-- */
+int  PIScrollBarX::GetSlSize()
+{
+int sz;
+int n=0;
+Arg warg[2];
+XtSetArg(warg[n], XmNsliderSize, &sz); n++;
+XtGetValues(this->sdw, warg, n);
+mSz = sz;
+return(mSz);
+}
+
+
+/* --Methode-- */
+void  PIScrollBarX::CBSetVal(int val)
+{
+mVal = val;
+scroll_value = mVal;
+//DBG printf("PIScrollBarX::CBSetVal(%d) %d -> %d \n", mDir, val, mVal);
+return;
+}
+
Index: /tags/V_Dec2002/SophyaPI/PI/pistdwdgx.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pistdwdgx.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pistdwdgx.h	(revision 2309)
@@ -0,0 +1,127 @@
+#ifndef PISTDWDGX_H_SEEN
+#define PISTDWDGX_H_SEEN
+
+#include "pistdwdggen.h"
+
+
+class PILabelX : public PILabelGen
+{
+public:
+                     PILabelX(PIContainerGen *par, const char *nom,
+                                 int sx=10, int sy=10, int px=0, int py=0);
+  virtual            ~PILabelX();
+  virtual void       SetLabel(string const&);
+  
+};
+
+class PIButtonX : public PIButtonGen
+{
+public:
+                     PIButtonX(PIContainerGen *par, const char *nom, 
+                               PIMessage msg = PIMsg_Click,
+                               int sx=10, int sy=10, int px=0, int py=0);
+  virtual            ~PIButtonX();
+
+  virtual void       ActivatePress(bool acp=false);
+  virtual void       SetLabel(string const&);
+
+  void               ReleaseButton();   // Fonction a utiliser avec attention
+
+  XEvent myevt;   // Attention - Pour usage interne 
+
+protected :
+  bool mAcP;
+};
+
+
+class PITextX : public PITextGen
+{
+public:
+                     PITextX(PIContainerGen *par, const char *nom, 
+                                  int sx=10, int sy=10, int px=0, int py=0);
+  		     PITextX(PIContainerGen* par, const char* nom, bool vsb, bool hsb,
+         		     int sx=100, int sy=100, int px=0, int py=0);
+  virtual            ~PITextX();
+  virtual void       SetText(string const&);
+  virtual string     GetText() const;
+
+  virtual void       SetMutiLineMode(bool mlm=false);
+  virtual void       SetTextEditable(bool te=true);
+
+  virtual void       SetMsg(PIMessage msg=0);
+
+protected:
+
+SysDWdg mtext;  
+};
+
+
+class PICheckBoxX : public PICheckBoxGen
+{
+public:
+                     PICheckBoxX(PIContainerGen *par, const char *nom, 
+                                 PIMessage msg=PIMsg_Click,
+                                 int sx=10, int sy=10, int px=0, int py=0);
+  virtual            ~PICheckBoxX();
+
+  virtual void       SetState(bool st=false);
+  virtual bool       GetState();
+
+  bool mSt;          // Etat du bouton, en public a cause du Callback
+};
+
+
+
+class PIScaleX : public PIScaleGen
+{
+public:
+                     PIScaleX(PIContainerGen* par, const char* nom, 
+                              PIMessage msg=PIMsg_DataChanged, int dir=kSDirLtoR, 
+                              int sx=100, int sy=10, int px=0, int py=0);
+  virtual            ~PIScaleX();
+
+  virtual void       SetMinMax(int min, int max);
+  virtual void       GetMinMax(int& min, int& max);
+  virtual void       SetValue(int val);
+  virtual int        GetValue(); 
+
+  virtual void       CBSetVal(int val);   // A ne pas utiliser (pour Callback Xt)
+protected: 
+  int mVal, mMin, mMax;
+};
+
+
+
+class PIScrollBarX : public PIScrollBarGen
+{
+public:
+                     PIScrollBarX(PIContainerGen* par, const char* nom, 
+                                  PIMessage msg = PIMsg_DataChanged, int dir=kSDirUpDown,
+                                  int sx=10, int sy=100, int px=0, int py=0);
+                     ~PIScrollBarX();
+
+  virtual void       ActivateDrag(bool acd=false);
+  virtual void       SetMinMax(int min, int max);
+  virtual void       GetMinMax(int& min, int& max);
+  virtual void       SetValue(int val);
+  virtual int        GetValue(); 
+  virtual void       SetSlSize(int sz);
+  virtual int        GetSlSize();
+
+  virtual void       CBSetVal(int val);   // A ne pas utiliser (pour Callback Xt)
+
+protected: 
+  int mVal, mMin, mMax, mSz, mDir;
+  bool mAcD;
+};
+
+
+typedef PILabelX       PILabel;
+typedef PIButtonX      PIButton;
+typedef PITextX        PIText;
+typedef PICheckBoxX    PICheckBox;
+typedef PIScaleX       PIScale;
+typedef PIScrollBarX   PIScrollBar;
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pistzwin.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pistzwin.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pistzwin.cc	(revision 2309)
@@ -0,0 +1,373 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive  - Zone/Stack Layout
+// PIStackLayout , PIZone Layout , PIStackWindow , PIZoneWindow
+//                             R. Ansari  08/98
+
+#include <stdio.h>
+
+#include "pistzwin.h"
+#include "psfile.h"
+
+// -------------- Classe PIStackLayout --------------
+
+//++
+// Class	PIStackLayout
+// Lib		PI
+// include	pistzwin.h
+//
+//	Classe de gestionnaire de "PIWdg" dans un conteneur avec un seul 
+//	"PIWdg" visible à un moment donné. Permet d'empiler plusieurs
+//	objet dans une fenêtre, et passer de l'un à l'autre.
+//--
+//++
+// Links	Parent
+// PILayoutMgr
+//--
+
+//++
+// Titre	Constructeur, méthodes
+//--
+//++
+// PIStackLayout()
+// 	Constructeur
+// PIWdg*  CurrentWdg() 
+//	Retourne l'objet "PIWdg" visible au moment de l'appel.
+// int NumCurrentWdg()
+//	Retourne le numéro de l'objet "PIWdg" visible au moment de l'appel.
+// void  DispNext()
+//	Affiche l'objet "PIWdg" suivant.
+// void  DispWdgNum(int n)
+//	Affiche l'objet "PIWdg" numéro "n".
+//--
+
+/* --Methode-- */
+PIStackLayout::PIStackLayout()
+	: PILayoutMgr()
+{
+mCurdisp = -1;
+}
+
+/* --Methode-- */
+PIStackLayout::~PIStackLayout()
+{
+}
+
+/* --Methode-- */
+void PIStackLayout::ChildAdd(PIWdg* child)
+{
+int k;
+for(k=0; k<NbChilds(); k++) GetChild(k)->UnManage();
+PILayoutMgr::ChildAdd(child);
+child->Manage();
+mCurdisp = NbChilds()-1;
+return;
+}
+
+/* --Methode-- */
+void PIStackLayout::ChildDel(PIWdg* child)
+{
+int k;
+for(k=0; k<NbChilds(); k++) GetChild(k)->UnManage();
+PILayoutMgr::ChildDel(child);
+if (NbChilds() > 0) {
+  mCurdisp--;
+  if (mCurdisp < 0)  mCurdisp = 0;
+  if (mCurdisp > NbChilds()) mCurdisp = NbChilds()-1; 
+  GetChild(mCurdisp)->Manage();
+  }
+else mCurdisp = -1;
+return;
+}
+
+/* --Methode-- */
+void PIStackLayout::DispNext()
+{
+if (NbChilds() < 1) return;
+int n = (mCurdisp+1)%NbChilds();
+DispWdgNum(n);
+}
+
+/* --Methode-- */
+void PIStackLayout::DispWdgNum(int n)
+{
+if ( (n < 0) || (n >= NbChilds()) )  return;
+for(int k=0; k<NbChilds(); k++) GetChild(k)->UnManage();
+mCurdisp = n;
+GetChild(mCurdisp)->Manage();
+return;
+}
+
+
+// -------------- Classe PIStackWindow --------------
+
+// Fonction de l'objet PIPeriodic de PIStackWindow
+static void myadperpact(void* a);
+
+void myadperpact(void* a)
+{
+((PIStackWindow*)a)->DispNext();
+}
+
+//++
+// Class	PIStackWindow
+// Lib		PI
+// include	pistzwin.h
+//
+//	Classe de fenêtre ("PIWindow") avec le "PIStackLayout".
+//	Le "PILayoutMgr" ne peut être changé.
+//--
+//++
+// Links	Parent
+// PIWindow
+//--
+//++
+// Links	Voir aussi
+// PIStackLayout
+//--
+//++
+// Titre	Constructeur, méthodes
+//--
+//++
+// PIStackWindow(PIMsgHandler* par, const char* nom, PIWindowKind k=PIWK_normal, int sx=100, int sy=100, int px=0, int py=0)
+// 	Constructeur - identique à celui de "PIWindow"
+// void  DispNext()
+//	Affichage du "PIWdg" suivant.
+// PIWdg* CurrentWdg()
+//	Retourne l'objet "PIWdg" courant.
+// void  StartAutoDisp(int dtms=1000)
+//	Démarre  l'affichage cyclique automatique avec l'intervalle en temps 
+//	"dtms" spécifié en millisecondes.
+// void  StopAutoDisp()
+//	Arrête l'affichage cyclique automatique.
+// void  PSPrint(PSFile *psf, int ofx=0, int ofy=0)
+//	Rajoute tous les "PIWdg" associés à la fenêtre à l'objet
+//	"PSFile" (fichier PostScript), un objet par page.
+//--
+
+/* --Methode-- */
+PIStackWindow::PIStackWindow(PIMsgHandler* par, const char* nom, PIWindowKind k,
+                             int sx, int sy, int px, int py)
+        : PIWindow(par, nom, k, sx, sy, px, py) , mPerad(1)
+{
+mPerad.SetAction(myadperpact, this);
+delete layout;
+layout = new PIStackLayout;
+layout->SetContainer(this); 
+} 
+
+
+/* --Methode-- */
+PIStackWindow::~PIStackWindow()
+{
+mPerad.Stop();
+Hide();
+}
+
+/* --Methode-- */
+void PIStackWindow::SetLayoutMgr(PILayoutMgr*)
+{
+fprintf(stderr, "PIStackWindow::SetLayoutMgr() - LayoutMgr cannot be changed \n");
+return;
+}
+
+/* --Methode-- */
+void PIStackWindow::PSPrint(PSFile *psf, int ofx, int ofy, double scale_x, double scale_y)
+{
+if (!psf) return;
+int k;
+for(k=0; k<NbChilds(); k++) { 
+  psf->NewPage((double)XSize()*scale_x, (double)YSize()*scale_y,PI_Auto);
+  GetChild(k)->PSPrint(psf, ofx, ofy, scale_x, scale_y);
+  }
+}
+
+
+/* --Methode-- */
+void PIStackWindow::StartAutoDisp(int dtms)
+{
+mPerad.SetIntervalms(dtms);
+mPerad.Start();
+}
+
+/* --Methode-- */
+void PIStackWindow::StopAutoDisp()
+{
+mPerad.Stop();
+}
+
+//-------------------- Classe PIZoneLayout ------------------------------
+//++
+// Class	PIZoneLayout
+// Lib		PI
+// include	pistzwin.h
+//
+//	Classe de gestionnaire de "PIWdg" dans un conteneur, 
+//	divisé en cellule horizotale-verticale.
+//	En cas d'ajout d'un objet dans une cellule déjà occupée,
+//	l'objet est supprimé si "SetAutoDelChilds(true)", 
+//	sinon "UnManage()" est appelé pour cet objet.
+//--
+//++
+// Links	Parent
+// PILayoutMgr
+//--
+
+//++
+// Titre	Constructeur, méthodes
+//--
+//++
+// PIZoneLayout(int nzx, int nzy)
+// 	Constructeur. Subdivision en "nzx" cellules horizontales,
+//	"nzy" cellules verticales.
+// void SetZone(int nzx, int nzy)
+//	Modification du découpage en cellules.
+// void  NbZone(int& nzx, int& nzy)
+//	Retourne le nombre de cellules verticale-horizontale.
+// PIWdg* NextChildPosSize(int& px, int& py, int& sx, int& sy)
+//	Retourne la position et la taille d'un eventuel objet "PIWdg"
+//	ajouté. Retourne le "PIWdg" actuellement dans cette cellule.
+//-- 
+
+/* --Methode-- */
+PIZoneLayout::PIZoneLayout(int nzx, int nzy)
+	: PILayoutMgr()
+{
+mZWdg = NULL;
+SetZone(nzx, nzy);
+}
+
+/* --Methode-- */
+PIZoneLayout::~PIZoneLayout()
+{
+delete[] mZWdg;
+}
+
+
+/* --Methode-- */
+void PIZoneLayout::SetZone(int nzx, int nzy)
+{
+int i;
+if (mZWdg) {
+  for(i=0; i<mZx*mZy; i++) 
+    if (mZWdg[i]) delete mZWdg[i];  
+  delete[]  mZWdg;
+  }
+
+if (nzx < 1) nzx = 1;
+if (nzy < 1) nzy = 1;
+if (nzx > 50) nzx = 50;
+if (nzx > 50) nzx = 50;
+mZx = nzx;  mZy = nzy;   mZc = 0;
+
+mZWdg = new PIWdg*[nzx*nzy];
+for(i=0; i<mZx*mZy; i++) mZWdg[i] = NULL; 
+}
+
+
+/* --Methode-- */
+void PIZoneLayout::ChildAdd(PIWdg * child)
+{
+if (!child) return;
+int nx = mZc%mZx;
+int ny = mZc/mZx;
+PILayoutMgr::ChildAdd(child);
+child->SetBinding(PIBK_free,PIBK_free,PIBK_free, PIBK_free);
+int sx = mCont->XSize()/mZx;
+int sy = mCont->YSize()/mZy;
+child->SetPos(nx*sx, ny*sy);
+child->SetSize(sx, sy);
+child->SetBinding(PIBK_elastic,PIBK_elastic,PIBK_elastic, PIBK_elastic);
+child->LockBinding();
+//  Il faut faire le delete a cet endroit, sinon probleme avec widget motif XmForm  Reza 18/08/98
+if (mZWdg[mZc])  { 
+  if (mACSup) delete mZWdg[mZc]; 
+  else mZWdg[mZc]->UnManage();
+  }
+mZWdg[mZc] = child;
+mZc = (mZc+1)%(mZx*mZy);
+}
+
+/* --Methode-- */
+void PIZoneLayout::ChildDel(PIWdg * child)
+{
+if (!child)  return;
+int k;
+for(k=0; k<mZx*mZy; k++) 
+  if (mZWdg[k] == child) mZWdg[k] = NULL;  
+PILayoutMgr::ChildDel(child);
+return;
+}
+
+/* --Methode-- */
+void PIZoneLayout::NbZone(int& nzx, int& nzy)
+{
+nzx = mZx;   nzy = mZy;
+}
+
+/* --Methode-- */
+PIWdg* PIZoneLayout::NextChildPosSize(int& px, int& py, int& sx, int& sy)
+{
+sx = mCont->XSize()/mZx;
+sy = mCont->YSize()/mZy;
+int nx = mZc%mZx;
+int ny = mZc/mZx;
+px = nx*sx;  py = ny*sy;
+return ((PIWdg*)mZWdg[mZc]);
+}
+
+
+//-------------------- Classe PIZoneWindow ------------------------------
+//++
+// Class	PIZoneWindow
+// Lib		PI
+// include	pistzwin.h
+//
+//	Classe de fenêtre ("PIWindow") avec le "PIZoneLayout".
+//	Le "PILayoutMgr" ne peut être changé.
+//--
+//++
+// Links	Parent
+// PIWindow
+//--
+//++
+// Links	Voir aussi
+// PIZoneLayout
+//--
+//++
+// Titre	Constructeur, méthodes
+//--
+//++
+// PIZoneWindow(PIMsgHandler* par, const char* nom, PIWindowKind k=PIWK_normal, -
+//              int nzx=1, int nzy=1, int sx=100, int sy=100, int px=0, int py=0)
+// 	Constructeur avec spécification de nombre de cellules horizontal "nzx", vertical "nzy".
+// void  SetZone(int nzx, int nzy)
+//	Modification du découpage en cellules.
+// void NbZone(int& nzx, int& nzy)
+//	Retourne le nombre de cellules verticale-horizontale.
+// PIWdg* NextChildPosSize(int& px, int& py, int& sx, int& sy)
+//	Appel à " PIZoneLayout::NextChildPosSize(...) "
+//--
+
+/* --Methode-- */
+PIZoneWindow::PIZoneWindow(PIMsgHandler* par, const char* nom, PIWindowKind k,
+                           int nzx, int nzy, int sx, int sy, int px, int py)
+        : PIWindow(par, nom, k, sx, sy, px, py)
+{
+delete layout;
+layout = new PIZoneLayout(nzx, nzy);
+layout->SetContainer(this); 
+}
+
+/* --Methode-- */
+PIZoneWindow::~PIZoneWindow()
+{
+Hide();
+}
+
+/* --Methode-- */
+void PIZoneWindow::SetLayoutMgr(PILayoutMgr*)
+{
+fprintf(stderr, "PIZoneWindow::SetLayoutMgr() - LayoutMgr cannot be changed \n");
+return;
+}
+
Index: /tags/V_Dec2002/SophyaPI/PI/pistzwin.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pistzwin.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pistzwin.h	(revision 2309)
@@ -0,0 +1,96 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive  PIStackWindow  PIZoneWindow
+//                             R. Ansari  08/98
+
+#ifndef PISTZWIN_H_SEEN
+#define PISTZWIN_H_SEEN
+
+#include "pisysdep.h"
+#include PIWIN_H
+#include PIPERIODIC_H
+
+// ----------------------- Classe PIStackLayout ----------------------------
+// Pour Fenetre de type empilement , tout widget occupe la totalite 
+// de la fenetre - Un seul des widget visible (active) a chaque moment
+
+class PIStackLayout : public PILayoutMgr {
+public:
+		PIStackLayout();
+  virtual 	~PIStackLayout();
+
+  virtual void  ChildAdd(PIWdg* child);
+  virtual void  ChildDel(PIWdg* child);
+
+  inline PIWdg*  CurrentWdg() { return(GetChild(mCurdisp)); }
+  inline int    NumCurrentWdg() { return(mCurdisp); } 
+  virtual void  DispNext();
+  virtual void  DispWdgNum(int n);
+
+protected:
+  int mCurdisp;
+};
+		
+// ----------------------- Classe PIStackWindow ----------------------------
+//                    Fenetre avec un PIStackLayout
+
+class PIStackWindow : public PIWindow {
+public:
+		PIStackWindow(PIMsgHandler* par, const char* nom, PIWindowKind k=PIWK_normal,
+                              int sx=100, int sy=100, int px=0, int py=0);
+  virtual	~PIStackWindow();
+
+  virtual void  SetLayoutMgr(PILayoutMgr* nlay);
+  virtual void  PSPrint(PSFile *psf, int ofx=0, int ofy=0,
+			double scale_x=1., double scale_y=1.);
+
+  inline  void  DispNext() { ((PIStackLayout*)layout)->DispNext(); }
+  inline  PIWdg* CurrentWdg() { return( ((PIStackLayout*)layout)->CurrentWdg() ); }
+
+  virtual void  StartAutoDisp(int dtms=1000);
+  virtual void  StopAutoDisp();
+
+protected:
+  PIPeriodic mPerad;
+};
+
+// ----------------------- Classe PIZoneLayout ----------------------------
+// Pour fenetre avec nzx*nzy zone d affichage - Les nouveaux widgets dans chaque
+// zone viennent remplacer les anciennes - Ceux-ci sont detruits automatiquement
+
+
+class PIZoneLayout : public PILayoutMgr {
+public:
+		PIZoneLayout(int nzx=1, int nzy=1);
+  virtual 	~PIZoneLayout();
+
+  virtual void  ChildAdd(PIWdg* child);
+  virtual void  ChildDel(PIWdg* child);
+  virtual void  SetZone(int nzx, int nzy);
+  virtual void  NbZone(int& nzx, int& nzy);
+  virtual PIWdg* NextChildPosSize(int& px, int& py, int& sx, int& sy);
+
+protected:
+  int mZx, mZy, mZc;
+  PIWdg** mZWdg;
+};
+
+// ----------------------- Classe PIZoneWindow ----------------------------
+//                    Fenetre avec un PIZoneLayout 
+ 
+class PIZoneWindow : public PIWindow {
+public:
+		PIZoneWindow(PIMsgHandler* par, const char* nom, PIWindowKind k=PIWK_normal,
+                             int nzx=1, int nzy=1, int sx=100, int sy=100, int px=0, int py=0);
+  virtual	~PIZoneWindow();
+
+  virtual void  SetLayoutMgr(PILayoutMgr* nlay);
+
+  inline  void  SetZone(int nzx, int nzy) { ((PIZoneLayout*)layout)->SetZone(nzx, nzy); }
+  inline  void  NbZone(int& nzx, int& nzy)  { ((PIZoneLayout*)layout)->NbZone(nzx, nzy); }
+  inline PIWdg* NextChildPosSize(int& px, int& py, int& sx, int& sy)
+                { return ( ((PIZoneLayout*)layout)->NextChildPosSize(px, py, sx, sy) ); }
+
+protected:
+};
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pisurfdr.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pisurfdr.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pisurfdr.cc	(revision 2309)
@@ -0,0 +1,290 @@
+// Module PI : Peida Interactive     PISurfaceDrawer
+// Traceur de surface 3D  - R.Ansari, C.Magneville 98 
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include <math.h>
+#include "pisurfdr.h"
+
+#define PERC_GARDE 0.05
+
+//++
+// Class	PISurfaceDrawer
+// Lib		PI
+// include	pisurfdr.h
+//
+//	Classe de traceur d'une surface Z = f(X,Y)
+//--
+//++
+// Links	Parents
+// PIDrawer3D
+//--
+//++
+// Links	Voir aussi
+// P2DArrayAdapter
+//--
+//++
+// Titre	Constructeur
+//--
+//++
+//  PISurfaceDrawer(P2DArrayAdapter* arr, bool asxy=false, bool asz=true, bool ad = true)
+//	Constructeur. Tracé d'une surface définie par le tableau 2D "arr".
+//	Si asxy == true : Application d'un facteur d'échelle pour égaliser 
+//	le rapport d'aspect des deux axes X et Y
+//	Si asz == true : Application d'un facteur d'échelle pour égaliser 
+//	le rapport d'aspect de l'axe Z par rapport a XY.
+//--
+
+/* --Methode-- */
+PISurfaceDrawer::PISurfaceDrawer(P2DArrayAdapter* arr, bool asxy, bool asz, bool ad)
+{
+  mArr = arr;  mAda = ad;
+  mScx = mScy = mScz = 1.;
+  mZmin = 0.; mZmax = 1.;
+  mLut = NULL;
+  if (arr == NULL)  return;
+  arr->XYfromxy(0,0,mXmin, mYmin);
+  arr->XYfromxy(arr->XSize(),arr->YSize(),mXmax, mYmax);
+  double scm=1.;
+  if (asxy)  { 
+    mScy = (mXmax-mXmin)/(mYmax-mYmin);
+    scm = mXmax-mXmin;
+    }
+  else scm =  ((mXmax-mXmin) > (mYmax-mYmin)) ? (mXmax-mXmin)  : (mYmax-mYmin);
+  int i,j;   double cv;
+  mZmin = mZmax = arr->Value(0,0);
+  for(i=0; i<arr->XSize(); i++) 
+    for(j=0; j<arr->YSize(); j++) {
+      cv  = arr->Value(i,j);
+      if (cv < mZmin) mZmin = cv;
+      if (cv > mZmax) mZmax = cv;
+    }
+  if ((mZmax-mZmin) <= 1.e-19)  mZmax = mZmin + 1.e-19;
+  if (asz) mScz = scm/(mZmax-mZmin);
+//  printf("PISurfaceDrawer::PISurfaceDrawer Min/Max: %g,%g  %g,%g  %g,%g  Sc: %g %g %g \n",
+//          mXmin, mXmax, mYmin, mYmax, mZmin, mZmax, mScx, mScy, mScz);
+  double zmin = mZmin; 
+  double zmax = mZmax;
+  double dzz = (mZmax-mZmin)*PERC_GARDE;
+  mLut = new LUT(zmin-dzz*2, zmax-dzz, 256);
+
+  SetName("SurfDrw");
+}
+
+/* --Methode-- */
+PISurfaceDrawer::~PISurfaceDrawer()
+{
+  if (mAda) delete mArr;
+  if (mLut) delete mLut;
+}
+
+/* --Methode-- */
+void PISurfaceDrawer::UpdateLimits()
+{
+  if (mArr == NULL)  return;
+  double xmin, xmax, ymin, ymax, zmin, zmax;
+  xmin = mXmin*mScx;  xmax = mXmax*mScx;
+  ymin = mYmin*mScy;  ymax = mYmax*mScy;
+  zmin = mZmin*mScz;  zmax = mZmax*mScz;
+// Centre du champ en C = (xmin+xmax)/2., (ymin+ymax)/2  (zmin+zmax)*0.5
+// Distance D = Max(xmax-xmin,ymin-ymax)*2
+// Observateur en O = X+D, Yc+2*D 
+  double D = xmax-xmin;
+  if (D < (ymax-ymin))  D = ymax-ymin;
+  D *= 1.4;
+  
+  Set3DView((xmin+xmax)/2., (ymin+ymax)/2, zmin+(zmax-zmin)*0.40, 
+            (xmin+xmax)/2.+D , (ymin+ymax)/2.-2.5*D , zmin+(zmax-zmin)*0.85, 0.25, 0.25);  
+
+  Set3DBox(xmin, xmax, ymin, ymax, zmin-PERC_GARDE*(zmax-zmin), zmax+PERC_GARDE*(zmax-zmin));
+
+//  printf("PISurfaceDrawer::UpdateLimits() : %g-%g  %g-%g  %g-%g (%g) \n", xmin,xmax,ymin,ymax,zmin,zmax,D);
+//  printf("PISurfaceDrawer::UpdateLimits() :  %g %g %g <<- %g %g %g \n", 
+//         (xmin+xmax)/2., (ymin+ymax)/2, zmin+(zmax-zmin)*0.40, 
+//         (xmin+xmax)/2.+D , (ymin+ymax)/2.+2.*D , zmin+(zmax-zmin)*0.60 );
+
+}
+
+
+typedef struct   /*  structures pour trier en ZP les facettes */
+  { double dp;  double zh;  int ij;  } ZPSORT;
+/* Nouvelle-Fonction */
+static int ijzpsort(const void * sp1, const void * sp2)
+/*  Fonctions de tri des etoiles en flux ds un starlist */
+{
+  ZPSORT* p1 = (ZPSORT*)sp1;   
+  ZPSORT* p2 = (ZPSORT*)sp2;  
+  if (p1->dp > p2->dp)  return(-1);
+  else if (p1->dp < p2->dp)  return(1);
+  return(0);
+}
+
+/* --Methode-- */
+void PISurfaceDrawer::DrawAxes(PIGraphicUC* g)
+{
+  if (axesFlags == kAxesNone) return;
+#if defined(CC_HAS_RTTI_SUPPORT)
+  PIGraphic3D* g3 = dynamic_cast<PIGraphic3D*>(g);
+#else
+  PIGraphic3D* g3 = (PIGraphic3D*)(g);
+#endif
+  Draw3DBoxe(g3,XMin3(),XMax3(),YMin3(),YMax3(),ZMin3(),ZMax3(),
+            mXmin,mXmax,mYmin,mYmax,
+            mZmin-PERC_GARDE*(mZmax-mZmin),mZmax+PERC_GARDE*(mZmax-mZmin));
+}
+
+/* --Methode-- */
+void PISurfaceDrawer::Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax)
+{
+// On trace les axes - En attendant de faire mieux - Reza 8/12/98
+  if (axesFlags != kAxesNone)  DrawAxes(g);
+
+  if (mArr == NULL)  return;
+
+#if defined(CC_HAS_RTTI_SUPPORT)
+  PIGraphic3D* g3 = dynamic_cast<PIGraphic3D*>(g);
+#else
+  PIGraphic3D* g3 = (PIGraphic3D*)(g);
+#endif
+
+  g3->SelBackground(PI_White);
+//  g3->Erase(xmin, ymin, xmax-xmin, ymax-ymin);
+
+  int xsz = mArr->XSize();
+  int ysz = mArr->YSize();
+
+  ZPSORT* ijzp = new ZPSORT[xsz*ysz];
+  double* xw = new double[(xsz+1)*(ysz+1)];
+  double* yw = new double[(xsz+1)*(ysz+1)];
+  double* zw = new double[(xsz+1)*(ysz+1)];
+
+  double dx,dy;   // taille du bin 
+  dx = (mXmax-mXmin)*mScx/xsz; 
+  dy = (mYmax-mYmin)*mScy/ysz;
+ 
+  int i1,j1;
+  int i,j,k,l;
+  double x,y,z,xp,yp,zp;
+
+  k = 0;
+  for(i=0; i<xsz; i++) 
+    for(j=0; j<ysz; j++) { 
+      ijzp[k].ij = j*xsz+i; 
+      mArr->XYfromxy(i,j,x,y);
+      x *= mScx; x += dx/2.;
+      y *= mScy; y += dy/2.;
+      ijzp[k].zh = mArr->Value(i,j);
+      z = ijzp[k].zh * mScz;
+      g3->C3DC2ObsCS(x,y,z,xp,yp,zp);
+      ijzp[k].dp = zp; 
+      k++;
+
+// Calcul de la projection du coin de la facette
+      x -= dx/2.;   y -= dy/2.;
+      i1 = (i>0) ? i-1 : 0;
+      j1 = (j>0) ? j-1 : 0;
+      z = mArr->Value(i,j) + mArr->Value(i1,j) + mArr->Value(i1,j1) +  mArr->Value(i,j1);
+      z = z/4.*mScz;        
+//      g3->Proj3DC2GrC(x,y,z, xw[j*(xsz+1)+i], yw[j*(xsz+1)+i]);
+      xw[j*(xsz+1)+i] = x;      yw[j*(xsz+1)+i] = y;    zw[j*(xsz+1)+i] = z;    
+    }
+
+  j = ysz;
+  for(i=0; i<xsz; i++) {
+     mArr->XYfromxy(i,j-1,x,y);
+     x *= mScx; 
+     y *= mScy; y += dy;
+     i1 = (i>0) ? i-1 : 0;
+     j1 = j-1;
+     z = mArr->Value(i,j-1) + mArr->Value(i1,j-1) + mArr->Value(i1,j1) +  mArr->Value(i,j1);
+     z = z/4.*mScz;
+//     g3->Proj3DC2GrC(x,y,z, xw[j*(xsz+1)+i], yw[j*(xsz+1)+i]);     
+     xw[j*(xsz+1)+i] = x;      yw[j*(xsz+1)+i] = y;   zw[j*(xsz+1)+i] = z;   
+  }
+  i = xsz;
+  for(j=0; j<ysz; j++) {
+     mArr->XYfromxy(i-1,j,x,y);
+     x *= mScx; x += dx;
+     y *= mScy; 
+     i1 = i-1;
+     j1 = (j>0) ? j-1 : 0;
+     z = mArr->Value(i-1,j) + mArr->Value(i1,j) + mArr->Value(i1,j1) +  mArr->Value(i-1,j1);
+     z = z/4.*mScz;
+//     g3->Proj3DC2GrC(x,y,z, xw[j*(xsz+1)+i], yw[j*(xsz+1)+i]);     
+     xw[j*(xsz+1)+i] = x;      yw[j*(xsz+1)+i] = y;   zw[j*(xsz+1)+i] = z;   
+  }
+  i = xsz;  j = ysz;
+  mArr->XYfromxy(i-1,j-1,x,y);
+  i1 = i-1;   j1 = j-1;
+  x *= mScx; x += dx;
+  y *= mScy; y += dy;
+  z = mArr->Value(i-1,j-1) + mArr->Value(i1,j-1) + mArr->Value(i1,j1) +  mArr->Value(i-1,j1);
+  z = z/4.*mScz;
+//  g3->Proj3DC2GrC(x,y,z, xw[j*(xsz+1)+i], yw[j*(xsz+1)+i]);     
+  xw[j*(xsz+1)+i] = x;      yw[j*(xsz+1)+i] = y;    zw[j*(xsz+1)+i] = z;   
+
+// On trie par ordre de distance zp de projection / observateur, du plus loin au plus proche
+  qsort(ijzp,(size_t) k,sizeof(ZPSORT),ijzpsort);
+
+  PIGrCoord xg[5],yg[5],zg[5];
+  PIColors mfcol = GetGraphicAtt().GetFgColor();
+  PIColors fgc = mfcol;
+
+
+  if (GetGraphicAtt().GetColMapId() == CMAP_OTHER) {   // Trace avec des lignes
+    if (GetGraphicAtt().GetLineAtt() == PI_NotDefLineAtt)    g3->SelLine(PI_ThinLine);
+    fgc = (mfcol  == PI_NotDefColor ) ? PI_Black : mfcol;
+    for(l=0;l<k;l++) {
+      i =  ijzp[l].ij%xsz;
+      j =  ijzp[l].ij/xsz;
+      xg[4] = xg[0] = xw[i+j*(xsz+1)];    yg[4] = yg[0] = yw[i+j*(xsz+1)];  
+      zg[4] = zg[0] =   zw[i+j*(xsz+1)];
+      xg[1] = xw[i+1+j*(xsz+1)];          yg[1] = yw[i+1+j*(xsz+1)];   
+      zg[1] = zw[i+1+j*(xsz+1)];   
+      xg[2] = xw[i+1+(j+1)*(xsz+1)];      yg[2] = yw[i+1+(j+1)*(xsz+1)];
+      zg[2] = zw[i+1+(j+1)*(xsz+1)];
+      xg[3] = xw[i+(j+1)*(xsz+1)];        yg[3] = yw[i+(j+1)*(xsz+1)];  
+      zg[3] = zw[i+(j+1)*(xsz+1)]; 
+// On efface derriere 
+      g3->SelForeground(PI_White);
+//      g3->BaseGraphic()->DrawFPolygon(xg,yg,5);
+      g3->DrawFPolygon3D(xg,yg,zg,5);
+// On trace 
+      g3->SelForeground(fgc);
+//      g3->BaseGraphic()->DrawPolygon(xg,yg,5);
+      g3->DrawPolygon3D(xg,yg,zg,5);
+    }
+  }
+  else {   // Trace avec niveaux de couleur
+    PIColorMap* cmap = new PIColorMap(GetGraphicAtt().GetColMapId());
+    CMapId mcmapid = GetGraphicAtt().GetColMapId();
+    if ( (mcmapid == CMAP_GREY32) || (mcmapid == CMAP_GREYINV32) || 
+         (mcmapid == CMAP_GREY128)  || (mcmapid == CMAP_GREYINV128) )
+      fgc = ( mfcol == PI_NotDefColor ) ? PI_Red : mfcol;
+    else  fgc = ( mfcol == PI_NotDefColor ) ? PI_Black : mfcol;
+    for(l=0;l<k;l++) {
+      i =  ijzp[l].ij%xsz;
+      j =  ijzp[l].ij/xsz;
+      xg[4] = xg[0] = xw[i+j*(xsz+1)];    yg[4] = yg[0] = yw[i+j*(xsz+1)];  
+      zg[4] = zg[0] =   zw[i+j*(xsz+1)];
+      xg[1] = xw[i+1+j*(xsz+1)];          yg[1] = yw[i+1+j*(xsz+1)];   
+      zg[1] = zw[i+1+j*(xsz+1)];   
+      xg[2] = xw[i+1+(j+1)*(xsz+1)];      yg[2] = yw[i+1+(j+1)*(xsz+1)];
+      zg[2] = zw[i+1+(j+1)*(xsz+1)];
+      xg[3] = xw[i+(j+1)*(xsz+1)];        yg[3] = yw[i+(j+1)*(xsz+1)];  
+      zg[3] = zw[i+(j+1)*(xsz+1)]; 
+// On efface derriere 
+      g3->SelForeground(*cmap, mLut->ApplyFast(ijzp[l].zh));
+      g3->DrawFPolygon3D(xg,yg,zg,5);
+// On trace 
+      if (GetGraphicAtt().GetLineAtt() == PI_NotDefLineAtt)   continue;
+      g3->SelForeground(fgc);
+      g3->DrawPolygon3D(xg,yg,zg,5);
+    }
+      
+  }
+
+  delete[] ijzp;
+  delete[] xw; 
+  delete[] yw;
+  delete[] zw;
+}
Index: /tags/V_Dec2002/SophyaPI/PI/pisurfdr.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pisurfdr.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pisurfdr.h	(revision 2309)
@@ -0,0 +1,32 @@
+// Module PI : Peida Interactive PISurfaceDrawer
+// Drawer et DrawWidget 3D       R. Ansari 06/98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PISURFDRW_H_SEEN
+#define PISURFDRW_H_SEEN
+
+#include "parradapter.h"
+#include "pi3ddrw.h"
+
+// Trace d une surface defini par Z=f(x,y)  travers un tableau 
+class PISurfaceDrawer : public PIDrawer3D {
+public :
+  			PISurfaceDrawer(P2DArrayAdapter* arr, bool asxy=false, bool asz=true, bool ad = true);
+  			~PISurfaceDrawer();
+
+  virtual void 		UpdateLimits();   // Calcule et change la vue-3D
+
+  virtual void 		Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax); 
+  virtual void       	DrawAxes(PIGraphicUC* g);
+
+protected :
+  P2DArrayAdapter* mArr;
+  bool mAda;
+  double mScz, mScx, mScy;
+  double mXmin, mXmax;
+  double mYmin, mYmax;
+  double mZmin, mZmax;
+  LUT* mLut;
+};
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pisysdep.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pisysdep.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pisysdep.h	(revision 2309)
@@ -0,0 +1,53 @@
+#ifndef PISYSDEP_SEEN
+#define PISYSDEP_SEEN
+
+#include "machdefs.h"
+
+#ifdef __MWERKS__         // Macintosh
+
+  #define PIWDG_H  "piwdgmac.h"
+  #define PICONT_H "picontainermac.h"
+  #define PIWIN_H  "piwindowmac.h"
+  #define PISTDWDG_H "pistdwdgmac.h"
+  #define PIMENU_H "pimenumac.h"
+  #define PIMENUBAR_H "pimenubarmac.h"
+  #define PIOPTMENU_H "pioptmenumac.h"
+  #define PIFILECHO_H "pifilechomac.h"
+  #define PILIST_H "pilistmac.h"
+
+  #define PIAPP_H "piapplmac.h"
+  #define PIPERIODIC_H "piperiodmac.h"
+  
+  #define PIFONT_H "pifontmac.h"
+  #define PIGRAPHIC_H "pigraphmac.h"
+  #define PICMAPNTV_H "picmapmac.h"
+  #define PICMAP_H "picmap.h"
+
+  #define PIBWDG_H "pibwdgmac.h"
+  #define PIPIXMAP_H "pipixmapmac.h"
+
+#else                  // XWindow
+  #define PIWDG_H  "piwdgx.h"
+  #define PICONT_H "picontainerx.h"
+  #define PIWIN_H  "piwindowx.h"
+  #define PISTDWDG_H "pistdwdgx.h"
+  #define PIMENU_H "pimenux.h"
+  #define PIMENUBAR_H "pimenubarx.h"
+  #define PIOPTMENU_H "pioptmenux.h"
+  #define PIFILECHO_H "pifilechox.h"
+  #define PILIST_H "pilistx.h"
+
+  #define PIAPP_H "piapplx.h"
+  #define PIPERIODIC_H "piperiodx.h"
+
+  #define PIFONT_H "pifontx.h"
+  #define PIGRAPHIC_H "pigraphx.h"
+  #define PICMAPNTV_H "picmapx.h"
+  #define PICMAP_H "picmap.h"
+
+  #define PIBWDG_H "pibwdgx.h"
+  #define PIPIXMAP_H "pipixmapx.h"
+
+#endif
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/pitherm.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pitherm.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pitherm.cc	(revision 2309)
@@ -0,0 +1,206 @@
+// Module PI : Peida Interactive   PIThermometer
+// Thermometre                   R. Ansari  05/00
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "pitherm.h"
+
+//++
+// Class	PIThermometer
+// Lib		PI
+// include	pitherm.h
+//
+//   	Classe permettant la visualisation d'une valeur sous forme 
+//   	d'une barre de progression ou d'un thermomètre, avec trois 
+//	couleurs différentes, suivant deux valeurs de seuil.
+//--
+//++
+// Links	Parents
+// PIBaseWdg
+//--
+
+//++
+// Titre	Constructeur
+//--
+//++
+//  PIThermometer(PIContainerGen *par, char *nom, int sx=256, int sy=10, int px=0, int py=0)
+//	Constructeur - Le choix d'affichage (vertical ou horizontal) dépend
+//	du rapport des tailles "sx", "sy"
+//--
+
+
+/* --Methode-- */
+PIThermometer::PIThermometer(PIContainerGen *par, char *nom,
+                       int sx, int sy, int px, int py) 
+: PIBaseWdg(par, nom, sx, sy, px, py)
+
+{
+  SetMinMax();
+  val_ = 0.;
+  SetThreshold();
+  SetColors();
+  lastperc_ = 0.;
+}
+
+/* --Methode-- */
+PIThermometer::~PIThermometer()
+{
+}
+
+//++
+// Titre	Méthodes
+//--
+//++
+// long  kind()
+//	Retourne PIThermometer::ClassId .
+//--
+
+//++
+// void  SetMinMax(double min=0., double max=1.)
+//	Définit les valeurs minimum et maximum du thermomètre.
+// void  GetMinMax(double& min, double& max)
+//	Retourne les valeurs minimum et maximum du thermomètre.
+// void  SetValue(double val)
+//	Définit la valeur actuelle du thermomètre.
+// void  GetValue()
+//	Retourne la valeur actuelle du thermomètre.
+//--
+
+/* --Methode-- */
+void
+PIThermometer::SetMinMax(double min, double max)
+{
+  if (max <= min) return;
+  min_ = min;  max_ = max;   
+}
+
+/* --Methode-- */
+void 
+PIThermometer::GetMinMax(double& min, double& max)
+{
+  min = min_;  max = max_; 
+}
+
+/* --Methode-- */
+void
+PIThermometer::SetValue(double val)
+//	Définit la valeur actuelle du thermomètre.
+{
+  val_ = val;   
+  Refresh();
+}
+
+/* --Methode-- */
+double
+PIThermometer::GetValue()
+{
+return val_;
+}
+
+//++
+// void  SetThreshold(double t1=0.75, double t2=0.9)
+//	Définit les deux seuils pour les changements de couleurs.
+// void  GetThreshold(double& t1, double& t2)
+//	Retourne les deux seuils pour les changements de couleurs.
+// void  SetColors(PIColors c1=PI_Green, PIColors c2=PI_Yellow, PIColors c3=PI_Red)
+//	Définit les trois couleurs utilisées pour l'affichage.
+//|	Val : .... < Seuil1 <  ....  < Seuil2 <  ....
+//|	       c1               c2                c3
+//|     
+//--
+
+/* --Methode-- */
+void
+PIThermometer::SetThreshold(double t1, double t2)
+{
+  thr1_ = t1;   thr2_ = t2;  
+}
+
+/* --Methode-- */
+void
+PIThermometer::GetThreshold(double& t1, double& t2)
+{
+  t1 = thr1_;   t2 = thr2_;  
+}
+
+
+/* --Methode-- */
+void
+PIThermometer::SetColors(PIColors c1, PIColors c2, PIColors c3)
+{
+  lowc_ = c1;  medc_ = c2;  highc_ = c3;
+}
+ 
+/* --Methode-- */
+//++
+// void  Draw(PIGraphicGen* g, int x0, int y0, int dx, int dy)
+//	Méthode effectuant l'affichage.
+//--
+void PIThermometer::Draw(PIGraphicGen* g, int /*x0*/, int /*y0*/, int /*dx*/, int /*dy*/)
+{
+  double delta = (max_-min_);
+  if (delta < 1.e-39) delta = 1.e-39;
+
+  double perc = (val_-min_)/delta;
+  int sx = XSize(); 
+  int sy = YSize(); 
+  if (perc < lastperc_)  
+    EraseWindow(0, 0, XSize(), YSize());
+  
+  g->SelForeground(PI_Black);
+  g->DrawBox(0, 0, sx, sy);
+  
+  lastperc_ = perc;
+  char buff[32];
+  sprintf(buff, "%d%%", (int)(perc*100.));
+
+  if (perc < 0.) perc = 0.;
+  if (perc > 1.) perc = 1.;
+  // Representation verticale si SizeY > SizeX 
+  // ou horizontale  si SizeX > SizeY
+  if (perc < thr1_)  g->SelForeground(lowc_);
+  else if (perc < thr2_)  g->SelForeground(medc_);
+  else g->SelForeground(highc_);
+
+  int w,h,fa,fd;
+  g->SelFont(PI_NormalSizeFont, PI_BoldFont);
+  w = g->GetFont().GetStringWidth(buff);
+  h = g->GetFont().GetFontHeight(fa, fd);
+
+  g->SelLine(PI_ThinLine);
+  if (sx > sy) {    // horizontal
+    int dx = (double)(sx-2)*perc; 
+    g->DrawFBox(1, 1, dx, sy-2);
+    int dcx = (sy-2)*0.66;
+    int cx = 1+dcx;   
+    g->SelForeground(PI_Grey);
+    while (cx <= dx) {
+      g->DrawLine(cx, 1, cx, sy-2);
+      cx += dcx;
+    }
+    g->SelForeground(PI_Black);
+    cx = ((dx-w-2)>=1) ? (dx-w-2) : 1;  
+    g->DrawString(cx, sy/2-1+h/2, buff);
+  }
+  else  {    // vertical
+    int dy = (double)(sy-2)*perc;
+    g->DrawFBox(1, (sy-dy-1), sx-2, dy);
+    int dcy = (sx-2)*0.66;
+    int cy = sy-1-dcy;
+    g->SelForeground(PI_Grey);
+    while (cy > (sy-dy-1)) {
+      g->DrawLine(1, cy, sx-2, cy);
+      cy -= dcy;
+    }
+    g->SelForeground(PI_Black);
+    cy = ((dy+1+h) < sy-1) ? (dy+1+h) : sy-2;
+    g->DrawString((sx-w)/2, cy, buff);    
+  }
+  
+  return;
+}
+
+
+
+
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/pitherm.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pitherm.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pitherm.h	(revision 2309)
@@ -0,0 +1,45 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive     PIThermometer
+// Thermometre                   R. Ansari  05/00
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PITHERM_H_SEEN
+#define PITHERM_H_SEEN
+
+#include "pisysdep.h"
+
+#include PIBWDG_H
+
+class PIThermometer : public PIBaseWdg
+{
+public:
+  enum {ClassId = 5160};
+
+                  PIThermometer(PIContainerGen *par, char *nom,
+                                int sx=256, int sy=10, int px=0, int py=0);
+  virtual         ~PIThermometer();
+
+  virtual long	  kind() {return ClassId; }
+  virtual void    SetMinMax(double min=0., double max=1.);
+  virtual void    GetMinMax(double& min, double& max);
+  virtual void    SetValue(double val);
+  virtual double  GetValue(); 
+  virtual void    SetThreshold(double t1=0.75, double t2=0.9);
+  virtual void    GetThreshold(double& t1, double& t2);
+  virtual void    SetColors(PIColors c1=PI_Green, PIColors c2=PI_Yellow, 
+                            PIColors c3=PI_Red);
+
+// Traitement des evenements   
+
+  virtual void   Draw(PIGraphic* g, int x0, int y0, int dx, int dy);
+
+
+protected:
+  double min_, max_, val_;
+  double thr1_, thr2_;
+  PIColors lowc_, medc_, highc_;
+  double lastperc_;
+};
+
+
+#endif 
Index: /tags/V_Dec2002/SophyaPI/PI/piup.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piup.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piup.cc	(revision 2309)
@@ -0,0 +1,61 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "ctimer.h"
+#include "imageop.h"
+
+#include "piup.h"
+
+RzImage * PIUserProc_1(ImageR4& myimg, int xp, int yp, int dx, int dy,
+                       char * arg1, char * arg2)
+{
+printf("**** PIUserProc_1 Pave[%d*%d] en (%d,%d) %s %s  Filtrage passe-bas 3*3 \n",
+       dx, dy, xp, yp, arg1, arg2);
+ImageR4 filt(3,3);
+ImageR4 * out;
+
+// Definition du filtre passe-bas
+int i,j;
+for(i=0; i<3; i++)
+  for(j=0; j<3; j++)  filt(i,j) = 0.1;
+filt(1,1) = 0.2;
+
+filt.PrintImage();
+out = new ImageR4(myimg.XSize(), myimg.YSize());
+TIMEF ;
+FilterImage(&myimg, out, &filt); 
+return((RzImage*)out);
+}
+ 
+RzImage * PIUserProc_2(ImageR4& myimg, int xp, int yp, int dx, int dy,
+                       char * arg1, char * arg2)
+{
+printf("**** PIUserProc_2 Pave[%d*%d] en (%d,%d) %s %s  Ombre 3*3 \n",
+       dx, dy, xp, yp, arg1, arg2);
+printf(" PIUserProc_2(%d %d %s %s)  Ombre 3*3 \n", xp, yp, arg1, arg2);
+ImageR4 filt(3,3);
+ImageR4 * out;
+
+// Definition du filtre ombre
+int i,j;
+filt(0,0) = filt(1,1) = filt(2,2) = 0.;
+filt(0,1) = filt(1,2) = -1.;
+filt(1,0) = filt(2,1) = 1.;
+filt(0,2) = -2.;
+filt(2,0) = 2.;
+filt.PrintImage();
+out = new ImageR4(myimg.XSize(), myimg.YSize());
+TIMEF ;
+FilterImage(&myimg, out, &filt); 
+return((RzImage*)out);
+}
+
+ 
+RzImage * PIUserProc_3(ImageR4& , int xp, int yp, int dx, int dy,
+                       char * arg1, char * arg2)
+{
+printf("PIUserProc_3 Pave[%d,%d] en (%d %d) %s %s ne fait rien !\n", 
+       dx, dy, xp, yp, arg1, arg2);
+return(NULL);
+}
Index: /tags/V_Dec2002/SophyaPI/PI/piup.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piup.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piup.h	(revision 2309)
@@ -0,0 +1,10 @@
+#include "cimage.h"
+extern "C" {
+RzImage * PIUserProc_1(ImageR4& myimg, int xp, int yp, int dx, int dy,
+                       char * arg1, char * arg2);
+RzImage * PIUserProc_2(ImageR4& myimg, int xp, int yp, int dx, int dy,
+                       char * arg1, char * arg2);
+RzImage * PIUserProc_3(ImageR4& myimg, int xp, int yp, int dx, int dy, 
+                       char * arg1, char * arg2);
+}
+
Index: /tags/V_Dec2002/SophyaPI/PI/piup_def.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piup_def.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piup_def.cc	(revision 2309)
@@ -0,0 +1,33 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "ctimer.h"
+#include "imageop.h"
+
+#include "piup.h"
+
+RzImage * PIUserProc_1(ImageR4 & , int xp, int yp, int dx, int dy,
+                       char * arg1, char * arg2)
+{
+printf("PIUserProc_1/Dummy Pave[%d,%d] en (%d %d) %s %s ne fait rien !\n", 
+       dx, dy, xp, yp, arg1, arg2);
+return(NULL);
+}
+ 
+RzImage * PIUserProc_2(ImageR4 & , int xp, int yp, int dx, int dy,
+                       char * arg1, char * arg2)
+{
+printf("PIUserProc_2/Dummy Pave[%d,%d] en (%d %d) %s %s ne fait rien !\n", 
+       dx, dy, xp, yp, arg1, arg2);
+return(NULL);
+}
+ 
+RzImage * PIUserProc_3(ImageR4 & , int xp, int yp, int dx, int dy,
+                       char * arg1, char * arg2)
+{
+printf("PIUserProc_3/Dummy Pave[%d,%d] en (%d %d) %s %s ne fait rien !\n", 
+       dx, dy, xp, yp, arg1, arg2);
+return(NULL);
+}
+ 
Index: /tags/V_Dec2002/SophyaPI/PI/piupdattachment.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piupdattachment.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piupdattachment.cc	(revision 2309)
@@ -0,0 +1,104 @@
+#include "piupdattachment.h"
+//const MessageT	msg_MouseUp			= 819;
+
+PIUpdAttachment* PIUpdAttachment::lastCursPane = NULL;
+bool PIUpdAttachment::hit = false;
+int PIUpdAttachment::down = 0;
+
+PIUpdAttachment::PIUpdAttachment(PIBaseWdgMac* wdg)
+: LAttachment(), myWdg(wdg)
+{
+  myGraphic = (PIGraphicMac*) wdg->WindowGraphic();
+}
+
+PIUpdAttachment::~PIUpdAttachment()
+{
+  if (lastCursPane == this) lastCursPane = NULL;
+  delete myGraphic;
+}
+
+void PIUpdAttachment::ExecuteSelf(MessageT msg, void* data)
+{
+  if (myWdg)
+    switch(msg) {
+      case msg_DrawOrPrint:
+        myWdg->Draw(myGraphic,0,0,999999,999999);
+ 		break;
+      case msg_Resize:
+        myWdg->Resize();
+ 		break;
+      case msg_Move:
+//        myWdg->Move();
+        break;
+//      case cmd_Close: {
+//        delete myWdg;
+//        break;
+//      }
+      case msg_Click: {
+        SMouseDownEvent* evt = (SMouseDownEvent*) data;
+        EventModifiers mod = evt->macEvent.modifiers;
+        if ((mod & cmdKey) && (mod & optionKey))
+          { myWdg->But3Press(evt->whereLocal.h,evt->whereLocal.v); down = 3;}
+        else if (mod & cmdKey)
+          { myWdg->But2Press(evt->whereLocal.h,evt->whereLocal.v); down = 2;}
+        else
+          { myWdg->But1Press(evt->whereLocal.h,evt->whereLocal.v); down = 1;}
+ 		break;
+ 		}
+ 	  case msg_KeyPress: {
+ 	    EventRecord* evt = (EventRecord*) data;
+ 	    PIKeyModifier kmod = PIKM_Blank;
+ 	    if (evt->modifiers & shiftKey)
+ 	      kmod = (PIKeyModifier) (kmod | PIKM_Shift);
+ 	      //kmod |= PIKM_Shift;  // Ca devrait passer !!!
+ 	    if (evt->modifiers & optionKey)
+ 	      kmod = (PIKeyModifier) (kmod | PIKM_Alt);
+ 	    if (evt->modifiers & controlKey)
+ 	      kmod = (PIKeyModifier) (kmod | PIKM_Cntl);
+ 	    myWdg->Keyboard(evt->message & charCodeMask, kmod);
+ 	    break;
+ 	    }
+ 	  case msg_AdjustCursor: {
+ 	    EventRecord* evt = (EventRecord*) data;
+ 	    if (lastCursPane != this) {
+ 	      if (lastCursPane)
+ 	        lastCursPane->myWdg->Leave();
+ 	      myWdg->Enter();
+ 	      lastCursPane = this;
+ 	    }
+ 	    hit = true;
+ 	    SetExecuteHost(!myWdg->AdjustCursor());
+ 	    // Est-ce un move, i.e. le bouton est-il toujours appuye depuis le dernier MouseDown ?
+ 	    if (::StillDown() && down) {
+ 	      Point pt = evt->where;
+ 	      myWdg->mPane->GlobalToPortPoint(pt);
+ 	      myWdg->mPane->PortToLocalPoint(pt);
+ 	      if (lastPt.h != pt.h || lastPt.v != pt.v) {
+ 	        lastPt = pt;
+            EventModifiers mod = evt->modifiers;
+            if ((mod & cmdKey) && (mod & optionKey))
+              myWdg->Ptr3Move(pt.h,pt.v);
+            else if (mod & cmdKey)
+              myWdg->Ptr2Move(pt.h,pt.v);
+            else
+              myWdg->Ptr1Move(pt.h,pt.v);
+          }
+ 	    } else if (down) {  // A changer le jour ou les attachements recoivent les mouseup.
+ 	      Point pt = evt->where;
+ 	      myWdg->mPane->GlobalToPortPoint(pt);
+ 	      myWdg->mPane->PortToLocalPoint(pt);
+          EventModifiers mod = evt->modifiers;
+          //if ((mod & cmdKey) && (mod & optionKey))
+          if (down == 3)
+            myWdg->But3Release(pt.h,pt.v);
+          //else if (mod & cmdKey)
+          else if (down == 2)
+            myWdg->But2Release(pt.h,pt.v);
+          else
+            myWdg->But1Release(pt.h,pt.v);
+ 	      down = 0;
+        }
+ 	    break;
+ 	    }
+    }
+}
Index: /tags/V_Dec2002/SophyaPI/PI/piupdattachment.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piupdattachment.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piupdattachment.h	(revision 2309)
@@ -0,0 +1,28 @@
+
+#include <LAttachment.h>
+
+#include "pibwdgmac.h"
+
+const MessageT	msg_Resize			= 817;
+const MessageT	msg_Move			= 818;
+
+class PIUpdAttachment : public LAttachment {
+public:
+  PIUpdAttachment(PIBaseWdgMac* wdg);
+  ~PIUpdAttachment();
+  
+protected:
+ virtual void	ExecuteSelf(
+							MessageT		inMessage,
+							void			*ioParam);
+
+ PIBaseWdgMac* myWdg;
+ PIGraphicMac* myGraphic;
+ 
+ friend class PIPPApplMac;
+ static PIUpdAttachment* lastCursPane;
+ static bool hit;
+ static int down;
+ Point lastPt;
+};
+
Index: /tags/V_Dec2002/SophyaPI/PI/piusmak
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piusmak	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piusmak	(revision 2309)
@@ -0,0 +1,39 @@
+include  $(EROSBASEREP)/Include/MakefileUser.h
+
+%.o:%.cc
+	$(COMPILE.cc) -o $@ $<
+LIBF =  $(SLB)libpeida.so $(SLB)liberosc.so
+LIBS = -L$(SLB) -lpeida -lerosc
+
+#-------------------------------------------------------- 
+all : piup.so
+
+clean:
+	rm -f user.o user.so piup.so
+
+piup.so : user.so
+	cp -p user.so piup.so
+
+user.so : user.o $(LIBF)
+ifeq (${MACHEROS},Linux)
+	$(LINK.cc) -shared -o user.so --whole-archive user.o --nowhole-archive $(LIBS) -lm -lc
+endif
+ifeq (${MACHEROS},OSF1)
+ifeq ($(CXX), cxx)
+	$(LINK.cc) -shared -o user.so -all user.o -none $(LIBS) -lm -lc
+endif
+ifeq ($(CXX), g++)
+	ld -shared -o user.so -all user.o -none $(LIBS) -L$(GLB) -lg++ -lstdc++ -lm -lc
+endif
+endif
+
+user.o: user.cc  $(INC)piup.h \
+ $(INC)perrors.h \
+ $(INC)exceptions.h \
+ $(INC)defs.h \
+ $(INC)cimage.h \
+ $(INC)rzimage.h \
+ $(INC)rzvect.h \
+ $(INC)machine.h \
+ $(INC)datatypes.h \
+ $(INC)utils.h $(INC)peida.h 
Index: /tags/V_Dec2002/SophyaPI/PI/piversion.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piversion.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piversion.h	(revision 2309)
@@ -0,0 +1,6 @@
+#ifndef PIVERSION_H_SEEN
+#define PIVERSION_H_SEEN
+
+#define PI_VERSIONNUMBER  3.90
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/piwdggen.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piwdggen.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piwdggen.cc	(revision 2309)
@@ -0,0 +1,423 @@
+//  Classe de base pour les objets correspondant a une fenetre 
+//  dans les programmes graphiques interactives
+//
+//                  E.Aubourg , R. Ansari  96 - 98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "piwdggen.h"
+#include "picontainergen.h"
+#include "pievthandler.h"
+#include "psfile.h"
+
+//++
+// Class	PIWdg
+// Lib		PI
+// include	piwdggen.h
+//
+//   	Classe de base pour tout objets correspondant à une fenêtre
+//	à l'écran, ayant donc une représentation graphique et 
+//	pouvant jouer un rôle dans la hiérarchie des objets interactif. 
+//	*PIWdg* hérite de *PIMsgHandler*, avec une hiérarchie correspondant
+//	par défaut à celles des PIWdg. La classe "PIWdg" est une des 
+//	classes de PI qui ont une implementation dépendante du systeme utilisé
+//	(Mac, XWindow, ...). La classe "PIWdgGen" est la classe qui
+//	définit l'interface, et ne doit pas être instanciée directement
+//	(Méthodes virtuelles pures). Les objets instanciés sont de la 
+//	classes "PIWdg" et le fichier entête correspondant est "PIWDG_H"
+//	défini dans "pisysdep.h"
+//--
+//++
+// Links	Parents
+// PIMsgHandler
+//--
+//++
+// Links	Voir aussi
+// PIEventHandler
+//--
+
+//++
+// Titre	Constructeur
+//--
+//++
+// PIWdg(PIContainerGen *par, const char *nom, int sx=10, int sy=10, int px=0, int py=0)
+//	Création d'un objet contenu dans l'objet *PIContainer* "par", de
+//	taille "sx,sy", se trouvant à la position "px,py" avec le nom "nom"
+// long kind()
+//	Renvoie le type de la classe de l'objet ("=PIWdgGen::ClassId") pour cette classe
+//	de base. Doit être redéfinie par les classes dérivées.
+//--  
+
+
+//++
+// Titre	Taille, position
+//--
+//++
+// void  PSPrint(PSFile *psf, int ofx=0, int ofy=0)
+//	Méthode virtuelle qui doit être redéfinie pour chacune des classes filles.
+//	produit une représentation graphique de l'objet en Postscript.
+// SetSize(int sx, int sy)
+//	Modifie la taille de l'objet.
+// SetPos(int px, int py)
+//	Modifie la position de l'objet.
+// int  XSize()  YSize()
+//	Renvoient la taille (X,Y) de l'objet.
+// int  XPos()  YPos()
+//	Renvoient la position (X,Y) de l'objet.
+// void  GetScreenPos(int & spx, int & spy)
+//	Renvoie la position de l'objet sur l'écran.
+//--
+
+//++
+// Titre	Decodage des options
+//--
+//++
+// int  DecodeOptionString(vector<string> & opt, bool rmdecopt=true) 
+//	Méthode virtuelle qui peut être redéfinie dans les classes filles,
+//	pour decoder des options a partir de chaines de caracteres.
+//	Renvoie le nombre d'options decodees.
+//--
+
+int PIWdgGen::DecodeOptionString(vector<string> & opt, bool rmdecopt)
+{
+  return(0);
+}
+
+//++
+// Titre	Couleurs, etc ...
+//--
+//++
+// void  SetBackgroundColor(PIColors col=PI_White)
+//	Choix de la couleur de fond.
+// void  SetForegroundColor(PIColors col=PI_Black)
+//	Choix de la couleur d'avant plan.
+// PIColors  GetBackgroundColor()
+//	Renvoie la couleur de fond
+// PIColors  GetForegroundColor()
+//	Renvoie la couleur d'avant-plan.
+// void  EraseWindow(int x0=0, int y0=0, int dx=0, int dy=0) 
+//	Efface la zone rectangulaire définie par le coin "(x0,y0)" ,
+//	de taille "dx,dy" à l'aide de la couleur de fond.
+//--
+
+//++
+// Titre	Gestion des accrochages (Binding)
+//--
+//++
+// void  SetBinding(PIBindingKind left, PIBindingKind top, PIBindingKind right, PIBindingKind bottom)
+//	Permet de contrôler le comportement de l'objet en cas de changement de taille 
+//	du conteneur parent. La position de chaque bord peut être sans contrainte ("PIBK_free")
+//	attachée à une distance fixe par rapport au bord opposé du conteneur ("PIBK_fixed"), 
+//	ou à une position proportionnelle à la taille du conteneur parent. ("PIBK_elastic") 
+// bool  GetBinding((PIBindingKind& left, PIBindingKind& top, PIBindingKind& right, PIBindingKind& bottom)
+//	Permet de connaitre l'état des accrochages. Retourne "true" si les accrochages ont été
+//	verrouillé (appel à "LockBinding()"), "false" sinon.
+// void  LockBinding()
+//	Verrouille l'état des accrochages. Appel à "SetBinding()" sera alors sans effet.
+//	Permet à certains *LayouMgr* d'imposer une contrôle strict.
+// void  UnLockBinding()
+//	Deverrouille les accrochages.
+//--
+
+//++
+// Titre	Etat de l'objet
+//	L'objet peut se trouver dans l'état actif ou inactif. Cet état est contrôlé par les 
+//	méthodes "Manage(), UnManage()". L'objet ne se trouve effectivement dans l'état 
+//	actif que si son conteneur parent est lui même actif.
+//	L'objet peut aussi être affichés, mais insensible aux actions utilisateur
+//	(clavier, souris, ...). Cette sensibilité est controlée par les 
+//	méthodes  "SetSensitive(), SetUnSensitive()".
+//--
+//++
+// void  Manage()  UnManage()
+//	Change l'état de l'objet (actif, inactif)
+// bool  IfManaged()  IfVisible()
+//	indique si l'objet est actif , visible	
+// void  SetSensitive() SetUnSensitive()
+//	Rend l'objet sensible/ insensible aux actions utilisateurs (clavier, souris, ...)
+//	L'état visuel de l'objet peut être modifié en conséquence.
+// bool  IfSensitive() 
+//	indique si l'objet est répond aux sollicitations utilisateur.
+//--
+
+//++
+// Titre	Rafraîchissement de la fenêtre
+//--
+//++
+// void  Refresh()
+//	L'appel à cette méthode permet de retracer le contenu de la 
+//	fenêtre et des "Drawer" associés.
+//--
+
+//++
+// Titre	Méthodes
+//--
+
+//++
+// void SetMsg(PIMessage msg = 0)
+//	Modifie la valeur du message associé à l'objet.
+// PIMessage  Msg()
+//	Renvoie le message associé à l'objet.
+// string  Nom()
+//	Renvoie le nom associé à l'objet.
+// PIWdg*  Parent()
+//	Renvoie le conteneur parent de l'objet.
+// void  SetUserData( void * p, int fg = 0)
+//	Associe un pointeur de données à la disposition de l'utilisateur 
+//	("void* p") à l'objet, ainsi qu'une valeur ("int fg")
+// void* UserData()
+//	Renvoie le pointeur de données user de l'objet. (NULL par défaut)
+// int  UserFlag()
+//	Renvoie la valeur "int" user de l'objet.
+//--
+
+//++
+// Titre	Gestion du copier/coller
+//	L'ensemble des méthodes de gestion de copier/coller sont décrites ici. Les méthodes
+//	"SelectionLost()", "ProvideSelection()", et "PasteSelection()" doivent être 
+//	redéfinies par les classes héritières de *PIWdg* implémentant la fonctionalité
+//	copier/coller. Le mécanisme copier/coller entre objets d'une même application,
+//	ainsi qu'entre différentes applications. Dans les opérations de copier/coller,
+//	il existe un PIWdg ou une application source des données et un PIWdg ou 
+//	une application destinatire.
+//--
+
+//++
+// bool  ClaimSelection(int typ=PICP_string)
+//	Cette méthode doit être appelée par l'objet "PIWdg" source quand celui-ci veut 
+//	s'approprier la zone d'échange de données (Selection) pour le copier/coller. "typ" indique 
+//	le type de données que peut fournir l'objet. Le type "PICP_string" (suite de caractères)
+//	est le seul type supporté actuellement. La valeur de retour est "true" si 
+//	la zone d'échange est attribué a l'objet. Cette méthode ne doit en principe pas 
+//	être redéfinie par les classes héritières de *PIWdg*.
+// void  SelectionLost()
+//	Cette méthode est appelée quand l'objet "PIWdg" source qui possede la zone d'échange 
+//	(Selection) perd celle-ci, suite par exemple à la demande d'un autre objet. Cette méthode 
+//	doit être redéfinies par les classes qui implémentent la fonctionalité et ne doit 
+//	doit pas être appelée directement.
+// int  RequestSelection(int typ=PICP_string)
+//	Cette méthode doit être appelée par l'objet "PIWdg" destinatire quand celui-ci souhaite 
+//	obtenir les données de la zone d'échange (Selection). "typ" indique les types de données 
+//	acceptables par l'objet. La valeur de retour indique le type qui sera fourni
+//	(à l'appel de "PasteSelection()"). Cette méthode ne doit en principe pas 
+//	être redéfinie par les classes héritières de *PIWdg*.
+// void* ProvideSelection(int& typ, int& len)  
+//	Cette méthode est appelée quand l'objet "PIWdg" source, qui possede la zone d'échange 
+//	(Selection) doit  fournir les données correspondantes à la sélection. Renvoie le pointeur 
+//	de la zone mémoire correspondante, sa longueur ("len") et le type ("typ") des données.
+//	cette zone mémoire appartient à l'objet, et ne doit être modifié tant que 
+//	la méthode "SelectionTransferEnd()" n'a été appelé.
+// void  SelectionTransferEnd()
+//	Cette méthode est appelé une fois que l'objet ou l'application destinataire 
+//	des données de sélection a fini de traiter l'opération de copie. l'objet PIWdg 
+//	source peut alors détruire ou modifier les données correspondantes à l'échange.
+// void  PasteSelection(int typ, void *pdata, int l)
+//	Cette méthode est appelée après l'appel à "RequestSelection()" pour l'objet 
+//	destinataire. "typ" indique le type des données dans "pdata", et "l" la longeur. 
+//	La zone mémoire "pdata" n'appartient pas à l'objet destinataire et ne doit pas 
+//	être modifié par celui-ci. Une copie doit être effectué si cesCette méthode  données devaient
+//	être utilisées après la sortie de "PasteSelection()".
+//--
+
+/* --Methode-- */
+PIWdgGen::PIWdgGen(PIContainerGen *par, const char*, int, int, int, int)
+: PIMsgHandler(par)
+{
+parent = par;
+bindingLock = false;
+SetMsg(0);
+SetUserData(NULL, 0);
+//  ChildAdd() doit etre appele par la classe qui implemente le widget
+// if (par)  par->ChildAdd(this);   //  On previent le container parent  
+return;
+}
+
+
+/* --Methode-- */
+PIWdgGen::~PIWdgGen()
+{
+//  ChildDel() doit etre appele par la classe qui implemente le widget
+// if (parent)  parent->ChildDel(this);   //  On previent le container parent 
+list<EvHand>::iterator it;
+for(it= mDHlist.begin(); it != mDHlist.end(); it++) 
+  if ((*it).ad) delete (*it).evh;
+for(it= mEHlist.begin(); it != mEHlist.end(); it++) 
+  if ((*it).ad) delete (*it).evh;
+}
+
+/* --Methode-- */
+void PIWdgGen::SetMsg(PIMessage msg)
+{
+myMsg = msg;
+}
+
+/* --Methode-- */
+void PIWdgGen::GetScreenPos(int & spx, int & spy)
+/*  Renvoie la position de la fenetre par rapport a l'ecran */
+{
+PIWdgGen * wc;
+spx = 0;  spy = 0;
+wc = this;
+
+while (wc) 
+  { spx += wc->XPos();  
+  spy += wc->YPos();  wc = wc->Parent();
+  }
+return;
+}
+
+/* --Methode-- */
+void PIWdgGen::LockBinding()
+{
+bindingLock = true;
+}
+
+/* --Methode-- */
+void PIWdgGen::UnLockBinding()
+{
+bindingLock = false;
+}
+
+/* --Methode-- */
+void PIWdgGen::PSPrint(PSFile *psf, int ofx, int ofy, double scale_x, double scale_y)
+{
+char str[256];
+
+if (!psf) return;
+double dx = (double)XSize()*scale_x;
+double dy = (double)YSize()*scale_y;
+psf->NewBloc((double)ofx+XPos(), (double)ofy+YPos(), dx, dy, dx, dy);
+psf->DrawBox(0., 0., dx, dy);
+sprintf(str,"PIWdgGen::PSPrint() Kind=%ld Name= %s", kind(), Nom().c_str());
+// N.R. 07/08/99 FontName specifie dans DrawString() 
+psf->DrawString(12., 12., str, PI_Black, PI_DefaultFont, PI_RomanFont, 10);
+psf->EndBloc();
+
+return;
+}
+
+//++
+// Titre	Gestion des Draw/Event Handler
+//	Les objets de la classe "PIWdg" peuvent gérer des objets "PIEventHandler" 
+//	qui peuvent prendre en charge une partie du traitement des événements
+//	clavier-souris-écran.
+//--
+
+//++
+// void AddDrawHandler(PIEventHandler* drwh, bool ad=false)
+//	Ajout d'un objet gestionnaire d'événements, responsable du tracé du contenu de la fenêtre.
+//	La méthode "Draw(PIGraphic* g, ...)" sera appelé pour rafraîchir le contenu de la fenêtre.
+// void RemoveDrawHandler(PIEventHandler* drwh)
+//	Suppression d'un objet gestionnaire de tracé. Toutes les réferences sonnt supprimées en cas 
+//	d' enregistrement multiple.
+// void AddEventHandler(PIEventHandler* evh, unsigned long evtmask, bool ad=false)
+//	Ajout d'un objet gestionnaire d'événements. La variable "evtmask" détermine pour
+//	quels types d'événements, la méthode "Process()" du gestionnaire est appelée.
+//|	PIEvent_Resize   (Non implementé en version X11 , 12/98)
+//|	PIEvent_Enter , PIEvent_Leave
+//|	PIEvent_ButxPress, PIEvent_ButxRelease (x=1,2,3)
+//|	PIEvent_PtrMove , PIEvent_PtrxMove (x=1,2,3)
+//|	PIEvent_Keyboard
+//
+// void RemoveEventHandler(PIEventHandler* evh)
+//	Suppression d'un gestionnaire d'événements. Toutes les réferences sonnt supprimées en cas
+//	d' enregistrement multiple, même avec différents masques d'événements.
+//--
+
+/* --Methode-- */
+void PIWdgGen::AddDrawHandler(PIEventHandler* drwh, bool ad)
+{
+EvHand eh;
+eh.evh = drwh; eh.mask = PIEvent_Draw;  eh.ad = ad;
+mDHlist.push_back(eh);
+}
+
+/* --Methode-- */
+void PIWdgGen::RemoveDrawHandler(PIEventHandler* drwh)
+{
+list<EvHand>::iterator it;
+bool found = true;
+while (found) {
+  found = false;
+  for(it= mDHlist.begin(); it != mDHlist.end(); it++) 
+    if ((*it).evh == drwh) { mDHlist.erase(it); found = true; break; }
+  }
+}
+
+/* --Methode-- */
+void PIWdgGen::AddEventHandler(PIEventHandler* evh, unsigned long evtmask, bool ad)
+{
+EvHand eh;
+eh.evh = evh; eh.mask = evtmask;  eh.ad = ad;
+mEHlist.push_back(eh);
+}
+
+/* --Methode-- */
+void PIWdgGen::RemoveEventHandler(PIEventHandler* evh)
+{
+list<EvHand>::iterator it;
+bool found = true;
+while (found) {
+  found = false;
+  for(it= mEHlist.begin(); it != mEHlist.end(); it++) 
+    if ((*it).evh == evh) { mEHlist.erase(it); found = true; break; }
+  }
+}
+
+
+/* --Methode-- 
+string PIWdgGen::kindstr()
+{
+char b[5];
+string s;
+
+b[0] = (char) (kind()&0x000000FF);
+b[1] = (char) ((kind()&0x0000FF00) / 0x100);
+b[2] = (char) ((kind()&0x00FF0000) / 0x10000);
+b[3] = (char) ((kind()&0xFF000000) / 0x1000000);
+b[4] = '\0';
+s = b;
+return(s);
+}
+*/
+
+//++
+// Class	PIScreenBuffer
+// Lib		PI
+// include	piwdggen.h
+//
+//	Classe de tampon de dessin hors écran. Permet la copie du contenu des pixels
+//	depuis et vers des objets "PIWdg", ainsi que depuis et vers d'autres tampon
+//	d'écran. Un objet "PIGraphic" peut-être instancié pour fournir les services
+//	de dessin dans un "PIScreenBuffer"
+//--
+//++
+// Links	Voir aussi
+// PIWdg
+// PIGraphic
+//--
+
+//++
+// Titre	Constructeurs, méthodes
+//--
+//++
+// PIScreenBuffer(int sx, int sy)
+//	Constructeur, création d'un tampon de taille "sx * sy" pixels.
+// int  XSize()
+//	Renvoie la taille en X.
+// int  YSize()
+//	Renvoie la taille en Y.
+//
+//	Pour les opérations de copie, le rectangle source est défini par
+//	la position du coin haut-gauche "(ox,oy)" et la taille "dx * dy" en pixels.
+//	La copie s'effectue sur l'objet destination à partir de l'offset "(x,y)".
+//
+// void CopyFromWdg(PIWdg* wdg, int ox, int oy, int dx, int dy, int x, int y)
+//	Copie depuis l'objet "PIWdg* wdg".
+// void CopyToWdg(PIWdg* wdg, int ox, int oy, int dx, int dy, int x, int y)
+//	Copie vers l'objet "PIWdg* wdg".
+// void CopyFrom(PIScreenBuffer* grb, int ox, int oy, int dx, int dy, int x, int y)
+//	Copie depuis l'objet "PIScreenBuffer* grb"
+//--
Index: /tags/V_Dec2002/SophyaPI/PI/piwdggen.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piwdggen.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piwdggen.h	(revision 2309)
@@ -0,0 +1,153 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive      PIWdgGen
+//                                    Reza 10/95            
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PIWDG_H_SEEN
+#define PIWDG_H_SEEN
+
+#include "machdefs.h"
+#include "pimsghandler.h"
+#include "picolist.h"
+
+#include <string>
+#include <list>
+#include <vector>
+
+
+void PIBeep();
+
+// Les differents types d accrochage aux containers  
+
+enum PIBindingKind {    
+  PIBK_free = 0,
+  PIBK_fixed = 1,
+  PIBK_elastic = 2
+};
+
+enum PICopyPasteKind {    // Pour gerer les types d objets echange en copier/coller
+  PICP_string = 1
+};
+
+class PSFile;
+class PIContainerGen;
+class PIEventHandler;
+
+//  -------------------- Classe PIWdgGen -----------------------
+class PIWdgGen : public PIMsgHandler
+{
+public:
+  enum {ClassId = 100};
+
+                         PIWdgGen(PIContainerGen *par, const char *nom,
+                                   int sx=10, int sy=10, int px=0, int py=0);
+  virtual               ~PIWdgGen();
+  virtual void		 FinishCreate()=0; // apres avoir installe les sous-vues
+
+  virtual long           kind() {return ClassId; }
+//  string               kindstr();
+
+  inline PIContainerGen* Parent() { return( parent ); }
+
+  inline void         	 SetUserData( void * p, int fg = 0) {pdata=p; flag=fg; }
+  inline void*       	 UserData() { return (pdata); };
+  inline void const* 	 UserData() const { return (pdata); };
+  inline int         	 UserFlag() { return(flag); };
+
+
+  virtual void           SetMsg(PIMessage msg = 0);
+  inline  PIMessage      Msg() { return (myMsg); }
+
+  virtual void           SetSize(int sx, int sy)=0;
+  virtual void           SetPos(int px, int py)=0;
+  virtual void           SetBorderWidth(int bw)=0;
+
+//  Divers : couleur de fond, et d'avant plan Effacement fenetre,
+  virtual void           SetBackgroundColor(PIColors col=PI_White)= 0;
+  virtual void           SetForegroundColor(PIColors col=PI_Black)= 0;
+  virtual void           EraseWindow(int x0=0, int y0=0, int dx=0, int dy=0)= 0;
+  virtual PIColors       GetBackgroundColor()= 0;
+  virtual PIColors       GetForegroundColor()= 0;
+
+//   Methode permettant de decoder des options a partir de chaines
+  virtual int            DecodeOptionString(vector<string> & opt, 
+					    bool rmdecopt=true);
+
+//  Gestion des accrochages (binding) aux containers
+  virtual void           SetBinding(PIBindingKind left, PIBindingKind top, 
+                                    PIBindingKind right, PIBindingKind bottom)      =0;
+  virtual bool           GetBinding(PIBindingKind& left, PIBindingKind& top, 
+                                    PIBindingKind& right, PIBindingKind& bottom)    =0;
+  virtual void		 LockBinding();
+  virtual void		 UnLockBinding();
+
+  virtual int            XSize()=0;
+  virtual int            YSize()=0;
+  virtual int            XPos()=0;
+  virtual int            YPos()=0;
+
+  virtual string         Nom()=0;
+  virtual void           GetScreenPos(int & spx, int & spy);
+
+// Pour activer, desactiver un composant graphique (PIWdg)
+  virtual void           Manage()=0;
+  virtual void           UnManage()=0;
+  virtual bool           IfManaged()=0;
+  virtual bool           IsVisible()=0;
+
+//  Fonction qui doit etre appelee pour rafraichir la fenetre 
+  virtual void       	 Refresh()=0;
+
+//  Pour rendre un composant graphique (PIWdg) sensible/insensible 
+//  aux actions utilisateur (souris, clavier, ...)
+  virtual void           SetSensitive()=0;
+  virtual void           SetUnSensitive()=0;
+  virtual bool           IfSensitive()=0;
+
+  virtual void           PSPrint(PSFile *psf, int ofx=0, int ofy=0,
+				 double scale_x=1., double scale_y=1.);
+
+//  Gestion de copier-coller
+  virtual bool           ClaimSelection(unsigned int typ=PICP_string)                     = 0;
+  virtual void           SelectionLost()                                                  = 0;
+  virtual unsigned int   RequestSelection(unsigned int typ=PICP_string)                   = 0;
+  virtual void*          ProvideSelection(unsigned int& typ, unsigned int& len)           = 0;
+  virtual void           SelectionTransferEnd()                                           = 0;
+  virtual void           PasteSelection(unsigned int typ, void *pdata, unsigned int l)    = 0;
+
+//  Copie depuis un PIWdgGen
+  virtual void		 CopyFrom(PIWdgGen* wdg, int ox, int oy, int dx, int dy, int x, int y) = 0;
+
+//  Gestion des EventHandler
+  virtual void		 AddDrawHandler(PIEventHandler* drwh, bool ad=false);
+  virtual void		 RemoveDrawHandler(PIEventHandler* drwh);
+  virtual void		 AddEventHandler(PIEventHandler* evh, unsigned long evtmask, bool ad=false);
+  virtual void		 RemoveEventHandler(PIEventHandler* evh);
+
+// !! Devrait etre protected - mis ici a cause de cxx  Reza 12/98
+  struct EvHand { PIEventHandler* evh; unsigned long mask;  bool ad; };
+protected:
+  PIContainerGen*        parent;
+  PIMessage              myMsg;
+  list<EvHand>		 mDHlist;
+  list<EvHand>		 mEHlist;
+  bool			 bindingLock;
+private:
+  int flag;
+  void * pdata;
+};
+
+// ---- La classe PIScreenBuffer doit se conformer a l'interface suivante
+// class PIScreenBuffer {
+// public :
+//  			PIScreenBuffer(int sx, int sy);
+//  virtual		~PIScreenBuffer();
+//  virtual int         XSize();
+//  virtual int         YSize();
+//  virtual  void 	CopyFromWdg(PIWdg* wdg, int ox, int oy, int dx, int dy, int x, int y);
+//  virtual  void 	CopyToWdg(PIWdg* wdg, int ox, int oy, int dx, int dy, int x, int y);
+//  virtual  void 	CopyFrom(PIScreenBuffer* grb, int ox, int oy, int dx, int dy, int x, int y);
+// };
+  
+
+#endif/* PIWDG_H_SEEN */
Index: /tags/V_Dec2002/SophyaPI/PI/piwdgmac.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piwdgmac.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piwdgmac.cc	(revision 2309)
@@ -0,0 +1,332 @@
+#include "piwdgmac.h"
+#include "pisysdep.h"
+
+#include PICONT_H
+
+#include <LView.h>
+#include <LString.h>
+
+void PIBeep()
+{
+  ::SysBeep(1);
+}
+
+
+PIWdgMac::PIWdgMac(PIContainerGen *par, char *nom,
+                   int sx, int sy, int px, int py)
+:PIWdgGen(par, nom, sx, sy, px, py), mNom(nom)
+{
+  mAdapterPaneInfo.paneID    = 0;
+  mAdapterPaneInfo.width     = sx;
+  mAdapterPaneInfo.height    = sy;
+  mAdapterPaneInfo.visible   = true;
+  mAdapterPaneInfo.enabled   = true;
+  mAdapterPaneInfo.bindings.left =
+    mAdapterPaneInfo.bindings.top =
+    mAdapterPaneInfo.bindings.right =
+    mAdapterPaneInfo.bindings.bottom = false;
+  mAdapterPaneInfo.left      = px;
+  mAdapterPaneInfo.top       = py;
+  mAdapterPaneInfo.userCon   = 0;
+  mAdapterPaneInfo.superView = par ? (LView*) (((PIContainerMac*)(par))->mPane) : NULL;
+
+  mAdapterViewInfo.imageSize.width = sx;
+  mAdapterViewInfo.imageSize.height = sy;
+  mAdapterViewInfo.scrollPos.h = 
+    mAdapterViewInfo.scrollPos.v = 
+    mAdapterViewInfo.scrollUnit.h = 
+    mAdapterViewInfo.scrollUnit.v = 0;
+  mAdapterViewInfo.reconcileOverhang = 0;
+
+  mAdapter = new PIPPViewAdapter(mAdapterPaneInfo, mAdapterViewInfo);
+
+  mPaneInfo.paneID    = 'PIWD';
+  mPaneInfo.width     = sx;
+  mPaneInfo.height    = sy;
+  mPaneInfo.visible   = true;
+  mPaneInfo.enabled   = true;
+  mPaneInfo.bindings.left =
+    mPaneInfo.bindings.top =
+    mPaneInfo.bindings.right =
+    mPaneInfo.bindings.bottom = true;
+  mPaneInfo.left      = 0;
+  mPaneInfo.top       = 0;
+  mPaneInfo.userCon   = 'PIWD';
+  mPaneInfo.superView = mAdapter;
+
+  mViewInfo.imageSize.width = sx;
+  mViewInfo.imageSize.height = sy;
+  mViewInfo.scrollPos.h = 
+    mViewInfo.scrollPos.v = 
+    mViewInfo.scrollUnit.h = 
+    mViewInfo.scrollUnit.v = 0;
+  mViewInfo.reconcileOverhang = 0;
+  
+  mPane = new LView(mPaneInfo, mViewInfo);
+  ((LView*)mAdapter)->CalcPortOrigin();
+  ((LView*)mPane)->CalcPortOrigin();
+}
+
+
+PIWdgMac::~PIWdgMac()
+{
+  delete mPane;
+  delete mAdapter;
+}
+
+void
+PIWdgMac::FinishCreate()
+{
+  mPane->FinishCreate();
+}
+
+void
+PIWdgMac::ListenToMessage(MessageT /*inMessage*/, void */*ioParam*/)
+{
+
+}
+
+void
+PIWdgMac::SetLabel(string const& lab)
+{
+  LStr255 titre(lab.c_str());
+  mPane->SetDescriptor(titre);
+}
+
+void
+PIWdgMac::SetSize(int sx, int sy)
+{
+  if (mAdapter)
+   mAdapter->ResizeFrameTo(sx, sy, true);
+  else
+   mPane->ResizeFrameTo(sx, sy, true);
+}
+
+void
+PIWdgMac::SetPos(int px, int py)
+{
+  if (mAdapter)
+   mAdapter->MoveBy(px-XPos(), py-YPos(), false);
+  else
+   mPane->MoveBy(px-XPos(), py-YPos(), false);
+}
+
+void
+PIWdgMac::SetBinding(PIBindingKind left, PIBindingKind top, 
+                     PIBindingKind right, PIBindingKind bottom)
+{
+  if (mAdapter)  
+    mAdapter->SetBinding(left, top, right, bottom);
+  //else
+  //  mPane->SetBinding(left, top, right, bottom);
+}
+
+bool
+PIWdgMac::GetBinding(PIBindingKind& left, PIBindingKind& top, 
+                     PIBindingKind& right, PIBindingKind& bottom)
+{
+  if (mAdapter)  
+    mAdapter->GetBinding(left, top, right, bottom);
+  //else
+  //  mPane->SetBinding(left, top, right, bottom);
+  return false;
+}
+
+void PIWdgMac::Refresh()
+{
+  if (mPane) mPane->Refresh();
+  if (mAdapter) mAdapter->Refresh();
+}
+
+
+int
+PIWdgMac::XSize()
+{ 
+  SDimension16 outSize;
+  mPane->GetFrameSize(outSize);
+  return outSize.width;
+}
+
+int
+PIWdgMac::YSize()
+{ 
+  SDimension16 outSize;
+  mPane->GetFrameSize(outSize);
+  return outSize.height;
+}
+
+int
+PIWdgMac::XPos()
+{
+  SPoint32 p;
+  mPane->GetFrameLocation(p);
+  return p.h;
+}
+
+int
+PIWdgMac::YPos()
+{
+  SPoint32 p;
+  mPane->GetFrameLocation(p);
+  return p.v;
+}
+
+
+bool 
+PIWdgMac::IsVisible()    // $CHECK$  REZA a verifier  01/12/97
+{
+if (mPane->IsVisible())  return(true);
+else return(false);
+}
+
+
+// Gestion de Copier/Coller
+#include <LClipboard.h>
+/* --Methode-- */
+// COPY
+bool PIWdgMac::ClaimSelection(unsigned int)
+{
+  unsigned int l;
+  char* txt = SelectionString(l);
+  LClipboard::GetClipboard()->SetData('TEXT',txt,l,true);
+  delete[] txt;
+  return (true);
+}
+
+/* --Methode-- */
+void PIWdgMac::SelectionLost()
+{
+}
+
+/* --Methode-- */
+// PASTE
+unsigned int PIWdgMac::RequestSelection(unsigned int)
+{
+  Handle h = NewHandle(0);
+  Int32 l = LClipboard::GetClipboard()->GetData('TEXT', h);
+  if (l) {
+    CopyFromSelection(*h, l);
+  }
+  return 1;
+}
+
+/* --Methode-- */
+void PIWdgMac::CopyFromSelection(char * sv, int l)
+{
+char* buff = new char[l+2];
+strncpy(buff, sv, l);
+buff[l] = '\0';
+printf("PIWdgMac::RequestSelection() L=%d [%s] \n", l, buff);
+delete buff;
+return;
+}
+
+/* --Methode-- */
+void PIWdgMac::PasteSelection(unsigned int, void *buff, unsigned int l)
+{
+  CopyFromSelection((char*) buff, l);
+}
+
+/* --Methode-- */
+char* PIWdgMac::SelectionString(unsigned int& len)
+{
+char *rs = new char[60];
+strcpy(rs, "Test-of-PIWdgMac::SelectionString()");
+len = strlen(rs);
+return(rs);
+}
+
+
+/* --Methode-- */
+void* PIWdgMac::ProvideSelection(unsigned int&, unsigned int& len)
+{
+  return SelectionString(len);
+}
+
+/* --Methode-- */
+void PIWdgMac::SelectionTransferEnd()
+{
+}
+
+/* --Methode-- */
+void PIWdgMac::Manage()
+{
+  if (mAdapter) mAdapter->Show();
+  mPane->Show();
+}
+
+/* --Methode-- */
+void PIWdgMac::UnManage()
+{
+  mPane->Hide();
+  if (mAdapter) mAdapter->Hide();
+}
+
+/* --Methode-- */
+bool PIWdgMac::IfManaged()
+{
+  return(mPane->IsVisible());
+}
+
+
+// -------- La classe PIScreenBuffer ----------
+/* --Methode-- */
+PIScreenBuffer::PIScreenBuffer(int sx, int sy)
+{
+  if (sx < 1) sx = 1;
+  if (sy < 1) sy = 1;
+  Rect bounds = {0,0,sy,sx};
+  mGWorld = new LGWorld(bounds);
+}
+/* --Methode-- */
+PIScreenBuffer::~PIScreenBuffer()
+{
+  delete mGWorld; 
+}
+
+/* --Methode-- */
+int PIScreenBuffer::XSize()
+{
+  Rect bounds;
+  mGWorld->GetBounds(bounds);
+  return bounds.right - bounds.left;
+}
+
+/* --Methode-- */
+int PIScreenBuffer::YSize()
+{
+  Rect bounds;
+  mGWorld->GetBounds(bounds);
+  return bounds.bottom - bounds.top;
+}
+
+/* --Methode-- */
+void PIScreenBuffer::CopyFromWdg(PIWdg* wdg, int ox, int oy, int dx, int dy, int x, int y)
+{
+  mGWorld->BeginDrawing();
+  LPane* pane = wdg->GetPane();
+  Rect srcRect = {oy, ox, oy+dy, ox+dx};
+  Rect destRect = {y, x, y+dy, x+dx};
+  CopyBits(&pane->GetMacPort()->portBits,&GrafPtr(mGWorld->GetMacGWorld())->portBits,&srcRect,&destRect,srcCopy,NULL);
+  mGWorld->EndDrawing();
+}
+
+/* --Methode-- */
+void PIScreenBuffer::CopyToWdg(PIWdg* wdg, int ox, int oy, int dx, int dy, int x, int y)
+{
+  LPane* pane = wdg->GetPane();
+  Rect srcRect = {oy, ox, oy+dy, ox+dx};
+  Rect destRect = {y, x, y+dy, x+dx};
+  CopyBits(&GrafPtr(mGWorld->GetMacGWorld())->portBits,&pane->GetMacPort()->portBits,&srcRect,&destRect,srcCopy,NULL);
+}
+
+/* --Methode-- */
+void PIScreenBuffer::CopyFrom(PIScreenBuffer* grb, int ox, int oy, int dx, int dy, int x, int y)
+{
+
+  mGWorld->BeginDrawing();
+  Rect srcRect = {oy, ox, oy+dy, ox+dx};
+  Rect destRect = {y, x, y+dy, x+dx};
+  CopyBits(&GrafPtr(grb->mGWorld->GetMacGWorld())->portBits,&GrafPtr(mGWorld->GetMacGWorld())->portBits,&srcRect,&destRect,srcCopy,NULL);
+  mGWorld->EndDrawing();
+}
Index: /tags/V_Dec2002/SophyaPI/PI/piwdgmac.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piwdgmac.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piwdgmac.h	(revision 2309)
@@ -0,0 +1,106 @@
+#ifndef PIWDG_MAC_SEEN
+#define PIWDG_MAC_SEEN
+
+#include "piwdggen.h"
+#include "pippviewadapter.h"
+#include <LPane.h>
+#include <LListener.h>
+
+class PIWdgMac : public PIWdgGen, public LListener {
+public:
+  
+                         PIWdgMac(PIContainerGen *par, char *nom,
+                                   int sx=10, int sy=10, int px=0, int py=0);
+  virtual                ~PIWdgMac();
+  virtual void			 FinishCreate(); // apres avoir installe les sous-vues
+                                       
+  virtual void	         ListenToMessage(MessageT inMessage, void *ioParam);
+  virtual void           SetLabel(string const&);
+
+  virtual void           SetSize(int sx, int sy);
+  virtual void           SetPos(int px, int py);
+  virtual void           SetBorderWidth(int /*bw*/) {}
+  
+  virtual void           SetBinding(PIBindingKind left, PIBindingKind top, 
+                                    PIBindingKind right, PIBindingKind bottom);
+  virtual bool           GetBinding(PIBindingKind& left, PIBindingKind& top, 
+                                    PIBindingKind& right, PIBindingKind& bottom);
+  virtual int            XSize();
+  virtual int            YSize();
+  virtual int            XPos();
+  virtual int            YPos();
+  virtual string         Nom()  { return mNom; }
+
+// Pour activer, desactiver un composant graphique (PIWdg)
+  virtual void           Manage();
+  virtual void           UnManage();
+  virtual bool           IfManaged();
+  virtual bool           IsVisible();
+  
+//  Fonction qui doit etre appelee pour rafraichir la fenetre 
+  virtual void       	 Refresh();
+  
+//  Pour rendre un composant graphique (PIWdg) sensible/insensible 
+//  aux actions utilisateur (souris, clavier, ...)
+  virtual void           SetSensitive();
+  virtual void           SetUnSensitive();
+  virtual bool           IfSensitive();
+
+//  Gestion de copier-coller
+  virtual bool           ClaimSelection(unsigned int typ=PICP_string);
+  virtual void           SelectionLost();
+  virtual unsigned int   RequestSelection(unsigned int typ=PICP_string);
+  virtual void*          ProvideSelection(unsigned int& typ, unsigned int& len);
+  virtual void           PasteSelection(unsigned int typ, void *, unsigned int l);
+  virtual void           CopyFromSelection(char *, int l);
+  virtual char*          SelectionString(unsigned int& len);
+  virtual void           SelectionTransferEnd();
+
+//  Copie depuis un PIWdgGen
+  virtual void		 CopyFrom(PIWdgGen* wdg, int ox, int oy, int dx, int dy, int x, int y);
+
+//  Gestion des EventHandler
+  virtual void		 AddDrawHandler(PIEventHandler* drwh, bool ad=false);
+  virtual void		 RemoveDrawHandler(PIEventHandler* drwh);
+  virtual void		 AddEventHandler(PIEventHandler* evh, unsigned long evtmask, bool ad=false);
+  virtual void		 RemoveEventHandler(PIEventHandler* evh);
+
+
+  LPane*                 GetPane() {return mPane;}
+  
+protected:
+  LPane*				 mPane;
+  PIPPViewAdapter*       mAdapter;
+  SPaneInfo				 mAdapterPaneInfo;
+  SViewInfo				 mAdapterViewInfo;
+  SPaneInfo				 mPaneInfo;
+  SViewInfo				 mViewInfo;
+  string                 mNom;
+  
+  friend class PIGraphicMac;
+};
+
+typedef PIWdgMac PIWdg;
+
+// -------- La classe PIScreenBuffer ----------
+
+#include <UGWorld.h>
+
+class PIScreenBuffer {
+public :
+                 PIScreenBuffer(int sx, int sy);
+  virtual       ~PIScreenBuffer();
+
+  virtual int       XSize();
+  virtual int       YSize();
+  virtual void      CopyFromWdg(PIWdg* wdg, int ox, int oy, int dx, int dy, int x, int y);
+  virtual void      CopyToWdg(PIWdg* wdg, int ox, int oy, int dx, int dy, int x, int y);
+  virtual void      CopyFrom(PIScreenBuffer* grb, int ox, int oy, int dx, int dy, int x, int y);
+
+protected :
+  LGWorld* mGWorld;
+};
+
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/piwdgx.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piwdgx.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piwdgx.cc	(revision 2309)
@@ -0,0 +1,1184 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#include <X11/IntrinsicP.h>
+#include <X11/Shell.h>
+#include <X11/Core.h>
+#include <X11/CoreP.h>
+
+#include <X11/keysym.h>
+
+#include <Xm/Xm.h>       // A cause des container XmForm 
+#include <Xm/Form.h>     // Idem 
+
+#include "piwdgx.h"
+#include "picontainerx.h"
+#include "pievthandler.h"
+#include "pigraphx.h"
+
+
+// #define DEBUG_PIWdgX
+
+// Quelques variables statiques globales, Connection Display, Top Widget Xt, AppContext Xt ...
+// et leurs fonctions d'acces 
+static SysDWdg  top = NULL;
+static Display * dpy = NULL;
+static GC defgc;
+// static char appname[64];
+static char appclass[64];
+static XtAppContext appctx;
+static int appSzX = 10;
+static int appSzY = 10;
+static int appSzFont = 10;
+static XFontStruct * stdfnt = NULL;
+
+// Variable globale Widget qui possede la selection pour le copier-coller
+static PIWdgX* curselwdg = NULL;    // Le PIWdg qui possede la selection
+
+/* Nouvelle-Fonction */
+XtAppContext* PIXtAppCtx(int& szx, int& szy, int& szf)
+{
+szx = appSzX;  szy = appSzY;
+szf = appSzFont;
+return(&appctx);
+}
+
+/* Nouvelle-Fonction */
+SysDWdg   PIXtTopWdg()
+{
+return (top);
+}
+
+/* Nouvelle-Fonction */
+Display * PIXDisplay()
+{
+return(dpy);
+}
+
+/* Nouvelle-Fonction */
+void PIBeep()
+{
+XBell(dpy, 0);
+return;
+}
+
+/* Nouvelle-Fonction */
+int CStrFrXmStr(XmString xms, char* buff, int nmx)
+/*  Pour recuperer le contenu d'un string Motif  */
+{
+int n,l,m;
+XmStringContext cntx;
+char *txs;
+XmStringDirection dir;
+XmStringCharSet cset;
+Boolean sep;
+
+if (nmx < 2)  return(0);
+n = 0;  m = nmx-1;  buff[0] = buff[m] = '\0';
+XmStringInitContext (&cntx, xms);
+while (m > 0)
+  {
+  if (XmStringGetNextSegment( cntx, &txs, &cset, &dir, &sep) )
+    {
+    l = strlen(txs);
+    if (m < l)  txs[m] = '\0';
+    strcpy(buff+n, txs);
+    n += l;   m -= l;
+    if (sep)  m = -2;
+    XtFree(txs);
+    }
+  else m = -1;
+  }
+
+return(n);
+} 
+
+
+/* --Methode-- */
+PIWdgX::PIWdgX(int narg, char *arg[])
+:PIWdgGen(NULL, "PITopLevel")  
+{
+if (top == NULL)  InitXt(narg, arg);
+sdw = top;
+wmis =  k_wmi_appshell;
+stmng = false;
+finishDone = false;
+mFCol = mBCol = PI_NotDefColor;
+mBKleft =  mBKright =  mBKtop =  mBKbottom = PIBK_free;
+#ifdef DEBUG_PIWdgX
+printf("Debug_PIWdgX::PIWdgX(int , char * [])  this=%lx  top=%lx \n", (long)this, (long)sdw);
+#endif
+}
+
+
+
+/* --Methode-- */
+PIWdgX::PIWdgX(PIContainerGen *par, const char *nom, 
+               int sx, int sy, int px, int py)
+:PIWdgGen(par, nom, sx, sy, px, py) 
+{
+sdw = NULL;
+wmis = k_wmi_unknown;
+finishDone = false;
+mFCol = mBCol = PI_NotDefColor;
+mBKleft =  mBKright =  mBKtop =  mBKbottom = PIBK_free;
+}
+
+/* --Methode-- */
+int PIWdgX::CreateXtWdg(const char *nom, SysDWdgClass wdgcl, SysDWdg pwdg,
+                        int sx, int sy, int px, int py, Arg* oarg, int na)
+{
+Arg  wargs[20];
+int n=0;
+
+#ifdef DEBUG_PIWdgX
+printf("Debug_PIWdgX::CreateXtWdg(%s) Getting in \n");
+#endif
+
+if (pwdg == NULL)
+  {
+  if (parent == NULL)
+    {
+    if (top == NULL)  InitXt();
+    pwdg = top;
+    }
+  // else pwdg = ((PIContainerX *)parent)->sdw;
+  else pwdg = ((PIWdgX *)parent)->sdw;
+  }
+
+n=0;
+if ((sx >= 0) && (sy >= 0))
+  {
+  XtSetArg(wargs[n],XtNwidth,sx);  n++;
+  XtSetArg(wargs[n],XtNheight,sy);  n++;
+  }
+XtSetArg(wargs[n],XtNx,px);  n++;
+XtSetArg(wargs[n],XtNy,py);  n++;
+
+if (na > 16) { printf("PIWdgX::CreateXtWdg()/Warning: na=%d > Max=16 \n", na);  na = 16; }
+for(int kk=0; kk<na; kk++) { wargs[n] = oarg[kk]; n++; }
+
+if (wdgcl == NULL)  wdgcl = coreWidgetClass;
+
+if ( (wdgcl == topLevelShellWidgetClass) || 
+     (wdgcl == transientShellWidgetClass) ||
+     (wdgcl == overrideShellWidgetClass) )
+  {
+  sdw = XtCreatePopupShell(nom, wdgcl, pwdg, wargs, n);
+  }
+else
+  {
+  sdw = XtCreateWidget(nom, wdgcl, pwdg, wargs, n);
+  }
+
+if (wdgcl == topLevelShellWidgetClass)  wmis = k_wmi_toplevel;
+else if (wdgcl == transientShellWidgetClass)  wmis = k_wmi_transient;
+else if (wdgcl == overrideShellWidgetClass)  wmis = k_wmi_override;
+else wmis = k_wmi_normal ;
+
+stmng = false;
+#ifdef DEBUG_PIWdgX
+printf("Debug_PIWdgX::CreateXtWdg(%s) this=%lx sdw=%lx pere=%lx wmis=%d\n", nom, 
+       (long)this, (long)sdw, (long)pwdg, wmis);
+#endif
+mFCol = mBCol = PI_NotDefColor;
+SetBinding(PIBK_free, PIBK_free, PIBK_free, PIBK_free);
+if (parent) parent->ChildAdd(this);
+return(0);
+}
+
+
+/* --Methode-- */
+PIWdgX::~PIWdgX()
+{
+#ifdef DEBUG_PIWdgX
+printf("Debug_PIWdgX::~PIWdgX()  %lx %lx \n", (long)this, (long)sdw);
+#endif
+if (parent) parent->ChildDel(this);
+UnManage();
+if (curselwdg == this)  { SelectionLost(); curselwdg = NULL; }
+if (sdw)  { 
+// Pour gerer la double structure en Widget des PIWindowX
+  if (wmis == k_wmi_normal) XtDestroyWidget(sdw);
+  else if (wmis == k_wmi_cascade) { 
+    SysDWdg pwdg = XtParent(sdw);
+    XtDestroyWidget(sdw);
+    if (pwdg) XtDestroyWidget(pwdg);
+    }
+  }
+}
+
+
+/* --Methode-- */
+void PIWdgX::FinishCreate()
+{
+// appele par la fenetre mere, apres XtRealize()
+if (finishDone) { 
+  fprintf(stderr, "BUG/PIWdgX::FinishCreate() multiple call \n"); 
+  return; 
+  }
+finishDone = true;
+return;
+}
+
+
+/* --Methode-- */
+void PIWdgX::Manage()
+{
+#ifdef DEBUG_PIWdgX
+printf("Debug_PIWdgX::Manage  this=%lx  sdw=%lx \n", (long)this, (long)sdw);
+#endif
+if (!sdw)  return;
+if (wmis != k_wmi_appshell)  XtManageChild(sdw);
+else if (!XtIsRealized(sdw))  XtRealizeWidget(sdw);  
+stmng = true;
+return;
+}
+
+/* --Methode-- */
+void PIWdgX::UnManage()
+{
+#ifdef DEBUG_PIWdgX
+printf("Debug_PIWdgX::UnManage  this=%lx sdw=%lx \n", (long)this, (long)sdw);
+#endif
+if (!sdw)  return;
+if (wmis != k_wmi_appshell) 
+  XtUnmanageChild(sdw);
+stmng = false;
+return;
+}
+
+/* --Methode-- */
+bool PIWdgX::IfManaged()
+{
+return(stmng);
+}
+
+/* --Methode-- */
+bool PIWdgX::IsVisible()
+{
+if ( (XtIsRealized(XtWdg())) &&  
+   ( (this->XtWdg())->core.visible) )  return(true);
+else return(false);       
+}
+
+/* --Methode-- */
+void PIWdgX::Refresh()
+{
+if (XtIsRealized(XtWdg()))
+  XClearArea(XtDisplay(XtWdg()), XtWindow(XtWdg()), 0, 0, 0, 0, True);
+}
+
+/* --Methode-- */
+void PIWdgX::SetSensitive()
+{
+XtSetSensitive(XtWdg(), TRUE);
+}
+
+/* --Methode-- */
+void PIWdgX::SetUnSensitive()
+{
+XtSetSensitive(XtWdg(), FALSE);
+}
+
+/* --Methode-- */
+bool PIWdgX::IfSensitive()
+{
+if (XtIsSensitive(XtWdg()) == TRUE)  return(true);
+else return(false);
+}
+
+/* --Methode-- */
+void PIWdgX::SetSize(int sx, int sy)
+{
+#ifdef DEBUG_PIWdgX
+printf("Debug_PIWdgX::SetSize  this=%lx  sdw=%lx \n", (long)this, (long)sdw);
+#endif
+
+if (!sdw)  return;
+/*
+Arg  wargs[2];
+XtSetArg(wargs[0],XtNwidth,sx); 
+XtSetArg(wargs[1],XtNheight,sy); 
+XtSetValues(this->sdw, wargs, 2);
+*/
+XtResizeWidget(sdw, sx, sy, BorderWidth());
+
+return;
+} 
+
+/* --Methode-- */
+void PIWdgX::SetPos(int px, int py)
+{
+if (!sdw)  return;
+/*
+Arg  wargs[2];
+XtSetArg(wargs[0],XtNx,px);  
+XtSetArg(wargs[1],XtNy,py);  
+XtSetValues(this->sdw, wargs, 2);
+*/
+XtMoveWidget(sdw, px, py);
+
+return;
+} 
+
+/* --Methode-- */
+void PIWdgX::SetBackgroundColor(PIColors col)
+{
+if (col < 0)  return;
+Arg  wargs[2];
+XtSetArg(wargs[0],XtNbackground, PIGraphicX::GetPixelValueforColor(col) );  
+XtSetValues(XtWdg(), wargs, 1);
+mBCol = col;
+return;
+}
+
+/* --Methode-- */
+void PIWdgX::SetForegroundColor(PIColors col)
+{
+if (col < 0)  return;
+Arg  wargs[2];
+XtSetArg(wargs[0],XtNforeground, PIGraphicX::GetPixelValueforColor(col) );  
+XtSetValues(XtWdg(), wargs, 1);
+mFCol = col;
+return;
+}
+
+/* --Methode-- */
+void PIWdgX::EraseWindow(int x0, int y0, int dx, int dy)
+{
+XClearArea (XtDisplay(XtWdg()),XtWindow(XtWdg()), x0, y0, dx, dy, False );
+return;
+}
+
+/* --Methode-- */
+PIColors   PIWdgX::GetBackgroundColor()
+{
+return(mBCol);
+}
+
+/* --Methode-- */
+PIColors   PIWdgX::GetForegroundColor()
+{
+return(mFCol);
+}
+
+ 
+/* --Methode-- */
+void PIWdgX::SetBinding(PIBindingKind left, PIBindingKind top, 
+                        PIBindingKind right, PIBindingKind bottom)
+{
+if (bindingLock) return;
+mBKleft = left;  mBKright = right;
+mBKtop = top;  mBKbottom = bottom;
+BindWdgtoParent();
+}
+
+
+/* *** ATTENTION *** La constante ci-dessous PIXMFORMFRACBASE
+   doit etre identique ds piwdgx.cc  picontainerx.cc et piwindowx.cc
+   ***************************************************************** */
+#define PIXMFORMFRACBASE 1000
+
+/* --Methode-- */
+void PIWdgX::BindWdgtoParent()
+{
+if (bindingLock) return;
+if (!sdw)  return;
+if (!parent)  return;
+
+
+PIBindingKind left, top, right, bottom;
+left = mBKleft;  right = mBKright;
+top = mBKtop;  bottom = mBKbottom;
+
+int fbase = PIXMFORMFRACBASE ;  // Valeur de XmNfractionBase des XmForm ds PIContainerX
+int frpos = 0;
+float frac;
+Arg  wargs[13];
+int n=0;
+
+// printf(" DEBUG_SetBinding: C-Sz= %d %d - Sz=%d %d , Pos= %d %d \n",  parent->XSize(),
+// parent->YSize(), XSize(), YSize(), XPos(), YPos());
+switch (left)
+  {
+  case PIBK_free : 
+    XtSetArg(wargs[n],XmNleftAttachment, XmATTACH_NONE);  n++;
+    break;
+  case PIBK_fixed :
+    XtSetArg(wargs[n],XmNleftAttachment, XmATTACH_FORM);  n++;
+    XtSetArg(wargs[n],XmNleftOffset, XPos() );  n++;
+    break;
+  case PIBK_elastic :
+    XtSetArg(wargs[n],XmNleftAttachment, XmATTACH_POSITION);  n++;
+    frac = (float)(XPos())/(float)parent->XSize() ;
+    frpos = frac*fbase;
+    XtSetArg(wargs[n],XmNleftPosition, frpos );  n++;
+    XtSetArg(wargs[n],XmNleftOffset, 0 );  n++;
+    break;
+  default :
+    left = PIBK_free;
+    XtSetArg(wargs[n],XmNleftAttachment, XmATTACH_NONE);  n++;
+    break;    
+  }
+ 
+switch (top)
+  {
+  case PIBK_free : 
+    XtSetArg(wargs[n],XmNtopAttachment, XmATTACH_NONE);  n++;
+    break;
+  case PIBK_fixed :
+    XtSetArg(wargs[n],XmNtopAttachment, XmATTACH_FORM);  n++;
+    XtSetArg(wargs[n],XmNtopOffset, YPos() );  n++;
+    break;
+  case PIBK_elastic :
+    XtSetArg(wargs[n],XmNtopAttachment, XmATTACH_POSITION);  n++;
+    frac = (float)(YPos())/(float)parent->YSize() ;
+    frpos = frac*fbase;
+    XtSetArg(wargs[n],XmNtopPosition, frpos );  n++;
+    XtSetArg(wargs[n],XmNtopOffset, 0 );  n++;
+    break;
+  default :
+    top = PIBK_free;
+    XtSetArg(wargs[n],XmNtopAttachment, XmATTACH_NONE);  n++;
+    break;
+  }
+  
+switch (right) 
+  {
+  case PIBK_free : 
+    XtSetArg(wargs[n],XmNrightAttachment, XmATTACH_NONE);  n++;
+    break;
+  case PIBK_fixed :
+    XtSetArg(wargs[n],XmNrightAttachment, XmATTACH_FORM);  n++;
+    XtSetArg(wargs[n],XmNrightOffset, parent->XSize()-(XSize()+XPos()) );  n++;
+    break;
+  case PIBK_elastic :
+    XtSetArg(wargs[n],XmNrightAttachment, XmATTACH_POSITION);  n++;
+    frac = (float)(XPos()+XSize())/(float)parent->XSize() ;
+    frpos = frac*fbase;
+    XtSetArg(wargs[n],XmNrightPosition, frpos );  n++;
+    XtSetArg(wargs[n],XmNrightOffset, 0 );  n++;
+    break;
+  default : 
+    right = PIBK_free;
+    XtSetArg(wargs[n],XmNrightAttachment, XmATTACH_NONE);  n++;
+    break;
+
+  }
+
+switch (bottom) 
+  {
+  case PIBK_free : 
+    XtSetArg(wargs[n],XmNbottomAttachment, XmATTACH_NONE);  n++;
+    break;
+  case PIBK_fixed :
+    XtSetArg(wargs[n],XmNbottomAttachment, XmATTACH_FORM);  n++;
+    XtSetArg(wargs[n],XmNbottomOffset, parent->YSize()-(YSize()+YPos()) );  n++;
+    break;
+  case PIBK_elastic :
+    XtSetArg(wargs[n],XmNbottomAttachment, XmATTACH_POSITION);  n++;
+    frac = (float)(YPos()+YSize())/(float)parent->YSize() ;
+    frpos = frac*fbase;
+    XtSetArg(wargs[n],XmNbottomPosition, frpos );  n++;
+    XtSetArg(wargs[n],XmNbottomOffset, 0 );  n++;
+    break;
+  default :
+    bottom =  PIBK_free;
+    XtSetArg(wargs[n],XmNbottomAttachment, XmATTACH_NONE);  n++;
+    break;
+  }
+
+// Widget bwd = (XtParent(this->sdw) == parent->XtWdg()) ? this->sdw : XtParent(this->sdw);
+XtSetValues(this->sdw, wargs, n);
+// printf(" Out_SetBinding: C-Sz= %d %d - Sz=%d %d , Pos= %d %d \n",  parent->XSize(),
+// parent->YSize(), XSize(), YSize(), XPos(), YPos());
+
+return;
+}
+
+/* --Methode-- */
+bool PIWdgX::GetBinding(PIBindingKind& left, PIBindingKind& top, 
+                        PIBindingKind& right, PIBindingKind& bottom)
+{
+left = mBKleft;  right = mBKright;
+top = mBKtop;  bottom = mBKbottom;
+return(bindingLock);
+}
+
+/* --Methode-- */
+void PIWdgX::SetBorderWidth(int bw)
+{
+if (!sdw)  return;
+
+Arg  wargs[2];
+int n=0;
+
+XtSetArg(wargs[n],XtNborderWidth,bw);  n++;
+XtSetValues(this->sdw, wargs, n);
+return;
+}
+
+
+/* --Methode-- */
+int PIWdgX::XSize()
+{
+if (!sdw)  return(-1);
+else return((int)this->sdw->core.width);
+}
+
+/* --Methode-- */
+int PIWdgX::YSize()
+{
+if (!sdw)  return(-1);
+else return((int)this->sdw->core.height);
+}
+
+/* --Methode-- */
+int PIWdgX::XPos()
+{
+if (!sdw)  return(-1);
+else return((int)this->sdw->core.x);
+}
+
+/* --Methode-- */
+int PIWdgX::YPos()
+{
+if (!sdw)  return(-1);
+else return((int)this->sdw->core.y);
+}
+
+
+/* --Methode-- */
+int PIWdgX::BorderWidth()
+{
+if (!sdw)  return(-1);
+Arg  wargs[2];
+int bw;
+XtSetArg(wargs[0],XtNborderWidth, &bw);  
+XtGetValues(this->sdw, wargs, 1);
+return(bw);
+}
+
+/* --Methode-- */
+string PIWdgX::Nom()
+{
+return(XtName(this->sdw));
+}
+
+/* --Methode-- */
+void PIWdgX::GetScreenPos(int & spx, int & spy)
+{
+PIWdgX * wc;
+Display *mdsp;
+Window w, rw, pw, *cw;
+unsigned int ncw;
+Status st;
+int x,y;
+unsigned int bw, l, h, d;
+
+spx = 0;  spy = 0;
+wc = this;
+
+while (wc)
+  { spx += wc->XPos();
+  spy += wc->YPos();  wc = (PIWdgX *)wc->Parent();
+  }
+
+mdsp = XtDisplay(XtWdg());
+w = XtWindow(XtWdg());
+ncw = 0;
+st = XQueryTree(mdsp, w, &rw, &pw, &cw, &ncw);
+if (st) 
+  { XFree(cw);
+  if (pw == rw)  return; }
+
+while (st && (pw != rw))  
+  {
+  w = pw;
+  st = XQueryTree(mdsp, w, &rw, &pw, &cw, &ncw); 
+  if (st)   XFree(cw);
+  XGetGeometry(mdsp, w, &rw, &x, &y, &l, &h, &bw, &d);  
+  spy += y;  spx += x;
+  }  
+return;
+}
+
+
+// Ressources X si non definis 
+static const String fallback_res[26] = {
+"PeidaInt*default*background:                 LightGrey" ,
+"PeidaInt*background:                         LightGrey" ,
+"PeidaInt*Foreground:                         Black",
+"PeidaInt*default*Foreground:                 Black",
+"PeidaInt*default*bottomShadowColor:          Black",
+"PeidaInt*bottomShadowColor:                  Black",
+"PeidaInt*default*topShadowColor:             White",
+"PeidaInt*topShadowColor:                     White",
+"PeidaInt*borderColor:                        Black",
+"PeidaInt*XmLabel.borderWidth:                0",
+"PeidaInt*XmDrawingArea*background:           Black",
+"PeidaInt*XmPushButton*borderWidth:           0",
+"PeidaInt*XmText*shadowThickness:             2",
+"PeidaInt*XmText*highlightThickness:          0",
+"PeidaInt*XmText*marginHeigt:                 0",
+"PeidaInt*XmText*marginWidth:                 2",
+// "PeidaInt*DefMenubar*XtNwidth:                250",
+// "PeidaInt*DefMenubar*XtNheight:               30",
+"PeidaInt*fontList:           -*-courier-bold-r-normal-*-12-*-*-*-*-*-ISO8859-1",
+"PeidaInt*default*fontList:   -*-courier-bold-r-normal-*-12-*-*-*-*-*-ISO8859-1",
+"PeidaInt*fontFamilyName:                     *-courier",    // Pas de blanc apres le nom de font
+"PeidaInt*courierfontFamilyName:              *-courier",    //           "        " 
+"PeidaInt*helveticafontFamilyName:            *-helvetica",  //           "        " 
+"PeidaInt*timesfontFamilyName:                *-times",      //           "        " 
+"PeidaInt*symbolfontFamilyName:               *-symbol",     //           "        " 
+"PeidaInt*XmToggleButton*selectColor:         Red",
+NULL
+};
+
+
+/* --Methode-- */
+int PIWdgX::InitXt(int narg, char *arg[])
+{
+if (top != NULL)  return(0);
+// Initialisation ...  
+int n;
+const char *pc = (const char *)"PIWdgX";
+char **ppc;
+if (narg > 0)  { n = narg, ppc = arg; }
+else { ppc = const_cast<char **>(&pc); n = 1; }
+//  strncpy(appname, ppc[0], 63); appname[63] = '\0';
+strncpy(appclass,"PeidaInt",63);  appclass[63] = '\0';     
+//-----  XtAppInitialize obsolete (X11/R6 , remplace par XtOpenApplication   -  Reza 14/06/99  -----
+//  top = XtAppInitialize(&appctx, appclass, NULL, 0, &n, ppc, 
+//                      const_cast<String*>(fallback_res), NULL, 0 );
+//BUG ? - DEL top = XtVaAppInitialize(&appctx, appclass, NULL, 0, &n, ppc, const_cast<String*>(fallback_res));
+top = XtOpenApplication(&appctx, appclass, NULL, 0, &n, ppc, const_cast<String*>(fallback_res), 
+                          applicationShellWidgetClass, NULL, 0);
+if (top == NULL) {
+  fprintf(stderr, "PIWdgX::InitXt()/ Error XtVaAppInitialize() -> Exit \n");
+  exit(9);
+  }
+dpy = XtDisplay(top);
+if (dpy == NULL)  {
+  fprintf(stderr, "PIWdgX::InitXt()/ Error XtVaAppInitialize()/DisplayConnection -> Exit \n");
+  exit(9);
+  }
+
+/*  le GC pour les XCopyArea */
+XGCValues  xgv;
+xgv.function = GXcopy;
+xgv.plane_mask = ~0;
+defgc = XCreateGC (dpy, DefaultRootWindow(dpy), GCFunction | GCPlaneMask, &xgv); 
+
+// On va recuperer la fonte par defaut des composantes Motif
+XtResource res[] = {
+  { (char *)"fontList", (char *)"FontList", XtRString, sizeof(String),
+    0, XtRString, const_cast<char *>("-*-courier-bold-*-*-*-*-*-*-*-*-*-*-*") }
+};
+
+String fntname;
+XtGetApplicationResources(top, &fntname, res, XtNumber(res), NULL, 0);
+// scr = XDefaultScreen(dpy);
+// printf("-DBG-F= %s \n", fntname);
+int count;
+char **list;
+char buff[256];
+strcpy(buff, fntname);
+list = XListFonts(dpy, buff, 15, &count);
+if (count < 1)  { 
+  strcpy(buff,"-*-*-*-*-*-*-12-*-*-*-*-*-*-*" );
+  XFreeFontNames(list);
+  list = XListFonts(dpy, buff, 15, &count);
+  }
+if (count < 1)  { 
+  strcpy(buff,"-*-*-*-*-*-*-13-*-*-*-*-*-*-*" );
+  XFreeFontNames(list);
+  list = XListFonts(dpy, buff, 15, &count);
+  }
+if (count < 1)  { 
+  strcpy(buff,"-*-*-*-*-*-*-11-*-*-*-*-*-*-*" );
+  XFreeFontNames(list);
+  list = XListFonts(dpy, buff, 15, &count);
+  }
+stdfnt = XLoadQueryFont(dpy, buff);
+char * myfntname = "???";
+// Recherche du champ taille en pixel de la fonte : apres le 7eme tiret
+int mySzFont = 12;
+if (count > 0) {
+  myfntname = list[0];
+  int kt = 0;
+  int kdx = 0;
+  char * pcf = list[0];
+  //  printf("DBG-X1 : %s \n ", pcf);
+  while (kt < 7)  {
+    if (pcf[kdx] == '-')  kt++;
+    if (pcf[kdx] == '\0')  break;
+    kdx++;
+    }
+  //  printf("DBG-X2 : %s \n ", pcf+kdx);
+  int iii = 0;
+  while ( (pcf[kdx+iii] != '-') && (pcf[kdx+iii] != '\0') )
+     { buff[iii] = pcf[kdx+iii];  iii++; }
+  buff[iii] = '\0';
+  mySzFont = atoi(buff);
+  //  printf("*DBG*X3* %s -> %d \n", buff, mySzFont);
+}
+// On calcule la taille de la chaine CANCEL (6 caracteres)
+char a[2];
+XCharStruct  ovr;
+int hd, fa, fd, len;  // direction, font-ascent, font-descent len("CANCEL")
+XTextExtents(stdfnt, a, 0, &hd, &fa, &fd, &ovr);
+len = XTextWidth(stdfnt, "CANCEL", 6);
+appSzY = (float)(fa+fd)*1.4+8;  // pour les shadow  $CHECK$ - a ameliorer peut-etre 
+appSzX = (float)len*1.4;
+appSzFont =  mySzFont ;
+// Taille X multiple de 5 pixels, Y mult 2 pixels 
+if ( (appSzX % 5) != 0 )   appSzX = 5*(appSzX/5 + 1);
+if ( (appSzY % 2) != 0 )   appSzY = 2*(appSzY/2 + 1);
+if(appSzY < 10) appSzY = 10;
+if(appSzX < 30) appSzX = 30;
+
+// printf("PIWdgX::InitXt(Font=%s- %d %d , %d ) SzX,Y= %d %d - FSz= %d \n", myfntname, fa,fd,len,appSzX, appSzY, appSzFont);
+XFreeFontNames(list);
+return(0);
+}
+
+/* .................................................................*/
+/* ................... Gestion de Copier/Coller ....................*/
+/* .................................................................*/
+
+// Les Call-Backs Xt
+
+static Boolean forXt_ConvertSelection(Widget w, Atom* sel, Atom *targ, Atom* typ,
+                                   XtPointer* value, unsigned long* len, int* format);
+
+static void forXt_LoseSelection(Widget w, Atom* sel);
+static void forXt_DoneSelection(Widget w, Atom* sel, Atom *targ);
+static void forXt_SelectionValue(Widget w, XtPointer usd, Atom* sel, Atom* typ, 
+                                 XtPointer value, unsigned long* len, int* format );
+
+static unsigned int curseltype = PICP_string; // Type de selcetion qu'il peut fournir
+static unsigned int reqseltype = PICP_string; // Type de selection demande
+static unsigned int provseltype = PICP_string; // Type de selection fourni
+
+/* Nouvelle-Fonction */
+Boolean forXt_ConvertSelection(Widget w, Atom* sel, Atom *targ, Atom* typ,
+                                   XtPointer* value, unsigned long* len, int* format)
+{
+if (*targ != XA_STRING)  return(FALSE);
+if (!curselwdg)  return(FALSE);
+unsigned int ll = 0;
+unsigned int styp = reqseltype;
+*value = curselwdg->ProvideSelection(styp, ll);
+*len=ll;
+*typ = XA_STRING;
+*format = 8;
+provseltype = (styp != 0) ? styp : PICP_string;
+return(TRUE);
+}
+
+/* Nouvelle-Fonction */
+void forXt_LoseSelection(Widget w, Atom* sel)
+{
+if (curselwdg)  curselwdg->SelectionLost();
+curselwdg = NULL; curseltype = PICP_string; 
+}
+
+/* Nouvelle-Fonction */
+void forXt_DoneSelection(Widget w, Atom* sel, Atom *targ)
+{
+if (curselwdg)  curselwdg->SelectionTransferEnd();
+}
+
+/* Nouvelle-Fonction */
+void forXt_SelectionValue(Widget w, XtPointer usd, Atom* sel, Atom* typ, 
+                                 XtPointer value, unsigned long* len, int* format )
+{
+if ( (value != NULL) && (*len > 0) ) 
+  ((PIWdgX*)usd)->PasteSelection(provseltype, (void*)value, (*len)) ;
+}
+
+
+
+// Gestion de Copier/Coller
+/* --Methode-- */
+bool PIWdgX::ClaimSelection(unsigned int typ)
+// Pour prendre possession du buffer copier/coller
+{
+if (XtOwnSelection(XtWdg(), XA_PRIMARY, PIXGetLastEventTime(), forXt_ConvertSelection, 
+                   forXt_LoseSelection, forXt_DoneSelection) ) {
+#ifdef DEBUG_PIWdgX
+  printf("PIWdgX::ClaimSelection(%d) - OK  (Wdg= %lx)\n", typ, (unsigned long)this);
+#endif
+  curselwdg = this;
+  curseltype = (typ != 0) ? typ : PICP_string;
+  return (true);
+}
+else {
+#ifdef DEBUG_PIWdgX
+  printf("PIWdgX::ClaimSelection() - Probleme (Wdg= %lx)\n", (unsigned long)this);
+#endif
+  curselwdg = NULL;
+  curseltype = PICP_string;
+  return (false);
+}
+}
+
+/* --Methode-- */
+void PIWdgX::SelectionLost()
+// Appele quand le PIWdg perd la possession du buffer copier/coller
+{
+return;
+}
+
+/* --Methode-- */
+unsigned int PIWdgX::RequestSelection(unsigned int typ)
+{
+// Pour demander le contenu du buffer de copier/coller
+#ifdef DEBUG_PIWdgX
+printf("PIWdgX::RequestSelection(%d) (Wdg= %lx - %lx) \n", typ,  
+        (unsigned long)this, (unsigned long)curselwdg);
+#endif
+reqseltype = (typ != 0) ? typ : PICP_string;
+XtGetSelectionValue(XtWdg(), XA_PRIMARY, XA_STRING, forXt_SelectionValue, 
+                    (XtPointer)this, PIXGetLastEventTime());
+return(reqseltype);
+}
+
+static char* rs = NULL;
+
+/* --Methode-- */
+void* PIWdgX::ProvideSelection(unsigned int& typ, unsigned int& len)
+// Le widget doit fournier une l zone memoire contenant la selection
+// en un type donne
+// Renvoie le pointeur de cette zone, sa taille et son typ
+{
+rs = new char[128];
+sprintf(rs, "Test-of-PIWdgX::ProvideSelection(%d)- %lx", typ,(long)rs);
+len = strlen(rs);
+return(rs);
+}
+
+/* --Methode-- */
+void PIWdgX::SelectionTransferEnd()
+{
+delete[] rs;
+}
+
+
+/* --Methode-- */
+void PIWdgX::PasteSelection(unsigned int typ, void *buff, unsigned int l)
+{
+// Methode appele apres que le widget ait fait RequestSelection
+// Le typ de donnees fourni ainsi que les donnees et leur taille 
+// sont en argument 
+#ifdef DEBUG_PIWdgX
+char* mbuff = new char[l+1];
+strncpy(mbuff, (char *)buff, l);
+mbuff[l] = '\0';
+printf("PIWdgX::PasteSelection(%d, %lx, %d) [%s] \n", typ, (long)buff, l, mbuff);
+delete[] mbuff;
+#endif
+return;
+}
+
+//  Copie depuis un PIWdgGen
+void PIWdgX::CopyFrom(PIWdgGen* wdg, int ox, int oy, int dx, int dy, int x, int y)
+{
+PIWdgX* wx = (PIWdgX*)wdg;
+XCopyArea(XtDisplay(XtWdg()), XtWindow(wx->XtWdg()), XtWindow(XtWdg()), defgc, ox, oy, 
+          (unsigned int)dx, (unsigned int)dy, x, y);
+}
+
+
+// Declaration de l' EventHandler Xt
+static void evthandler_piwdgx (Widget wdgp, XtPointer, XEvent* evt, Boolean* cont);
+
+
+/* --Methode-- */
+void PIWdgX::AddDrawHandler(PIEventHandler* drwh, bool ad)
+{
+PIWdgGen::AddDrawHandler(drwh, ad);
+XtInsertEventHandler( XtWdg(), ExposureMask, FALSE, evthandler_piwdgx, this, XtListTail);
+}
+
+/* --Methode-- */
+void PIWdgX::RemoveDrawHandler(PIEventHandler* drwh)
+{
+PIWdgGen::RemoveDrawHandler(drwh);
+if (mEHlist.size() <= 0) XtRemoveEventHandler( XtWdg(), ExposureMask, FALSE, evthandler_piwdgx, this);
+}
+
+/* --Methode-- */
+void PIWdgX::AddEventHandler(PIEventHandler* evh, unsigned long evtmask, bool ad)
+{
+PIWdgGen::AddEventHandler(evh, evtmask, ad);
+EventMask mask = 0;
+// if (evtmask & PIEvent_Resize)  pas traite pour le moment
+if (evtmask & PIEvent_Enter)  mask |= EnterNotify;
+if (evtmask & PIEvent_Leave)  mask |= LeaveNotify;
+if (evtmask & PIEvent_But1Press)  mask |= ButtonPressMask;
+if (evtmask & PIEvent_But1Release)  mask |= ButtonReleaseMask;
+if (evtmask & PIEvent_But2Press)  mask |= ButtonPressMask;
+if (evtmask & PIEvent_But2Release)  mask |= ButtonReleaseMask;
+if (evtmask & PIEvent_But3Press)  mask |= ButtonPressMask;
+if (evtmask & PIEvent_But3Release)  mask |= ButtonReleaseMask;
+if (evtmask & PIEvent_PtrMove)  mask |= PointerMotionHintMask;
+if (evtmask & PIEvent_Ptr1Move)  mask |= (PointerMotionHintMask | Button1MotionMask);
+if (evtmask & PIEvent_Ptr2Move)  mask |= (PointerMotionHintMask | Button2MotionMask);
+if (evtmask & PIEvent_Ptr3Move)  mask |= (PointerMotionHintMask | Button3MotionMask);
+if (evtmask & PIEvent_Keyboard)  mask |= KeyPressMask;
+printf("PIWdgX::AddEventHandler() Mask = %lx \n", (long)mask);
+XtInsertEventHandler( XtWdg(), mask, FALSE, evthandler_piwdgx, this, XtListTail);
+}
+
+/* --Methode-- */
+void PIWdgX::RemoveEventHandler(PIEventHandler* evh)
+{
+PIWdgGen::RemoveEventHandler(evh);
+if (mEHlist.size() > 0) return; 
+EventMask mask = EnterNotify;
+mask |= LeaveNotify;
+mask |= ButtonPressMask;
+mask |= ButtonRelease;
+mask |= ButtonPressMask;
+mask |= ButtonRelease;
+mask |= ButtonPressMask;
+mask |= ButtonRelease;
+mask |= PointerMotionHintMask;
+mask |= (PointerMotionHintMask | Button1MotionMask);
+mask |= (PointerMotionHintMask | Button2MotionMask);
+mask |= (PointerMotionHintMask | Button3MotionMask);
+mask |= KeyPressMask;
+XtRemoveEventHandler( XtWdg(), mask, FALSE, evthandler_piwdgx, this);
+}
+
+/* --Methode-- */
+void PIWdgX::CallDrawHandlers(int x0, int y0, int dx, int dy)
+{
+PIGraphicWin* g = new PIGraphicWin(this);
+PIEventHandler* eh;
+list<EvHand>::iterator it;
+for(it= mDHlist.begin(); it != mDHlist.end(); it++) { 
+  eh = (*it).evh;
+  eh->SetCurrentWdg(this);
+  eh->SetEventInfo(PIEvent_Draw, x0, y0, 0, PIKM_Blank, 0);
+  g->SaveGraphicAtt();
+  eh->Draw(g, x0, y0, dx, dy);
+  g->RestoreGraphicAtt();
+  }
+delete g;
+}
+
+/* --Methode-- */
+void PIWdgX::CallEventHandlers(unsigned long evt, int px, int py,
+                               int k, int km, unsigned long tm)
+{
+PIEventHandler* eh;
+list<EvHand>::iterator it;
+for(it= mEHlist.begin(); it != mEHlist.end(); it++) {
+  if (!((*it).mask & evt))  continue; 
+  eh = (*it).evh;
+  eh->SetCurrentWdg(this);
+  eh->SetEventInfo((PIEventMask)evt, px, py, k, (PIKeyModifier)km, tm);
+  eh->ProcessEvent();
+  }
+}
+
+
+// -------   Event Handler Xt ----------
+/* Nouvelle-Fonction */
+void evthandler_piwdgx (Widget wdgp, XtPointer usd, 
+                             XEvent* evt, Boolean* cont)
+{
+
+*cont = true ; 
+PIWdgX* wx = (PIWdgX*)usd;
+PIEventMask evm = PIEvent_None;
+PIKeyModifier kmod = PIKM_Blank;
+
+switch (evt->type) {
+  case Expose :
+    wx->CallDrawHandlers(evt->xexpose.x , evt->xexpose.y , evt->xexpose.width , evt->xexpose.height);
+    break;
+  case EnterNotify : 
+    wx->CallEventHandlers(PIEvent_Enter, evt->xcrossing.x, evt->xcrossing.y, 0, 
+                          PIKM_Blank, evt->xcrossing.time);
+    PIXSetLastEventTimeSerial(evt->xcrossing.time, evt->xcrossing.serial);
+    break;
+
+  case LeaveNotify : 
+    wx->CallEventHandlers(PIEvent_Leave, evt->xcrossing.x, evt->xcrossing.y, 0, 
+                          PIKM_Blank, evt->xcrossing.time);
+    PIXSetLastEventTimeSerial(evt->xcrossing.time, evt->xcrossing.serial);
+  break;
+
+  case ButtonPress :
+    if  (evt->xbutton.state & ShiftMask)   
+      kmod = (PIKeyModifier) (kmod | PIKM_Shift);
+    if  (evt->xbutton.state & ControlMask) 
+      kmod = (PIKeyModifier) (kmod | PIKM_Cntl);
+    if  (evt->xbutton.state & Mod1Mask)    
+      kmod = (PIKeyModifier) (kmod | PIKM_Alt);
+    if (evt->xbutton.button == 1) evm = PIEvent_But1Press;
+    else if (evt->xbutton.button == 2) evm = PIEvent_But2Press;
+    else if (evt->xbutton.button == 3) evm = PIEvent_But3Press;
+    wx->CallEventHandlers(evm, evt->xbutton.x, evt->xbutton.y, 0, 
+                          kmod, evt->xbutton.time);
+    PIXSetLastEventTimeSerial(evt->xbutton.time, evt->xbutton.serial);
+  break;
+
+  case ButtonRelease :
+    if  (evt->xbutton.state & ShiftMask)   
+      kmod = (PIKeyModifier) (kmod | PIKM_Shift);
+    if  (evt->xbutton.state & ControlMask) 
+      kmod = (PIKeyModifier) (kmod | PIKM_Cntl);
+    if  (evt->xbutton.state & Mod1Mask)    
+      kmod = (PIKeyModifier) (kmod | PIKM_Alt);
+    if (evt->xbutton.button == 1) evm = PIEvent_But1Release;
+    else if (evt->xbutton.button == 2) evm = PIEvent_But2Release;
+    else if (evt->xbutton.button == 3) evm = PIEvent_But3Release;
+
+    wx->CallEventHandlers(evm, evt->xbutton.x, evt->xbutton.y, 0, 
+                          kmod, evt->xbutton.time);
+    PIXSetLastEventTimeSerial(evt->xbutton.time, evt->xbutton.serial);
+  break;
+
+  case MotionNotify :
+    {
+    int xw, yw, xr, yr;
+    unsigned int key_but;
+    Window rw, cw;
+    if ( evt->xmotion.is_hint == NotifyHint ) { 
+      if (!XQueryPointer( XtDisplay(wdgp), evt->xmotion.window, &rw, &cw,
+                  &xr, &yr, &xw, &yw, &key_but) ) break ;
+      }
+    else { key_but =  evt->xmotion.state ; xw = evt->xmotion.x;  yw = evt->xmotion.y; }
+    if  (key_but & Button1Mask ) evm = PIEvent_Ptr1Move;
+    else  if (key_but & Button2Mask ) evm = PIEvent_Ptr2Move;
+    else  if (key_but & Button3Mask ) evm = PIEvent_Ptr3Move;
+    else if ( !(key_but & (Button4Mask|Button5Mask)) )  evm = PIEvent_PtrMove;
+
+    if  (key_but & ShiftMask)   kmod = (PIKeyModifier) (kmod | PIKM_Shift);
+    if  (key_but & ControlMask) kmod = (PIKeyModifier) (kmod | PIKM_Cntl);
+    if  (key_but & Mod1Mask)    kmod = (PIKeyModifier) (kmod | PIKM_Alt);
+
+    wx->CallEventHandlers(evm, xw, yw, 0, kmod, evt->xbutton.time);
+    PIXSetLastEventTimeSerial(evt->xmotion.time, evt->xmotion.serial);    
+    }
+  break;
+
+  case KeyPress :
+    {
+    XComposeStatus cs;
+    KeySym key;
+    char buf[10];
+    int i,nc,rkey;
+
+  
+    kmod = PIKM_Blank;
+    nc = XLookupString(&(evt->xkey), buf, 10, &key, &cs);
+
+    if  (evt->xkey.state & ShiftMask)   
+      kmod = (PIKeyModifier) (kmod | PIKM_Shift);
+    if  (evt->xkey.state & ControlMask) 
+      kmod = (PIKeyModifier) (kmod | PIKM_Cntl);
+    if  (evt->xkey.state & Mod1Mask)    
+      kmod = (PIKeyModifier) (kmod | PIKM_Alt);
+    switch (key) {
+      case XK_Return :
+        rkey = PIK_Return;
+      break;
+      case XK_KP_Enter :
+        rkey = PIK_Enter;
+      break;
+      case XK_Up :
+        rkey = PIK_Up;
+      break;
+      case XK_Down :
+        rkey = PIK_Down;
+      break;
+      case XK_Left :
+        rkey = PIK_Left;
+      break;
+      case XK_Right :
+        rkey = PIK_Right;
+      break;
+      case XK_Prior :
+        rkey = PIK_Previous;
+      break;
+      case XK_Next :
+        rkey = PIK_Next;
+      break;
+      default :
+        rkey = 0;
+      break;
+    }
+    if (rkey > 0)  wx->CallEventHandlers(PIEvent_Keyboard, evt->xkey.y, evt->xkey.x, 
+                                         rkey, kmod, evt->xkey.time);
+    else for(i=0; i<nc; i++)  
+            wx->CallEventHandlers(PIEvent_Keyboard, evt->xkey.y, evt->xkey.x, 
+                                 (int)(buf[i]), kmod, evt->xkey.time);
+    PIXSetLastEventTimeSerial(evt->xkey.time, evt->xkey.serial);    
+
+  }
+  break;
+}
+
+return;
+}
+
+
+// -------- La classe PIScreenBuffer ----------
+/* --Methode-- */
+PIScreenBuffer::PIScreenBuffer(int sx, int sy)
+{
+if (sx < 1) sx = 1;
+if (sy < 1) sy = 1;
+mSx = sx;  mSy = sy;
+Display * dsx = PIXDisplay();
+Window rw = DefaultRootWindow(dsx);
+xScrbuff = XCreatePixmap(dsx, rw, sx, sy, DefaultDepth(dsx, DefaultScreen(dsx)) );
+}
+/* --Methode-- */
+PIScreenBuffer::~PIScreenBuffer()
+{
+XFreePixmap(PIXDisplay(),xScrbuff); 
+}
+
+/* --Methode-- */
+int PIScreenBuffer::XSize()
+{
+return(mSx);
+}
+
+/* --Methode-- */
+int PIScreenBuffer::YSize()
+{
+return(mSx);
+}
+
+/* --Methode-- */
+void PIScreenBuffer::CopyFromWdg(PIWdg* wdg, int ox, int oy, int dx, int dy, int x, int y)
+{
+XCopyArea(XtDisplay(wdg->XtWdg()), XtWindow(wdg->XtWdg()), XScrBuffer(), defgc, ox, oy, 
+          (unsigned int)dx, (unsigned int)dy, x, y);
+}
+
+/* --Methode-- */
+void PIScreenBuffer::CopyToWdg(PIWdg* wdg, int ox, int oy, int dx, int dy, int x, int y)
+{
+XCopyArea(XtDisplay(wdg->XtWdg()), XScrBuffer(), XtWindow(wdg->XtWdg()), defgc, ox, oy, 
+          (unsigned int)dx, (unsigned int)dy, x, y);
+}
+
+/* --Methode-- */
+void PIScreenBuffer::CopyFrom(PIScreenBuffer* grb, int ox, int oy, int dx, int dy, int x, int y)
+{
+
+XCopyArea(PIXDisplay(), grb->XScrBuffer(), XScrBuffer(), defgc, ox, oy, 
+          (unsigned int)dx, (unsigned int)dy, x, y);
+}
Index: /tags/V_Dec2002/SophyaPI/PI/piwdgx.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piwdgx.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piwdgx.h	(revision 2309)
@@ -0,0 +1,154 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive      PIWdgX
+//                                    Reza 10/95            
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PIWDG_X_SEEN
+#define PIWDG_X_SEEN
+
+#include <X11/Xlib.h>
+#include <X11/Intrinsic.h>
+
+#include "piwdggen.h"
+
+typedef Widget SysDWdg;
+typedef WidgetClass SysDWdgClass;
+
+
+class PIWdgX : public PIWdgGen 
+{
+public:
+// Les methodes ...
+  		  PIWdgX(int narg=0, char *arg[]=NULL);
+  		  PIWdgX(PIContainerGen *par, const char *nom, 
+         		 int sx=10, int sy=10, int px=0, int py=0);
+
+  virtual 	 ~PIWdgX();
+
+  virtual void	 FinishCreate(); // apres avoir installe les sous-vues
+
+  virtual void   SetSize(int sx, int sy);
+  virtual void   SetPos(int px, int py);
+
+//  Divers : couleur de fond, et d'avant plan Effacement fenetre,
+  virtual void           SetBackgroundColor(PIColors col=PI_White);
+  virtual void           SetForegroundColor(PIColors col=PI_Black);
+  virtual void           EraseWindow(int x0=0, int y0=0, int dx=0, int dy=0);
+  virtual PIColors       GetBackgroundColor();
+  virtual PIColors       GetForegroundColor();
+
+  virtual void   SetBinding(PIBindingKind left, PIBindingKind top, 
+                            PIBindingKind right, PIBindingKind bottom);
+  virtual bool   GetBinding(PIBindingKind& left, PIBindingKind& top, 
+                            PIBindingKind& right, PIBindingKind& bottom);
+
+  virtual int    XSize();
+  virtual int    YSize();
+  virtual int    XPos();
+  virtual int    YPos();
+
+  virtual string Nom();  
+  virtual void   GetScreenPos(int & spx, int & spy);
+
+  virtual void   Manage();
+  virtual void   UnManage();
+  virtual bool   IfManaged();
+  virtual bool   IsVisible();
+
+//  Fonction qui doit etre appelee pour rafraichir la fenetre 
+  virtual void       	 Refresh();
+
+//  Pour rendre un composant graphique (PIWdg) sensible/insensible 
+  virtual void           SetSensitive();
+  virtual void           SetUnSensitive();
+  virtual bool           IfSensitive();
+
+//  Gestion de copier-coller
+  virtual bool           ClaimSelection(unsigned int typ=PICP_string);
+  virtual void           SelectionLost();
+  virtual unsigned int   RequestSelection(unsigned int typ=PICP_string);
+  virtual void*          ProvideSelection(unsigned int& typ, unsigned int& len);
+  virtual void           SelectionTransferEnd();
+  virtual void           PasteSelection(unsigned int typ, void *, unsigned int l);
+
+//  Copie depuis un PIWdgGen
+  virtual void		 CopyFrom(PIWdgGen* wdg, int ox, int oy, int dx, int dy, int x, int y);
+
+//  Gestion des EventHandler
+  virtual void		 AddDrawHandler(PIEventHandler* drwh, bool ad=false);
+  virtual void		 RemoveDrawHandler(PIEventHandler* drwh);
+  virtual void		 AddEventHandler(PIEventHandler* evh, unsigned long evtmask, bool ad=false);
+  virtual void		 RemoveEventHandler(PIEventHandler* evh);
+
+// En public, pour permettre l'acces depuis call-back Xt
+  virtual void		 CallDrawHandlers(int x0, int y0, int dx, int dy); 
+  virtual void		 CallEventHandlers(unsigned long evt, int px, int py,
+                                           int k, int km, unsigned long tm);
+
+//  Usage limite a a la version X11
+  inline SysDWdg XtWdg() const {return(sdw); }; 
+  inline SysDWdg& XtWdg() {return(sdw); }; 
+  int 		CreateXtWdg(const char *nom, SysDWdgClass wdgcl=NULL, SysDWdg pwdg=NULL,
+                  int sx=10, int sy=10, int px=0, int py=0, Arg* oarg=NULL, int na=0);
+  int   	BorderWidth();
+  void  	SetBorderWidth(int bw);
+
+protected:
+// Attache effectivement le widget au container
+// Parent - Doit etre appele ds FinishCreate  
+  virtual void		BindWdgtoParent();  
+
+// Definit le type de Widget, en particulier pour la gestion des feneteres de haut niveau
+// k_wmi_cascade : Widget cree en cascade d'un autre (Exemple pour PIWIndowX)
+  enum WmIntState { k_wmi_unknown=0,
+                    k_wmi_normal=1, k_wmi_toplevel=2, 
+                    k_wmi_transient=3, k_wmi_override=4,
+                    k_wmi_appshell=5, k_wmi_cascade=6 };
+
+  int 		InitXt(int narg=0, char *arg[]=NULL); 
+
+  SysDWdg sdw;
+  WmIntState wmis;
+  bool stmng;
+  bool finishDone;  // FinishCreate appele
+  PIColors mBCol, mFCol;
+  PIBindingKind mBKleft, mBKright, mBKtop, mBKbottom;
+};
+
+typedef PIWdgX PIWdg;
+
+// -------- La classe PIScreenBuffer ----------
+class PIScreenBuffer {
+public :
+  			PIScreenBuffer(int sx, int sy);
+  virtual		~PIScreenBuffer();
+
+  virtual int         	XSize();
+  virtual int         	YSize();
+  virtual  void 	CopyFromWdg(PIWdg* wdg, int ox, int oy, int dx, int dy, int x, int y);
+  virtual  void 	CopyToWdg(PIWdg* wdg, int ox, int oy, int dx, int dy, int x, int y);
+  virtual  void 	CopyFrom(PIScreenBuffer* grb, int ox, int oy, int dx, int dy, int x, int y);
+
+//  Acces au Drawable X 
+  inline Pixmap		XScrBuffer() { return(xScrbuff); }
+protected :
+  Pixmap xScrbuff;
+  int mSx, mSy;
+};
+
+
+// Utile pour avoir acces au Display et Screen X ...
+SysDWdg   PIXtTopWdg();
+XtAppContext* PIXtAppCtx(int& szx, int& szy, int& szf);
+Display * PIXDisplay();
+#define  PIXScreen()  DefaultScreen(PIXDisplay()) 
+Time PIXGetLastEventTime();
+unsigned long PIXGetLastEventSerial();
+void PIXSetLastEventTimeSerial(Time t, unsigned long ser);
+void PIXGetLastEventInfo(unsigned int& st, Time& t);
+
+
+#endif/* PIWDGX_SEEN */
+
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/piwindowgen.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piwindowgen.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piwindowgen.cc	(revision 2309)
@@ -0,0 +1,110 @@
+//  Classe de base pour les fenêtre de premier niveau
+//  dans les programmes graphiques interactives
+//
+//                  E.Aubourg , R. Ansari  96 - 98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "piwindowgen.h"
+#include "psfile.h"
+
+//++
+// Class	PIWindow
+// Lib		PI
+// include	piwindowgen.h
+//
+//	Classe de conteneur (dérivant de *PIContainer") spécialisée pour 
+//	la création des fenêtres de premier niveau, gérée par l'application
+//	"WindowManager". La classe "PIWindow" a  implementation dépendante 
+//	du systeme utilisé (Mac, XWindow, ...). La classe "PIWindowGen" est 
+//	la classe qui définit l'interface, et ne pas doit être instanciée 
+//	directement (Méthodes virtuelles pures). Les objets instanciés sont 
+//	de la classes "PIWindow" et le fichier entête correspondant est 
+//	"PIWIN_H" défini dans "pisysdep.h"
+//--
+//++
+// Links	Parents
+// PIContainer
+//--
+//++
+// Titre	Constructeur
+//--
+//++
+// PIWindowGen(PIMsgHandler* par, const char *nom, PIWindowKind k=PIWK_normal, int sx=10, int sy=10, int px=0, int py=0)
+//	Création d'une fenêtre de haut niveau. La variable "PIWindowKind k"  contrôle
+//	le comportement de l'objet vis à vis de l'application WindowManager. Le comportement
+//	exacte, ainsi que l'apparence graphique dépend de la plateforme et du WindowManager
+//	utilisés. "par" est le l'objet "PIMsgHandler" dont dépend la fenêtre, en général un objet
+//	de la classe "PIApplication". "nom" désigne le nom, "sx,sy" la taille et 
+//	"px,py" la position de l'objet.
+//	- "PIWK_normal" : fenêtre ordinaire
+//	- "PIWK_floating" : fenêtre qui reste en avant plan 
+//	- "PIWK_dialog" : fenêtre de dialogue 
+//	- "PIWK_transient" : fenêtre apparaissant an avant plan, sans barre de contrôle 
+// long kind()
+//	Renvoie le type de la classe de l'objet ("=PIWindowGen::ClassId") pour cette classe.
+//--
+
+//++
+// Titre	Méthodes
+//--
+//++
+// void  AutoHideOnClose(bool ahc=true)
+//	Contrôle le comportement par défaut de l'objet quand la fenêtre est fermée
+//	à travers le WindowManager. si "ahc=true", "Hide()" est appelé. 
+//	Le message de l'objet avec le qualificatif "PIMsg_Closë est transmis
+//	au "PIMsgHandler" parent.
+// void  PSPrint(PSFile *psf, int ofx=0, int ofy=0)
+//	Définit une nouvelle page et appelle la méthode "PSPrint()" pour tous les
+//	objets "PIWdg" contenus dans la fenêtre.
+//--
+
+
+/* --Methode-- */
+PIWindowGen::PIWindowGen(PIMsgHandler *par, const char *nom, PIWindowKind k, 
+                         int sx, int sy, int px, int py)
+: PIContainer(NULL, nom, sx, sy, px, py), mWtyp(k)
+{
+  SetMsgParent(par);
+  AutoHideOnClose();
+}
+
+
+/* --Methode-- */
+PIWindowGen::~PIWindowGen()
+{}
+
+/* --Methode-- */
+void PIWindowGen::PSPrint(PSFile *psf, int ofx, int ofy, double scale_x, double scale_y)
+{
+if (!psf) return;
+//int ori;
+//ori = (XSize() > YSize()) ? LANDSCAPE : PORTRAIT ;
+psf->NewPage((float)XSize()*scale_x, (float)YSize()*scale_y,PI_Auto);
+PIContainerGen::PSPrint(psf, ofx, ofy, scale_x, scale_y);
+}
+
+
+/* --Methode-- */
+void PIWindowGen::Process(PIMessage msg, PIMsgHandler* sender, void* data)
+/*  On intercepte le message Active, et Close avant de les renvoyer */
+/*  avec un message ActiveWdg de la part de la fenetre              */
+{
+if (ModMsg(msg) == PIMsg_ResizeRequest) { 
+  // On change la taille de la fenetre - data est un pointeur sur entier
+  // data[0] represente l'increment (positif ou negatif) en X, data[1] en Y
+  int* nsz = (int*) data;
+  SetSize(XSize()+nsz[0], YSize()+nsz[1]);
+  return;
+  }
+else if ((msg == BuildMsg(Msg(), PIMsg_Close)) && (sender == this) && mAHC) {
+  Hide();   // Action par defaut en cas de MsgClose.
+  ReSend(msg, sender, data);
+  }
+else if (ModMsg(msg) == PIMsg_Active) {
+  ReSend(msg, sender, data);
+  PIWdg * sndw = dynamic_cast<PIWdg *>(sender);
+  if (sndw && (sndw->kind() != PIWindowGen::ClassId))  Send(Msg(),PIMsg_Active);
+  }
+else ReSend(msg, sender, data);
+return;  
+}
Index: /tags/V_Dec2002/SophyaPI/PI/piwindowgen.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piwindowgen.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piwindowgen.h	(revision 2309)
@@ -0,0 +1,37 @@
+#ifndef PIWINDOWGEN_H_SEEN
+#define PIWINDOWGEN_H_SEEN
+
+#include "pisysdep.h"
+
+#include PICONT_H
+
+enum PIWindowKind {
+  PIWK_normal = 0,
+  PIWK_dialog = 1,
+  PIWK_transient = 2,
+  PIWK_floating = 3
+};
+
+class PIWindowGen : public PIContainer {
+public:
+  enum {ClassId = 1550};
+		    PIWindowGen(PIMsgHandler* par, const char *nom, PIWindowKind k=PIWK_normal,
+                                int sx=10, int sy=10, int px=0, int py=0);
+  virtual           ~PIWindowGen();
+
+  virtual long      kind() {return ClassId; }
+
+  virtual void      PSPrint(PSFile *psf, int ofx=0, int ofy=0,
+			    double scale_x=1., double scale_y=1.);
+
+  inline  void      AutoHideOnClose(bool ahc=true) { mAHC = ahc; }
+
+  virtual void      Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+  
+protected:  
+  PIWindowKind	       mWtyp;
+  bool                 mAHC;
+};
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/piwindowmac.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piwindowmac.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piwindowmac.cc	(revision 2309)
@@ -0,0 +1,91 @@
+#include "piwindowmac.h"
+#include "pippwindowmac.h"
+
+PIWindowMac::PIWindowMac(PIMsgHandler *par, char *nom, PIWindowKind k, int sx, int sy, int px, int py)
+: PIWindowGen(par, nom, k, sx, sy, px, py), finalized(false)
+{
+	delete mPane;
+	delete mAdapter;
+	mAdapter = NULL;
+	mWindowInfo.WINDid = 1000+k;
+	mWindowInfo.attributes = windAttr_EraseOnUpdate |
+	                         windAttr_Targetable |
+	                         windAttr_Enabled;
+	switch (k) {
+	 case PIWK_normal:
+	  mWindowInfo.attributes |= windAttr_Regular | 
+	                            windAttr_TitleBar |
+	                            windAttr_SizeBox |
+	                            windAttr_CloseBox |
+	                            windAttr_Resizable;
+	  mWindowInfo.layer = windLayer_Regular;
+	  break;
+	 case PIWK_dialog:
+	  mWindowInfo.attributes |= windAttr_Modal;
+	  mWindowInfo.layer = windLayer_Modal;
+	  break;
+	 case PIWK_floating:
+	  mWindowInfo.attributes |= windAttr_Floating |
+	                            windAttr_HideOnSuspend;
+	  mWindowInfo.layer = windLayer_Floating;
+	  break;
+	}
+	mWindowInfo.minimumWidth = 30;
+	mWindowInfo.minimumHeight = 30;
+	mWindowInfo.maximumWidth = 32000;
+	mWindowInfo.maximumHeight = 32000;
+	mWindowInfo.standardSize.width = sx;
+	mWindowInfo.standardSize.height = sy;
+	mWindowInfo.userCon = 0;
+	
+	//mPane = new LWindow(mWindowInfo);
+	mPane = LWindow::CreateWindow(1000+k,LCommander::GetTopCommander());
+    ((PIPPWindowMac*)mPane)->myPIWindow = this; 
+	Rect r = {py, px, py+sy, px+sx};
+    ((LWindow*) mPane)->DoSetBounds(r);
+    SetLabel(nom);
+    //((LWindow*) mPane)->SetSuperCommander(LCommander::GetTopCommander());
+}
+
+
+PIWindowMac::~PIWindowMac()
+{}
+
+
+void PIWindowMac::Show()
+{
+  if (!finalized) {
+    FinishCreate();
+    finalized = true;
+  }
+  PIWindowGen::Show();
+}
+
+void
+PIWindowMac::SetSize(int sx, int sy)
+{
+   ((LWindow*) mPane)->ResizeWindowTo(sx, sy);
+}
+
+void
+PIWindowMac::SetPos(int px, int py)
+{
+   ((LWindow*) mPane)->MoveWindowBy(px-XPos(), py-YPos());
+}
+
+int
+PIWindowMac::XPos()
+{
+	Rect	theBounds;
+	((LWindow*) mPane)->GetGlobalBounds(theBounds);
+    return theBounds.left;
+}
+
+int
+PIWindowMac::YPos()
+{
+	Rect	theBounds;
+	((LWindow*) mPane)->GetGlobalBounds(theBounds);
+    return theBounds.top;
+}
+
Index: /tags/V_Dec2002/SophyaPI/PI/piwindowmac.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piwindowmac.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piwindowmac.h	(revision 2309)
@@ -0,0 +1,26 @@
+#ifndef PIWINDOWMAC_H_SEEN
+#define PIWINDOWMAC_H_SEEN
+
+#include "piwindowgen.h"
+#include "pisysdep.h"
+#include <LWindow.h>
+
+class PIWindowMac : public PIWindowGen {
+public:
+                         PIWindowMac(PIMsgHandler *par, char *nom, PIWindowKind k=PIWK_normal,
+                                   int sx=10, int sy=10, int px=0, int py=0);
+  virtual                ~PIWindowMac();
+  virtual void           Show();
+  virtual void           SetSize(int sx, int sy);
+  virtual void           SetPos(int px, int py);
+  virtual int            XPos();
+  virtual int            YPos();
+
+protected:
+  SWindowInfo			  mWindowInfo;
+  Boolean				  finalized;
+};
+
+typedef PIWindowMac PIWindow;
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/piwindowx.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piwindowx.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piwindowx.cc	(revision 2309)
@@ -0,0 +1,164 @@
+#include <stdio.h>
+
+#include "piwindowx.h"
+
+#include <X11/Xlib.h>
+
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#include <X11/IntrinsicP.h>
+#include <X11/Shell.h>
+#include <Xm/Form.h>
+
+/* Fonctions (Callback et action) pour traiter le message Close de WM  */
+
+/* Nouvelle-Fonction */
+static void popdwn_cb(Widget /*w*/, XtPointer *usd,  XtPointer * )
+{
+PIWindowX * dw = (PIWindowX *) usd;
+dw->Process(dw->BuildMsg(dw->Msg(),PIMsg_Close), dw, NULL) ;
+}
+
+
+/* *** ATTENTION *** La constante ci-dessous PIXMFORMFRACBASE
+   doit etre identique ds piwdgx.cc  picontainerx.cc et piwindowx.cc
+   ***************************************************************** */
+#define PIXMFORMFRACBASE 1000
+
+
+/* --Methode-- */
+PIWindowX::PIWindowX(PIMsgHandler *par, const char *nom, PIWindowKind k, 
+                     int sx, int sy, int px, int py)
+: PIWindowGen(par, nom, k, -1, -1, 0, 0)
+{
+XtTranslations trans;
+
+pwm = new PIWdgX(NULL, nom, sx, sy, px, py);
+
+switch (k)
+  {
+  case PIWK_normal :
+  case PIWK_floating :
+    pwm->CreateXtWdg(nom, topLevelShellWidgetClass, NULL, sx, sy, px, py);
+    break;
+  case PIWK_dialog :
+    pwm->CreateXtWdg(nom, transientShellWidgetClass, NULL, sx, sy, px, py);
+    break;
+  case PIWK_transient :
+    pwm->CreateXtWdg(nom, overrideShellWidgetClass, NULL, sx, sy, px, py);
+    break;
+  }
+
+
+/*  Il faut "attraper" l'action close, genere par le window-manager       */
+/*  2 actions sont necessaires, installation d'une action (CloseWindow()) */
+/*  et j'utilise ensuite un callback ds CloseWindow()                     */
+/*  Il faut aussi desactiver l'action de destruction du widget par defaut */
+/*  (XtSetArg(warg, XmNdeleteResponse, ...                                */
+/*  Attention, voir la fonction Show(), pour l'appel a XSetWMProptocols() */
+/*  Pour une fenetre donnee, on peut recuperer les Map, UnMap, Destroy,   */
+/*  etc... il faut appeler XtAddEventHandler( w, Mask, ...)               */
+/*    Mask =  StructureNotifyMask | SubstructureNotifyMask                */
+
+
+
+if ((k == PIWK_normal) || (k == PIWK_floating) || (k == PIWK_dialog))
+  { 
+  if (k == PIWK_dialog)  AutoHideOnClose(false);
+  /* XtAddEventHandler(pwm->XtWdg(), StructureNotifyMask | SubstructureNotifyMask, 
+                  FALSE, wmaction_evthandler, this);*/
+
+  XtAddCallback(pwm->XtWdg(), XtNpopdownCallback,
+                (XtCallbackProc)popdwn_cb, (XtPointer)this);
+
+
+  trans = XtParseTranslationTable("<Message>WM_PROTOCOLS:CloseWindow()");
+  XtOverrideTranslations(pwm->XtWdg() , trans);
+  Arg warg[2];
+  XtSetArg(warg[0], XmNdeleteResponse, XmDO_NOTHING);
+  XtSetValues(pwm->XtWdg(), warg, 1);
+  }
+
+CreateXtWdg(nom, xmFormWidgetClass, pwm->XtWdg(), sx, sy, 0, 0);
+int fbase = 1000 ;  // Valeur de XmNfractionBase des XmForm ds PIContainerX
+Arg  wargs[2];
+int n=0;
+XtSetArg(wargs[n],XmNfractionBase, fbase);  n++;
+XtSetValues(XtWdg(), wargs, n);
+
+wmis = k_wmi_cascade;
+}
+
+/* --Methode-- */
+PIWindowX::~PIWindowX()
+{
+Hide();
+delete pwm;
+}
+
+/* --Methode-- */
+void PIWindowX::BindWdgtoParent()
+{
+// On ne doit rien faire pour les fenetres 
+return;
+}
+
+/* --Methode-- */
+void PIWindowX::SetSize(int sx, int sy)
+{
+pwm->SetSize(sx, sy);
+PIWdgX::SetSize(sx, sy);
+return;
+}
+
+/* --Methode-- */
+void PIWindowX::SetPos(int px, int py)
+{
+pwm->SetPos(px, py);
+PIWdgX::SetPos(px, py);
+return;
+}
+
+
+/* --Methode-- */
+void PIWindowX::Show()
+{
+int fgr = 0;
+Display *mdsp;
+
+mdsp = XtDisplay(pwm->XtWdg());
+
+PIContainerGen::Show();
+// Manage();  $CHECK$ Ca ne doit plus etre necessaire Reza 9/7/97
+if (!XtIsRealized(pwm->XtWdg()))  fgr = 1;
+pwm->Manage();
+if (fgr) 
+  {
+  Atom wmd;
+  if ((mWtyp == PIWK_normal) || (mWtyp == PIWK_floating) || (mWtyp == PIWK_dialog))
+    { 
+    wmd = XInternAtom(mdsp, "WM_DELETE_WINDOW",False);
+    XSetWMProtocols(mdsp, XtWindow(pwm->XtWdg()), &wmd, 1);
+    }
+  else 
+    XSetTransientForHint(mdsp, XtWindow(PIXtTopWdg()), XtWindow(pwm->XtWdg()));
+  //  Pour faire les actions sur les fenetres X, sinon fenetre pas cree 
+  PIContainerGen::FinishCreate();
+  }
+
+// XRaiseWindow est necessaire, sinon la fenetre passe des fois derriere ...
+//if (mWtyp == PIWK_transient)  
+  XRaiseWindow(mdsp, XtWindow(pwm->XtWdg()));
+ 
+return;
+}
+
+/* --Methode-- */
+void PIWindowX::Hide()
+{
+PIWindowGen::Hide();
+// UnManage();  $CHECK$ Ca ne doit plus etre necessaire Reza 9/7/97
+pwm->UnManage();
+}
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/piwindowx.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piwindowx.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piwindowx.h	(revision 2309)
@@ -0,0 +1,28 @@
+#ifndef PIWINDOWX_H_SEEN
+#define PIWINDOWX_H_SEEN
+
+#include "piwindowgen.h"
+#include "pisysdep.h"
+
+
+class PIWindowX : public PIWindowGen {
+public:
+                         PIWindowX(PIMsgHandler *par, const char *nom, PIWindowKind k=PIWK_normal,
+                                   int sx=10, int sy=10, int px=0, int py=0);
+  virtual                ~PIWindowX();
+  
+  virtual void           SetSize(int sx, int sy);
+  virtual void           SetPos(int px, int py);  
+
+  virtual void           Show();
+  virtual void           Hide();
+
+protected:
+  virtual void		 BindWdgtoParent();  
+  PIWdgX   *pwm;
+
+};
+
+typedef PIWindowX PIWindow;
+
+#endif   /* PIWINDOWX_H_SEEN  */
Index: /tags/V_Dec2002/SophyaPI/PI/pixtbase.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pixtbase.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pixtbase.cc	(revision 2309)
@@ -0,0 +1,337 @@
+#include <stdio.h>
+
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+
+#include <X11/IntrinsicP.h>
+#include <X11/CoreP.h>
+
+#include <X11/keysym.h>
+
+#include "pixtbaseP.h"
+#include "pixtbase.h"
+
+// #define DEBUG_PIXTB
+
+ 
+//  ------- Pb de gestion du focus-keyboard  Motif-PIBaseWdg -------
+// ** Note 30/04/98  Reza
+// Il y un probleme d'attribution du focus-keyboard entre Widget Motif et
+// PIBaseWdg (Widget PIXtBase) les Attributs XmNnavigationType et XmNtraversalOn
+// ont ete desactives pour les StdWdgX - Le probleme n'a pas pu etre resolu
+// meme en attribuant les attributs  XmNnavigationType XmNtraversalOn 
+// (et XmNsensitive) a PIXtBase, ni en utilisant 
+// XSetInputFocus(XtDisplay (wdgp), XtWindow(wdgp), RevertToParent, evt->xbutton.time)
+// Solution pour le moment :
+//  XmNnavigationType =XmNONE et XmNtraversalOn=FALSE pour les PIStdWdgX 
+// sauf pour PIText ou XmNtraversalOn=TRUE
+
+
+/*  Construction du widget Xt PIXtBase   */
+
+static void     init_class_pixtbase(void);
+
+static void     init_pixtbase    (Widget, Widget, ArgList, Cardinal*);
+static void     destroy_pixtbase (Widget);
+static void     resize_pixtbase  (Widget);
+static void     expose_pixtbase  (Widget, XEvent*, Region);
+
+
+// Si on ne veut pas utiliser XtInheritAcceptFocus
+// static Boolean  acceptfocus_pixtbase   (Widget, Time* ); 
+
+
+static XtResource resources[] ={
+  {PIXNobject ,(char *)"Object", XtRPointer, sizeof(XtRPointer),
+   XtOffset(PIXtBaseWidget,  pixtbase.objet), XtRImmediate, (XtPointer)0},
+};
+
+
+PIXtBaseClassRec  piXtBaseClassRec = {
+/* Core Class Part */
+{
+
+(WidgetClass) &coreClassRec,    /* pointer to superclass ClassRec   */
+(char*)"PIXtBase",         	/* widget resource class name       */
+sizeof(PIXtBaseRec),	        /* size in bytes of widget record   */
+init_class_pixtbase,            /* class_initialize                 */
+NULL, 			        /* dynamic initialization           */
+FALSE,       		        /* has class been initialized?      */
+init_pixtbase,                  /* initialize                       */
+NULL,			        /* notify that initialize called    */
+XtInheritRealize,               /* XCreateWindow for widget         */
+// actions,     		/* widget semantics name to proc map*/
+// XtNumber(actions),           /* number of entries in actions     */
+NULL,                           /* widget semantics name to proc map*/
+0,                              /* number of entries in actions     */
+resources,                      /* resources             */
+XtNumber(resources),            /* resources             */
+NULLQUARK,		        /* resource class quarkified        */
+TRUE,			        /* compress MotionNotify for widget */
+TRUE,			        /* compress Expose events for widget*/
+TRUE,			        /* compress enter and leave events  */
+TRUE,			        /* select for VisibilityNotify      */
+destroy_pixtbase,	        /* free data for subclass pointers  */
+resize_pixtbase,                /* geom manager changed widget size */
+expose_pixtbase,       	        /* rediplay window                  */
+NULL,		                /* set subclass resource values     */
+NULL,			        /* notify that set_values called    */
+XtInheritSetValuesAlmost,       /* set_values got "Almost" geo reply*/
+NULL,		                /* notify that get_values called    */
+XtInheritAcceptFocus,           /* assign input focus to widget     */
+// acceptfocus_pixtbase,           /* assign input focus to widget     */
+XtVersion,	                /* version of intrinsics used       */
+NULL,		                /* list of callback offsets         */
+// translations,	        /* state machine                    */
+NULL,                           /* state machine                    */
+XtInheritQueryGeometry,         /* return preferred geometry        */
+XtInheritDisplayAccelerator,    /* display your accelerator         */
+NULL		                /* pointer to extension record      */
+}
+/* PIXtBase */
+,{   NULL }
+
+};
+
+WidgetClass piXtBaseWidgetClass = (WidgetClass) &piXtBaseClassRec;
+
+
+/*  Last XEvent Serial Number and Time-Stamp , and Key-state */
+static Time last_time_xevt = 0;
+static unsigned long last_serial_xevt = 0;
+static unsigned int  last_state_xevt = 0;
+
+
+Time PIXGetLastEventTime() { return(last_time_xevt); }
+unsigned long PIXGetLastEventSerial() { return(last_serial_xevt); }
+void PIXSetLastEventTimeSerial(Time t, unsigned long ser) 
+{ last_time_xevt = t;  last_serial_xevt = ser; }
+void PIXGetLastEventInfo(unsigned int& st, Time& t)
+{ st = last_state_xevt;  t = last_time_xevt; }
+
+/* Nouvelle-Fonction */
+static void init_class_pixtbase()
+{
+#ifdef DEBUG_PIXTB
+puts("Debug_init_class_pixtbase() ");
+#endif
+return;
+}
+
+/* Nouvelle-Fonction */
+static void init_pixtbase (Widget request, Widget wdg,
+                          ArgList /*args*/, Cardinal* /*narg*/)
+{
+PIXtBaseWidget wdgp;
+wdgp = (PIXtBaseWidget)wdg;
+
+if(request->core.width<=0)  wdgp->core.width  = 10;
+if(request->core.height<=0) wdgp->core.height = 10;
+// get_GCs (wdgp);
+#ifdef DEBUG_PIXTB
+printf("Debug_init_pixtbase: Wdg=%lx Object= %lx  narg=%d \n", 
+(long)wdgp, (long)(wdgp->pixtbase.objet), (int)(*narg));
+#endif
+return;
+}
+
+/* Nouvelle-Fonction */
+static void destroy_pixtbase (Widget /*wdgp*/)
+{
+#ifdef DEBUG_PIXTB
+printf("Debug_destroy_pixtbase: Wdg= %lx Object= %lx \n", (long)wdgp, 
+(long)(((PIXtBaseWidget)wdgp)->pixtbase.objet) );
+#endif
+// free_GCs((PIXtBaseWidget)wdgp);
+//    $CHECK$ Reza  21/11/97
+// J'ai l'impression que cette fonction n'est pas appellee au moment 
+// de destruction du Widget - Par contre la fonction leave est appelee
+// si l'action correspondante a ete enregistree ?!
+}
+
+
+/* Nouvelle-Fonction */
+static void resize_pixtbase (Widget wdgp)
+{
+#ifdef DEBUG_PIXTB
+printf("Debug_resize_pixtbase: Wdg=%lx Object= %lx \n", (long)wdgp, 
+(long)(((PIXtBaseWidget)wdgp)->pixtbase.objet) );
+#endif
+if (((PIXtBaseWidget)wdgp)->pixtbase.objet) 
+  (((PIXtBaseWidget)wdgp)->pixtbase.objet)->Resize();
+return;
+}
+
+/* Nouvelle-Fonction */
+static void expose_pixtbase (Widget  wdgp, XEvent* /*event*/, Region region)
+{
+#ifdef DEBUG_PIXTB
+printf("Debug_expose_pixtbase: Wdg=%lx Object= %lx \n", (long)wdgp, 
+(long)(((PIXtBaseWidget)wdgp)->pixtbase.objet) );
+#endif
+if (!(wdgp->core.visible))  return;
+if ( ((PIXtBaseWidget)wdgp)->pixtbase.objet ) 
+  {
+  XRectangle  xrec;
+  int x0, y0, dx, dy;
+  XClipBox(region, &xrec);
+  x0 = xrec.x;  y0 = xrec.y;
+  dx = xrec.width;  dy = xrec.height;
+  (((PIXtBaseWidget)wdgp)->pixtbase.objet)->eXposeProcess(x0, y0, dx, dy);
+  }
+return;
+}
+
+/* Nouvelle-Fonction 
+static Boolean  acceptfocus_pixtbase   (Widget wdgp , Time* )
+{
+// printf("acceptfocus_pixtbase() %lx %x \n",  ((PIXtBaseWidget)wdgp)->pixtbase.myeventmask, ShiftMask );
+if (  ((PIXtBaseWidget)wdgp)->pixtbase.myeventmask & ShiftMask  )  return TRUE;
+else return FALSE;
+}
+*/
+
+/* -------- Fonction de traitement des evenements --------- */
+/* Nouvelle-Fonction */
+void event_handler_pixtbase (Widget wdgp, XtPointer /*closure*/, 
+                             XEvent* evt, Boolean* cont)
+{
+
+*cont = true ; 
+switch (evt->type) {
+  case EnterNotify : 
+#ifdef DEBUG_PIXTB
+    printf("Debug_enter_pixtbase: Wdg=%lx Object= %lx \n", (long)wdgp, 
+           (long)(((PIXtBaseWidget)wdgp)->pixtbase.objet) );
+#endif
+    last_time_xevt = evt->xcrossing.time;
+    last_serial_xevt = evt->xcrossing.serial;
+    last_state_xevt = evt->xcrossing.state;
+//    if (((PIXtBaseWidget)wdgp)->pixtbase.objet) 
+    (((PIXtBaseWidget)wdgp)->pixtbase.objet)->Enter();
+  break;
+
+  case LeaveNotify : 
+#ifdef DEBUG_PIXTB
+    printf("Debug_leave_pixtbase: Wdg=%lx Object= %lx \n", (long)wdgp, 
+           (long)(((PIXtBaseWidget)wdgp)->pixtbase.objet) );
+#endif
+    last_time_xevt = evt->xcrossing.time;
+    last_serial_xevt = evt->xcrossing.serial;
+    last_state_xevt = evt->xcrossing.state;
+//    if (((PIXtBaseWidget)wdgp)->pixtbase.objet) 
+       (((PIXtBaseWidget)wdgp)->pixtbase.objet)->Leave();
+  break;
+
+  case ButtonPress :
+    last_time_xevt = evt->xbutton.time;
+    last_serial_xevt = evt->xbutton.serial;
+    last_state_xevt = evt->xbutton.state;
+    if ( (evt->xbutton.button == 1) && ( ((PIXtBaseWidget)wdgp)->pixtbase.myeventmask & Button1Mask) )
+      (((PIXtBaseWidget)wdgp)->pixtbase.objet)->But1Press(evt->xbutton.x, evt->xbutton.y);
+    else  if ( (evt->xbutton.button == 2) && ( ((PIXtBaseWidget)wdgp)->pixtbase.myeventmask & Button2Mask) )
+      (((PIXtBaseWidget)wdgp)->pixtbase.objet)->But2Press(evt->xbutton.x, evt->xbutton.y);
+    else  if ( (evt->xbutton.button == 3)  && ( ((PIXtBaseWidget)wdgp)->pixtbase.myeventmask & Button3Mask) )
+      (((PIXtBaseWidget)wdgp)->pixtbase.objet)->But3Press(evt->xbutton.x, evt->xbutton.y);
+  break;
+
+  case ButtonRelease :
+    last_time_xevt = evt->xbutton.time;
+    last_serial_xevt = evt->xbutton.serial;
+    last_state_xevt = evt->xbutton.state;
+    if ( (evt->xbutton.button == 1) && ( ((PIXtBaseWidget)wdgp)->pixtbase.myeventmask & Button1Mask) )
+      (((PIXtBaseWidget)wdgp)->pixtbase.objet)->But1Release(evt->xbutton.x, evt->xbutton.y);
+    else  if ( (evt->xbutton.button == 2) && ( ((PIXtBaseWidget)wdgp)->pixtbase.myeventmask & Button2Mask) )
+      (((PIXtBaseWidget)wdgp)->pixtbase.objet)->But2Release(evt->xbutton.x, evt->xbutton.y);
+    else  if ( (evt->xbutton.button == 3)  && ( ((PIXtBaseWidget)wdgp)->pixtbase.myeventmask & Button3Mask) )
+      (((PIXtBaseWidget)wdgp)->pixtbase.objet)->But3Release(evt->xbutton.x, evt->xbutton.y);
+  break;
+
+  case MotionNotify :
+    {
+    int xw, yw, xr, yr;
+    unsigned int key_but;
+    Window rw, cw;
+    if ( evt->xmotion.is_hint == NotifyHint ) { 
+      if (!XQueryPointer( XtDisplay(wdgp), evt->xmotion.window, &rw, &cw,
+                  &xr, &yr, &xw, &yw, &key_but) ) break ;
+      }
+    else { key_but =  evt->xmotion.state ; xw = evt->xmotion.x;  yw = evt->xmotion.y; }
+//    if  ( !(key_but & ( Button1Mask | Button2Mask | Button3Mask ) ) ) break;
+      last_time_xevt = evt->xmotion.time;
+      last_serial_xevt = evt->xmotion.serial;
+      last_state_xevt = evt->xmotion.state;
+      if  (key_but & Button1Mask ) 
+        (((PIXtBaseWidget)wdgp)->pixtbase.objet)->Ptr1Move(xw, yw);
+      else  if (key_but & Button2Mask ) 
+        (((PIXtBaseWidget)wdgp)->pixtbase.objet)->Ptr2Move(xw, yw);
+      else  if (key_but & Button3Mask ) 
+        (((PIXtBaseWidget)wdgp)->pixtbase.objet)->Ptr3Move(xw, yw);
+      else if ( !(key_but & (Button4Mask|Button5Mask)) ) 
+        (((PIXtBaseWidget)wdgp)->pixtbase.objet)->PtrMove(xw, yw);
+    }
+  break;
+
+  case KeyPress :
+    {
+    XComposeStatus cs;
+    KeySym key;
+    char buf[10];
+    int i,nc,rkey;
+    PIKeyModifier kmod;
+  
+    kmod = PIKM_Blank;
+    nc = XLookupString(&(evt->xkey), buf, 10, &key, &cs);
+
+    if  (evt->xkey.state & ShiftMask)   
+      kmod = (PIKeyModifier) (kmod | PIKM_Shift);
+    if  (evt->xkey.state & ControlMask) 
+      kmod = (PIKeyModifier) (kmod | PIKM_Cntl);
+    if  (evt->xkey.state & Mod1Mask)    
+      kmod = (PIKeyModifier) (kmod | PIKM_Alt);
+    // sur MacOSX, la touche Alt correspond a la touche pomme 
+    // et la masque associe est Mod2Mask   -    Reza 02/2002
+#if defined(Darwin)
+    if  (evt->xkey.state & Mod2Mask)    
+      kmod = (PIKeyModifier) (kmod | PIKM_Alt);
+#endif
+    switch (key) {
+      case XK_Return :
+        rkey = PIK_Return;
+      break;
+      case XK_KP_Enter :
+        rkey = PIK_Enter;
+      break;
+      case XK_Up :
+        rkey = PIK_Up;
+      break;
+      case XK_Down :
+        rkey = PIK_Down;
+      break;
+      case XK_Left :
+        rkey = PIK_Left;
+      break;
+      case XK_Right :
+        rkey = PIK_Right;
+      break;
+      case XK_Prior :
+        rkey = PIK_Previous;
+      break;
+      case XK_Next :
+        rkey = PIK_Next;
+      break;
+      default :
+        rkey = 0;
+      break;
+    }
+    if (rkey > 0)  (((PIXtBaseWidget)wdgp)->pixtbase.objet)->Keyboard(rkey, kmod);
+    else for(i=0; i<nc; i++)  
+      (((PIXtBaseWidget)wdgp)->pixtbase.objet)->Keyboard((int)(buf[i]), kmod);
+  }
+  break;
+}
+
+return;
+}
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/pixtbase.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pixtbase.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pixtbase.h	(revision 2309)
@@ -0,0 +1,19 @@
+/* Widget Xt pour construction Widget C++  Interface Public  */
+/*                                    Reza 10/95             */
+
+#ifndef PIXTBASE_H_SEEN
+#define PIXTBASE_H_SEEN
+
+#include <X11/Intrinsic.h>
+ 
+typedef struct _PIXtBaseClassRec * PIXtBaseWidgetClass;
+typedef struct _PIXtBaseRec      * PIXtBaseWidget;
+
+#define PIXNobject      "mypiobject"
+
+extern WidgetClass piXtBaseWidgetClass;
+
+void event_handler_pixtbase (Widget wdgp, XtPointer closure, 
+                             XEvent* evt, Boolean* cont);
+
+#endif /* PIXTBASE_H_SEEN */
Index: /tags/V_Dec2002/SophyaPI/PI/pixtbaseP.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/pixtbaseP.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/pixtbaseP.h	(revision 2309)
@@ -0,0 +1,41 @@
+/* Widget Xt pour affichage d'image   Declaration privee  */
+/*                                      Reza 10/95        */
+
+
+#ifndef PIXTBASEP_H_SEEN
+#define PIXTBASEP_H_SEEN
+
+#include "pibwdgx.h"
+
+typedef struct
+{
+   void * mumble;   /* No new procedures */
+} PIXtBaseClassPart;
+
+
+typedef struct _RzXBaseClassRec
+{
+CoreClassPart		core_class;
+PIXtBaseClassPart	pixtbase_class;
+} PIXtBaseClassRec;
+
+typedef struct
+{
+PIBaseWdgX  * objet; 
+unsigned long myeventmask;
+} PIXtBasePart;
+
+
+typedef struct _PIXtBaseRec
+{
+CorePart		core;
+PIXtBasePart		pixtbase;
+} PIXtBaseRec;
+
+extern PIXtBaseClassRec piXtBaseClassRec;
+
+
+#endif /* PIXTBASEP_H_SEEN */
+
+
+
Index: /tags/V_Dec2002/SophyaPI/PI/piyfxdrw.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piyfxdrw.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piyfxdrw.cc	(revision 2309)
@@ -0,0 +1,210 @@
+// Module PI : Peida Interactive  PIYfXDrawer, PIFuncDrawer
+// Drawer Y=f(X)      E.Aubourg, R. Ansari  96-02
+// (C) LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "machdefs.h"
+#include <math.h>
+#include "piyfxdrw.h"
+#include "parradapter.h"
+
+// --------------------------------------------------------------------------
+// --------------------------------------------------------------------------
+// --------------------------------------------------------------------------
+// ----------------------------------------------------------
+//  Classe de trace de points/fonctions Y=f(X)
+//  Trace Y=ay->Value() = f(X= ax->Value()) si ax et ay != NULL
+//  Trace Y=ax->Value() = f(X= ax->X())  si ay == NULL
+// ----------------------------------------------------------
+// --------------------------------------------------------------------------
+
+//++
+// Class	PIYfXDrawer
+// Lib		PI
+// include	piyfxdrw.h
+//
+//	Classe de traceur de points/fonctions Y = f(X).
+//--
+//++
+// Links	Parents
+// PIDrawer
+//--
+//++
+// Links	Voir aussi
+// P1DArrayAdapter
+//--
+//++
+// Titre	Constructeur
+//--
+
+//++
+// PIYfXDrawer(P1DArrayAdapter* ax, P1DArrayAdapter* ay, bool ad)
+//	Constructeur. Tracé de 
+//|	 Y=ay->Value() = f(X= ax->Value()) si ax et ay != NULL
+//|	Y=ax->Value() = f(X= ax->X())  si ay == NULL
+//	Si "ad==true" les objets "ax" et "ay" sont détruits par 
+//	le destructeur de "PIYfXDrawer".
+//--
+
+/* --Methode-- */
+PIYfXDrawer::PIYfXDrawer(P1DArrayAdapter* ax, P1DArrayAdapter* ay, bool ad)
+    : PIDrawer()
+{
+  mAdDO = ad;
+  mAx = ax;
+  mAy = ay;
+  mName = "YfXDrawer";
+} 
+
+/* --Methode-- */
+PIYfXDrawer::~PIYfXDrawer()
+{
+  if (mAdDO && mAx)  delete mAx;
+  if (mAdDO && mAy)  delete mAy;
+}
+
+/* --Methode-- */
+void PIYfXDrawer::UpdateLimits()
+{
+  if ((mAx == NULL))  mSz = 0;
+  else {
+    if (!mAy)  mSz = mAx->Size();
+    else   mSz = (mAx->Size() < mAy->Size()) ? mAx->Size() :  mAy->Size();
+    }
+  if (mSz <= 0)  return;
+  double xmin, xmax, ymin, ymax;
+  int i=0;
+  double cv;
+  if (mAy) {
+    xmin = xmax = mAx->Value(0);
+    ymin = ymax = mAy->Value(0);
+    for(i=1; i<mSz; i++) {
+      cv = mAx->Value(i); 
+      if (cv < xmin)  xmin = cv;
+      if (cv > xmax)  xmax = cv;
+      cv = mAy->Value(i); 
+      if (cv < ymin)  ymin = cv;
+      if (cv > ymax)  ymax = cv;
+      }
+    }
+  else {
+    xmin = xmax = mAx->X(0);
+    ymin = ymax = mAx->Value(0);
+    for(i=1; i<mSz; i++) {
+      cv = mAx->X(i); 
+      if (cv < xmin)  xmin = cv;
+      if (cv > xmax)  xmax = cv;
+      cv = mAx->Value(i); 
+      if (cv < ymin)  ymin = cv;
+      if (cv > ymax)  ymax = cv;
+      }
+    }
+
+  PIAxes::ReSizeMinMax(isLogScaleX(),xmin,xmax);
+  PIAxes::ReSizeMinMax(isLogScaleY(),ymin,ymax);
+  SetLimits(xmin,xmax,ymin,ymax);
+  SetAxesFlags(kBoxAxes | kExtTicks | kLabels);
+}
+
+
+/* --Methode-- */
+void PIYfXDrawer::Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax)
+{
+  double xp,yp;
+  int i;
+
+  if ((mAx == NULL))  mSz = 0;
+  else {
+    if (!mAy)  mSz = mAx->Size();
+    else   mSz = (mAx->Size() < mAy->Size()) ? mAx->Size() :  mAy->Size();
+    }
+  if (mSz <= 0)  return;
+
+//  Trace des markers 
+  if ( (GetGraphicAtt().GetMarker() != PI_NotDefMarker) ||  
+       (GetGraphicAtt().GetLineAtt() == PI_NotDefLineAtt) ) {
+    for(i=0; i<mSz; i++) {
+      if (mAy) { xp = mAx->Value(i); yp = mAy->Value(i); }
+      else { xp = mAx->X(i);  yp = mAx->Value(i); }
+      if ( (xp < xmin) || (xp > xmax) || (yp < ymin) || (yp > ymax) )  continue;
+      g->DrawMarker(xp, yp);
+    }
+  }
+
+  if (GetGraphicAtt().GetLineAtt() == PI_NotDefLineAtt)    return;
+
+// Trace des lignes 
+  double xp2, yp2;
+  if (mAy) { xp2 = mAx->Value(0); yp2 = mAy->Value(0); }
+  else { xp2 = mAx->X(0);  yp2 = mAx->Value(0); }
+  for(i=1; i<mSz; i++) {
+    xp = xp2; yp = yp2;
+    if (mAy) { xp2 = mAx->Value(i); yp2 = mAy->Value(i); }
+    else { xp2 = mAx->X(i);  yp2 = mAx->Value(i); }
+    if ( ((xp < xmin) || (xp > xmax) || (yp < ymin) || (yp > ymax)) &&
+         ((xp2 < xmin) || (xp2 > xmax) || (yp2 < ymin) || (yp2 > ymax)) )  continue;
+    g->DrawLine(xp, yp, xp2, yp2);
+  }
+}
+
+
+//================================================================
+// PIFuncDrawer
+// Classe de traceur de fonction  double = f(fouble)
+//================================================================
+
+//++
+// Class	PIFuncDrawer
+// Lib		PI
+// include	piyfxdrw.h
+//
+//	Classe de traceur de fonctions Y = f(double X).
+//--
+//++
+// Links	Parents
+// PIDrawer
+//--
+//++
+// Titre	Constructeur
+//--
+//++
+//  PIFuncDrawer(FUNC f)
+//	Constructeur de traceur d'une fonction "FUNC f" avec
+//|	typedef double(*FUNC)(double)
+//--
+
+
+/* --Methode-- */
+PIFuncDrawer::PIFuncDrawer(PIFuncDrawer::FUNC f)
+: mFunc(f)
+{}
+
+/* --Methode-- */
+PIFuncDrawer::~PIFuncDrawer()
+{
+}
+
+/* --Methode-- */
+void
+PIFuncDrawer::Draw(PIGraphicUC* g, double /*xmin*/, double/*ymin*/, double/*xmax*/, double/*ymax*/)
+{
+  if (mFunc == NULL) return;
+
+  PIGrCoord x1, x2, y1, y2;
+  g->GetGrSpace(x1, x2, y1, y2);
+  double xMax = x2;
+  double xMin = x1;
+  double yMax = y2;
+  double yMin = y1;
+  double xStep = (xMax - xMin)/100;
+  double xOld = xMin;
+  double yOld = mFunc(xMin);
+  for (double x = xMin+xStep; x<xMax; x+=xStep) {
+    double y = mFunc(x);
+    if (y>yMin && yOld>yMin && 
+        y<yMax && yOld<yMax) 
+           g->DrawLine(xOld, yOld, x, y);
+    xOld = x;
+    yOld = y;
+  }
+}
+
Index: /tags/V_Dec2002/SophyaPI/PI/piyfxdrw.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/piyfxdrw.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/piyfxdrw.h	(revision 2309)
@@ -0,0 +1,50 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive  PIYfXDrawer, PIFuncDrawer
+// Drawer Y=f(X)      E.Aubourg, R. Ansari  96-02
+// (C) LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PIYFXDRW_H
+#define PIYFXDRW_H
+
+#include "pisysdep.h"
+#include "parradapter.h"
+#include "pidrawer.h"
+
+// ----------------------------------------------------------
+// Classe de traceur de points/fonction Y=F(x)
+// Trace Y=ay->Value() = f(X= ax->Value()) si ax et ay != NULL
+// Trace Y=ax->Value() = f(X= ax->X())  si ay == NULL
+ 
+class P1DArrayAdapter;
+class PIYfXDrawer : public PIDrawer {
+public:
+                     PIYfXDrawer(P1DArrayAdapter* ax, P1DArrayAdapter* ay, bool ad);
+  virtual           ~PIYfXDrawer();
+  
+  virtual void       Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax);
+  virtual void       UpdateLimits();
+  
+       
+protected:
+  P1DArrayAdapter* mAx;
+  P1DArrayAdapter* mAy;
+  int mSz;
+  bool mAdDO;
+};
+
+// ----------------------------------------------------------
+// Classe de traceur de fonction  double = f(fouble)
+// ----------------------------------------------------------
+
+class PIFuncDrawer : public PIDrawer {
+public:
+  typedef double(*FUNC)(double);
+                     PIFuncDrawer(FUNC);
+  virtual           ~PIFuncDrawer();
+  
+  virtual void       Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax);
+protected:
+  FUNC               mFunc;
+};
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/psfile.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/psfile.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/psfile.cc	(revision 2309)
@@ -0,0 +1,1408 @@
+/*
+ *   PSFile.cc
+ *   
+ *   19/06/96
+ *
+ *   Modification le 01/03/96
+ *    - fusion psfile.cc - psdict.cc
+ *
+ *
+ *   07/08/99 : Gestion des fontes ; ajout Times/Helvetica/Symbol 
+ *              
+ * 
+ *
+ *
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <time.h>
+
+#include "psfile.h"
+
+//++
+// Class	PSFile
+// Lib		PI
+// include	psfile.h
+//
+//   	Classe encapsulant un fichier PostScript, fournissant des primitives
+//	graphiques produisant du code PostScript.
+//--
+//++
+// Links	Voir aussi
+// PIGraphicPS
+//--
+
+
+
+/* En cm */
+#define  MIN_SIZE_IN_PAGE  2.
+
+/*
+ *  Dictionnaire PIDict
+ *
+ *  Contient les fonctions suivantes : 
+ *
+ *
+ */
+#define PIDICT_PAR   \
+  \
+  PI_Landscape, PI_Portrait,\
+  \
+  PI_ColorFromMap, PI_Black, PI_White, PI_Grey, PI_Red, PI_Blue,\
+  PI_Green, PI_Yellow, PI_Magenta, PI_NotDefColor,\
+  PI_Cyan, PI_Turquoise, PI_NavyBlue,\
+  PI_Orange, PI_SiennaRed, PI_Purple,\
+  PI_LimeGreen, PI_Gold, PI_Violet, PI_VioletRed, PI_BlueViolet, PI_DarkViolet, \
+  \
+  PI_RomanFont, PI_BoldFont, PI_ItalicFont, PI_NotDefFontAtt,\
+  PI_SmallSizeFont, PI_NormalSizeFont, PI_LargeSizeFont, PI_NotDefFontSize, \
+  \
+  PI_NormalLine, PI_ThinLine, PI_ThickLine, PI_NotDefLineAtt
+
+#define PIDICT       "\
+/$PIDict 50 dict def\n\
+$PIDict begin $PIDict /mtrx matrix put /Landscape %d def /Portrait %d def\n\
+%% Couleurs et fontes courantes\n\
+/C%-2d  {ur    ug    ub    setrgbcolor} bind def %% PI_ColorFromMap\n\
+/C%-2d  {0.0   0.0   0.0   setrgbcolor} bind def %% PI_Black\n\
+/C%-2d  {0.996 0.996 0.996 setrgbcolor} bind def %% PI_White\n\
+/C%-2d  {0.824 0.824 0.824 setrgbcolor} bind def %% PI_Grey\n\
+/C%-2d  {0.996 0.0   0.0   setrgbcolor} bind def %% PI_Red\n\
+/C%-2d  {0.0   0.0   0.996 setrgbcolor} bind def %% PI_Blue\n\
+/C%-2d  {0.0   0.996 0.0   setrgbcolor} bind def %% PI_Green\n\
+/C%-2d  {0.996 0.996 0.0   setrgbcolor} bind def %% PI_Yellow\n\
+/C%-2d  {0.996 0.0   0.996 setrgbcolor} bind def %% PI_Magenta\n\
+/C%-2d  {}                              bind def %% PI_NotDefColor\n\
+/C%-2d  {0.0   0.996 0.996 setrgbcolor} bind def %% PI_Cyan\n\
+/C%-2d  {0.250 0.875 0.813 setrgbcolor} bind def %% PI_Turquoise\n\
+/C%-2d  {0.0   0.0   0.500 setrgbcolor} bind def %% PI_NavyBlue\n\
+/C%-2d  {0.996 0.644 0.0   setrgbcolor} bind def %% PI_Orange\n\
+/C%-2d  {0.625 0.320 0.176 setrgbcolor} bind def %% PI_SiennaRed\n\
+/C%-2d  {0.625 0.125 0.937 setrgbcolor} bind def %% PI_Purple\n\
+/C%-2d  {0.195 0.800 0.195 setrgbcolor} bind def %% PI_LimeGreen\n\
+/C%-2d  {0.996 0.840 0.0   setrgbcolor} bind def %% PI_Gold\n\
+/C%-2d  {0.933 0.510 0.933 setrgbcolor} bind def %% PI_Violet\n\
+/C%-2d  {0.816 0.125 0.565 setrgbcolor} bind def %% PI_VioletRed\n\
+/C%-2d  {0.541 0.167 0.886 setrgbcolor} bind def %% PI_BlueViolet\n\
+/C%-2d  {0.580 0.000 0.827 setrgbcolor} bind def %% PI_DarkViolet\n\
+/F%-2d  {/Courier   findfont} bind def           %% PI_RomanFont\n\
+/F%-2d  {/Courier-Bold    findfont} bind def     %% PI_BoldFont\n\
+/F%-2d  {/Courier-Italic  findfont} bind def     %% PI_ItalicFont\n\
+/F%-2d  {}\
+                        bind def       %% PI_NotDefFontAtt\n\
+/FS {scalefont setfont} bind def\n\
+%%/FS%-2d {8  scalefont setfont} bind def          %% PI_SmallSizeFont\n\
+%%/FS%-2d {12 scalefont setfont} bind def          %% PI_NormalSizeFont\n\
+%%/FS%-2d {16 scalefont setfont} bind def          %% PI_LargeSizeFont\n\
+/FS%-2d {}                     bind def          %% PI_NotDefFontSize\n\
+/L%-2d  {1    slw} bind def                      %% PI_NormalLine\n\
+/L%-2d  {0.5  slw} bind def                      %% PI_ThinLine\n\
+/L%-2d  {3    slw} bind def                      %% PI_ThickLine\n\
+/L%-2d  {}         bind def                      %% PI_NotDefLineAtt\n\
+\
+%% Conversion\n\
+/cm   {28.3 mul}   bind def  %% cm --> points\n\
+/Ux   {$Cvrtx mul} bind def  %% Unites utilisateur /x --> points\n\
+/Uy   {$Cvrty mul} bind def  %% Unites utilisateur /y --> points\n\
+\
+%% Pages et Blocs\n\
+/newref  {%% Dx Dy Tx Ty X0 Y0 newref\n\
+translate 3 -1 roll cm div 28.3 mul /$Cvrty exch def\n\
+exch cm div 28.3 mul /$Cvrtx exch def} bind def\n\
+/NewPage {%% Dx Dy orientation NewPage\n\
+/$PageEnteredState save def 1 -1 scale Portrait eq {w cm h cm 0 h cm neg\n\
+newref} { -90 rotate h cm w cm 0 0 newref} ifelse} bind def\n\
+/EndPage { %% EndPage\n\
+$PageEnteredState restore} bind def\n\
+/NewBloc { %% Dx Dy Tx Ty X0 Y0 NewBloc\n\
+/$BlocEnteredState save def newref} bind def\n\
+/EndBloc { %% EndBloc\n\
+$BlocEnteredState restore} bind def\n\
+\
+%% Trace\n\
+/n  {newpath} bind def    /c  {closepath} bind def\n\
+/gs {gsave}  bind def     /gr {grestore} bind def\n\
+/m  {moveto} bind def     /l  {lineto} bind def\n\
+/s  {stroke} bind def     /f  {fill}   bind def\n\
+/sc {scale}  bind def     /S  {gs 1 -1 sc show gr} bind def \n\
+/slw {setlinewidth} bind def\n\
+/sljoin {setlinejoin} bind def\n\
+/slcap {setlinecap} bind def\n\
+/slsolid {[] 0 setdash} bind def %% Solid-Line \n\
+/sldash {[6 6] 0 setdash} bind def %% Dashed-Line \n\
+/sldott {[2 6] 0 setdash} bind def %% Dotted-Line \n\
+/sldashdott {[2 2 4 6] 0 setdash} bind def %% Dash-Dotted-Line \n\
+/ff {findfont} bind def   /sf {setfont} bind def /scf {scalefont} bind def\n\
+/rl {rlineto} bind def    /tr {translate} bind def\n\
+/rmv {rmoveto} bind def \n\
+%% Trace de chaine avec justification diverse \n\
+%% ------------------------------------------------- \n\
+%% hxshstr  stack: TheString \n\
+%% hx (x=r,c,l) Horizontal-X Right,Center,Left - Vertical: BaseLine \n\
+%% ------------------------------------------------- \n\
+/hlshstr   %% Horizontal-left Vertical-BaseLine justified \n\
+{ gs 1 -1 sc show gr } bind def \n\
+/hcshstr   %% Horizontal-Center Vertical-BaseLine justified \n\
+{ dup stringwidth pop 2 div neg  %% get minus(string length/2)  \n\
+  0 rmoveto gs 1 -1 sc show gr } bind def \n\
+/hrshstr   %% Horizontal-Right Vertical-BaseLine justified \n\
+{ dup stringwidth pop neg  %% get minus(string width)  \n\
+  0 rmoveto gs 1 -1 sc show gr } bind def \n\
+%% ------------------------------------------------- \n\
+%% hxvyshstr  stack: TheString \n\
+%% hx (x=r,c,l) Horizontal-X Right,Center,Left \n\
+%% vy (y=t,c,b) Vertical-Y Top,Center,Bottom \n\
+%% Ces procs (hxvyshstr) utilisent la variable curfntsz que l'on definit par defaut \n\
+%% hxshstr  stack: TheString \n\
+%% hx (x=r,c,l) Horizontal-X Right,Center,Left - Vertical: BaseLine \n\
+%% ------------------------------------------------- \n\
+/curfntsz 10 def \n\
+/hlvbshstr   %% Horizontal-left Vertical-Bottom justified \n\
+{ gs 1 -1 sc show gr } bind def \n\
+/hcvbshstr   %% Horizontal-Center Vertical-Bottom justified \n\
+{ dup stringwidth pop 2 div neg  %% get minus(string length/2)  \n\
+  0 rmoveto gs 1 -1 sc show gr } bind def \n\
+/hrvbshstr   %% Horizontal-Right Vertical-Bottom justified \n\
+{ dup stringwidth pop neg  %% get minus(string width)  \n\
+  0 rmoveto gs 1 -1 sc show gr } bind def \n\
+/hlvcshstr   %% Horizontal-left Vertical-Center justified \n\
+{ 0 curfntsz 2 div   %% get (string height)/2  \n\
+  rmoveto gs 1 -1 sc show gr } bind def \n\
+/hcvcshstr   %% Horizontal-Center Vertical-Center justified \n\
+{ dup stringwidth pop 2 div neg curfntsz 2 div  %% s_wy/2 -s_wx/2  \n\
+  rmoveto gs 1 -1 sc show gr } bind def \n\
+/hrvcshstr   %% Horizontal-Right Vertical-Center justified \n\
+{ dup stringwidth pop neg curfntsz  %% s_wy/2 -s_wx  \n\
+  rmoveto gs 1 -1 sc show gr } bind def \n\
+/hlvtshstr   %% Horizontal-left Vertical-Top justified \n\
+{ 0 curfntsz   %% get s_wy  \n\
+  rmoveto gs 1 -1 sc show gr } bind def \n\
+/hcvtshstr   %% Horizontal-Center Vertical-Top justified \n\
+{ dup stringwidth pop 2 div neg curfntsz  %% s_wy -s_wx/2  \n\
+  rmoveto gs 1 -1 sc show gr } bind def \n\
+/hrvtshstr   %% Horizontal-Right Vertical-Top justified \n\
+{ dup stringwidth pop neg curfntsz  %% s_wy -s_wx  \n\
+  rmoveto gs 1 -1 sc show gr } bind def \n\
+%% Tx Ty X0 Y0 box\n\
+/box {tr 0 3 1 roll neg exch 0 0 3 index neg 0 0 m rl rl rl c} bind def\n\
+%% R X0 Y0 circle\n\
+/circle {tr dup 0 m 0 0 3 -1 roll 0 380 arc} bind def\n\
+%% DrawEllipse pompee sur transfig\n\
+/ellipse {/endangle exch def /startangle exch def /yrad exch def\n\
+/xrad exch def /y exch def /x exch def /savematrix mtrx currentmatrix def\n\
+x y tr xrad yrad sc 0 0 1 startangle endangle arc\n\
+closepath savematrix setmatrix } def\n\
+\
+%% pipsarc Arc \n\
+/pipsarc {/endangle exch def /startangle exch def /yrad exch def\n\
+/xrad exch def /y exch def /x exch def /savematrix mtrx currentmatrix def\n\
+x y tr xrad yrad sc 0 0 1 startangle endangle arc\n\
+savematrix setmatrix } def\n\
+\
+%% pipsfarc Arc plein \n\
+/pipsfarc {/endangle exch def /startangle exch def /yrad exch def\n\
+/xrad exch def /y exch def /x exch def /savematrix mtrx currentmatrix def\n\
+x y tr 0 0 moveto xrad yrad sc 0 0 1 startangle endangle arc 0 0  lineto\n\
+closepath savematrix setmatrix } def\n\
+\
+%% Gestion des images\n\
+%% ColorImage, pompee sur xv (qui les avait pompees sur xgrab)\n\
+/colorimage where   %% do we know about 'colorimage'?\n\
+  { pop }           %% yes: pop off the 'dict' returned\n\
+  {                 %% no:  define one\n\
+    /colortogray {  %% define an RGB->I function\n\
+      /rgbdata exch store    %% call input 'rgbdata'\n\
+      rgbdata length 3 idiv\n\
+      /npixls exch store\n\
+      /rgbindx 0 store\n\
+      0 1 npixls 1 sub {\n\
+        grays exch\n\
+        rgbdata rgbindx       get 20 mul    %% Red\n\
+        rgbdata rgbindx 1 add get 32 mul    %% Green\n\
+        rgbdata rgbindx 2 add get 12 mul    %% Blue\n\
+        add add 64 idiv      %% I = .5G + .31R + .18B\n\
+        put\n\
+        /rgbindx rgbindx 3 add store\n\
+      } for\n\
+      grays 0 npixls getinterval\n\
+    } bind def\n\
+    /mergeprocs { %% def\n\
+      dup length 3 -1 roll dup length dup 5 1 roll 3 -1 roll add\n\
+      array cvx dup 3 -1 roll 0 exch putinterval dup 4 2 roll\n\
+      putinterval } bind def\n\
+    /colorimage {\n\
+      pop pop     %% remove 'false 3' operands\n\
+      {colortogray} mergeprocs image} bind def\n\
+  } ifelse          %% end of 'false' case\n\
+\
+%% GetRGB\n\
+/GetRGB { %% ImageStr --> RGBStr\n\
+  /ImageData exch store\n\
+  %% Pour chaque element de ImageData,\n\
+  %% On va chercher les valeurs RGB correspondantes\n\
+  0 1 Taille 1 sub {\n\
+    /i      exch store  %% On met a jour l'indice de parcours\n\
+    ImageData i get     %% Recupere la Indice e val dans la chaine ImData\n\
+    ColorMap exch get   %% On recupere la valeur RGB Correspondante\n\
+    aload pop           %% On met tout ca dans la pile\n\
+    %% Maintenant, on va mettre tout ca dans la chaine RGBStr\n\
+    RGBStr i 3 mul 2 add 3 -1 roll put\n\
+    RGBStr i 3 mul 1 add 3 -1 roll put\n\
+    RGBStr i 3 mul       3 -1 roll put\n\
+    } for\n\
+  RGBStr 0 Taille 3 mul getinterval %% On renvoie la chaine RGB\n\
+} bind def\n\
+end\n\
+"
+
+
+
+/* 
+ *  Les PIMarkers sont definis et geres commes des fontes
+ *
+ *
+ */
+#define PIMARKERS_PAR  PI_DotMarker, PI_PlusMarker, PI_CrossMarker,\
+  PI_CircleMarker, PI_FCircleMarker, PI_BoxMarker, PI_FBoxMarker,\
+  PI_TriangleMarker, PI_FTriangleMarker, PI_StarMarker, PI_FStarMarker
+
+#define PIMARKERS  "\
+%% Definition de la fonte $PIMarkers\n\
+/$PIMarkers 26 dict def\n\
+$PIMarkers begin\n\
+/FontType 3 def\n\
+/FontMatrix [0.001 0 0 0.001 -0.375 -0.375] def\n\
+/FontBBox   [0 0 1000 1000] def\n\
+/Encoding 256 array def\n\
+0 1 255 {Encoding exch /.notdef put} for\n\
+Encoding  %d /PIDot       put %% PI_DotMarker\n\
+Encoding  %d /PIPlus      put %% PI_PlusMarker\n\
+Encoding  %d /PICross     put %% PI_CrossMarker\n\
+Encoding  %d /PICircle    put %% PI_CircleMarker\n\
+Encoding  %d /PIFCircle   put %% PI_FCircleMarker\n\
+Encoding  %d /PIBox       put %% PI_BoxMarker\n\
+Encoding  %d /PIFBox      put %% PI_FBoxMarker\n\
+Encoding  %d /PITriangle  put %% PI_TriangleMarker\n\
+Encoding  %d /PIFTriangle put %% PI_FTriangleMarker\n\
+Encoding  %d /PIStar      put %% PI_StarMarker\n\
+Encoding  %d /PIFStar     put %% PI_FStarMarker\n\
+/CharProcs 26 dict def\n\
+$PIDict begin\n\
+CharProcs begin\n\
+/.notdef     {} def\n\
+/PIDot       {100 375 375 circle f} bind def\n\
+/PIPlus      {0 375 m 750 375 l 375 0 m 375 750 l s} bind def\n\
+/PICross     {0 0 m 750 750 l 750 0 m 0 750 l s} bind def\n\
+/PICircle    {375 375 375 circle s} bind def\n\
+/PIFCircle   {375 375 375 circle f} bind def\n\
+/PIBox       {0 0 m 750 0 l 750 750 l 0 750 l c s} bind def\n\
+/PIFBox      {0 0 m 750 0 l 750 750 l 0 750 l c f} bind def\n\
+/PITriangle  {0 750 m 375 0 l 750 750 l c s} bind def\n\
+/PIFTriangle {0 750 m 375 0 l 750 750 l c f} bind def\n\
+/PIStar      {731 260 m 459 260 l 375 0 l 291 260 l 19 260 l \
+239 419 l 155 678 l 375 518 l 595 678 l 511 419 l c s} def\n\
+/PIFStar     {731 260 m 459 260 l 375 0 l 291 260 l 19 260 l \
+239 419 l 155 678 l 375 518 l 595 678 l 511 419 l c f} def\n\
+end %%$PIDict\n\
+end %%$CharProcs\n\
+/BuildChar {\n\
+1000 0      %% Largeur \n\
+0 0 750 750 %% Bounding Box\n\
+setcachedevice \n\
+exch begin\n\
+Encoding exch get\n\
+CharProcs exch get\n\
+end 75 slw exec} def\n\
+end\n\
+/PIMarkers $PIMarkers definefont pop\n\
+save\n\
+"
+
+/* Dimensions des divers formats */
+  struct PaperSize {
+      double width ;
+      double height ;
+  };
+struct PaperSize PaperSizeTable[] = {
+    { 0.0,  0.0},    /* PI_NotDefFormat */
+    {21.0, 29.7},    /* PI_A4 */
+    {29.7, 42.0},    /* PI_A3 */
+    {14.8, 21.0}     /* PI_A5 ? */
+} ;
+
+
+double cm2pt(double x);
+
+
+/* Fonction WriteHeader */
+#define END_PROLOG_PAR  PAGE_WIDTH, PAGE_HEIGHT
+#define END_PROLOG  "/NewFile { %%%% w h NewFile (--> h et w en cm <--)\n\
+$PIDict begin /PIMarkers ff 14 scf sf /h exch def /w exch def \n\
+/$PIEnteredState save def} bind def\n\
+/EndFile {$PIEnteredState restore end} bind def\n\
+%%%%EndProlog\n\n\
+"
+
+#define HEADER     "\
+%%%%Title: %s\n\
+%%%%Creator: PI-PSFile (N.R. 07/08/99)\n\
+%%%%CreationDate: %s\
+%%%%Pages: (atend)\n\
+%%%%EndComments\n\n\
+"
+
+//++
+// Titre	Constructeurs
+//--
+//++
+// PSFile (const char * FileName, double sc = 1.0)
+//	Créateur pour fichier Encapsulated Postscript
+// PSFile (const char * FileName, PIOrientation orientation, -
+//         PIPaperSize paperSize= PI_A4, -
+//         double marginX = 5.0, double marginY = 5.0 )
+//	Créateur pour fichier Postscript
+//--
+
+/* 
+   Utilisation de la resolution coordonnees utilisateur (resolution ecran)
+   pour definir correctement la taille des fontes 
+                                      R. Ansari - Juillet 2001
+*/
+/* Definition de la resolution coordonnees user par defaut (point/cm ou pixels/cm) */ 
+
+float PSFile::postscript_resolution = 28.;  /* environ 72 points / pouce  */
+float PSFile::def_user_resol_X = 30.;      /* environ 75 points / pouce  */
+float PSFile::def_user_resol_Y = 30.;
+float PSFile::def_user_resolution = 30.;
+
+void PSFile::SetUserCoordResolution(float resx, float resy)
+{
+  if ((resx < 1.) || (resy < 1.)) return;
+  def_user_resol_X = resx;
+  def_user_resol_Y = resy;
+  def_user_resolution = 0.5*(resx+resy);
+}
+float PSFile::GetUserCoordResolution(float& resx, float& resy)
+{
+  resx = def_user_resol_X;
+  resy = def_user_resol_Y;
+  return (def_user_resolution);
+}
+float PSFile::PSCoordResolution()
+{
+  return (postscript_resolution);
+}
+
+/* 
+ *   PostScript encapsule...
+ * 
+ *   Attention la bounding Box ne sera specifiee 
+ *     qu'au premier NewPage() --> definie dans 
+ *     le champ "Trailer" 
+ *
+ */
+PSFile::PSFile(const char * FileName, double sc) 
+    : mPSFileName(FileName==NULL? "unnamed.eps" : const_cast<char *>(FileName)),
+      Tw (-1.), Th(-1.),         /* Non specifies pour du eps  */
+      WMargin (-1), HMargin(-1), /* Non specifiees en eps  */ 
+      isEPS(1),
+      scale(sc),                 /* Defaut : 1. */
+      mPaperSize(PI_NotDefPaperSize), /* Non specifiee en eps */
+      PageCounter(0),            /* Fichier vide */
+      FileEmpty(1),              /* Fichier vide */
+      currentPage(NULL),
+      currentBloc(NULL),
+      mDrawColor(PI_Black),
+      mFillColor(PI_Black),
+      mFontAtt(PI_RomanFont),
+      mFontSize(0),
+      mFontName(PI_DefaultFont), 
+      mLineAtt(PI_NormalLine),
+      mMarker(PI_DotMarker),
+      setFontDone(true)
+{
+    char*  date = new (char[64] ) ; 
+    time_t timer ; 
+
+    /* Ouverture du fichier en mode w+ */
+    if ( (mPSFile = fopen(FileName, "w+")) == NULL){
+	  perror (FileName);
+	  return;
+    }
+
+    /* Ecriture du Header  */
+    fprintf(mPSFile, "%%!PS-Adobe-2.0 EPSF-2.0\n");
+    fprintf(mPSFile, "%%%%BoundingBox: ");
+    /* 
+     * Les dimensions de la BB seront notees ici lors du 
+     * premier appel a NewPage
+     *
+     * C'est laid... si qqn a une meilleure idee...
+     */
+    boundingBox = ftell(mPSFile) ; 
+    fprintf(mPSFile, "                       \n");
+
+    time(&timer) ; 
+    date = ctime(&timer) ; 
+    fprintf(mPSFile, HEADER, mPSFileName, date) ; /* titre, date etc... */
+    fprintf(mPSFile, PIDICT, PIDICT_PAR) ;        /* Dictionnaire */
+    fprintf(mPSFile, PIMARKERS, PIMARKERS_PAR) ;  /* Fonte "PIMARKERS" */
+    //    fprintf(mPSFile, END_PROLOG) ;
+    /* Aucun format n'est specifie ici ... */
+    fprintf(mPSFile, "$PIDict begin /PIMarkers ff 14 scf sf\n") ;
+    fprintf(mPSFile, "/FState save def\n%%%%EndProlog\n\n") ;
+}
+
+
+
+/*
+ *  PostScript simple...
+ *
+ *
+ */
+PSFile::PSFile(const char *FileName,
+	       PIOrientation orientation,
+	       PIPaperSize   paperSize,
+	       double marginX, double marginY)
+ :  mPSFileName (FileName == NULL ? "unnamed.ps" : const_cast<char *>(FileName)),
+    Tw(PaperSizeTable[paperSize].width),  /* Format papier utilise */
+    Th(PaperSizeTable[paperSize].height), /*                       */
+    WMargin(marginX),
+    HMargin(marginY),
+    isEPS(0),
+    scale(0.),
+    PageCounter(0),  /* Fichier vide */
+    FileEmpty(1),    /*              */
+    currentPage(NULL),
+    currentBloc(NULL),
+    mDrawColor(PI_Black),
+    mFillColor(PI_Black),
+    mFontAtt(PI_RomanFont),
+    mFontSize(0),
+    mFontName(PI_DefaultFont),
+    mLineAtt(PI_NormalLine),
+    mMarker(PI_DotMarker), 
+    setFontDone(true)
+{
+    char * date = new(char[64]) ; 
+    time_t timer ; 
+
+    /* Ouverture du fichier, en mode w+ (tout est ecrase) */
+    if ( (mPSFile = fopen(FileName, "w+")) == NULL){
+	  perror (FileName);
+	  return;
+    }
+
+    /* Format et orientation */
+
+    /* Ecriture du Header  */
+    fprintf(mPSFile, "%%!PS-Adobe-2.0\n") ;
+    time(&timer) ; 
+    date = ctime(&timer) ; 
+    fprintf(mPSFile, HEADER, mPSFileName, date) ; /* titre, date etc... */
+    fprintf(mPSFile, PIDICT, PIDICT_PAR) ;        /* Dictionnaire */
+    fprintf(mPSFile, PIMARKERS, PIMARKERS_PAR) ;  /* Fonte "PIMARKERS" */
+    fprintf(mPSFile, "$PIDict begin /PIMarkers ff 14 scf sf\n") ;
+    fprintf(mPSFile, "/FState save def\n%%%%EndProlog\n\n") ;
+}
+
+
+/* 
+ * Destructeur
+ *
+ */
+PSFile::~PSFile () {
+
+    /* On ferme tout ce qui ne l'est pas */
+    if (currentBloc) PSFile::EndBloc();
+    if (currentPage) PSFile::EndPage();
+
+    /* Si le fichier est vide, on le detruit */
+    if (FileEmpty) remove(mPSFileName);
+
+    /* On ecrit le "Trailer" et on ferme */
+    else {
+	/* On restore l'etat initial */
+	fprintf(mPSFile,"FState restore\n") ;
+	fprintf(mPSFile, "%%%%Trailer\n%%%%Pages: %d\n%%%%EOF\n", 
+		PageCounter) ;
+	fclose (mPSFile);
+    }
+}
+
+
+int   PSFile::IsEPS(){
+
+    return(isEPS);
+}
+
+
+const char* PSFile::GetFileName() {
+
+    return(mPSFileName);
+}
+
+PIColors PSFile::GetDrawColor() {
+
+    return(mDrawColor);
+}
+
+PIColors PSFile::GetFillColor() {
+
+    return(mFillColor);
+}
+
+PIFontAtt PSFile::GetFontAtt() {
+
+    return(mFontAtt);
+}
+
+// N.R. 07/08/99 return val PIFontSize --> int 
+int PSFile::GetFontSize() {
+
+    return(mFontSize);
+}
+
+PILineAtt PSFile::GetLineAtt() {
+
+    return(mLineAtt);
+}
+
+PIMarker PSFile::GetMarker() {
+
+    return(mMarker);
+}
+
+//++
+// NewPage(double Dx, double Dy, PIOrientation orientation) 
+//	Debut de nouvelle page, (Dx,Dy) indique l'extension
+//	(taille) du systeme de coordonnees utilisees pour la page
+// EndPage()
+//	Fin de page
+//--
+
+void  PSFile::NewPage(double Dx, double Dy, PIOrientation orientation) {
+
+double  tw, th; /* largeur & hauteur corrigees des marges */
+
+    /* On ferme ce qui doit l'etre ... */
+    if (currentPage) PSFile::EndPage();
+
+    currentPage = new (Page) ; 
+
+    /* Initialisations */
+    currentPage->num = ++PageCounter;
+    currentPage->BlocCounter = 0;
+    currentPage->Dx = Dx;
+    currentPage->Dy = Dy;
+    currentPage->orientation = orientation ;
+
+    /* Position du debut AVANT D'ECRIRE! */
+    currentPage->begin  = ftell(mPSFile);
+
+    /* On ecrit dans le fichier */
+    fprintf(mPSFile, "%%%%Page: %d %d\n", PageCounter, PageCounter) ;
+    fprintf(mPSFile, "/PState save def 1 -1 scale\n");
+
+    /* 
+     *  Si eps : Portrait || Auto == on laisse tel que
+     *           Landscape == on tourne de -90 degres
+     */
+    if(isEPS) {
+	if( (orientation == PI_Portrait) || (orientation == PI_Auto) )
+	    fprintf(mPSFile,
+		    "%.2f %.2f %.2f %.2f %.2f %.2f newref\n",
+		    Dx, Dy, Dx*scale, Dy*scale, 0., -Dy*scale);
+	else
+	    if(orientation==PI_Landscape)
+		fprintf(mPSFile, 
+			"-90 rotate %.2f %.2f %.2f %.2f %.2f %.2f newref\n",
+			Dx, Dy, Dx*scale, Dy*scale, 0., 0.);
+	    else
+		fprintf(stderr, "Orientation Error ; Page : %d\n",
+			currentPage->num) ; 
+    /* 
+     * On specifie la bb 
+     * (Si non encore fait par un appel precedent a NewPage() ) 
+     */
+	if(boundingBox) {
+	    currentPage->tmp = ftell(mPSFile) ;
+	    fseek(mPSFile,boundingBox,SEEK_SET) ;
+	    if( (orientation == PI_Portrait) || (orientation == PI_Auto) )
+		fprintf(mPSFile, "%d %d %d %d", 0, 0, 
+			(int)(Dx*scale), (int)(Dy*scale) ) ; 
+	    else
+		fprintf(mPSFile, "%d %d %d %d", 0, 0, 
+			(int)(Dy*scale), (int)(Dx*scale) ) ;
+	    fseek(mPSFile,currentPage->tmp,SEEK_SET) ;
+	    boundingBox = 0 ; 
+	} /* BB */
+	/* facteur d'echelle pour les fontes*/
+	currentPage->FontScaleFactor = scale; 
+	//	  postscript_resolution/def_user_resolution*scale;
+	/*
+	cout << " EPS_DBG_FontScaleFactor = " << currentPage->FontScaleFactor
+	     << " scale= " << scale << " postscript_resolution= " 
+	     << postscript_resolution << " def_user_resolution= " 
+	     << def_user_resolution << endl;
+	*/
+    } /* EPS */
+    /*
+     * Si ps : 
+     *   - soustraction marges --> rectangle utile.
+     *   - Si PI_Auto : On fait au mieux pour minimiser le 
+     *      redimensionnement...
+     *   - Si PI_Portrait, on ne fait rien, sauf 
+     *      peut-etre un redimensionnement pour rentrer dans les marges
+     *   - Si PI_Landscape, on tourne de -90 degres.
+     */
+    else {
+        // Si marges <= 0 on les met a 2cm
+        if(WMargin<=0) WMargin = 2. ; 
+        if(HMargin<=0) HMargin = 2. ; 
+	/* Eviter image reduite a un point...ou moins... */
+	if((tw = Tw - 2*WMargin) < (Tw/10)) {
+	    WMargin = (0.45)*Tw ;
+	    tw = Tw/10;
+	}
+	if((th = Th - 2*HMargin)< (Th/10)) {
+	    HMargin = (0.45)*Th ;
+	    th = Th/10;
+	}
+	/* Portrait ou Landscape ? */
+	if(orientation == PI_Auto) 
+	    if( ((tw < th) && (Dx < 1.2*Dy)) ||
+		((tw > th) && (Dx > Dy) )) 
+		currentPage->orientation = PI_Portrait ;
+	    else 
+		currentPage->orientation = PI_Landscape ;
+
+	if(currentPage->orientation == PI_Portrait) {
+	  //	    if( (tw/Dx) < (th/Dy) ) 
+	  //		scale = tw/Dx ;
+	  //                scale = tw/Tw ; 
+	  //	    else 
+	  //		scale = th/Dy;
+	  //                scale = th/Th;
+	  //	    fprintf(mPSFile, 
+	  //		    "%.2f %.2f %.2f cm %.2f cm %.2f cm %.2f cm newref\n",
+	  //		    Dx, Dy, 
+	  //		    Dx*scale, Dy*scale, 
+	  //		    Tw*scale, Th*scale, 
+	  //		    0.5*(Tw-tw), -0.5*(Th+th)) ;
+            scale = (tw/Dx)<(th/Dy) ? tw/Dx : th/Dy ; 
+            tw = scale*Dx ; th = scale*Dy ; 
+	    fprintf(mPSFile, 
+		    "%.2f %.2f %.2f cm %.2f cm %.2f cm %.2f cm newref\n",
+		    Dx, Dy, 
+		    tw, th, 
+		    0.5*(Tw-tw), -0.5*(Th+th)) ;
+	}  /* End if .Portrait  */
+	if(currentPage->orientation == PI_Landscape) {
+	    /* Idem avec X<->Y */
+//	    if( (th/Dx) < (th/Dy) ) 
+//		scale = th/Dx;
+//                scale = th/Tw;
+//	    else
+//		scale = tw/Dy ;
+//                scale = tw/Th;
+//	    fprintf(mPSFile,
+//	       "-90 rotate %.2f %.2f %.2f cm %.2f cm %.2f cm %.2f cm newref\n",
+//	       Dx, Dy,
+//	       Dx*scale, Dy*scale, 
+//	       Th*scale, Tw*scale, 
+//	       0.5*(Th-th), 0.5*(Tw-tw));
+
+            scale = (th/Dx)<(tw/Dy) ? th/Dx : tw/Dy ; 
+            th = scale*Dx ; tw = scale*Dy ; 
+	    fprintf(mPSFile,
+	       "-90 rotate %.2f %.2f %.2f cm %.2f cm %.2f cm %.2f cm newref\n",
+	       Dx, Dy,
+	       th, tw,
+	       0.5*(Th-th), 0.5*(Tw-tw));
+	} /* End if .Landscape */
+	/* facteur d'echelle pour les fontes*/
+	currentPage->FontScaleFactor = scale*postscript_resolution;
+	/*
+	cout << " PS_DBG_FontScaleFactor = " << currentPage->FontScaleFactor
+	     << " scale= " << scale << " postscript_resolution= " 
+	     << postscript_resolution << " def_user_resolution= " 
+	     << def_user_resolution << endl;
+	*/
+    } /* End if .ps */
+// On redefint la fonte par defaut - $CHECK$ Reza 11/12/99
+mFontAtt = PI_RomanFont;
+mFontSize = 10;
+mFontName = PI_DefaultFont;
+double scaledFontSize = (double)mFontSize*currentPage->FontScaleFactor;
+fprintf(mPSFile, "/Courier ff %g FS /curfntsz %g def \n", scaledFontSize, scaledFontSize) ; 
+setFontDone = true;
+currentPage->tmp = ftell(mPSFile);
+}
+
+
+
+void  PSFile::EndPage() {
+
+    /* Si rien a fermer, on s'en va */
+    if ( ! currentPage ) return;
+
+    /* Si un bloc non ferme, on appelle EndBloc */
+    if ( currentBloc ) PSFile::EndBloc();
+    
+    /* Si la page est vide, on la detruit */
+    if (currentPage->tmp == ftell(mPSFile)) {
+	fseek(mPSFile, currentPage->begin, SEEK_SET);
+	delete(currentPage) ;
+	PageCounter--;
+    }
+    /* Sinon, fin page + empilage */
+    else {
+	//	it = mPageList.end(); it--;
+	fprintf(mPSFile,"PState restore  showpage\n");
+	fprintf(mPSFile,"%%>EndPage %d\n\n\n", currentPage->num);
+	currentPage->end = ftell(mPSFile);
+	mPageList.push_back(*currentPage); /* Pourquoi PageList ? */
+	FileEmpty = 0;
+    }
+    currentPage = NULL;
+}
+
+
+//++
+// NewBloc(double x0, double y0, double Tx, double Ty, double Dx, double Dy)
+//	Debut de bloc.
+//|	x0,y0 : position du bloc ds la page
+//|	Tx,Ty : Taille du bloc dans la page
+//|	Dx,Dy : Extension (taille) du systeme de coordonnees utilisateur
+//|	dans le bloc
+//
+// EndBloc()
+//	Fin de bloc
+//--
+
+
+void  PSFile::NewBloc(double x0, double y0, double Tx, double Ty,
+			      double Dx, double Dy){
+
+    /* Si pas de page, on s'en va */
+    if ( ! currentPage ) return;
+
+    /* On ferme le bloc precedent (Pas de Bloc-gigognes ! ) */
+    if (currentBloc) PSFile::EndBloc();
+
+    currentBloc = new (Bloc) ; 
+    /* On remplit currentBloc */
+    currentBloc->num = ++(currentPage->BlocCounter);
+    currentBloc->X0 = x0;
+    currentBloc->Y0 = y0;
+    currentBloc->Tx = Tx;
+    currentBloc->Ty = Ty;
+    currentBloc->Dx = Dx;
+    currentBloc->Dy = Dy;
+    currentBloc->begin = ftell(mPSFile);
+
+    /* On met a jour le fichier */
+    fprintf(mPSFile, "%%>BeginBloc %d\n", currentBloc->num);
+    fprintf(mPSFile, "%.2f %.2f %.2f Ux %.2f Uy %.2f Ux %.2f Uy NewBloc\n",
+	    currentBloc->Dx, currentBloc->Dy,
+	    currentBloc->Tx, currentBloc->Ty,
+	    currentBloc->X0, currentBloc->Y0);
+    // On redefinit la zone de clip
+    fprintf(mPSFile, "%% Define clip region to the entire bloc area \n");
+    fprintf(mPSFile, "initclip newpath 0 0 m %.2f Ux 0 rl 0 %.2f Uy rl %2f Ux 0 rl closepath clip \n",
+	    currentBloc->Dx, currentBloc->Dy, -currentBloc->Dx); 
+    // On redefint la fonte par defaut - $CHECK$ Reza 11/12/99
+    mFontAtt = PI_RomanFont;
+    mFontSize = 10;
+    mFontName = PI_DefaultFont;
+    double scaledFontSize = (double)mFontSize*currentPage->FontScaleFactor;
+    fprintf(mPSFile, "/Courier ff %g FS /curfntsz %g def \n", 
+	    scaledFontSize, scaledFontSize) ;
+    mLineAtt = PI_NotDefLineAtt;
+    SelectLine(PILineAtt(PI_NormalLine));
+    setFontDone = true;
+    currentBloc->tmp = ftell(mPSFile) ;
+}
+
+
+void  PSFile::EndBloc() {
+
+    /* On verifie qu'un bloc ouvert existe bien */
+    if ( ! currentBloc ) return;
+
+    /* Si le bloc est vide, on le detruit */
+    if (currentBloc->tmp == ftell(mPSFile)) {
+	fseek(mPSFile, currentBloc->begin, SEEK_SET) ; 
+	currentPage->BlocCounter-- ; 
+    }
+    /* Sinon, Ok met a jour le fichier */
+    else { 
+	fprintf(mPSFile, "EndBloc\n"); 
+	fprintf(mPSFile, "%%>EndBloc %d\n", currentBloc->num); 
+	currentBloc->end = ftell(mPSFile) ; 
+	currentPage->mBlocList.push_back(*currentBloc) ; 
+	//	PageEmpty = 0; 
+    } 
+    /* Flags */
+    currentBloc = NULL ; 
+}
+
+
+void PSFile::SetClipRectangle(double x0, double y0, double dx, double dy)
+{
+  // On redefinit la zone de clip
+  fprintf(mPSFile, "%% SetClipRectangle: Define clip region \n ");
+  fprintf(mPSFile, "newpath %.2f Ux %.2f Uy m %.2f Ux 0 rl 0 %.2f Uy rl %.2f Ux 0 rl closepath clip \n",
+	  x0, y0, dx, dy, -dx); 
+}
+
+void PSFile::ClearClipRectangle()
+{
+  // On redefinit la zone de clip a l'ensemble du bloc
+  fprintf(mPSFile, "%% Define clip region to the entire bloc area \n");
+  fprintf(mPSFile, "initclip newpath 0 0 m %.2f Ux 0 rl 0 %.2f Uy rl %2f Ux 0 rl closepath clip \n",
+	  currentBloc->Dx, currentBloc->Dy, -currentBloc->Dx); 
+}
+
+void PSFile::SelForeground(PIColorMap& cmap, int cid)
+{
+  mDrawColor = PI_ColorFromMap ; 
+  PIColor tmp = cmap.GetColor(cid) ; 
+  fprintf(mPSFile, "/ur %.3f def /ug %.3f def /ub %.3f def \n", 
+          (double)(tmp.red)/65535., 
+          (double)(tmp.green)/65535., 
+          (double)(tmp.blue)/65535.) ; 
+}
+
+
+void PSFile::SelBackground(PIColorMap& cmap, int cid)
+{
+  mDrawColor = PI_ColorFromMap ; 
+}
+
+
+void  PSFile::DrawString  (double x,  double y, const char *s, 
+			   PIColors DrawColor, 
+			   PIFontName FontName, 
+			   PIFontAtt FontAtt, 
+			   int FontSize, 
+			   unsigned long pos) {
+    bool change = false;
+
+    /* Couleurs */
+    if ( (DrawColor != PI_NotDefColor) && (DrawColor != mDrawColor) ) {
+	mDrawColor = DrawColor;
+	fprintf(mPSFile, "C%d ", mDrawColor) ; 
+    }
+    /* Choix des fontes */
+    if ( (FontAtt != PI_NotDefFontAtt) && (FontAtt != mFontAtt) ) {
+//DBG      printf("PSFile::DrawString(%s) : FontAtt a change : %d %d \n", s, mFontAtt, FontAtt) ; 
+      mFontAtt = FontAtt;
+      change = true;
+    }
+    if ( (FontSize != PI_NotDefFontSize) && (FontSize != mFontSize) ) {
+//DBG      printf("PSFile::DrawString(%s) : FontSize a change : %d %d \n", s, mFontSize, FontSize) ; 
+      mFontSize = FontSize;  
+      change = true;
+    }
+    if( (FontName != mFontName) ) {
+//DBG      printf("PSFile::DrawString(%s) : FontName a change : %d %d \n", s, mFontName, FontName) ; 
+      mFontName = (PIFontName) FontName ; 
+      change = true ; 
+    }
+
+    if (change || !setFontDone) { // $CHECK$ setFontDone Reza 11/12/99 
+      string fname ; 
+      switch(mFontName) {
+      case PI_DefaultFont:
+      case PI_CourierFont:
+	fprintf(mPSFile, "/Courier") ; 
+	break ; 
+      case PI_HelveticaFont:
+	fprintf(mPSFile, "/Helvetica") ; 
+	break ; 
+      case PI_TimesFont:
+	fprintf(mPSFile, "/Times") ; 
+	break ; 
+      case PI_SymbolFont:
+	fprintf(mPSFile, "/Symbol ") ; 
+	break ; 
+      } // endsw 
+      
+      switch(mFontAtt) {
+      case PI_NotDefFontAtt:
+      case PI_RomanFont:
+	fprintf(mPSFile, " ") ; 
+	break ; 
+      case PI_BoldFont:
+	if(mFontName != PI_SymbolFont) fprintf(mPSFile, "-Bold ") ; 
+	break ; 
+      case PI_ItalicFont:
+	if ((mFontName == PI_DefaultFont) || (mFontName == PI_CourierFont) ||
+	    (mFontName == PI_HelveticaFont) ) fprintf(mPSFile, "-Oblique ") ;
+	else if (mFontName == PI_TimesFont) fprintf(mPSFile, "-Italic ") ; 
+	break ; 
+      case PI_BoldItalicFont:
+	if ((mFontName == PI_DefaultFont) || (mFontName == PI_CourierFont) ||
+	    (mFontName == PI_HelveticaFont) ) fprintf(mPSFile, "-BoldOblique ") ;
+	else if (mFontName == PI_TimesFont) fprintf(mPSFile, "-BoldItalic ") ; 
+	break ; 	
+      } // endsw 
+      double scaledFontSize = (double)FontSize*currentPage->FontScaleFactor;
+      fprintf(mPSFile, " ff %g FS /curfntsz %g def \n", scaledFontSize, scaledFontSize);
+      setFontDone = true ;   // $CHECK$ - doit etre fait uniquement a ce moment
+    }
+    if (pos == 0) 
+      fprintf(mPSFile, "gs %.2f Ux %.2f Uy m (%s) S gr\n", x, y, s) ; 
+    else {
+      unsigned long txtdir = pos & PI_TextDirection;
+      int posh = pos & PI_HorizontalPosition;
+      int posv = pos & PI_VerticalPosition;
+      int angle = 0;
+      if (txtdir == PI_TextDirectionVerticalUp) angle = -90;
+      else if (txtdir == PI_TextDirectionVerticalDown) angle = 90;
+
+      if ((posh == PI_HorizontalLeft)  && 
+	  ((posv == PI_VerticalBaseLine) || (posv == 0)) ) {
+	if (angle == 0) 
+	  fprintf(mPSFile, "gs %.2f Ux %.2f Uy m (%s) hlshstr gr\n", 
+		  x, y, s) ;
+	else 
+	  fprintf(mPSFile, "gs %.2f Ux %.2f Uy m %d rotate (%s) hlshstr gr\n", 
+		  x, y, angle, s) ;
+      }
+      else {
+	char ssvp = 'b';
+	char sshp = 'l';
+	if (posh != PI_HorizontalLeft) {
+	  if (posh == PI_HorizontalCenter)  sshp = 'c';
+	  else if (posh == PI_HorizontalRight)  sshp = 'r';
+	  else sshp = 'l';
+	}
+	if (posv == 0) {
+	  if (angle == 0) 
+	    fprintf(mPSFile, "gs %.2f Ux %.2f Uy m (%s) h%cshstr gr\n", 
+		    x, y, s, sshp) ;
+	  else fprintf(mPSFile, "gs %.2f Ux %.2f Uy m %d rotate (%s) h%cshstr gr\n", 
+		       x, y, angle, s, sshp) ;
+	}
+	else {
+	  if (posv == PI_VerticalCenter)  ssvp = 'c';
+	  else if (posv == PI_VerticalTop)  ssvp = 't';
+	  else ssvp = 'b';
+	}
+	if (angle == 0) 
+	  fprintf(mPSFile, "gs %.2f Ux %.2f Uy m (%s) h%cv%cshstr gr\n", 
+		  x, y, s, sshp, ssvp) ; 
+	else 
+	  fprintf(mPSFile, "gs %.2f Ux %.2f Uy m %d rotate (%s) h%cv%cshstr gr\n", 
+		  x, y, angle, s, sshp, ssvp) ; 
+      }
+    }
+
+}
+
+
+void  PSFile::DrawLine    (double x1, double y1, double x2, double y2, 
+			   PIColors DrawColor,
+			   PILineAtt LineAtt) {
+
+
+    /* Line Att */  
+    if ( (LineAtt != PI_NotDefLineAtt) && (LineAtt != mLineAtt) ) 
+      SelectLine(LineAtt);
+
+    /* Couleurs */
+    if ( (DrawColor != PI_NotDefColor) || (DrawColor != mDrawColor) ) {
+	mDrawColor = DrawColor;
+	fprintf(mPSFile, "C%d ", mDrawColor);
+    }
+
+    /* Dessin */
+    fprintf(mPSFile, "n %.2f Ux %.2f Uy m %.2f Ux %.2f Uy l s\n",
+	    x1, y1, x2, y2) ;
+}
+
+
+
+void  PSFile::DrawBox(double x0, double y0, double Tx, double Ty, 
+		      PIColors  DrawColor,
+		      PILineAtt LineAtt) {
+
+    /* Line Att */  
+    if ( (LineAtt != PI_NotDefLineAtt) && (LineAtt != mLineAtt) ) 
+      SelectLine(LineAtt);
+
+    /* Changement couleurs ? */
+    if ( (DrawColor != PI_NotDefColor) || (DrawColor != mDrawColor) ) {
+	mDrawColor = DrawColor;
+	fprintf(mPSFile, "C%d ", mDrawColor) ; 
+    }
+
+
+    /* On dessine */
+    fprintf(mPSFile, "gs n %.2f Ux %.2f Uy %.2f Ux %.2f Uy box s gr\n",
+	    Tx, Ty, x0, y0) ; 
+}
+
+
+void  PSFile::DrawFBox(double x0, double y0, double Tx, double Ty, 
+		   PIColors DrawColor,
+		   PIColors FillColor, 
+		   PILineAtt LineAtt) {
+
+    /* Line Att */  
+    if ( (LineAtt != PI_NotDefLineAtt) && (LineAtt != mLineAtt) ) 
+      SelectLine(LineAtt);
+
+    /* Dessin du fond */
+    if ( (FillColor != PI_NotDefColor) || (FillColor != mDrawColor) ) {
+      mDrawColor = FillColor;
+      fprintf(mPSFile, "C%d ", mDrawColor) ;
+    } 
+    fprintf(mPSFile, "gs n %.2f Ux %.2f Uy %.2f Ux %.2f Uy box f gr\n",
+	    Tx, Ty, x0, y0) ; 
+
+    /* Dessin du contour (s'il y a lieu) */
+    if ( (DrawColor != PI_NotDefColor) && (FillColor != DrawColor) ) {
+	mDrawColor = DrawColor;
+	fprintf(mPSFile, "C%d ", mDrawColor) ; 
+	fprintf(mPSFile, "gs n %.2f Ux %.2f Uy %.2f Ux %.2f Uy box s gr\n",
+		Tx, Ty, x0, y0) ;
+    }
+}
+
+
+void  PSFile::DrawCircle  (double x0, double y0, double r, 
+			   PIColors DrawColor,
+			   PILineAtt LineAtt) {
+
+    /* Line Att */  
+    if ( (LineAtt != PI_NotDefLineAtt) && (LineAtt != mLineAtt) ) 
+      SelectLine(LineAtt);
+
+    /* Couleurs */
+    if ( (DrawColor != PI_NotDefColor) || (DrawColor != mDrawColor) ) {
+	mDrawColor = DrawColor;
+	fprintf(mPSFile, "C%d ", mDrawColor); 
+    }
+
+
+    /* Dessin */
+    fprintf(mPSFile, "gs n %.2f Ux %.2f Uy %.2f Ux %.2f Uy 0 360 ellipse s gr\n",
+	    x0, y0, r, r) ;
+}
+
+
+void  PSFile::DrawFCircle (double x0, double y0, double r,
+		   PIColors DrawColor,
+		   PIColors FillColor, 
+		   PILineAtt LineAtt) {
+
+    /* Line Att */  
+    if ( (LineAtt != PI_NotDefLineAtt) && (LineAtt != mLineAtt) ) 
+      SelectLine(LineAtt);
+
+    /* Dessin du fond */
+    if ( (FillColor != PI_NotDefColor) || (FillColor != mDrawColor) ){
+	mDrawColor = FillColor;
+	fprintf(mPSFile, "C%d ", mDrawColor) ;
+    }
+    fprintf(mPSFile, "gs n %.2f Ux %.2f Uy %.2f Ux %.2f Uy \
+                      0 360 ellipse f gr\n",
+	    x0, y0, r, r);
+
+    /* Dessin du contour (s'il y a lieu) */
+    if ( (DrawColor != PI_NotDefColor) && (FillColor != DrawColor) ) {
+	mDrawColor = DrawColor;
+	fprintf(mPSFile, "C%d ", mDrawColor); 
+	fprintf(mPSFile, "gs n %.2f Ux %.2f Uy %.2f Ux %.2f Uy 0 360 ellipse s gr\n",
+		x0, y0, r, r) ;
+    }
+}
+
+void  PSFile::DrawArc (double x0, double y0, double dx, double dy,
+		       double degdeb, double deltadeg,
+		       PIColors DrawColor,
+		       PILineAtt LineAtt) {
+
+    /* Line Att */  
+    if ( (LineAtt != PI_NotDefLineAtt) && (LineAtt != mLineAtt) ) 
+      SelectLine(LineAtt);
+
+    /* Couleurs */
+    if ( (DrawColor != PI_NotDefColor) || (DrawColor != mDrawColor) ) {
+	mDrawColor = DrawColor;
+	fprintf(mPSFile, "C%d ", mDrawColor); 
+    }
+    
+    double degfin = degdeb+deltadeg;
+    while (degfin > 360.) degfin -= 360.;
+    while (degfin < 0.)   degfin += 360.;
+    /* Dessin */
+    fprintf(mPSFile, "gs n %.2f Ux %.2f Uy %.2f Ux %.2f Uy %.2f %.2f pipsarc s gr\n",
+	    x0, y0, dx, dy, degdeb, degfin) ;
+}
+
+
+void  PSFile::DrawFArc (double x0, double y0, double dx, double dy,
+			double degdeb, double deltadeg,
+			PIColors DrawColor,
+			PIColors FillColor, 
+			PILineAtt LineAtt) {
+
+    /* Line Att */  
+    if ( (LineAtt != PI_NotDefLineAtt) && (LineAtt != mLineAtt) ) 
+      SelectLine(LineAtt);
+
+    double degfin = degdeb+deltadeg;
+    while (degfin > 360.) degfin -= 360.;
+    while (degfin < 0.)   degfin += 360.;
+    /* Dessin du fond */
+    if ( (FillColor != PI_NotDefColor) || (FillColor != mDrawColor) ){
+	mDrawColor = FillColor;
+	fprintf(mPSFile, "C%d ", mDrawColor) ;
+    }
+    fprintf(mPSFile, "gs n %.2f Ux %.2f Uy %.2f Ux %.2f Uy %.2f %.2f pipsfarc f gr\n",
+	    x0, y0, dx, dy, degdeb, degfin);
+
+    /* Dessin du contour (s'il y a lieu) */
+    if ( (DrawColor != PI_NotDefColor) && (FillColor != DrawColor) ) {
+	mDrawColor = DrawColor;
+	fprintf(mPSFile, "C%d ", mDrawColor); 
+	fprintf(mPSFile, "gs n %.2f Ux %.2f Uy %.2f Ux %.2f Uy %.2f %.2f pipsfarc s gr\n",
+		x0, y0, dx, dy, degdeb, degfin) ;
+    }
+}
+
+
+// Les coordonnees sont supposees etre en mode incremental .
+void  PSFile::DrawPolygon (double *x, double *y, int n,
+		   PIColors DrawColor, 
+		   PILineAtt LineAtt, bool cinc) {
+
+    /* Line Att */  
+    if ( (LineAtt != PI_NotDefLineAtt) && (LineAtt != mLineAtt) ) 
+      SelectLine(LineAtt);
+
+    /* Couleur */
+    if ( (DrawColor != PI_NotDefColor) || (DrawColor != mDrawColor) ) {
+	mDrawColor = DrawColor;
+	fprintf(mPSFile, "C%d ", mDrawColor) ;
+    }
+    
+    /* On dessine ; ici*/
+    fprintf(mPSFile, "%.2f Ux %.2f Uy m\n", x[0], y[0]);
+
+    const char* cmd ; 
+    if(cinc == true) cmd = "%.2f Ux %.2f Uy rl\n" ; 
+    else             cmd = "%.2f Ux %.2f Uy l\n" ; 
+
+    for(int i = 1; i<n; i++) 
+      fprintf(mPSFile, cmd, x[i], y[i]);
+    fprintf(mPSFile, " s\n");   // On ne ferme pas le path - Reza 02/2002 - fprintf(mPSFile, "c s\n");
+}
+
+
+void  PSFile::DrawFPolygon(double *x, double *y, int n,
+		   PIColors DrawColor,
+		   PIColors FillColor,
+		   PILineAtt LineAtt, bool cinc) {
+
+    /* Line Att */  
+    if ( (LineAtt != PI_NotDefLineAtt) && (LineAtt != mLineAtt) ) 
+      SelectLine(LineAtt);
+
+    const char* cmd ; 
+    if(cinc == true) cmd = "%.2f Ux %.2f Uy rl\n" ; 
+    else             cmd = "%.2f Ux %.2f Uy l\n" ; 
+
+    /* Dessin du fond... */
+    if ( (FillColor != PI_NotDefColor) || (FillColor != mDrawColor) ) {
+	mDrawColor = FillColor;
+	fprintf(mPSFile, "C%d ", mDrawColor) ;
+    }
+    fprintf(mPSFile, "%.2f Ux %.2f Uy m\n", x[0], y[0]);
+    int i;
+    for(i = 1; i<n; i++) 
+	fprintf(mPSFile, cmd, x[i], y[i]);
+    fprintf(mPSFile, "c f\n");
+
+    /* ...puis du contour (s'il y a lieu) */
+    if ( (DrawColor != PI_NotDefColor) && (DrawColor != FillColor) ) {
+      mDrawColor = DrawColor;
+      fprintf(mPSFile, "C%d ", mDrawColor) ;
+      fprintf(mPSFile, "%.2f Ux %.2f Uy m\n", x[0], y[0]);
+      for(i = 1; i<n; i++) 
+	fprintf(mPSFile, cmd, x[i], y[i]);
+      fprintf(mPSFile, "c s\n");
+    }
+}
+
+
+
+void  PSFile::DrawMarker  (double x0, double y0,
+			   PIMarker MrkType,   
+			   PIColors DrawColor,
+			   int MarkerSize) {
+    /* Couleurs */
+    if ( (DrawColor != PI_NotDefColor) || (DrawColor != mDrawColor) ) {
+	mDrawColor = DrawColor;
+	fprintf(mPSFile, "C%d ", mDrawColor) ; 
+    }
+
+    /* Marker */
+    if (MrkType != PI_NotDefMarker)
+	mMarker = MrkType;
+    if ((MrkType == PI_DotMarker) && (MarkerSize<3)) MarkerSize=3;
+    if(MarkerSize != mMarkerSize || setFontDone) {
+	mMarkerSize = MarkerSize ;
+	fprintf(mPSFile, "/PIMarkers ff %d scf sf\n", 
+		(int)(mMarkerSize*currentPage->FontScaleFactor)) ; 
+        setFontDone = false ; 
+    }
+    /* Dessin */
+    fprintf(mPSFile, "%.2f Ux %.2f Uy m (\\%#o) show\n", x0, y0, mMarker) ;
+}
+
+/*
+ * Pas d'options pour specifier la taille des Markers ?
+ *
+ */
+void  PSFile::DrawMarkers (double *x0, double *y0, int n,
+			   PIMarker MrkType,
+			   PIColors DrawColor,
+			   int MarkerSize) {
+    /* Couleurs */
+    if ( (DrawColor != PI_NotDefColor) || (DrawColor != mDrawColor) ) {
+	mDrawColor = DrawColor;
+	fprintf(mPSFile, "C%d ", mDrawColor) ; 
+    }    
+
+    /* Marker */
+    if (MrkType != PI_NotDefMarker)
+	mMarker = MrkType;
+
+    if(MarkerSize != mMarkerSize || setFontDone) {
+	mMarkerSize = MarkerSize ;
+	fprintf(mPSFile, "/PIMarkers ff %d scf sf\n",  
+		(int)(mMarkerSize*currentPage->FontScaleFactor)) ; 
+        setFontDone = false ; 
+    }
+    /* Dessin */
+    for(int i = 0; i<n; i++)
+	fprintf(mPSFile, "%.2f Ux %.2f Uy m (\\%#o) show\n", x0[i], y0[i], mMarker) ; 
+}
+
+void PSFile::Image(double x0, double y0, double Tx, double Ty,
+		   int Nx, int Ny,
+		   unsigned char *Pict, 
+		   PIColorMap *mMap) {
+
+    int i, j;
+
+    /* Buffers PostScript */
+    fprintf(mPSFile, "/Taille %d def\n", Nx);
+    fprintf(mPSFile, "/ImStr Taille string def\n");
+    fprintf(mPSFile, "/RGBStr Taille 3  mul string def\n");
+
+    /* Ecriture ColorMap */
+    fprintf(mPSFile, "/ColorMap %02d array def\n", mMap->NCol() );
+    for(i = 0; i < mMap->NCol(); i++) {
+	fprintf(mPSFile, "ColorMap %d [16#%02X 16#%02X 16#%02X] put\n",
+		i,
+		(int)(mMap->GetColor(i).red/256),
+		(int)(mMap->GetColor(i).green/256),
+		(int)(mMap->GetColor(i).blue/256));
+    }
+    /* Emplacement de l'image */
+    fprintf(mPSFile, "gs %.2f Ux %.2f Uy tr %.2f Ux %.2f Uy sc\n", x0, y0, Tx, Ty);
+    /* Nbr pix-X, Nbr pix-Y bits/pixels */
+    fprintf(mPSFile, "%d %d 8\n", Nx, Ny);
+    /* Matrice de passage */
+    fprintf(mPSFile, "[%d 0 0 %d 0 0]", Nx, Ny);
+    /* Fonction colorimage */
+    fprintf(mPSFile, "{currentfile ImStr readhexstring pop GetRGB}\
+false 3 colorimage\n\n");
+    /* Data */
+    for(i = 0; i < Ny; i++) {
+	for(j = 0; j<Nx-1; j++ )
+	    fprintf(mPSFile, "%02X", Pict[i*Nx+j]);
+    fprintf(mPSFile, "%02X\n", Pict[i*Nx+j]);
+    }
+    /* Un petit grestore ...*/
+    fprintf(mPSFile, "gr\n");
+}
+
+
+void  PSFile::SelectLine(PILineAtt att)
+{
+    
+  //  if (att.GetLineWidth() != mLineAtt.GetLineWidth()) {
+  double scaledLineWidth = att.GetLineWidthD()*currentPage->FontScaleFactor;
+  fprintf(mPSFile, "%g slw ", scaledLineWidth) ;
+  if (att.GetLineDash() != mLineAtt.GetLineDash()) {
+      switch (att.GetLineDash()) {
+        case PI_LineSolid :
+	  fprintf(mPSFile, "slsolid ");
+	  break;
+        case PI_LineDashed :
+	  fprintf(mPSFile, "sldash ");
+	  break;
+        case PI_LineDotted :
+	  fprintf(mPSFile, "sldott ");
+	  break;
+        case PI_LineDashDotted :
+	  fprintf(mPSFile, "sldashdott ");
+	  break;
+        default :
+	  fprintf(mPSFile, "slsolid ");
+	  break;
+      }
+  }
+  if (att.GetLineJoin() != mLineAtt.GetLineJoin()) {
+      switch (att.GetLineJoin()) {
+        case PI_JoinMiter :
+	  fprintf(mPSFile, "0 sljoin ");
+	  break;
+        case PI_JoinRound :
+	  fprintf(mPSFile, "1 sljoin ");
+	  break;
+        case PI_JoinBevel :
+	  fprintf(mPSFile, "2 sljoin ");
+	  break;
+        default :
+	  fprintf(mPSFile, "0 sljoin ");
+	  break;
+      }
+  }
+  if (att.GetLineCap() != mLineAtt.GetLineCap()) {
+      switch (att.GetLineCap()) {
+        case PI_CapButt :
+	  fprintf(mPSFile, "0 slcap \n");
+	  break;
+        case PI_CapRound :
+	  fprintf(mPSFile, "1 slcap \n");
+	  break;
+        case PI_CapProjecting :
+	  fprintf(mPSFile, "2 slcap \n");
+	  break;
+        default :
+	  fprintf(mPSFile, "0 slcap \n");	  
+	  break;
+      }
+  }
+      mLineAtt = att;
+}
+
+/* 
+ *  Conversion
+ *
+ */
+
+double cm2pt(double x) {
+    return (x*28.35);
+}
+
Index: /tags/V_Dec2002/SophyaPI/PI/psfile.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/psfile.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/psfile.h	(revision 2309)
@@ -0,0 +1,232 @@
+#ifndef PSFILE_H_SEEN
+#define PSFILE_H_SEEN
+
+/*
+ *  PSFile.h
+ * 
+ *  14/06/96, 19/06/96
+ *
+ *  Gestion des fichier .ps et .eps
+ *
+ *     - L'unite de mesure est lUnite Courante (UC)
+ *        Au depart, 1UC == 1cm 
+ *     - Les reperes sont orientes a la maniere XWindow
+ * 
+ *  17/02/97 : modification des constructeurs(1-->eps,2-->ps)
+ *             ajout du type enum orientation
+ *
+ */
+
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef __mac__
+#include <stat.h>
+#endif
+#include "pisysdep.h"
+#include "pifontgen.h"
+
+#include "pigraphgen.h"      // Types enumeres repris de PI:PIFontSize...
+#include PICMAP_H
+
+#include <list>
+
+enum PIPaperSize { PI_A4 = 1, PI_A3 = 2, PI_A5 = 3, PI_NotDefPaperSize = 0};
+
+enum PIOrientation { PI_Landscape = 0, PI_Portrait = 1, PI_Auto = 2 } ;
+
+
+/*
+ *#define PAGE_WIDTH   21.0    == 595 points 
+ *#define PAGE_HEIGHT  29.7    == 842 points 
+ *#define PORTRAIT  1
+ *#define LANDSCAPE 0
+ */
+
+
+
+/* Valable pour une page, ou un bloc */
+/*typedef struct {
+ *  double X0;          Coordonnes sommet NO  
+ *  double Y0;           en unites courantes  
+ *  double Tx;          Format                
+ *  double Ty;           en unites courantes  
+ *  double Dx;          Coord sommet SE       
+ *  double Dy;           en unites courantes  
+ *  int orientation;   LANDSCAPE OU PORTRAIT 
+ *} Format;
+ */
+
+/*
+ *typedef struct{
+ *    char *Name;
+ *    int  Tx;     En 1/72e de pouce  !! 
+ *    int  Ty;     unite naturelle de ps 
+ *} PIMedia;
+ */
+
+
+
+class PSFile{
+
+public:
+    /* Definition de la resolution coordonnees user par defaut (point/cm) */ 
+    static void SetUserCoordResolution(float resx, float resy);
+    static float GetUserCoordResolution(float & resx, float & resy);
+    static float PSCoordResolution(); 
+
+    /* Production fichier eps */
+    PSFile (const char * FileName, double sc = 1.0);
+    /* Production fichier ps  */
+    PSFile (const char * FileName, PIOrientation orientation, 
+	    PIPaperSize paperSize= PI_A4, 
+	    double marginX = 3.0, double marginY = 3.0 ) ;
+
+    virtual      ~PSFile();
+
+    virtual int     IsEPS();
+    virtual const char*   GetFileName();
+
+
+    /*    virtual Format* GetFormat(); */
+    /* Attributs graphiques */
+    virtual PIColors    GetDrawColor();
+    virtual PIColors    GetFillColor();
+    virtual PIFontAtt   GetFontAtt();
+    virtual int         GetFontSize();
+    virtual PILineAtt   GetLineAtt();
+    virtual PIMarker    GetMarker();
+
+    virtual void  NewPage(double Dx, double Dy, PIOrientation orientation);
+    virtual void  EndPage();
+    virtual void  NewBloc(double x0, double y0, double Tx, double Ty,
+			  double Dx, double Dy);
+    virtual void  EndBloc();
+
+    virtual void  SetClipRectangle(double x0, double y0, double dx, double dy);
+    virtual void  ClearClipRectangle();
+
+    virtual void SelForeground(PIColorMap& cmap, int cid) ; 
+    virtual void SelBackground(PIColorMap& cmap, int cid) ; 
+
+    /* Trace */
+    virtual void  DrawString  (double x,  double y, const char *s, 
+			       PIColors DrawColor  = PI_NotDefColor, 
+			       PIFontName FontName = PI_DefaultFont,
+			       PIFontAtt FontAtt   = PI_NotDefFontAtt, 
+			       int FontSize        = 8, 
+			       unsigned long pos = 0);
+    virtual void  DrawLine    (double x1, double y1, double x2, double y2, 
+			       PIColors DrawColor  = PI_NotDefColor,
+			       PILineAtt LineAtt   = PI_NotDefLineAtt);
+    virtual void  DrawBox     (double x0, double y0, double Tx, double Ty, 
+			       PIColors DrawColor  = PI_NotDefColor,
+			       PILineAtt LineAtt   = PI_NotDefLineAtt);
+    virtual void  DrawFBox    (double x0, double y0, double Tx, double Ty, 
+			       PIColors DrawColor  = PI_NotDefColor,
+			       PIColors FillColor  = PI_NotDefColor, 
+			       PILineAtt LineAtt   = PI_NotDefLineAtt);
+    virtual void  DrawCircle  (double x0, double y0, double r, 
+			       PIColors DrawColor  = PI_NotDefColor,
+			       PILineAtt LineAtt   = PI_NotDefLineAtt);
+    virtual void  DrawFCircle (double x0, double y0, double r,
+			       PIColors DrawColor  = PI_NotDefColor,
+			       PIColors FillColor  = PI_NotDefColor, 
+			       PILineAtt LineAtt   = PI_NotDefLineAtt);
+    virtual void  DrawArc     (double x0, double y0, double dx, double dy,
+			       double degdeb, double deltadeg,
+			       PIColors DrawColor  = PI_NotDefColor,
+			       PILineAtt LineAtt   = PI_NotDefLineAtt);
+    virtual void  DrawFArc    (double x0, double y0, double dx, double dy,
+			       double degdeb, double deltadeg,
+			       PIColors DrawColor  = PI_NotDefColor,
+			       PIColors FillColor  = PI_NotDefColor, 
+			       PILineAtt LineAtt   = PI_NotDefLineAtt);
+    virtual void  DrawPolygon (double *x, double *y, int n,
+			       PIColors DrawColor  = PI_NotDefColor, 
+			       PILineAtt LineAtt   = PI_NotDefLineAtt, 
+                               bool cinc = true);
+    virtual void  DrawFPolygon(double *x, double *y, int n,
+			       PIColors DrawColor  = PI_NotDefColor,
+			       PIColors FillColor  = PI_NotDefColor,
+			       PILineAtt LineAtt   = PI_NotDefLineAtt, 
+                               bool cinc = true);
+    virtual void  DrawMarker  (double x0, double y0, 
+			       PIMarker MrkType    = PI_NotDefMarker, 
+			       PIColors DrawColor  = PI_NotDefColor,
+			       int MarkerSize=14);
+    virtual void  DrawMarkers (double *x0, double *y0, int n,
+			       PIMarker MrkType    = PI_NotDefMarker,
+			       PIColors DrawColor  = PI_NotDefColor,
+			       int MarkerSize=14); 
+
+    virtual void  Image(double x0, double y0, double Tx, double Ty,
+			int Nx, int Ny,
+			unsigned char *pict,
+			PIColorMap *mColorMap);
+
+// Declarations en public - sinon certains compilateurs cxx , aCC, xlC ont des problemes
+    /* Blocs */
+    typedef struct {
+	int    num;
+	char*  label;
+	double  X0, Y0;            /* coordonnees sommet NO */
+	double  Tx, Ty;            /* Format */
+	double  Dx, Dy;            /* Repere utilisateur */
+	long  begin,end,tmp;   /* offsets dans le fichier */
+    } Bloc ;
+    typedef list<Bloc> BlocList;  /* STL */
+
+
+    /* Pages */
+    typedef struct {
+	int num;
+	int BlocCounter;
+	double Dx,Dy;              /* Sommet SE (unites utilisateur) */ 
+        float FontScaleFactor;    /* Facteur d'echelle pour les fontes */ 
+	PIOrientation orientation;
+	long  begin, end, tmp;    /* Offsets dans le fichier */
+	BlocList mBlocList;       /* Page == Liste de blocs  */
+    } Page ;
+    typedef list<Page> PageList;  /* STL */
+
+private:
+    void SelectLine(PILineAtt att);   // attributs de ligne ds le fichier PS
+
+    /* Fichier ps/eps */
+    FILE *   mPSFile;
+    const char *   mPSFileName;
+    double    Tw,Th ;              /* Format, en cm */
+    double    WMargin,HMargin ;    /* Marges minimales */
+    int      isEPS;               /* Vrai si PostScript Encapsule */
+    long     boundingBox;         /* Endroit ou est specifiee la bb */
+    double    scale;              /* boundingbox = Dx*scale ; Dy*scale */
+    PIPaperSize mPaperSize ; 
+    int      PageCounter;         /* nbr pages */
+    int      FileEmpty;
+    Page*    currentPage;        /* Avant empilage */
+    Bloc*    currentBloc;        /* Avant empilage */
+    PageList mPageList;          /* Fichier == Liste de pages */
+
+
+    /* Attributs graphiques, initialises par constructeur */
+    PIColors    mDrawColor;  /* Couleur de trace courante */
+    PIColors    mFillColor;  /* Couleur de remplissage courante */
+    PIFontAtt   mFontAtt; 
+    //    enum PIFontSize  mFontSize; 
+    int              mFontSize; 
+    PIFontName  mFontName; 
+    PILineAtt   mLineAtt;    /* Epaisseur d une ligne */
+    PIMarker    mMarker;     /* Marker courant */
+    int         mMarkerSize; /* Taille (en points) du marker courant */
+    bool setFontDone ; /* Pour forcer la selection de Marker apres DrawString() */
+
+  /* resolution coordonnees user (point/cm - pixels/cm) */
+    static float  def_user_resol_X, def_user_resol_Y; 
+    static float  def_user_resolution;
+  /* resolution coordonnees PostScript (point/cm - pixels/cm) */
+    static float  postscript_resolution;
+} ;
+
+
+#endif/* PSFILE_H_SEEN */
Index: /tags/V_Dec2002/SophyaPI/PI/ucckprot.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/ucckprot.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/ucckprot.h	(revision 2309)
@@ -0,0 +1,67 @@
+// Module PI : Peida Interactive   - ucckprot.h
+// Protection transfo coordonnees UserCoord<>GraphicCoord 
+//                    C. Magneville, R. Ansari  2002
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef UCCKPROT_H_SEEN
+#define UCCKPROT_H_SEEN
+
+#include <math.h>
+//  Pour la declaration de finite() isnan() ...
+#if defined(SunOS)
+#include <ieeefp.h>
+#endif
+
+//define PETIT_DBLE 1.e-39
+//define PREC_DBLE  1.e-5
+//define PROT_DBLE  1.e-19
+#define PETIT_DBLE 1.e-85
+// qque probleme sur le trace - J'augmente les marges - Reza 14/5/2002 
+// #define PREC_DBLE  1.e-16  
+#define PREC_DBLE  1.e-14
+#define MINRAP_DBLE  1.e-12
+#define PROT_DBLE_MIN  1.e-100
+#define PROT_DBLE_MAX  1.e+100
+
+inline double UC_LimitProtectDouble(double x)
+{ 
+  if (x < 0.) {
+    if (x < -PROT_DBLE_MAX) return (-PROT_DBLE_MAX);
+    if (x > -PROT_DBLE_MIN) return (-PROT_DBLE_MIN);
+    return(x);
+  }
+  else {
+    if (x > PROT_DBLE_MAX) return (PROT_DBLE_MAX);
+    if (x < PROT_DBLE_MIN) return (PROT_DBLE_MIN);
+    return(x);
+  }
+}
+
+inline bool UC_CheckMinMaxDiff(double& xmin, double& xmax) 
+{
+  bool rc = false;
+  double xym,xym2;
+  xym = fabs(xmax);
+  xym2 = fabs(xmin);
+  if (xym2 > xym) xym = xym2;
+  if (xym < PETIT_DBLE) xym = PETIT_DBLE;
+  if ((xmax-xmin) < MINRAP_DBLE*xym) {
+    xmin -= MINRAP_DBLE*xym*0.5;  xmax = xmin+MINRAP_DBLE*xym;
+    //    cerr << " DBG-CheckMinMaxDiff: xmin,max=" << xmin << "," << xmax 
+    //	 << " xym=" << xym << " diff=" << xmax-xmin << endl;
+    rc = true;
+  }
+  return(rc);
+}
+
+inline bool UC_CheckFinite(double xmin, double xmax)
+{
+#if defined(OSF1) || defined(SunOS) || defined(Darwin) || (defined(Linux) && !defined(__KCC__) )
+  if (finite(xmin) && finite(xmax)) return(true);
+  else return(false);
+#else
+  return(true);
+#endif
+}
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PI/xdispim.c
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/xdispim.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/xdispim.c	(revision 2309)
@@ -0,0 +1,383 @@
+#if 0
+/* Fonctions interface XWindow pour affichage d'images */
+/*                  Reza   05/95                       */
+
+/*                  LAL (Orsay) / IN2P3-CNRS           */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+
+#include "xdispim.h"
+
+/*  Variables globales pour  */
+
+static int RzXwDispImg = 0;
+static Display * display;
+static int screen;
+static GC defgc;
+static RzXCMap rzxcmap[5];
+static int rzxgcok = 0;
+static Font fonts[5];
+
+static int NbRzXw = 0;
+
+
+/*  Fin des variables globales   */
+
+
+/* Nouvelle-Fonction */
+int RzXInitDisplay(int prtl)
+
+/*   Connection avec un serveur X, et allocation des couleurs    */
+
+{
+Visual* vis;
+
+
+struct rzvisu_struc
+  {
+  int MMsize_x;
+  int MMsize_y;
+  int Pixsize_x;
+  int Pixsize_y;
+  float resol_x;
+  float resol_y;
+  } rzvisu;
+
+
+display = XOpenDisplay ("");
+
+if (display == 0)
+  { printf("RzXInitDisplay_Error: Cannot connect to X-Server \n");
+    return(1); }
+screen = XDefaultScreen(display);
+
+rzvisu.Pixsize_x = DisplayWidth  (display, screen);
+rzvisu.Pixsize_y = DisplayHeight (display, screen);
+rzvisu.MMsize_x = DisplayWidthMM  (display, screen);
+rzvisu.MMsize_y = DisplayHeightMM (display, screen);
+
+rzvisu.resol_x = (float)rzvisu.Pixsize_x*10./(float)rzvisu.MMsize_x;
+rzvisu.resol_y = (float)rzvisu.Pixsize_y*10./(float)rzvisu.MMsize_y;
+
+vis = DefaultVisual(display,screen);
+
+if (prtl > 0)
+  {
+  printf("RzXInitDisplay_Info: Screen size (X,Y) : %d * %d Pix (%d * %d  mm)\n",
+         rzvisu.Pixsize_x,rzvisu.Pixsize_y,
+         rzvisu.MMsize_x,rzvisu.MMsize_y);
+  printf ("... Planes= %d  Cells= %d  depth= %d ", XDisplayPlanes(display, screen) ,
+          XDisplayCells(display, screen), XDefaultDepth(display, screen));
+
+  switch (vis->class)
+    {
+    case PseudoColor :
+      printf (".... Class = %d (PseudoColor) \n",vis->class);
+      break;
+    case DirectColor : 
+      printf (".... Class = %d (DirectColor) \n",vis->class);
+      break;
+    case GrayScale :
+      printf (".... Class = %d (GreyScale) \n",vis->class);
+      break;
+    case StaticColor :
+      printf (".... Class = %d (StaticColor) \n",vis->class);
+      break;
+    case StaticGray :
+      printf (".... Class = %d (StaticGray) \n",vis->class);
+      break;
+    case TrueColor :   
+      printf (".... Class = %d (TrueColor) \n",vis->class);
+      break;
+    default :
+      printf (".... Class = %d (Unknown !) \n",vis->class);
+      break;
+    }
+
+  }
+
+/*  Allocating default CMap */
+RzXAllocCMap(rzxcmap, CMAP_GREY32, prtl);
+RzXAllocCMap(rzxcmap+1, CMAP_COL16, prtl);
+RzXAllocCMap(rzxcmap+2, CMAP_GREYINV32, prtl);
+RzXAllocCMap(rzxcmap+3, CMAP_COLRJ32, prtl);
+rzxcmap[4].typ = -1;  rzxcmap[4].nCol = 0;
+
+if (prtl > 1)
+  printf("...Loading fonts Adobe-Courier Normal/Bold/Ital : \n");
+fonts[0] = XLoadFont(display,
+       "-adobe-courier-medium-r-normal--*-140-*-iso8859-1");
+fonts[1] = XLoadFont(display,
+       "-adobe-courier-bold-r-normal--*-140-*-iso8859-1");
+fonts[2] = XLoadFont(display,
+       "-adobe-courier-medium-o-normal--*-140-*-iso8859-1");
+
+RzXwDispImg = 1;    /*  Variable de controle d'initialisation */
+
+return(0);
+}
+
+/* Nouvelle-Fonction */
+int RzXCheckInitDisp()
+{
+return (RzXwDispImg);
+}
+
+
+/* Nouvelle-Fonction */
+int RzXGetPixDSize()
+/*  Retourne la taille correspondant a depth en Byte ( 8->1) */
+{
+int depth;
+depth = DefaultDepth(display,screen);
+if (depth <= 8)  return(1);
+else if (depth <= 16)  return(2);
+else return(4);
+}
+
+/* Nouvelle-Fonction */
+int RzXDispPixMap(Window xw, unsigned char *pix,  int sizx, int sizy, RzXCMap *cmap)
+{
+int depth;
+XImage * ximg;
+int i,j;
+unsigned char *pp;
+
+depth = DefaultDepth(display,screen);
+ximg = XCreateImage (display,DefaultVisual(display,screen),
+       depth,ZPixmap,0,pix,sizx,sizy,8,0);
+pp = pix;
+for(j=0; j<sizy; j++)
+  for(i=0; i<sizx; i++) 
+    { XPutPixel(ximg, i, j, cmap->colpix[*pp]);  pp++; }
+XRaiseWindow(display, xw);
+XPutImage(display,xw,defgc,ximg,0,0,0,0,sizx, sizy);
+XSync(display,1);
+XFree(ximg);
+
+return(0);
+
+}
+
+
+/* Nouvelle-Fonction */
+RzXCMap * RzXGetCMap(int cmapid)
+{
+int i;
+for(i=0; i<5; i++)
+  if (rzxcmap[i].typ == cmapid)  return(rzxcmap+i);
+if (rzxcmap[4].typ >= 0)  RzXFreeCMap(rzxcmap+4);
+RzXAllocCMap(rzxcmap+4, cmapid, 0);
+return(rzxcmap+4);
+}
+
+
+/*  Definition d' une table de couleurs  R G B   */
+
+static float R_RGB1[16] =
+{0.0,0.00,0.0,0.0,0.0,0.00,0.0,0.6,0.8,1.0,1.00,1.0,0.75,1.0,0.85,1.0};
+static float G_RGB1[16] =
+{0.0,0.00,0.0,0.8,1.0,1.00,1.0,0.8,0.8,1.0,0.75,0.6,0.00,0.0,0.0,0.0};
+static float B_RGB1[16] =
+{0.0,0.75,1.0,1.0,1.0,0.75,0.0,0.0,0.0,0.0,0.00,0.5,0.75,1.0,0.0,0.0};
+
+
+
+/* Nouvelle-Fonction */
+int RzXAllocCMap(RzXCMap *rcmap, int cmapid, int prtl)
+/*  Allocation des tables de couleurs  */
+
+{
+Colormap cmap;
+XColor mycol;
+int nok,i;
+
+cmap = XDefaultColormap (display, screen);
+
+nok = 0;
+
+rcmap->typ = -1;
+
+switch (cmapid)
+  {
+  case CMAP_GREY32 :
+    rcmap->nCol = 32;   nok = 0;
+    for(i=0; i<rcmap->nCol; i++)
+      {
+      mycol.red = mycol.green = mycol.blue = 3535+(i*62000/32);
+      if (XAllocColor(display, cmap, &mycol) )
+        { rcmap->colpix[i] = mycol.pixel;   nok++; }
+      else rcmap->colpix[i] = BlackPixel(display, screen);  
+      }
+    rcmap->typ = CMAP_GREY32;
+    break;
+
+  case CMAP_GREYINV32 :
+    rcmap->nCol = 32;   nok = 0;
+    for(i=0; i<rcmap->nCol; i++)
+      {
+      mycol.red = mycol.green = mycol.blue = 65535-(i*62000/32);
+      if (XAllocColor(display, cmap, &mycol) )
+        { rcmap->colpix[i] = mycol.pixel;   nok++; }
+      else rcmap->colpix[i] = BlackPixel(display, screen);  
+      }
+    rcmap->typ = CMAP_GREYINV32;
+    break;
+
+  case CMAP_COL16 :
+    rcmap->nCol = 16;   nok = 0;
+    for(i=0; i<rcmap->nCol; i++)
+      {
+      mycol.red = (int)(R_RGB1[i]*65535.);
+      mycol.green = (int)(G_RGB1[i]*65535.);
+      mycol.blue =(int)(B_RGB1[i]*65535.) ;
+      if (XAllocColor(display, cmap, &mycol) )
+        { rcmap->colpix[i] = mycol.pixel;   nok++; }
+      else rcmap->colpix[i] = BlackPixel(display, screen);  
+      }
+    rcmap->typ = CMAP_COL16;
+    break;
+
+  case CMAP_COLRJ32 :
+    rcmap->nCol = 32;   nok = 0;
+    for(i=0; i<rcmap->nCol; i++)
+      {
+      if (i < 12) 
+        { mycol.green = mycol.blue = 0;  
+          mycol.red = 21535+(i*4000); }
+      else if (i < 24)
+        { mycol.blue = 0;   mycol.red = 65535;
+          mycol.green = 21535+(i-12)*4000;  }
+      else 
+        { mycol.green = mycol.red = 65535;
+          mycol.blue = 17535+(i-23)*6000; }
+
+      if (XAllocColor(display, cmap, &mycol) )
+        { rcmap->colpix[i] = mycol.pixel;   nok++; }
+      else rcmap->colpix[i] = BlackPixel(display, screen);  
+      }
+    rcmap->typ = CMAP_COLRJ32;
+    break;
+
+  case CMAP_COLBR32 :
+    rcmap->nCol = 32;   nok = 0;
+    for(i=0; i<rcmap->nCol; i++)
+      {
+      if (i < 5) 
+        { mycol.green = mycol.red = 0;  
+          mycol.blue = 5535+i*15000; }
+      else if (i < 10)
+        { mycol.blue = 65535;
+          mycol.green = 5535+(i-5)*9000;
+          mycol.red = 0;  }
+      else if (i < 15)
+        { mycol.blue = 60000-(i-10)*15000;
+          mycol.green = 41535+(i-10)*6000;
+          mycol.red = 0;  }
+      else if (i < 21)
+        { mycol.blue = 0;
+          mycol.green = 65535;
+          mycol.red = 5535+(i-15)*12000;  }
+      else if (i < 27)
+        { mycol.blue = 0;
+          mycol.green = 60000-(i-21)*12000;
+          mycol.red = 65535-(i-21)*2000;  }
+      else 
+        { mycol.blue = 0;
+          mycol.green = 0;
+          mycol.red = 57535+(i-27)*2000; }
+
+      if (XAllocColor(display, cmap, &mycol) )
+        { rcmap->colpix[i] = mycol.pixel;   nok++; }
+      else rcmap->colpix[i] = BlackPixel(display, screen);  
+      }
+    rcmap->typ = CMAP_COLBR32;
+    break;
+
+  case CMAP_COLRV32 :
+    rcmap->nCol = 32;   nok = 0;
+    for(i=0; i<rcmap->nCol; i++)
+      {
+      if (i < 8) 
+        { mycol.green = 15000+(i*5000); mycol.blue = 0;  
+          mycol.red = 15000+(i*5000); }
+      else if (i < 21)
+        { mycol.green = 50000-(i-7)*5000;   
+          if (mycol.green < 0)  mycol.green = 0;
+          mycol.blue = 0;
+          mycol.red = 53535+(i-8)*1000;  }
+      else 
+        { mycol.green = 0;  mycol.red = 65535;
+          mycol.blue = 15535+(i-21)*5000; }
+
+      if (XAllocColor(display, cmap, &mycol) )
+        { rcmap->colpix[i] = mycol.pixel;   nok++; }
+      else rcmap->colpix[i] = BlackPixel(display, screen);  
+      }
+    rcmap->typ = CMAP_COLRV32;
+    break;
+
+  default :
+    printf("RzXAllocCMap_Info: Erreur specification CMapType (%d) \n", cmapid);
+    break;
+  }
+
+for(i=rcmap->nCol; i<256; i++)  rcmap->colpix[i] = 0;
+
+if (prtl)
+  printf("RzXAllocCMap_Info: %d colors allocated for CMap Type %d \n", nok, cmapid);
+
+return(0);
+
+}
+
+/* Nouvelle-Fonction */
+int RzXFreeCMap(RzXCMap *rcmap)
+{
+Colormap cmap;
+int i;
+
+cmap = XDefaultColormap (display, screen);
+XFreeColors(display, cmap, rcmap->colpix,  rcmap->nCol, 0);
+for(i=0; i<rcmap->nCol; i++)  rcmap->colpix[i] = 0;
+rcmap->nCol = 0;
+return(0);
+}
+
+
+/* Nouvelle-Fonction */
+Window RzXNewWin(int sx, int sy, char *title, int posx, int posy)
+
+/*  Creation de fenetre X simple pour mettre une image  */
+{
+XSizeHints hint;
+Window   win;
+
+hint.x = posx;   hint.y = posy;
+hint.width  = sx;  hint.height = sy;
+hint.flags  = PPosition | PSize;
+
+
+win =  XCreateSimpleWindow (display, DefaultRootWindow (display),
+       hint.x, hint.y, hint.width, hint.height, 3,
+       WhitePixel(display, screen), BlackPixel(display, screen) );                        
+
+XSetStandardProperties (display, win, title, title, None, NULL, 0, &hint);
+
+if (!rzxgcok)
+  {
+  defgc = XCreateGC (display, win, 0, 0);
+  rzxgcok = 1;
+  }
+XMapRaised(display,win);
+XSync(display,1);
+
+return(win);
+}
+#endif
+
Index: /tags/V_Dec2002/SophyaPI/PI/xdispim.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PI/xdispim.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PI/xdispim.h	(revision 2309)
@@ -0,0 +1,36 @@
+/* Fonctions interface XWindow pour affichage d'images */
+
+#ifndef XDISPIM_SEEN
+#define XDISPIM_SEEN
+
+
+#include <X11/Xlib.h>
+
+#define CMAP_GREY32         0
+#define CMAP_COL16          1
+#define CMAP_COLRJ32        2
+#define CMAP_GREYINV32      3
+#define CMAP_COLBR32        4
+#define CMAP_COLRV32        5
+
+struct _RzXCMap_
+  {
+  int typ;
+  int nCol;
+  unsigned long colpix[256];
+  };
+typedef struct _RzXCMap_  RzXCMap;
+
+int RzXInitDisplay(int prtl);
+int RzXCheckInitDisp(void);
+
+int RzXGetPixDSize(void);
+int RzXDispPixMap(Window xw, unsigned char *pix,  int sizx, int sizy, RzXCMap *cmap);
+
+RzXCMap * RzXGetCMap(int cmpaid);
+int RzXAllocCMap(RzXCMap *rcmap, int cmapid, int prtl);
+int RzXFreeCMap(RzXCMap *rcmap);
+
+Window RzXNewWin(int sx, int sy, char *title, int posx, int posy);
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIGcont/Makefile
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIGcont/Makefile	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIGcont/Makefile	(revision 2309)
@@ -0,0 +1,185 @@
+MODULECXXREPNAME := PI
+MODULEDECCXXFLAGS := -msg_quiet
+include ../Mgr/Makefile.h
+ 
+all: $(LIB)libPIGcont.a
+$(LIB)libPIGcont.a : $(OBJ)gp_alloc.o $(OBJ)gp_axis.o $(OBJ)gp_contour.o $(OBJ)picntools.o $(OBJ)pigncont.o
+	$(AR) $(ARFLAGS)  $@ $($(ARARGS)) 
+ifeq ($(CXX),cxx)
+	$(CXX) $? $(CPPFLAGS) $(CXXFLAGS) -o $(OBJ)xx.x -Hf
+endif 
+ 
+clean:
+	rm -f $(OBJ)gp_alloc.o $(OBJ)gp_axis.o $(OBJ)gp_contour.o $(OBJ)picntools.o $(OBJ)pigncont.o
+ifeq ($(CXX),cxx)
+	cd $(REPM); rm -f *.o
+endif 
+ 
+$(OBJ)gp_alloc.o: gp_alloc.c gp_alloc.h gp_graph3d.h gp_types.h gpc_misc.h
+$(OBJ)gp_axis.o: gp_axis.c gp_axis.h gpc_misc.h
+$(OBJ)gp_contour.o: gp_contour.c gp_contour.h gp_types.h gpc_misc.h \
+ gp_dynarray.h gp_graph3d.h gp_alloc.h gp_axis.h
+$(OBJ)picntools.o: picntools.cc $(INC)machdefs.h \
+ picntools.h $(INC)pisysdep.h \
+ $(INC)pistdwdgx.h \
+ $(INC)pistdwdggen.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picolist.h \
+ $(INC)pioptmenux.h \
+ $(INC)pioptmenugen.h \
+ $(INC)pimenux.h \
+ $(INC)pimenugen.h \
+ $(INC)piwindowx.h \
+ $(INC)piwindowgen.h \
+ $(INC)picontainerx.h \
+ $(INC)picontainergen.h \
+ $(INC)piapplx.h \
+ $(INC)piapplgen.h \
+ $(INC)pimenubarx.h \
+ $(INC)pimenubargen.h \
+ $(INC)picons.h \
+ $(INC)pibwdgx.h \
+ $(INC)pibwdggen.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigraphps.h \
+ $(INC)picmapview.h pigncont.h \
+ $(INC)pistdimgapp.h \
+ $(INC)pifilechox.h \
+ $(INC)pifilechogen.h \
+ $(INC)piperiodx.h \
+ $(INC)periodic.h \
+ $(INC)piimage.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)pieldrw.h \
+ $(INC)pidrawer.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h \
+ $(INC)pipixmapx.h \
+ $(INC)pipixmapgen.h \
+ $(INC)pi3dwdg.h \
+ $(INC)pi3ddrw.h \
+ $(INC)pigraph3d.h \
+ $(INC)nobjmgr.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)mutyv.h \
+ $(INC)dlftypes.h \
+ $(INC)piacmd.h \
+ $(INC)pdlmgr.h \
+ $(INC)ctimer.h \
+ $(INC)pisiadw.h \
+ $(INC)pilistx.h \
+ $(INC)pilistgen.h \
+ $(INC)pistzwin.h \
+ $(INC)pitherm.h \
+ $(INC)resusage.h \
+ $(INC)piscdrawwdg.h \
+ $(INC)ntuple.h \
+ $(INC)ntupintf.h gp_contour.h gp_types.h \
+ gpc_misc.h gp_dynarray.h gp_graph3d.h gp_alloc.h
+$(OBJ)pigncont.o: pigncont.cc $(INC)machdefs.h \
+ $(INC)histos.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)fmath.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)ntuple.h \
+ $(INC)ntupintf.h \
+ $(INC)nbtri.h picntools.h \
+ $(INC)pisysdep.h \
+ $(INC)pistdwdgx.h \
+ $(INC)pistdwdggen.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picolist.h \
+ $(INC)pioptmenux.h \
+ $(INC)pioptmenugen.h \
+ $(INC)pimenux.h \
+ $(INC)pimenugen.h \
+ $(INC)piwindowx.h \
+ $(INC)piwindowgen.h \
+ $(INC)picontainerx.h \
+ $(INC)picontainergen.h \
+ $(INC)piapplx.h \
+ $(INC)piapplgen.h \
+ $(INC)pimenubarx.h \
+ $(INC)pimenubargen.h \
+ $(INC)picons.h \
+ $(INC)pibwdgx.h \
+ $(INC)pibwdggen.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigraphps.h \
+ $(INC)picmapview.h pigncont.h \
+ $(INC)pistdimgapp.h \
+ $(INC)pifilechox.h \
+ $(INC)pifilechogen.h \
+ $(INC)piperiodx.h \
+ $(INC)periodic.h \
+ $(INC)piimage.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)pieldrw.h \
+ $(INC)pidrawer.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h \
+ $(INC)pipixmapx.h \
+ $(INC)pipixmapgen.h \
+ $(INC)pi3dwdg.h \
+ $(INC)pi3ddrw.h \
+ $(INC)pigraph3d.h \
+ $(INC)nobjmgr.h \
+ $(INC)dlftypes.h \
+ $(INC)piacmd.h \
+ $(INC)pdlmgr.h \
+ $(INC)ctimer.h \
+ $(INC)pisiadw.h \
+ $(INC)pilistx.h \
+ $(INC)pilistgen.h \
+ $(INC)pistzwin.h \
+ $(INC)pitherm.h \
+ $(INC)resusage.h \
+ $(INC)piscdrawwdg.h gp_contour.h gp_types.h \
+ gpc_misc.h gp_dynarray.h gp_graph3d.h gp_alloc.h
Index: /tags/V_Dec2002/SophyaPI/PIGcont/gp_alloc.c
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIGcont/gp_alloc.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIGcont/gp_alloc.c	(revision 2309)
@@ -0,0 +1,106 @@
+#include "gp_alloc.h"
+/* #include "gp_graph3d.h" */
+#include <math.h>
+#define TRACE_ALLOC(x)	
+struct frame_struct {
+    char *use;
+    int requested_size;
+    int pad;			/* preserve 8-byte alignment */
+    int checksum;
+};
+ 
+#define CHECKSUM_INT 0xcaac5e1f
+#define RESERVED_SIZE sizeof(struct frame_struct)
+#define CHECKSUM_CHAR 0xc5
+
+static long bytes_allocated = 0;
+
+static void
+mark(p, size, usage)
+struct frame_struct *p;
+unsigned long size;
+char *usage;
+{
+    p->use = usage;
+    p->requested_size = size;
+    p->checksum = (CHECKSUM_INT ^ (int) (p->use) ^ size);
+    ((unsigned char *) (p + 1))[size] = CHECKSUM_CHAR;
+}
+
+void *
+gp_alloc(size, usage)
+size_t size;
+const char *usage;
+{
+    struct frame_struct *p;
+    size_t total_size = size + RESERVED_SIZE + 1;
+
+    /*TRACE_ALLOC(("gp_alloc %d for %s\n", (int) size, usage ? usage : "<unknown>"));*/
+    /*printf("gp_alloc %d for %s\n", (int) total_size, usage ? usage : "<unknown>");*/
+    p = malloc(total_size);
+    if (!p){ printf("gp_alloc :  Out of memory !!!! \n"); exit(-99);}
+    /*int_error(NO_CARET, "Out of memory");*/
+
+    bytes_allocated += size;
+
+    /*mark(p, size, usage);*/
+
+    /*return (char *) (p+1);*/
+    return (char *) (p);
+}
+ 
+void gp_free(void *p){
+  free(p);
+}
+
+void contour_free(struct gnuplot_contours *ptr){
+  //char *c;
+  struct coordinate *coords;
+  struct gnuplot_contours *old;
+  struct gnuplot_contours *cur;
+ 
+  cur = ptr; 
+  //printf("\n contour_free  %x \n",cur);
+  while(cur){
+    /*printf(" contour_free  %x \n",cur);*/
+    old = cur;
+    cur = cur->next;    
+    coords = old->coords;    
+    if(coords){free(coords) ; coords = NULL;}
+    free(old);    
+    old=NULL;
+  } 
+  
+
+}
+/*
+ * iso_alloc() allocates a iso_curve structure that can hold 'num'
+ * points.
+ */
+struct iso_curve *
+iso_alloc(num)
+int num;
+{
+    struct iso_curve *ip;
+    ip = (struct iso_curve *) gp_alloc(sizeof(struct iso_curve), "iso curve");
+    ip->p_max = (num >= 0 ? num : 0);
+    if (num > 0) {
+	ip->points = (struct coordinate  *)
+	    gp_alloc(num * sizeof(struct coordinate), "iso curve points");
+    } else
+	ip->points = (struct coordinate  *) NULL;
+    ip->next = NULL;
+    return (ip);
+}
+/*
+ * iso_free() releases any memory which was previously malloc()'d to hold
+ *   iso curve points.
+ */
+void iso_free(struct iso_curve *ip)
+{
+    if (ip) {
+        if (ip->points)
+            free((char *) ip->points);
+        free((char *) ip);
+    }
+}
Index: /tags/V_Dec2002/SophyaPI/PIGcont/gp_alloc.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIGcont/gp_alloc.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIGcont/gp_alloc.h	(revision 2309)
@@ -0,0 +1,89 @@
+
+/* GNUPLOT - gp_alloc.h (alloc.h renamed to gp_alloc.h) */
+
+/*[
+ * Copyright 1986 - 1993, 1998   Thomas Williams, Colin Kelley
+ *
+ * Permission to use, copy, and distribute this software and its
+ * documentation for any purpose with or without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.
+ *
+ * Permission to modify the software is granted, but not the right to
+ * distribute the complete modified source code.  Modifications are to
+ * be distributed as patches to the released version.  Permission to
+ * distribute binaries produced by compiling modified sources is granted,
+ * provided you
+ *   1. distribute the corresponding source modifications from the
+ *    released version in the form of a patch file along with the binaries,
+ *   2. add special version identification to distinguish your version
+ *    in addition to the base release version number,
+ *   3. provide your name and address as the primary contact for the
+ *    support of your modified version, and
+ *   4. retain our contact information in regard to use of the base
+ *    software.
+ * Permission to distribute the released version of the source code along
+ * with corresponding source modifications in the form of a patch file is
+ * granted with same provisions 2 through 4 for binary distributions.
+ *
+ * This software is provided "as is" without express or implied warranty
+ * to the extent permitted by applicable law.
+]*/
+
+#ifndef GNUPLOT_ALLOC_H
+# define GNUPLOT_ALLOC_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "gp_graph3d.h"
+/****
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "stdfn.h"
+****/
+/* prototypes from "alloc.c". This file figures out if the free hack is needed
+ * and redefines free if necessary.
+ */
+ 
+void *gp_alloc(size_t size, const char *message);
+void *gp_realloc(void *p, size_t size, const char *message);
+struct iso_curve *iso_alloc(int);
+
+void iso_free(struct iso_curve *);
+void gp_free(void *);
+void contour_free(struct gnuplot_contours *ptr);
+/* dont define CHECK_HEAP_USE on a FARALLOC machine ! */
+
+#ifdef CHECK_HEAP_USE
+
+/* all allocated blocks have guards at front and back.
+ * CHECK_POINTER checks guards on block, and checks that p is in range
+ * START_LEAK_CHECK and END_LEAK_CHECK allow assert that no net memory
+ * is allocated within enclosed block
+ */
+ 
+void checked_free(void *p);
+void check_pointer_in_block(void *block, void *p, int size, char *file, int line);
+void start_leak_check(char *file,int line);
+void end_leak_check(char *file,int line);
+/*# define free(x) checked_free(x)*/
+# define CHECK_POINTER(block, p) check_pointer_in_block(block, p, sizeof(*p), __FILE__, __LINE__)
+# define START_LEAK_CHECK() start_leak_check(__FILE__, __LINE__)
+# define END_LEAK_CHECK() end_leak_check(__FILE__, __LINE__)
+#else
+# define CHECK_POINTER(block, p) /*nowt*/
+# define START_LEAK_CHECK() /*nowt*/
+# define END_LEAK_CHECK() /*nowt*/
+#endif
+
+/***
+#if defined(MSDOS) && defined(__TURBOC__) && !defined(DOSX286) || defined(_Windows) && !defined(WIN32) 
+#define FARALLOC 
+void gpfree((generic *p)); 
+#define free gpfree 
+#endif 
+***/
+#endif /* GNUPLOT_ALLOC_H */
Index: /tags/V_Dec2002/SophyaPI/PIGcont/gp_axis.c
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIGcont/gp_axis.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIGcont/gp_axis.c	(revision 2309)
@@ -0,0 +1,97 @@
+#include "gp_axis.h"
+#include <math.h>
+AXIS axis_array[AXIS_ARRAY_SIZE] = AXIS_ARRAY_INITIALIZER(DEFAULT_AXIS_STRUCT);
+
+void dummy(){
+
+  int k=4;
+  
+}
+/*{{{  dbl_raise() used by set_tics */
+/* FIXME HBB 20000426: is this really useful? */
+static double
+dbl_raise(x, y)
+double x;
+int y;
+{
+    register int i = abs(y);
+    double val = 1.0;
+
+    while (--i >= 0)
+	val *= x;
+
+    if (y < 0)
+	return (1.0 / val);
+    return (val);
+}
+
+/*}}} */
+
+/*{{{  set_tic() */
+/* the guide parameter was intended to allow the number of tics
+ * to depend on the relative sizes of the plot and the font.
+ * It is the approximate upper limit on number of tics allowed.
+ * But it did not go down well with the users.
+ * A value of 20 gives the same behaviour as 3.5, so that is
+ * hardwired into the calls to here. Maybe we will restore it
+ * to the automatic calculation one day
+ */
+
+double
+set_tic(l10, guide)
+     double l10;
+     int guide;
+{
+    double xnorm, tics, posns;
+
+    int fl = (int) floor(l10);
+    xnorm = pow(10.0, l10 - fl);	/* approx number of decades */
+
+    posns = guide / xnorm;	/* approx number of tic posns per decade */
+
+    if (posns > 40)
+	tics = 0.05;		/* eg 0, .05, .10, ... */
+    else if (posns > 20)
+	tics = 0.1;		/* eg 0, .1, .2, ... */
+    else if (posns > 10)
+	tics = 0.2;		/* eg 0,0.2,0.4,... */
+    else if (posns > 4)
+	tics = 0.5;		/* 0,0.5,1, */
+    else if (posns > 1)
+	tics = 1;		/* 0,1,2,.... */
+    else if (posns > 0.5)
+	tics = 2;		/* 0, 2, 4, 6 */
+    else
+	/* getting desperate... the ceil is to make sure we
+	 * go over rather than under - eg plot [-10:10] x*x
+	 * gives a range of about 99.999 - tics=xnorm gives
+	 * tics at 0, 99.99 and 109.98  - BAD !
+	 * This way, inaccuracy the other way will round
+	 * up (eg 0->100.0001 => tics at 0 and 101
+	 * I think latter is better than former
+	 */
+	tics = ceil(xnorm);
+
+    return (tics * dbl_raise(10.0, fl));
+}
+/* this is used in a few places all over the code: undo logscaling of
+ * a given range if necessary. If checkrange is TRUE, will int_error() if
+ * range is invalid */
+void
+axis_unlog_interval(axis, min, max, checkrange)
+    AXIS_INDEX axis;
+    double *min, *max;
+    TBOOLEAN checkrange;
+{
+    if (axis_array[axis].log) {
+      if (checkrange && (*min<= 0.0 || *max <= 0.0))printf(" axis_unlog_interval : range must be > 0 !! \n");
+	  /*int_error(NO_CARET,
+		      "%s range must be greater than 0 for log scale",
+		      axis_defaults[axis].name);*/
+	*min = (*min<=0) ? -VERYLARGE : AXIS_DO_LOG(axis,*min);
+	*max = (*max<=0) ? -VERYLARGE : AXIS_DO_LOG(axis,*max);
+    }
+} 
+
+/*}}} */
+
Index: /tags/V_Dec2002/SophyaPI/PIGcont/gp_axis.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIGcont/gp_axis.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIGcont/gp_axis.h	(revision 2309)
@@ -0,0 +1,615 @@
+/*[
+ * Copyright 2000   Thomas Williams, Colin Kelley
+ *
+ * Permission to use, copy, and distribute this software and its
+ * documentation for any purpose with or without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.
+ *
+ * Permission to modify the software is granted, but not the right to
+ * distribute the complete modified source code.  Modifications are to
+ * be distributed as patches to the released version.  Permission to
+ * distribute binaries produced by compiling modified sources is granted,
+ * provided you
+ *   1. distribute the corresponding source modifications from the
+ *    released version in the form of a patch file along with the binaries,
+ *   2. add special version identification to distinguish your version
+ *    in addition to the base release version number,
+ *   3. provide your name and address as the primary contact for the
+ *    support of your modified version, and
+ *   4. retain our contact information in regard to use of the base
+ *    software.
+ * Permission to distribute the released version of the source code along
+ * with corresponding source modifications in the form of a patch file is
+ * granted with same provisions 2 through 4 for binary distributions.
+ *
+ * This software is provided "as is" without express or implied warranty
+ * to the extent permitted by applicable law.
+]*/
+
+#ifndef GNUPLOT_AXIS_H
+#define GNUPLOT_AXIS_H
+
+#include "gpc_misc.h"
+#include <stdio.h>
+/*#include "gp_types.h"	*/	/* for TBOOLEAN */
+
+/*#include "gadgets.h"*/
+/*#include "parse.h"	*/	/* for const_express() */
+/*#include "tables.h"	*/	/* for the axis name parse table */
+/*#include "term_api.h"	*/	/* for lp_style_type */
+/*#include "util.h"	*/	/* for int_error() */
+/****/
+
+/* typedefs / #defines */
+#ifndef TRUE
+#define TRUE     -1
+#define FALSE    0
+#endif
+
+/* give some names to some array elements used in command.c and grap*.c
+ * maybe one day the relevant items in setshow will also be stored
+ * in arrays. 
+ *
+ * Always keep the following conditions alive:
+ * SECOND_X_AXIS = FIRST_X_AXIS + SECOND_AXES
+ * FIRST_X_AXIS & SECOND_AXES == 0
+ */
+
+typedef enum AXIS_INDEX {
+#define FIRST_AXES 0
+    FIRST_Z_AXIS, 
+    FIRST_Y_AXIS,
+    FIRST_X_AXIS,
+    T_AXIS,			/* fill gap */
+#define SECOND_AXES 4
+    SECOND_Z_AXIS,		/* not used, yet */
+    SECOND_Y_AXIS,
+    SECOND_X_AXIS,
+    R_AXIS,			/* never used ? */
+    U_AXIS,			/* dito */
+    V_AXIS			/* dito */
+#ifdef PM3D
+    ,COLOR_AXIS
+#endif
+} AXIS_INDEX ;
+
+#ifdef PM3D
+# define AXIS_ARRAY_SIZE 11
+#else
+# define AXIS_ARRAY_SIZE 10
+#endif
+
+
+/* What kind of ticmarking is wanted? */
+typedef enum en_ticseries_type {
+    TIC_COMPUTED=1, 		/* default; gnuplot figures them */
+    TIC_SERIES,			/* user-defined series */
+    TIC_USER,			/* user-defined points */
+    TIC_MONTH,   		/* print out month names ((mo-1)%12)+1 */
+    TIC_DAY      		/* print out day of week */
+} t_ticseries_type;
+
+/* Defines one ticmark for TIC_USER style.
+ * If label==NULL, the value is printed with the usual format string.
+ * else, it is used as the format string (note that it may be a constant
+ * string, like "high" or "low").
+ */
+typedef struct ticmark {
+    double position;		/* where on axis is this */
+    char *label;		/* optional (format) string label */
+    struct ticmark *next;	/* linked list */
+} ticmark;
+
+/* Tic-mark labelling definition; see set xtics */
+typedef struct ticdef {
+    t_ticseries_type type;	
+    union {
+	   struct ticmark *user;	/* for TIC_USER */
+	   struct {			/* for TIC_SERIES */
+		  double start, incr;
+		  double end;		/* ymax, if VERYLARGE */
+	   } series;
+    } def;
+} t_ticdef;
+
+/* we want two auto modes for minitics - default where minitics are
+ * auto for log/time and off for linear, and auto where auto for all
+ * graphs I've done them in this order so that logscale-mode can
+ * simply test bit 0 to see if it must do the minitics automatically.
+ * similarly, conventional plot can test bit 1 to see if minitics are
+ * required */
+enum en_minitics_status {
+    MINI_OFF,
+    MINI_DEFAULT,
+    MINI_USER,
+    MINI_AUTO
+};
+
+/* Function pointer type for callback functions doing operations for a
+ * single ticmark */
+/*typedef void (*tic_callback) __PROTO((AXIS_INDEX, double, char *, struct lp_style_type ));*/
+
+/* Values to put in the axis_tics[] variables that decides where the
+ * ticmarks should be drawn: not at all, on one or both plot borders,
+ * or the zeroaxes. These look like a series of values, but TICS_MASK
+ * shows that they're actually bit masks --> don't turn into an enum
+ * */
+#define NO_TICS        0
+#define TICS_ON_BORDER 1
+#define TICS_ON_AXIS   2
+#define TICS_MASK      3
+#define TICS_MIRROR    4
+
+
+/* Need to allow user to choose grid at first and/or second axes tics.
+ * Also want to let user choose circles at x or y tics for polar grid.
+ * Also want to allow user rectangular grid for polar plot or polar
+ * grid for parametric plot. So just go for full configurability.
+ * These are bitmasks
+ */
+#define GRID_OFF    0
+#define GRID_X      (1<<0)
+#define GRID_Y      (1<<1)
+#define GRID_Z      (1<<2)
+#define GRID_X2     (1<<3)
+#define GRID_Y2     (1<<4)
+#define GRID_MX     (1<<5)
+#define GRID_MY     (1<<6)
+#define GRID_MZ     (1<<7)
+#define GRID_MX2    (1<<8)
+#define GRID_MY2    (1<<9)
+/* GRID_{M}CB only for PM3D, but defined always for source code readability */
+#define GRID_CB     (1<<10)
+#define GRID_MCB    (1<<11)
+
+/* HBB 20010610: new type for storing autoscale activity. Effectively
+ * two booleans (bits) in a single variable, so I'm using an enum with
+ * all 4 possible bit masks given readable names. */
+typedef enum e_autoscale {
+    AUTOSCALE_NONE = 0,
+    AUTOSCALE_MIN = 1<<0,
+    AUTOSCALE_MAX = 1<<1,
+    AUTOSCALE_BOTH = (1<<0 | 1 << 1),
+    AUTOSCALE_FIXMIN = 1<<2,
+    AUTOSCALE_FIXMAX = 1<<3
+} t_autoscale;
+
+
+/* HBB 20000725: gather all per-axis variables into a struct, and set up
+ * a single large array of such structs */
+/* FIXME 20000725: collect some of those various TBOOLEAN fields into
+ * a larger int (or -- shudder -- a bitfield?) */
+typedef struct axis {
+/* range of this axis */
+    t_autoscale autoscale;	/* Which end(s) are autoscaled? */
+    t_autoscale set_autoscale;	/* what does 'set' think autoscale to be? */
+    int range_flags;		/* flag bits about autoscale/writeback: */
+    /* write auto-ed ranges back to variables for autoscale */
+#define RANGE_WRITEBACK 1	
+    /* allow auto and reversed ranges */
+#define RANGE_REVERSE   2	
+    TBOOLEAN reverse_range;	/* range [high:low] silently reverted? */
+    double min;			/* 'transient' axis extremal values */
+    double max;
+    double set_min;		/* set/show 'permanent' values */
+    double set_max;
+    double writeback_min;	/* ULIG's writeback implementation */
+    double writeback_max;
+
+/* output-related quantities */
+    int term_lower;		/* low and high end of the axis on output, */
+    int term_upper;		/* ... (in terminal coordinates)*/
+    double term_scale;		/* scale factor: plot --> term coords */
+    unsigned int term_zero;	/* position of zero axis */
+
+/* log axis control */
+    TBOOLEAN log;		/* log axis stuff: flag "islog?" */
+    double base;		/* logarithm base value */
+    double log_base;		/* ln(base), for easier computations */
+
+/* time/date axis control */
+    TBOOLEAN is_timedata;	/* is this a time/date axis? */
+    TBOOLEAN format_is_numeric;	/* format string looks like numeric??? */
+    char timefmt[MAX_ID_LEN+1];	/* format string for input */
+    char formatstring[MAX_ID_LEN+1];
+				/* the format string for output */
+
+/* ticmark control variables */
+    int ticmode;		/* tics on border/axis? mirrored? */
+    struct ticdef ticdef;	/* tic series definition */
+    TBOOLEAN tic_rotate;	/* ticmarks rotated (vertical text)? */
+    int minitics;		/* minor tic mode (none/auto/user)? */
+    double mtic_freq;		/* minitic stepsize */
+
+/* other miscellaneous fields */
+    label_struct label;		/* label string and position offsets */
+  /*lp_style_type zeroaxis;*/	/* drawing style for zeroaxis, if any */
+} AXIS;
+
+#define DEFAULT_AXIS_TICDEF {TIC_COMPUTED, {NULL} }
+#ifdef PM3D
+# define DEFAULT_AXIS_ZEROAXIS {0, -3, 0, 1.0, 1.0, 0}
+#else
+# define DEFAULT_AXIS_ZEROAXIS {0, -3, 0, 1.0, 1.0}
+#endif
+#define DEFAULT_AXIS_STRUCT {						    \
+	AUTOSCALE_BOTH, AUTOSCALE_BOTH, /* auto, set_auto */		    \
+	0, FALSE,		/* range_flags, rev_range */		    \
+	-10.0, 10.0,		/* 3 pairs of min/max */		    \
+	-10.0, 10.0,							    \
+	-10.0, 10.0,							    \
+	0, 0, 0, 0,		/* terminal dependents */		    \
+	FALSE, 0.0, 0.0,	/* log, base, log(base) */		    \
+	0, 1,			/* is_timedata, format_numeric */	    \
+	DEF_FORMAT, TIMEFMT,	/* output format, timefmt */		    \
+	NO_TICS,		/* tic output positions (border, mirror) */ \
+	DEFAULT_AXIS_TICDEF,	/* tic series definition */		    \
+	FALSE, MINI_DEFAULT, 10, /* tic_rotate, minitics, mtic_freq */	    \
+	EMPTY_LABELSTRUCT/**,**/	/* axis label */			    \
+	/**DEFAULT_AXIS_ZEROAXIS**/}	/* zeroaxis line style */
+
+/* Table of default behaviours --- a subset of the struct above. Only
+ * those fields are present that differ from axis to axis. */
+typedef struct axis_defaults {
+    double min;			/* default axis endpoints */
+    double max;
+    char name[4];		/* axis name, like in "x2" or "t" */
+    int ticmode;		/* tics on border/axis? mirrored? */
+} AXIS_DEFAULTS;
+
+
+
+/* global variables in axis.c */
+
+extern AXIS axis_array[AXIS_ARRAY_SIZE];
+extern AXIS_DEFAULTS axis_defaults[AXIS_ARRAY_SIZE];
+
+/* A parsing table for mapping axis names into axis indices. For use
+ * by the set/show machinery, mainly */
+extern struct gen_table axisname_tbl[AXIS_ARRAY_SIZE+1];
+
+
+extern const struct ticdef default_axis_ticdef;
+
+extern double ticscale;		/* scale factor for tic marks (was (0..1])*/
+extern double miniticscale;	/* and for minitics */
+extern TBOOLEAN	tic_in;		/* tics to be drawn inward?  */
+
+
+/* default format for tic mark labels */
+#define DEF_FORMAT "% g"
+
+/* default parse timedata string */
+#define TIMEFMT "%d/%m/%y,%H:%M"
+
+/* axis labels */
+extern const label_struct default_axis_label;
+
+/* zeroaxis linetype (flag type==-3 if none wanted) */
+
+/***extern const lp_style_type default_axis_zeroaxis;***/
+
+/* grid drawing control variables */
+extern int grid_selection;
+/***extern const struct lp_style_type default_grid_lp;***/ /* default for 'unset' */
+/***extern struct lp_style_type grid_lp;***/ /* linestyle for major grid lines */
+/***extern struct lp_style_type mgrid_lp;***/ /* linestyle for minor grid lines */
+/***extern double polar_grid_angle;***/ /* angle step in polar grid in radians */
+
+/* global variables for communication with the tic callback functions */
+
+extern int tic_start, tic_direction, tic_text,
+    rotate_tics, tic_hjust, tic_vjust, tic_mirror;
+
+/* axes being used by the current plot */
+extern AXIS_INDEX x_axis, y_axis, z_axis;
+/* macros to reduce code clutter caused by the array notation, mainly
+ * in graphics.c and fit.c */
+#define X_AXIS axis_array[x_axis]
+#define Y_AXIS axis_array[y_axis]
+#define Z_AXIS axis_array[z_axis]
+#ifdef PM3D
+#define CB_AXIS axis_array[COLOR_AXIS]
+#endif
+
+/* -------- macros using these variables: */
+
+/* Macros to map from user to terminal coordinates and back */
+#define AXIS_MAP(axis, variable)		\
+  (int) ((axis_array[axis].term_lower)		\
+	 + ((variable) - axis_array[axis].min)	\
+	 * axis_array[axis].term_scale + 0.5)
+#define AXIS_MAPBACK(axis, pos)						   \
+  (((double)(pos)-axis_array[axis].term_lower)/axis_array[axis].term_scale \
+   + axis_array[axis].min)
+
+/* these are the old names for these: */
+#define map_x(x) AXIS_MAP(x_axis, x)
+#define map_y(y) AXIS_MAP(y_axis, y)
+
+#define AXIS_SETSCALE(axis, out_low, out_high)			\
+    axis_array[axis].term_scale = ((out_high) - (out_low))	\
+        / (axis_array[axis].max - axis_array[axis].min)
+
+/* write current min/max_array contents into the set/show status
+ * variables */
+#define AXIS_WRITEBACK(axis)			\
+do {						\
+    AXIS *this = axis_array + axis;		\
+						\
+    if (this->range_flags & RANGE_WRITEBACK) {	\
+	if (this->autoscale & AUTOSCALE_MIN)	\
+	    this->set_min = this->min;		\
+	if (this->autoscale & AUTOSCALE_MAX)	\
+	    this->set_max = this->max;		\
+    }						\
+} while(0)
+
+/* HBB 20000430: New macros, logarithmize a value into a stored
+ * coordinate*/ 
+#define AXIS_DO_LOG(axis,value) (log(value) / axis_array[axis].log_base)
+#define AXIS_UNDO_LOG(axis,value) exp((value) * axis_array[axis].log_base)
+
+/* HBB 20000430: same, but these test if the axis is log, first: */
+#define AXIS_LOG_VALUE(axis,value)				\
+    (axis_array[axis].log ? AXIS_DO_LOG(axis,value) : (value))
+#define AXIS_DE_LOG_VALUE(axis,coordinate)				  \
+    (axis_array[axis].log ? AXIS_UNDO_LOG(axis,coordinate): (coordinate))
+ 
+
+/* copy scalar data to arrays. The difference between 3D and 2D
+ * versions is: dont know we have to support ranges [10:-10] - lets
+ * reverse it for now, then fix it at the end.  */
+/* FIXME HBB 20000426: unknown if this distinction makes any sense... */
+#define AXIS_INIT3D(axis, islog_override, infinite)			\
+do {									\
+    AXIS *this = axis_array + axis;					\
+									\
+    if ((this->autoscale = this->set_autoscale) == AUTOSCALE_NONE	\
+	&& this->set_max < this->set_min) {				\
+	this->min = this->set_max;					\
+	this->max = this->set_min;					\
+        /* we will fix later */						\
+    } else {								\
+	this->min = (infinite && (this->set_autoscale & AUTOSCALE_MIN))	\
+	    ? VERYLARGE : this->set_min;				\
+	this->max = (infinite && (this->set_autoscale & AUTOSCALE_MAX))	\
+	    ? -VERYLARGE : this->set_max;				\
+    }									\
+    if (islog_override) {						\
+	this->log = 0;							\
+	this->base = 1;							\
+	this->log_base = 0;						\
+    } else {								\
+	this->log_base = this->log ? log(this->base) : 0;		\
+    }									\
+} while(0)
+
+#define AXIS_INIT2D(axis, infinite)					\
+do {									\
+    AXIS *this = axis_array + axis;					\
+									\
+    this->autoscale = this->set_autoscale;				\
+    this->min = (infinite && (this->set_autoscale & AUTOSCALE_MIN))	\
+	? VERYLARGE : this->set_min;					\
+    this->max = (infinite && (this->set_autoscale & AUTOSCALE_MAX))	\
+	? -VERYLARGE : this->set_max;					\
+    this->log_base = this->log ? log(this->base) : 0;			\
+} while(0)
+
+/* handle reversed ranges */
+#define CHECK_REVERSE(axis)						\
+do {									\
+    AXIS *this = axis_array + axis;					\
+									\
+    if ((this->autoscale == AUTOSCALE_NONE)				\
+	&& (this->max < this->min)					\
+	) {								\
+	double temp = this->min;					\
+	this->min = this->max;						\
+	this->max = temp;						\
+	this->reverse_range = 1;					\
+    } else								\
+	this->reverse_range = (this->range_flags & RANGE_REVERSE);	\
+} while(0)
+
+/* HBB 20000725: new macro, built upon ULIG's SAVE_WRITEBACK(axis),
+ * but easier to use. Code like this occured twice, in plot2d and
+ * plot3d: */
+#define SAVE_WRITEBACK_ALL_AXES					\
+do {								\
+    AXIS_INDEX axis;						\
+								\
+    for (axis = 0; axis < AXIS_ARRAY_SIZE; axis++)		\
+	if(axis_array[axis].range_flags & RANGE_WRITEBACK) {	\
+	    set_writeback_min(axis);				\
+	    set_writeback_max(axis);				\
+	}							\
+} while(0)
+	    
+/* get optional [min:max] */
+#define PARSE_RANGE(axis)						   \
+do {									   \
+    if (equals(c_token, "[")) {						   \
+	c_token++;							   \
+	axis_array[axis].autoscale =					   \
+	    load_range(axis, &axis_array[axis].min, &axis_array[axis].max, \
+		       axis_array[axis].autoscale);			   \
+	if (!equals(c_token, "]"))					   \
+	    int_error(c_token, "']' expected");				   \
+	c_token++;							   \
+    }									   \
+} while (0)
+
+/* HBB 20000430: new macro, like PARSE_RANGE, but for named ranges as
+ * in 'plot [phi=3.5:7] sin(phi)' */
+#define PARSE_NAMED_RANGE(axis, dummy_token)				     \
+do {									     \
+    if (equals(c_token, "[")) {						     \
+	c_token++;							     \
+	if (isletter(c_token)) {					     \
+	    if (equals(c_token + 1, "=")) {				     \
+		dummy_token = c_token;					     \
+		c_token += 2;						     \
+	    }								     \
+		/* oops; probably an expression with a variable: act	     \
+		 * as if no variable name had been seen, by		     \
+		 * fallthrough */					     \
+	}								     \
+	axis_array[axis].autoscale = load_range(axis, &axis_array[axis].min, \
+				      &axis_array[axis].max,		     \
+				      axis_array[axis].autoscale);	     \
+	if (!equals(c_token, "]"))					     \
+	    int_error(c_token, "']' expected");				     \
+	c_token++;							     \
+    }				/* first '[' */				     \
+} while (0)
+
+/* parse a position of the form
+ *    [coords] x, [coords] y {,[coords] z}
+ * where coords is one of first,second.graph,screen
+ * if first or second, we need to take axis_is_timedata into account
+ */
+#define GET_NUMBER_OR_TIME(store,axes,axis)				\
+do {									\
+    if (((axes) >= 0) && (axis_array[(axes)+(axis)].is_timedata)	\
+	&& isstring(c_token)) {						\
+	char ss[80];							\
+	struct tm tm;							\
+	quote_str(ss,c_token, 80);					\
+	++c_token;							\
+	if (gstrptime(ss,axis_array[axis].timefmt,&tm))			\
+	    (store) = (double) gtimegm(&tm);				\
+    } else {								\
+	struct value value;						\
+	(store) = real(const_express(&value));				\
+    }									\
+} while(0)
+
+/* This is one is very similar to GET_NUMBER_OR_TIME, but has slightly
+ * different usage: it writes out '0' in case of inparsable time data,
+ * and it's used when the target axis is fixed without a 'first' or
+ * 'second' keyword in front of it. */
+#define GET_NUM_OR_TIME(store,axis)			\
+do {							\
+    (store) = 0;					\
+    GET_NUMBER_OR_TIME(store, FIRST_AXES, axis);	\
+} while (0);
+
+/* store VALUE or log(VALUE) in STORE, set TYPE as appropriate
+ * Do OUT_ACTION or UNDEF_ACTION as appropriate
+ * adjust range provided type is INRANGE (ie dont adjust y if x is outrange
+ * VALUE must not be same as STORE
+ */
+
+#define STORE_WITH_LOG_AND_UPDATE_RANGE(STORE, VALUE, TYPE, AXIS,	  \
+				       OUT_ACTION, UNDEF_ACTION)	  \
+do {									  \
+    /* HBB 20000726: new check, to avoid crashes with axis index -1 */	  \
+    if (AXIS==-1)							  \
+	break;								  \
+    if (axis_array[AXIS].log) {						  \
+	if (VALUE<0.0) {						  \
+	    TYPE = UNDEFINED;						  \
+	    UNDEF_ACTION;						  \
+	    break;							  \
+	} else if (VALUE == 0.0) {					  \
+	    STORE = -VERYLARGE;						  \
+	    TYPE = OUTRANGE;						  \
+	    OUT_ACTION;							  \
+	    break;							  \
+	} else {							  \
+	    STORE = AXIS_DO_LOG(AXIS,VALUE);				  \
+	}								  \
+    } else								  \
+	STORE = VALUE;							  \
+    if (TYPE != INRANGE)						  \
+	break;  /* don't set y range if x is outrange, for example */	  \
+    if ((int)AXIS < 0)							  \
+	break;	/* HBB 20000507: don't check range if not a coordinate */ \
+    if ( VALUE<axis_array[AXIS].min ) {					  \
+	if (axis_array[AXIS].autoscale & AUTOSCALE_MIN)			  \
+	    axis_array[AXIS].min = VALUE;				  \
+	else {								  \
+	    TYPE = OUTRANGE;						  \
+	    OUT_ACTION;							  \
+	    break;							  \
+	}								  \
+    }									  \
+    if ( VALUE>axis_array[AXIS].max ) {					  \
+	if (axis_array[AXIS].autoscale & AUTOSCALE_MAX)			  \
+	    axis_array[AXIS].max = VALUE;				  \
+	else {								  \
+	    TYPE = OUTRANGE;						  \
+	    OUT_ACTION;							  \
+	}								  \
+    }									  \
+} while(0)
+
+/* use this instead empty macro arguments to work around NeXT cpp bug */
+/* if this fails on any system, we might use ((void)0) */
+#define NOOP			/* */
+
+/* HBB 20000506: new macro, initializes one variable to the same
+ * value, for all axes. */
+#define INIT_AXIS_ARRAY(field, value)		\
+do {						\
+    int tmp;					\
+    for (tmp=0; tmp<AXIS_ARRAY_SIZE; tmp++)	\
+	axis_array[tmp].field=(value);		\
+} while(0)
+
+/* HBB 20000506: new macro to automatically build intializer lists
+ * for arrays of AXIS_ARRAY_SIZE equal elements */
+#ifdef PM3D
+#define AXIS_ARRAY_INITIALIZER(value) {			\
+    value, value, value, value, value,			\
+	value, value, value, value, value /*, value*/ }
+#else
+#define AXIS_ARRAY_INITIALIZER(value) {		\
+    value, value, value, value, value,		\
+	value, value, value, value, value }
+#endif
+
+
+/* used by set.c */
+#define SET_DEFFORMAT(axis, flag_array)				\
+	if (flag_array[axis]) {					\
+	    (void) strcpy(axis_array[axis].formatstring,DEF_FORMAT);	\
+	    axis_array[axis].format_is_numeric = 1;		\
+	}
+
+
+/* 'roundoff' check tolerance: less than one hundredth of a tic mark */
+#define SIGNIF (0.01)
+/* (DFK) Watch for cancellation error near zero on axes labels */
+/* FIXME HBB 20000521: these seem not to be used much, anywhere... */
+#define CheckZero(x,tic) (fabs(x) < ((tic) * SIGNIF) ? 0.0 : (x))
+#define NearlyEqual(x,y,tic) (fabs((x)-(y)) < ((tic) * SIGNIF))
+
+
+	
+/* ------------ functions exported by axis.c */
+/*t_autoscale load_range __PROTO((AXIS_INDEX, double *, double *, t_autoscale));*/
+void axis_unlog_interval(AXIS_INDEX, double *, double *, TBOOLEAN);
+/*void axis_revert_and_unlog_range __PROTO((AXIS_INDEX));*/
+/*double axis_log_value_checked __PROTO((AXIS_INDEX, double, const char *));*/
+/*void axis_checked_extend_empty_range __PROTO((AXIS_INDEX, const char *mesg));*/
+/*void   timetic_format __PROTO((AXIS_INDEX, double, double));*/
+double set_tic(double, int); 
+/*void setup_tics __PROTO((AXIS_INDEX, int));*/
+/*void gen_tics __PROTO((AXIS_INDEX, int, tic_callback));*/
+/*void gprintf __PROTO((char *, size_t, char *, double, double));*/
+/*void axis_output_tics __PROTO((AXIS_INDEX, int *, AXIS_INDEX, int, tic_callback));*/
+/*void axis_set_graphical_range __PROTO((AXIS_INDEX, unsigned int lower, unsigned int upper));*/
+/*TBOOLEAN axis_position_zeroaxis __PROTO((AXIS_INDEX));*/
+/*void axis_draw_2d_zeroaxis __PROTO((AXIS_INDEX, AXIS_INDEX)); */
+
+/*double get_writeback_min __PROTO((AXIS_INDEX));*/
+/*double get_writeback_max __PROTO((AXIS_INDEX));*/
+/*void set_writeback_min __PROTO((AXIS_INDEX));*/
+/*void set_writeback_max __PROTO((AXIS_INDEX));*/
+
+#endif /* GNUPLOT_AXIS_H */
Index: /tags/V_Dec2002/SophyaPI/PIGcont/gp_contour.c
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIGcont/gp_contour.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIGcont/gp_contour.c	(revision 2309)
@@ -0,0 +1,1621 @@
+/* GNUPLOT - contour.c */
+
+/*[
+ * Copyright 1986 - 1993, 1998   Thomas Williams, Colin Kelley
+ *
+ * Permission to use, copy, and distribute this software and its
+ * documentation for any purpose with or without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.
+ *
+ * Permission to modify the software is granted, but not the right to
+ * distribute the complete modified source code.  Modifications are to
+ * be distributed as patches to the released version.  Permission to
+ * distribute binaries produced by compiling modified sources is granted,
+ * provided you
+ *   1. distribute the corresponding source modifications from the
+ *    released version in the form of a patch file along with the binaries,
+ *   2. add special version identification to distinguish your version
+ *    in addition to the base release version number,
+ *   3. provide your name and address as the primary contact for the
+ *    support of your modified version, and
+ *   4. retain our contact information in regard to use of the base
+ *    software.
+ * Permission to distribute the released version of the source code along
+ * with corresponding source modifications in the form of a patch file is
+ * granted with same provisions 2 through 4 for binary distributions.
+ *
+ * This software is provided "as is" without express or implied warranty
+ * to the extent permitted by applicable law.
+]*/
+
+ 
+/* 
+ * AUTHORS
+ * 
+ *   Original Software:
+ *       Gershon Elber
+ * 
+ *   Improvements to the numerical algorithms:
+ *        Hans-Martin Keller, 1995,1997 (hkeller@gwdg.de)
+ *
+ *   Quelques modifs (adaptation pour SOPHYA/PEIDA) O. PErdereau 11/2001
+ */
+
+#include "gp_contour.h"
+
+#include "gp_alloc.h"
+#include "gp_axis.h"
+
+#include <sys/time.h>
+#include <sys/resource.h>
+
+/*  #include "setshow.h" */
+
+/* exported variables (to be handled by the 'set' and friends): */
+
+char contour_format[32] = "%8.3g";	/* format for contour key entries */
+static t_contour_kind contour_kind = CONTOUR_KIND_LINEAR;
+static t_contour_levels_kind contour_levels_kind = LEVELS_AUTO;
+static int contour_levels = DEFAULT_CONTOUR_LEVELS;
+static int contour_order = DEFAULT_CONTOUR_ORDER;
+static int contour_pts = DEFAULT_NUM_APPROX_PTS;
+
+static dynarray dyn_contour_levels_list;/* storage for z levels to draw contours at */
+static double * contour_levels_list=NULL;
+
+/* position of edge in mesh */
+typedef enum en_edge_position {
+    INNER_MESH=1,
+    BOUNDARY,
+    DIAGONAL
+} t_edge_position;
+
+
+/* Valeur de zero - Reza 21/12/2001 - Pourquoi zero = 0. ??? */
+        double zero = 0.;
+
+/* FIXME HBB 2000052: yet another local copy of 'epsilon'. Why? */
+#define EPSILON  1e-5		/* Used to decide if two float are equal. */
+
+
+#ifndef TRUE
+#define TRUE     -1
+#define FALSE    0
+#endif
+
+
+#define MAX_POINTS_PER_CNTR 	100
+
+#define SQR(x)  ((x) * (x))
+
+/*
+ * struct vrtx_struct {
+ *      double X, Y, Z;
+ *      struct vrtx_struct *next;
+ * };
+ * 
+ * replaced by 'struct coordinate  ', see plot.h (HMK 1997) 
+ */
+
+struct edge_struct {
+    struct poly_struct *poly[2]; /* Each edge belongs to up to 2 polygons */
+    struct coordinate  *vertex[2]; /* The two extreme points of this edge. */
+    struct edge_struct *next;	/* To chain lists */
+    TBOOLEAN is_active;		/* is edge is 'active' at certain Z level? */
+    t_edge_position position;	/* position of edge in mesh */
+};
+
+struct poly_struct {
+    struct edge_struct *edge[3];	/* As we do triangolation here... */
+    struct poly_struct *next;	/* To chain lists. */
+};
+
+struct cntr_struct {		/* Contours are saved using this struct list. */
+    double X, Y;		/* The coordinates of this vertex. */
+    struct cntr_struct *next;	/* To chain lists. */
+};
+
+static struct gnuplot_contours *contour_list = NULL;
+static double crnt_cntr[MAX_POINTS_PER_CNTR * 2];
+static int crnt_cntr_pt_index = 0;
+static double contour_level = 0.0;
+
+/* Linear, Cubic interp., Bspline: */
+static t_contour_kind interp_kind = CONTOUR_KIND_LINEAR;
+
+static double x_min, y_min, z_min;	/* Minimum values of x, y, and z */
+static double x_max, y_max, z_max;	/* Maximum values of x, y, and z */
+
+static void add_cntr_point (double x, double y);
+static void end_crnt_cntr (void);
+static void gen_contours(struct edge_struct * p_edges, double z_level,
+				  double xx_min, double xx_max, double yy_min, double yy_max);
+static int update_all_edges(struct edge_struct * p_edges,
+				     double z_level);
+static struct cntr_struct *gen_one_contour (
+						       struct edge_struct * p_edges, double
+						       z_level, TBOOLEAN *contr_isclosed,
+						       int *num_active);
+static struct cntr_struct *trace_contour (
+						     struct edge_struct * pe_start, double
+						     z_level, int *num_active,
+						     TBOOLEAN contr_isclosed);
+static struct cntr_struct *update_cntr_pt (struct edge_struct * p_edge,
+						   double z_level);
+static int fuzzy_equal (struct cntr_struct * p_cntr1,
+				struct cntr_struct * p_cntr2);
+
+
+static void gen_triangle (int num_isolines,
+				  struct iso_curve * iso_lines, struct poly_struct ** p_polys,
+				  struct edge_struct ** p_edges);
+static void calc_min_max (int num_isolines,
+				  struct iso_curve * iso_lines, double *xx_min, double *yy_min,
+				  double *zz_min,
+				  double *xx_max, double *yy_max, double *zz_max);
+static struct edge_struct *add_edge (struct coordinate  * point0,
+					     struct coordinate  * point1, struct edge_struct
+					     ** p_edge,
+					     struct edge_struct ** pe_tail);
+static struct poly_struct *add_poly (struct edge_struct * edge0,
+					     struct edge_struct * edge1, struct edge_struct * edge2,
+					     struct poly_struct ** p_poly, struct poly_struct ** pp_tail);
+
+
+static void put_contour (struct cntr_struct * p_cntr, double z_level,
+				 double xx_min, double xx_max, double yy_min, double yy_max,
+		 		 TBOOLEAN contr_isclosed);
+static void put_contour_nothing (struct cntr_struct * p_cntr);
+static int chk_contour_kind (struct cntr_struct * p_cntr,
+				     TBOOLEAN contr_isclosed);
+static void put_contour_cubic (struct cntr_struct * p_cntr,
+				       double z_level, double xx_min, double xx_max, double
+				       yy_min, double yy_max,
+				       TBOOLEAN contr_isclosed);
+static void put_contour_bspline (struct cntr_struct * p_cntr,
+					 double z_level, double xx_min, double xx_max, double
+					 yy_min, double yy_max,
+					 TBOOLEAN contr_isclosed);
+static void free_contour (struct cntr_struct * p_cntr);
+static int count_contour (struct cntr_struct * p_cntr);
+static int gen_cubic_spline (int num_pts, struct cntr_struct * p_cntr,
+				     double d2x[], double d2y[], double delta_t[], TBOOLEAN contr_isclosed,
+				     double unit_x, double unit_y);
+static void intp_cubic_spline (int n, struct cntr_struct * p_cntr,
+				       double d2x[], double d2y[], double delta_t[], int n_intpol);
+static int solve_cubic_1 (tri_diag m[], int n);
+static void solve_cubic_2 (tri_diag m[], double x[], int n);
+static void gen_bspline_approx (struct cntr_struct * p_cntr,
+					int num_of_points, int order, TBOOLEAN contr_isclosed);
+static void eval_bspline (double t, struct cntr_struct * p_cntr,
+				  int num_of_points, int order, int j, TBOOLEAN contr_isclosed, double *x,
+				  double *y);
+static double fetch_knot (TBOOLEAN contr_isclosed, int num_of_points,
+				  int order, int i);
+
+
+static int num_of_z_levels;/*_____ OP ___________*/	/* # Z contour levels. */
+
+int Get_Num_Of_Z_Levels(){
+return num_of_z_levels;
+} /* OP       __________ */
+
+/*
+ * Entry routine to this whole set of contouring module.
+ */
+struct gnuplot_contours *
+contour(num_isolines, iso_lines)
+int num_isolines;
+struct iso_curve *iso_lines;
+{
+    struct rusage r_usage;
+    int rcus;
+ 
+    int i;
+    /*OP    int num_of_z_levels;*/	/* # Z contour levels. */
+    struct poly_struct *p_polys, *p_poly;
+    struct edge_struct *p_edges, *p_edge;
+    double z = 0, dz = 0;
+    struct gnuplot_contours *save_contour_list;
+
+    num_of_z_levels = contour_levels;
+    interp_kind = contour_kind;
+
+    contour_list = NULL;
+    /******* DEBUG ********
+    rcus = getrusage( RUSAGE_SELF , &r_usage);
+    if(rcus==0) 
+      printf("contour[1] / rusage -> %ld , %ld , %ld \n",  r_usage.ru_maxrss , r_usage.ru_ixrss , r_usage.ru_ixrss);
+    else
+      perror("contour/1er appel");
+    *************/
+    /* 
+     * Calculate min/max values :
+     */
+    calc_min_max(num_isolines, iso_lines,
+		 &x_min, &y_min, &z_min, &x_max, &y_max, &z_max);
+
+
+    dz = fabs(z_max - z_min);
+    /* 
+     *  printf(" contour z_max %g z_min %g dz=%g kind %d   \n",z_max, z_min , dz,contour_levels_kind);
+     * Generate list of edges (p_edges) and list of triangles (p_polys):
+     */
+
+    gen_triangle(num_isolines, iso_lines, &p_polys, &p_edges);
+    crnt_cntr_pt_index = 0;
+
+
+    /*AJOUT OP */
+    if (contour_levels_kind == LEVELS_NUM) {
+	dz = fabs(z_max - z_min)/(num_of_z_levels);
+	z = z_min - dz/2.;
+    }
+
+    if (contour_levels_kind == LEVELS_AUTO) {
+	dz = fabs(z_max - z_min);
+	/*printf(" contour z_max %g z_min %g dz=%g\n",z_max, z_min , dz);*/
+	if (dz == 0)
+	    return NULL;	/* empty z range ? */
+	/* what is the deeper sense of this ? (joze) */
+	dz = set_tic(log10(dz), ((int) contour_levels + 1) * 2);
+	z = floor(z_min / dz) * dz;
+	num_of_z_levels = (int) floor((z_max - z) / dz);
+        /*printf("contour() : num_of_z_levels %d\n",num_of_z_levels);*/
+    }
+    for (i = 0; i < num_of_z_levels; i++) {
+	switch (contour_levels_kind) {
+	case LEVELS_AUTO:
+	case LEVELS_NUM:
+	    z += dz;
+	    break;
+	case LEVELS_INCREMENTAL:
+	    z = contour_levels_list[0] + i * contour_levels_list[1];
+	    break;
+	case LEVELS_DISCRETE:
+	  /*printf("????? contour z=%f\n",contour_levels_list[i] );*/
+	    /*z = AXIS_LOG_VALUE(FIRST_Z_AXIS, contour_levels_list[i]); PAS BESOIN ? OP */
+	    z = contour_levels_list[i];
+	    break;
+	}
+	contour_level = z;
+	/*printf(" contour z=%f\n",z);*/
+	save_contour_list = contour_list;
+	gen_contours(p_edges, z, x_min, x_max, y_min, y_max);
+	if (contour_list != save_contour_list) {
+	    contour_list->isNewLevel = 1;
+	    sprintf(contour_list->label, contour_format, AXIS_DE_LOG_VALUE(FIRST_Z_AXIS,z));
+#ifdef PM3D
+	    contour_list->z = AXIS_DE_LOG_VALUE(FIRST_Z_AXIS, z);
+#endif
+	}
+    }
+
+    /* Free all contouring related temporary data. */ 
+    while (p_polys) {
+        
+	p_poly = p_polys->next;
+	free(p_polys);
+	p_polys = p_poly; 
+    }
+
+
+    while (p_edges) {        
+	p_edge = p_edges->next;
+	free(p_edges);
+	p_edges = p_edge;
+    }
+    /*********DEBUG 
+    rcus = getrusage( RUSAGE_SELF , &r_usage);
+    if(rcus==0) 
+      printf("contour[5] / rusage -> %ld , %ld , %ld \n",  r_usage.ru_maxrss , r_usage.ru_ixrss , r_usage.ru_ixrss);
+    else
+      perror("contour / 5eme appel");
+    rcus = getrusage( RUSAGE_SELF , &r_usage);
+    ********/
+
+    return contour_list;
+}
+
+/*
+ * Adds another point to the currently build contour.
+ */
+static void
+add_cntr_point(x, y)
+double x, y;
+{
+    int index;
+
+    if (crnt_cntr_pt_index >= MAX_POINTS_PER_CNTR - 1) {
+	index = crnt_cntr_pt_index - 1;
+	end_crnt_cntr();
+	crnt_cntr[0] = crnt_cntr[index * 2];
+	crnt_cntr[1] = crnt_cntr[index * 2 + 1];
+	crnt_cntr_pt_index = 1;	/* Keep the last point as first of this one. */
+    }
+    crnt_cntr[crnt_cntr_pt_index * 2] = x;
+    crnt_cntr[crnt_cntr_pt_index * 2 + 1] = y;
+    crnt_cntr_pt_index++;
+}
+ 
+/*
+ * Done with current contour - create gnuplot data structure for it.
+ */
+static void
+end_crnt_cntr()
+{
+    int i;
+    struct gnuplot_contours *cntr = (struct gnuplot_contours *)
+    gp_alloc(sizeof(struct gnuplot_contours), "gnuplot_contour");
+    cntr->coords = (struct coordinate  *)
+	gp_alloc(sizeof(struct coordinate) * crnt_cntr_pt_index,
+		 "contour coords");
+
+    for (i = 0; i < crnt_cntr_pt_index; i++) {
+	cntr->coords[i].x = crnt_cntr[i * 2];
+	cntr->coords[i].y = crnt_cntr[i * 2 + 1];
+	cntr->coords[i].z = contour_level;
+    }
+    cntr->num_pts = crnt_cntr_pt_index;
+
+    cntr->next = contour_list;
+    contour_list = cntr;
+    contour_list->isNewLevel = 0;
+
+    crnt_cntr_pt_index = 0;
+}
+
+/*
+ * Generates all contours by tracing the intersecting triangles.
+ */
+static void
+gen_contours(p_edges, z_level, xx_min, xx_max, yy_min, yy_max)
+struct edge_struct *p_edges;
+double z_level, xx_min, xx_max, yy_min, yy_max;
+{
+    int num_active;		/* Number of edges marked ACTIVE. */
+    TBOOLEAN contr_isclosed;	/* Is this contour a closed line? */
+    struct cntr_struct *p_cntr;
+
+    num_active = update_all_edges(p_edges, z_level);	/* Do pass 1. */
+
+    contr_isclosed = FALSE;	/* Start to look for contour on boundaries. */
+    /*printf("<gen_contour> z=%g num_active %d \n",z_level,num_active);*/
+    while (num_active > 0) {	/* Do Pass 2. */
+	/* Generate One contour (and update MumActive as needed): */
+	p_cntr = gen_one_contour(p_edges, z_level, &contr_isclosed, &num_active);
+	if (p_cntr ==NULL) printf("<gen_contour> gen_one_contour retourne NULL \n");
+	/* Emit it in requested format: */
+	put_contour(p_cntr, z_level, xx_min, xx_max, yy_min, yy_max, contr_isclosed);
+    }
+}
+
+/*
+ * Does pass 1, or marks the edges which are active (crosses this z_level)
+ * Returns number of active edges (marked ACTIVE).
+ */
+static int
+update_all_edges(p_edges, z_level)
+struct edge_struct *p_edges;
+double z_level;
+{
+    int count = 0;
+
+    while (p_edges) {
+	/* use the same test at both vertices to avoid roundoff errors */
+        
+	if ((p_edges->vertex[0]->z >= z_level) !=
+	    (p_edges->vertex[1]->z >= z_level)) {
+	    p_edges->is_active = TRUE;
+	    count++;
+	} else
+	    p_edges->is_active = FALSE;
+	p_edges = p_edges->next;
+    }
+
+    return count;
+}
+
+/*
+ * Does pass 2, or find one complete contour out of the triangulation
+ * data base:
+ *
+ * Returns a pointer to the contour (as linked list), contr_isclosed
+ * tells if the contour is a closed line or not, and num_active is
+ * updated.  
+ */
+static struct cntr_struct *
+gen_one_contour(p_edges, z_level, contr_isclosed, num_active)
+struct edge_struct *p_edges;	/* list of edges input */
+double z_level;			/* Z level of contour input */
+TBOOLEAN *contr_isclosed;	/* open or closed contour, in/out */
+int *num_active;		/* number of active edges     in/out */
+{
+    struct edge_struct *pe_temp;
+    
+    if (! *contr_isclosed) {
+      /*printf("<gen_one_contour> contr_isclosed FALSE \n");*/
+	/* Look for something to start with on boundary: */
+	pe_temp = p_edges;
+	while (pe_temp) {
+	    if (pe_temp->is_active && (pe_temp->position == BOUNDARY))
+		break;
+	    pe_temp = pe_temp->next;
+	}
+	if (!pe_temp)
+	    *contr_isclosed = TRUE;	/* No more contours on boundary. */
+	else {
+	  /*printf("<gen_one_contour> contr_isclosed FALSE return \n");*/
+	    return trace_contour(pe_temp, z_level, num_active, *contr_isclosed);
+	}
+    }
+    if (*contr_isclosed) {
+	/* Look for something to start with inside: */
+      /*printf("<gen_one_contour> contr_isclosed TRUE \n");*/
+	pe_temp = p_edges;
+	while (pe_temp) {
+	    if (pe_temp->is_active && (pe_temp->position != BOUNDARY))
+		break;
+	    pe_temp = pe_temp->next;
+	}
+	if (!pe_temp) {
+	    *num_active = 0;
+	    fprintf(stderr, "gen_one_contour: no contour found\n");
+	    return NULL;
+	} else {
+	    *contr_isclosed = TRUE;
+	    return trace_contour(pe_temp, z_level, num_active, *contr_isclosed);
+	}
+    }
+    printf("<gen_one_contour> We should never be here, but lint... \n"); 
+    return NULL;		/* We should never be here, but lint... */
+}
+
+/*
+ * Search the data base along a contour starts at the edge pe_start until
+ * a boundary edge is detected or until we close the loop back to pe_start.
+ * Returns a linked list of all the points on the contour
+ * Also decreases num_active by the number of points on contour.
+ */
+static struct cntr_struct *
+trace_contour(pe_start, z_level, num_active, contr_isclosed)
+    struct edge_struct *pe_start; /* edge to start contour input */
+    double z_level;		/* Z level of contour input */
+    int *num_active;		/* number of active edges in/out */
+    TBOOLEAN contr_isclosed;	/* open or closed contour line (input) */
+{
+    struct cntr_struct *p_cntr, *pc_tail;
+    struct edge_struct *p_edge, *p_next_edge;
+    struct poly_struct *p_poly, *PLastpoly = NULL;
+    int i;
+
+    p_edge = pe_start;		/* first edge to start contour */
+
+    /* Generate the header of the contour - the point on pe_start. */
+    if (! contr_isclosed) {
+	pe_start->is_active = FALSE;
+	(*num_active)--;
+    }
+    if (p_edge->poly[0] || p_edge->poly[1]) {	/* more than one point */
+
+	p_cntr = pc_tail = update_cntr_pt(pe_start, z_level);	/* first point */
+
+	do {
+	    /* Find polygon to continue (Not where we came from - PLastpoly): */
+	    if (p_edge->poly[0] == PLastpoly)
+		p_poly = p_edge->poly[1];
+	    else
+		p_poly = p_edge->poly[0];
+	    p_next_edge = NULL;	/* In case of error, remains NULL. */
+	    for (i = 0; i < 3; i++)	/* Test the 3 edges of the polygon: */
+		if (p_poly->edge[i] != p_edge)
+		    if (p_poly->edge[i]->is_active)
+			p_next_edge = p_poly->edge[i];
+	    if (!p_next_edge) {	/* Error exit */
+		pc_tail->next = NULL;
+		free_contour(p_cntr);
+		fprintf(stderr, "trace_contour: unexpected end of contour\n");
+		return NULL;
+	    }
+	    p_edge = p_next_edge;
+	    PLastpoly = p_poly;
+	    p_edge->is_active = FALSE;
+	    (*num_active)--;
+
+	    /* Do not allocate contour points on diagonal edges */
+	    if (p_edge->position != DIAGONAL) {
+
+		pc_tail->next = update_cntr_pt(p_edge, z_level);
+
+		/* Remove nearby points */
+		if (fuzzy_equal(pc_tail, pc_tail->next)) {
+
+		    free((char *) pc_tail->next);
+		} else
+		    pc_tail = pc_tail->next;
+	    }
+	} while ((p_edge != pe_start) && (p_edge->position != BOUNDARY));
+
+	pc_tail->next = NULL;
+
+	/* For closed contour the first and last point should be equal */
+	if (pe_start == p_edge) {
+	    (p_cntr->X) = (pc_tail->X);
+	    (p_cntr->Y) = (pc_tail->Y);
+	}
+    } else {			/* only one point, forget it */
+	p_cntr = NULL;
+    }
+
+    return p_cntr;
+}
+
+/*
+ * Allocates one contour location and update it to to correct position
+ * according to z_level and edge p_edge.
+ */
+static struct cntr_struct *
+update_cntr_pt(p_edge, z_level)
+struct edge_struct *p_edge;
+double z_level;
+{
+    double t;
+    struct cntr_struct *p_cntr;
+
+    t = (z_level - p_edge->vertex[0]->z) /
+	(p_edge->vertex[1]->z - p_edge->vertex[0]->z);
+
+    /* test if t is out of interval [0:1] (should not happen but who knows ...) */
+    /*if(t>1) printf(" <update_cntr_pt> t >1 !\n");*/
+    /*if(t<0) printf(" <update_cntr_pt> t negatif !\n");*/
+    t = (t < 0.0 ? 0.0 : t);
+    t = (t > 1.0 ? 1.0 : t);
+    /*printf(" <update_cntr_pt> Point 0 %g %g %g \n",p_edge->vertex[0]->x,p_edge->vertex[0]->y,p_edge->vertex[0]->z);*/
+    /*printf(" <update_cntr_pt> Point 1 %g %g %g \n",p_edge->vertex[1]->x,p_edge->vertex[1]->y,p_edge->vertex[1]->z);*/
+    p_cntr = (struct cntr_struct *)
+	gp_alloc(sizeof(struct cntr_struct), "contour cntr_struct");
+
+    p_cntr->X = p_edge->vertex[1]->x * t +
+	p_edge->vertex[0]->x * (1 - t);
+    p_cntr->Y = p_edge->vertex[1]->y * t +
+	p_edge->vertex[0]->y * (1 - t);
+    /*printf(" <update_cntr_pt> p_cntr X %g Y %g \n",p_cntr->X,p_cntr->Y);*/
+    return p_cntr;
+}
+
+/* Simple routine to decide if two contour points are equal by
+ * calculating the relative error (< EPSILON).  */
+/* HBB 20010121: don't use absolute value 'zero' to compare to data
+ * values. */
+static int
+fuzzy_equal(p_cntr1, p_cntr2)
+    struct cntr_struct *p_cntr1, *p_cntr2;
+{
+    double unit_x, unit_y;
+    unit_x = fabs(x_max - x_min);		/* reference */
+    unit_y = fabs(y_max - y_min);
+    return ((fabs(p_cntr1->X - p_cntr2->X) < unit_x * EPSILON)
+	    && (fabs(p_cntr1->Y - p_cntr2->Y) < unit_y * EPSILON));
+}
+
+/*
+ * Generate the triangles.
+ * Returns the lists (edges & polys) via pointers to their heads.
+ */
+static void
+gen_triangle(num_isolines, iso_lines, p_polys, p_edges)
+int num_isolines;		/* number of iso-lines input */
+struct iso_curve *iso_lines;	/* iso-lines input */
+struct poly_struct **p_polys;	/* list of polygons output */
+struct edge_struct **p_edges;	/* list of edges output */
+{
+    int i, j, grid_x_max = iso_lines->p_count;
+    struct edge_struct *p_edge1, *p_edge2, *edge0, *edge1, *edge2, *pe_tail,
+	   *pe_tail2, *pe_temp;
+    struct poly_struct *pp_tail, *lower_tri, *upper_tri;
+    /* HBB 980308: need to tag *each* of them as ! */
+    struct coordinate  *p_vrtx1,  * p_vrtx2;
+
+    (*p_polys) = pp_tail = NULL;	/* clear lists */
+    (*p_edges) = pe_tail = NULL;
+
+    p_vrtx1 = iso_lines->points;	/* first row of vertices */
+    p_edge1 = pe_tail = NULL;	/* clear list of edges */
+
+    /* Generate edges of first row */
+    for (j = 0; j < grid_x_max - 1; j++)
+	add_edge(p_vrtx1 + j, p_vrtx1 + j + 1, &p_edge1, &pe_tail);
+
+    (*p_edges) = p_edge1;	/* update main list */
+
+
+    /*
+     * Combines vertices to edges and edges to triangles:
+     * ==================================================
+     * The edges are stored in the edge list, referenced by p_edges
+     * (pe_tail points on last edge).
+     *
+     * Temporary pointers:
+     * 1. p_edge2: Top horizontal edge list:      +-----------------------+ 2
+     * 2. p_tail : end of middle edge list:       |\  |\  |\  |\  |\  |\  |
+     *                                            |  \|  \|  \|  \|  \|  \|
+     * 3. p_edge1: Bottom horizontal edge list:   +-----------------------+ 1
+     *
+     * pe_tail2  : end of list beginning at p_edge2
+     * pe_temp   : position inside list beginning at p_edge1
+     * p_edges   : head of the master edge list (part of our output)
+     * p_vrtx1   : start of lower row of input vertices
+     * p_vrtx2   : start of higher row of input vertices
+     *
+     * The routine generates two triangle            Lower      Upper 1  
+     * upper one and lower one:                     | \           ----   
+     * (Nums. are edges order in polys)            0|   \1       0\   |2 
+     * The polygons are stored in the polygon        ----           \ |  
+     * list (*p_polys) (pp_tail points on             2                  
+     * last polygon).
+     *                                                        1
+     *                                                   -----------
+     * In addition, the edge lists are updated -        | \   0     |
+     * each edge has two pointers on the two            |   \       |
+     * (one active if boundary) polygons which         0|1   0\1   0|1
+     * uses it. These two pointer to polygons           |       \   |
+     * are named: poly[0], poly[1]. The diagram         |    1    \ |
+     * on the right show how they are used for the       -----------
+     * upper and lower polygons (INNER_MESH polygons only).  0
+     */
+
+    for (i = 1; i < num_isolines; i++) {
+	/* Read next column and gen. polys. */
+	iso_lines = iso_lines->next;
+
+	p_vrtx2 = iso_lines->points;	/* next row of vertices */
+	p_edge2 = pe_tail2 = NULL;	/* clear top horizontal list */
+	pe_temp = p_edge1;	/* pointer in bottom list */
+
+	/*
+	 * Generate edges and triagles for next row:
+	 */
+
+	/* generate first vertical edge */
+	edge2 = add_edge(p_vrtx1, p_vrtx2, p_edges, &pe_tail);
+
+	for (j = 0; j < grid_x_max - 1; j++) {
+
+	    /* copy vertical edge for lower triangle */
+	    edge0 = edge2;
+
+	    if (pe_temp && pe_temp->vertex[0] == p_vrtx1 + j) {
+		/* test lower edge */
+		edge2 = pe_temp;
+		pe_temp = pe_temp->next;
+	    } else {
+		edge2 = NULL;	/* edge is undefined */
+	    }
+
+	    /* generate diagonal edge */
+	    edge1 = add_edge(p_vrtx1 + j + 1, p_vrtx2 + j, p_edges, &pe_tail);
+	    if (edge1)
+		edge1->position = DIAGONAL;
+
+	    /* generate lower triangle */
+	    lower_tri = add_poly(edge0, edge1, edge2, p_polys, &pp_tail);
+
+	    /* copy diagonal edge for upper triangle */
+	    edge0 = edge1;
+
+	    /* generate upper edge */
+	    edge1 = add_edge(p_vrtx2 + j, p_vrtx2 + j + 1, &p_edge2, &pe_tail2);
+
+	    /* generate vertical edge */
+	    edge2 = add_edge(p_vrtx1 + j + 1, p_vrtx2 + j + 1, p_edges, &pe_tail);
+
+	    /* generate upper triangle */
+	    upper_tri = add_poly(edge0, edge1, edge2, p_polys, &pp_tail);
+	}
+
+	if (p_edge2) {
+	    /* HBB 19991130 bugfix: if p_edge2 list is empty,
+	     * don't change p_edges list! Crashes by access
+	     * to NULL pointer pe_tail, the second time through,
+	     * otherwise */
+	    if ((*p_edges)) {	/* Chain new edges to main list. */
+		pe_tail->next = p_edge2;
+		pe_tail = pe_tail2;
+	    } else {
+		(*p_edges) = p_edge2;
+		pe_tail = pe_tail2;
+	    }
+	}
+
+	/* this row finished, move list heads up one row: */
+	p_edge1 = p_edge2;
+	p_vrtx1 = p_vrtx2;
+    }
+
+    /* Update the boundary flag, saved in each edge, and update indexes: */
+
+    pe_temp = (*p_edges);
+
+    while (pe_temp) {
+	if ((!(pe_temp->poly[0])) || (!(pe_temp->poly[1])))
+	    (pe_temp->position) = BOUNDARY;
+	pe_temp = pe_temp->next;
+    }
+}
+
+/*
+ * Calculate minimum and maximum values
+ */
+static void
+calc_min_max(num_isolines, iso_lines, xx_min, yy_min, zz_min, xx_max, yy_max, zz_max)
+    int num_isolines;		/* number of iso-lines input */
+    struct iso_curve *iso_lines; /* iso-lines input */
+    double *xx_min, *yy_min, *zz_min, *xx_max, *yy_max, *zz_max; /* min/max values in/out */
+{
+    int i, j, grid_x_max;
+    struct coordinate  *vertex;
+    /*printf("<calc_min_max> :  iso_lines->p_count %ld \n",iso_lines->p_count);*/
+    grid_x_max = iso_lines->p_count;	/* number of vertices per iso_line */
+
+    (*xx_min) = (*yy_min) = (*zz_min) = VERYLARGE;	/* clear min/max values */
+    (*xx_max) = (*yy_max) = (*zz_max) = -VERYLARGE;
+    /*printf(" <calc_min_max> %d \n",num_isolines);*/
+    for (j = 0; j < num_isolines; j++) {
+      /*printf(" <calc_min_max> iso_lines %lx %lx %d min %g max %g\n",      */
+      /*       iso_lines,iso_lines->points,grid_x_max,(*zz_min),(*zz_max)); */
+	vertex = iso_lines->points;
+
+	for (i = 0; i < grid_x_max; i++) {
+	    if (vertex[i].type != UNDEFINED) {
+		if (vertex[i].x > (*xx_max))
+		    (*xx_max) = vertex[i].x;
+		if (vertex[i].y > (*yy_max))
+		    (*yy_max) = vertex[i].y;
+		if (vertex[i].z > (*zz_max))
+		    (*zz_max) = vertex[i].z;
+		if (vertex[i].x < (*xx_min))
+		    (*xx_min) = vertex[i].x;
+		if (vertex[i].y < (*yy_min))
+		    (*yy_min) = vertex[i].y;
+		if (vertex[i].z < (*zz_min))
+		    (*zz_min) = vertex[i].z;
+		
+	    }
+	}
+	iso_lines = iso_lines->next;
+	/*printf(" End of loop calc_min_max %d \n", j);*/
+    }
+    /* HBB 20000426: this code didn't take into account that axes might
+     * be logscaled... */
+#if 0
+    /* HBB 20001220: DON'T. The values are actually already stored
+     * logarithmized, as should be! */
+    axis_unlog_interval(FIRST_X_AXIS, xx_min, xx_max, 0);
+    axis_unlog_interval(FIRST_Y_AXIS, yy_min, yy_max, 0);
+    axis_unlog_interval(FIRST_Z_AXIS, zz_min, zz_max, 0);
+#endif
+
+    /* 
+     * fprintf(stderr," x: %g, %g\n", (*xx_min), (*xx_max));
+     * fprintf(stderr," y: %g, %g\n", (*yy_min), (*yy_max));
+     * fprintf(stderr," z: %g, %g\n", (*zz_min), (*zz_max));
+     */
+}
+
+/*
+ * Generate new edge and append it to list, but only if both vertices are 
+ * defined. The list is referenced by p_edge and pe_tail (p_edge points on 
+ * first edge and pe_tail on last one).
+ * Note, the list may be empty (pe_edge==pe_tail==NULL) on entry and exit.
+ */
+static struct edge_struct *
+add_edge(point0, point1, p_edge, pe_tail)
+struct coordinate  *point0;	/* 2 vertices input */
+struct coordinate  *point1;
+struct edge_struct **p_edge, **pe_tail;		/* pointers to edge list in/out */
+{
+    struct edge_struct *pe_temp = NULL;
+
+#if 1
+    if (point0->type == INRANGE && point1->type == INRANGE) {
+#else
+    if (point0->type != UNDEFINED && point1->type != UNDEFINED) {
+#endif
+
+	pe_temp = (struct edge_struct *)
+	    gp_alloc(sizeof(struct edge_struct), "contour edge");
+
+	pe_temp->poly[0] = NULL;	/* clear links           */
+	pe_temp->poly[1] = NULL;
+	pe_temp->vertex[0] = point0;	/* First vertex of edge. */
+	pe_temp->vertex[1] = point1;	/* Second vertex of edge. */
+	pe_temp->next = NULL;
+	pe_temp->position = INNER_MESH;		/* default position in mesh */
+
+	if ((*pe_tail)) {
+	    (*pe_tail)->next = pe_temp;		/* Stick new record as last one. */
+	} else {
+	    (*p_edge) = pe_temp;	/* start new list if empty */
+	}
+	(*pe_tail) = pe_temp;	/* continue to last record. */
+
+    }
+    return pe_temp;		/* returns NULL, if no edge allocated */
+}
+
+/*
+ * Generate new triangle and append it to list, but only if all edges are defined.
+ * The list is referenced by p_poly and pp_tail (p_poly points on first ploygon
+ * and pp_tail on last one).
+ * Note, the list may be empty (pe_ploy==pp_tail==NULL) on entry and exit.
+ */
+static struct poly_struct *
+add_poly(edge0, edge1, edge2, p_poly, pp_tail)
+    struct edge_struct *edge0, *edge1, *edge2;	/* 3 edges input */
+    struct poly_struct **p_poly, **pp_tail;		/* pointers to polygon list in/out */
+{
+    struct poly_struct *pp_temp = NULL;
+
+    if (edge0 && edge1 && edge2) {
+
+	pp_temp = (struct poly_struct *)
+	    gp_alloc(sizeof(struct poly_struct), "contour polygon");
+
+	pp_temp->edge[0] = edge0;	/* First edge of triangle */
+	pp_temp->edge[1] = edge1;	/* Second one             */
+	pp_temp->edge[2] = edge2;	/* Third one              */
+	pp_temp->next = NULL;
+
+	if (edge0->poly[0])	/* update edge0 */
+	    edge0->poly[1] = pp_temp;
+	else
+	    edge0->poly[0] = pp_temp;
+
+	if (edge1->poly[0])	/* update edge1 */
+	    edge1->poly[1] = pp_temp;
+	else
+	    edge1->poly[0] = pp_temp;
+
+	if (edge2->poly[0])	/* update edge2 */
+	    edge2->poly[1] = pp_temp;
+	else
+	    edge2->poly[0] = pp_temp;
+
+	if ((*pp_tail))		/* Stick new record as last one. */
+	    (*pp_tail)->next = pp_temp;
+	else
+	    (*p_poly) = pp_temp;	/* start new list if empty */
+
+	(*pp_tail) = pp_temp;	/* continue to last record. */
+
+    }
+    return pp_temp;		/* returns NULL, if no edge allocated */
+}
+
+
+
+/*
+ * Calls the (hopefully) desired interpolation/approximation routine.
+ */
+static void
+put_contour(p_cntr, z_level, xx_min, xx_max, yy_min, yy_max, contr_isclosed)
+    struct cntr_struct *p_cntr;	/* contour structure input */
+    double z_level;		/* Z level of contour input */
+    double xx_min, xx_max, yy_min, yy_max; /* minimum/maximum values input */
+    TBOOLEAN contr_isclosed;		/* contour line closed? (input) */
+{
+
+    if (!p_cntr)
+	return;			/* Nothing to do if it is empty contour. */
+
+    switch (interp_kind) {
+    case CONTOUR_KIND_LINEAR:	/* No interpolation/approximation. */
+	put_contour_nothing(p_cntr);
+	break;
+    case CONTOUR_KIND_CUBIC_SPL: /* Cubic spline interpolation. */
+	put_contour_cubic(p_cntr, z_level, xx_min, xx_max, yy_min, yy_max,
+			  chk_contour_kind(p_cntr, contr_isclosed));
+
+	break;
+    case CONTOUR_KIND_BSPLINE:	/* Bspline approximation. */
+	put_contour_bspline(p_cntr, z_level, xx_min, xx_max, yy_min, yy_max,
+			    chk_contour_kind(p_cntr, contr_isclosed));
+	break;
+    }
+    free_contour(p_cntr);
+}
+
+/*
+ * Simply puts contour coordinates in order with no interpolation or
+ * approximation.
+ */
+static void
+put_contour_nothing(p_cntr)
+struct cntr_struct *p_cntr;
+{
+    while (p_cntr) {
+	add_cntr_point(p_cntr->X, p_cntr->Y);
+	p_cntr = p_cntr->next;
+    }
+    end_crnt_cntr();
+}
+
+/*
+ * for some reason contours are never flagged as 'isclosed'
+ * if first point == last point, set flag accordingly
+ *
+ */
+
+static int
+chk_contour_kind(p_cntr, contr_isclosed)
+    struct cntr_struct *p_cntr;
+    TBOOLEAN contr_isclosed;
+{
+    struct cntr_struct *pc_tail = NULL;
+    TBOOLEAN current_contr_isclosed;
+
+    /*fprintf(stderr, "check_contour_kind: current contour_kind value is %d\n", contour_kind);*/
+
+    current_contr_isclosed = contr_isclosed;
+
+    if (! contr_isclosed) {
+	pc_tail = p_cntr;
+	while (pc_tail->next)
+	    pc_tail = pc_tail->next;	/* Find last point. */
+
+	/* test if first and last point are equal */
+	if (fuzzy_equal(pc_tail, p_cntr)) {
+	    current_contr_isclosed = TRUE;
+	    fprintf(stderr, "check_contour_kind: contr_isclosed changed to %d\n", current_contr_isclosed);
+	}
+    }
+    return (current_contr_isclosed);
+}
+
+/*
+ * Generate a cubic spline curve through the points (x_i,y_i) which are
+ * stored in the linked list p_cntr.
+ * The spline is defined as a 2d-function s(t) = (x(t),y(t)), where the
+ * parameter t is the length of the linear stroke.
+ */
+static void
+put_contour_cubic(p_cntr, z_level, xx_min, xx_max, yy_min, yy_max, contr_isclosed)
+    struct cntr_struct *p_cntr;
+    double z_level, xx_min, xx_max, yy_min, yy_max;
+    TBOOLEAN contr_isclosed;
+{
+    int num_pts, num_intpol;
+    double unit_x, unit_y;	/* To define norm (x,y)-plane */
+    double *delta_t;		/* Interval length t_{i+1}-t_i */
+    double *d2x, *d2y;		/* Second derivatives x''(t_i), y''(t_i) */
+    struct cntr_struct *pc_tail;
+
+    num_pts = count_contour(p_cntr);	/* Number of points in contour. */
+
+    pc_tail = p_cntr;		/* Find last point. */
+    while (pc_tail->next)
+	pc_tail = pc_tail->next;
+
+    if (contr_isclosed) {
+	/* Test if first and last point are equal (should be) */
+	if (!fuzzy_equal(pc_tail, p_cntr)) {
+	    pc_tail->next = p_cntr;	/* Close contour list - make it circular. */
+	    num_pts++;
+	}
+    }
+    delta_t = (double *) gp_alloc(num_pts * sizeof(double), "contour delta_t");
+    d2x = (double *) gp_alloc(num_pts * sizeof(double), "contour d2x");
+    d2y = (double *) gp_alloc(num_pts * sizeof(double), "contour d2y");
+
+    /* Width and height of the grid is used as a unit length (2d-norm) */
+    unit_x = xx_max - x_min;
+    unit_y = yy_max - y_min;
+    /* FIXME HBB 20010121: 'zero' should not be used as an absolute
+     * figure to compare to data */
+    unit_x = (unit_x > zero ? unit_x : zero);	/* should not be zero */
+    unit_y = (unit_y > zero ? unit_y : zero);
+
+    if (num_pts > 2) {
+	/*
+	 * Calculate second derivatives d2x[], d2y[] and interval lengths delta_t[]:
+	 */
+	if (!gen_cubic_spline(num_pts, p_cntr, d2x, d2y, delta_t,
+			      contr_isclosed, unit_x, unit_y)) {
+	    free((char *) delta_t);
+	    free((char *) d2x);
+	    free((char *) d2y);
+	    if (contr_isclosed)
+		pc_tail->next = NULL;	/* Un-circular list */
+	    return;
+	}
+    }
+    /* If following (num_pts > 1) is TRUE then exactly 2 points in contour.  */
+    else if (num_pts > 1) {
+	/* set all second derivatives to zero, interval length to 1 */
+	d2x[0] = 0.;
+	d2y[0] = 0.;
+	d2x[1] = 0.;
+	d2y[1] = 0.;
+	delta_t[0] = 1.;
+    } else {			/* Only one point ( ?? ) - ignore it. */
+	free((char *) delta_t);
+	free((char *) d2x);
+	free((char *) d2y);
+	if (contr_isclosed)
+	    pc_tail->next = NULL;	/* Un-circular list */
+	return;
+    }
+
+    /* Calculate "num_intpol" interpolated values */
+    num_intpol = 1 + (num_pts - 1) * contour_pts;	/* global: contour_pts */
+    intp_cubic_spline(num_pts, p_cntr, d2x, d2y, delta_t, num_intpol);
+
+    free((char *) delta_t);
+    free((char *) d2x);
+    free((char *) d2y);
+
+    if (contr_isclosed)
+	pc_tail->next = NULL;	/* Un-circular list */
+
+    end_crnt_cntr();
+}
+
+
+/*
+ * Find Bspline approximation for this data set.
+ * Uses global variable contour_pts to determine number of samples per
+ * interval, where the knot vector intervals are assumed to be uniform, and
+ * global variable contour_order for the order of Bspline to use.
+ */
+static void
+put_contour_bspline(p_cntr, z_level, xx_min, xx_max, yy_min, yy_max, contr_isclosed)
+struct cntr_struct *p_cntr;
+double z_level, xx_min, xx_max, yy_min, yy_max;
+TBOOLEAN contr_isclosed;
+{
+    int num_pts;
+    int order = contour_order - 1;
+
+    num_pts = count_contour(p_cntr);	/* Number of points in contour. */
+    if (num_pts < 2)
+	return;			/* Can't do nothing if empty or one points! */
+    /* Order must be less than number of points in curve - fix it if needed. */
+    if (order > num_pts - 1)
+	order = num_pts - 1;
+
+    gen_bspline_approx(p_cntr, num_pts, order, contr_isclosed);
+    end_crnt_cntr();
+}
+
+/*
+ * Free all elements in the contour list.
+ */
+static void
+free_contour(p_cntr)
+struct cntr_struct *p_cntr;
+{
+    struct cntr_struct *pc_temp;
+
+    while (p_cntr) {
+	pc_temp = p_cntr;
+	p_cntr = p_cntr->next;
+	free((char *) pc_temp);
+    }
+}
+
+/*
+ * Counts number of points in contour.
+ */
+static int
+count_contour(p_cntr)
+struct cntr_struct *p_cntr;
+{
+    int count = 0;
+
+    while (p_cntr) {
+	count++;
+	p_cntr = p_cntr->next;
+    }
+    return count;
+}
+
+/*
+ * Find second derivatives (x''(t_i),y''(t_i)) of cubic spline interpolation
+ * through list of points (x_i,y_i). The parameter t is calculated as the
+ * length of the linear stroke. The number of points must be at least 3.
+ * Note: For closed contours the first and last point must be equal.
+ */
+static int
+gen_cubic_spline(num_pts, p_cntr, d2x, d2y, delta_t, contr_isclosed, unit_x, unit_y)
+int num_pts;			/* Number of points (num_pts>=3), input */
+struct cntr_struct *p_cntr;	/* List of points (x(t_i),y(t_i)), input */
+double d2x[], d2y[],		/* Second derivatives (x''(t_i),y''(t_i)), output */
+ delta_t[];			/* List of interval lengths t_{i+1}-t_{i}, output */
+TBOOLEAN contr_isclosed;	/* Closed or open contour?, input  */
+double unit_x, unit_y;		/* Unit length in x and y (norm=1), input */
+{
+    int n, i;
+    double norm;
+    tri_diag *m;		/* The tri-diagonal matrix is saved here. */
+    struct cntr_struct *pc_temp;
+
+    m = (tri_diag *) gp_alloc(num_pts * sizeof(tri_diag), "contour tridiag m");
+
+    /*
+     * Calculate first differences in (d2x[i], d2y[i]) and interval lengths
+     * in delta_t[i]:
+     */
+    pc_temp = p_cntr;
+    for (i = 0; i < num_pts - 1; i++) {
+	d2x[i] = pc_temp->next->X - pc_temp->X;
+	d2y[i] = pc_temp->next->Y - pc_temp->Y;
+	/*
+	 * The norm of a linear stroke is calculated in "normal coordinates"
+	 * and used as interval length:
+	 */
+	delta_t[i] = sqrt(SQR(d2x[i] / unit_x) + SQR(d2y[i] / unit_y));
+
+	d2x[i] /= delta_t[i];	/* first difference, with unit norm: */
+	d2y[i] /= delta_t[i];	/*   || (d2x[i], d2y[i]) || = 1      */
+
+	pc_temp = pc_temp->next;
+    }
+
+    /*
+     * Setup linear system:  m * x = b
+     */
+    n = num_pts - 2;		/* Without first and last point */
+    if (contr_isclosed) {
+	/* First and last points must be equal for closed contours */
+	delta_t[num_pts - 1] = delta_t[0];
+	d2x[num_pts - 1] = d2x[0];
+	d2y[num_pts - 1] = d2y[0];
+	n++;			/* Add last point (= first point) */
+    }
+    for (i = 0; i < n; i++) {
+	/* Matrix M, mainly tridiagonal with cyclic second index ("j = j+n mod n") */
+	m[i][0] = delta_t[i];	/* Off-diagonal element M_{i,i-1} */
+	m[i][1] = 2. * (delta_t[i] + delta_t[i + 1]);	/* M_{i,i} */
+	m[i][2] = delta_t[i + 1];	/* Off-diagonal element M_{i,i+1} */
+
+	/* Right side b_x and b_y */
+	d2x[i] = (d2x[i + 1] - d2x[i]) * 6.;
+	d2y[i] = (d2y[i + 1] - d2y[i]) * 6.;
+
+	/*
+	 * If the linear stroke shows a cusps of more than 90 degree, the right
+	 * side is reduced to avoid oscillations in the spline:
+	 */
+	norm = sqrt(SQR(d2x[i] / unit_x) + SQR(d2y[i] / unit_y)) / 8.5;
+
+	if (norm > 1.) {
+	    d2x[i] /= norm;
+	    d2y[i] /= norm;
+	    /* The first derivative will not be continuous */
+	}
+    }
+
+    if (!contr_isclosed) {
+	/* Third derivative is set to zero at both ends */
+	m[0][1] += m[0][0];	/* M_{0,0}     */
+	m[0][0] = 0.;		/* M_{0,n-1}   */
+	m[n - 1][1] += m[n - 1][2];	/* M_{n-1,n-1} */
+	m[n - 1][2] = 0.;	/* M_{n-1,0}   */
+    }
+    /* Solve linear systems for d2x[] and d2y[] */
+
+
+    if (solve_cubic_1(m, n)) {	/* Calculate Cholesky decomposition */
+	solve_cubic_2(m, d2x, n);	/* solve M * d2x = b_x */
+	solve_cubic_2(m, d2y, n);	/* solve M * d2y = b_y */
+
+    } else {			/* Should not happen, but who knows ... */
+	free((char *) m);
+	return FALSE;
+    }
+
+    /* Shift all second derivatives one place right and abdate end points */
+    for (i = n; i > 0; i--) {
+	d2x[i] = d2x[i - 1];
+	d2y[i] = d2y[i - 1];
+    }
+    if (contr_isclosed) {
+	d2x[0] = d2x[n];
+	d2y[0] = d2y[n];
+    } else {
+	d2x[0] = d2x[1];	/* Third derivative is zero in */
+	d2y[0] = d2y[1];	/*     first and last interval */
+	d2x[n + 1] = d2x[n];
+	d2y[n + 1] = d2y[n];
+    }
+
+    free((char *) m);
+    return TRUE;
+}
+
+/*
+ * Calculate interpolated values of the spline function (defined via p_cntr
+ * and the second derivatives d2x[] and d2y[]). The number of tabulated
+ * values is n. On an equidistant grid n_intpol values are calculated.
+ */
+static void
+intp_cubic_spline(n, p_cntr, d2x, d2y, delta_t, n_intpol)
+int n;
+struct cntr_struct *p_cntr;
+double d2x[], d2y[], delta_t[];
+int n_intpol;
+{
+    double t, t_skip, t_max;
+    double x0, x1, x, y0, y1, y;
+    double d, hx, dx0, dx01, hy, dy0, dy01;
+    int i;
+
+    /* The length of the total interval */
+    t_max = 0.;
+    for (i = 0; i < n - 1; i++)
+	t_max += delta_t[i];
+
+    /* The distance between interpolated points */
+    t_skip = (1. - 1e-7) * t_max / (n_intpol - 1);
+
+    t = 0.;			/* Parameter value */
+    x1 = p_cntr->X;
+    y1 = p_cntr->Y;
+    add_cntr_point(x1, y1);	/* First point. */
+    t += t_skip;
+
+    for (i = 0; i < n - 1; i++) {
+	p_cntr = p_cntr->next;
+
+	d = delta_t[i];		/* Interval length */
+	x0 = x1;
+	y0 = y1;
+	x1 = p_cntr->X;
+	y1 = p_cntr->Y;
+	hx = (x1 - x0) / d;
+	hy = (y1 - y0) / d;
+	dx0 = (d2x[i + 1] + 2 * d2x[i]) / 6.;
+	dy0 = (d2y[i + 1] + 2 * d2y[i]) / 6.;
+	dx01 = (d2x[i + 1] - d2x[i]) / (6. * d);
+	dy01 = (d2y[i + 1] - d2y[i]) / (6. * d);
+	while (t <= delta_t[i]) {	/* t in current interval ? */
+	    x = x0 + t * (hx + (t - d) * (dx0 + t * dx01));
+	    y = y0 + t * (hy + (t - d) * (dy0 + t * dy01));
+	    add_cntr_point(x, y);	/* next point. */
+	    t += t_skip;
+	}
+	t -= delta_t[i];	/* Parameter t relative to start of next interval */
+    }
+}
+
+/*
+ * The following two procedures solve the special linear system which arise
+ * in cubic spline interpolation. If x is assumed cyclic ( x[i]=x[n+i] ) the
+ * equations can be written as (i=0,1,...,n-1):
+ *     m[i][0] * x[i-1] + m[i][1] * x[i] + m[i][2] * x[i+1] = b[i] .
+ * In matrix notation one gets M * x = b, where the matrix M is tridiagonal
+ * with additional elements in the upper right and lower left position:
+ *   m[i][0] = M_{i,i-1}  for i=1,2,...,n-1    and    m[0][0] = M_{0,n-1} ,
+ *   m[i][1] = M_{i, i }  for i=0,1,...,n-1
+ *   m[i][2] = M_{i,i+1}  for i=0,1,...,n-2    and    m[n-1][2] = M_{n-1,0}.
+ * M should be symmetric (m[i+1][0]=m[i][2]) and positiv definite.
+ * The size of the system is given in n (n>=1).
+ *
+ * In the first procedure the Cholesky decomposition M = C^T * D * C
+ * (C is upper triangle with unit diagonal, D is diagonal) is calculated.
+ * Return TRUE if decomposition exist.
+ */
+static int
+solve_cubic_1(m, n)
+tri_diag m[];
+int n;
+{
+    int i;
+    double m_ij, m_n, m_nn, d;
+
+    if (n < 1)
+	return FALSE;		/* Dimension should be at least 1 */
+
+    d = m[0][1];		/* D_{0,0} = M_{0,0} */
+    if (d <= 0.)
+	return FALSE;		/* M (or D) should be positiv definite */
+    m_n = m[0][0];		/*  M_{0,n-1}  */
+    m_nn = m[n - 1][1];		/* M_{n-1,n-1} */
+    for (i = 0; i < n - 2; i++) {
+	m_ij = m[i][2];		/*  M_{i,1}  */
+	m[i][2] = m_ij / d;	/* C_{i,i+1} */
+	m[i][0] = m_n / d;	/* C_{i,n-1} */
+	m_nn -= m[i][0] * m_n;	/* to get C_{n-1,n-1} */
+	m_n = -m[i][2] * m_n;	/* to get C_{i+1,n-1} */
+	d = m[i + 1][1] - m[i][2] * m_ij;	/* D_{i+1,i+1} */
+	if (d <= 0.)
+	    return FALSE;	/* Elements of D should be positiv */
+	m[i + 1][1] = d;
+    }
+    if (n >= 2) {		/* Complete last column */
+	m_n += m[n - 2][2];	/* add M_{n-2,n-1} */
+	m[n - 2][0] = m_n / d;	/* C_{n-2,n-1} */
+	m[n - 1][1] = d = m_nn - m[n - 2][0] * m_n;	/* D_{n-1,n-1} */
+	if (d <= 0.)
+	    return FALSE;
+    }
+    return TRUE;
+}
+
+/*
+ * The second procedure solves the linear system, with the Choleky
+ * decomposition calculated above (in m[][]) and the right side b given
+ * in x[]. The solution x overwrites the right side in x[].
+ */
+static void
+solve_cubic_2(m, x, n)
+tri_diag m[];
+double x[];
+int n;
+{
+    int i;
+    double x_n;
+
+    /* Division by transpose of C : b = C^{-T} * b */
+    x_n = x[n - 1];
+    for (i = 0; i < n - 2; i++) {
+	x[i + 1] -= m[i][2] * x[i];	/* C_{i,i+1} * x_{i} */
+	x_n -= m[i][0] * x[i];	/* C_{i,n-1} * x_{i} */
+    }
+    if (n >= 2)
+	x[n - 1] = x_n - m[n - 2][0] * x[n - 2];	/* C_{n-2,n-1} * x_{n-1} */
+
+    /* Division by D: b = D^{-1} * b */
+    for (i = 0; i < n; i++)
+	x[i] /= m[i][1];
+
+    /* Division by C: b = C^{-1} * b */
+    x_n = x[n - 1];
+    if (n >= 2)
+	x[n - 2] -= m[n - 2][0] * x_n;	/* C_{n-2,n-1} * x_{n-1} */
+    for (i = n - 3; i >= 0; i--) {
+	/*      C_{i,i+1} * x_{i+1} + C_{i,n-1} * x_{n-1} */
+	x[i] -= m[i][2] * x[i + 1] + m[i][0] * x_n;
+    }
+    return;
+}
+
+/*
+ * Solve tri diagonal linear system equation. The tri diagonal matrix is
+ * defined via matrix M, right side is r, and solution X i.e. M * X = R.
+ * Size of system given in n. Return TRUE if solution exist.
+ */
+/* not used any more in "contour.c", but in "spline.c" (21. Dec. 1995) ! */
+
+int
+solve_tri_diag(m, r, x, n)
+tri_diag m[];
+double r[], x[];
+int n;
+{
+    int i;
+    double t;
+
+    for (i = 1; i < n; i++) {	/* Eliminate element m[i][i-1] (lower diagonal). */
+	if (m[i - 1][1] == 0)
+	    return FALSE;
+	t = m[i][0] / m[i - 1][1];	/* Find ratio between the two lines. */
+/*      m[i][0] = m[i][0] - m[i-1][1] * t; */
+/* m[i][0] is not used any more (and set to 0 in the above line) */
+	m[i][1] = m[i][1] - m[i - 1][2] * t;
+	r[i] = r[i] - r[i - 1] * t;
+    }
+    /* Now do back subtitution - update the solution vector X: */
+    if (m[n - 1][1] == 0)
+	return FALSE;
+    x[n - 1] = r[n - 1] / m[n - 1][1];	/* Find last element. */
+    for (i = n - 2; i >= 0; i--) {
+	if (m[i][1] == 0)
+	    return FALSE;
+	x[i] = (r[i] - x[i + 1] * m[i][2]) / m[i][1];
+    }
+    return TRUE;
+}
+
+/*
+ * Generate a Bspline curve defined by all the points given in linked list p:
+ * Algorithm: using deBoor algorithm
+ * Note: if Curvekind is open contour than Open end knot vector is assumed,
+ *       else (closed contour) Float end knot vector is assumed.
+ * It is assumed that num_of_points is at least 2, and order of Bspline is less
+ * than num_of_points!
+ */
+static void
+gen_bspline_approx(p_cntr, num_of_points, order, contr_isclosed)
+struct cntr_struct *p_cntr;
+int num_of_points, order;
+TBOOLEAN contr_isclosed;
+{
+    int knot_index = 0, pts_count = 1;
+    double dt, t, next_t, t_min, t_max, x, y;
+    struct cntr_struct *pc_temp = p_cntr, *pc_tail = NULL;
+
+    /* If the contour is Closed one we must update few things:
+     * 1. Make the list temporary circular, so we can close the contour.
+     * 2. Update num_of_points - increase it by "order-1" so contour will be
+     *    closed. This will evaluate order more sections to close it!
+     */
+    if (contr_isclosed) {
+	pc_tail = p_cntr;
+	while (pc_tail->next)
+	    pc_tail = pc_tail->next;	/* Find last point. */
+
+	/* test if first and last point are equal */
+	if (fuzzy_equal(pc_tail, p_cntr)) {
+	    /* Close contour list - make it circular. */
+	    pc_tail->next = p_cntr->next;
+	    num_of_points += order - 1;
+	} else {
+	    pc_tail->next = p_cntr;
+	    num_of_points += order;
+	}
+    }
+    /* Find first (t_min) and last (t_max) t value to eval: */
+    t = t_min = fetch_knot(contr_isclosed, num_of_points, order, order);
+    t_max = fetch_knot(contr_isclosed, num_of_points, order, num_of_points);
+    next_t = t_min + 1.0;
+    knot_index = order;
+    dt = 1.0 / contour_pts;	/* Number of points per one section. */
+
+
+    while (t < t_max) {
+	if (t > next_t) {
+	    pc_temp = pc_temp->next;	/* Next order ctrl. pt. to blend. */
+	    knot_index++;
+	    next_t += 1.0;
+	}
+	eval_bspline(t, pc_temp, num_of_points, order, knot_index,
+		     contr_isclosed, &x, &y);	/* Next pt. */
+	add_cntr_point(x, y);
+	pts_count++;
+	/* As we might have some real number round off problems we do      */
+	/* the last point outside the loop                                 */
+	if (pts_count == contour_pts * (num_of_points - order) + 1)
+	    break;
+	t += dt;
+    }
+
+    /* Now do the last point */
+    eval_bspline(t_max - EPSILON, pc_temp, num_of_points, order, knot_index,
+		 contr_isclosed, &x, &y);
+    add_cntr_point(x, y);	/* Complete the contour. */
+
+    if (contr_isclosed)	/* Update list - un-circular it. */
+	pc_tail->next = NULL;
+}
+
+/*
+ * The routine to evaluate the B-spline value at point t using knot vector
+ * from function fetch_knot(), and the control points p_cntr.
+ * Returns (x, y) of approximated B-spline. Note that p_cntr points on the
+ * first control point to blend with. The B-spline is of order order.
+ */
+static void
+eval_bspline(t, p_cntr, num_of_points, order, j, contr_isclosed, x, y)
+double t;
+struct cntr_struct *p_cntr;
+int num_of_points, order, j;
+TBOOLEAN contr_isclosed;
+double *x, *y;
+{
+    int i, p;
+    double ti, tikp, *dx, *dy;	/* Copy p_cntr into it to make it faster. */
+
+    dx = (double *) gp_alloc((order + j) * sizeof(double), "contour b_spline");
+    dy = (double *) gp_alloc((order + j) * sizeof(double), "contour b_spline");
+
+    /* Set the dx/dy - [0] iteration step, control points (p==0 iterat.): */
+    for (i = j - order; i <= j; i++) {
+	dx[i] = p_cntr->X;
+	dy[i] = p_cntr->Y;
+	p_cntr = p_cntr->next;
+    }
+
+    for (p = 1; p <= order; p++) {	/* Iteration (b-spline level) counter. */
+	for (i = j; i >= j - order + p; i--) {	/* Control points indexing. */
+	    ti = fetch_knot(contr_isclosed, num_of_points, order, i);
+	    tikp = fetch_knot(contr_isclosed, num_of_points, order, i + order + 1 - p);
+	    if (ti == tikp) {	/* Should not be a problems but how knows... */
+	    } else {
+		dx[i] = dx[i] * (t - ti) / (tikp - ti) +	/* Calculate x. */
+		    dx[i - 1] * (tikp - t) / (tikp - ti);
+		dy[i] = dy[i] * (t - ti) / (tikp - ti) +	/* Calculate y. */
+		    dy[i - 1] * (tikp - t) / (tikp - ti);
+	    }
+	}
+    }
+    *x = dx[j];
+    *y = dy[j];
+    free((char *) dx);
+    free((char *) dy);
+}
+
+/*
+ * Routine to get the i knot from uniform knot vector. The knot vector
+ * might be float (Knot(i) = i) or open (where the first and last "order"
+ * knots are equal). contr_isclosed determines knot kind - open contour means
+ * open knot vector, and closed contour selects float knot vector.
+ * Note the knot vector is not exist and this routine simulates it existance
+ * Also note the indexes for the knot vector starts from 0.
+ */
+static double
+fetch_knot(contr_isclosed, num_of_points, order, i)
+    TBOOLEAN contr_isclosed;
+    int num_of_points, order, i;
+{
+    if(! contr_isclosed) {
+	if (i <= order)
+	    return 0.0;
+	else if (i <= num_of_points)
+	    return (double) (i - order);
+	else
+	    return (double) (num_of_points - order);
+    } else {
+	return (double) i;
+    }
+}
+
+
+/* setting et getting de variables */
+/*        OP 01/2002               */
+
+void set_contour_kind(t_contour_kind in){
+  contour_kind = in;
+}
+
+t_contour_kind get_contour_kind(){
+  return (contour_kind);
+}
+
+void set_contour_levels_kind(t_contour_levels_kind in){
+ contour_levels_kind = in;
+
+}
+
+t_contour_levels_kind get_contour_levels_kind(){
+
+  return(contour_levels_kind);
+}
+
+void set_contour_levels(int num){
+  contour_levels = num;
+}
+
+int get_contour_levels(){
+  return(contour_levels);
+}
+void set_contour_levels_list(double *vec){
+
+  contour_levels_list=vec;
+}
+
+/*******
+void set_contour_levels_list(double *vec,int sz){
+  int i;
+  printf(" <set_contour_levels_list> sz %d \n",sz);
+  contour_levels_list = (double *)  malloc(sz*sizeof(double));
+  for (i=0 ; i<sz ; i++){
+    printf(" <set_contour_levels_list> i %d vec %g\n",i,vec[i]);
+    contour_levels_list[i] = vec[i];
+    
+  }
+}
+void free_contour_levels_list(){
+  if(contour_levels_list != NULL){
+    free(contour_levels_list);
+    contour_levels_list = NULL;
+  }
+}
+*****/
+double * get_contour_levels_list(){
+
+return(contour_levels_list);
+}
+ 
Index: /tags/V_Dec2002/SophyaPI/PIGcont/gp_contour.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIGcont/gp_contour.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIGcont/gp_contour.h	(revision 2309)
@@ -0,0 +1,114 @@
+/* GNUPLOT - contour.h */
+
+/*[
+ * Copyright 1999   Thomas Williams, Colin Kelley
+ *
+ * Permission to use, copy, and distribute this software and its
+ * documentation for any purpose with or without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.
+ *
+ * Permission to modify the software is granted, but not the right to
+ * distribute the complete modified source code.  Modifications are to
+ * be distributed as patches to the released version.  Permission to
+ * distribute binaries produced by compiling modified sources is granted,
+ * provided you
+ *   1. distribute the corresponding source modifications from the
+ *    released version in the form of a patch file along with the binaries,
+ *   2. add special version identification to distinguish your version
+ *    in addition to the base release version number,
+ *   3. provide your name and address as the primary contact for the
+ *    support of your modified version, and
+ *   4. retain our contact information in regard to use of the base
+ *    software.
+ * Permission to distribute the released version of the source code along
+ * with corresponding source modifications in the form of a patch file is
+ * granted with same provisions 2 through 4 for binary distributions.
+ *
+ * This software is provided "as is" without express or implied warranty
+ * to the extent permitted by applicable law.
+]*/
+
+#ifndef GNUPLOT_CONTOUR_H
+#define GNUPLOT_CONTOUR_H
+
+/* #if... / #include / #define collection: */
+
+/***
+#include "syscfg.h"
+***/
+#include "gp_types.h"
+
+#include "gp_dynarray.h"
+#include "gp_graph3d.h"
+#include "gpc_misc.h"
+#include <math.h>
+
+#define DEFAULT_CONTOUR_LEVELS 5
+#define DEFAULT_NUM_APPROX_PTS 5
+#define DEFAULT_CONTOUR_ORDER  4
+#define MAX_BSPLINE_ORDER      10
+
+/* Type definitions */
+
+typedef enum en_contour_kind {
+    /* Method of drawing the contour lines found */
+    CONTOUR_KIND_LINEAR,
+    CONTOUR_KIND_CUBIC_SPL,
+    CONTOUR_KIND_BSPLINE
+} t_contour_kind;
+
+typedef enum en_contour_levels_kind {
+    /* How contour levels are set */
+    LEVELS_AUTO,		/* automatically selected */
+
+    LEVELS_INCREMENTAL,		/* user specified start & incremnet */
+    LEVELS_DISCRETE,		/* user specified discrete levels */
+    LEVELS_NUM                  /* User sets contour number - AJOUT OP */
+     
+} t_contour_levels_kind;
+
+
+/* Used to allocate the tri-diag matrix. */
+typedef double tri_diag[3];
+
+/* Variables of contour.c needed by other modules: */
+
+extern char contour_format[];
+/***********************************************/
+/* VARIABLES MAINTENANT STATIQUES - OP 01/2002 */
+/*extern t_contour_kind contour_kind;*/
+/*extern t_contour_levels_kind contour_levels_kind;*/
+/*extern int contour_levels;*/
+/*extern int contour_order;*/
+/*extern int contour_pts;*/
+/***********************************************/
+
+/* storage for z levels to draw contours at */
+/* extern dynarray dyn_contour_levels_list; */
+/*#define contour_levels_list ((double *)dyn_contour_levels_list.v) */
+/* extern double * contour_levels_list; */
+
+/* Prototypes of functions exported by contour.c */
+
+struct gnuplot_contours *contour(int num_isolines, struct iso_curve *iso_lines);
+int solve_tri_diag(tri_diag m[], double r[], double x[], int n);
+int Get_Num_Of_Z_Levels();
+
+/* seting de variables OP 01/2002 */
+
+void set_contour_kind(t_contour_kind);
+t_contour_kind get_contour_kind();
+
+void set_contour_levels_kind(t_contour_levels_kind);
+t_contour_levels_kind get_contour_levels_kind();
+
+void set_contour_levels(int);
+int get_contour_levels();
+void set_contour_levels_list(double *);
+double * get_contour_levels_list();
+
+
+
+#endif /* GNUPLOT_CONTOUR_H */
Index: /tags/V_Dec2002/SophyaPI/PIGcont/gp_dynarray.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIGcont/gp_dynarray.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIGcont/gp_dynarray.h	(revision 2309)
@@ -0,0 +1,59 @@
+/* GNUPLOT - dynarray.h */
+
+/*[
+ * Copyright 1999   Thomas Williams, Colin Kelley
+ *
+ * Permission to use, copy, and distribute this software and its
+ * documentation for any purpose with or without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.
+ *
+ * Permission to modify the software is granted, but not the right to
+ * distribute the complete modified source code.  Modifications are to
+ * be distributed as patches to the released version.  Permission to
+ * distribute binaries produced by compiling modified sources is granted,
+ * provided you
+ *   1. distribute the corresponding source modifications from the
+ *    released version in the form of a patch file along with the binaries,
+ *   2. add special version identification to distinguish your version
+ *    in addition to the base release version number,
+ *   3. provide your name and address as the primary contact for the
+ *    support of your modified version, and
+ *   4. retain our contact information in regard to use of the base
+ *    software.
+ * Permission to distribute the released version of the source code along
+ * with corresponding source modifications in the form of a patch file is
+ * granted with same provisions 2 through 4 for binary distributions.
+ *
+ * This software is provided "as is" without express or implied warranty
+ * to the extent permitted by applicable law.
+]*/
+
+#ifndef GP_DYNARRAY__H
+#define GP_DYNARRAY__H
+
+/***
+# include "syscfg.h"
+# include "stdfn.h"
+***/
+#include <stdio.h>
+#include "gpc_misc.h"
+
+typedef struct dynarray {
+    long size;			/* alloced size of the array */
+    long end;			/* index of first unused entry */
+    long increment;		/* amount to increment size by, on realloc */
+    size_t entry_size;		/* size of the entries in this array */
+    void *v;		/* the vector itself */
+} dynarray;
+
+/* Prototypes */
+void init_dynarray (dynarray * array, size_t element, long size, long increment);
+void free_dynarray (dynarray * array);
+void extend_dynarray(dynarray * array, long increment);
+void resize_dynarray (dynarray * array, long newsize);
+void *nextfrom_dynarray (dynarray * array);
+void droplast_dynarray (dynarray * array);
+
+#endif /* GP_DYNARRAY_H */
Index: /tags/V_Dec2002/SophyaPI/PIGcont/gp_graph3d.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIGcont/gp_graph3d.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIGcont/gp_graph3d.h	(revision 2309)
@@ -0,0 +1,147 @@
+/* GNUPLOT - graph3d.h */
+
+/*[
+ * Copyright 1999   Thomas Williams, Colin Kelley
+ *
+ * Permission to use, copy, and distribute this software and its
+ * documentation for any purpose with or without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.
+ *
+ * Permission to modify the software is granted, but not the right to
+ * distribute the complete modified source code.  Modifications are to
+ * be distributed as patches to the released version.  Permission to
+ * distribute binaries produced by compiling modified sources is granted,
+ * provided you
+ *   1. distribute the corresponding source modifications from the
+ *    released version in the form of a patch file along with the binaries,
+ *   2. add special version identification to distinguish your version
+ *    in addition to the base release version number,
+ *   3. provide your name and address as the primary contact for the
+ *    support of your modified version, and
+ *   4. retain our contact information in regard to use of the base
+ *    software.
+ * Permission to distribute the released version of the source code along
+ * with corresponding source modifications in the form of a patch file is
+ * granted with same provisions 2 through 4 for binary distributions.
+ *
+ * This software is provided "as is" without express or implied warranty
+ * to the extent permitted by applicable law.
+]*/
+
+#ifndef GNUPLOT_GRAPH3D_H
+# define GNUPLOT_GRAPH3D_H
+
+/* #if... / #include / #define collection: */
+
+/***
+#include "syscfg.h"
+
+#include "gadgets.h"
+#include "term_api.h"
+****/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "gp_types.h"
+#include "gpc_misc.h"
+/* Function macros to map from user 3D space into normalized -1..1 */
+#define map_x3d(x) ((x-X_AXIS.min)*xscale3d-1.0)
+#define map_y3d(y) ((y-Y_AXIS.min)*yscale3d-1.0)
+#define map_z3d(z) ((z-floor_z)*zscale3d-1.0)
+
+/* Type definitions */
+
+typedef enum en_contour_placement {
+    /* Where to place contour maps if at all. */
+    CONTOUR_NONE,
+    CONTOUR_BASE,
+    CONTOUR_SRF,
+    CONTOUR_BOTH
+} t_contour_placement;
+
+typedef double transform_matrix[4][4]; /* HBB 990826: added */
+
+typedef struct gnuplot_contours {
+    struct gnuplot_contours *next;
+    struct coordinate *coords;
+    char isNewLevel;
+    char label[32];
+    int num_pts;
+#ifdef PM3D
+    double z;
+#endif
+} gnuplot_contours;
+
+typedef struct iso_curve {
+    struct iso_curve *next;
+    int p_max;			/* how many points are allocated */
+    int p_count;			/* count of points in points */
+    struct coordinate  *points;
+} iso_curve;
+
+typedef struct surface_points {
+    struct surface_points *next_sp; /* linked list */
+    int token;			/* last token nr, for second pass */
+    enum PLOT_TYPE plot_type;
+    enum PLOT_STYLE plot_style;
+    char *title;
+    int title_no_enhanced;	/* don't typeset title in enhanced mode */
+  /*struct lp_style_type lp_properties;*/
+    int has_grid_topology;
+    
+    /* Data files only - num of isolines read from file. For
+     * functions, num_iso_read is the number of 'primary' isolines (in
+     * x direction) */
+    int num_iso_read;		
+    struct gnuplot_contours *contours; /* NULL if not doing contours. */
+    struct iso_curve *iso_crvs;	/* the actual data */
+
+#ifdef PM3D_COLUMN
+    int pm3d_color_from_column;
+    coordval color_min;
+    coordval color_max;
+#endif
+    
+} surface_points;
+
+/* Variables of graph3d.c needed by other modules: */
+
+extern int xmiddle, ymiddle, xscaler, yscaler;
+extern double floor_z;
+extern double ceiling_z, base_z; /* made exportable for PM3D */
+extern transform_matrix trans_mat;
+extern double xscale3d, yscale3d, zscale3d;
+
+extern t_contour_placement draw_contour;
+extern TBOOLEAN	label_contours;
+
+extern TBOOLEAN	draw_surface;
+
+/* is hidden3d display wanted? */
+extern TBOOLEAN	hidden3d;
+
+extern float surface_rot_z;
+extern float surface_rot_x;
+extern float surface_scale;
+extern float surface_zscale;
+
+extern float ticslevel;
+
+#define ISO_SAMPLES 10		/* default number of isolines per splot */
+extern int iso_samples_1;
+extern int iso_samples_2;
+
+#ifdef USE_MOUSE
+extern int axis3d_o_x, axis3d_o_y, axis3d_x_dx, axis3d_x_dy, axis3d_y_dx, axis3d_y_dy;
+#endif
+
+/* Prototypes from file "graph3d.c" */
+
+void do_3dplot (struct surface_points *plots, int pcount, int quick);
+void map3d_position (struct position * pos, unsigned int *x,
+				  unsigned int *y, const char *what);
+
+
+#endif /* GNUPLOT_GRAPH3D_H */
Index: /tags/V_Dec2002/SophyaPI/PIGcont/gp_types.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIGcont/gp_types.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIGcont/gp_types.h	(revision 2309)
@@ -0,0 +1,191 @@
+/*
+ * $Id: gp_types.h,v 1.2 2001-12-30 22:09:34 ansari Exp $
+ */
+
+/* GNUPLOT - gp_types.h */
+
+/*[
+ * Copyright 2000   Thomas Williams, Colin Kelley
+ *
+ * Permission to use, copy, and distribute this software and its
+ * documentation for any purpose with or without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.
+ *
+ * Permission to modify the software is granted, but not the right to
+ * distribute the complete modified source code.  Modifications are to
+ * be distributed as patches to the released version.  Permission to
+ * distribute binaries produced by compiling modified sources is granted,
+ * provided you
+ *   1. distribute the corresponding source modifications from the
+ *    released version in the form of a patch file along with the binaries,
+ *   2. add special version identification to distinguish your version
+ *    in addition to the base release version number,
+ *   3. provide your name and address as the primary contact for the
+ *    support of your modified version, and
+ *   4. retain our contact information in regard to use of the base
+ *    software.
+ * Permission to distribute the released version of the source code along
+ * with corresponding source modifications in the form of a patch file is
+ * granted with same provisions 2 through 4 for binary distributions.
+ *
+ * This software is provided "as is" without express or implied warranty
+ * to the extent permitted by applicable law.
+]*/
+
+#ifndef GNUPLOT_GPTYPES_H
+#define GNUPLOT_GPTYPES_H
+
+/***
+#include "syscfg.h"
+***/
+#include "gpc_misc.h"
+
+#define MAX_ID_LEN 50		/* max length of an identifier */
+#define MAX_LINE_LEN 1024	/* maximum number of chars allowed on line */
+
+#define DEG2RAD (M_PI / 180.0)
+
+/* These used to be #defines in plot.h. For easier debugging, I've
+ * converted most of them into enum's. */
+enum DATA_TYPES {
+	INTGR, CMPLX
+};
+
+enum PLOT_TYPE {
+	FUNC, DATA, FUNC3D, DATA3D
+};
+
+/* we explicitly assign values to the types, such that we can
+ * perform bit tests to see if the style involves points and/or lines
+ * bit 0 (val 1) = line, bit 1 (val 2) = point, bit 2 (val 4)= error
+ * This allows rapid decisions about the sample drawn into the key,
+ * for example.
+ */
+/* HBB 20010610: new enum, to make mnemonic names for these flags
+ * accessible everywhere */
+typedef enum e_PLOT_STYLE_FLAGS {
+    PLOT_STYLE_HAS_LINE      = (1<<0),
+    PLOT_STYLE_HAS_POINT     = (1<<1),
+    PLOT_STYLE_HAS_ERRORBAR  = (1<<2)
+} PLOT_STYLE_FLAGS;
+
+typedef enum PLOT_STYLE {
+    LINES        =  0*(1<<3) + PLOT_STYLE_HAS_LINE,
+    POINTSTYLE   =  1*(1<<3) + PLOT_STYLE_HAS_POINT,
+    IMPULSES     =  2*(1<<3) + PLOT_STYLE_HAS_LINE,
+    LINESPOINTS  =  3*(1<<3) + (PLOT_STYLE_HAS_POINT | PLOT_STYLE_HAS_LINE),
+    DOTS         =  4*(1<<3) + 0,
+    XERRORBARS   =  5*(1<<3) + (PLOT_STYLE_HAS_POINT | PLOT_STYLE_HAS_ERRORBAR),
+    YERRORBARS   =  6*(1<<3) + (PLOT_STYLE_HAS_POINT | PLOT_STYLE_HAS_ERRORBAR),
+    XYERRORBARS  =  7*(1<<3) + (PLOT_STYLE_HAS_POINT | PLOT_STYLE_HAS_ERRORBAR),
+    BOXXYERROR   =  8*(1<<3) + PLOT_STYLE_HAS_LINE,
+    BOXES        =  9*(1<<3) + PLOT_STYLE_HAS_LINE,
+    BOXERROR     = 10*(1<<3) + PLOT_STYLE_HAS_LINE,
+    STEPS        = 11*(1<<3) + PLOT_STYLE_HAS_LINE,
+    FSTEPS       = 12*(1<<3) + PLOT_STYLE_HAS_LINE,
+    HISTEPS      = 13*(1<<3) + PLOT_STYLE_HAS_LINE,
+    VECTOR       = 14*(1<<3) + PLOT_STYLE_HAS_LINE,
+    CANDLESTICKS = 15*(1<<3) + PLOT_STYLE_HAS_ERRORBAR,
+    /* FIXME HBB 20010214: shouldn't fincancebars have 4 or 5?
+     * They behave very much like errorbars, with the sole
+     * exception of the key entry ... */
+    FINANCEBARS  = 16*(1<<3) + PLOT_STYLE_HAS_LINE,
+    XERRORLINES  = 17*(1<<3) + (PLOT_STYLE_HAS_LINE | PLOT_STYLE_HAS_POINT | PLOT_STYLE_HAS_ERRORBAR),
+    YERRORLINES  = 18*(1<<3) + (PLOT_STYLE_HAS_LINE | PLOT_STYLE_HAS_POINT | PLOT_STYLE_HAS_ERRORBAR),
+    XYERRORLINES = 19*(1<<3) + (PLOT_STYLE_HAS_LINE | PLOT_STYLE_HAS_POINT | PLOT_STYLE_HAS_ERRORBAR)
+} PLOT_STYLE;
+
+typedef enum PLOT_SMOOTH { 
+    SMOOTH_NONE,
+    SMOOTH_ACSPLINES,
+    SMOOTH_BEZIER,
+    SMOOTH_CSPLINES,
+    SMOOTH_SBEZIER,
+    SMOOTH_UNIQUE
+} PLOT_SMOOTH;
+
+/* FIXME HBB 20000521: 'struct value' and its part, 'cmplx', should go
+ * into one of scanner/internal/standard/util .h, but I've yet to
+ * decide which of them */
+
+#if !(defined(ATARI)&&defined(__GNUC__)&&defined(_MATH_H)) &&  !(defined(MTOS)&&defined(__GNUC__)&&defined(_MATH_H)) /* FF's math.h has the type already */
+struct cmplx {
+	double real, imag;
+};
+#endif
+
+typedef struct value {
+    enum DATA_TYPES type;
+    union {
+	int int_val;
+	struct cmplx cmplx_val;
+    } v;
+} t_value;
+
+#if 0 /* HBB 20000521: move to command.h */
+typedef struct lexical_unit {	/* produced by scanner */
+	TBOOLEAN is_token;	/* true if token, false if a value */ 
+	struct value l_val;
+	int start_index;	/* index of first char in token */
+	int length;			/* length of token in chars */
+} lexical_unit;
+#endif /* 0 */
+
+#if 0 /* HBB 20000521: move to eval.h */
+typedef struct udft_entry {	/* user-defined function table entry */
+  struct udft_entry *next_udf;	/* pointer to next udf in linked list */
+  char *udf_name;		/* name of this function entry */
+  struct at_type *at;		/* pointer to action table to execute */
+  char *definition;		/* definition of function as typed */
+  struct value dummy_values[MAX_NUM_VAR]; /* current value of dummy variables */
+} udft_entry;
+
+
+typedef struct udvt_entry {	/* user-defined value table entry */
+	struct udvt_entry *next_udv; /* pointer to next value in linked list */
+	char *udv_name;			/* name of this value entry */
+	TBOOLEAN udv_undef;		/* true if not defined yet */
+	struct value udv_value;	/* value it has */
+} udvt_entry;
+
+typedef union argument {	/* p-code argument */
+	int j_arg;		/* offset for jump */
+	struct value v_arg;	/* constant value */
+	struct udvt_entry *udv_arg; /* pointer to dummy variable */
+	struct udft_entry *udf_arg; /* pointer to udf to execute */
+} argument;
+
+
+/* This type definition has to come after union argument has been declared. */
+#ifdef __ZTC__
+typedef int (*FUNC_PTR)(...);
+#else
+typedef int (*FUNC_PTR) __PROTO((union argument *arg));
+#endif
+
+typedef struct ft_entry {	/* standard/internal function table entry */
+	const char *f_name;	/* pointer to name of this function */
+	FUNC_PTR func;		/* address of function to call */
+} ft_entry;
+#endif /* 0 */
+
+
+/* Defines the type of a coordinate */
+/* INRANGE and OUTRANGE points have an x,y point associated with them */
+typedef enum coord_type {
+    INRANGE,			/* inside plot boundary */
+    OUTRANGE,			/* outside plot boundary, but defined */
+    UNDEFINED			/* not defined at all */
+} coord_type;
+
+
+typedef struct coordinate {
+    enum coord_type type;	/* see above */
+    double x, y, z;
+    double ylow, yhigh;	/* ignored in 3d */
+    double xlow, xhigh;	/* also ignored in 3d */
+} coordinate;
+
+#endif /* GNUPLOT_GPTYPES_H */
Index: /tags/V_Dec2002/SophyaPI/PIGcont/gpc_misc.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIGcont/gpc_misc.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIGcont/gpc_misc.h	(revision 2309)
@@ -0,0 +1,43 @@
+#ifndef GPC_MISC_H
+#define GPC_MISC_H
+
+#ifndef __cplusplus
+#undef bool
+typedef unsigned int bool;
+#endif
+
+/* TRUE or FALSE */
+#define TBOOLEAN bool
+#define EMPTY_LABELSTRUCT {"", "", 0.0, 0.0}
+#define NO_CARET (-1)
+#define VERYLARGE 1e37
+
+#define MAX_LINE_LEN 1024       /* maximum number of chars allowed on line */
+#define MAX_ID_LEN 50  
+
+#define ZERO 1e-8               /* default for 'zero' set option */
+extern double zero;             /* zero threshold, not 0! */
+
+/** labels **/
+/* The data describing an axis label, or the plot title */
+typedef struct {
+    char text[MAX_LINE_LEN+1];
+    char font[MAX_LINE_LEN+1];
+    double xoffset, yoffset;
+} label_struct;
+
+typedef enum position_type {
+    first_axes,
+    second_axes,
+    graph,
+    screen
+} position_type; 
+
+/* A full 3D position, with all 3 coordinates of different axes,
+ * possibly. Used for 'set label' and 'set arrow' positions: */
+typedef struct position {
+    enum position_type scalex,scaley,scalez;
+    double x,y,z;
+} t_position;
+
+#endif /*ifndef GPC_MISC_H*/
Index: /tags/V_Dec2002/SophyaPI/PIGcont/objlist.list
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIGcont/objlist.list	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIGcont/objlist.list	(revision 2309)
@@ -0,0 +1,5 @@
+gp_alloc.o
+gp_axis.o
+gp_contour.o
+picntools.o
+pigncont.o
Index: /tags/V_Dec2002/SophyaPI/PIGcont/picntools.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIGcont/picntools.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIGcont/picntools.cc	(revision 2309)
@@ -0,0 +1,847 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Outils de manipulation des Contours  O. Perdereau 11/2001
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+// #include <stdlib.h>
+
+#include "machdefs.h"
+#include <string>
+#include <iostream.h>
+
+#include "picntools.h"
+#include "pigncont.h"
+
+//++
+// Class	PICnTools
+// Lib		PIGcont
+// include	pidcntools.h
+//
+//	Classe de fenêtre de dialogue permettant de modifier interactivement
+//	les attributs graphique des "PIContourDrawer" ainsi que 
+//	les parametres de calcul des contours. 
+//--
+// Links	Parents
+// PIWindow
+//--
+//++
+// Links	Voir aussi
+// PIDrawer
+// PIContourDrawer
+//--
+
+//++
+// Titre	Méthodes statiques
+//--
+//++
+// void  ShowPICnTools() 	
+//	Méthode statique permettant l'affichage de la fenêtre de contrôle des
+//	attributs graphiques des "PIContourDrawer". L'instance de la classe
+//	"PICnTools" est créée si nécessaire. Un seul "PIContourDrawer" est gere.      
+// void  HidePICnTools() 
+//	Désactive (cache) la fenêtre "PICnTools" (méthode statique).
+// void  SetCurrentBaseWdg(PIBaseWdgGen* cbw)
+//	Méthode statique permettant de s'attacher au "PIBaseWdg" courant.
+// PIBaseWdgGen*  GetCurrentBaseWdg()
+//	Retourne le "PIBaseWdg" courant (méthode statique).
+// void  SetCurrentCnDrw( PIContourDrawer* pcd) 
+//	Méthode statique permettant de s'attacher au "PIContourDrawer".
+// PIBaseWdgGen*  :GetCurrentCnDrw()
+//	Retourne le "PIContourDrawer" (méthode statique).
+//--
+
+
+PICnTools* PICnTools::cwdrwt = NULL;
+PIBaseWdgGen* PICnTools::mCurBW = NULL;
+PIContourDrawer* PICnTools::mCurCDrw = NULL;
+
+/* --Methode-- */
+void PICnTools::ShowPICnTools() 
+{
+if (cwdrwt == NULL)  cwdrwt = new PICnTools(PIApplicationGetApp());
+// cout << " from PICnTools::ShowPICnTools() - hello "<<endl;
+cwdrwt->Show();
+}
+
+
+/* --Methode-- */
+void PICnTools::HidePICnTools() 
+{
+if (cwdrwt == NULL)  return; 
+cwdrwt->Hide();
+}
+
+void PICnTools::SetCurrentBaseWdg(PIBaseWdgGen* cbw)
+{
+if (mCurBW == cbw) return;
+mCurBW = cbw;
+}
+
+/* --Methode-- */
+PIBaseWdgGen* PICnTools::GetCurrentBaseWdg()
+{
+return(mCurBW);
+}
+/* --Methode-- */
+void PICnTools::SetCurrentCnDrw( PIContourDrawer* pcd) 
+{ 
+ 
+    mCurCDrw = pcd ; 
+}
+
+/* --Methode-- */
+PIContourDrawer*  PICnTools::GetCurrentCnDrw()
+{
+return(mCurCDrw);
+}
+
+/* --Methode-- */
+PICnTools::PICnTools(PIApplication* par)
+: PIWindow((PIMsgHandler*)par, "PIContourTools", PIWK_normal, 240, 240, 150, 150)
+{
+int bsx, bsy, spx, spy;
+
+// On definit la taille a partir de la taille par defaut des composantes 
+// PIApplicationPrefCompSize(bsx, bsy);
+par->PrefCompSize(bsx, bsy);
+
+// Espacements entre elts 
+spx = bsx/10;
+spy = bsy/4;
+
+int wszx = 5*spx+5.5*bsx; 
+int wszy = (1+8*0.85)*bsy+12*(1.85)*spy+15;
+SetSize(wszx, wszy);
+
+//int cpx = spx*2;
+//int offy = cpy+bsy+spy*2;
+
+//  Option-Menu  Marker, Line, couleur, etc...
+int cpx = 2*spx; // current position 
+int cpy = 2*spy;
+
+int bsyo = bsy;  
+int spyo = spy; 
+bsy = 0.85*bsy;   spy = 0.85*spy;
+
+mLab[0] = new PILabel(this, " Couleurs ", 2*bsx, 1.25*bsy, cpx, cpy);
+mLab[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+
+cpx += spx+2*bsx; 
+mOpt[1] = new PIOptMenu(this, "cwt-opt-1", bsx*1.75, bsy, cpx, cpy);
+mOpt[1]->AppendItem("No.CMap", 200);
+int kcc;
+//  Groupement des tables de couleurs
+mCasc[0] = new PIMenu(mOpt[1]->Menu(), "PIStd-128Col");
+mCasc[1] = new PIMenu(mOpt[1]->Menu(), "MIDAS-CMap");
+
+int nsct1,nsct2,nsct3;
+//  D'abord les tables standard de PI  32 couleurs
+nsct1 = 5;   // Les 5 premieres tables
+for(kcc=0; kcc<nsct1; kcc++) 
+  mOpt[1]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(), 201+kcc);
+//  Ensuite les tables standard de PI  128 couleurs
+nsct2 = 9;   // Les 4 tables suivantes
+for(kcc=nsct1; kcc<nsct2; kcc++) 
+  mCasc[0]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(), 201+kcc);
+mOpt[1]->AppendPDMenu(mCasc[0]);
+//  Apres les tables importees de MIDAS
+nsct3 = PIColorMap::NumberStandardColorMaps()-1; // Les reste jusqu'a l'avant derniere
+for(kcc=nsct2; kcc<nsct3; kcc++) 
+  mCasc[1]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(), 201+kcc);
+
+mOpt[1]->AppendPDMenu(mCasc[1]);
+// Les tables qui restent ( Col16 , ... )
+for(kcc=nsct3; kcc<PIColorMap::NumberStandardColorMaps(); kcc++) 
+mOpt[1]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(), 201+kcc);
+
+mOpt[1]->SetValue(200);
+mOpt[1]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+cpx += spx+1.75*bsx;
+
+mOpt[0] = new PIOptMenu(this, "cwt-opt-0", bsx*1.75, bsy, cpx, cpy);
+mOpt[0]->AppendItem("Def.Col", 100);
+mOpt[0]->AppendItem("Black", 101);
+mOpt[0]->AppendItem("White", 102);
+mOpt[0]->AppendItem("Grey", 103);
+mOpt[0]->AppendItem("Red", 104);
+mOpt[0]->AppendItem("Blue", 105);
+mOpt[0]->AppendItem("Green", 106);
+mOpt[0]->AppendItem("Yellow", 107);
+mOpt[0]->AppendItem("Magenta", 108);
+mOpt[0]->AppendItem("Cyan", 109);
+mOpt[0]->AppendItem("Turquoise", 110);
+mOpt[0]->AppendItem("NavyBlue", 111);
+mOpt[0]->AppendItem("Orange", 112);
+mOpt[0]->AppendItem("SiennaRed", 113);
+mOpt[0]->AppendItem("Purple", 114);
+mOpt[0]->AppendItem("LimeGreen", 115);
+mOpt[0]->AppendItem("Gold", 116);
+mOpt[0]->AppendItem("Violet", 117);
+mOpt[0]->AppendItem("VioletRed", 118);
+mOpt[0]->AppendItem("BlueViolet", 119);
+mOpt[0]->AppendItem("DarkViolet", 120);
+mOpt[0]->SetValue(100);
+mOpt[0]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+
+
+cpx = 2*spx;
+cpy += spy+bsyo;
+
+cmapv = new PICMapView(this, "CMapView",wszx-4*spx,20 ,cpx,cpy); 
+cmapv->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+
+
+cpx = 2*spx; // current position 
+cpy += spy+bsy;
+
+// check boxes : lines on/off ; marker on/off 
+mCkb[0] = new PICheckBox(this,"LineON", 2001, bsx, bsy, cpx, cpy);
+mCkb[0]->SetState(false); 
+mCkb[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+// type de ligne pour les niveaux
+cpx += spx+1.75*bsx; 
+mOpt[5] = new PIOptMenu(this, "bwt-opt-5", bsx*1.75, bsy, cpx, cpy);
+mOpt[5]->AppendItem("Def.Line", 600);
+mOpt[5]->AppendItem("Thin-Line", 601);
+mOpt[5]->AppendItem("Normal-Line", 602);
+mOpt[5]->AppendItem("Thick-Line", 603);
+mOpt[5]->AppendItem("ThinDashed", 604);
+mOpt[5]->AppendItem("Dashed-Line", 605);
+mOpt[5]->AppendItem("ThickDashed", 606);
+mOpt[5]->AppendItem("ThinDotted", 607);
+mOpt[5]->AppendItem("Dotted-Line", 608);
+mOpt[5]->AppendItem("ThickDotted", 609);
+mOpt[5]->SetValue(600);
+mOpt[5]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+
+if(mCkb[0]->GetState()==false) 
+  mOpt[5]->SetUnSensitive();
+
+
+cpx = 2*spx;
+cpy += spy+bsy;
+//cpx += spx+bsx; 
+
+mCkb[1] = new PICheckBox(this,"MarkerON", 2002, bsx, bsy, cpx, cpy);
+mCkb[1]->SetState(true); 
+mCkb[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += spx+1.75*bsx; 
+
+mOpt[2] = new PIOptMenu(this, "bwt-opt-2", bsx*1.75, bsy, cpx, cpy);
+mOpt[2]->AppendItem("Def.Mrk", 300);
+mOpt[2]->AppendItem("Mrk Dot(.)", 301);
+mOpt[2]->AppendItem("Mrk Plus(+)", 302);
+mOpt[2]->AppendItem("Mrk Cross(x)", 303);
+mOpt[2]->AppendItem("Mrk Circle", 304);
+mOpt[2]->AppendItem("Mrk FCircle", 305);
+mOpt[2]->AppendItem("Mrk Box", 306);
+mOpt[2]->AppendItem("Mrk FBox", 307);
+mOpt[2]->AppendItem("Mrk Triangle", 308);
+mOpt[2]->AppendItem("Mrk FTriangle", 309);
+mOpt[2]->AppendItem("Mrk Star", 310);
+mOpt[2]->AppendItem("Mrk FStar", 311);
+mOpt[2]->SetValue(300);
+mOpt[2]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+if(mCkb[1]->GetState()==false) 
+  mOpt[2]->SetUnSensitive();
+
+cpx += spx+1.75*bsx; 
+mOpt[3] = new PIOptMenu(this, "bwt-opt-3", bsx*1.75, bsy, cpx, cpy);
+mOpt[3]->AppendItem("Mrk 1 pt", 401);
+mOpt[3]->AppendItem("Mrk 3 pt", 403);
+mOpt[3]->AppendItem("Mrk 5 pt", 405);
+mOpt[3]->AppendItem("Mrk 7 pt", 407);
+mOpt[3]->AppendItem("Mrk 9 pt", 409);
+mOpt[3]->AppendItem("Mrk 11 pt", 411);
+mOpt[3]->AppendItem("Mrk 13 pt", 413);
+mOpt[3]->AppendItem("Mrk 15 pt", 415);
+mOpt[3]->SetValue(405);
+mOpt[3]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+if(mCkb[1]->GetState()==false) 
+  mOpt[3]->SetUnSensitive();
+
+
+
+cpx = 2*spx;
+cpy += spy+bsy;
+mLab[1] = new PILabel(this, " Labels ", 2*bsx, 1.25*bsy, cpx, cpy);
+mLab[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += spx+2*bsx; 
+//  check boxes : label on/off 
+mCkb[2] = new PICheckBox(this,"LabelON", 2003, bsx, bsy, cpx, cpy);
+mCkb[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+mCkb[2]->SetState(false);
+
+// fonte pour les niveaux 
+cpx = 2*spx;
+cpy += spy+bsy;
+mOpt[4] = new PIOptMenu(this, "bwt-opt-4", bsx*1.75, bsy, cpx, cpy);
+mOpt[4]->AppendItem("Def.Font", 500);
+mOpt[4]->AppendItem("Courier", 501);
+mOpt[4]->AppendItem("Helvetica", 502);
+mOpt[4]->AppendItem("Times", 503);
+mOpt[4]->AppendItem("Symbol-Font", 504);
+mOpt[4]->SetValue(500);
+mOpt[4]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+if(mCkb[2]->GetState()==false) mOpt[4]->SetUnSensitive();
+
+
+cpx += spx+1.75*bsx;
+mOpt[6] = new PIOptMenu(this, "bwt-opt-6", bsx*1.75, bsy, cpx, cpy);
+mOpt[6]->AppendItem("Def.FontAtt", 700);
+mOpt[6]->AppendItem("Roman-Font", 701);
+mOpt[6]->AppendItem("Bold-Font", 702);
+mOpt[6]->AppendItem("Italic-Font", 703);
+mOpt[6]->AppendItem("BoldItalic", 704);
+mOpt[6]->SetValue(700);
+mOpt[6]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+if(mCkb[2]->GetState()==false) mOpt[6]->SetUnSensitive();
+
+cpx += spx+1.75*bsx; 
+mOpt[7] = new PIOptMenu(this, "bwt-opt-7", bsx*1.75, bsy, cpx, cpy);
+mOpt[7]->AppendItem("Def.FontSz", 800);
+mOpt[7]->AppendItem("Tiny FontSz", 801);
+mOpt[7]->AppendItem("Small FontSz", 802);
+mOpt[7]->AppendItem("Normal FontSz", 803);
+mOpt[7]->AppendItem("Large FontSz", 804);
+mOpt[7]->AppendItem("Huge FontSz", 805);
+mOpt[7]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+if(mCkb[2]->GetState()==false) mOpt[7]->SetUnSensitive();
+
+cpy += spyo+bsyo;
+cpx = 2*spx;
+mButcf[0] = new PIButton(this, "GetAtt", 2800, bsx, bsy, cpx, cpy);
+mButcf[0]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+
+cpx += bsx+spx;
+mButcf[1] = new PIButton(this, "SetAtt", 2900, bsx, bsy, cpx, cpy);
+mButcf[1]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+
+cpx += bsx+spx;
+mButcf[4] = new PIButton(this, "Refresh", 2950, bsx, bsy, cpx, cpy);
+mButcf[4]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+
+
+cpx = 2*spx;
+cpy += spy+bsyo;
+mLab[2] = new PILabel(this, " params du calcul ", 3*bsx, bsy, cpx, cpy);
+mLab[2]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+
+cpy += spy+bsyo;
+
+mOpt[8] = new PIOptMenu(this, "bwt-opt-8", bsx*1.75, bsy, cpx, cpy);
+mOpt[8]->AppendItem("Int. Lin.", 900);
+mOpt[8]->AppendItem("CubicCpl", 901);
+mOpt[8]->AppendItem("B-Spline", 902);
+mOpt[8]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+
+
+cpx += spx+1.75*bsx;
+mOpt[9] = new PIOptMenu(this, "bwt-opt-9", bsx*1.75, bsy, cpx, cpy);
+mOpt[9]->AppendItem("LevelAuto", 910);
+mOpt[9]->AppendItem("LevelNum ", 911);
+mOpt[9]->AppendItem("LevelInc ", 912);
+mOpt[9]->AppendItem("LevelDisc", 913);
+mOpt[9]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+
+cpy += spy+bsyo;
+cpx = 2*spx;
+
+mLab[3] = new PILabel(this, "Nombre", bsx, bsy, cpx, cpy);
+mLab[3]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+cpx += spx+bsx;
+
+mTxt[0] = new PIText(this, "Nlev",bsx, (int)(bsy*1.3), cpx, cpy);
+mTxt[0]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+mTxt[0]->SetText("5");
+cpx += spx+bsx;
+mLab[4] = new PILabel(this, "Niveaux", bsx, bsy, cpx, cpy);
+mLab[4]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+cpx += spx+bsx;
+mTxt[1] = new PIText(this, "levels",(int)(bsx*2), (int)(bsy*1.3), cpx, cpy);
+mTxt[1]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+
+
+bsy = bsyo; spy = spyo;
+
+
+cpx = (wszx-3.2*bsx-2*spx)/2;
+cpy += 2*spy+bsy;
+mButcf[2] = new PIButton(this, "SetPArm", 3100, bsx*1.2, bsyo, cpx, cpy);
+mButcf[2]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+cpx += bsx*1.2+spx;
+
+cpx += bsx*0.8+spx; 
+
+
+mButcf[3] = new PIButton(this, "Dismiss", 3777, bsx*1.2, bsyo, cpx, cpy);
+mButcf[3]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+
+cwdrwt = this;
+
+}
+
+/* --Methode-- */
+PICnTools::~PICnTools()
+{
+
+if (cwdrwt == this)  cwdrwt = NULL; 
+
+mCurCDrw = NULL;
+int i;
+for(i=0; i<5; i++)  
+  delete mLab[i];
+for(i=0; i<2; i++)  
+  delete mCkb[i];
+
+for(i=0; i<5; i++) delete mButcf[i]; 
+for(i=0; i<2; i++) delete mButdr[i]; 
+for(i=0; i<10; i++)  delete mOpt[i];
+for(i=0; i<2; i++)  delete mCasc[i];
+for(i=0; i<2; i++)  delete mTxt[i];
+
+delete mNlb;
+
+delete cmapv;
+}
+
+//  Declaration des differents attributs graphiques 
+#define MYNMXCOLORS 21
+static PIColors cols[MYNMXCOLORS] = { PI_NotDefColor, 
+                     PI_Black, PI_White, PI_Grey, 
+                     PI_Red, PI_Blue, PI_Green, 
+                     PI_Yellow, PI_Magenta, 
+                     PI_Cyan , PI_Turquoise, PI_NavyBlue, 
+                     PI_Orange, PI_SiennaRed, PI_Purple, 
+                     PI_LimeGreen, PI_Gold, PI_Violet, PI_VioletRed,
+                     PI_BlueViolet, PI_DarkViolet };
+
+static PIMarker mrk[12] = { PI_NotDefMarker, PI_DotMarker, 
+                            PI_PlusMarker, PI_CrossMarker,
+                            PI_CircleMarker, PI_FCircleMarker,
+                            PI_BoxMarker, PI_FBoxMarker,
+                            PI_TriangleMarker, PI_FTriangleMarker,
+                            PI_StarMarker, PI_FStarMarker };
+static PILineAtt line[10] = { PI_NotDefLineAtt, PI_ThinLine, PI_NormalLine, PI_ThickLine, 
+                              PI_ThinDashedLine, PI_DashedLine, PI_ThickDashedLine, 
+                              PI_ThinDottedLine, PI_DottedLine, PI_ThickDottedLine };
+
+static PIFontName fntname[5] = { PI_DefaultFont, PI_CourierFont, PI_HelveticaFont, 
+				 PI_TimesFont, PI_SymbolFont};
+static PIFontAtt fntatt[5] = { PI_NotDefFontAtt, PI_RomanFont, PI_BoldFont, 
+			       PI_ItalicFont, PI_BoldItalicFont };
+static PIFontSize fntsz[6] = { PI_NotDefFontSize, PI_TinySizeFont, PI_SmallSizeFont, 
+			       PI_NormalSizeFont, PI_LargeSizeFont, PI_HugeSizeFont };
+
+/* --Methode-- */
+void PICnTools::Show()
+{
+PIWindow::Show();
+
+mNDr = 0;
+
+
+UpdateAttFromDrawer();
+return;
+}
+// Liste des differentes options de calcul 
+static t_contour_kind crbe_algo[3]={CONTOUR_KIND_LINEAR,CONTOUR_KIND_CUBIC_SPL,CONTOUR_KIND_BSPLINE};
+static t_contour_levels_kind lev_kind[4]={LEVELS_AUTO,LEVELS_NUM,LEVELS_INCREMENTAL,LEVELS_DISCRETE};
+
+/* --Methode-- */
+void PICnTools::UpdateAttFromDrawer()
+{
+
+PIContourDrawer* dr = mCurCDrw;
+
+mOpt[0]->SetValue(100);
+mOpt[1]->SetValue(200);
+mOpt[2]->SetValue(300);
+mOpt[3]->SetValue(405);
+mOpt[4]->SetValue(500);
+mOpt[5]->SetValue(600);
+mOpt[6]->SetValue(700);
+mOpt[7]->SetValue(800);
+mOpt[8]->SetValue(800);
+mOpt[9]->SetValue(800);
+
+// etats des check
+
+
+
+if (!dr)  return;
+
+mCkb[0]->SetState(mCurCDrw->IsLineOn());
+mCkb[1]->SetState(mCurCDrw->IsMarkOn());
+mCkb[2]->SetState(mCurCDrw->IsLabelOn());
+if(mCkb[2]->GetState()==false){ 
+  mOpt[4]->SetUnSensitive();
+  mOpt[6]->SetUnSensitive();
+  mOpt[7]->SetUnSensitive();
+}else {
+  mOpt[4]->SetSensitive();
+  mOpt[6]->SetSensitive();
+  mOpt[7]->SetSensitive();
+}
+
+
+if(mCkb[1]->GetState()==false) {
+  mOpt[3]->SetUnSensitive();
+  mOpt[2]->SetUnSensitive();
+}else{
+  mOpt[3]->SetSensitive();
+  mOpt[2]->SetSensitive();
+}
+
+
+if(mCkb[0]->GetState()==false) 
+  mOpt[5]->SetUnSensitive();
+else
+  mOpt[5]->SetSensitive();
+
+int ii,jj,kk;
+PIColors fc = dr->GetGraphicAtt().GetFgColor();
+for(kk=0; kk<MYNMXCOLORS; kk++) 
+  if (fc == cols[kk])  
+    { mOpt[0]->SetValue(100+kk);  break; }    
+
+
+CMapId cmi = dr->GetGraphicAtt().GetColMapId();
+double zmin=0;
+double zmax=1.;
+if(mCurCDrw!=NULL){
+   zmin = mCurCDrw->Zmin();
+    zmax = mCurCDrw->Zmax();
+}
+
+if (cmi == CMAP_OTHER)  {
+  mOpt[1]->SetValue(200);
+  mCurCDrw->GetGraphicAtt().SetColMapId(CMAP_OTHER);
+  cmapv->SetColMapId(CMAP_OTHER,false, zmin , zmax,true);
+}else for(kk=0; kk<PIColorMap::NumberStandardColorMaps(); kk++)
+  if (cmi == PIColorMap::GetStandardColorMapId(kk)) { 
+    mOpt[1]->SetValue(201+kk);
+    cmapv->SetColMapId(PIColorMap::GetStandardColorMapId(kk),false, zmin , zmax,true);
+    break; 
+  }
+  
+PIMarker mk = dr->GetGraphicAtt().GetMarker();   
+for(kk=0; kk<12; kk++) 
+  if (mk == mrk[kk])   { mOpt[2]->SetValue(300+kk);  break; }
+kk = dr->GetGraphicAtt().GetMarkerSz();
+if (kk < 1)  kk = 1;
+if (kk > 15) kk = 15;
+if (kk%2 == 0) kk++;
+mOpt[3]->SetValue(400+kk);
+PIFontName fnm = dr->GetGraphicAtt().GetFontName();
+PIFontAtt fat = dr->GetGraphicAtt().GetFontAtt();
+PIFontSize fsz = dr->GetGraphicAtt().GetFontSz();
+for(ii=0; ii<5; ii++)
+  if (fnm ==  fntname[ii]) break;
+for(kk=0; kk<5; kk++)
+  if (fat ==  fntatt[kk]) break;
+for(jj=0; jj<5; jj++) 
+  if (fsz == fntsz[jj])  break;
+
+if (ii >= 5) ii = 1;
+if (kk >= 5) kk = 1;
+if (jj >= 6) jj = 3;
+mOpt[4]->SetValue(500+ii);
+mOpt[6]->SetValue(700+kk);
+mOpt[7]->SetValue(800+jj);
+
+PILineAtt lat = dr->GetGraphicAtt().GetLineAtt();
+for(kk=0; kk<10; kk++)
+  if (lat == line[kk])   { mOpt[5]->SetValue(600+kk);  break; }
+
+// parametres pour calcul des niveaux 
+t_contour_kind kind = dr->GetCntKind()  ;
+for (ii=0 ; ii<3 ; ii++)
+  if(crbe_algo[ii]==kind)
+    {mOpt[8]->SetValue(900+ii); break;}
+
+t_contour_levels_kind lvkind = dr->GetCntLevelKind()  ;
+for (ii=0 ; ii<4 ; ii++)
+  if(lev_kind[ii]==lvkind)
+    {mOpt[9]->SetValue(910+ii); break;}
+
+int nlv =  dr->NLevels();
+char txt[24];
+sprintf(txt,"%d",nlv);
+mTxt[0]->SetText(txt);  
+
+if(dr->Levels()!=NULL){
+  string strg=" ";
+  for(int kk=0 ; kk<nlv ; kk++) {
+    //cout << " dr->Level("<<kk<<") "<<endl;
+    cout <<dr->Level(kk)<<endl;
+    if (kk!=nlv-1)
+       sprintf(txt,"%g ,",dr->Level(kk)); 
+    else
+      sprintf(txt,"%g",dr->Level(kk)); 
+
+    strg += txt;
+  }
+  mTxt[1]->SetText(strg);  
+  
+}
+
+
+return;
+}
+
+
+
+
+
+
+
+/* --Methode-- */
+//setting des parms du calcul des crbes de niveau
+void PICnTools::SetCalcParm(){
+
+PIContourDrawer* dr = mCurCDrw;
+if(dr==NULL)return;
+int k,ii,jj,kk;
+
+k = mOpt[8]->GetValue()-900; // type de contour 
+dr->SetCntKind(crbe_algo[k]);
+
+k = mOpt[9]->GetValue()-910; // choix des niveaux des courbes 
+dr->SetCntLevelKind(lev_kind[k]);
+
+string str=mTxt[0]->GetText();
+
+ii=atoi(str.c_str());
+if(ii>0) 
+  dr->SetNLevel(ii);
+else 
+  cerr<< " PICnTools::SetCalcParm ERREUR noombre de contours <=0 "<<ii<<endl;
+char *buff;
+char *tmp;
+str=mTxt[1]->GetText();
+
+buff=strdup(str.c_str());
+double * zlev=NULL;
+//out << " k= "<<k<<endl;
+if(k==2) {
+  zlev = new double[2];
+  tmp = strtok(buff,",");
+  if(tmp ==NULL) {
+    cerr<< " PICnTools::SetCalcParm ERREUR decodage des niveaux impossible avec " << buff <<endl;
+    return;
+  }
+  zlev[0] = atof(tmp);
+  
+  tmp = strtok(NULL,",");
+  if(tmp ==NULL) {
+    cerr<< " PICnTools::SetCalcParm ERREUR decodage des niveaux impossible avec " << buff <<endl;
+    return;
+  }
+  zlev[1]= atof(tmp);
+  dr->SetMyLevels(zlev,2);
+  // cas LEVELS_INCREMENTAL
+}else if (k==3){
+  // cas LEVELS_DISCRETE
+  zlev = new double[ii];
+  tmp = strtok(buff,",");
+  if(tmp ==NULL) {
+    cerr<< " PICnTools::SetCalcParm ERREUR decodage des niveaux impossible dans  " << buff <<endl;
+    return;
+  }
+  int cntr = 0;
+  for(jj=0 ; jj<ii ; jj++){
+      zlev[jj]= atof(tmp);
+      cntr++;
+      //cout << " jj "<<zlev[jj]<<endl;
+      tmp = strtok(NULL,"," );
+      if(tmp == NULL) {
+	
+	break;
+      }
+      cout << " tmp = <"<<tmp<<"<"<<endl;
+
+  }
+  if(cntr<ii) {
+    cerr<< " PICnTools::SetCalcParm ERREUR decodage des niveaux "<<cntr
+	<<" trouves sur "<<ii<<" dans " << buff <<endl;
+    return;
+
+  }
+  dr->SetMyLevels(zlev,ii);
+   
+
+
+}  
+
+//
+//
+
+dr->CalcContour();
+dr->Refresh();
+
+if(zlev!=NULL) {
+  delete[] zlev;
+  zlev=NULL;
+}
+
+}
+
+/* --Methode-- */
+void PICnTools::SetGraphicAtt(bool refr)
+{
+
+  if ( mCurCDrw== NULL )  return;
+  // etats des boutons 
+  
+  mCurCDrw->SetLineOn(mCkb[0]->GetState());
+  mCurCDrw->SetMarkOn(mCkb[1]->GetState());
+  mCurCDrw->SetLabelOn(mCkb[2]->GetState());
+
+  
+  int k,ii,jj,kk;
+  k = mOpt[0]->GetValue()-100; // -> COULEUR 
+  if ( (k < 0) || (k >= MYNMXCOLORS) )  k = 0;
+  mCurCDrw->GetGraphicAtt().SetColAtt(cols[k]);
+  double zmin=0;
+  double zmax=1.;
+  if(mCurCDrw!=NULL){
+    zmin = mCurCDrw->Zmin();
+    zmax = mCurCDrw->Zmax();
+  }
+  
+  k = mOpt[1]->GetValue()-200; // --> COLOR MAP 
+  if (k == 0){
+    mCurCDrw->GetGraphicAtt().SetColMapId(CMAP_OTHER);
+    cmapv->SetColMapId(CMAP_OTHER,false, zmin , zmax,true);
+
+  }else{
+    mCurCDrw->GetGraphicAtt().SetColMapId(PIColorMap::GetStandardColorMapId(k-1));
+    cmapv->SetColMapId(PIColorMap::GetStandardColorMapId(k-1),false, zmin , zmax,true);
+  }
+  k =  mOpt[2]->GetValue()-300; // Marker 
+  if ( (k < 0) || (k > 11) )  k = 0;
+  kk =  mOpt[3]->GetValue()-400; // marker SIZE
+  if ( (kk < 1) || (kk > 27) )  kk = 1;
+  mCurCDrw->GetGraphicAtt().SetMarkerAtt(kk, mrk[k]);
+
+  ii =  (mOpt[4]->GetValue()-500);
+  jj =  (mOpt[6]->GetValue()-700);
+  kk =  (mOpt[7]->GetValue()-800);
+  mCurCDrw->GetGraphicAtt().SetFontAtt(fntname[ii], fntsz[kk], fntatt[jj]);
+
+  k =  mOpt[5]->GetValue()-600;
+  if ( (k < 0) || (k > 9) )  k = 0;
+  mCurCDrw->GetGraphicAtt().SetLineAtt(line[k]);
+
+  if (refr)
+    if (mCurBW !=NULL) 
+      mCurBW->Refresh();
+    else  
+      mCurCDrw->Refresh();
+  else  
+    mCurCDrw->Refresh();
+
+}
+
+/* --Methode-- */
+void PICnTools::Process(PIMessage msg, PIMsgHandler* /*sender*/, void* /*data*/)
+{
+  char strg[64];
+  PIMessage mod = ModMsg(msg);
+  msg = UserMsg(msg);
+  double zmin=0;
+  double zmax=1.;
+  if(mCurCDrw!=NULL){
+    zmin = mCurCDrw->Zmin();
+    zmax = mCurCDrw->Zmax();
+  }
+  
+  if(msg>=200&&msg<300){
+    int k = mOpt[1]->GetValue()-200; // _> COLOR MAP 
+    if (k == 0){
+      cmapv->SetColMapId(CMAP_OTHER,false, zmin , zmax,true);
+      
+    }else{
+      
+      cmapv->SetColMapId(PIColorMap::GetStandardColorMapId(k-1),false , zmin , zmax,true);
+    }
+    
+  }
+  switch (msg) {
+    case 2001 :
+      if(mCkb[0]->GetState()==false) 
+	mOpt[5]->SetUnSensitive();
+      else 
+	mOpt[5]->SetSensitive();
+
+      break;
+
+    case 2002 :
+      if(mCkb[1]->GetState()==false){ 	
+	mOpt[2]->SetUnSensitive();
+	mOpt[3]->SetUnSensitive();
+      }else{	
+	mOpt[2]->SetSensitive();
+	mOpt[3]->SetSensitive();
+      }
+
+    case 2003 :
+      if(mCkb[2]->GetState()==false){ 
+	mOpt[4]->SetUnSensitive();
+	mOpt[6]->SetUnSensitive();
+	mOpt[7]->SetUnSensitive();
+      }else{
+	mOpt[4]->SetSensitive();
+	mOpt[6]->SetSensitive();
+	mOpt[7]->SetSensitive();
+      }
+      
+      
+      break;
+    case 2800 :
+      UpdateAttFromDrawer();
+      break;
+
+    case 2900 :
+      SetGraphicAtt(false);
+      break;
+
+    case 2950 :
+      SetGraphicAtt(true);
+      break;
+
+    case 3100 :
+      SetCalcParm();
+      break;
+
+
+    case 3200 :
+ 
+      break;
+
+    case 3777 :
+      Hide();
+      break;
+
+      /*   On ne change pas les options choisies   Reza+cmv 2/10/98  
+	   mOpt[0]->SetValue(100);
+	   mOpt[1]->SetValue(200);
+	   mOpt[2]->SetValue(300);
+	   mOpt[3]->SetValue(405);
+	   mOpt[4]->SetValue(500);
+	   mOpt[5]->SetValue(600);
+    */
+      break;
+
+    default :
+      break;
+  }
+
+return;
+}
+
+
+
Index: /tags/V_Dec2002/SophyaPI/PIGcont/picntools.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIGcont/picntools.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIGcont/picntools.h	(revision 2309)
@@ -0,0 +1,63 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Outils de manipulation des PIContDrawer  O. Perdereau 11/2001
+// Relatif a un SEUL contourdrawer 
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PICNTOOLS_H_SEEN
+#define PICNTOOLS_H_SEEN
+
+#include "pisysdep.h"
+#include PISTDWDG_H
+#include PIOPTMENU_H
+#include PIWIN_H
+#include PIAPP_H
+#include "picmapview.h"
+
+// --------- fenetre de dialogue pour modifs  options de trace des contours  ----------
+// --------------------------------------------------------------------------------
+
+class PIContourDrawer;
+class PIBaseWdgGen;
+
+class PICnTools : public PIWindow 
+{
+public :
+  PICnTools(PIApplication* par);
+  ~PICnTools();
+  virtual void  Show();
+
+  static PICnTools* curlutw;
+  static void ShowPICnTools();
+  static void HidePICnTools();
+  static void SetCurrentBaseWdg(PIBaseWdgGen* cbw);
+  static void SetCurrentCnDrw(PIContourDrawer* drw);
+  static PIBaseWdgGen* GetCurrentBaseWdg();
+  static PIContourDrawer* GetCurrentCnDrw();
+  inline PICMapView* CMapVW() { return cmapv; }
+protected:
+  virtual void  UpdateAttFromDrawer();
+  virtual void  SetGraphicAtt(bool );
+  virtual void  SetCalcParm();
+  virtual void  Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+
+private:
+// Pour couleur, fontes, etc 
+
+  PICMapView* cmapv;
+  PICheckBox*  mCkb[3];
+  PILabel* mLab[5];
+  PIOptMenu* mOpt[10];
+  PIMenu* mCasc[5];
+  PILabel* mNlb;
+  PIText* mTxt[2];
+  PIButton* mButdr[2];
+  PIButton* mButcf[5];
+  int mNDr;
+  int mtyp, msz;
+//
+  static PIBaseWdgGen* mCurBW;
+  static PIContourDrawer* mCurCDrw;
+  static PICnTools* cwdrwt;
+};
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIGcont/pigncont.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIGcont/pigncont.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIGcont/pigncont.cc	(revision 2309)
@@ -0,0 +1,965 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe d'interface avec le code de GNUplot 
+// pour calculer les contours & classe de trace de contours
+// O. Perdereau
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <iostream.h>
+#include <math.h>
+
+#include "histos.h"
+#include "ntuple.h"
+
+#include "nbtri.h" 
+
+#include "picntools.h"
+#include "pigncont.h"
+
+#include <sys/time.h>
+#include <sys/resource.h>
+
+//++
+// Class	GNUPlotContour
+// Lib		PIGcont
+// include	pigncont.h
+//
+//      Classe d'interface avec le code de GNUplot qui calcule les courbes de niveaux 
+//      GNUplot part d'une grille (structure iso_curve) qui est remplie par les 
+//      createurs 
+//      Les parametres du calcul sont modifiable a partir de la fenetre d'options 
+//      du traceur de contour (classe PIContourDrawer)
+//      Options (reconnues dans un enum t_contour_kind dans GNUplot)
+// 
+//       1) nombre de courbes et et niveaux determines automatiquement par le programme (defaut)
+//          En general, 5 courbes sont tracees LEVELS_AUTO
+// 
+//       2) nombre de niveaux fixe par l'utilisateur. Les niveaux sont equidistants entre 
+//          le min et le max de la surface LEVELS_NUM
+//
+//       3) nombre et hauteurs des niveaux fixes par l'utilisateur. Les niveaux sont passes
+//          dans un tableau LEVELS_DISCRETE
+//
+//       4) nombre niveau min et ecart entre niveaux fixe par l'utilisateur LEVELS_INCREMENTAL
+//         
+//     Les contours sont traces en interpolant entre les points de la grille. 
+//     On peut choisir 3 algorithmes d'interpolation a travers p.ex. les options 
+//     de PIContourDrawer
+//     (enum t_contour_levels_kind ds GNUplot) 
+//
+//       a) interpolation simple CONTOUR_KIND_LINEAR
+//
+//       b) spline cubique       CONTOUR_KIND_CUBIC_SPL
+//
+//       c) B-spline             CONTOUR_KIND_BSPLINE
+//
+//--
+//++
+// Links	Voir aussi
+// PIContourDrawer
+// PICnTools 
+//--
+//++
+// Titre	Constructeurs et Méthodes 
+//--
+//++
+// GNUPlotContour(struct iso_curve * iso) : 
+//         constructeur a partir d'une structure iso_curve
+//         (structure de GNUplot)             
+//--
+
+
+GNUPlotContour::GNUPlotContour(struct iso_curve * iso){
+  int k=0;
+  iso1 = iso;
+  struct iso_curve *iso_cur = iso ;
+  struct iso_curve *iso_old;
+  _xmin = 1.e37;
+  _ymin = 1.e37;
+  _xmax = -1.e37;
+  _ymax = -1.e37;
+  _myiso = NULL;
+  _zmin = 1.e37;
+  _zmax = -1.e37;
+  while(iso_cur){
+    k++;
+    iso_cur = iso_cur->next;
+    _ny = iso_cur->p_count;
+    for(int k=0 ; k<_ny ; k++){
+      double xx=iso->points[k].x;
+      double yy=iso->points[k].y;
+      double zz=iso->points[k].z;
+      if(xx<_xmin) _xmin = xx;
+      if(xx>_xmax) _xmax = xx;
+      if(yy<_ymin) _ymin = yy;
+      if(yy>_ymax) _ymax = yy;
+      if(zz<_zmin) _zmin = zz;
+      if(zz>_zmax) _zmax = zz;
+
+    }
+  }
+
+  _nx = k;
+  _contours = NULL;
+  My_Levels = NULL;
+  
+  _npolys=-1;  
+  _Dxp =_Dyp =1.;
+  _Exy =_Invy =_Invy = FALSE ;
+
+}
+
+
+//++
+// GNUPlotContour(NTupleInterface *nt,int *nz=NULL,double *z=NULL,double *dz=NULL):
+//         constructeur a partir d'un NTupleInterface 
+//         la structure iso_curve est remplie par le constructeur 
+//Inputs 
+//| NTupleInterface *nt 
+//| double *nz nombre de contours (optionnel)
+//| double *z tabelau avec les niveaux des contours (optionnel)
+//| double *dz increment entre contours (optionnel)                
+//--
+GNUPlotContour::GNUPlotContour(NTupleInterface *nt,int *nz=NULL,double *z=NULL,double *dz=NULL){
+  _xmin = 1.e37;
+  _ymin = 1.e37;
+  _xmax = -1.e37;
+  _ymax = -1.e37;
+  _zmin = 1.e37;
+  _zmax = -1.e37;
+  char *nom[4]={"x","y","z","niso"};
+  _myiso = new NTuple(4,nom);  
+  //_myiso->Show();
+  float xnt[4];
+  double mn,mx;
+
+  nt->GetMinMax(0,_xmin,_xmax);
+  nt->GetMinMax(1,_ymin,_ymax);
+  nt->GetMinMax(2,_zmin,_zmax);
+
+  
+  struct iso_curve *istmp = NULL ;
+  struct iso_curve *iso = NULL ;
+  struct iso_curve *iso_old = NULL ;
+  double x,y;
+  int nen = nt->NbLines();
+  
+  // histo des y
+  for(int k= 0 ; k<1000 ; k++){
+    istmp = iso_alloc(100);
+    iso_free(istmp);
+  }
+
+#define NUMPTMIN 25
+#define MAXISO 100
+#define MINISO 5
+
+  Histo prep(_ymin,_ymax,nen);  
+  for(int ix=0 ; ix<nen ; ix++) prep.Add(nt->GetCell(ix,1),1.);
+  Histo Intg = prep;
+  Intg.HInteg(0);
+  //prep.Print();
+  //Intg.Print();
+  float *bin;
+  int *cnt;
+
+  int niso = sqrt( (double)nen);
+  bin = new float[niso+1];
+  cnt = new int[niso+1];
+
+  int i;
+  for(i=0 ; i<niso ; i++){    
+    bin[i] = prep.BinHighEdge(prep.BinPercent( ((double)i)/(double)niso));
+    cnt[i] = Intg(prep.BinPercent( ((double)i)/(double)niso)); 
+  }
+
+  bin[niso]=_ymax;
+  
+  cnt[niso] = prep.NEntries();
+  int numx = 0;
+  int numi = 9999;
+  for(i=0;i<niso ; i++){
+    int numy = cnt[i+1]-cnt[i];
+    
+    if(numy>0){
+      numx = numx>numy ? numx : numy ;
+      numi = numy>numi ? numi : numy ;
+    }
+  }
+
+  
+  if (numi<=0) {
+    
+    return;
+  }
+  _nx = 0;
+  
+  for(i=0;i<niso ; i++){
+    double ymi = bin[i];
+    double ymx = bin[i+1];
+    int numy = cnt[i+1]-cnt[i];
+    
+    if(numy<=0) continue;
+    double *xp;
+    xp = new double[numy];
+    
+    int *indx;
+    indx = new int[numy];
+
+    istmp = iso_alloc(numy) ; // structure temporaire 
+    
+    int ip=0;
+    int ix;
+    for(ix=0 ; ix<nen ; ix++){
+      
+      if(nt->GetCell(ix,1)>=ymi&&nt->GetCell(ix,1)<ymx){
+        
+
+	istmp->points[ip].type = INRANGE;
+	istmp->points[ip].x = nt->GetCell(ix,0);
+	istmp->points[ip].y = nt->GetCell(ix,1);
+	istmp->points[ip].z = nt->GetCell(ix,2);
+	indx[ip] = ip;
+	xp[ip++] = nt->GetCell(ix,0);
+      }      
+    }
+    
+    // tri des points de l'iso_curve 
+    //
+    istmp->p_count = ip;
+    
+    tri_double(xp,indx,ip);
+    
+    // remplissage structure finale 
+    
+    iso = iso_alloc(numx) ;
+    if( _nx == 0 ) iso1 = iso; //premiere structure remplie 
+    if (iso_old) iso_old->next = iso;
+    for(ix=0 ; ix<numy   ; ix++){
+      int jx = indx[ix];
+    
+      
+      iso->points[ix].type = INRANGE ;
+      iso->points[ix].x = istmp->points[jx].x ;
+      iso->points[ix].y = istmp->points[jx].y ;
+      iso->points[ix].z = istmp->points[jx].z ;
+      xnt[0] = iso->points[ix].x;
+      xnt[1] = iso->points[ix].y;
+      xnt[2] = iso->points[ix].z;
+      xnt[3] = _nx;
+      //cout << " fill avec "<<xnt[0]<<"  "<<xnt[1] <<" "<<xnt[2] << " "<<xnt[3]<<endl;
+      // _myiso->Show();
+ 
+      _myiso->Fill(xnt);
+    }
+    //cout << " completion "<<ip<<" =>> "<<numx<<endl;
+    // on complete 
+    for(ix=ip; ix<numx ; ix++ ){
+      int jmx = indx[ip-1];
+      iso->points[ix].type = INRANGE ;
+      iso->points[ix].x = istmp->points[jmx].x ;
+      iso->points[ix].y = istmp->points[jmx].y ;
+      iso->points[ix].z = istmp->points[jmx].z ;
+      xnt[0] = iso->points[ix].x;
+      xnt[1] = iso->points[ix].y;
+      xnt[2] = iso->points[ix].z;
+      xnt[3] = _nx;
+      //cout << " fill avec "<<xnt[0]<<"  "<<xnt[1] <<" "<<xnt[2] << " "<<xnt[3]<<endl;
+      _myiso->Fill(xnt);
+      //_myiso->Show();
+    }
+    
+    iso->p_count = numx;
+
+    iso_old = iso;
+    _nx++;
+    //cout << " destruction structure tempo "<<_nx <<endl;
+    if(istmp){
+      iso_free( istmp );// destruction de la structure temporaire 
+      istmp = NULL;
+    }
+    if(xp){delete[] xp ; xp=NULL;}
+    if(indx) {delete[] indx ; indx = NULL;}
+
+  }
+  //if(_myiso!=NULL)_myiso->Write("myiso.ppf"); 
+  //cout << " fin du remplissage des iso_curves xmin,max "<< _xmin<<","<<_xmax<<" ymin,max "<<_ymin<<","<<_ymax<<endl;
+  _contours = NULL;
+  My_Levels = NULL;
+  _npolys=-1;  
+  Contour_Levels_kind = LEVELS_AUTO ;
+  Contour_kind = CONTOUR_KIND_LINEAR ;
+  set_contour_kind(Contour_kind);
+  Contour_Levels = 5;
+  set_contour_levels(Contour_Levels);
+  set_contour_levels_kind(Contour_Levels_kind);
+  
+ 
+  if(dz!=NULL){
+    My_Levels = new double[2];
+    Contour_Levels = *nz;
+    My_Levels[0] = *z ;
+    My_Levels[1] = *dz;
+    Contour_Levels_kind = LEVELS_INCREMENTAL ;
+    set_contour_levels(Contour_Levels);
+    set_contour_levels_kind(Contour_Levels_kind);
+    set_contour_levels_list(My_Levels);//,2);
+
+  }else  if(nz!=NULL){
+    
+    Contour_Levels = *nz;
+    Contour_Levels_kind = LEVELS_NUM ;
+    set_contour_levels(Contour_Levels);
+    set_contour_levels_kind(Contour_Levels_kind);
+  }
+  
+}
+
+//++
+// GNUPlotContour(P2DArrayAdapter*arr,int *nz=NULL,double *z=NULL,double *dz=NULL):
+//         constructeur a partir d'un P2DArrayAdapter
+//         la structure iso_curve est remplie par le constructeur 
+//Inputs 
+//| P2DArrayAdapter* arr 
+//| double *nz nombre de contours (optionnel)
+//| double *z tabelau avec les niveaux des contours (optionnel)
+//| double *dz increment entre contours (optionnel)                
+//--
+
+GNUPlotContour::GNUPlotContour(P2DArrayAdapter* arr,int *nz=NULL,double *z=NULL,double *dz=NULL){
+  _xmin = 1.e37;
+  _ymin = 1.e37;
+  _xmax = -1.e37;
+  _ymax = -1.e37;
+  _zmin = 1.e37;
+  _zmax = -1.e37;
+  // _nx = arr->XSize()-1;
+  // _ny = arr->YSize()-1;
+   _nx = arr->XSize()  ;
+   _ny = arr->YSize()  ;
+   //cout << " size x,y "<<_nx<<" , "<<_ny <<endl;
+   char *nom[4]={"x","y","z","niso"};
+   
+   _myiso = new NTuple(4,nom);  
+   float xnt[4];
+   struct iso_curve *iso =NULL ;
+   struct iso_curve *iso_old =NULL ;
+   double x,y;
+   // Calcul de la taille en X et en Y d'un pixel
+   double dxp, dyp;
+   double x1,y1;
+   arr->XYfromxy(0,0,x,y);
+   arr->XYfromxy(1,1,x1,y1);
+   _Dxp = (x1-x);
+   _Dyp = (y1-y);
+   double zz;
+   for(int ix=0 ; ix<_nx ; ix++){
+     iso = iso_alloc(_ny) ;
+     if(ix==0) iso1 = iso;
+     if (iso_old) iso_old->next = iso;
+     for(int iy = 0 ; iy<_ny ; iy++){
+       /*i = ix*100+iy;*/
+       arr->XYfromxy(ix,iy,x,y);
+
+       iso->points[iy].type = INRANGE;
+       iso->points[iy].x = x + _Dxp/2.;
+       iso->points[iy].y = y + _Dyp/2.;
+       zz=arr->Value(ix,iy);
+       iso->points[iy].z = zz;
+       //iso->points[iy].z = ((x-25)*(x-25) + (y-25)*(y-25))*.05 ;
+       if(x <_xmin) _xmin = x;
+       if(x >_xmax) _xmax = x;
+       if(y <_ymin) _ymin = y;
+       if(y >_ymax) _ymax = y;
+       if(zz <_zmin) _zmin = zz;
+       if(zz >_zmax) _zmax = zz;
+       //printf("ix=%d iy=%d x=%f y=%f z=%f \n",ix,iy,iso->points[iy].x,iso->points[iy].y,iso->points[iy].z);
+       xnt[0] = iso->points[iy].x;
+       xnt[1] = iso->points[iy].y;
+       xnt[2] = iso->points[iy].z;
+       xnt[3] = _nx;
+
+       _myiso->Fill(xnt);
+     }
+     iso->p_count = _ny;
+     iso_old = iso;
+     /*printf(" remplissage %lx old %lx old next %lx \n",iso,iso_old,iso->next,iso_old->next);*/
+     /*iso->next = iso ;*/
+   }
+   //cout << " fin du remplissage des iso_curves xmin,max "<< _xmin<<","<<_xmax<<" ymin,max "<<_ymin<<","<<_ymax<<endl;
+   _contours = NULL;
+   My_Levels = NULL;
+  _npolys=-1;  
+  Contour_kind = CONTOUR_KIND_LINEAR ;
+  set_contour_kind(Contour_kind);
+  Contour_Levels_kind = LEVELS_AUTO ;
+  Contour_Levels = 5;
+  set_contour_levels(Contour_Levels);
+  set_contour_levels_kind(Contour_Levels_kind);
+  
+
+  if(dz!=NULL){
+    My_Levels = new double[2];
+    Contour_Levels = *nz;
+    My_Levels[0] = *z ;
+    My_Levels[1] = *dz;
+    Contour_Levels_kind = LEVELS_INCREMENTAL ;
+    set_contour_levels(Contour_Levels);
+    set_contour_levels_kind(Contour_Levels_kind);
+    set_contour_levels_list(My_Levels);//,2);
+
+  }else  if(nz!=NULL){
+    Contour_Levels = *nz;
+    Contour_Levels_kind = LEVELS_NUM ;
+    set_contour_levels(Contour_Levels);
+    set_contour_levels_kind(Contour_Levels_kind);
+  }
+  
+}
+
+
+//++
+// ~GNUPlotContour()
+//          
+//       Destructeur        
+//
+//--
+GNUPlotContour::~GNUPlotContour(){
+ cout << " destructeur de GNUPlotContour "<<endl;
+  
+ struct iso_curve *iso_cur;
+ struct iso_curve *iso_nx;
+ iso_cur = iso1;
+ 
+  while(iso_cur){
+    // cout << " ~GNUPlotContour() : destruction de  iso1 "<< iso_cur << endl;
+   iso_nx = iso_cur->next;  
+   iso_free(iso_cur);iso_cur = NULL;
+   
+   iso_cur = iso_nx;
+   
+   }
+ 
+ iso1 = NULL;
+ 
+ struct gnuplot_contours *cntcur = _contours;
+ /*****
+ struct gnuplot_contours *cntold;
+
+ while(cntcur) { 
+   //cout << " ~GNUPlotContour() : destruction de _contours" << _contours <<endl; 
+   cntold = cntcur; 
+   cntcur = cntold->next; 
+   gp_free(cntold); 
+   cntold=NULL; 
+ }  
+ *******/
+ contour_free(cntcur);
+ _contours = NULL;
+
+ if(My_Levels) {
+   //cout << " ~GNUPlotContour() : destruction de MyLevels "<<My_Levels <<endl;
+   delete[] My_Levels; My_Levels=NULL;}
+
+ if(_myiso!=NULL){ delete _myiso; _myiso=NULL;}
+
+} 
+
+
+//++
+// void CalcContour()
+//      Methode de calcul des courbes de niveaux 
+//      par appel a la routine de GNUplot 
+//
+//--
+void GNUPlotContour::CalcContour(){
+  //cout << " GNUPlotContour::CalcContour(): determination des contours "<<endl;
+
+ struct rusage r_usage;
+ int rcus;
+
+ set_contour_kind(Contour_kind);
+ if(Contour_Levels_kind == LEVELS_INCREMENTAL){
+    
+    set_contour_levels(Contour_Levels);
+    set_contour_levels_kind(Contour_Levels_kind);
+    //free_contour_levels_list();
+    set_contour_levels_list(My_Levels);//,2);
+
+  }else  if(Contour_Levels_kind == LEVELS_DISCRETE ){
+    set_contour_levels(Contour_Levels);
+    set_contour_levels_kind(Contour_Levels_kind);
+    //free_contour_levels_list();
+    set_contour_levels_list(My_Levels);//,Contour_Levels);
+    
+  }else  if(Contour_Levels_kind == LEVELS_NUM ){
+    
+    set_contour_levels(Contour_Levels);
+    set_contour_levels_kind(Contour_Levels_kind);
+  }else if(Contour_Levels_kind == LEVELS_AUTO){
+    Contour_Levels = 5;
+    set_contour_levels(Contour_Levels);
+    set_contour_levels_kind(Contour_Levels_kind);
+  }
+
+ 
+ //rcus = getrusage( RUSAGE_SELF , &r_usage);
+
+ //if(rcus==0) 
+ //  cout << " rusage -> "<<  r_usage.ru_maxrss <<" , "<< r_usage.ru_ixrss <<" , "<< r_usage.ru_ixrss <<endl;
+ //else
+ //  perror("1er appel");
+
+ if(_contours) {
+   cout << " GNUPlotContour::CalcContour(): destruction des contours "<<_contours<<endl;
+   struct gnuplot_contours *cntcur = _contours;
+   /******
+   struct gnuplot_contours *cntold; 
+   while(cntcur) { 
+   cout << " GNUPlotContour::CalcContour(): destruction des contours "<< cntcur<<endl; 
+     cntold = cntcur; 
+     cntcur = cntold->next; 
+     gp_free(cntold); 
+     cntold = NULL; 
+   } 
+   ******/
+   contour_free(cntcur);
+   _contours = NULL;
+   
+ }
+
+ //struct gnuplot_contours *cntcur; 
+ //struct gnuplot_contours *cntold;
+ 
+
+ //rcus = getrusage( RUSAGE_SELF , &r_usage);
+ //if(rcus==0) 
+ //  cout << " rusage -> "<< r_usage.ru_maxrss <<" , "<< r_usage.ru_ixrss <<" , "<< r_usage.ru_ixrss <<endl;
+ //else
+ //  perror("2d appel");
+
+
+ _contours = contour (_nx,iso1);
+ 
+
+ //rcus = getrusage( RUSAGE_SELF , &r_usage);
+ //if(rcus==0) 
+ //  cout << " rusage -> "<<  r_usage.ru_maxrss <<" , "<< r_usage.ru_ixrss <<" , "<< r_usage.ru_ixrss <<endl;
+ //else
+ //  perror("3ieme appel");
+
+ //free_contour_levels_list();
+ 
+ 
+}
+//++
+// void SetMyLevels(double *ptr,int k)
+//      Setting du tableau des niveaux des contours 
+//Inputs      
+//| int k : nombre de niveaux 
+//| double *ptr : adresse du tableau des niveaux 
+//--
+void 
+GNUPlotContour::SetMyLevels(double *ptr,int k){
+  
+  if(My_Levels!=NULL) delete My_Levels;
+  My_Levels = new double[k];
+  for(int i=0 ; i<k ; i++)My_Levels[i] = ptr[i];
+}
+//++
+// void SetMyLevels(vector<double>vec)
+//      Setting du tableau des niveaux des contours 
+//Inputs      
+//| 
+//| vector <double> vec  : vecteur des niveaux 
+//--
+void 
+GNUPlotContour::SetMyLevels(vector <double> vec){
+  
+  if(My_Levels!=NULL) delete My_Levels;
+  int sz = vec.size();
+  assert (sz>0);
+
+  My_Levels = new double[sz];
+  for(int i=0 ; i<sz ; i++)
+    My_Levels[i] = vec[i];
+}
+
+//++
+// Class	PIContourDrawer
+// Lib		PIGcont
+// include	pigncont.h
+// 
+//      Classe de traceur de contour qui herite de PIDrawer et de GNUPlotContour 
+//      elle gere les options graphiques generales (couleurs, lignes, fontes,...)
+//      les contours peuvent etre traces avec des lignes ou des markers
+//      on peut afficher les valeurs des niveaux des contours
+//      on peut demander a utiliser une table de couleur 
+//      tout ca a travers la fenetre de controle associee (PICnTools) 
+//
+//--
+//++
+// Links	Parents
+// PIDrawer
+// GNUPlotContour
+//-- 
+//++
+// Links	Voir aussi
+// PICnTools 
+//--
+//++
+// Titre	Constructeurs et Méthodes 
+//--
+//++
+// PIContourDrawer(P2DArrayAdapter* arr,bool autodel,int *nz,double *z0,double *dz )
+// Constructeur a partir d'un P2DArrayAdapter* - voir le createur de GNUPlotContour
+// 
+//--
+
+PIContourDrawer::PIContourDrawer(P2DArrayAdapter* arr,bool autodel,int *nz,double *z0,double *dz )
+  :GNUPlotContour(arr,nz,z0,dz)
+
+{
+  _arr = arr;
+  _nti = NULL;
+  _nz=5;
+  if(nz!=NULL)_nz = *nz;
+  _autodel = autodel;
+
+  // This drawer has specific control tools 
+  mFgSpecContWind = true;
+  InitAtts();
+}
+
+//++
+// PIContourDrawer(NTupleInterface* nti,bool autodel,int *nz,double *z0,double *dz )
+// Constructeur a partir d'un NTupleInterface*  - voir le createur de GNUPlotContour
+// 
+//--
+PIContourDrawer::PIContourDrawer(NTupleInterface* nti,bool autodel,int *nz,double *z0,double *dz )
+  :GNUPlotContour(nti,nz,z0,dz)
+
+{
+  _arr = NULL;
+  _nti = nti;
+  _nz=5;
+  if(nz!=NULL)_nz = *nz;
+  _autodel = autodel;
+  InitAtts();
+}
+
+
+
+/* --Methode-- */
+PIContourDrawer::~PIContourDrawer()
+{
+  if(_autodel){ 
+    if(_arr!=NULL){delete _arr; _arr=NULL;}
+    if(_nti!=NULL){delete _nti ; _nti=NULL;}
+  }
+  DeactivateControlWindow(NULL);
+  //if (mColorMap!=NULL){delete  mColorMap;  mColorMap=NULL;}
+}
+
+/* --Methode-- */
+void PIContourDrawer::Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax)
+{
+  // double xmin, double ymin, double xmax, double ymax LIMITES DE LA ZONE A REFRESHER
+  //PIGrCoord * xx = new PIGrCoord[10];
+  //PIGrCoord * yy = new PIGrCoord[10];
+  PIGrCoord * xx =NULL;
+  PIGrCoord * yy =NULL;
+  PIGrCoord xa;
+  PIGrCoord ya;
+  char buff[64];
+  // On met les bons attributs graphiques
+  //SelGraAtt(g);
+  g->SaveGraphicAtt();
+  struct gnuplot_contours *cntcur;
+  struct gnuplot_contours *cntold;
+  cntcur = _contours;
+
+  double a,b;
+  int tot=0;
+  bool Invx, Invy, Exy;
+  PIColorMap * cmap = NULL;
+  CMapId mcmapid = GetGraphicAtt().GetColMapId();
+  if(mcmapid !=CMAP_OTHER ){
+    cmap = new PIColorMap(mcmapid);
+  }
+  int numdr = 0;
+  while(cntcur){
+    int npts = cntcur->num_pts ;
+    if(npts<0) continue;
+
+    xx = new PIGrCoord[npts];
+    yy = new PIGrCoord[npts];
+    double lev = (cntcur->coords)[0].z ;
+    for(int l=0 ; l< npts ; l++){
+      a = (cntcur->coords)[l].x;
+      b = (cntcur->coords)[l].y;
+      
+      xx[l] = a ;
+      yy[l] = b ;
+
+    }
+
+    // choix de la couleur 
+    
+    g->SelForeground(GetGraphicAtt().GetFgColor());
+    if(mcmapid !=CMAP_OTHER ){
+      if(_zmax-_zmin!=0){
+	int kc = ((lev - _zmin)/(_zmax-_zmin))*cmap->NCol();	
+	
+	g->SelForeground(*cmap,kc);
+      }
+    }    
+    // traitement des  des markers 
+    if(IsMarkOn()==true){
+      
+      g->SelMarker(GetGraphicAtt().GetMarkerSz(), GetGraphicAtt().GetMarker());
+      g->DrawMarkers(xx,yy,npts);
+    }
+    // traitement des lignes 
+    if(mLineOn==true){
+      
+      g->SelLine(GetGraphicAtt().GetLineAtt());
+      g->DrawPolygon(xx,yy,npts,false);
+    }
+    // traitement des labels     
+    // SIMPLISTE POUR L'INSTANT : UN AFFICHAGE 
+    if(mLabelOn==true){
+      // 
+      
+      char strg[10];
+      sprintf(strg,"%g",lev);
+      PIFont myfont(GetGraphicAtt().GetFont());
+      
+      g->SelFont(myfont);
+      double px,py;
+      px = (cntcur->coords)[0].x+2*(Xmax()-Xmin())/100.;
+      py = (cntcur->coords)[0].y;
+      g->DrawString(px,py,strg, PI_HorizontalCenter&&PI_VerticalCenter );
+      
+    }
+    numdr++;
+    delete[] xx;
+    xx=NULL;
+    delete[] yy;
+    yy=NULL;
+    cntcur = cntcur->next;
+    tot++;
+  }    
+  
+  //cout << "PIContourDrawer::Draw  fin de trace des "<<tot<< " polygones "<<endl; 
+ 
+  // 
+  if(cmap !=NULL)delete cmap;
+  
+  g->RestoreGraphicAtt();
+}
+
+/* --Methode-- */
+void PIContourDrawer::UpdateLimits()
+{
+  // Doit calculer les limites
+
+  double xmn = _xmin;
+  double xmx = _xmax;  
+  double ymn = _ymin;
+  double ymx = _ymax;
+  
+  SetLimits(xmn, xmx, ymn, ymx);
+}
+
+
+/* --Methode-- */
+void PIContourDrawer::ShowControlWindow(PIBaseWdgGen* wdg)
+{
+  PICnTools::SetCurrentBaseWdg(wdg);
+  PICnTools::SetCurrentCnDrw(this);
+  PICnTools::ShowPICnTools();
+}
+
+//++
+void PIContourDrawer::DeactivateControlWindow(PIBaseWdgGen* wdg)
+//
+//	Desactivation de la fenetre de controle specialisee
+//--
+{
+  // si wdg != NULL, c'est un Detach (Drawer detache du PIBaseWdg
+  // si wdg == NULL, c'est un delete du PIHisto2D (du PIDrawer)
+  
+  PICnTools::SetCurrentBaseWdg(NULL);
+  PICnTools::SetCurrentCnDrw(NULL);
+  PICnTools::HidePICnTools(); 
+
+  return;
+}
+
+
+/* --Methode-- */
+bool PIContourDrawer::IsLabelOn(){
+  return (mLabelOn);
+}
+
+bool PIContourDrawer::IsLineOn(){
+  return (mLineOn);
+}
+
+bool PIContourDrawer::IsMarkOn(){
+  return (mMarkOn);
+}
+
+void PIContourDrawer::SetLabelOn(bool state){
+  mLabelOn = state;
+}
+
+void PIContourDrawer::SetMarkOn(bool state){
+  mMarkOn = state;
+}
+
+void PIContourDrawer::SetLineOn(bool state){
+  mLineOn = state;
+}
+
+void PIContourDrawer::InitAtts(){
+  mLineOn = true;
+  mMarkOn = false;
+  mLabelOn = false;
+}
+
+int PIContourDrawer::DecodeOptionString(vector<string> & opt, bool rmdecopt)
+{
+  // inspire de int PINTuple::DecodeOptionString
+  // OP 11/2002 LAL Orsay
+  
+  int ndec = opt.size();
+  if (ndec < 1)  return(0);  
+
+
+  cout << " PIDrawer::DecodeOptionString  : ndec = "<< ndec <<endl;
+  // On appelle d'abord le decodage de la classe PIDrawer de laquelle
+  // on herite. (Pas obligatoire) on decode donc ici les attributs de
+  // couleur, fontes ...
+  int ndec1 = PIDrawer::DecodeOptionString(opt, rmdecopt);
+  cout << " PIDrawer::DecodeOptionString apres PIDrawer::DecodeOptionString : ndec = "
+       << ndec1 <<"<>" << ndec <<endl;
+  if( ndec - ndec1 < 1 ) return(ndec1);  // si tout a ete decode
+
+  vector<string> udopt;  // On gardera ici les options non decodees
+  int iopt  = 0;
+  ndec = opt.size();
+  int recalc = 0;
+  for (iopt = 0 ; iopt<ndec ; iopt++){
+
+    string sopt = opt[iopt];
+    if( sopt.find_first_of("=") != string::npos ){
+      // options avec = 
+      string deb = sopt.substr(0,sopt.find_first_of("="));
+      cout << " option avec =  : "<<deb<<" "<<sopt<<endl;
+      if( (deb =="ncont") || (deb =="nc") ){ // # de contours 
+	string fin =  sopt.substr(sopt.find_first_of("=")+1 , string::npos);
+	cout <<" fin "<<fin<<endl;
+	int nlev = atoi(fin.c_str());
+	this->SetNLevel(nlev);
+	this->SetCntLevelKind(LEVELS_NUM);
+	recalc =1;
+      }else if(deb=="niv"||deb=="lev"){ // hauteur des niveaux 
+	string fin =  sopt.substr(sopt.find_first_of("=")+1 , string::npos);
+	char * buff = strdup(fin.c_str());
+	char *tmp;
+	tmp = strtok(buff,",");
+	
+	if(tmp==NULL){
+	   cerr<< " PICOntourDrawer::DecodeOptionString ERREUR decodage des niveaux impossible " << buff <<endl;
+	  
+	}else {
+	
+	  vector <double> ztmp;
+	  while(tmp!=NULL){
+	    ztmp.push_back(atof(tmp));
+	    tmp = strtok(NULL,",");
+	  }
+	  int nlev = ztmp.size();
+	  cout << "  PICOntourDrawer::DecodeOptionString "<<nlev<<" niveaux decodes "<<endl; 
+	  this->SetCntLevelKind(LEVELS_DISCRETE);
+	  this->SetNLevel(nlev); 
+	  this->SetMyLevels(ztmp);
+	  recalc =1;
+	}
+      }else if(deb=="lstep" ){ // niveaux incrementaux : args = nombre,depart,pas
+	string fin =  sopt.substr(sopt.find_first_of("=")+1 , string::npos);
+	char * buff = strdup(fin.c_str());
+	char *tmp;
+	tmp = strtok(buff,",");
+	
+	if(tmp==NULL){
+	  cerr<< " PICOntourDrawer::DecodeOptionString ERREUR decodage nvx/incr. impossible " << buff <<endl;
+	}else{
+	  
+	  vector <double> ztmp;
+	  while(tmp!=NULL){
+	    ztmp.push_back(atof(tmp));
+	    tmp = strtok(NULL,",");
+	  }
+	  if(ztmp.size() !=2) {
+	    cerr<< " PICOntourDrawer::DecodeOptionString ERREUR nb params incorrect(incr) " << buff <<endl;
+	  }else{
+	    vector <double> zlev;
+	    zlev.push_back(ztmp[1]);
+	    zlev.push_back(ztmp[2]);
+	    this->SetCntLevelKind(LEVELS_INCREMENTAL);
+	    this->SetNLevel( (int) ztmp[0]); 
+	    this->SetMyLevels(zlev);
+	    recalc=1;
+	  }
+	}
+
+      }else{
+	cout<<"PICOntourDrawer::DecodeOptionString ERREUR  option "<<sopt<<" non reconnue "<<endl;
+	ndec--;
+	if (rmdecopt)  udopt.push_back( sopt );
+      }
+    }else{ //options sans "="
+      if( sopt == "labon" )
+	this->SetLabelOn();
+      else if (sopt == "bspline" ){
+	this->SetCntKind(CONTOUR_KIND_BSPLINE);
+	recalc = 1;
+      }else if (sopt == "3spl" ){
+	this->SetCntKind(CONTOUR_KIND_CUBIC_SPL);
+	recalc = 1;
+      }
+      else{
+	cout<<"PICOntourDrawer::DecodeOptionString ERREUR  option "<<sopt<<" non reconnue "<<endl;
+	ndec--;
+	if (rmdecopt)  udopt.push_back(sopt);
+      }
+    }
+    
+  }// FIN DE LA BOUCLE SUR LES OPTIONS 
+
+  if(recalc==1){
+    // il faut (re)calculer les contours 
+    cout << " PICOntourDrawer::DecodeOptionString(re)calcul des contours "<<endl;
+    this->CalcContour(); 
+  }
+  this->Refresh();
+
+  
+  //
+
+  // S'il faut supprimer les options decodees, on remplace l'argument opt
+  // par le vecteur des options non decodees.
+  if (rmdecopt)  opt = udopt;
+
+  return(ndec+ndec1);  
+  
+}
+
+
+ 
Index: /tags/V_Dec2002/SophyaPI/PIGcont/pigncont.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIGcont/pigncont.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIGcont/pigncont.h	(revision 2309)
@@ -0,0 +1,112 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe  GNUPlotContour   : interface avec le code de gnuplot pour tracer les contours
+// Classe  PIContourDrawer  : trace des contours dans PI 
+// (c) DAPNIA (CEA)                 LAL (IN2P3/CNRS)
+//                           R. Ansari O.Perdereau  11/2001
+//=========================================================//
+
+#ifndef PIGNCONT_H_SEEN 
+#define PIGNCONT_H_SEEN 
+#include "pistdimgapp.h"
+#include "piscdrawwdg.h"
+
+#include "ntuple.h"
+extern "C" { 
+#include "gp_contour.h"
+#include "gp_alloc.h"
+  //#include "gpc_set.h"
+}
+
+class GNUPlotContour{
+public:
+  GNUPlotContour(P2DArrayAdapter*,int *nz,double *z0,double *dz);
+  GNUPlotContour(NTupleInterface *nt,int *nz,double *z0,double *dz);
+  GNUPlotContour(struct iso_curve *);
+  ~GNUPlotContour();
+  void CalcContour();
+  double Level(int i){return My_Levels[i];};
+  const double *Levels(){return My_Levels;};
+  void SetMyLevels(double *ptr,int k);
+  void SetMyLevels(vector <double> vec);
+  int NLevels(){return Contour_Levels;};
+  void SetNLevel(int n){Contour_Levels=n;};
+  int NContours(){return _npolys;};
+  void SetCntLevelKind(t_contour_levels_kind kind){Contour_Levels_kind = kind;};
+  t_contour_levels_kind GetCntLevelKind(){return Contour_Levels_kind ;};
+  void SetCntKind(t_contour_kind kind){Contour_kind = kind;};
+  t_contour_kind GetCntKind(){return Contour_kind ;};
+
+
+  NTuple * & MyIso(){return  _myiso;};
+
+  double Xmin(){return _xmin;};
+  double Xmax(){return _xmax;};
+  double Ymin(){return _ymin;};
+  double Ymax(){return _ymax;};
+  double Zmin(){return _zmin;};
+  double Zmax(){return _zmax;};
+
+private: 
+
+protected: 
+  NTuple * _myiso;
+  int _nx,_ny;
+  struct iso_curve *iso1 ;
+  bool _Invx,_Invy,_Exy;
+  double _Dxp, _Dyp;
+  struct gnuplot_contours *_contours;
+  int Contour_Levels;
+  
+  double *My_Levels; 
+  
+  double _xmin,_xmax,_ymin,_ymax,_zmin,_zmax;
+  int _npolys;
+  t_contour_levels_kind Contour_Levels_kind;
+  t_contour_kind Contour_kind;
+  
+  
+};
+
+class PIContourDrawer : public PIDrawer, public GNUPlotContour{
+public:
+                    PIContourDrawer(P2DArrayAdapter* arr,bool autodel ,int *nz=NULL,double *z0=NULL,double *dz=NULL);
+                    PIContourDrawer(NTupleInterface* nti,bool autodel ,int *nz=NULL,double *z0=NULL,double *dz=NULL);
+  virtual           ~PIContourDrawer();
+  virtual void      Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax);
+  virtual void      UpdateLimits();
+  virtual bool      IsLineOn();
+  virtual bool      IsMarkOn();  
+  virtual bool      IsLabelOn();
+  virtual void      SetLineOn(bool b=true);
+  virtual void      SetMarkOn(bool b=true);
+  virtual void      SetLabelOn(bool b=true);
+
+  //Init  attributs graphiques 
+
+  void InitAtts();  
+  
+  
+//  Methode permettant l'affichage d'une fenetre de controle specialisee 
+  virtual void      ShowControlWindow(PIBaseWdgGen* wdg);
+  //  Desactivation de la fenetre de controle specialisee
+  virtual void DeactivateControlWindow(PIBaseWdgGen* wdg);
+//   Methode permettant de decoder des options a partir de chaines
+  int        DecodeOptionString(vector<string> & opt, bool rmdecopt=true);
+
+
+protected:
+  bool _autodel;
+  int _nz;
+  P2DArrayAdapter* _arr;
+  NTupleInterface* _nti;
+  bool mLineOn,mMarkOn,mLabelOn;
+  
+
+  
+
+};
+
+
+//
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/Makefile
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/Makefile	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/Makefile	(revision 2309)
@@ -0,0 +1,2018 @@
+MODULECXXREPNAME := PI
+MODULEDECCXXFLAGS := -msg_quiet
+include ../Mgr/Makefile.h
+ 
+all: $(LIB)libPIext.a
+$(LIB)libPIext.a : $(OBJ)basexecut.o $(OBJ)contmodex.o $(OBJ)cxxexecutor.o $(OBJ)cxxexecwin.o $(OBJ)flowmodex.o $(OBJ)nobjmgr.o $(OBJ)nomgadapter.o $(OBJ)nomgfdadapter.o $(OBJ)nomhistadapter.o $(OBJ)nomimagadapter.o $(OBJ)nomskymapadapter.o $(OBJ)nomspecrespadapter.o $(OBJ)nomtarradapter.o $(OBJ)nomtmatvecadapter.o $(OBJ)pawexecut.o $(OBJ)pi2dvec.o $(OBJ)piacmd.o $(OBJ)piafitting.o $(OBJ)pigfd1.o $(OBJ)pigfd2.o $(OBJ)pihisto.o $(OBJ)pihisto2d.o $(OBJ)piinit.o $(OBJ)pintup3d.o $(OBJ)pintuple.o $(OBJ)pipodrw.o $(OBJ)pisiadw.o $(OBJ)pistdimgapp.o $(OBJ)pitvmaad.o $(OBJ)servnobjm.o
+	$(AR) $(ARFLAGS)  $@ $($(ARARGS)) 
+ifeq ($(CXX),cxx)
+	$(CXX) $? $(CPPFLAGS) $(CXXFLAGS) -o $(OBJ)xx.x -Hf
+endif 
+ 
+clean:
+	rm -f $(OBJ)basexecut.o $(OBJ)contmodex.o $(OBJ)cxxexecutor.o $(OBJ)cxxexecwin.o $(OBJ)flowmodex.o $(OBJ)nobjmgr.o $(OBJ)nomgadapter.o $(OBJ)nomgfdadapter.o $(OBJ)nomhistadapter.o $(OBJ)nomimagadapter.o $(OBJ)nomskymapadapter.o $(OBJ)nomspecrespadapter.o $(OBJ)nomtarradapter.o $(OBJ)nomtmatvecadapter.o $(OBJ)pawexecut.o $(OBJ)pi2dvec.o $(OBJ)piacmd.o $(OBJ)piafitting.o $(OBJ)pigfd1.o $(OBJ)pigfd2.o $(OBJ)pihisto.o $(OBJ)pihisto2d.o $(OBJ)piinit.o $(OBJ)pintup3d.o $(OBJ)pintuple.o $(OBJ)pipodrw.o $(OBJ)pisiadw.o $(OBJ)pistdimgapp.o $(OBJ)pitvmaad.o $(OBJ)servnobjm.o
+ifeq ($(CXX),cxx)
+	cd $(REPM); rm -f *.o
+endif 
+ 
+$(OBJ)basexecut.o: basexecut.cc piacmd.h \
+ $(INC)machdefs.h dlftypes.h \
+ $(INC)pdlmgr.h \
+ $(INC)ctimer.h basexecut.h pistdimgapp.h \
+ $(INC)pisysdep.h \
+ $(INC)piapplx.h \
+ $(INC)piapplgen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picontainerx.h \
+ $(INC)picontainergen.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)picolist.h \
+ $(INC)pimenubarx.h \
+ $(INC)pimenubargen.h \
+ $(INC)pimenux.h \
+ $(INC)pimenugen.h \
+ $(INC)picons.h \
+ $(INC)pistdwdgx.h \
+ $(INC)pistdwdggen.h \
+ $(INC)pibwdgx.h \
+ $(INC)pibwdggen.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigraphps.h \
+ $(INC)piwindowx.h \
+ $(INC)piwindowgen.h \
+ $(INC)pioptmenux.h \
+ $(INC)pioptmenugen.h \
+ $(INC)pifilechox.h \
+ $(INC)pifilechogen.h \
+ $(INC)piperiodx.h \
+ $(INC)periodic.h \
+ $(INC)piimage.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)pieldrw.h \
+ $(INC)pidrawer.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h \
+ $(INC)pipixmapx.h \
+ $(INC)pipixmapgen.h \
+ $(INC)picmapview.h \
+ $(INC)pi3dwdg.h \
+ $(INC)pi3ddrw.h \
+ $(INC)pigraph3d.h nobjmgr.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)mutyv.h pisiadw.h \
+ $(INC)pilistx.h \
+ $(INC)pilistgen.h \
+ $(INC)pistzwin.h \
+ $(INC)pitherm.h \
+ $(INC)resusage.h servnobjm.h \
+ $(INC)histos.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)fmath.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)histos2.h \
+ $(INC)hisprof.h \
+ $(INC)ntuple.h \
+ $(INC)ntupintf.h \
+ $(INC)generaldata.h \
+ $(INC)poly.h
+$(OBJ)contmodex.o: contmodex.cc contmodex.h \
+ $(INC)machdefs.h piacmd.h dlftypes.h \
+ $(INC)pdlmgr.h \
+ $(INC)ctimer.h nobjmgr.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)mutyv.h \
+ $(INC)pigncont.h \
+ $(INC)pistdimgapp.h \
+ $(INC)pisysdep.h \
+ $(INC)piapplx.h \
+ $(INC)piapplgen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picontainerx.h \
+ $(INC)picontainergen.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)picolist.h \
+ $(INC)pimenubarx.h \
+ $(INC)pimenubargen.h \
+ $(INC)pimenux.h \
+ $(INC)pimenugen.h \
+ $(INC)picons.h \
+ $(INC)pistdwdgx.h \
+ $(INC)pistdwdggen.h \
+ $(INC)pibwdgx.h \
+ $(INC)pibwdggen.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigraphps.h \
+ $(INC)piwindowx.h \
+ $(INC)piwindowgen.h \
+ $(INC)pioptmenux.h \
+ $(INC)pioptmenugen.h \
+ $(INC)pifilechox.h \
+ $(INC)pifilechogen.h \
+ $(INC)piperiodx.h \
+ $(INC)periodic.h \
+ $(INC)piimage.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)pieldrw.h \
+ $(INC)pidrawer.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h \
+ $(INC)pipixmapx.h \
+ $(INC)pipixmapgen.h \
+ $(INC)picmapview.h \
+ $(INC)pi3dwdg.h \
+ $(INC)pi3ddrw.h \
+ $(INC)pigraph3d.h \
+ $(INC)nobjmgr.h \
+ $(INC)piacmd.h \
+ $(INC)pisiadw.h \
+ $(INC)pilistx.h \
+ $(INC)pilistgen.h \
+ $(INC)pistzwin.h \
+ $(INC)pitherm.h \
+ $(INC)resusage.h \
+ $(INC)piscdrawwdg.h \
+ $(INC)ntuple.h \
+ $(INC)ntupintf.h \
+ $(INC)gp_contour.h \
+ $(INC)gp_types.h \
+ $(INC)gpc_misc.h \
+ $(INC)gp_dynarray.h \
+ $(INC)gp_graph3d.h \
+ $(INC)gp_alloc.h nomgadapter.h \
+ $(INC)generalfit.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)generaldata.h \
+ $(INC)poly.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)fmath.h servnobjm.h
+$(OBJ)cxxexecutor.o: cxxexecutor.cc cxxexecutor.h \
+ $(INC)machdefs.h piacmd.h dlftypes.h \
+ $(INC)pdlmgr.h \
+ $(INC)ctimer.h nobjmgr.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)mutyv.h \
+ $(INC)strutilxx.h \
+ $(INC)cxxcmplnk.h nomgadapter.h \
+ $(INC)pidrawer.h \
+ $(INC)pibwdggen.h \
+ $(INC)pisysdep.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picolist.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)ntupintf.h \
+ $(INC)generalfit.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)generaldata.h \
+ $(INC)poly.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)fmath.h pistdimgapp.h \
+ $(INC)piapplx.h \
+ $(INC)piapplgen.h \
+ $(INC)picontainerx.h \
+ $(INC)picontainergen.h \
+ $(INC)pimenubarx.h \
+ $(INC)pimenubargen.h \
+ $(INC)pimenux.h \
+ $(INC)pimenugen.h \
+ $(INC)picons.h \
+ $(INC)pistdwdgx.h \
+ $(INC)pistdwdggen.h \
+ $(INC)pibwdgx.h \
+ $(INC)pigraphps.h \
+ $(INC)piwindowx.h \
+ $(INC)piwindowgen.h \
+ $(INC)pioptmenux.h \
+ $(INC)pioptmenugen.h \
+ $(INC)pifilechox.h \
+ $(INC)pifilechogen.h \
+ $(INC)piperiodx.h \
+ $(INC)periodic.h \
+ $(INC)piimage.h \
+ $(INC)pieldrw.h \
+ $(INC)pipixmapx.h \
+ $(INC)pipixmapgen.h \
+ $(INC)picmapview.h \
+ $(INC)pi3dwdg.h \
+ $(INC)pi3ddrw.h \
+ $(INC)pigraph3d.h pisiadw.h \
+ $(INC)pilistx.h \
+ $(INC)pilistgen.h \
+ $(INC)pistzwin.h \
+ $(INC)pitherm.h \
+ $(INC)resusage.h
+$(OBJ)cxxexecwin.o: cxxexecwin.cc cxxexecutor.h \
+ $(INC)machdefs.h piacmd.h dlftypes.h \
+ $(INC)pdlmgr.h \
+ $(INC)ctimer.h nobjmgr.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)mutyv.h cxxexecwin.h \
+ $(INC)pisysdep.h pistdimgapp.h \
+ $(INC)piapplx.h \
+ $(INC)piapplgen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picontainerx.h \
+ $(INC)picontainergen.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)picolist.h \
+ $(INC)pimenubarx.h \
+ $(INC)pimenubargen.h \
+ $(INC)pimenux.h \
+ $(INC)pimenugen.h \
+ $(INC)picons.h \
+ $(INC)pistdwdgx.h \
+ $(INC)pistdwdggen.h \
+ $(INC)pibwdgx.h \
+ $(INC)pibwdggen.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigraphps.h \
+ $(INC)piwindowx.h \
+ $(INC)piwindowgen.h \
+ $(INC)pioptmenux.h \
+ $(INC)pioptmenugen.h \
+ $(INC)pifilechox.h \
+ $(INC)pifilechogen.h \
+ $(INC)piperiodx.h \
+ $(INC)periodic.h \
+ $(INC)piimage.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)pieldrw.h \
+ $(INC)pidrawer.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h \
+ $(INC)pipixmapx.h \
+ $(INC)pipixmapgen.h \
+ $(INC)picmapview.h \
+ $(INC)pi3dwdg.h \
+ $(INC)pi3ddrw.h \
+ $(INC)pigraph3d.h pisiadw.h \
+ $(INC)pilistx.h \
+ $(INC)pilistgen.h \
+ $(INC)pistzwin.h \
+ $(INC)pitherm.h \
+ $(INC)resusage.h
+$(OBJ)flowmodex.o: flowmodex.cc flowmodex.h \
+ $(INC)machdefs.h piacmd.h dlftypes.h \
+ $(INC)pdlmgr.h \
+ $(INC)ctimer.h nobjmgr.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)mutyv.h pi2dvec.h pistdimgapp.h \
+ $(INC)pisysdep.h \
+ $(INC)piapplx.h \
+ $(INC)piapplgen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picontainerx.h \
+ $(INC)picontainergen.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)picolist.h \
+ $(INC)pimenubarx.h \
+ $(INC)pimenubargen.h \
+ $(INC)pimenux.h \
+ $(INC)pimenugen.h \
+ $(INC)picons.h \
+ $(INC)pistdwdgx.h \
+ $(INC)pistdwdggen.h \
+ $(INC)pibwdgx.h \
+ $(INC)pibwdggen.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigraphps.h \
+ $(INC)piwindowx.h \
+ $(INC)piwindowgen.h \
+ $(INC)pioptmenux.h \
+ $(INC)pioptmenugen.h \
+ $(INC)pifilechox.h \
+ $(INC)pifilechogen.h \
+ $(INC)piperiodx.h \
+ $(INC)periodic.h \
+ $(INC)piimage.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)pieldrw.h \
+ $(INC)pidrawer.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h \
+ $(INC)pipixmapx.h \
+ $(INC)pipixmapgen.h \
+ $(INC)picmapview.h \
+ $(INC)pi3dwdg.h \
+ $(INC)pi3ddrw.h \
+ $(INC)pigraph3d.h pisiadw.h \
+ $(INC)pilistx.h \
+ $(INC)pilistgen.h \
+ $(INC)pistzwin.h \
+ $(INC)pitherm.h \
+ $(INC)resusage.h \
+ $(INC)piscdrawwdg.h \
+ $(INC)ntupintf.h \
+ $(INC)ntuple.h nomgadapter.h \
+ $(INC)generalfit.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)generaldata.h \
+ $(INC)poly.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)fmath.h servnobjm.h
+$(OBJ)nobjmgr.o: nobjmgr.cc $(INC)strutil.h \
+ $(INC)datatypes.h \
+ $(INC)machdefs.h nobjmgr.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)mutyv.h dlftypes.h servnobjm.h \
+ $(INC)pdlmgr.h nomgadapter.h \
+ $(INC)pidrawer.h \
+ $(INC)pibwdggen.h \
+ $(INC)pisysdep.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picolist.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)ntupintf.h \
+ $(INC)generalfit.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)generaldata.h \
+ $(INC)poly.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)fmath.h pistdimgapp.h \
+ $(INC)piapplx.h \
+ $(INC)piapplgen.h \
+ $(INC)picontainerx.h \
+ $(INC)picontainergen.h \
+ $(INC)pimenubarx.h \
+ $(INC)pimenubargen.h \
+ $(INC)pimenux.h \
+ $(INC)pimenugen.h \
+ $(INC)picons.h \
+ $(INC)pistdwdgx.h \
+ $(INC)pistdwdggen.h \
+ $(INC)pibwdgx.h \
+ $(INC)pigraphps.h \
+ $(INC)piwindowx.h \
+ $(INC)piwindowgen.h \
+ $(INC)pioptmenux.h \
+ $(INC)pioptmenugen.h \
+ $(INC)pifilechox.h \
+ $(INC)pifilechogen.h \
+ $(INC)piperiodx.h \
+ $(INC)periodic.h \
+ $(INC)piimage.h \
+ $(INC)pieldrw.h \
+ $(INC)pipixmapx.h \
+ $(INC)pipixmapgen.h \
+ $(INC)picmapview.h \
+ $(INC)pi3dwdg.h \
+ $(INC)pi3ddrw.h \
+ $(INC)pigraph3d.h piacmd.h \
+ $(INC)ctimer.h pisiadw.h \
+ $(INC)pilistx.h \
+ $(INC)pilistgen.h \
+ $(INC)pistzwin.h \
+ $(INC)pitherm.h \
+ $(INC)resusage.h \
+ $(INC)fitsautoreader.h \
+ $(INC)fitsfile.h \
+ $(EXTINCPATH)FitsIO/fitsio.h \
+ $(EXTINCPATH)FitsIO/longnam.h \
+ $(INC)fitstarray.h \
+ $(INC)fitsspherehealpix.h \
+ $(INC)spherehealpix.h \
+ $(INC)sphericalmap.h \
+ $(INC)smathconst.h \
+ $(INC)pixelmap.h \
+ $(INC)spherepos.h \
+ $(INC)unitvector.h \
+ $(INC)vector3d.h \
+ $(INC)longlat.h \
+ $(INC)utilgeom.h \
+ $(INC)HEALPixUtils.h \
+ $(INC)fitsntuple.h \
+ $(INC)ntuple.h \
+ $(INC)fitsxntuple.h \
+ $(INC)xntuple.h \
+ $(INC)fitslocalmap.h \
+ $(INC)localmap.h \
+ $(INC)fbtntintf.h pitvmaad.h \
+ $(INC)piyfxdrw.h \
+ $(INC)pisurfdr.h pipodrw.h \
+ $(INC)histos2.h \
+ $(INC)histos.h pintuple.h pintup3d.h \
+ pigfd1.h pigfd2.h
+$(OBJ)nomgadapter.o: nomgadapter.cc \
+ $(INC)machdefs.h nomgadapter.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)anydataobj.h \
+ $(INC)pidrawer.h \
+ $(INC)pibwdggen.h \
+ $(INC)pisysdep.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picolist.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)ntupintf.h \
+ $(INC)generalfit.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)generaldata.h \
+ $(INC)poly.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)fmath.h
+$(OBJ)nomgfdadapter.o: nomgfdadapter.cc \
+ $(INC)machdefs.h nomgfdadapter.h \
+ nomgadapter.h $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)anydataobj.h \
+ $(INC)pidrawer.h \
+ $(INC)pibwdggen.h \
+ $(INC)pisysdep.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picolist.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)ntupintf.h \
+ $(INC)generalfit.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)generaldata.h \
+ $(INC)poly.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)fmath.h pipodrw.h \
+ $(INC)histos2.h \
+ $(INC)histos.h \
+ $(INC)objfitter.h \
+ $(INC)cimage.h \
+ $(INC)fioarr.h \
+ $(INC)hisprof.h
+$(OBJ)nomhistadapter.o: nomhistadapter.cc \
+ $(INC)machdefs.h nomhistadapter.h \
+ nomgadapter.h $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)anydataobj.h \
+ $(INC)pidrawer.h \
+ $(INC)pibwdggen.h \
+ $(INC)pisysdep.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picolist.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)ntupintf.h \
+ $(INC)generalfit.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)generaldata.h \
+ $(INC)poly.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)fmath.h \
+ $(INC)histos.h \
+ $(INC)histos2.h \
+ $(INC)hisprof.h \
+ $(INC)ntuple.h \
+ $(INC)xntuple.h pihisto.h pihisto2d.h \
+ $(INC)pimenux.h \
+ $(INC)pimenugen.h \
+ $(INC)pimenubarx.h \
+ $(INC)pimenubargen.h \
+ $(INC)pioptmenux.h \
+ $(INC)pioptmenugen.h \
+ $(INC)pistdwdgx.h \
+ $(INC)pistdwdggen.h \
+ $(INC)piscdrawwdg.h \
+ $(INC)pibwdgx.h \
+ $(INC)pigraphps.h \
+ $(INC)piwindowx.h \
+ $(INC)piwindowgen.h \
+ $(INC)picontainerx.h \
+ $(INC)picontainergen.h \
+ $(INC)pieldrw.h pipodrw.h servnobjm.h \
+ $(INC)pdlmgr.h dlftypes.h \
+ $(INC)objfitter.h \
+ $(INC)cimage.h \
+ $(INC)fioarr.h \
+ $(INC)fitsntuple.h \
+ $(INC)fitsfile.h \
+ $(EXTINCPATH)FitsIO/fitsio.h \
+ $(EXTINCPATH)FitsIO/longnam.h \
+ $(INC)fitsxntuple.h
+$(OBJ)nomimagadapter.o: nomimagadapter.cc \
+ $(INC)machdefs.h \
+ $(INC)datatype.h nomimagadapter.h \
+ nomgadapter.h $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)anydataobj.h \
+ $(INC)pidrawer.h \
+ $(INC)pibwdggen.h \
+ $(INC)pisysdep.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picolist.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)ntupintf.h \
+ $(INC)generalfit.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)generaldata.h \
+ $(INC)poly.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)fmath.h \
+ $(INC)cimage.h \
+ $(INC)fioarr.h pimgadapter.h \
+ $(INC)objfitter.h \
+ $(INC)histos.h \
+ $(INC)histos2.h \
+ $(INC)hisprof.h \
+ $(INC)fitstarray.h \
+ $(INC)fitsfile.h \
+ $(EXTINCPATH)FitsIO/fitsio.h \
+ $(EXTINCPATH)FitsIO/longnam.h
+$(OBJ)nomskymapadapter.o: nomskymapadapter.cc \
+ $(INC)machdefs.h \
+ $(INC)datatype.h nomskymapadapter.h \
+ nomgadapter.h $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)anydataobj.h \
+ $(INC)pidrawer.h \
+ $(INC)pibwdggen.h \
+ $(INC)pisysdep.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picolist.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)ntupintf.h \
+ $(INC)generalfit.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)generaldata.h \
+ $(INC)poly.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)fmath.h \
+ $(INC)pixelmap.h \
+ $(INC)spherepos.h \
+ $(INC)unitvector.h \
+ $(INC)vector3d.h \
+ $(INC)longlat.h \
+ $(INC)utilgeom.h \
+ $(INC)skymap.h \
+ $(INC)spherethetaphi.h \
+ $(INC)sphericalmap.h \
+ $(INC)smathconst.h \
+ $(INC)spherehealpix.h \
+ $(INC)HEALPixUtils.h \
+ $(INC)localmap.h \
+ $(INC)fiospherethetaphi.h \
+ $(INC)fiospherehealpix.h \
+ $(INC)fiolocalmap.h pitvmaad.h \
+ $(INC)complexios.h \
+ $(INC)fitsspherehealpix.h \
+ $(INC)fitsfile.h \
+ $(EXTINCPATH)FitsIO/fitsio.h \
+ $(EXTINCPATH)FitsIO/longnam.h \
+ $(INC)fitslocalmap.h
+$(OBJ)nomspecrespadapter.o: nomspecrespadapter.cc \
+ $(INC)machdefs.h nomspecrespadapter.h \
+ nomgadapter.h $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)anydataobj.h \
+ $(INC)pidrawer.h \
+ $(INC)pibwdggen.h \
+ $(INC)pisysdep.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picolist.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)ntupintf.h \
+ $(INC)generalfit.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)generaldata.h \
+ $(INC)poly.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)fmath.h \
+ $(INC)specresp.h \
+ $(INC)specrespvector.h \
+ $(INC)gaussfilt.h
+$(OBJ)nomtarradapter.o: nomtarradapter.cc \
+ $(INC)machdefs.h \
+ $(INC)datatype.h nomtarradapter.h \
+ nomgadapter.h $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)anydataobj.h \
+ $(INC)pidrawer.h \
+ $(INC)pibwdggen.h \
+ $(INC)pisysdep.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picolist.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)ntupintf.h \
+ $(INC)generalfit.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)generaldata.h \
+ $(INC)poly.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)fmath.h pitvmaad.h \
+ $(INC)piyfxdrw.h \
+ $(INC)fioarr.h \
+ $(INC)fitstarray.h \
+ $(INC)fitsfile.h \
+ $(EXTINCPATH)FitsIO/fitsio.h \
+ $(EXTINCPATH)FitsIO/longnam.h
+$(OBJ)nomtmatvecadapter.o: nomtmatvecadapter.cc \
+ $(INC)machdefs.h \
+ $(INC)datatype.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)objfitter.h \
+ $(INC)cimage.h \
+ $(INC)fioarr.h \
+ $(INC)histos.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)fmath.h \
+ $(INC)histos2.h \
+ $(INC)hisprof.h \
+ $(INC)generalfit.h \
+ $(INC)generaldata.h \
+ $(INC)ntupintf.h \
+ $(INC)poly.h nomtmatvecadapter.h \
+ nomgadapter.h $(INC)pidrawer.h \
+ $(INC)pibwdggen.h \
+ $(INC)pisysdep.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picolist.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)piyfxdrw.h pitvmaad.h \
+ $(INC)fitstarray.h \
+ $(INC)fitsfile.h \
+ $(EXTINCPATH)FitsIO/fitsio.h \
+ $(EXTINCPATH)FitsIO/longnam.h
+$(OBJ)pawexecut.o: pawexecut.cc $(INC)strutil.h \
+ $(INC)histos.h \
+ $(INC)objfio.h \
+ $(INC)machdefs.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)fmath.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)histos2.h \
+ $(INC)hisprof.h \
+ $(INC)ntuple.h \
+ $(INC)ntupintf.h pawexecut.h piacmd.h \
+ dlftypes.h $(INC)pdlmgr.h \
+ $(INC)ctimer.h nobjmgr.h servnobjm.h \
+ nomgadapter.h $(INC)pidrawer.h \
+ $(INC)pibwdggen.h \
+ $(INC)pisysdep.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picolist.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)generalfit.h \
+ $(INC)generaldata.h \
+ $(INC)poly.h pistdimgapp.h \
+ $(INC)piapplx.h \
+ $(INC)piapplgen.h \
+ $(INC)picontainerx.h \
+ $(INC)picontainergen.h \
+ $(INC)pimenubarx.h \
+ $(INC)pimenubargen.h \
+ $(INC)pimenux.h \
+ $(INC)pimenugen.h \
+ $(INC)picons.h \
+ $(INC)pistdwdgx.h \
+ $(INC)pistdwdggen.h \
+ $(INC)pibwdgx.h \
+ $(INC)pigraphps.h \
+ $(INC)piwindowx.h \
+ $(INC)piwindowgen.h \
+ $(INC)pioptmenux.h \
+ $(INC)pioptmenugen.h \
+ $(INC)pifilechox.h \
+ $(INC)pifilechogen.h \
+ $(INC)piperiodx.h \
+ $(INC)periodic.h \
+ $(INC)piimage.h \
+ $(INC)pieldrw.h \
+ $(INC)pipixmapx.h \
+ $(INC)pipixmapgen.h \
+ $(INC)picmapview.h \
+ $(INC)pi3dwdg.h \
+ $(INC)pi3ddrw.h \
+ $(INC)pigraph3d.h pisiadw.h \
+ $(INC)pilistx.h \
+ $(INC)pilistgen.h \
+ $(INC)pistzwin.h \
+ $(INC)pitherm.h \
+ $(INC)resusage.h
+$(OBJ)pi2dvec.o: pi2dvec.cc $(INC)machdefs.h \
+ $(INC)histos.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)fmath.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)ntuple.h \
+ $(INC)ntupintf.h \
+ $(INC)nbtri.h pi2dvec.h pistdimgapp.h \
+ $(INC)pisysdep.h \
+ $(INC)piapplx.h \
+ $(INC)piapplgen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picontainerx.h \
+ $(INC)picontainergen.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)picolist.h \
+ $(INC)pimenubarx.h \
+ $(INC)pimenubargen.h \
+ $(INC)pimenux.h \
+ $(INC)pimenugen.h \
+ $(INC)picons.h \
+ $(INC)pistdwdgx.h \
+ $(INC)pistdwdggen.h \
+ $(INC)pibwdgx.h \
+ $(INC)pibwdggen.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigraphps.h \
+ $(INC)piwindowx.h \
+ $(INC)piwindowgen.h \
+ $(INC)pioptmenux.h \
+ $(INC)pioptmenugen.h \
+ $(INC)pifilechox.h \
+ $(INC)pifilechogen.h \
+ $(INC)piperiodx.h \
+ $(INC)periodic.h \
+ $(INC)piimage.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)pieldrw.h \
+ $(INC)pidrawer.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h \
+ $(INC)pipixmapx.h \
+ $(INC)pipixmapgen.h \
+ $(INC)picmapview.h \
+ $(INC)pi3dwdg.h \
+ $(INC)pi3ddrw.h \
+ $(INC)pigraph3d.h nobjmgr.h dlftypes.h \
+ piacmd.h $(INC)pdlmgr.h \
+ $(INC)ctimer.h pisiadw.h \
+ $(INC)pilistx.h \
+ $(INC)pilistgen.h \
+ $(INC)pistzwin.h \
+ $(INC)pitherm.h \
+ $(INC)resusage.h \
+ $(INC)piscdrawwdg.h
+$(OBJ)piacmd.o: piacmd.cc piacmd.h $(INC)machdefs.h \
+ dlftypes.h $(INC)pdlmgr.h \
+ $(INC)ctimer.h basexecut.h pistdimgapp.h \
+ $(INC)pisysdep.h \
+ $(INC)piapplx.h \
+ $(INC)piapplgen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picontainerx.h \
+ $(INC)picontainergen.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)picolist.h \
+ $(INC)pimenubarx.h \
+ $(INC)pimenubargen.h \
+ $(INC)pimenux.h \
+ $(INC)pimenugen.h \
+ $(INC)picons.h \
+ $(INC)pistdwdgx.h \
+ $(INC)pistdwdggen.h \
+ $(INC)pibwdgx.h \
+ $(INC)pibwdggen.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigraphps.h \
+ $(INC)piwindowx.h \
+ $(INC)piwindowgen.h \
+ $(INC)pioptmenux.h \
+ $(INC)pioptmenugen.h \
+ $(INC)pifilechox.h \
+ $(INC)pifilechogen.h \
+ $(INC)piperiodx.h \
+ $(INC)periodic.h \
+ $(INC)piimage.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)pieldrw.h \
+ $(INC)pidrawer.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h \
+ $(INC)pipixmapx.h \
+ $(INC)pipixmapgen.h \
+ $(INC)picmapview.h \
+ $(INC)pi3dwdg.h \
+ $(INC)pi3ddrw.h \
+ $(INC)pigraph3d.h nobjmgr.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)mutyv.h pisiadw.h \
+ $(INC)pilistx.h \
+ $(INC)pilistgen.h \
+ $(INC)pistzwin.h \
+ $(INC)pitherm.h \
+ $(INC)resusage.h piafitting.h nomgadapter.h \
+ $(INC)ntupintf.h \
+ $(INC)generalfit.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)generaldata.h \
+ $(INC)poly.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)fmath.h pawexecut.h cxxexecutor.h \
+ cxxexecwin.h contmodex.h flowmodex.h
+$(OBJ)piafitting.o: piafitting.cc $(INC)strutil.h \
+ $(INC)nbtri.h \
+ $(INC)machdefs.h \
+ $(INC)generalfit.h \
+ $(INC)pexceptions.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)generaldata.h \
+ $(INC)ntupintf.h \
+ $(INC)poly.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)fmath.h \
+ $(INC)fct1dfit.h \
+ $(INC)fct2dfit.h \
+ $(INC)ntuple.h \
+ $(INC)cimage.h \
+ $(INC)fioarr.h \
+ $(INC)histos.h \
+ $(INC)histos2.h \
+ $(INC)hisprof.h \
+ $(INC)objfitter.h piafitting.h nomgadapter.h \
+ $(INC)pidrawer.h \
+ $(INC)pibwdggen.h \
+ $(INC)pisysdep.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picolist.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)pdlmgr.h dlftypes.h piacmd.h \
+ $(INC)ctimer.h nobjmgr.h pistdimgapp.h \
+ $(INC)piapplx.h \
+ $(INC)piapplgen.h \
+ $(INC)picontainerx.h \
+ $(INC)picontainergen.h \
+ $(INC)pimenubarx.h \
+ $(INC)pimenubargen.h \
+ $(INC)pimenux.h \
+ $(INC)pimenugen.h \
+ $(INC)picons.h \
+ $(INC)pistdwdgx.h \
+ $(INC)pistdwdggen.h \
+ $(INC)pibwdgx.h \
+ $(INC)pigraphps.h \
+ $(INC)piwindowx.h \
+ $(INC)piwindowgen.h \
+ $(INC)pioptmenux.h \
+ $(INC)pioptmenugen.h \
+ $(INC)pifilechox.h \
+ $(INC)pifilechogen.h \
+ $(INC)piperiodx.h \
+ $(INC)periodic.h \
+ $(INC)piimage.h \
+ $(INC)pieldrw.h \
+ $(INC)pipixmapx.h \
+ $(INC)pipixmapgen.h \
+ $(INC)picmapview.h \
+ $(INC)pi3dwdg.h \
+ $(INC)pi3ddrw.h \
+ $(INC)pigraph3d.h pisiadw.h \
+ $(INC)pilistx.h \
+ $(INC)pilistgen.h \
+ $(INC)pistzwin.h \
+ $(INC)pitherm.h \
+ $(INC)resusage.h nomhistadapter.h \
+ $(INC)xntuple.h nomgfdadapter.h \
+ nomimagadapter.h nomtmatvecadapter.h
+$(OBJ)pigfd1.o: pigfd1.cc pigfd1.h \
+ $(INC)generaldata.h \
+ $(INC)objfio.h \
+ $(INC)machdefs.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)ntupintf.h \
+ $(INC)poly.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)fmath.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)pidrawer.h \
+ $(INC)pibwdggen.h \
+ $(INC)pisysdep.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picolist.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h
+$(OBJ)pigfd2.o: pigfd2.cc pigfd2.h \
+ $(INC)generaldata.h \
+ $(INC)objfio.h \
+ $(INC)machdefs.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)ntupintf.h \
+ $(INC)poly.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)fmath.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)pi3ddrw.h \
+ $(INC)pisysdep.h \
+ $(INC)pidrawer.h \
+ $(INC)pibwdggen.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picolist.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h \
+ $(INC)pieldrw.h \
+ $(INC)pigraph3d.h
+$(OBJ)pihisto.o: pihisto.cc pihisto.h \
+ $(INC)histos.h \
+ $(INC)objfio.h \
+ $(INC)machdefs.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)fmath.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)pidrawer.h \
+ $(INC)pibwdggen.h \
+ $(INC)pisysdep.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picolist.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h \
+ $(INC)hisprof.h
+$(OBJ)pihisto2d.o: pihisto2d.cc $(INC)piapplx.h \
+ $(INC)piapplgen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picontainerx.h \
+ $(INC)picontainergen.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)picolist.h \
+ $(INC)pimenubarx.h \
+ $(INC)pimenubargen.h \
+ $(INC)pimenux.h \
+ $(INC)pimenugen.h \
+ $(INC)picons.h \
+ $(INC)pistdwdgx.h \
+ $(INC)pistdwdggen.h \
+ $(INC)pibwdgx.h \
+ $(INC)pibwdggen.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigraphps.h pihisto2d.h \
+ $(INC)pioptmenux.h \
+ $(INC)pioptmenugen.h \
+ $(INC)histos2.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)pexceptions.h \
+ $(INC)fmath.h \
+ $(INC)histos.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)piscdrawwdg.h \
+ $(INC)piwindowx.h \
+ $(INC)piwindowgen.h \
+ $(INC)pidrawer.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h \
+ $(INC)pieldrw.h \
+ $(INC)nbrandom.h \
+ $(INC)srandgen.h
+$(OBJ)piinit.o: piinit.cc $(INC)machdefs.h piinit.h \
+ $(INC)sambainit.h \
+ $(INC)skymapinit.h \
+ $(INC)sophyainit.h \
+ $(INC)ntoolsinit.h \
+ $(INC)tarrinit.h pistdimgapp.h \
+ $(INC)pisysdep.h \
+ $(INC)piapplx.h \
+ $(INC)piapplgen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picontainerx.h \
+ $(INC)picontainergen.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)picolist.h \
+ $(INC)pimenubarx.h \
+ $(INC)pimenubargen.h \
+ $(INC)pimenux.h \
+ $(INC)pimenugen.h \
+ $(INC)picons.h \
+ $(INC)pistdwdgx.h \
+ $(INC)pistdwdggen.h \
+ $(INC)pibwdgx.h \
+ $(INC)pibwdggen.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigraphps.h \
+ $(INC)piwindowx.h \
+ $(INC)piwindowgen.h \
+ $(INC)pioptmenux.h \
+ $(INC)pioptmenugen.h \
+ $(INC)pifilechox.h \
+ $(INC)pifilechogen.h \
+ $(INC)piperiodx.h \
+ $(INC)periodic.h \
+ $(INC)piimage.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)pieldrw.h \
+ $(INC)pidrawer.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h \
+ $(INC)pipixmapx.h \
+ $(INC)pipixmapgen.h \
+ $(INC)picmapview.h \
+ $(INC)pi3dwdg.h \
+ $(INC)pi3ddrw.h \
+ $(INC)pigraph3d.h nobjmgr.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)mutyv.h dlftypes.h piacmd.h \
+ $(INC)pdlmgr.h \
+ $(INC)ctimer.h pisiadw.h \
+ $(INC)pilistx.h \
+ $(INC)pilistgen.h \
+ $(INC)pistzwin.h \
+ $(INC)pitherm.h \
+ $(INC)resusage.h servnobjm.h \
+ nomhistadapter.h nomgadapter.h \
+ $(INC)ntupintf.h \
+ $(INC)generalfit.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)generaldata.h \
+ $(INC)poly.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)fmath.h \
+ $(INC)histos.h \
+ $(INC)histos2.h \
+ $(INC)hisprof.h \
+ $(INC)ntuple.h \
+ $(INC)xntuple.h nomgfdadapter.h \
+ nomimagadapter.h $(INC)cimage.h \
+ $(INC)fioarr.h nomtmatvecadapter.h \
+ nomtarradapter.h nomskymapadapter.h \
+ $(INC)pixelmap.h \
+ $(INC)spherepos.h \
+ $(INC)unitvector.h \
+ $(INC)vector3d.h \
+ $(INC)longlat.h \
+ $(INC)utilgeom.h \
+ $(INC)spherethetaphi.h \
+ $(INC)sphericalmap.h \
+ $(INC)smathconst.h \
+ $(INC)spherehealpix.h \
+ $(INC)HEALPixUtils.h \
+ $(INC)localmap.h \
+ $(INC)specrespvector.h \
+ $(INC)specresp.h \
+ $(INC)gaussfilt.h nomspecrespadapter.h
+$(OBJ)pintup3d.o: pintup3d.cc pintup3d.h \
+ $(INC)ntupintf.h \
+ $(INC)machdefs.h \
+ $(INC)pi3ddrw.h \
+ $(INC)pisysdep.h \
+ $(INC)pidrawer.h \
+ $(INC)pibwdggen.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picolist.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h \
+ $(INC)pieldrw.h \
+ $(INC)pigraph3d.h
+$(OBJ)pintuple.o: pintuple.cc pintuple.h \
+ $(INC)ntupintf.h \
+ $(INC)machdefs.h \
+ $(INC)pidrawer.h \
+ $(INC)pibwdggen.h \
+ $(INC)pisysdep.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picolist.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h
+$(OBJ)pipodrw.o: pipodrw.cc pipodrw.h \
+ $(INC)machdefs.h \
+ $(INC)pidrawer.h \
+ $(INC)pibwdggen.h \
+ $(INC)pisysdep.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picolist.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)histos2.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)pexceptions.h \
+ $(INC)fmath.h \
+ $(INC)histos.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)generalfit.h \
+ $(INC)generaldata.h \
+ $(INC)ntupintf.h \
+ $(INC)poly.h
+$(OBJ)pisiadw.o: pisiadw.cc $(INC)machdefs.h \
+ $(INC)perrors.h \
+ $(INC)pexceptions.h \
+ $(INC)ctimer.h \
+ $(INC)nbmath.h \
+ $(INC)smathconst.h pistdimgapp.h \
+ $(INC)pisysdep.h \
+ $(INC)piapplx.h \
+ $(INC)piapplgen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picontainerx.h \
+ $(INC)picontainergen.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)picolist.h \
+ $(INC)pimenubarx.h \
+ $(INC)pimenubargen.h \
+ $(INC)pimenux.h \
+ $(INC)pimenugen.h \
+ $(INC)picons.h \
+ $(INC)pistdwdgx.h \
+ $(INC)pistdwdggen.h \
+ $(INC)pibwdgx.h \
+ $(INC)pibwdggen.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigraphps.h \
+ $(INC)piwindowx.h \
+ $(INC)piwindowgen.h \
+ $(INC)pioptmenux.h \
+ $(INC)pioptmenugen.h \
+ $(INC)pifilechox.h \
+ $(INC)pifilechogen.h \
+ $(INC)piperiodx.h \
+ $(INC)periodic.h \
+ $(INC)piimage.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)pieldrw.h \
+ $(INC)pidrawer.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h \
+ $(INC)pipixmapx.h \
+ $(INC)pipixmapgen.h \
+ $(INC)picmapview.h \
+ $(INC)pi3dwdg.h \
+ $(INC)pi3ddrw.h \
+ $(INC)pigraph3d.h nobjmgr.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)mutyv.h dlftypes.h piacmd.h \
+ $(INC)pdlmgr.h pisiadw.h \
+ $(INC)pilistx.h \
+ $(INC)pilistgen.h \
+ $(INC)pistzwin.h \
+ $(INC)pitherm.h \
+ $(INC)resusage.h servnobjm.h
+$(OBJ)pistdimgapp.o: pistdimgapp.cc \
+ $(INC)machdefs.h \
+ $(INC)strutil.h \
+ $(INC)timing.h \
+ $(INC)perrors.h \
+ $(INC)pexceptions.h \
+ $(INC)ctimer.h \
+ $(INC)psighand.h \
+ $(INC)cimage.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)fioarr.h \
+ $(INC)tvector.h pistdimgapp.h \
+ $(INC)pisysdep.h \
+ $(INC)piapplx.h \
+ $(INC)piapplgen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picontainerx.h \
+ $(INC)picontainergen.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)picolist.h \
+ $(INC)pimenubarx.h \
+ $(INC)pimenubargen.h \
+ $(INC)pimenux.h \
+ $(INC)pimenugen.h \
+ $(INC)picons.h \
+ $(INC)pistdwdgx.h \
+ $(INC)pistdwdggen.h \
+ $(INC)pibwdgx.h \
+ $(INC)pibwdggen.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigraphps.h \
+ $(INC)piwindowx.h \
+ $(INC)piwindowgen.h \
+ $(INC)pioptmenux.h \
+ $(INC)pioptmenugen.h \
+ $(INC)pifilechox.h \
+ $(INC)pifilechogen.h \
+ $(INC)piperiodx.h \
+ $(INC)periodic.h \
+ $(INC)piimage.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)pieldrw.h \
+ $(INC)pidrawer.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h \
+ $(INC)pipixmapx.h \
+ $(INC)pipixmapgen.h \
+ $(INC)picmapview.h \
+ $(INC)pi3dwdg.h \
+ $(INC)pi3ddrw.h \
+ $(INC)pigraph3d.h nobjmgr.h dlftypes.h \
+ piacmd.h $(INC)pdlmgr.h pisiadw.h \
+ $(INC)pilistx.h \
+ $(INC)pilistgen.h \
+ $(INC)pistzwin.h \
+ $(INC)pitherm.h \
+ $(INC)resusage.h \
+ $(INC)piimgtools.h \
+ $(INC)pidrwtools.h \
+ $(INC)piaxestools.h \
+ $(INC)piscdrawwdg.h piinit.h \
+ $(INC)sambainit.h \
+ $(INC)skymapinit.h \
+ $(INC)sophyainit.h \
+ $(INC)ntoolsinit.h \
+ $(INC)tarrinit.h \
+ $(INC)piversion.h piaversion.h
+$(OBJ)pitvmaad.o: pitvmaad.cc pitvmaad.h \
+ $(INC)machdefs.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)tvector.h
+$(OBJ)servnobjm.o: servnobjm.cc $(INC)strutil.h \
+ nobjmgr.h $(INC)machdefs.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)mutyv.h dlftypes.h servnobjm.h \
+ $(INC)pdlmgr.h nomgadapter.h \
+ $(INC)pidrawer.h \
+ $(INC)pibwdggen.h \
+ $(INC)pisysdep.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picolist.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigrcoord.h \
+ $(INC)pilineatt.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigratt.h \
+ $(INC)piaxes.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)ntupintf.h \
+ $(INC)generalfit.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)generaldata.h \
+ $(INC)poly.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)fmath.h pistdimgapp.h \
+ $(INC)piapplx.h \
+ $(INC)piapplgen.h \
+ $(INC)picontainerx.h \
+ $(INC)picontainergen.h \
+ $(INC)pimenubarx.h \
+ $(INC)pimenubargen.h \
+ $(INC)pimenux.h \
+ $(INC)pimenugen.h \
+ $(INC)picons.h \
+ $(INC)pistdwdgx.h \
+ $(INC)pistdwdggen.h \
+ $(INC)pibwdgx.h \
+ $(INC)pigraphps.h \
+ $(INC)piwindowx.h \
+ $(INC)piwindowgen.h \
+ $(INC)pioptmenux.h \
+ $(INC)pioptmenugen.h \
+ $(INC)pifilechox.h \
+ $(INC)pifilechogen.h \
+ $(INC)piperiodx.h \
+ $(INC)periodic.h \
+ $(INC)piimage.h \
+ $(INC)pieldrw.h \
+ $(INC)pipixmapx.h \
+ $(INC)pipixmapgen.h \
+ $(INC)picmapview.h \
+ $(INC)pi3dwdg.h \
+ $(INC)pi3ddrw.h \
+ $(INC)pigraph3d.h piacmd.h \
+ $(INC)ctimer.h pisiadw.h \
+ $(INC)pilistx.h \
+ $(INC)pilistgen.h \
+ $(INC)pistzwin.h \
+ $(INC)pitherm.h \
+ $(INC)resusage.h \
+ $(INC)fct1dfit.h \
+ $(INC)fct2dfit.h pitvmaad.h \
+ $(INC)ntuple.h \
+ $(INC)cimage.h \
+ $(INC)fioarr.h \
+ $(INC)histos.h \
+ $(INC)histos2.h \
+ $(INC)hisprof.h \
+ $(INC)piyfxdrw.h \
+ $(INC)pisurfdr.h pintuple.h pintup3d.h \
+ pipodrw.h
Index: /tags/V_Dec2002/SophyaPI/PIext/basexecut.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/basexecut.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/basexecut.cc	(revision 2309)
@@ -0,0 +1,1955 @@
+#include "piacmd.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "basexecut.h"
+
+#include "pdlmgr.h"
+#include "ctimer.h"
+#include "strutilxx.h"
+
+#include "pistdimgapp.h"
+#include "nobjmgr.h"
+#include "servnobjm.h"
+#include "nomgadapter.h"
+#include "piyfxdrw.h"
+
+#include "histos.h"
+#include "histos2.h"
+#include "hisprof.h"
+#include "ntuple.h"
+#include "generaldata.h"
+
+#ifdef SANS_EVOLPLANCK
+#include "cvector.h"
+#else
+#include "tvector.h"
+#endif
+
+
+/* --Methode-- */
+PIABaseExecutor::PIABaseExecutor(PIACmd* piac, NamedObjMgr* omg, PIStdImgApp* app)
+{
+mpiac = piac;
+mObjMgr = omg; 
+mImgApp = app;
+dynlink = NULL;
+dynlink2 = NULL;
+RegisterCommands();
+}
+
+PIABaseExecutor::~PIABaseExecutor()
+{
+  if (dynlink) delete dynlink;
+  if (dynlink2) delete dynlink2;
+}
+
+
+/* Macro pour tester si flag normalized coordinate est present */
+#define _CkBoolNC_(_jk_) ((tokens.size()>_jk_) && (tokens[_jk_] == "true")) ? true : false;
+ 
+/* --Methode-- */
+int PIABaseExecutor::Execute(string& kw, vector<string>& tokens, string& toks)
+{
+Services2NObjMgr* srvo = mObjMgr->GetServiceObj();
+// >>>>> Chargement de modules
+if (kw == "loadmodule") {
+  if (tokens.size() < 2) { cout << "Usage: loadmodule fnameso modulename" << endl;  return(0); }
+  mpiac->LoadModule(tokens[0], tokens[1]);
+  }
+// >>>>>>>>>>> Fenetre graphique , changement d'attributs graphiques 
+else if (kw == "zone") {
+  while (tokens.size() < 2) tokens.push_back("1");
+  int nx, ny;
+  nx = ny = 1;
+  nx = atoi(tokens[0].c_str());    ny = atoi(tokens[1].c_str());
+  if (mImgApp) mImgApp->SetZone(nx, ny);
+  }  
+else if (kw == "newwin") {
+  int nx=1, ny=1;
+  int sx=0, sy=0;
+  //if(tokens.size() < 2) { cout << "Usage: newwin nx ny" << endl;  return(0); }
+  if(tokens.size() > 0) nx = atoi(tokens[0].c_str());
+  if(tokens.size() > 1) ny = atoi(tokens[1].c_str());
+  if(tokens.size() > 3) { 
+    sx = atoi(tokens[2].c_str());
+    sy = atoi(tokens[3].c_str());
+  }
+  if (mImgApp) mImgApp->CreateGraphWin(nx, ny, sx, sy);
+}  
+else if (kw == "stacknext") mImgApp->StackWinNext(); 
+else if (kw == "graphicatt") {
+  if (tokens.size() < 1) { cout << "Usage: graphicatt attributes_list (att=def->defaut)" << endl;  return(0); }
+  string opts = tokens[0];
+  if (tokens.size() > 1) 
+    for(unsigned int kt=1; kt<tokens.size(); kt++)  { opts += ' '; opts += tokens[kt]; }
+  if (mImgApp) mImgApp->SetDefaultGraphicAttributes(opts);
+  }
+else if (kw == "setaxesatt") {
+  if (tokens.size() < 1) { cout << "Usage: setaxesatt attributes_list " << endl;  return(0); }
+  string opts = tokens[0];
+  if (tokens.size() > 1) 
+    for(unsigned int kt=1; kt<tokens.size(); kt++)  { opts += ' '; opts += tokens[kt]; }
+  if (mImgApp) mImgApp->SetDefaultAxesAttributes(opts);
+  }
+else if (kw == "setinsetlimits") {
+  if (tokens.size() < 4) { cout << "Usage: setinsetlimits xmin xmax ymin ymax" << endl;  return(0); }
+  double xmin = atof(tokens[0].c_str());
+  double xmax = atof(tokens[1].c_str());
+  double ymin = atof(tokens[2].c_str());
+  double ymax = atof(tokens[3].c_str());
+  mImgApp->SetInsetLimits(xmin, xmax, ymin, ymax);
+  }
+else if (kw == "drpanel") {
+  if (tokens.size() < 4) { 
+    cout << "Usage: drpanel xmin xmax ymin ymax [gratt] [name]" << endl;  
+    return(0); 
+  }
+  double xmin = atof(tokens[0].c_str());
+  double xmax = atof(tokens[1].c_str());
+  double ymin = atof(tokens[2].c_str());
+  double ymax = atof(tokens[3].c_str());
+  char buff[128];
+  sprintf(buff, "axesnone xylimits=%g,%g,%g,%g ", xmin, xmax, ymin, ymax);
+  string sop = buff;
+  if (tokens.size() > 4) sop += tokens[4];
+  string name;
+  if (tokens.size() > 5) name = tokens[5];
+  PIFuncDrawer* gdr = new PIFuncDrawer(NULL);
+  mImgApp->DispScDrawer(gdr, name, sop); 
+}
+else if (kw == "addtext") {
+  if (tokens.size() < 3) { 
+    cout << "Usage: addtext x y txt [colfontatt] [fgnc]" << endl;  
+    return(0); 
+  }
+  double xp = atof(tokens[0].c_str());
+  double yp = atof(tokens[1].c_str());
+  string txt = tokens[2];
+  string sop;
+  if (tokens.size() > 3) sop = tokens[3];
+  bool fgnc = _CkBoolNC_(4);  
+  mImgApp->AddText(txt, xp, yp, sop, fgnc);
+  }
+else if (kw == "addctext") {
+  if (tokens.size() < 5) { 
+    cout << "Usage: addctext x y txt s_up s_dn [colfontatt] [updnfatt] [fgnc] " << endl;  
+    return(0); 
+  }
+  double xp = atof(tokens[0].c_str());
+  double yp = atof(tokens[1].c_str());
+  string sop;
+  if (tokens.size() > 5) sop = tokens[5];
+  string sopfss;
+  if (tokens.size() > 6) sopfss = tokens[6];
+  bool fgnc = _CkBoolNC_(7);  
+  mImgApp->AddCompText(tokens[2], tokens[3], tokens[4], xp, yp, sop, sopfss, fgnc);
+  }
+else if ((kw == "addline") || (kw == "addrect") || (kw == "addfrect") ||
+	 (kw == "addarrow") ) {
+  if (tokens.size() < 4) { 
+    cout << "Usage: addline/addrect/addfrect x1 y1 x2 y2 [colatt] [fgnc]" << endl;  
+    return(0); 
+  }
+  double xp1 = atof(tokens[0].c_str());
+  double yp1 = atof(tokens[1].c_str());
+  double xp2 = atof(tokens[2].c_str());
+  double yp2 = atof(tokens[3].c_str());
+  string sop;
+  if (tokens.size() > 4) sop = tokens[4];
+  bool fgnc = _CkBoolNC_(5);  
+  if (kw == "addline") mImgApp->AddLine(xp1, yp1, xp2, yp2, sop, false, fgnc);
+  else if (kw == "addarrow") mImgApp->AddLine(xp1, yp1, xp2, yp2, sop, true, fgnc);
+  else {
+    bool fgfill = (kw == "addrect") ? false : true;
+    mImgApp->AddRectangle(xp1, yp1, xp2, yp2, sop, fgfill, fgnc);
+  }
+}
+else if ((kw == "addcirc") || (kw == "addfcirc")) {
+  if (tokens.size() < 3) { 
+    cout << "Usage: addcirc/addfcirc xc yc r [colatt] [fgnc]" << endl;  
+    return(0); 
+  }
+  double xc = atof(tokens[0].c_str());
+  double yc = atof(tokens[1].c_str());
+  double rad = atof(tokens[2].c_str());
+  string sop;
+  if (tokens.size() > 3) sop = tokens[3];
+  bool fgnc = _CkBoolNC_(4);  
+  bool fgfill = (kw == "addcirc") ? false : true;
+  mImgApp->AddCircle(xc, yc, rad, sop, fgfill, fgnc);
+  }
+else if ((kw == "addarca") || (kw == "addfarca")) {
+  if (tokens.size() < 5) { 
+    cout << "Usage: addarca/addfarca xc yc r a da [colatt] [fgnc]" << endl;  
+    return(0); 
+  }
+  double xc = atof(tokens[0].c_str());
+  double yc = atof(tokens[1].c_str());
+  double rad = atof(tokens[2].c_str());
+  double ang = atof(tokens[3].c_str());
+  double dang = atof(tokens[4].c_str());
+  string sop;
+  if (tokens.size() > 5) sop = tokens[5];
+  bool fgnc = _CkBoolNC_(6);  
+  bool fgfill = (kw == "addarca") ? false : true;
+  mImgApp->AddArc(xc, yc, rad, ang, dang, sop, fgfill, fgnc);
+  }
+else if (kw == "addmarker") {
+  if (tokens.size() < 2) { 
+    cout << "Usage: addmarker x y [gratt] [fgnc]" << endl;  
+    return(0); 
+  }
+  double xm = atof(tokens[0].c_str());
+  double ym = atof(tokens[1].c_str());
+  string sop;
+  if (tokens.size() > 2) sop = tokens[2];
+  bool fgnc = _CkBoolNC_(3);  
+  mImgApp->AddCircle(xm, ym, -1, sop, false, fgnc);
+}
+else if ((kw == "addarc") || (kw == "addfarc") ) {
+  if (tokens.size() < 6) { 
+    cout << "Usage: addarc/addfarc x1 y1 x2 y2 x3 y3 [gratt] [fgnc]" << endl;  
+    return(0); 
+  }
+  double x1 = atof(tokens[0].c_str());
+  double y1 = atof(tokens[1].c_str());
+  double x2 = atof(tokens[2].c_str());
+  double y2 = atof(tokens[3].c_str());
+  double x3 = atof(tokens[4].c_str());
+  double y3 = atof(tokens[5].c_str());
+  string sop;
+  if (tokens.size() > 6) sop = tokens[6];
+  bool fgnc = _CkBoolNC_(7);  
+  bool fgfill = (kw == "addarc") ? false : true;
+  mImgApp->AddArc(x1, y1, x2, y2, x3, y3, sop, fgfill, fgnc);
+}
+else if ((kw == "addpoly") || (kw == "addfpoly")) {
+  if (tokens.size() < 1) { 
+    cout << "Usage: addpoly/addfpoly 'x1,y1 x2,y2 x3,y3 ...' [gratt] [fgnc]" << endl;  
+    return(0); 
+  }
+  vector<string> sxy;
+  vector<double> xpol, ypol;
+  double xp, yp;
+  FillVStringFrString(tokens[0], sxy);
+  for(int jkk=0; jkk<sxy.size(); jkk++) {
+    xp = yp = 0;
+    if (sscanf(sxy[jkk].c_str(), "%lg,%lg", &xp, &yp) == 2) { 
+      xpol.push_back(xp); 
+      ypol.push_back(yp);
+    }
+  }
+  string sop;
+  if (tokens.size() > 1) sop = tokens[1];
+  bool fgnc = _CkBoolNC_(2);  
+  bool fgfill = (kw == "addpoly") ? false : true;
+  mImgApp->AddPoly(xpol, ypol, sop, fgfill, fgnc);
+  }
+
+
+else if ((kw == "settitle") || (kw == "addtitle")) {
+  if (tokens.size() < 1) { cout << "Usage: settitle/addtitle TopTitle [BotTitle] [fontatt]" << endl;  return(0); }
+  if(tokens.size()<2) tokens.push_back("");
+  string gropt;
+  if(tokens.size()>2) gropt = tokens[2];
+  mImgApp->SetTitle(tokens[0], tokens[1], gropt);
+}
+
+else if ((kw == "setaxelabels") || (kw == "addaxelabels")) {
+  if (tokens.size() < 2) { cout << "Usage: setaxelabels/addaxelabels xLabel yLabel [fontatt]" << endl;  return(0); }
+  string gropt;
+  if(tokens.size()>2) gropt = tokens[2];
+  mImgApp->SetAxeLabels(tokens[0], tokens[1], gropt);
+}
+  
+// >>>>>>>>>>> Link dynamique de fonctions C++
+else if (kw == "link" ) {
+  if (tokens.size() < 2) { cout << "Usage: link fnameso f1 [f2 f3]" << endl;  return(0); }
+  string sph = "";
+  for(int gg=0; gg<5; gg++)   tokens.push_back(sph);
+  int rc = LinkUserFuncs(tokens[0], tokens[1], tokens[2], tokens[3]);
+  if (rc == 0)  cout << "PIABaseExecutor: Link from " << tokens[0] << " OK " << endl;
+}
+else if (kw == "linkff2" ) {
+  if (tokens.size() < 2) { cout << "Usage: linkff2 fnameso f1 [f2 f3]" << endl;  return(0); }
+  string sph = "";
+  for(int gg=0; gg<5; gg++)   tokens.push_back(sph);
+  int rc = LinkUserFuncs2(tokens[0], tokens[1], tokens[2], tokens[3]);
+  if (rc == 0)  cout << "PIABaseExecutor: Link2 from " << tokens[0] << " OK " << endl;
+}
+else if (kw == "call" ) {
+  if (tokens.size() < 1) { cout << "Usage: call userf [arg1 arg2 ...]" << endl;  return(0); }
+  UsFmap::iterator it;
+  UsFmap::iterator it1 = usfmap.find(tokens[0]);
+  UsFmap::iterator it2 = usfmap2.find(tokens[0]);
+  if ((it1 == usfmap.end()) && (it2 == usfmap2.end()) ) {
+    cerr << "PIABaseExecutor: No User Function " << tokens[0] << endl;
+    return(0);
+  }
+  if (it1 == usfmap.end())  it = it2;
+  else it = it1;
+  cout << "PIABaseExecutor: Call " << tokens[0] << "( ... )" << endl;
+// on est oblige de faire un cast  etant donne qu'on 
+// utilise donc des DlFunction  (Reza 20/08/98)  voir commentaire ds .h (pb g++)
+  DlUserProcFunction fuf = (DlUserProcFunction)(*it).second;
+//   On redirige la sortie sur le terminal 
+  bool red = mImgApp->HasRedirectedStdOutErr();
+  mImgApp->RedirectStdOutErr(false);
+#ifdef SANS_EVOLPLANCK
+  TRY {
+    tokens.erase(tokens.begin());
+    fuf(tokens);
+  }  CATCH(merr) {
+    fflush(stdout); 
+    string es = PeidaExc(merr);
+    cerr << "\n PIABaseExecutor: Call UserFunc  Exception :" << merr << es;
+    cout << endl; 
+    }
+#else
+  try {
+    tokens.erase(tokens.begin());
+    fuf(tokens);
+  }
+  catch ( PThrowable & exc ) {
+    cerr << "\n PIABaseExecutor: Call / Catched Exception :" 
+	 << (string)typeid(exc).name() << " Msg= " 
+	 << exc.Msg() << endl;
+    cout << endl; 
+  }
+  catch ( ... ) {
+    cerr << "\n PIABaseExecutor: Call / Catched Exception ... " 
+	 << endl;
+    cout << endl; 
+  }
+#endif
+  mImgApp->RedirectStdOutErr(red);
+}
+
+// >>>>>>>>>>> lecture/ecriture des objets, gestion des objets 
+else if (kw == "openfits" ) {
+  if (tokens.size() < 1) { cout << "Usage: openfits file " << endl;  return(0); }
+  else { string nomobj = "";  mObjMgr->ReadFits(tokens[0], nomobj); }
+}
+else if (kw == "savefits" ) {
+  if (tokens.size() < 2) { cout << "Usage: savefits nameobj filename " << endl;  return(0); }
+  else mObjMgr->SaveFits(tokens[0], tokens[1]);
+}
+else if (kw == "openppf" ) {
+  if (tokens.size() < 1) { cout << "Usage: openppf file " << endl; return(0); }
+  mObjMgr->ReadAll(tokens[0]);  
+}
+else if ((kw == "saveobjs") || (kw == "saveppf"))  {
+  if (tokens.size() < 2) { cout << "Usage: saveobjs patt filename " << endl; return(0); }
+  mObjMgr->SaveObjects(tokens[0], tokens[1]);  
+}
+else if (kw == "saveall" ) {
+  if (tokens.size() < 1) { cout << "Usage: saveall file " << endl; return(0); }
+  mObjMgr->SaveAll(tokens[0]);  
+}
+else if (kw == "print" ) {
+  if (tokens.size() < 1) { cout << "Usage: print nameobj " << endl; return(0); }
+  mObjMgr->PrintObj(tokens[0]);  
+}
+else if ( (kw == "rename" ) || (kw == "mv") )  {
+  if (tokens.size() < 2) { cout << "Usage: rename/mv nameobj namenew" << endl; return(0); }
+  mObjMgr->RenameObj(tokens[0], tokens[1]);  
+}
+else if ( (kw == "del" ) || (kw == "rm") ) {
+  if (tokens.size() < 1) { cout << "Usage: del nameobj [nameobj2 ...]" << endl; return(0); }
+  if (tokens.size()>0)
+    for(uint_4 i=0;i<tokens.size();i++)  mObjMgr->DelObj(tokens[i]);  
+}
+else if (kw == "delobjs" ) {
+  if (tokens.size() < 1) { cout << "Usage: delobjs nomobjpattern (*,?) " << endl; return(0); }
+  mObjMgr->DelObjects(tokens[0]);  
+}
+else if ( (kw == "listobjs") || (kw == "ls") )    { 
+  if  (tokens.size() < 1)  tokens.push_back("*");
+  mObjMgr->ListObjs(tokens[0]);
+}
+// Gestion des repertoires
+else if (kw == "mkdir" ) {
+  if (tokens.size() < 1) { cout << "Usage: mkdir dirname [true]" << endl; return(0); }
+  bool crd = mObjMgr->CreateDir(tokens[0]);  
+  if ( crd && (tokens.size() > 1) && (tokens[1] == "true") )
+    mObjMgr->SetKeepOldDirAtt(tokens[0], true);
+  }
+else if (kw == "rmdir" ) {
+  if (tokens.size() < 1) { cout << "Usage: rmdir dirname " << endl; return(0); }
+  mObjMgr->DeleteDir(tokens[0]);  
+  }
+else if (kw == "setdiratt" ) {
+  if (tokens.size() < 2) { cout << "Usage: setdiratt dirname true/false" << endl; return(0); }
+  if (tokens[1] == "true") mObjMgr->SetKeepOldDirAtt(tokens[0], true);
+  else mObjMgr->SetKeepOldDirAtt(tokens[0], false);
+}
+else if (kw == "cd")   { 
+  if  (tokens.size() < 1)  tokens.push_back("home");
+  mObjMgr->SetCurrentDir(tokens[0]);
+  }
+else if (kw == "pwd") { 
+  string dirn;
+  mObjMgr->GetCurrentDir(dirn);
+  cout << "CurrentDirectory: " << dirn << endl;
+  }  
+else if (kw == "listdirs")   { 
+  if  (tokens.size() < 1)  tokens.push_back("*");
+  mObjMgr->ListDirs(tokens[0]);
+  }
+
+// >>>>>>>>>>> Creation d'histos 1D-2D
+else if (kw == "newh1d") {
+  if (tokens.size() < 4) { cout << "Usage: newh1d name xmin xmax nbin" << endl; return(0); }
+  int_4 nbx = 100;
+  r_8 xmin = 0., xmax = 1.;
+  nbx = atoi(tokens[3].c_str());
+  xmin = atof(tokens[1].c_str());   xmax = atof(tokens[2].c_str());
+  Histo* h = new Histo(xmin, xmax, nbx);
+  mObjMgr->AddObj(h, tokens[0]);
+  }
+else if (kw == "newh2d") {
+  if (tokens.size() < 7) { 
+    cout << "Usage: newh2d name xmin xmax nbinx ymin ymax nbiny" << endl; 
+    return(0); 
+    }
+  int_4 nbx = 50, nby = 50;
+  r_8 xmin = 0., xmax = 1.;
+  r_8 ymin = 0., ymax = 1.;
+  nbx = atoi(tokens[3].c_str());
+  nby = atoi(tokens[6].c_str());
+  xmin = atof(tokens[1].c_str());   xmax = atof(tokens[2].c_str());
+  ymin = atof(tokens[4].c_str());   ymax = atof(tokens[5].c_str());
+  Histo2D* h = new Histo2D(xmin, xmax, nbx, ymin, ymax, nby);
+  mObjMgr->AddObj(h, tokens[0]);
+  }
+else if (kw == "newprof" || kw == "newprofe") {
+  if (tokens.size() < 4)
+    { cout << "Usage: newprof[e] name xmin xmax nbin [ymin ymax]" << endl; return(0); }
+  int_4 nbx = 100;
+  r_8 xmin = 0., xmax = 1., ymin = 1., ymax = -1.;
+  if(tokens.size() > 5)
+    {ymin = atof(tokens[4].c_str());   ymax = atof(tokens[5].c_str());}
+  nbx = atoi(tokens[3].c_str());
+  xmin = atof(tokens[1].c_str());   xmax = atof(tokens[2].c_str());
+  HProf* h = new HProf(xmin, xmax, nbx, ymin, ymax);
+  if(kw == "newprofe") h->SetErrOpt(false);
+  mObjMgr->AddObj(h, tokens[0]);
+  }
+
+// Creation de NTuple
+else if (kw == "newnt") {
+  if(tokens.size() < 2)
+    {cout<<"Usage: newnt name v1 v2 ... vn / newnt name nvar"<<endl; return(0);}
+  vector<string> varname;
+  int nvar = 0;
+  const char *c = tokens[1].c_str();
+  if(isdigit(c[0])) {
+    nvar = atoi(tokens[1].c_str());
+    if(nvar<=0 || nvar>=10000)
+      {cout<<"newnt name nvar : nvar must be an positive integer<10000"<<endl;
+       return(0);}
+    for(int i=0;i<nvar;i++) {
+      char str[16]; sprintf(str,"%d",i);
+      string dum = "v"; dum += str;
+      varname.push_back(dum.c_str());
+    }
+  } else if( islower(c[0]) || isupper(c[0]) ) {
+    for(int i=1;i<(int)tokens.size();i++) {
+      varname.push_back(tokens[i].c_str());
+      nvar++;
+    }
+  } else {
+    cout<<"newnt name v1 v2 ... vn : name vi must begin by a letter"<<endl
+        <<"newnt name nvar : nvar must be an positive integer"<<endl;
+    return(0);
+  }
+  char **noms = new char*[nvar];
+  for(int i=0;i<nvar;i++) noms[i] = (char *)varname[i].c_str();
+  NTuple* nt = new NTuple(nvar,noms);
+  delete [] noms;
+  mObjMgr->AddObj(nt,tokens[0]);
+  }
+
+// Creation de GeneralFitData
+else if (kw == "newgfd") {
+  if (tokens.size() < 3)
+    { cout << "Usage: newgfd nvar nalloc [errx(0/1)]" << endl; return(0); }
+  int nvar, nalloc, errx=0;
+  if (tokens.size() > 3)
+    { errx = atoi(tokens[3].c_str()); if(errx>0) errx=1; else errx = 0;}
+  nvar = atoi(tokens[1].c_str()); nalloc = atoi(tokens[2].c_str());
+  if(nvar>0 && nalloc>0) {
+    GeneralFitData* gfd = new GeneralFitData(nvar,nalloc,errx);
+    mObjMgr->AddObj(gfd, tokens[0]);
+    }
+  }
+
+// Creation/remplissage de vecteur et de matrice
+else if (kw == "newvec") {
+  if (tokens.size() < 2) { 
+    cout << "Usage: newvec name size [f(i) dopt] " << endl; return(0); 
+    }
+  int n = atoi(tokens[1].c_str());
+  double xmin, xmax;
+  xmin = 0.;  xmax = n;
+  if (tokens.size() < 3)  { 
+    Vector* v = new Vector(n);
+    mObjMgr->AddObj(v, tokens[0]);
+    }
+  else {
+    if (tokens.size() < 4)  tokens.push_back("");
+    mObjMgr->GetServiceObj()->PlotFunc(tokens[2], tokens[0], xmin, xmax, n, tokens[3]); 
+    }
+  }
+else if (kw == "newmtx") {
+  if (tokens.size() < 3) { 
+    cout << "Usage: newmtx name sizeX(Col) sizeY(Lines) [f(i,j) dopt] " << endl; return(0); 
+    }
+  int nx = atoi(tokens[1].c_str());
+  int ny = atoi(tokens[2].c_str());
+  double xmin, xmax, ymin, ymax;
+  xmin = 0.;  xmax = nx;
+  ymin = 0.;  ymax = ny;
+  if (tokens.size() < 4)  {
+    Matrix* mtx = new Matrix(ny,nx);
+    mObjMgr->AddObj(mtx, tokens[0]);
+    }
+  else {
+    if (tokens.size() < 5)  tokens.push_back("next");
+    mObjMgr->GetServiceObj()->PlotFunc2D(tokens[3], tokens[0], xmin, xmax, ymin, ymax, 
+                                         nx, ny, tokens[4]);
+    }
+  }
+// ----- Vecteur/NTuple <> Lignes/variables interpreteur
+// Creation de vecteur depuis le contenu de la ligne
+else if (kw == "line2vec") {  
+  if (tokens.size() < 2) { 
+    cout << "Usage: line2vec vecname v0 v1 v2 ... " << endl; return(0); 
+    }
+  int vsz = tokens.size()-1;
+  Vector* v = new Vector(vsz);
+  for(int kkv=0; kkv<vsz; kkv++)  (*v)(kkv) = atof(tokens[kkv+1].c_str());
+  mObjMgr->AddObj(v, tokens[0]);
+  }
+// Remplissage de NTuple depuis la ligne
+else if (kw == "line2nt") {
+  if (tokens.size() < 2) { 
+    cout << "Usage: line2nt ntname col0 col1 ..." << endl; return(0); 
+  }
+  AnyDataObj* obj;
+  obj = mObjMgr->GetObj(tokens[0]);
+  if(obj == NULL) {
+    cerr << "line2nt Error , No such object " << tokens[0] << endl; 
+    return(0);
+  }
+  NTuple* nt = dynamic_cast<NTuple *>(obj);
+  if(nt == NULL) {
+    cerr << "line2nt Error " << tokens[0] << " not an NTuple ! " << endl;
+    return(0);
+  }
+  if (nt->NbColumns() < 1) {
+    cerr << "line2nt Error: NbColumns  < 1" << endl;
+    return(0);
+  }
+  r_4* xnt = new r_4[ nt->NbColumns() ];
+  int kkx; 
+  for(kkx=0; kkx<nt->NbColumns(); kkx++) { 
+    if (kkx < tokens.size()-1)  xnt[kkx] = atof(tokens[kkx+1].c_str());
+    else xnt[kkx] = 0.;
+  }
+  nt->Fill(xnt);
+  delete[] xnt;
+}  
+// Contenu du vecteur vers variable interpreteur
+#define MAXNWORDSO2V 32768
+else if (kw == "vec2var") {  
+  if (tokens.size() < 2) { 
+    cout << "Usage: vec2var vecname varname [loop_param start:end:step] " << endl; return(0); 
+    }
+  AnyDataObj* obj;
+  obj = mObjMgr->GetObj(tokens[0]);
+  if(obj == NULL) {
+    cerr << "vec2var Error , No such object " << tokens[0] << endl; 
+    return(0);
+  }
+  Vector* v = dynamic_cast<Vector *>(obj);
+  if(v == NULL) {
+    cerr << "vec2var Error " << tokens[0] << " not a Vector ! " << endl;
+    return(0);
+  }
+  int kks = 0;
+  int kke = v->NElts();
+  int kkp = 1;
+  if (tokens.size() > 2) Services2NObjMgr::DecodeLoopParameters(tokens[2], kks, kke, kkp);
+  if (kks < 0)  kks = 0;
+  if (kke > v->NElts()) kke = v->NElts();
+  if (kkp < 1) kkp = 1;
+  int nelt = (kke-kks-1)/kkp;
+  if (nelt > MAXNWORDSO2V) {
+    nelt = MAXNWORDSO2V;
+    cout << "vec2var Warning:  Only " << nelt 
+	 << " elements  will be converted to string" << endl;
+    kke = kks+nelt*kkp;
+  }
+  string v2str;
+  char buff[64];
+  for(int kkv=kks; kkv<kke; kkv+=kkp) {
+    sprintf(buff, "%lg ", (*v)(kkv));
+    v2str += buff;
+  }
+  
+  mObjMgr->SetVar(tokens[1], v2str);
+}
+// Une ligne du NTuple/NTupleInterface -> variable interpreteur
+else if ((kw == "ntline2var") || (kw == "ntcol2var")) {  
+  if (tokens.size() < 3) {
+    cout << "Usage: ntline/col2var objname line_number varname" << endl; 
+    return(0); 
+  }
+  NObjMgrAdapter* oa = mObjMgr->GetObjAdapter(tokens[0]);
+  if(oa == NULL) {
+    cerr << "ntline/col2var Error , No such object " << tokens[0] << endl; 
+    return(0);
+  }
+  bool adel = false;
+  NTupleInterface* nti = oa->GetNTupleInterface(adel);
+  if(nti == NULL) {
+    cerr << "ntline/col2var Error: objet" << tokens[0] << " has no NTupleInterface" << endl; 
+    return(0);
+  }
+
+  if (nti->NbColumns() < 1 || nti->NbLines() < 1) {
+    cerr << "ntline/col2var Error: NbColumns or NbLines < 1" << endl;
+    return(0);
+  }
+  string v2str;
+  char buff[64];
+  if (kw == "ntline2var") {
+    int numline = atoi(tokens[1].c_str());
+    if ( (numline >= nti->NbLines()) || (numline < 0) )  {
+      cerr << "ntline2var Error: numline" << tokens[1] << " out of bounds" << endl; 
+      return(0);
+    }
+    r_8* dline = nti->GetLineD(numline);
+    for(int kkv=0; kkv<nti->NbColumns(); kkv++) {
+      sprintf(buff, "%lg ", dline[kkv]);
+      v2str += buff;
+    }
+  }
+  else {
+    int numcol = atoi(tokens[1].c_str());
+    if ( (numcol >= nti->NbColumns()) || (numcol < 0) )  {
+      cerr << "ntcol2var Error: numcol" << tokens[1] << " out of bounds" << endl; 
+      return(0);
+    }
+    int kks = 0;
+    int kke = nti->NbLines();
+    int kkp = 1;
+    if (tokens.size() > 3) Services2NObjMgr::DecodeLoopParameters(tokens[3], kks, kke, kkp);
+    if (kks < 0)  kks = 0;
+    if (kke > nti->NbLines()) kke = nti->NbLines();
+    if (kkp < 1) kkp = 1;
+    int nelt = (kke-kks-1)/kkp;
+    if (nelt > MAXNWORDSO2V) {
+      nelt = MAXNWORDSO2V;
+      cout << "ntcol2var Warning: Only " << nelt
+	   << " lines " << " will be converted to string" << endl;
+      kke = kks+nelt*kkp;
+    }
+    r_8* dline;
+    for(int kkl=kks; kkl<kke; kkl+=kkp) {
+      dline = nti->GetLineD(kkl);
+      sprintf(buff, "%lg ", dline[numcol]);
+      v2str += buff;
+    }
+  }
+  mObjMgr->SetVar(tokens[2], v2str);
+  if (adel) delete nti;
+}
+
+// -------------------------------------------------------
+// Copie d'objets
+else if ( (kw == "copy") || (kw == "cp") ) {
+  if(tokens.size()<2) { 
+    cout<<"Usage: copy name_from  name_to"<<endl;return(0); 
+  }
+  mObjMgr->CopyObj(tokens[0],tokens[1]);
+}
+
+
+// >>>>>>>>>>>  Affichage des objets 
+else if ( (kw == "disp") || (kw == "surf") || (kw == "imag") ) {
+  if (tokens.size() < 1) { cout << "Usage: disp/surf/imag nameobj [opt]" << endl; return(0); }
+  string opt = "next";
+  if (tokens.size() > 1)  opt = tokens[1];
+  if (kw == "disp") mObjMgr->DisplayObj(tokens[0], opt);
+  else if (kw == "surf")  mObjMgr->DisplaySurf3D(tokens[0], opt);
+  else if (kw == "imag")  mObjMgr->DisplayImage(tokens[0], opt);
+  }
+
+else if (kw == "nt2d") {
+  if (tokens.size() < 3) { 
+    cout << "Usage: nt2d nameobj varx vary [errx erry wt label opt]" << endl; 
+    return(0); 
+  }
+  while (tokens.size() < 8) tokens.push_back("");
+  string ph = "";
+  mObjMgr->DisplayNT(tokens[0], tokens[1], tokens[2], ph, tokens[3], tokens[4], ph, 
+                     tokens[5], tokens[6], tokens[7], false);
+  }
+else if (kw == "nt3d") {
+  if (tokens.size() < 7) { 
+    cout << "Usage: nt3d nameobj varx vary varz [errx erry errz wt label opt]" << endl; 
+    return(0); 
+  }
+  while (tokens.size() < 10) tokens.push_back("");
+  mObjMgr->DisplayNT(tokens[0], tokens[1], tokens[2], tokens[3], tokens[4], tokens[5],
+                     tokens[6], tokens[7], tokens[8], tokens[9], true);
+  }
+else if (kw == "vecplot") {
+  if (tokens.size() < 2) { 
+    cout << "Usage: vecplot nameVecX nameVecY [opt]" << endl;
+    return(0); 
+  }
+  while (tokens.size() < 3) tokens.push_back("");
+  mObjMgr->DisplayVector(tokens[0], tokens[1], tokens[2]);
+}
+
+// Obsolete : ne pas virer SVP, cmv 26/7/99
+else if (kw == "gfd2d") {
+  cout<<"----- gfd2d OBSOLETE: utilisez nt2d -----"<<endl;
+  if(tokens.size()<2)
+    {cout<<"Usage: gfd2d nomobj numvarx erreur=(x y xy) opt"<<endl;
+     return(0);}
+  string numvary = "";
+  string err = "";
+  string opt = "next";
+  if(tokens.size()>2) err = tokens[2];
+  if(tokens.size()>3) opt = tokens[3];
+  mObjMgr->DisplayGFD(tokens[0],tokens[1],numvary,err,opt);
+  }
+else if (kw == "gfd3d") {
+  cout<<"----- gfd3d OBSOLETE: utilisez nt3d -----"<<endl;
+  if(tokens.size()<3)
+    {cout<<"Usage: gfd3d nameobj numvarx numvary erreur=(x y z xy xz yz xyz) opt"<<endl;
+     return(0);}
+  string err = "";
+  string opt = "next";
+  if(tokens.size()>3) err = tokens[3];
+  if(tokens.size()>4) opt = tokens[4];
+  mObjMgr->DisplayGFD(tokens[0],tokens[1],tokens[2],err,opt);
+  }
+
+// >>>>>>>>>>>  Trace de fonctions 
+else if ( (kw == "func") ) {
+  if(tokens.size()<3) {cout<<"Usage: func f(x) xmin xmax [npt opt]"<<endl; return(0);}
+  int np = 100;
+  double xmin=0., xmax=1.;
+  string opt = "", nom = "";
+  xmin = atof(tokens[1].c_str()); xmax = atof(tokens[2].c_str());
+  if (tokens.size() > 3)  np = atoi(tokens[3].c_str());
+  if (tokens.size() > 4)  opt = tokens[4];
+  mObjMgr->GetServiceObj()->PlotFunc(tokens[0], nom, xmin, xmax, np, opt); 
+  }
+else if ( (kw == "funcff") ) {
+  if (tokens.size()<4) {cout<<"Usage: funcff C-filename f(x)-name xmin xmax [npt opt]"<<endl; return(0);}
+  int np = 100;
+  double xmin=0., xmax=1.;
+  string opt = "", nom = "";
+  xmin = atof(tokens[2].c_str());  xmax = atof(tokens[3].c_str());
+  if(tokens.size()>4)  np = atoi(tokens[4].c_str());
+  if(tokens.size()>5)  opt = tokens[5];
+  mObjMgr->GetServiceObj()->PlotFuncFrCFile(tokens[0], tokens[1], nom, xmin, xmax, np, opt); 
+  }
+else if ( (kw == "func2d") ) {
+  if (tokens.size() < 7) {
+    cout << "Usage: func2d f(x,y) xmin xmax nptx ymin ymax npty [opt]" << endl;
+    return(0);
+    }
+  int npx, npy;
+  double xmin, xmax;
+  double ymin, ymax;
+  npx = npy = 50;
+  xmin = 0.;  xmax = 1.;
+  ymin = 0.;  ymax = 1.;
+  npx = atoi(tokens[3].c_str());
+  npy = atoi(tokens[6].c_str());
+  xmin = atof(tokens[1].c_str());   xmax = atof(tokens[2].c_str());
+  ymin = atof(tokens[4].c_str());   ymax = atof(tokens[5].c_str());
+  string opt = "";
+  if (tokens.size() > 7)  opt = tokens[7];
+  string nom = "";
+  mObjMgr->GetServiceObj()->PlotFunc2D(tokens[0], nom, xmin, xmax, ymin, ymax, npx, npy, opt);
+  }
+else if ( (kw == "func2dff") ) {
+  if (tokens.size() < 8) {
+    cout << "Usage: func2d C-filename F(x,y)-name xmax nptx ymin ymax npty [opt]" << endl;
+    return(0);
+    }
+  int npx, npy;
+  double xmin, xmax;
+  double ymin, ymax;
+  npx = npy = 50;
+  xmin = 0.;  xmax = 1.;
+  ymin = 0.;  ymax = 1.;
+  npx = atoi(tokens[4].c_str());
+  npy = atoi(tokens[7].c_str());
+  xmin = atof(tokens[2].c_str());   xmax = atof(tokens[3].c_str());
+  ymin = atof(tokens[5].c_str());   ymax = atof(tokens[6].c_str());
+  string opt = "";
+  if (tokens.size() > 8)  opt = tokens[8];
+  string nom = "";
+  mObjMgr->GetServiceObj()->PlotFunc2DFrCFile(tokens[0], tokens[1], nom, xmin, xmax, ymin, ymax, npx, npy, opt);
+  }
+
+// >>>>>>>>>>>  Trace d'expressions de N_Tuple, StarList, etc ...
+else if (kw == "plot2d" ) {
+  if (tokens.size() < 3) {
+    cout << "Usage: plot2d nameobj expx expy [expcut opt loop_par]" << endl;
+    return(0); 
+    }
+  string errx = ""; string erry = ""; 
+  if (tokens.size() < 4) tokens.push_back("1");
+  while (tokens.size() < 6) tokens.push_back("");
+  srvo->DisplayPoints2D(tokens[0],tokens[1],tokens[2],errx,erry,tokens[3],tokens[4],tokens[5]);
+  }
+
+else if (kw == "plot2de" ) {  // Plot2D avec les erreurs 
+  if (tokens.size() < 5) {
+    cout << "Usage: plot2de nameobj expx expy experrx experry [expcut opt loop_par]" << endl;
+    return(0); 
+    }
+  if (tokens.size() < 6) tokens.push_back("1");
+  while (tokens.size() < 8) tokens.push_back("");
+  srvo->DisplayPoints2D(tokens[0],tokens[1],tokens[2],tokens[3],tokens[4],
+                        tokens[5],tokens[6],tokens[7]);
+  }
+
+else if (kw == "plot2dw" ) {   // Plot2d avec poids
+  if (tokens.size() < 4) { 
+    cout << "Usage: plot2dw nomobj expx expy expwt [expcut opt loop_par]" << endl;
+    return(0); 
+    }
+  if (tokens.size() < 5) tokens.push_back("1");
+  while (tokens.size() < 7) tokens.push_back("");
+  srvo->DisplayPoints2DW(tokens[0],tokens[1],tokens[2],tokens[3], tokens[4], tokens[5], tokens[6]);
+  }
+else if (kw == "plot3d" ) {  
+  if (tokens.size() < 4) { 
+    cout << "Usage: plot3d nomobj expx expy expz [expcut opt loop_par]" << endl;
+    return(0); 
+    }
+  if (tokens.size() < 5) tokens.push_back("1");
+  while (tokens.size() < 7) tokens.push_back("");
+  srvo->DisplayPoints3D(tokens[0],tokens[1],tokens[2],tokens[3], tokens[4], tokens[5], tokens[6]);
+  }
+
+else if (kw == "projh1d" ) {
+  if (tokens.size() < 3) { 
+    cout << "Usage: projh1d nomh1 nomobj expx [expwt expcut opt loop_par]" << endl;
+    return(0);
+    }
+  if (tokens.size() < 4) tokens.push_back("1.");
+  if (tokens.size() < 5) tokens.push_back("1");
+  while (tokens.size() < 7) tokens.push_back("");
+  srvo->ProjectH1(tokens[1], tokens[2], tokens[3], tokens[4], tokens[0], tokens[5], tokens[6] );
+  }
+
+
+// Projection dans histogrammes
+else if (kw == "projh2d" ) {
+  if (tokens.size() < 4) { 
+    cout << "Usage: projh2d nomh2 nomobj expx expy [expwt expcut opt loop_par]" << endl;
+    return(0);
+    }
+  if (tokens.size() < 5) tokens.push_back("1.");
+  if (tokens.size() < 6) tokens.push_back("1");
+  while (tokens.size() < 8) tokens.push_back("");
+  srvo->ProjectH2(tokens[1], tokens[2], tokens[3], tokens[4], tokens[5], tokens[0],
+                  tokens[6], tokens[7] );
+  }
+
+else if (kw == "projprof" ) {
+  if (tokens.size() < 4) { 
+    cout << "Usage: projprof nomprof nomobj expx expy [expwt expcut opt loop_par]" << endl;
+    return(0);
+    }
+  if (tokens.size() < 5) tokens.push_back("1.");
+  if (tokens.size() < 6) tokens.push_back("1");
+  while (tokens.size() < 8) tokens.push_back("");
+  srvo->ProjectHProf(tokens[1], tokens[2], tokens[3], tokens[4], tokens[5], tokens[0],
+                     tokens[6], tokens[7] );
+  }
+
+// Projection dans vector/matrix
+else if (kw == "fillvec" ) {
+  if (tokens.size() < 4) { 
+    cout << "Usage: fillvec nomvec nomobj expx expv [expcut opt loop_par]" << endl;
+    return(0);
+    }
+  if (tokens.size() < 5) tokens.push_back("1");
+  while (tokens.size() < 7) tokens.push_back("");
+  srvo->FillVect(tokens[1], tokens[2], tokens[3], tokens[4], tokens[0], tokens[5], tokens[6] );
+  }
+
+else if (kw == "fillmtx" ) {
+  if (tokens.size() < 5) { 
+    cout << "Usage: fillmtx nommtx nomobj expx expy expv [expcut opt loop_par]" << endl;
+    return(0);
+    }
+  if (tokens.size() < 6) tokens.push_back("1");
+  while (tokens.size() < 8) tokens.push_back("");
+  srvo->FillMatx(tokens[1], tokens[2], tokens[3], tokens[4], tokens[5], tokens[0],
+                    tokens[6], tokens[7] );
+  }
+
+// Remplissage NTuple,Vecteurs, ... , boucle de NTuple
+else if (kw == "ntfrascii" ) {
+  if(tokens.size() < 2) { 
+    cout<<"Usage: ntfrascii nt_name file_name [def_init_val]"<<endl;
+    return(0);
+    }
+  double def_val = 0.;
+  if(tokens.size()>=3) def_val = atof(tokens[2].c_str());
+  srvo->NtFromASCIIFile(tokens[0],tokens[1],def_val);
+  }
+
+#ifndef SANS_EVOLPLANCK
+/* Lecture matrice/vecteur depuis fichier ASCII  */
+else if ((kw == "mtxfrascii") || (kw == "vecfrascii") ) {
+  if(tokens.size() < 2) { 
+    cout<<"Usage: mtxfrascii/vecfrascii mtx/vec_name file_name [CommLine Separator]"<<endl;
+    return(0);
+    }
+  TMatrix<r_8> mtx;
+  TVector<r_8> vec;
+  FILE* fip = fopen(tokens[1].c_str(), "r");
+  if (fip == NULL) {
+    cout << "vec/mtxfrascii: can not open file " << tokens[1] << endl;
+    return(0);
+  }
+  fclose(fip);
+  ifstream is(tokens[1].c_str());
+  sa_size_t nr, nc;
+  char clm = '#';
+  string sep = " \t";
+  if (tokens.size()>2) clm = tokens[2][0];
+  if (tokens.size()>3) sep = tokens[3];
+  if (kw == "mtxfrascii") {
+    mtx.ReadASCII(is, nr, nc, clm, sep.c_str());
+    mObjMgr->AddObj(mtx, tokens[0]);    
+    cout << "mtxfrascii: TMatrix<r_8> " << tokens[0] << " read from file " 
+	 << tokens[1] << endl;
+  }
+  else {
+    vec.ReadASCII(is, nr, nc, clm, sep.c_str());
+    mObjMgr->AddObj(vec, tokens[0]);    
+    cout << "vecfrascii: TVector<r_8> " << tokens[0] << " read from file " 
+	 << tokens[1] << endl;
+  }
+}
+else if (kw == "arrtoascii")  {
+  if(tokens.size() < 2) { 
+    cout<<"Usage: arrtoascii array_name file_name "<<endl;
+    return(0);
+  }
+  
+  AnyDataObj* obj;
+  obj = mObjMgr->GetObj(tokens[0]);
+  if(obj == NULL) {
+    cerr << "arrtoascii Error , No such object " << tokens[0] << endl; 
+    return(0);
+  }
+  BaseArray* ba = dynamic_cast<BaseArray *>(obj);
+  if(ba == NULL) {
+    cerr << "arrtoascii Error " << tokens[0] << " not a BaseArray ! " << endl;
+    return(0);
+  }
+  ofstream os(tokens[1].c_str());  
+  ba->WriteASCII(os);
+  cout << "arrtoascii: Array " << tokens[0] << " written to file " << tokens[1] << endl;
+}
+  
+#endif
+
+else if (kw == "fillnt" ) {
+  if (tokens.size() < 5) { 
+    cout << "Usage: fillnt nameobj expx expy expz expt [expcut ntname loop_par]" << endl;
+    return(0);
+    }
+  while (tokens.size() < 8) tokens.push_back("");
+  srvo->FillNT(tokens[0],tokens[1],tokens[2], tokens[3], tokens[4], tokens[5], tokens[6], tokens[7] );
+  }
+
+else if (kw == "ntloop" ) {
+  if (tokens.size() < 3) { 
+    cout << "Usage: ntloop nameobj fname funcname [ntname loop_par ]" << endl;
+    return(0);
+    }
+  while (tokens.size() < 5) tokens.push_back("");
+  srvo->FillNTFrCFile(tokens[0],tokens[1], tokens[2], tokens[3], tokens[4]);
+  }
+
+else if (kw == "ntexpcfile" ) {
+  if (tokens.size() < 3) { 
+    cout << "Usage: ntexpcfile nameobj fname funcname" << endl;
+    return(0);
+    }
+  srvo->PrepareNTExpressionCFile(tokens[0],tokens[1], tokens[2]);
+  }
+
+else if (kw == "exptovec" ) {
+  if (tokens.size() < 3) { 
+    cout << "Usage: exptovec nomvec nameobj expx [expcut opt loop_par]" << endl;
+    return(0);
+    }
+  while (tokens.size() < 6) tokens.push_back("");
+  srvo->ExpressionToVector(tokens[1],tokens[2],tokens[3],tokens[0],tokens[4],tokens[5]);
+  }
+
+else if (kw == "fillgd1" ) {
+  if (tokens.size() < 5) {
+    cout << "Usage: fillgd1 nomgfd nomobj expx expy experry [expcut loop_par] " << endl;
+    return(0);
+    }
+  if (tokens.size() < 6) tokens.push_back("1");
+  if (tokens.size() < 7) tokens.push_back("");
+  string expy = "";
+  srvo->FillGFD(tokens[1],tokens[2], expy, tokens[3], tokens[4], tokens[5], tokens[0]);
+  }
+
+else if (kw == "fillgd2" ) {
+  if (tokens.size() < 6) {
+    cout << "Usage: fillgd2 nomgfd nomobj expx expy expz experrz [expcut loop_par]" << endl;
+    return(0);
+    }
+  if (tokens.size() < 7) tokens.push_back("1");
+  if (tokens.size() < 8) tokens.push_back("");
+  srvo->FillGFD(tokens[1],tokens[2],tokens[3], tokens[4], tokens[5], tokens[6], tokens[0], tokens[7]);
+  }
+
+else if (kw == "gdfrvec" ) {
+  if(tokens.size()<3) {
+    cout<<"Usage: gdfrvec namegfd X Y\n"
+        <<"       gdfrvec namegfd X Y"
+        <<"       gdfrvec namegfd X Y ! EY\n"
+        <<"       gdfrvec namegfd X Y Z\n"
+        <<"       gdfrvec namegfd X Y Z EZ"<<endl;
+    return(0);
+  }
+  while(tokens.size()<5) tokens.push_back("!");
+  srvo->FillGFDfrVec(tokens[0],tokens[1],tokens[2],tokens[3],tokens[4]);
+  }
+
+// >>>>>>>>>>>  Calcul d'expression arithmetique
+else if ( (kw == "eval") ) {
+  if(tokens.size()<2)
+    {cout<<"Usage: eval resultvarname arithmetic expression...."<<endl; return(0);}
+  string expval = "";
+  for(unsigned int i=1;i<tokens.size();i++) expval+=tokens[i];
+  string resultvarname = "";
+  if(isalpha(tokens[0][0])) resultvarname=tokens[0];
+  mObjMgr->GetServiceObj()->ExpVal(expval,resultvarname); 
+  }
+
+else  { 
+  cerr << "PIABaseExecutor::Do() Erreur - Commande " << kw << " inconuue ! " << endl;    
+  return(-1);
+  }
+
+return(0);
+}
+
+// Fonction pour enregistrer le Help des Widgets et Windows de piapp 
+static void RegisterPIGraphicsHelp(PIACmd* piac);
+
+/* --Methode-- */
+void PIABaseExecutor::RegisterCommands()
+{
+string kw, usage;
+kw = "loadmodule";
+usage = "To load and initialize modules \n  Usage: loadmodule fnameso modulename";
+usage += "\n  Related commands: link";  
+mpiac->RegisterCommand(kw, usage, this, "External Modules");
+kw = "link";
+usage = "Dynamic linking of compiled user functions \n  Usage: link fnameso f1 [f2 f3]";
+usage += "\n  fnameso: Shared-object file name, f1,f2,f3 : User function names ";
+usage += "\n  Related commands: call loadmodule linkff2";  
+mpiac->RegisterCommand(kw, usage, this, "External Modules");
+kw = "linkff2";
+usage = "Dynamic linking of compiled user functions (Set 2)\n  Usage: linkff2 fnameso f1 [f2 f3]";
+usage += "\n  fnameso: Shared-object file name, f1,f2,f3 : User function names ";
+usage += "\n  Related commands: call link loadmodule";  
+mpiac->RegisterCommand(kw, usage, this, "External Modules");
+kw = "call";
+usage = "Dynamically linked user function call \n Usage: call userf [arg1 arg2 ...]";
+usage += "\n  User function : f(vector<string>& args)";
+usage += "\n  Related commands: link";  
+mpiac->RegisterCommand(kw, usage, this, "External Modules");
+
+kw = "zone";
+usage = "To Divide the Graphic window \n  Usage: zone [nx=1 ny=1]";
+usage += "\n  Related commands: newwin";  
+mpiac->RegisterCommand(kw, usage, this, "Graphics");
+kw = "newwin";
+usage = "To Create a New Graphic window, with zones \n";
+usage += "  Window size can be specified \n";
+usage += "    Usage: newwin [nx ny [sizeX sizeY]] ";
+usage += "\n  Related commands: zone";  
+mpiac->RegisterCommand(kw, usage, this, "Graphics");
+kw = "stacknext";
+usage = "Displays the next widget on stack window \n  Usage: stacknext";
+mpiac->RegisterCommand(kw, usage, this, "Graphics");
+
+kw = "graphicatt";
+usage = "To change default graphic options \n  Usage: graphicatt att_list \n";
+usage += "att_list=def back to default values, Example: gratt 'red circlemarker5'";
+usage += "\n ------------------ Graphic attribute list ------------------ \n";
+usage += ">> Colors: defcol black white grey red blue green yellow \n";
+usage += "           magenta cyan turquoise navyblue orange siennared purple \n";
+usage += "           limegreen gold violet violetred blueviolet darkviolet \n";
+usage += ">> Lines:  defline normalline thinline thickline dashedline thindashedline \n";
+usage += "           thickdashedline dottedline thindottedline thickdottedline \n";
+usage += ">> Font Att: deffontatt normalfont boldfont italicfont bolditalicfont  \n";
+usage += "             smallfont smallboldfont smallitalicfont smallbolditalicfont \n";
+usage += "             bigfont bigboldfont bigitalicfont bigbolditalicfont \n";
+usage += "             hugefont  hugeboldfont hugeitalicfont hugebolditalicfont \n";
+usage += ">> Font Names: deffont courierfont helveticafont timesfont symbolfont  \n";
+usage += ">> Marker: dotmarker<T>  plusmarker<T>  crossmarker<T> circlemarker<T> \n";
+usage += "           fcirclemarker<T> boxmarker<T> fboxmarker<T> trianglemarker<T> \n";
+usage += "           ftrianglemarker<T>  starmarker<T>  fstarmarker<T> \n";
+usage += "   with <T> = 1 3 5 7 .. 15 , Example fboxmarker5 , plusmarker9 ... \n";
+usage += ">> ArrowMarker: basicarrow<T>  trianglearrow<T>  ftrianglearrow<T> \n";
+usage += "                arrowshapedarrow<T> farrowshapedarrow<T> \n";
+usage += "   with <T> = 5 7 .. 15 , Example trianglearrow7 ... \n";
+usage += ">> ColorTables: defcmap  grey32  invgrey32  colrj32  colbr32 \n";
+usage += "                grey128  invgrey128  colrj128  colbr128 \n";
+usage += "                midas_pastel midas_heat midas_rainbow3 midas_bluered\n";
+usage += "                midas_bluewhite midas_redwhite \n";
+usage += "                rainbow16 \n";
+usage += "   revcmap : This flag reverses ColorMap indexing \n";
+usage += ">> ZoomFactors      zoomxN zoomx1 zoomx2 zoomx3 ... \n";
+usage += "   (image display)  zoom/N zoom/2 zoom/3 zoom/4 ...\n";
+usage += ">> imagecenter=ix,iy -> Position the image in widget \n";
+usage += ">> lut=ltyp,min,max -> Sets LUT type and min/max for image display \n";
+usage += "                       (ltyp=lin/log/sqrt/square) \n";
+usage += ">> Axes:  stdaxes=defaxes=boxaxes boxaxesgrid centeredaxes\n";
+usage += "          fineaxes finecenteredaxes fineaxesgrid\n"; 
+usage += "          centeredaxesgrid finecenteredaxesgrid \n"; 
+usage += "          grid nogrid labels nolabels ticks noticks \n"; 
+usage += "          minorticks nominorticks extticks intticks axesnone \n"; 
+usage += ">> Axe labels font size: fixedfontsize/autofontsize \n";
+usage += "          autofontsize: Font size computed automatically \n";
+usage += "          fixedfontsize: Use font size attribute (BaseDrawer) \n";
+usage += ">> LogScale : linx liny logx logy -> Lin/Log Scales for 2D plots \n";
+usage += ">> xylimits=xmin,xmax,ymin,ymax  -> Forces X-Y limits in 2-D plots \n";
+usage += ">> defdrrect=xmin,xmax,ymin,ymax -> Defines drawing rectangle 2-D plots \n";
+usage += "          The rectangle is defined as a fraction of the widget size\n";
+usage += ">> stat/nostat or stats/nostats -> Toggle statistic display flag \n";
+usage += ">> title/notitle or tit/notit -> Toggle Auto AddTitle flag \n";
+usage += ">> DisplayWindow: next same win stack inset \n";
+usage += "   Related commands: setaxesatt setinsetlimits ";  
+mpiac->RegisterCommand(kw, usage, this, "Graphics");
+
+kw = "setaxesatt";
+usage = "To set default axes attributes \n  Usage: setaxesatt att_list \n";
+usage += "Color/Line/Font attributes and axes attributes \n";
+usage += ">> Axes:  stdaxes=defaxes=boxaxes boxaxesgrid centeredaxes\n";
+usage += "          fineaxes finecenteredaxes fineaxesgrid \n"; 
+usage += "          centeredaxesgrid finecenteredaxesgrid \n"; 
+usage += "          grid nogrid labels nolabels ticks noticks \n"; 
+usage += "          minorticks nominorticks extticks intticks axesnone \n"; 
+usage += ">> Axe labels font size: fixedfontsize/autofontsize \n";
+usage += "          autofontsize: Font size computed automatically \n";
+usage += "          fixedfontsize: Use font size attribute (BaseDrawer) \n";
+usage += ">> LogScale : linx liny logx logy -> Lin/Log Scales for 2D plots \n";
+usage += ">> xylimits=xmin,xmax,ymin,ymax  -> Forces X-Y limits in 2-D plots \n";
+usage += ">> defdrrect=xmin,xmax,ymin,ymax -> Defines drawing rectangle 2-D plots \n";
+usage += "          The rectangle is defined as a fraction of the widget size\n";
+mpiac->RegisterCommand(kw, usage, this, "Graphics");
+
+kw = "setinsetlimits";
+usage = "Define the display rectangle for drawers added as insets \n";
+usage += " over existing graphic objects - limits expressed as fraction \n";  
+usage += " graphic object size (0. .. 1.) Xmax at right, YMax top. ";
+usage += " Usage: setinsetlimits xmin xmax ymin ymax";
+usage += "\n  Related commands: graphicatt /inset";  
+mpiac->RegisterCommand(kw, usage, this, "Graphics");
+
+kw = "drpanel";
+usage = "Creates a new 2D drawing zone for addtext, addline \n";
+usage += " Usage: drpanel xmin xmax ymin ymax [GrAtt] [Name]";
+usage += "\n  Related commands: addtext addline addrect addcirc ...";  
+mpiac->RegisterCommand(kw, usage, this, "Graphics");
+
+kw = "addtext";
+usage = "Adds a text string to the current graphic object";
+usage += "\n at the specified position (+ color/font/pos/dir attributes) ";
+usage += "\n The Base/AxesDrawer is used to handle added text strings" ;
+usage += "\n Alt<E> to remove the added element";
+usage += "\n  Usage: addtext x y TextString [ColFontPosAtt] [fgnc=false/true]";
+usage += "\n  (use quotes '' for multi word text strings) ";
+usage += "\n  if fgnc==true : Normalized 0..1 coordinates specification (def=false)";
+usage += "\n Text position/direction attribute: "; 
+usage += "\n      horizleft horizcenter horizright";
+usage += "\n      vertbottom vertcenter verttop ";
+usage += "\n      textdirhoriz textdirvertup textdirvertdown ";
+usage += "\n  Related commands: addctext addline addarrow addrect addfrect";
+usage += "\n      addcirc addfcirc addarc addfrac addpoly addfpoly settitle graphicatt";  
+mpiac->RegisterCommand(kw, usage, this, "Graphic-Elts");
+
+kw = "addctext";
+usage = "Adds a composite text string with superscript and subscripts ";
+usage += "\n at the specified position (+ color/font/pos/dir attributes) ";
+usage += "\n  Usage: addctext x y Text sUp sDown [ColFontPosAtt] [UpDownFontAtt] [fgnc]";
+usage += "\n  if fgnc==true : Normalized 0..1 coordinates specification (def=false)";
+usage += "\n  Related commands: addtext addline addrect ...";
+usage += "\n      (See command addtext and graphicatt for more details)";  
+mpiac->RegisterCommand(kw, usage, this, "Graphic-Elts");
+
+kw = "addline";
+usage = "Adds a line to the current graphic object";
+usage += "\n at the specified position (+ graphic attribute)";
+usage += "\n The Base/AxesDrawer is used to handle added lines"; 
+usage += "\n Alt<E> to remove the added element";
+usage += "\n  Usage: addline x1 y1 x2 y2 [GraphicAtt] [fgnc=false/true]";
+usage += "\n  if fgnc==true : Normalized 0..1 coordinates specification (def=false)";
+usage += "\n  Related commands: addarrow addtext addrect addfrect ";
+usage += "\n       addmarker addcirc addfcirc addarc addfarc addpoly addfpoly graphicatt";  
+mpiac->RegisterCommand(kw, usage, this, "Graphic-Elts");
+
+kw = "addarrow";
+usage = "Adds an arrow to the current graphic object";
+usage += "\n at the specified position (+ graphic attribute)";
+usage += "\n The Base/AxesDrawer is used to handle added lines"; 
+usage += "\n Alt<E> to remove the added element";
+usage += "\n  Usage: addarrow x1 y1 x2 y2 [GraphicAtt] [fgnc=false/true]";
+usage += "\n  if fgnc==true : Normalized 0..1 coordinates specification (def=false)";
+usage += "\n  Related commands: addline addtext addrect addfrect ";
+usage += "\n       addmarker addcirc addfcirc addarc addfarc addpoly addfpoly graphicatt";  
+mpiac->RegisterCommand(kw, usage, this, "Graphic-Elts");
+kw = "addarrow_nc";
+
+kw = "addrect";
+usage = "Adds a rectangle to the current graphic object";
+usage += "\n between the specified positions (+ graphic attribute)";
+usage += "\n The Base/AxesDrawer is used to handle added rectangle"; 
+usage += "\n Alt<E> to remove added element";
+usage += "\n  Usage: addrect x1 y1 x2 y2 [GraphicAtt] [fgnc=false/true]";
+usage += "\n  if fgnc==true : Normalized 0..1 coordinates specification (def=false)";
+usage += "\n  Related commands: addtext addline addarrow addfrect";
+usage += "\n       addcirc addfcirc addarc addfarc addpoly addfpoly graphicatt";  
+mpiac->RegisterCommand(kw, usage, this, "Graphic-Elts");
+
+kw = "addfrect";
+usage = "Adds a filled rectangle to the current graphic object";
+usage += "\n between the specified positions (+ graphic attribute)";
+usage += "\n The Base/AxesDrawer is used to handle added rectangle"; 
+usage += "\n Alt<E> to remove added element";
+usage += "\n  Usage: addfrect x1 y1 x2 y2 [GraphicAtt] [fgnc=false/true]";
+usage += "\n  if fgnc==true : Normalized 0..1 coordinates specification (def=false)";
+usage += "\n  Related commands: addtext addline addarrow addrect";
+usage += "\n       addcirc addfcirc addpoly addfpoly graphicatt";  
+mpiac->RegisterCommand(kw, usage, this, "Graphic-Elts");
+
+kw = "addmarker";
+usage = "Adds a marker to the current graphic object";
+usage += "\n at the specified position (+ graphic attribute)";
+usage += "\n The Base/AxesDrawer is used to handle added circles"; 
+usage += "\n Alt<E> to remove added element";
+usage += "\n  Usage: addmarker xpos ypos [GraphicAtt] [fgnc=false/true]";
+usage += "\n  if fgnc==true : Normalized 0..1 coordinates specification (def=false)";
+usage += "\n  Related commands: addtext addline addarrow addfrect addfrect";
+usage += "\n       addcirc addfcirc addarc addfarc addpoly addfpoly graphicatt";  
+mpiac->RegisterCommand(kw, usage, this, "Graphic-Elts");
+
+kw = "addcirc";
+usage = "Adds a circle to the current graphic object";
+usage += "\n with the specified center and radius (+ graphic attribute)";
+usage += "\n The Base/AxesDrawer is used to handle added circles"; 
+usage += "\n Alt<E> to remove added element";
+usage += "\n  Usage: addcirc xcenter ycenter radius [GraphicAtt] [fgnc=false/true]";
+usage += "\n  if fgnc==true : Normalized 0..1 coordinates specification (def=false)";
+usage += "\n  Related commands: addtext addline addarrow addfrect addfrect";
+usage += "\n       addfcirc addarc addfarc addpoly addfpoly graphicatt";  
+mpiac->RegisterCommand(kw, usage, this, "Graphic-Elts");
+
+kw = "addfcirc";
+usage = "Adds a filled circle to the current graphic object";
+usage += "\n with the specified center and radius (+ graphic attribute)";
+usage += "\n The Base/AxesDrawer is used to handle added circles"; 
+usage += "\n Alt<E> to remove added element";
+usage += "\n  Usage: addcirc xcenter ycenter radius [GraphicAtt] [fgnc=false/true]";
+usage += "\n  if fgnc==true : Normalized 0..1 coordinates specification (def=false)";
+usage += "\n  Related commands: addtext addline addarrow addfrect addfrect";
+usage += "\n       addcirc addarc addfarc addpoly addfpoly graphicatt";  
+mpiac->RegisterCommand(kw, usage, this, "Graphic-Elts");
+
+kw = "addarca";
+usage = "Adds an arc to the current graphic object";
+usage += "\n defined by the circle (center+radius), start angle and angular extension";
+usage += "\n Angles are specified in degrees";
+usage += "\n  Usage: addarca xc yc r a0deg dadeg [GraphicAtt] [fgnc=false/true]";
+usage += "\n  if fgnc==true : Normalized 0..1 coordinates specification (def=false)";
+usage += "\n  Related commands: addtext addline addfarca addarc ...";
+mpiac->RegisterCommand(kw, usage, this, "Graphic-Elts");
+
+kw = "addfarca";
+usage = "Adds a filled arc to the current graphic object";
+usage += "\n defined by the circle (center+radius), start angle and angular extension";
+usage += "\n Angles are specified in degrees";
+usage += "\n  Usage: addfarca xc yc r a0deg dadeg [GraphicAtt] [fgnc=false/true]";
+usage += "\n  if fgnc==true : Normalized 0..1 coordinates specification (def=false)";
+usage += "\n  Related commands: addtext addline addarca addarc ...";
+mpiac->RegisterCommand(kw, usage, this, "Graphic-Elts");
+
+kw = "addarc";
+usage = "Adds an arc to the current graphic object";
+usage += "\n defined by 3 points (+ graphic attribute)";
+usage += "\n The Base/AxesDrawer is used to handle added arcs"; 
+usage += "\n Alt<E> to remove the added element";
+usage += "\n  Usage: addarc x1 y1 x2 y2 x3 y3 [GraphicAtt] [fgnc=false/true]";
+usage += "\n  if fgnc==true : Normalized 0..1 coordinates specification (def=false)";
+usage += "\n  Related commands: addtext addline addarrow addfrect addfrect";
+usage += "\n       addcirc addfcirc addfarc addarca addpoly addfpoly graphicatt";  
+mpiac->RegisterCommand(kw, usage, this, "Graphic-Elts");
+
+kw = "addfarc";
+usage = "Adds a filled arc to the current graphic object";
+usage += "\n defined by 3 points (+ graphic attribute)";
+usage += "\n The Base/AxesDrawer is used to handle added arcs"; 
+usage += "\n Alt<E> to remove added element";
+usage += "\n  Usage: addarc x1 y1 x2 y2 x3 y3 [GraphicAtt] [fgnc=false/true]";
+usage += "\n  if fgnc==true : Normalized 0..1 coordinates specification (def=false)";
+usage += "\n  Related commands: addtext addline addarrow addfrect addfrect";
+usage += "\n       addcirc addfcirc addfarc addpoly addfpoly graphicatt";  
+mpiac->RegisterCommand(kw, usage, this, "Graphic-Elts");
+
+kw = "addpoly";
+usage = "Adds a polyline/polygon to the current graphic object";
+usage += "\n  Usage: addploy 'x1,y1 x2,y2 x3,y3 ...' [GraphicAtt] [fgnc=false/true]";
+usage += "\n  Coordinates specified as pairs x,y in a single word (use simple or double quotes";
+usage += "\n  if fgnc==true : Normalized 0..1 coordinates specification (def=false)";
+usage += "\n  Related commands: addtext addline addarrow addfrect addfrect";
+usage += "\n       addcirc addfcirc addfarc  graphicatt";  
+mpiac->RegisterCommand(kw, usage, this, "Graphic-Elts");
+
+kw = "addfpoly";
+usage = "Adds a filled polygon to the current graphic object";
+usage += "\n  Usage: addploy 'x1,y1 x2,y2 x3,y3 ...' [GraphicAtt] [fgnc=false/true]";
+usage += "\n  Coordinates specified as pairs x,y in a single word (use simple or double quotes";
+usage += "\n  if fgnc==true : Normalized 0..1 coordinates specification (def=false)";
+usage += "\n  Related commands: addtext addline addarrow addfrect addfrect";
+usage += "\n       addcirc addfcirc addfarc  graphicatt";  
+mpiac->RegisterCommand(kw, usage, this, "Graphic-Elts");
+
+kw = "settitle";
+usage = "Set the title string (top title / bottom title) for the current graphic object";
+usage += "\n  Usage: settitle TopTitle [BottomTitle] [fontAtt]";
+usage += "\n  Related commands: addtext graphicatt";  
+mpiac->RegisterCommand(kw, usage, this, "Graphics");
+
+kw = "addtitle";
+usage = "Set the title string (top title / bottom title) \n";
+usage += "   alias for settitle ";
+mpiac->RegisterCommand(kw, usage, this, "Graphics");
+
+kw = "setaxelabels";
+usage = "Set the X and Y axis labels for the current 2D graphic object \n";
+usage += "\n  Usage: setaxelabels xLabel yLabel [ColorFntAtt]";
+usage += "\n  Related commands: settitle addtext graphicatt";  
+mpiac->RegisterCommand(kw, usage, this, "Graphics");
+
+kw = "addaxelabels";
+usage = "Set the X and Y axis labels for the current 2D graphic object";
+usage += "   alias for setaxelabels ";
+mpiac->RegisterCommand(kw, usage, this, "Graphics");
+
+RegisterPIGraphicsHelp(mpiac);
+
+kw = "openfits";
+usage = "Loads a FITS file into an appropriate object \n Usage: openfits filename";
+usage += "\n  Related commands: savefits openppf";  
+mpiac->RegisterCommand(kw, usage, this, "FileIO");
+kw = "savefits";
+usage = "Save an object into a FITS file \n Usage: savefits nameobj filename";
+usage += "\n  Related commands: openfits saveobjs saveall";  
+mpiac->RegisterCommand(kw, usage, this, "FileIO");
+kw = "openppf";
+usage = "Reads all objects from a PPF file \n Usage: openppf filename";
+usage += "\n  Related commands: saveall openfits";  
+mpiac->RegisterCommand(kw, usage, this, "FileIO");
+kw = "saveppf";
+usage = "Saves objects with names matching a pattern into a\n";
+usage += "  PPF file (pattern: x?y*) - Alias saveppf\n";
+usage += "Usage: saveppf nameobjpattern filename";
+usage += "\n  Related commands: saveobjs saveall openppf savefits";  
+mpiac->RegisterCommand(kw, usage, this, "FileIO");
+kw = "saveobjs";
+usage = "Saves objects with names matching a pattern into a\n";
+usage += "  PPF file (pattern: x?y*) - Alias saveppf\n";
+usage += "Usage: saveobjs nameobjpattern filename";
+usage += "\n  Related commands: saveppf saveall openppf savefits";  
+mpiac->RegisterCommand(kw, usage, this, "FileIO");
+kw = "saveall";
+usage = "Saves all objects into a PPF file \n Usage: saveall filename";
+usage += "\n  Related commands: saveobj openppf savefits";  
+mpiac->RegisterCommand(kw, usage, this, "FileIO");
+kw = "ntfrascii";
+usage = "Fills an existing NTuple from ASCII table file";
+usage += "\n Usage: ntfrascii nt_name file_name [def_init_val]";
+usage += "\n  Related commands: ntloop fillnt ";
+mpiac->RegisterCommand(kw, usage, this, "FileIO");
+#ifndef SANS_EVOLPLANCK
+kw = "mtxfrascii";
+usage = "Reads a matrix from an ASCII file (TMatrix<r_8>)";
+usage += "\n Usage: mtxfrascii mtx_name file_name [CommChar Separator]";
+usage += "\n  Related commands: arrtoascii vecfrascii ntfrascii ";
+mpiac->RegisterCommand(kw, usage, this, "FileIO");
+kw = "vecfrascii";
+usage = "Reads a vector from an ASCII file (TVector<r_8>)";
+usage += "\n Usage: vecfrascii vec_name file_name";
+usage += "\n  Related commands: arrtoascii mtxfrascii ntfrascii [CommChar Separator]";
+mpiac->RegisterCommand(kw, usage, this, "FileIO");
+kw = "arrtoascii";
+usage = "Writes an array (TArray<T>) to an ASCII file ";
+usage += "\n Usage: arrtoascii array_name file_name";
+usage += "\n  Related commands:  mtxfrascii vecfrascii ntfrascii ";
+mpiac->RegisterCommand(kw, usage, this, "FileIO");
+#endif
+
+kw = "print";
+usage = "Prints an object \n Usage: print nameobj";
+mpiac->RegisterCommand(kw, usage, this, "FileIO");
+
+kw = "mkdir";
+usage = "Create a directory";
+usage += "\n Usage: mkdir dirname [true]";
+usage += "\n if second argument==true, the directory's KeepOld attribute is set to true";
+mpiac->RegisterCommand(kw, usage, this, "Object Management");
+kw = "rmdir";
+usage = "Removes an empty directory";
+usage += "\n Usage: remove dirname";
+mpiac->RegisterCommand(kw, usage, this, "Object Management");
+kw = "setdiratt";
+usage = "Sets directory attributes";
+usage += "\n Usage: setdiratt dirname KeepOldFlag(=true/false)";
+usage += "\n   KeepOldFlag=true Object with the same name is moved to old";
+usage += "\n   when adding objects";
+mpiac->RegisterCommand(kw, usage, this, "Object Management");
+kw = "cd";
+usage = "Change current directory";
+usage += "\n Usage: cd [dirname]";
+mpiac->RegisterCommand(kw, usage, this, "Object Management");
+kw = "pwd";
+usage = "Prints current directory";
+usage += "\n Usage: pwd";
+mpiac->RegisterCommand(kw, usage, this, "Object Management");
+kw = "listdirs";
+usage = "Prints the list of directories";
+usage += "\n Usage: listdirs [patt=*] \n patt : * , ? ";
+mpiac->RegisterCommand(kw, usage, this, "Object Management");
+kw = "listobjs";
+usage = "Prints the list of objects (Alias: ls)";
+ usage += "\n Usage: listobjs [patt=*] \n patt : /*/x?y* ... ";
+mpiac->RegisterCommand(kw, usage, this, "Object Management");
+kw = "rename";
+usage = "Rename an object (Alias: mv) \n Usage: rename nameobj namenew";
+usage += "\n  Related commands: mv del delobjs";  
+mpiac->RegisterCommand(kw, usage, this, "Object Management");
+kw = "mv";
+usage = "Rename an object (Alias: rename) \n Usage: mv nameobj namenew";
+usage += "\n  Related commands: rename del delobjs";  
+mpiac->RegisterCommand(kw, usage, this, "Object Management");
+kw = "copy";
+usage = "Copy objects (Alias cp) \n";
+usage +="  Usage: copy name_from name_to";
+usage += "\n  Related commands: cp new...";  
+mpiac->RegisterCommand(kw, usage, this, "Object Management");
+kw = "cp";
+usage = "Copy objects (Alias copy) \n";
+usage +="  Usage: cp name_from name_to";
+usage += "\n  Related commands: copy new...";  
+mpiac->RegisterCommand(kw, usage, this, "Object Management");
+kw = "del";
+usage = "Deletes an object (Alias: rm) \n Usage: del nameobj [nameobj2 ...]";
+usage += "\n  Related commands: rm delobjs rename";  
+mpiac->RegisterCommand(kw, usage, this, "Object Management");
+kw = "rm";
+usage = "Deletes an object (Alias: del) \n Usage: rm nameobj [nameobj2 ...]";
+usage += "\n  Related commands: del delobjs rename";  
+mpiac->RegisterCommand(kw, usage, this, "Object Management");
+kw = "delobjs";
+usage = "Delete a set of objects with names matching a pattern (x?y*)";
+usage += "\n Usage: delobjs nameobjpattern \n";
+usage += "\n  Related commands: del rename";  
+mpiac->RegisterCommand(kw, usage, this, "Object Management");
+
+kw = "newh1d";
+usage = "Creates a 1D histogramm \n Usage: newh1d name xmin xmax nbin";
+usage += "\n  Related commands: newh2d  newprof[e] newnt  newgfd ";  
+mpiac->RegisterCommand(kw, usage, this, "Objects");
+kw = "newh2d";
+usage = "Creates a 2D histogramm \n Usage: newh2d name xmin xmax nbinx ymin ymax nbiny";
+usage += "\n  Related commands: newh1d  newprof[e] newnt  newgfd ";  
+mpiac->RegisterCommand(kw, usage, this, "Objects");
+kw = "newprof";
+usage = "Creates a profile histogramm \n Usage: newprof name xmin xmax nbin [ymin ymax]";
+usage += "\n  Errors represent the data spread in the X bin ";  
+usage += "\n  Related commands: newh1d  newh2d newprofe newnt newgfd ";  
+mpiac->RegisterCommand(kw, usage, this, "Objects");
+kw = "newprofe";
+usage = "Creates a profile histogramm \n Usage: newprofe name xmin xmax nbin [ymin ymax]";
+usage += "\n  Errors represent the error on the data mean in the X bin ";  
+usage += "\n  Related commands: newh1d  newh2d newprof newnt newgfd ";  
+mpiac->RegisterCommand(kw, usage, this, "Objects");
+kw = "newnt";
+usage = "Creates a ntuple \n Usage: newnt name v1 v2 v3 .. vn";
+usage += "\n        newnt name nvar";  
+usage += "\n  Related commands: newh1d  newh2d newprof[e] newgfd ";  
+mpiac->RegisterCommand(kw, usage, this, "Objects");
+kw = "newgfd";
+usage = "Creates GeneralFit Data object \n Usage: newgfd nvar nalloc [errx(0/1)]";
+usage += "\n  Related commands: newh1d  newh2d  newprof[e] newnt ";  
+mpiac->RegisterCommand(kw, usage, this, "Objects");
+kw = "newvec";
+usage = "Creates (and optionaly fills) a vector \n Usage: newvec name size [f(i) [dopt] ] ";
+usage += "\n  Related commands: newmtx line2vec";  
+mpiac->RegisterCommand(kw, usage, this, "Objects");
+kw = "newmtx";
+usage = "Creates (and optionaly fills) a matrix \n";
+usage +="  Usage: newmtx name sizeX(Col) sizeY(Lines) [f(i,j) [dopt] ] ";
+usage += "\n  Related commands: newvec";  
+mpiac->RegisterCommand(kw, usage, this, "Objects");
+kw = "line2vec";
+usage = "Creates a vector from the line \n";
+usage += "  Usage: line2vec vecname v0 v1 v2 ... \n";
+usage += "  Related commands: newvec line2nt";  
+mpiac->RegisterCommand(kw, usage, this, "Objects");
+kw = "line2nt";
+usage = "Fills (append) an NTuple from the line content \n";
+usage += "  Usage: line2nt ntname col0 col1 ... \n";
+usage += "  Related commands: newnt line2vec ntline2var ntcol2var";  
+mpiac->RegisterCommand(kw, usage, this, "Objects");
+kw = "vec2var";
+usage = "Vector content to an interpreter variable varname = 'v0 v1 v2 ...' \n";
+usage += "  Usage: line2vec vecname varname [LoopParam start:end[:step] ]\n";
+usage += "  Related commands: line2vec ntline2var";  
+mpiac->RegisterCommand(kw, usage, this, "Objects");
+kw = "ntline2var";
+usage = "Object NTupleInterface line to an interpreter variable \n";
+usage += "  Usage: ntline2var objname line_number varname \n";
+usage += "  Related commands: vec2var ntcol2var";  
+mpiac->RegisterCommand(kw, usage, this, "Objects");
+kw = "ntcol2var";
+usage = "Object NTupleInterface column to an interpreter variable \n";
+usage += "  Usage: ntline2var objname column_number varname [LoopParam start:end[:step] ] \n";
+usage += "  Related commands: vec2var ntline2var";  
+mpiac->RegisterCommand(kw, usage, this, "Objects");
+
+kw = "disp";
+usage = "Displays an object \n Usage: disp nameobj [graphic_attributes]";
+usage += "\n  Related commands: surf nt2d nt3d vecplot";  
+mpiac->RegisterCommand(kw, usage, this, "Obj. Display");
+kw = "imag";
+usage = "Displays an object as an image \n Usage: imag nameobj [graphic_attributes]";
+usage += "\n  Related commands: disp surf nt2d nt3d vecplot";  
+mpiac->RegisterCommand(kw, usage, this, "Obj. Display");
+kw = "surf";
+usage = "Displays an object as a 3D surface \n Usage: surf nameobj [graphic_attributes]";
+usage += "\n  Related commands: disp nt2d nt3d vecplot";  
+mpiac->RegisterCommand(kw, usage, this, "Obj. Display");
+kw = "nt2d";
+usage = "Displays Points (X-Y) [with error-bar / Weight / Label ] from an NTuple ";
+usage += "\n Usage : nt2d nameobj varx vary [errx erry wt label graphic_attributes]";
+usage += "\n  Related commands: disp  surf  nt3d  gfd2d vecplot";  
+mpiac->RegisterCommand(kw, usage, this, "Obj. Display");
+kw = "nt3d";
+usage = "Displays 3D-Points (X-Y-Z) [with error-bars / Weight / Label ] from an NTuple ";
+usage += "\n Usage : nt3d nameobj varx vary varz [errx erry errz wt label graphic_attributes]";
+usage += "\n  Related commands: disp  surf  nt2d gfd3d ";  
+mpiac->RegisterCommand(kw, usage, this, "Obj. Display");
+kw = "vecplot";
+usage = "Displays Points (X-Y) with coordinates defined by two vectors ";
+usage += "\n Usage : vecplot nameVecX nameVecY [graphic_attributes]";
+usage += "\n  Related commands: disp nt2d ";  
+mpiac->RegisterCommand(kw, usage, this, "Obj. Display");
+
+// Ceci est maintenant obsolete, on garde pour info.
+kw = "gfd2d";
+usage = "Displays Points (X-Y) with error-bars from a GeneralFit Data ";
+usage += "\n Usage : gfd2d nameobj numvarx erreur=(x y xy) [graphic_attributes]";
+usage += "\n  Related commands: gfd3d nt2d nt3d ";
+usage += "\n  ----- OBSOLETE: utilisez nt2d -----";
+mpiac->RegisterCommand(kw, usage, this, "Obj. Display");
+kw = "gfd3d";
+usage = "Displays 3D-Points (X-Y-Z) with error-bars from a GeneralFit Data ";
+usage += "\n Usage : gfd3d nameobj numvarx numvary erreur=(x y z xy xz yz xyz) [graphic_attributes]";
+usage += "\n  Related commands: gfd2d nt2d nt3d ";  
+usage += "\n  ----- OBSOLETE: utilisez nt3d -----";
+mpiac->RegisterCommand(kw, usage, this, "Obj. Display");
+
+kw = "func";
+usage = "Displays a function y=f(x) (Fills a vector with function values)";
+usage += "\n Usage: func f(x) xmin xmax [npt graphic_attributes]";
+usage += "\n  Related commands: funcff func2d func2dff ";  
+mpiac->RegisterCommand(kw, usage, this, "Func Plot");
+kw = "funcff";
+usage = "Displays a function y=f(x) from a C-file (Fills a vector with function values)";
+usage += "\n Usage: funcff C-FileName FunctionName xmin xmax [npt graphic_attributes]";
+usage += "\n  Related commands: func func2d func2dff ";  
+mpiac->RegisterCommand(kw, usage, this, "Func Plot");
+kw = "func2d";
+usage = "Displays a function z=f(x,y) (Fills a matrix with function values)";
+usage += "\n Usage: func2d f(x,y) xmin xmax nptx ymin ymax npty [graphic_attributes]";
+usage += "\n  Related commands: func";  
+mpiac->RegisterCommand(kw, usage, this, "Func Plot");
+kw = "func2dff";
+usage = "Displays a function z=f(x,y) from a C-file (Fills a matrix with function values)";
+usage += "\n Usage: func2dff C-FileName FunctionName xmin xmax nptx ymin ymax npty [graphic_attributes]";
+usage += "\n  Related commands: func funcff func2d ";  
+mpiac->RegisterCommand(kw, usage, this, "Func Plot");
+
+kw = "ObjectExpressions";
+usage = "Any mathematical expression (math.h) with object variables can be used";
+usage += "\n  ------ Object Variable names (double) -------- ";
+usage += "\n- NTuple: ntuple variable names";
+usage += "\n- Histo1D/HProf: i,x,val,err";
+usage += "\n- Histo2D: i,j,x,y,val,err";
+usage += "\n- Vector/Matrix: n,r,c,val,real,imag,mod,phas";
+usage += "\n- TArray: n,x,y,z,t,u,val,real,imag,mod,phas";
+usage += "\n- Image: i,j,x,y,val(=pix)";
+usage += "\n- GeneralFitData: x0,ex0 x1,ex1 ...  xn,exn   y,ey   ok";
+usage += "\n- LocalMap/SphereThetaPhi/SphereHEALPix: ";
+usage += "\n-         i,k,val,real,imag,mod,phas,teta,phi";
+usage += "\n- FITS Binary/ASCII table: fits column names";
+#ifdef SANS_EVOLPLANCK
+usage += "\n  ------ Eros Variable names (double) -------- ";
+usage += "\n- StarList: x,y,flux,fond,pixmax,flags,";
+usage += "\n-           xref,yref,fluxref,fondref,pixmaxref";
+#endif
+usage += "\n  ------ Other parameters -------- ";
+usage += "\nLoop parameters can be specified as I1[:I2[:DI]] for(int i=I1; i<I2; i+=DI)"; 
+usage += "\nThe default Cut() expression in true (=1) for all"; 
+usage += "\n\n  Related commands: plot2d plot2de plot2dw plot3d "; 
+usage += "\n        projh1d projh2d  projprof fillvec fillmtx "; 
+usage += "\n        fillnt fillgd1 fillgd2 ntloop exptovec ... ";
+mpiac->RegisterCommand(kw, usage, NULL, "Expr. Plotting");
+kw = "plot2d";
+usage = "Plots (2D) Y=g(Object) vs. X=f(Object) --- Object Variable names (double) :";
+usage += "\n Usage: plot2d nameobj f_X() g_Y() [f_Cut() graphic_attributes loop_param]";
+usage += "\n  Related commands: plot2de plot2dw plot3d ObjectExpressions ..."; 
+mpiac->RegisterCommand(kw, usage, this, "Expr. Plotting");
+kw = "plot2de";
+usage = "Plots (2D) Y=g(Object) vs. X=f(Object) with error bars eX/Y=f_ErrX/Y(Object) ";
+usage += "\n Usage: plot2de nameobj f_X() g_Y() f_ErrX() f_ErrY() [f_Cut() graphic_attributes loop_param]";
+usage += "\n  Related commands: plot2d plot2dw plot3d ObjectExpressions ..."; 
+mpiac->RegisterCommand(kw, usage, this, "Expr. Plotting");
+kw = "plot2dw";
+usage = "Plots (2D) Y=g(Object) vs. X=f(Object) with Weight W=h(Object) ";
+usage += "\n Usage: plot2dw nameobj f_X() g_Y() h_Wt() [Cut() graphic_attributes loop_param]";
+usage += "\n  Related commands: plot2d plot2dw plot3d ObjectExpressions ..."; 
+mpiac->RegisterCommand(kw, usage, this, "Expr. Plotting");
+kw = "plot3d";
+usage = "Plots (3D) Z=h(Object) vs. Y=g(Object) vs. X=f(Object) vs ";
+usage += "\n Usage: plot3d nameobj f_X() g_Y() h_Z() [Cut() graphic_attributes loop_param]";
+usage += "\n  Related commands: plot2d plot2dw plot2de plot3d ObjectExpressions ..."; 
+mpiac->RegisterCommand(kw, usage, this, "Expr. Plotting");
+
+kw = "projh1d";
+usage = "Projects X=f(Object) with weight WT=h(Object) into a 1D histogram ";
+usage += "\n Usage: projh1d nameh1d nameobj f_X() [h_WT()=1. Cut() graphic_attributes loop_param]";
+usage += "\n   Histo1D nameh1d is created if necessary ";
+usage += "\n  Related commands: projh2d projprof ObjectExpressions ..."; 
+mpiac->RegisterCommand(kw, usage, this, "Expr. Plotting");
+kw = "projh2d";
+usage = "Projects (X=f(Object),Y=g(Object)) with weight WT=h(Object) into a 2D histogram ";
+usage += "\n Usage: projh2d nameh2d nameobj f_X() g_Y() [h_WT()=1. Cut() graphic_attributes loop_param]";
+usage += "\n   Histo2D nameh2d is created if necessary ";
+usage += "\n  Related commands: projh1d projprof ObjectExpressions ..."; 
+mpiac->RegisterCommand(kw, usage, this, "Expr. Plotting");
+kw = "projprof";
+usage = "Projects (X=f(Object),Y=g(Object)) with weight WT=h(Object) into a profile histogram ";
+usage += "\n Usage: projprof nameprof nameobj f_X() g_Y() [h_WT()=1. Cut() graphic_attributes loop_param]";
+usage += "\n   HProf nameprof is created if necessary ";
+usage += "\n  Related commands: projh1d projh2d ObjectExpressions ..."; 
+mpiac->RegisterCommand(kw, usage, this, "Expr. Plotting");
+kw = "fillvec";
+usage = "Fills a Vector V((int)(f_X(Object)+0.5)) =  h_V(Object) ";
+usage += "\n Usage: fillvec namevec nameobj f_X() h_V() [Cut() graphic_attributes loop_param]";
+usage += "\n  Related commands: fillmtx fillnt ObjectExpressions ..."; 
+mpiac->RegisterCommand(kw, usage, this, "Expr. Plotting");
+kw = "fillmtx";
+usage = "Fills a Matrix M(Line=g_Y(Object)+0.5, Col=f_X(Object)+0.5)) =  h_V(Object) ";
+usage += "\n Usage: fillvec namevec nameobj f_X() g_Y() h_V() [Cut() graphic_attributes loop_param]";
+usage += "\n  Related commands: fillvec fillnt ObjectExpressions ..."; 
+mpiac->RegisterCommand(kw, usage, this, "Expr. Plotting");
+
+kw = "fillnt";
+usage = "Creates and Fills an NTuple(x,y,z,t) with (X=f(Object),Y=g(...),Z=h(...),T=k(...))";
+usage += "\n Usage: fillnt nameobj f_X() g_Y() h_Z() k_T() [Cut() nameNt loop_param]";
+usage += "\n  Related commands: ntloop plot2d projh1d projh2d projprof ";
+usage += "\n  Related commands: fillvec fillmtx ntloop exptovec fillgd1 fillgd2 ObjectExpressions ..."; 
+mpiac->RegisterCommand(kw, usage, this, "Expr. Plotting");
+
+kw = "ntloop";
+usage = "Loops over an Object NTupleInterface calling a function from a C-file \n";
+usage += "and optionaly fills an NTuple(x,y,z,t) with (X=f(Object),Y=g(...),Z=h(...),T=k(...))";
+usage += "\n Usage: ntloop nameobj CFileName FuncName [NtupleName loop_param]";
+usage += "\n  Related commands: fillvec fillmtx fillnt fillgd1 fillgd2 exptovec ObjectExpressions ..."; 
+usage += "\n  Related commands: ntexpcfile fillnt";
+mpiac->RegisterCommand(kw, usage, this, "Expr. Plotting");
+
+kw = "ntexpcfile";
+usage = "Creates a C-File with declarations suitable to be used for ntloop";
+usage += "\n Usage: ntexpcfile nameobj CFileName FuncName ";
+usage += "\n  Related commands: ntloop";
+mpiac->RegisterCommand(kw, usage, this, "Expr. Plotting");
+
+kw = "exptovec";
+usage = "Creates and Fills a Vector with X=f(Object)";
+usage += "\n Usage: exptovec namevec nameobj f_X() [Cut() graphic_attributes loop_param]";
+usage += "\n  Related commands: ntloop fillnt ObjectExpressions ..."; 
+mpiac->RegisterCommand(kw, usage, this, "Expr. Plotting");
+kw = "fillgd1";
+usage = "Creates and Fills a GeneralFitData with (X=f(Object), Y=g(...), ErrY=h(...))";
+usage += "\n Usage: fillgd1 namegfd nameobj f_X() g_Y() h_ErrY() [Cut() loop_param]";
+usage += "\n  Related commands: ntloop fillnt ObjectExpressions ..."; 
+mpiac->RegisterCommand(kw, usage, this, "Expr. Plotting");
+kw = "fillgd2";
+usage = "Creates and Fills a GeneralFitData with (X=f(Object), Y=g(...), Z=h(...)) ErrZ=k(...)";
+usage += "\n Usage: fillgd1 namegfd nameobj f_X() g_Y() h_Z() k_ErrZ() [Cut() loop_param]";
+usage += "\n  Related commands: ntloop fillnt ObjectExpressions ..."; 
+mpiac->RegisterCommand(kw, usage, this, "Expr. Plotting");
+kw = "gdfrvec";
+usage = "Fills a GeneralFitData with vectors X,Y,Z,EZ";
+usage += "\n Usage: gdfrvec namegfd X Y";
+usage += "\n Usage: gdfrvec namegfd X Y ! EY";
+usage += "\n Usage: gdfrvec namegfd X Y Z";
+usage += "\n Usage: gdfrvec namegfd X Y Z EZ";
+usage += "\n  Related commands: fillgd1 fillgd2 ..."; 
+mpiac->RegisterCommand(kw, usage, this, "Expr. Plotting");
+
+
+kw = "eval";
+usage = "Compute arithmetic expression\n";
+usage += "\n Usage: eval resultvarname arithmetic expression....";
+usage += "\n  resultvarname: store result in variable resultvarname";
+usage += "\n    - If first character is not alphabetic, just print result";
+usage += "\n  arithmetic expression:";
+usage += "\n      ex: x + sqrt(y)+z +3.14    (x,y,z are variables)";
+usage += "\n      ex: $x + sqrt($y)+$z +3.14 (x,y,z are variables)";
+usage += "\n      ex: 360 * M_PI / 180.";
+mpiac->RegisterCommand(kw, usage, this, "Expr. Arithmetic");
+
+}
+
+/* --Methode-- */
+int PIABaseExecutor::LinkUserFuncs(string& fnameso, string& func1, string& func2, string& func3)
+//                          string& func4, string& func5)
+{
+string cmd;
+
+if (dynlink) delete dynlink;    dynlink = NULL;
+usfmap.clear();
+
+dynlink = new PDynLinkMgr(fnameso, true);
+if (dynlink == NULL) { 
+  string sn = fnameso; 
+  cerr << "PIABaseExecutor/LinkUserFuncs_Erreur: Erreur ouverture SO " << sn << endl; 
+  return(2); 
+  }
+
+int nok=0;
+// on utilise donc des DlFunction  (Reza 20/08/98)  voir commentaire ds .h (pb g++)
+// DlUserProcFunction f = NULL;
+DlFunction f = NULL;
+if ((func1.length() < 1) || (func1 == "-") || (func1 == ".") )  goto fin;
+// f = (DlUserProcFunction)  dlsym(dlhandle, func1.c_str());
+f = dynlink->GetFunction(func1);
+if (f) { nok++;  usfmap[func1] = f; }
+else cerr << "PIABaseExecutor/LinkUserFuncs_Erreur: Erreur linking " << func1 << endl;
+
+if ((func2.length() < 1) || (func2 == "-") || (func2 == ".") )  goto fin;
+// f = (DlUserProcFunction)  dlsym(dlhandle, func2.c_str());
+f = dynlink->GetFunction(func2);
+if (f) { nok++;  usfmap[func2] = f; }
+else cerr << "PIABaseExecutor/LinkUserFuncs_Erreur: Erreur linking " << func2 << endl;
+
+if ((func3.length() < 1) || (func3 == "-") || (func3 == ".") )  goto fin;
+// f = (DlUserProcFunction)  dlsym(dlhandle, func3.c_str());
+f = dynlink->GetFunction(func3);
+if (f) { nok++;  usfmap[func3] = f; }
+else cerr << "PIABaseExecutor/LinkUserFuncs_Erreur: Erreur linking " << func3 << endl;
+
+/*  Pb compile g++ 2.7.2 
+if ((func4.length() < 1) || (func4 == "-") || (func4 == ".") )  goto fin;
+// f = (DlUserProcFunction)  dlsym(dlhandle, func4.c_str());
+f = dynlink->GetFunction(func4);
+if (f) { nok++;  usfmap[func4] = f; }
+else cerr << "PIABaseExecutor/LinkUserFuncs_Erreur: Erreur linking " << func4 << endl;
+
+if ((func5.length() < 1) || (func5 == "-") || (func5 == ".") )  goto fin;
+// f = (DlUserProcFunction)  dlsym(dlhandle, func5.c_str());
+f = dynlink->GetFunction(func5);
+if (f) { nok++;  usfmap[func5] = f; }
+else cerr << "PIABaseExecutor/LinkUserFuncs_Erreur: Erreur linking " << func5 << endl;
+*/
+fin:
+if (nok < 1) { if (dynlink) delete dynlink;    dynlink = NULL;  return(3); }
+else return(0);
+}
+
+/* --Methode-- */
+int PIABaseExecutor::LinkUserFuncs2(string& fnameso, string& func1, string& func2, string& func3)
+{
+string cmd;
+
+if (dynlink2) delete dynlink2;    dynlink2 = NULL;
+usfmap2.clear();
+
+dynlink2 = new PDynLinkMgr(fnameso, true);
+if (dynlink2 == NULL) { 
+  string sn = fnameso; 
+  cerr << "PIABaseExecutor/LinkUserFuncs2_Erreur: Erreur ouverture SO " << sn << endl; 
+  return(2); 
+  }
+
+int nok=0;
+// on utilise donc des DlFunction  (Reza 20/08/98)  voir commentaire ds .h (pb g++)
+// DlUserProcFunction f = NULL;
+DlFunction f = NULL;
+if ((func1.length() < 1) || (func1 == "-") || (func1 == ".") )  goto fin;
+f = dynlink2->GetFunction(func1);
+if (f) { nok++;  usfmap2[func1] = f; }
+else cerr << "PIABaseExecutor/LinkUserFuncs2_Erreur: Erreur linking " << func1 << endl;
+
+if ((func2.length() < 1) || (func2 == "-") || (func2 == ".") )  goto fin;
+f = dynlink2->GetFunction(func2);
+if (f) { nok++;  usfmap2[func2] = f; }
+else cerr << "PIABaseExecutor/LinkUserFuncs2_Erreur: Erreur linking " << func2 << endl;
+
+if ((func3.length() < 1) || (func3 == "-") || (func3 == ".") )  goto fin;
+f = dynlink2->GetFunction(func3);
+if (f) { nok++;  usfmap2[func3] = f; }
+else cerr << "PIABaseExecutor/LinkUserFuncs2_Erreur: Erreur linking " << func3 << endl;
+
+fin:
+if (nok < 1) { if (dynlink2) delete dynlink2;    dynlink2 = NULL;  return(3); }
+else return(0);
+}
+
+/* Nouvelle-Fonction */
+void RegisterPIGraphicsHelp(PIACmd* piac)
+{
+string kw,grp,usage;
+
+grp = "Graphics";
+
+kw = "PIImage";
+usage = "Manages the display of a 2-D array (P2DArrayAdapter) as an image \n";
+usage += "and controls a zoom widget, as well as a global image view widget \n";
+usage += ">>>> Mouse controls : \n";
+usage += "o Button-1: Display current coordinates and pixel value\n";
+usage += "  Position the cursor an refresh the zoom widget\n";
+usage += "o Button-2: Defines an image zone and positions the cursor \n";
+usage += "o Button-3: Moves the viewed portion of the array inside the window \n";
+usage += ">>>> Keyboard controls : \n";
+usage += "o <Alt>R : Refresh display \n";
+usage += "o <Alt>O : Shows the PIImageTools (image display parameter controls) \n";
+usage += "o <Alt>G : Show the PIDrawerTools (Graphic attributes of overlayed graphics (Drawers)) \n";
+usage += "o <Alt>V : Copy/Paste / Text paste at the current cursor position \n";
+usage += "o <Alt>C : Copy/Paste / Copies the selected regions content as text in the copy/paste buffer \n";
+usage += "o <Alt>X : Show/Hide the Cut Window \n";
+usage += "o <Alt>Z : Removes added graphic elements (handled by BaseDrawer - 0) \n";
+usage += "o <Alt>E : Removes the last added graphic element \n";
+usage += "o <Alt>+ or <Cntl>+ : Zoom in \n";
+usage += "o <Alt>- or <Cntl>- : Zoom out \n";
+usage += "o Cursor keys : Moves the image cursor \n";
+piac->RegisterHelp(kw, usage, grp);
+
+kw = "PIScDrawWdg";
+usage = "Manages display of 2-D drawers with interactive zoom \n";
+usage += ">>>> Mouse controls : \n";
+usage += "o Button-1: Display current coordinates \n";
+usage += "o Button-2: Defines a rectangle for zoom \n";
+usage += "o Button-3: Defines a rectangle for Text-Info (<Alt>I) \n";
+usage += ">>>> Keyboard controls : \n";
+usage += "o <Alt>R : Refresh display \n";
+usage += "o <Alt>O : Displays a specific control window (default: PIDrawerTools) \n";
+usage += "           Specific controls for 2-D histograms \n";
+usage += "o <Alt>G : Show the PIDrawerTools (Graphic attributes of displayed Drawers) \n";
+usage += "           Drawer 0 manages the axes, as well as the added text \n";
+usage += "o <Alt>V : Copy/Paste / Text paste at the current position \n";
+usage += "o <Alt>Z : Removes added graphic elements (handled by BaseDrawer - 0) \n";
+usage += "o <Alt>E : Removes the last added graphic element \n";
+usage += "o <Alt>I : Shows (or updates) a text info window on the selected rectangle \n";
+usage += "o <Alt>M : Activate/Deactivate a measurement cursor on Button-1\n";
+usage += "o <Alt>L : Deactivate DX,DY print (see below)\n";
+usage += ">>>> Mouse + Keyboard controls : \n";
+usage += "o Button-1 + <Alt>K : Set (reset) the reference point for DX,DY print \n";
+piac->RegisterHelp(kw, usage, grp);
+
+kw = "PIDraw3DWdg";
+usage = "Manages display of 3-D objects (drawers)  \n";
+usage += ">>>> Mouse controls : \n";
+usage += "o Button-2: Rotates the observer (camera) around object \n";
+usage += "o Shift-Button-2: Rotates object with camera fixed \n";
+usage += "  The object rotation mode can be assigned to Button-2 with <Alt>S \n";
+usage += "o Button-3: Zoom control (Camera distance And/Or view angle) \n";
+usage += ">>>> Keyboard controls : \n";
+usage += "o <Alt>R : Resets the 3-D view and refreshes the display \n";
+usage += "o <Alt>G : Show the PIDrawerTools (Graphic attributes of displayed Drawers) \n";
+usage += "o <Alt>O : = <Alt>G \n";
+usage += "o <Alt>V : Copy/Paste / Text paste at the current position (Drawer 0)\n";
+usage += "o <Alt>Z : Removes added graphic elements (handled by BaseDrawer - 0) \n";
+usage += "o <Alt>E : Removes the last added graphic element \n";
+usage += "o <Alt>A : Activate/Deactivate axes drawing \n";
+usage += "o <Alt>S : Activate/Deactivate object rotation mode on Button-2 \n";
+piac->RegisterHelp(kw, usage, grp);
+
+kw = "Windows";
+usage = "Objects can be displayed in different windows, or overlayed on the \n";
+usage += "previous display. The graphics attributes next,win,stack,same control \n";
+usage += "the display window. \n";
+usage += "o GraphicWindow : This is the default mode (gr_att=next)\n";
+usage += "  Graphic windows can be divided int zones. Object is displayed \n";
+usage += "  in the next available position, removing a previously displayed \n";
+usage += "  widget if necessary \n";
+usage += "o Window : An object is displayed in its own window (gr_att= win) \n";
+usage += "o StackWindow : multpile widgets can be stacked in a StackWindow (gr_att= stack) \n";
+usage += "  A single widget is displayed a any time. Different widgets in a StackWindow \n";
+usage += "  can be displayed using the stacknext command, as well as the StackTools item \n";
+usage += "  in the Tools menu (from Menubar). An automatic cyclic display mode can also \n";
+usage += "  be activated using the StackTools menu (Blink) \n";
+usage += "o Most objects can be also be displayed overlayed \n";
+usage += "  on the last displayed widget (gr_att= same) \n";
+usage += "o The overlay can be on a selected rectangle of the \n";  
+usage += "  last displayed widget (gr_att= inset) - See setinsetlimits\n";
+usage += "\n  Related commands: newwin zone stacknext graphicatt setinsetlimits";  
+piac->RegisterHelp(kw, usage, grp);
+
+kw = "PIConsole";
+usage = "Text output area and command editing window (console) \n";
+usage += ">>>> Mouse controls : \n";
+usage += "o Button-1: Rectangle selection for copy/paste \n";
+usage += "o Button-2: Paste text in the command editing line \n";
+usage += "o Button-3: activate display option menu \n";
+usage += ">>>> Keyboard controls : \n";
+usage += "o <Alt>O : activate display option menu   \n";
+usage += "o <Alt>V : Paste text in the command editing line \n";
+usage += "o <Alt>A : Selection of the whole window for copy \n";
+usage += "o <Alt>L : Command history (List of command history buffer) \n";
+usage += "o <Ctl>A : Command editing -> Goto the beginning of line \n";
+usage += "o <Ctl>E : Command editing -> Goto the end of line \n";
+usage += "o <Ctl>K : Command editing -> Clear to the end of line \n";
+usage += "o <Ctl>C : Command editing -> Clear the line \n";
+usage += "o Cursor left,right : Command editing -> Move cursor \n";
+usage += "o Cursor Up,Down : recall command from history buffer \n";
+usage += "o Backspace,Del : Command editing \n";
+usage += "o <Return>,<Enter> : Execute command \n";
+piac->RegisterHelp(kw, usage, grp);
+}
Index: /tags/V_Dec2002/SophyaPI/PIext/basexecut.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/basexecut.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/basexecut.h	(revision 2309)
@@ -0,0 +1,37 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe executeur de commande de base pour piapp
+//                                   Reza 05/99
+// LAL-IN2P3/CNRS
+
+#ifndef PIABaseExecutor_H_SEEN
+#define PIABaseExecutor_H_SEEN
+
+#include "piacmd.h"
+
+class PIABaseExecutor : public CmdExecutor {
+public :
+		PIABaseExecutor(PIACmd* piac, NamedObjMgr* omg, PIStdImgApp* app);
+  virtual	~PIABaseExecutor();
+  virtual int	Execute(string& keyw, vector<string>& args, string& toks);
+
+protected :
+  void		RegisterCommands();
+//  Link dynamique de fonction user
+  int 		LinkUserFuncs(string& fnameso, string& func1, string& func2, string& func3);
+  int 		LinkUserFuncs2(string& fnameso, string& func1, string& func2, string& func3);
+//                            string& func4, string& func5);   compil avec g++ 2.7.2
+  PIACmd* mpiac;
+  NamedObjMgr* mObjMgr;
+  PIStdImgApp* mImgApp;
+// g++ n'arrive pas a avaler ca (lignes trop longues)  on utilise donc des DlFunction  (Reza 20/08/98)
+// typedef map<string, DlUserProcFunction, less<string> > UsFmap;
+  typedef map<string, DlFunction, less<string> > UsFmap;
+  PDynLinkMgr* dynlink;
+  UsFmap usfmap;
+  PDynLinkMgr* dynlink2;
+  UsFmap usfmap2;
+
+};
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/contmodex.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/contmodex.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/contmodex.cc	(revision 2309)
@@ -0,0 +1,207 @@
+#include "contmodex.h"
+
+#include "pigncont.h"
+#include <typeinfo>
+
+#include <vector>
+#include <string>
+#include "nobjmgr.h"
+
+#include "pidrawer.h"
+#include "nomgadapter.h"
+#include "servnobjm.h"
+
+
+/* --Methode-- */
+ContModExecutor::ContModExecutor(PIACmd* mpiac, PIStdImgApp* app)
+{
+
+  //PIACmd * mpiac;
+  //NamedObjMgr omg;
+  //mpiac = omg.GetImgApp()->CmdInterpreter();
+
+  //cout << " ContModExecutor::ContModExecutor() mpiac = " << (unsigned long)mpiac << endl;
+  cout << " registration of contour commands "<<endl;
+  string hgrp,kw,usage;
+  
+  hgrp = "Obj. Display";
+  
+  kw = "contour";
+  usage = "Creates and displays a ContourDrawer ";
+  usage += "\n Usage: contour objectName [graphic_att/specific_opt] ";
+  usage += "\n Specific Options ";
+  usage += "\n    ncont=[number of contours (automatic levels) ] ";
+  usage += "\n    niv/lev=[values for contours, separated by ','] ";
+  usage += "\n    lstep=[nomber,first_value,increment for contours ] ";
+  usage += "\n    bspline : use bspline algo for contour " ;
+  usage += "\n    3spl : use cubic spline algo for contour " ;
+  usage += "\n    labon : put labels for contours " ;
+
+  mpiac->RegisterCommand(kw, usage, this, hgrp);
+  
+  hgrp = "Obj. Display";
+  kw = "ntcont";
+  usage = "Creates and displays a ContourDrawer (from a NTuple)";
+  usage += "\n Usage: ntcont NTupleName varx vary varz [graphic_att/specific_opt] ";
+  usage += "\n        specific options ";
+  usage += "\n    ncont=[number of contours (automatic levels) ] ";
+  usage += "\n    niv/lev=[values for contours, separated by ','] ";
+  usage += "\n    lstep=[nomber,first_value,increment for contours ] ";
+  usage += "\n    bspline : use bspline algo for contour " ;
+  usage += "\n    3spl : use cubic spline algo for contour " ;
+  usage += "\n    labon : put labels for contours " ;
+  mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+  //cout << " Out of ContModExecutor::ContModExecutor() " << endl;
+
+}
+ 
+
+
+/* --Methode-- */
+ContModExecutor::~ContModExecutor()
+{
+}
+
+/* --Methode-- */
+int ContModExecutor::Execute(string& kw, vector<string>& tokens, string& toks)
+{
+  
+int nz=-1;
+double z0,dz;
+  
+if ( kw == "contour") {
+   NamedObjMgr omg;
+   PIContourDrawer * contdrw = NULL;
+   string dopt="";
+ 
+   if (tokens.size() < 1) {
+     cout << "Usage: contour ObjName [graphic_att/specficic_opt: SEE HELP] " << endl;
+     return(0);
+   }
+
+   //   dopt = "same,thinline";  Si tu veux des valeurs par defaut
+   //if (tokens.size() > 1)  dopt = tokens[1];
+   //omg.PrintObj(tokens[0]);
+   NObjMgrAdapter* obja = omg.GetObjAdapter(tokens[0]);
+   if (obja == NULL) {
+     cout << "contour Error , No object with name " << tokens[0] << endl; 
+     return(0);
+   }
+   string ctyp = typeid(*obja).name();
+   cout << " objet de type "<<ctyp <<endl;
+   AnyDataObj* ob = obja->GetDataObj();
+   if (ob == NULL) {
+     cerr << "Error - NULL object ! in " <<  tokens[0] << endl;
+     return(0);
+   }
+   ctyp = typeid(*ob).name();
+   cout << " objet de type "<<ctyp <<endl;
+   cout << " ContModExecutor::Execute recuperation du p2darrayadapter "<<endl;
+   if (tokens.size() > 1) dopt = tokens[1];
+   P2DArrayAdapter* arr = obja->Get2DArray(dopt);
+   if (arr != NULL) {
+       contdrw = new PIContourDrawer(arr,true           );
+   }else{
+     cout <<"contour ERREUR : OBJET "<<tokens[0]<<" N'A PAS DE P2DARRADAPTOR "<<endl;
+     return(0);
+   }
+
+   
+   cout << " contour: Creating PIContourDrawer() for object" << tokens[0] << endl;
+   
+   cout << " contour: Determination of contour lines ..."<< contdrw <<endl;
+   contdrw->CalcContour();
+   //NTuple *out = contdrw->MyIso();
+   //NTuple *truc = new NTuple(*out);
+   //string nom = "isoc";
+   //if(out!=NULL) omg.AddObj(truc,nom   );
+   cout << " ===>>> success ! "<< contdrw <<endl;
+
+   // On affiche le Drawer
+   int wrsid = 0;
+   
+   string name = "contour";
+   cout << " ContModExecutor::Execute() : name "<<name<<" " <<"| dopt |"<<dopt<<"| contdrw |"<<contdrw<<endl;
+   wrsid = omg.GetImgApp()->DispScDrawer(contdrw, name, dopt); 
+   cout << " fin de ContModExecutor::Execute() "<< endl;
+   
+
+   // Ne pas oublier d'associer le wrsid a l'objet si on utilise le P2DArrayAdapter* arr
+   omg.AddWRsId(tokens[0], wrsid);
+   
+
+   }
+if ( kw == "ntcont"){  
+     NamedObjMgr omg;
+     PIContourDrawer * contdrw = NULL;
+     string dopt="";
+     bool adel;
+     //cout << " essai avec ntuple "<<tokens.size()<<endl;
+     if (tokens.size() < 4) {
+       cout << "Usage: contour NtName varx vary varz [graphic_att/specific_opt: SEE HELP]"
+	    << endl;
+       return(0);
+     }
+     dopt="";
+     NObjMgrAdapter* obja = omg.GetObjAdapter(tokens[0]);
+     if (obja == NULL) {
+       cout << "ntcont Error , No NTuple with name " << tokens[0] << endl; 
+       return(0);
+     }
+    
+     NTupleInterface *ntin = obja->GetNTupleInterface(adel);
+     //cout << " tokens.size() "<< tokens.size()<<endl;
+     //for (int k=0; k<tokens.size() ; k++)cout<<"| k "<<k<<" tok |"<<tokens[k];
+     //cout <<endl;
+     if (tokens.size() > 4) dopt = tokens[4];
+     if (tokens.size() > 6){
+         dz = atof(tokens[6].c_str());
+         z0 = atof(tokens[7].c_str());
+         cout << " ContModExecutor::Execute [NT] nz,z,dz : "<<nz<<" , "<<z0 << " , " << dz<<endl;
+         contdrw = new PIContourDrawer(ntin,adel,&nz,&z0,&dz);
+     }
+     if (tokens.size() > 5){
+         nz = atoi(tokens[5].c_str()); 
+         cout << " ContModExecutor::Execute [NT] nz : "<<nz<< endl;
+         contdrw = new PIContourDrawer(ntin,adel,&nz           );
+     }else {
+       contdrw = new PIContourDrawer(ntin,adel           );
+     }
+     cout << " ntcont: Creating PIContourDrawer() for object " << tokens[0] << endl;
+   
+     cout << " ntcont : Determination of contour lines ..." <<endl;
+     contdrw->CalcContour();
+    
+     NTuple *out = contdrw->MyIso();
+     if(out!=NULL){
+	NTuple *truc = new NTuple(*out);
+	string nom = "isoc";
+	//truc->Write("isocur.ppf");
+	//out->Write("outcur.ppf");
+	omg.AddObj(truc,nom   );
+     }
+     /****************/
+     cout << " ===>>> success ! "<<endl;
+
+   // On affiche le Drawer
+     int wrsid = 0;
+     bool fgsr = true;
+     
+     string name = "contour";
+     
+     wrsid = omg.GetImgApp()->DispScDrawer(contdrw, name, dopt); 
+     
+     // Ne pas oublier d'associer le wrsid a l'objet si on utilise le P2DArrayAdapter* arr
+     omg.AddWRsId(tokens[0], wrsid);
+
+   }
+   
+
+
+return(0);
+
+}
+
+
+
Index: /tags/V_Dec2002/SophyaPI/PIext/contmodex.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/contmodex.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/contmodex.h	(revision 2309)
@@ -0,0 +1,22 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe   : commands copntour drawing in Peida Interactive
+// (c) DAPNIA (CEA)                 LAL (IN2P3/CNRS)
+//                           R. Ansari O.Perdereau  11/2001
+//                           
+#ifndef CONTMODEXE_H_SEEN
+#define CONTMODEXE_H_SEEN
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream.h> 
+#include "piacmd.h"
+#include "nobjmgr.h"
+
+class ContModExecutor : public CmdExecutor { 
+public:
+                ContModExecutor(PIACmd* , PIStdImgApp* );
+  virtual       ~ContModExecutor();
+  virtual int   Execute(string& keyw, vector<string>& args, string& toks);
+};
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/cxxexecutor.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/cxxexecutor.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/cxxexecutor.cc	(revision 2309)
@@ -0,0 +1,864 @@
+#include "cxxexecutor.h"
+
+#include <typeinfo>
+
+#include "strutilxx.h"
+#include "dvlist.h"
+#include "cxxcmplnk.h"
+
+#include "nomgadapter.h"
+#include "pistdimgapp.h"
+
+
+/* --Methode-- */
+CxxExecutor::CxxExecutor(PIACmd *mpiac, PIStdImgApp* /* app */)
+  : mUserCodeFn(""), mUserFctFn("")
+  , mCompOpt(""), mLinkOpt(""), mMyLibs("")
+  , mDefRoot("cxx_spiapp"), mDefFunc("usercxx"), mPrtLevel(2), mFgPutVar(false)
+{
+mIncList.resize(0);
+mCallArgs.resize(0);
+
+mIncImportList.resize(0);
+mModuleImportList.resize(0);
+
+// La liste de tous les modules que l'on peut ajouter
+mModuleImportDefaultList.resize(0);
+mModuleImportDefaultList.push_back("Samba");
+mModuleImportDefaultList.push_back("SkyMap");
+mModuleImportDefaultList.push_back("SkyT");
+mModuleImportDefaultList.push_back("FitsIOServer");
+mModuleImportDefaultList.push_back("IFFTW");
+mModuleImportDefaultList.push_back("LinAlg");
+mModuleImportDefaultList.push_back("XAstroPack");
+
+// On enregistre les nouvelles commandes 
+string hgrp = "CxxExecutorCmd";
+string usage,kw;
+
+kw = "c++exec";
+usage = "c++exec: Execute the following c++ user code\n";
+usage+= "Usage: c++exec c++ user code\n";
+usage+= "Warning: c++ user code can be found in \"TmpDir/"+mDefRoot+".h\"\n";
+usage+= "         total generated code can be found in \"TmpDir/"+mDefRoot+".cc\"";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "c++execfrf";
+usage = "c++execfrf: Execute c++ user_code [user_function_code]\n";
+usage+= "Usage: c++execfrf fileuser.cc [fileuserfct.cc]\n";
+usage+= "Warning: total generated code can be found in \"TmpDir/"+mDefRoot+".cc\"";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "c++args";
+usage = "c++args: Define user function arguments for c++exec and c++execfrf\n";
+usage+= "Usage: c++args arg1 arg2 arg3 ...\n";
+usage+= "       c++args -? : give current arguments\n";
+usage+= "       c++args    : reset current arguments";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "c++create";
+usage = "c++create: create a file \"file.cc\" to be used by spiapp\n";
+usage+= "Usage: c++create file.cc func c++ user code...\n";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "c++createfrf";
+usage = "c++createfrf: create a file \"file.cc\" to be used by spiapp\n";
+usage+= "        with a user file code \"fileuser.cc\"\n";
+usage+= "        and an optional user function code \"fileuserfct.cc\"\n";
+usage+= "Usage: c++createfrf file.cc func fileuser.cc [fileuserfct.cc]\n";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "c++compile";
+usage = "c++compile: compile a file (file.cc -> file.so)\n";
+usage+= "Usage: c++compile file\n";
+usage+= "Warning: give \"file\" or \"file.so\" to create \"file.so\" from \"file.cc\"\n";
+usage+= "       : to be used before c++link";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "c++link";
+usage = "c++link: link function \"func\" in file.so to spiapp\n";
+usage+= "Usage: c++link file.so func";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "c++include";
+usage = "c++include: add personnal includes to be used by executor\n";
+usage+= "Usage: c++include myinc1.h myinc2.h ...\n";
+usage+= "       c++include -? : list current additionnal include files\n";
+usage+= "       c++include    : reset to no additionnal include files\n";
+usage+= "Warning: to be used before c++create c++compile c++exec...";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "c++compileopt";
+usage = "c++compileopt: add personnal compile options\n";
+usage+= "Usage: c++compileopt -g -O5 -IMy_Inc_Dir ...\n";
+usage+= "       c++compileopt -? : list current additionnal compile options\n";
+usage+= "       c++compileopt    : reset to no additionnal compile options\n";
+usage+= "Warning: to be used before c++create c++compile c++exec ...";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "c++linkopt";
+usage = "c++linkopt: add personnal link options\n";
+usage+= "Usage: c++linkopt -g -O5 ...\n";
+usage+= "       c++linkopt -? : list current additionnal link options\n";
+usage+= "       c++linkopt    : reset to no additionnal link options\n";
+usage+= "Warning: to be used before c++create c++compile c++exec ...";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "c++mylibs";
+usage = "c++mylibs: add personnal libraries\n";
+usage+= "Usage: c++mylibs -LMy_Lib_Dir -lmylib1 -lmylib2 ...\n";
+usage+= "       c++mylibs -? : list current additionnal libraries\n";
+usage+= "       c++mylibs    : reset to no additionnal libraries\n";
+usage+= "Warning: to be used before c++create c++compile c++exec ...";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "c++import";
+usage = "c++import: Sophya additionnal modules to be use in C++ executor\n";
+usage+= "Usage: c++import module1 ... : set list of modules to be used by executor\n";
+usage+= "       c++import all : set all modules known by executor\n";
+usage+= "       c++import     : reset to no additionnal module\n";
+usage+= "       c++import -?  : list modules currently used in executor\n";
+usage+= "       c++import -?? : list of available modules for executor\n";
+usage+= "Warning: to be used before c++create c++compile c++exec ...";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "c++declareomgvar";
+usage = "c++declareomgvar: Activate/Deactivate ObjectManager variables declaration \n";
+usage+= "Usage: c++declareomgvar [false/true] \n";
+usage+= "   if true, the ObjectManager variables are declared as $varname \n";
+usage+= "   no arguments: display the current status of the flag (default=false\n";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "c++prtlevel";
+usage = "c++prtlevel: Print level\n";
+usage+= "Usage: c++prtlevel prtlevel\n";
+usage+= "       prtlevel=0 : minimum printing\n";
+usage+= "       prtlevel=1 : + compiler/linker output\n";
+usage+= "       prtlevel=2 : + full infos (default)";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+}
+
+/* --Methode-- */
+CxxExecutor::~CxxExecutor()
+{
+}
+
+/* --Methode-- */
+int CxxExecutor::Execute(string& kw, vector<string>& tokens, string& toks)
+{
+int rc=0;
+if(kw == "c++exec") {
+  if(tokens.size()<1) {
+    cout<<"Usage: c++exec c++ user code"<<endl;
+    return(1);
+  }
+  rc = ExecuteCXX(toks); if(rc) return(1);
+
+} else if(kw == "c++execfrf") {
+  if(tokens.size()<1) {
+    cout<<"Usage: c++execfrf fileuser.cc [fileuserfct.cc]"<<endl;
+    return(1);
+  }
+  rc = FillUserCode(tokens[0]); if(rc) return(1);
+  if(tokens.size()>1) rc = FillUserFctFrF(tokens[1]);
+    else              rc = FillUserFctFrF();
+  if(rc) return(1);
+  rc = CrFile();   if(rc) return(1);
+  rc = Compile();  if(rc) return(1);
+  rc = Link();     if(rc) return(1);
+  rc = Call();     if(rc) return(1);
+
+} else if(kw == "c++args") {
+  if(tokens.size()==1) if(tokens[0]=="-?")
+    {cout<<"c++args "<<GetArgs()<<endl; return(0);}
+  FillArgs(tokens);
+
+} else if(kw == "c++create") {
+  if(tokens.size()<3) {
+    cout<<"Usage: c++create file.cc func c++ user code ..."<<endl;
+    return(1);
+  }
+  rc = FillUserCode(toks,2);        if(rc) return(1);
+  rc = FillUserFctFrS();            if(rc) return(1);
+  rc = CrFile(tokens[0],tokens[1]); if(rc) return(1);
+
+} else if(kw == "c++createfrf") {
+  if(tokens.size()<3) {
+    cout<<"Usage: c++createfrf file.cc func fileuser.cc [fileuserfct.cc]"<<endl;
+    return(1);
+  }
+  rc = FillUserCode(tokens[2]); if(rc) return(1);
+  if(tokens.size()>3) rc = FillUserFctFrF(tokens[3]);
+    else              rc = FillUserFctFrF(tokens[3]);
+  if(rc) return(1);
+  rc = CrFile(tokens[0],tokens[1]); if(rc) return(1);
+
+} else if(kw == "c++compile") {
+  if(tokens.size()>=1) rc = Compile(tokens[0]);
+  else                 rc = Compile();
+  if(rc) return(1);
+
+} else if(kw == "c++link") {
+  if(tokens.size()>=2)      rc = Link(tokens[0],tokens[1]);
+  else if(tokens.size()>=1) rc = Link(tokens[0]);
+  else                      rc = Link();
+  if(rc) return(1);
+
+} else if(kw == "c++include") {
+  if(tokens.size()==1) if(tokens[0]=="-?")
+    {cout<<"c++include "<<GetInclude()<<endl; return(0);}
+  FillInclude(tokens);
+
+} else if(kw == "c++compileopt") {
+  if(tokens.size()==1) if(tokens[0]=="-?")
+    {cout<<"c++compileopt "<<GetCompileOpt()<<endl; return(0);}
+  FillCompileOpt(tokens);
+
+} else if(kw == "c++linkopt") {
+  if(tokens.size()==1) if(tokens[0]=="-?")
+    {cout<<"c++linkopt "<<GetLinkOpt()<<endl; return(0);}
+  FillLinkOpt(tokens);
+
+} else if(kw == "c++mylibs") {
+  if(tokens.size()==1) if(tokens[0]=="-?")
+    {cout<<"c++mylibs "<<GetLinkLibs()<<endl; return(0);}
+  FillLinkLibs(tokens);
+
+} else if(kw == "c++import") {
+  if(tokens.size()==1) {
+    if(tokens[0]=="-?")
+      {cout<<"c++import "<<GetModuleImport()<<endl; return(0);}
+    if(tokens[0]=="-??") {
+      cout<<"c++import possibilities :"<<endl;
+      if(mModuleImportDefaultList.size()>0) {
+        for(uint_4 i=0;i<mModuleImportDefaultList.size();i++)
+          cout<<" "<<mModuleImportDefaultList[i];
+        cout<<endl;
+      }
+      return(0);
+    }
+  }
+  FillModuleImport(tokens);
+} else if(kw == "c++declareomgvar") {
+  if (tokens.size() <1) {
+    string fgstat = (mFgPutVar) ? "TRUE" : "FALSE" ; 
+    cout << " c++declareomgvar: Current flag status: " <<  fgstat << endl;
+  }
+  else {
+    if (tokens[0] == "true") DeclareObjMgrVar(true);
+    else  if (tokens[0] == "false") DeclareObjMgrVar(false);
+  }
+} else if(kw == "c++prtlevel") {
+  if(tokens.size()==1) if(tokens[0]=="-?")
+    {cout<<"c++prtlevel prtlevel = "<<mPrtLevel<<endl; return(0);}
+  if(tokens.size()>0) {
+    int lp=atoi(tokens[0].c_str()); if(lp<0) lp=0;
+    mPrtLevel=(uint_2) lp;
+  } else mPrtLevel=2;
+
+}
+
+return(0);
+}
+
+/* --Methode-- */
+int  CxxExecutor::ExecuteCXX(string usercode,string userfct)
+{
+int rc=0;
+rc = FillUserCode(usercode,0); if(rc) return(1);
+rc = FillUserFctFrS(userfct);  if(rc) return(1);
+rc = CrFile();   if(rc) return(1);
+rc = Compile();  if(rc) return(1);
+rc = Link();     if(rc) return(1);
+rc = Call();     if(rc) return(1);
+return 0;
+}
+
+/* --Methode-- */
+int CxxExecutor::CrFile(string cfilename,string func)
+// Si un nom n'est pas precise alors TmpDir/cxx_spiapp.cc
+{
+if(cfilename.size()<1) cfilename = TmpDir() + mDefRoot + ".cc";
+
+if(func.size()<1) func = mDefFunc;
+
+ofstream os(cfilename.c_str(),ios::out);
+if(!os)
+  {cout<<"CxxExecutor::CrFile: unable to open "<<cfilename<<endl;
+   return 1;}
+
+PutInclude(os);
+os<<endl;
+
+PutIncludeUser(os);
+os<<endl;
+
+os<<"//-------------------------------------------------//"<<endl;
+os<<"//----------------- User Functions ----------------//"<<endl;
+os<<"//-------------------------------------------------//"<<endl;
+if(mUserFctFn.size()>0) os<<"#include \""<<mUserFctFn<<"\""<<endl;
+os<<endl;
+
+
+os<<"extern \"C\" {"<<endl;
+os<<"  int "<<func<<"( vector<string>& args );"<<endl;
+os<<"}"<<endl<<endl;
+os<<"int "<<func<<"( vector<string>& args )"<<endl;
+os<<"{"<<endl;
+os<<"// Some definitions to help using spiapp;"<<endl;
+os<<"NamedObjMgr omg;"<<endl;
+os<<"Services2NObjMgr& srvo = *omg.GetServiceObj();"<<endl;
+os<<endl;
+
+PutObject(os);
+os<<endl;
+
+if (mFgPutVar) PutVar(os);
+os<<endl;
+
+os<<"//--------------------------------------------//"<<endl;
+os<<"//----------------- User Code ----------------//"<<endl;
+os<<"//--------------------------------------------//"<<endl;
+if(mUserCodeFn.size()>0) os<<"#include \""<<mUserCodeFn<<"\""<<endl;
+os<<endl;
+
+os<<"return 0;"<<endl;
+os<<"}"<<endl;
+
+if(mPrtLevel>1)
+  cout<<"File "<<cfilename<<" for function "<<func<<" created :"<<endl;
+if(mPrtLevel>1 && mUserCodeFn.size()>0)
+  cout<<"  User code was in file "<<mUserCodeFn<<endl;
+if(mPrtLevel>1 && mUserFctFn.size()>0)
+  cout<<"  User function code was in file "<<mUserFctFn<<endl;
+return 0;
+}
+
+/* --Methode-- */
+void CxxExecutor::PutInclude(ofstream& os)
+{
+os<<"#include \"machdefs.h\""<<endl<<endl;
+
+os<<"//---- System et stdc++ include files"<<endl
+  <<"#include <stdio.h>"<<endl
+  <<"#include <stdlib.h>"<<endl
+  <<"#include <math.h>"<<endl
+  <<"#include <ctype.h>"<<endl
+  <<"#include <string.h>"<<endl
+  <<"#include <iostream.h>"<<endl
+  <<"#include <fstream.h>"<<endl
+  <<"#include <complex>"<<endl
+  <<endl
+
+  <<"#include <typeinfo>"<<endl
+  <<"#include <string>"<<endl
+  <<"#include <vector>"<<endl
+  <<"#include <map>"<<endl
+  <<"#include <functional>"<<endl
+  <<"#include <list>"<<endl
+  <<endl
+
+#ifdef SANS_EVOLPLANCK
+  <<"//---- Peida include files"<<endl
+  <<"#include \"toutpeida.h\""<<endl
+#else
+  <<"//---- Sophya include files"<<endl
+  <<"#include \"basetools.h\""<<endl
+  <<"#include \"systools.h\""<<endl
+  <<"#include \"sutils.h\""<<endl
+  <<"#include \"ntools.h\""<<endl
+  <<"#include \"array.h\""<<endl
+  <<"#include \"histats.h\""<<endl
+  <<endl
+#endif
+
+  <<"//---- Spiapp include files"<<endl
+  <<"#include \"nobjmgr.h\""<<endl
+  <<"#include \"servnobjm.h\""<<endl
+  <<endl;
+
+os<<"//---- Include files from additionnal modules"<<endl;
+if(mIncImportList.size()>0)
+  for(uint_4 i=0;i<mIncImportList.size();i++)
+    os<<"#include \""<<mIncImportList[i]<<"\""<<endl;
+os<<endl;
+
+os<<"//---- function to compare bits on double \n"
+  <<"int_8 BitCmp64(double v,int_8 flg) \n"
+  <<"{return ((int_8)((v<0.) ? v-0.1 : v+0.1))&flg;} \n"
+  <<endl;
+
+os<<"//---- function for Adding and displaying Objects  " << endl;
+os<<"void Keep_Object(AnyDataObj & obj, string const & nom) \n{ \n" 
+  <<"  string name = nom; \n  NamedObjMgr om; \n"
+  <<"  if (om.GetObj(name)) \n" 
+  <<"    cerr << \"KeepObj()/Warning Already kept object \" << endl; \n"
+  <<"  else om.AddObj(obj, name); \n"
+  <<"} \n" << endl;
+os<<"void Display_Object(AnyDataObj & obj, string const & opt, string const & nom) \n { \n" 
+  <<"  string name = nom; \n  NamedObjMgr om; \n"
+  <<"  if (!om.GetObj(name)) \n" 
+  <<"    om.AddObj(obj, name); \n"
+  <<"  om.DisplayObj(name, opt); \n"
+  <<"} \n" << endl;
+os<<"//---- function for getting and setting ObjectManager variables  " << endl;
+os<<"void Set_ObjMgrVar(MuTyV v, string const & nom) \n{ \n" 
+  <<"  NamedObjMgr om; \n"
+  <<"  om.SetVar(nom, (string)v); \n"
+  <<"} \n" << endl;
+os<<"MuTyV Get_ObjMgrVar(const char * nom) \n{ \n" 
+  <<"  string name = nom; NamedObjMgr om; \n"
+  <<"  MuTyV v = om.GetVar(name); \n"
+  <<"  return v; \n"
+  <<"} \n" << endl;
+
+os<<"//---- Macro for Objects and variables saving"<<endl
+  <<"#define KeepObj(obj) Keep_Object(obj, #obj)"<<endl
+  <<"#define GetOMVar(var) Get_ObjMgrVar( #var )"<<endl
+  <<"#define SetOMVar(var) Set_ObjMgrVar(var, #var )"<<endl
+  <<endl;
+
+os<<"//---- Macro Displaying objects and command execution"<<endl;
+os<<"#define DisplayObj(obj, att) Display_Object(obj, att, #obj); \n" << endl;
+os<<"#define ExecuteCommand(cmd) srvo.ExecuteCommand(cmd); \n" << endl;
+
+return;
+}
+
+/* --Methode-- */
+void CxxExecutor::PutIncludeUser(ofstream& os)
+{
+if(mIncList.size()<1) return;
+for(uint_4 i=0;i<mIncList.size();i++)
+  os<<"#include \""<<mIncList[i]<<"\""<<endl;
+}
+
+/* --Methode-- */
+void CxxExecutor::PutObject(ofstream& os)
+{
+NamedObjMgr omg;
+NObjMgrAdapter* objmgrad;
+vector<string> objlist;
+string patt = "*";
+omg.GetObjList(patt,objlist); 
+int nobjs = objlist.size();
+
+os<<"//-------------- Object List --------------"<<endl;
+os<<"//Number of objects = "<<nobjs<<endl;
+os<<"string ___nomobj;"<<endl<<endl;
+if(nobjs<=0) return;
+
+string dir,nobj,stmp,obtype;
+for(int i=0;i<nobjs;i++) {
+  objmgrad = omg.GetObjAdapter(objlist[i]);
+  omg.ParseObjectName(objlist[i],dir,nobj);
+  obtype = objmgrad->GetDataObjType();
+  stmp = "___" + nobj;
+
+  os<<"___nomobj = \""<<nobj<<"\";"<<endl;
+  os<<obtype<<"* "<<stmp
+    <<" = dynamic_cast< "<<obtype<<" * >(omg.GetObj(___nomobj));"<<endl;
+#ifdef SANS_EVOLPLANCK
+  os<<"if("<<stmp<<"==NULL) { \n"
+    <<" long mExcErr = nullPtrErr; \n"
+    <<" cerr << \"CxxExecutor::PutObject: Non existing object "
+    <<" ... please update file \\n \" ;"
+    <<" throw mExcErr ; \n } "<<endl;
+#else
+  os<<"if("<<stmp<<"==NULL) throw NullPtrError"
+    <<"(\"CxxExecutor::PutObject: Non existing object "<<nobj
+    <<"... please update file\");"<<endl;
+#endif
+  os<<obtype<<"& "<<nobj<<" = (*"<<stmp<<");"<<endl<<endl;
+}
+
+return;
+}
+
+/* --Methode-- */
+void CxxExecutor::PutVar(ofstream& os)
+{  
+os<<"//-------------- Variable List --------------"<<endl;
+NamedObjMgr omg;
+DVList& varlist = omg.GetVarList();
+// varlist.Show(); varlist.Print();  
+DVList::ValList::const_iterator it;
+for(it=varlist.Begin(); it!=varlist.End(); it++) {
+  string key = (*it).first;
+  if (isalpha(key[0]) ) {
+    os<<"___nomobj = \""<<key<<"\";"<<endl;
+    os<<"MuTyV & $"<<key<<" = omg.GetVarList().Get(___nomobj);"<<endl;
+  }
+}
+
+return;
+}
+
+/* --Methode-- */
+int CxxExecutor::FillUserCode(string& usercode,uint_4 first)
+// User code is read from input.
+// - first is the first position in the "string" where the code starts
+// - Code is put into file "TmpDir/cxx_spiapp.h".
+{
+mUserCodeFn = "";
+
+// get the string part which is after word "first"
+string code = usercode;
+if(code.size()<=0) {cout<<"CxxExecutor::FillUserCode: no user code"<<endl;
+                    return 1;}
+size_t q;
+for(uint_4 i=0;i<=first;i++) {
+  q = code.find_first_not_of(" \t");
+  if(q>=code.size()) {code=""; break;}
+  code = code.substr(q);
+  if(i==first) break;
+  q = code.find_first_of(" \t");
+  if(q>=code.size()) {code=""; break;}
+  code = code.substr(q);
+}
+if(code.size()<=0)
+  {cout<<"CxxExecutor::FillUserCode: no user code after "<<first<<endl;
+   return 1;}
+
+// Fill the file with user code
+mUserCodeFn = TmpDir() + mDefRoot + ".h";
+ofstream os(mUserCodeFn.c_str(),ios::out);
+if(!os) {cout<<"CxxExecutor::FillUserCode: unable to open "
+             <<mUserCodeFn<<endl;  mUserCodeFn = ""; return 1;}
+os<<code<<endl;
+if(mPrtLevel>1)
+  cout<<"User code filled from standard input into "<<mUserCodeFn<<endl;
+return 0;
+}
+
+/* --Methode-- */
+int CxxExecutor::FillUserFctFrS(string userfctcode)
+// - Fill user Fonction code from string "userfct"
+// - Code is put into file "TmpDir/cxx_spiapp_fct.h".
+{
+mUserFctFn  = "";
+if(userfctcode.size()<1) return 0;
+mUserFctFn  = TmpDir() + mDefRoot + "_fct.h";
+ofstream os(mUserFctFn.c_str(),ios::out);
+if(!os) {cout<<"CxxExecutor::FillUserFctFrS: unable to open "
+             <<mUserFctFn<<endl;  mUserFctFn = ""; return 1;}
+os<<userfctcode<<endl;
+if(mPrtLevel>1)
+  cout<<"User Function code filled from standard input into "<<mUserFctFn<<endl;
+return 0;
+}
+
+/* --Methode-- */
+int CxxExecutor::FillUserCode(string filename)
+// User code is read from "filename".
+{
+mUserCodeFn = filename;
+if(mPrtLevel>1 && mUserCodeFn.size()>0)
+  cout<<"User code filled from file "<<mUserCodeFn<<endl;
+return 0;
+}
+
+/* --Methode-- */
+int CxxExecutor::FillUserFctFrF(string filefctname)
+// User function code is read from "filefctname".
+{
+mUserFctFn = filefctname;
+if(mPrtLevel>1 && mUserFctFn.size()>0)
+  cout<<"User Function code filled from file "<<mUserFctFn<<endl;
+return 0;
+}
+
+/* --Methode-- */
+int CxxExecutor::Compile(string rootfilename)
+//--------------------------------------------------------//
+// rootfilename = | name           | "" ou (default)      //
+//--------------------------------------------------------//
+// fichier .cc    | name.cc        | TmpDir/cxx_spiapp.cc //
+//                | ../dir/name.cc |                      //
+// fichier .o     | TmpDir/name.o  | TmpDir/cxx_spiapp.o  //
+// fichier .so    | TmpDir/name.so | TmpDir/cxx_spiapp.so //
+//--------------------------------------------------------//
+{
+if(rootfilename.size()<1) rootfilename = TmpDir() + mDefRoot;
+if(mPrtLevel>1) cout<<"Compile "<<rootfilename<<endl;
+
+int rc;
+#ifdef SANS_EVOLPLANCK
+CxxCompilerLinker cxx;
+string sophlib = " -lPIE -lm ";
+cxx.AddLinkOptions(sophlib);
+#else
+CxxCompilerLinker cxx(true,true,true);
+#endif
+if(TmpDir().size()>0) cxx.SetTmpDir(TmpDir());
+if(mPrtLevel>0) cxx.SetVerbose(true);
+  else          cxx.SetVerbose(false);
+
+// Compilation
+string fcc = rootfilename + ".cc";
+string fo  = "";
+cxx.AddCompileOptions(mCompOpt);
+rc = cxx.Compile(fcc,fo);
+if(mPrtLevel>1) cout << "Compilation rc = "<<rc<< endl;
+if(rc) return 1;
+
+// Fabrication Shared Lib.
+string fso = "";
+cxx.AddLinkOptions(mLinkOpt);
+cxx.AddLinkOptions(mMyLibs);
+rc = cxx.BuildSO(fo,fso);
+if(mPrtLevel>1) cout << "Shared Library rc = "<<rc<< endl;
+if(rc) return 2;
+
+return 0;
+}
+
+/* --Methode-- */
+//int CxxExecutor::Compile(string rootfilename)
+// Ne marche pas si TmpDir != ""
+//{
+//if(rootfilename.size()<1) rootfilename = mDefRoot;
+//if(mPrtLevel>1) cout<<"Compile: "<<rootfilename<<endl;
+//int rc = 0;
+//rc = CrMakefile();
+//if(rc) return(1);
+//string make  = "";
+//make += "make -f " + mDefRoot + "_Makefile";
+//make += " CXXFLAGS=\"" + mCompOpt + "\"";
+//make += " LDFLAGS=\""  + mLinkOpt + "\"";
+//make += " MYLIBS=\""   + mMyLibs  + "\"";
+//make += " " + rootfilename;
+//rc = system(make.c_str());
+//if(rc)
+//  {cout<<"CxxExecutor::Compile : \n"<<make<<" Failed"<<endl;
+//   return 1000+rc;}
+//return 0;
+//}
+
+/* --Methode-- */
+//int CxxExecutor::CrMakefile(void)
+// Ne marche pas si TmpDir != ""
+//{
+//string makename = TmpDir() + mDefRoot + "_Makefile";
+//ofstream os(makename.c_str(),ios::out);
+//if(!os)
+//  {cout<<"CxxExecutor::CrMakefile: unable to open file for Makefile"<<endl;
+//   return 1;}
+//---------------------------------------------------------------------
+//os<<"MODULEDECCXXFLAGS := -msg_quiet"<<endl;
+//os<<"include $(DPCBASEREP)/Include/MakefileUser.h"<<endl;
+//os<<"MYLIBS ="<<endl;
+//os<<"LIBS = -L$(SLB) -lPI -lextsophya -lsophya -lm"<<endl;
+//os<<"ifeq ($(MACHEROS),OSF1)"<<endl;
+//os<<"LIBS := $(LIBS) -lfor"<<endl;
+//os<<"endif"<<endl;
+//os<<"ifeq ($(MACHEROS),Linux)"<<endl;
+//os<<"#LIBS := $(LIBS) -ldl -lf2c"<<endl;
+//os<<"LIBS := $(LIBS) -ldl -lg2c"<<endl;
+//os<<"endif"<<endl;
+//os<<"%.so:%.o"<<endl;
+//os<<"%:%.cc"<<endl;
+//os<<"%:%.o"<<endl;
+//os<<"%.o:%.cc"<<endl;
+//os<<"%.o:%.c"<<endl;
+//os<<"%:%.c"<<endl;
+//os<<endl;
+//os<<".PRECIOUS: %.so"<<endl;
+//os<<endl;
+//os<<"%:%.so"<<endl;
+//os<<"\t"<<"echo $@ \" made (.so) \""<<endl;
+//os<<"%.so:%.o"<<endl;
+//os<<"\t"<<"$(LINK.cc) -shared -o $@ $< $(LIBS) $(MYLIBS)"<<endl;
+//os<<"%.o:%.cc"<<endl;
+//os<<"\t"<<"$(COMPILE.cc) -o $@ $<"<<endl;
+//os<<"%.o:%.c"<<endl;
+//os<<"\t"<<"$(COMPILE.c) -c $(CFLAGS) $(USERFLAGS) -o $@ $<"<<endl;
+//---------------------------------------------------------------------
+//return 0;
+//}
+
+/* --Methode-- */
+int CxxExecutor::Link(string libname,string func)
+{
+if(libname.size()<1) libname = TmpDir() + mDefRoot + ".so";
+  else               libname = TmpDir() + libname;
+if(func.size()<1) func = mDefFunc;
+
+NamedObjMgr omg;
+PIACmd* mpiac = omg.GetImgApp()->CmdInterpreter();
+
+string key("linkff2");
+vector<string> arg; arg.push_back(libname); arg.push_back(func);
+string toks = libname + " " + func;
+int rc = mpiac->ExecuteCommand(key,arg,toks);
+if(mPrtLevel>1) cout<<"Link from "<<libname<<" for function "<<func
+                  <<" (rc="<<rc<<")"<<endl;
+return 0;
+}
+
+/* --Methode-- */
+int CxxExecutor::Call(string func)
+{
+if(func.size()<1) func = mDefFunc;
+
+NamedObjMgr omg;
+PIACmd* mpiac = omg.GetImgApp()->CmdInterpreter();
+
+string key("call");
+vector<string> arg; arg.push_back(func);
+string toks = func;
+if(mCallArgs.size()>0)
+  for(uint_4 i=0;i<mCallArgs.size();i++) arg.push_back(mCallArgs[i]);
+mpiac->ExecuteCommand(key,arg,toks);
+return 0;
+}
+
+/* --Methode-- */
+void CxxExecutor::FillArgs(vector<string>& args)
+{
+mCallArgs.resize(0);
+if(args.size()<1) return;
+for(uint_4 i=0;i<args.size();i++) mCallArgs.push_back(args[i]);
+}
+
+void CxxExecutor::FillArgs(string& args)
+{
+mCallArgs.resize(0);
+FillVStringFrString(args,mCallArgs,' ');
+}
+
+string CxxExecutor::GetArgs(void)
+{
+string dum = "";
+if(mCallArgs.size()<1) return dum;
+for(uint_4 i=0;i<mCallArgs.size();i++) dum += mCallArgs[i] + " ";
+return dum;
+}
+
+/* --Methode-- */
+void CxxExecutor::FillInclude(vector<string>& inc)
+{
+mIncList.resize(0);
+if(inc.size()<1) return;
+for(uint_4 i=0;i<inc.size();i++) mIncList.push_back(inc[i]);
+}
+
+void CxxExecutor::FillInclude(string& inc)
+{
+mIncList.resize(0);
+FillVStringFrString(inc,mIncList,' ');
+}
+
+string CxxExecutor::GetInclude(void)
+{
+string dum = "";
+if(mIncList.size()<1) return dum;
+for(uint_4 i=0;i<mIncList.size();i++) dum += mIncList[i] + " ";
+return dum;
+}
+
+/* --Methode-- */
+void CxxExecutor::FillCompileOpt(vector<string>& copt)
+{
+mCompOpt = "";
+if(copt.size()<1) return;
+for(uint_4 i=0;i<copt.size();i++) mCompOpt += copt[i] + " ";
+}
+
+void CxxExecutor::FillCompileOpt(string& copt)
+{
+mCompOpt = copt;
+}
+
+string CxxExecutor::GetCompileOpt(void)
+{
+return mCompOpt;
+}
+
+/* --Methode-- */
+void CxxExecutor::FillLinkOpt(vector<string>& lopt)
+{
+mLinkOpt = "";
+if(lopt.size()<1) return;
+for(uint_4 i=0;i<lopt.size();i++) mLinkOpt += lopt[i] + " ";
+}
+
+void CxxExecutor::FillLinkOpt(string& lopt)
+{
+mLinkOpt = lopt;
+}
+
+string CxxExecutor::GetLinkOpt(void)
+{
+return mLinkOpt;
+}
+
+/* --Methode-- */
+void CxxExecutor::FillLinkLibs(vector<string>& llibs)
+{
+mMyLibs = "";
+if(llibs.size()<1) return;
+for(uint_4 i=0;i<llibs.size();i++) mMyLibs += llibs[i] + " ";
+}
+
+void CxxExecutor::FillLinkLibs(string& llibs)
+{
+mMyLibs = llibs;
+}
+
+string CxxExecutor::GetLinkLibs(void)
+{
+return mMyLibs;
+}
+
+/* --Methode-- */
+void CxxExecutor::FillModuleImport(vector<string>& import)
+{
+mModuleImportList.resize(0);
+mIncImportList.resize(0);
+if(import.size()<1) return;
+
+if(import[0]=="all" || import[0]=="All" || import[0]=="ALL") {
+  mModuleImportList = mModuleImportDefaultList;
+} else {
+  for(uint_4 i=0;i<import.size();i++) mModuleImportList.push_back(import[i]);
+}
+
+// Set additionnal Includes
+if(mModuleImportList.size()>0)
+  for(uint_4 i=0;i<mModuleImportList.size();i++) {
+    if(     mModuleImportList[i]=="FitsIOServer")
+      mIncImportList.push_back("fitsioserver.h");
+    else if(mModuleImportList[i]=="IFFTW")
+      mIncImportList.push_back("fftwserver.h");
+    else if(mModuleImportList[i]=="LinAlg")
+      mIncImportList.push_back("intflapack.h");
+    else if(     mModuleImportList[i]=="Samba")
+      {mIncImportList.push_back("skymap.h"); mIncImportList.push_back("samba.h");}
+    else if(mModuleImportList[i]=="SkyMap")
+      mIncImportList.push_back("skymap.h");
+    else if(mModuleImportList[i]=="SkyT")
+      mIncImportList.push_back("skyt.h");
+    else if(mModuleImportList[i]=="XAstroPack")
+      mIncImportList.push_back("xastropack.h");
+}
+
+return;
+}
+
+void CxxExecutor::FillModuleImport(string& import)
+{
+mModuleImportList.resize(0);
+vector<string> vsimport;
+FillVStringFrString(import,vsimport,' ');
+FillModuleImport(vsimport);
+}
+
+string CxxExecutor::GetModuleImport(void)
+{
+string dum = "";
+if(mModuleImportList.size()<1) return dum;
+for(uint_4 i=0;i<mModuleImportList.size();i++) dum += mModuleImportList[i] + " ";
+return dum;
+}
Index: /tags/V_Dec2002/SophyaPI/PIext/cxxexecutor.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/cxxexecutor.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/cxxexecutor.h	(revision 2309)
@@ -0,0 +1,100 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe CxxExecutor  : Dynamic C++ compile/execution in piapp
+// (c) DAPNIA (CEA)                 LAL (IN2P3/CNRS)
+//                           C. Magneville  10/2000
+
+#ifndef CXXEXECUTOR_H_SEEN
+#define CXXEXECUTOR_H_SEEN
+
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream.h>
+
+#include <vector>
+#include <string>
+
+#include "piacmd.h"
+#include "nobjmgr.h"
+
+class CxxExecutor : public CmdExecutor {
+public:
+           CxxExecutor(PIACmd* piac, PIStdImgApp* app);
+  virtual ~CxxExecutor();
+
+  virtual int Execute(string& keyw,vector<string>& args, string& toks);
+
+  inline void SetPrtLevel(uint_2 lp=2) {mPrtLevel = lp;}
+
+  int  ExecuteCXX(string usercode,string userfct="");
+
+  // if true , declare ObjMgr variables as $varname 
+  inline void DeclareObjMgrVar(bool fg=false) { mFgPutVar=fg; }
+
+  int  CrFile(string cfilename="",string func="");
+       void PutInclude(ofstream& os);
+       void PutIncludeUser(ofstream& os);
+       void PutObject(ofstream& os);
+       void PutVar(ofstream& os);
+
+  int  FillUserCode(string& usercode,uint_4 first);
+  int  FillUserCode(string filename);
+
+  int  FillUserFctFrS(string userfctcode="");
+  int  FillUserFctFrF(string filefctname="");
+
+  int  Compile(string rootfilename="");
+  /* int CrMakefile(void); */
+
+  int  Link(string libname="",string func="");
+  int  Call(string func="");
+
+  void   FillArgs(vector<string>& args);
+  void   FillArgs(string& args);
+  string GetArgs(void);
+
+  void   FillInclude(vector<string>& inc);
+  void   FillInclude(string& inc);
+  string GetInclude(void);
+
+  void   FillCompileOpt(vector<string>& copt);
+  void   FillCompileOpt(string& copt);
+  string GetCompileOpt(void);
+
+  void   FillLinkOpt(vector<string>& lopt);
+  void   FillLinkOpt(string& lopt);
+  string GetLinkOpt(void);
+
+  void   FillLinkLibs(vector<string>& llibs);
+  void   FillLinkLibs(string& llibs);
+  string GetLinkLibs(void);
+
+  void FillModuleImport(vector<string>& import);
+  void FillModuleImport(string& import);
+  string GetModuleImport(void);
+
+private:
+  string mUserCodeFn;
+  string mUserFctFn;
+  string mCompOpt;
+  string mLinkOpt;
+  string mMyLibs;
+  vector<string> mIncList;
+  vector<string> mCallArgs;
+
+  // Import des modules
+  vector<string> mIncImportList;
+  vector<string> mModuleImportList;
+  vector<string> mModuleImportDefaultList;
+
+
+  //  string mDefTmp; remplace par la methode TmpDir() - Reza 4/9/02
+  inline string const& TmpDir() { NamedObjMgr omg; return omg.GetTmpDir(); }
+  string mDefRoot;
+  string mDefFunc;
+
+  uint_2 mPrtLevel;
+  bool   mFgPutVar;  // if true , declare ObjMgr variables as $varname, default=false
+};
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/cxxexecwin.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/cxxexecwin.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/cxxexecwin.cc	(revision 2309)
@@ -0,0 +1,411 @@
+// Classe CxxExecWindow : Control Window for CxxExecutor
+// Classe CxxExecOptWindow : Option Window for CxxExecutor
+// (c) DAPNIA (CEA)                 LAL (IN2P3/CNRS)
+//                           R. Ansari  C.Magneville 10/2000
+
+#include "cxxexecutor.h"
+#include "cxxexecwin.h"
+
+// --------------------------------------------------------------------
+// --------------------------------------------------------------------
+// ------------- Fenetre dde commande pour le CxxExecutor -------------
+// --------------------------------------------------------------------
+// --------------------------------------------------------------------
+
+/* --Methode-- */
+CxxExecWind::CxxExecWind(PIStdImgApp* par, CxxExecutor * cxxexec)
+: PIWindow((PIMsgHandler *)par, "CxxExecutor", PIWK_normal, 400, 300, 150, 150)
+{
+  dap = par;
+  cxxex = cxxexec;
+  mFName[0] = "";
+  mFName[1] = "";
+
+  int bsx, bsy, szx, szy;
+  int px, py, spx, spy;
+  int xtext, ytext;
+
+  ////////////////////////////////////
+  //       Window Definition        //
+  ////////////////////////////////////
+
+  // On definit la taille a partir de la taille par defaut des composantes 
+  PIApplicationPrefCompSize(bsx, bsy);
+  // On redefinit la taille de la fenetre
+  spx = bsx/6;
+  spy = bsy/6;
+  xtext = 8*bsx;
+  ytext = 8*bsy;
+  szx = xtext+2*spx;   
+  szy = 2*ytext+5*bsy+10*spy;
+  SetSize(szx, szy);
+
+  ////////////////////////////////////
+  //       User Function Code       //
+  ////////////////////////////////////
+
+// Creation du champ texte 
+  px = spx;
+  py = spy;
+  mText[0] = new PIText(this,"helptext",true,true,xtext,0.75*ytext,px,py);
+  mText[0]->SetTextEditable(true);
+  mText[0]->SetText("");
+
+// Creation du champ titre, des boutons d'action et label fichier
+  px = spx;
+  py += (int)(spy+0.75*ytext);
+  mLab[3] = new PILabel(this,"FileFunc",xtext,bsy,px,py);
+  mLab[3]->SetLabel("");
+  mLab[3]->SetBorderWidth(1);
+  px = spx;
+  py += spy+bsy;
+  mLab[0] = new PILabel(this,"Function",2*bsx,bsy,px,py);
+  mLab[0]->SetLabel("User Function Code");
+  mLab[0]->SetBorderWidth(1);
+  px += spx+2*bsx;
+  mBut[0] = new PIButton(this,"Open",500,bsx,bsy,px,py);
+  px += bsx+spx;
+  mBut[1] = new PIButton(this,"Save",510,bsx,bsy,px,py);
+  px += bsx+spx;
+  mBut[2] = new PIButton(this,"Save As",520,bsx,bsy,px,py);
+  px += bsx+spx;
+  mBut[3] = new PIButton(this,"Reset Name",530,1.5*bsx,bsy,px,py);
+
+  ////////////////////////////////////
+  //           User Code            //
+  ////////////////////////////////////
+
+// Creation du champ texte 
+  px = spx;
+  py += 2*spy+bsy;
+  mText[1] = new PIText(this,"helptext",true,true,xtext,1.25*ytext,px,py);
+  mText[1]->SetTextEditable(true);
+  mText[1]->SetText("");
+
+// Creation du champ titre, des boutons d'action et label fichier
+  px = spx;
+  py += (int)(spy+1.25*ytext);
+  mLab[4] = new PILabel(this,"FileCode",xtext,bsy,px,py);
+  mLab[4]->SetLabel("");
+  mLab[4]->SetBorderWidth(1);
+  px = spx;
+  py += spy+bsy;
+  mLab[1] = new PILabel(this,"Code",2*bsx,bsy,px,py);
+  mLab[1]->SetLabel("User Code");
+  mLab[1]->SetBorderWidth(1);
+  px += spx+2*bsx;
+  mBut[4] = new PIButton(this,"Open",501,bsx,bsy,px,py);
+  px += bsx+spx;
+  mBut[5] = new PIButton(this,"Save",511,bsx,bsy,px,py);
+  px += bsx+spx;
+  mBut[6] = new PIButton(this,"Save As",521,bsx,bsy,px,py);
+  px += bsx+spx;
+  mBut[7] = new PIButton(this,"Reset Name",531,1.5*bsx,bsy,px,py);
+
+  ////////////////////////////////////
+  //     Buttons for execution      //
+  ////////////////////////////////////
+
+// Creation du champ titre pour le code
+  px = spx;
+  py += 2*spy+bsy;
+  mLab[2] = new PILabel(this, "Execute",2*bsx,bsy,px,py);
+  mLab[2]->SetLabel("Execute :");
+  mLab[2]->SetBorderWidth(1);
+
+// Creation des boutons d'action 
+  px += (int)(szx/2 - 1.2*bsx - spx);
+  mBut[8] = new PIButton(this,"Exec",600,1.2*bsx,bsy,px,py);
+  px += (int)(1.2*bsx+spx);
+  mBut[9] = new PIButton(this,"Dismiss",601,1.2*bsx,bsy,px,py);
+
+  ////////////////////////////////////
+  //  Set Attributes for Elements   //
+  ////////////////////////////////////
+
+  int ii;
+  for(ii=0; ii<5; ii++) 
+    mLab[ii]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+  for(ii=0; ii<10; ii++) 
+    mBut[ii]->SetBinding(PIBK_elastic , PIBK_elastic , PIBK_elastic , PIBK_elastic);
+  for(ii=0; ii<2; ii++) 
+    mText[ii]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+  // File Chooser
+  pfc = new PIFileChooser(this,"CxxExec-FileChooser", 5000); 
+}
+
+/* --Methode-- */
+CxxExecWind::~CxxExecWind()
+{
+  int i;
+  for(i=0; i<5; i++)  delete mLab[i];
+  for(i=0; i<10; i++) delete mBut[i];
+  for(i=0; i<2; i++)  delete mText[i];
+  delete pfc;
+}
+
+/* --Methode-- */
+void CxxExecWind::Show()
+{
+mLab[3]->SetLabel(mFName[0]);
+mLab[4]->SetLabel(mFName[1]);
+PIWindow::Show();
+}
+
+/* --Methode-- */
+void CxxExecWind::Process(PIMessage msg, PIMsgHandler* /*sender*/, void* data)
+{
+  msg = UserMsg(msg);
+  switch (msg)  {
+    case 600:    // Bouton Execute C++
+      SetUnSensitive();
+      dap->GetConsole()->AddStr(
+	 "CxxExecWind::Process() - Executing C++ Code ... \n", PIVA_Magenta);
+      dap->SetBusy();
+      cxxex->ExecuteCXX(mText[1]->GetText(),mText[0]->GetText());
+      dap->GetConsole()->AddStr(
+	 "CxxExecWind ... End of Executing C++ Code \n");
+      SetSensitive();
+      dap->SetReady();
+      break;
+    case 601:   // Bouton Dismiss - On cache la fenetre
+      this->Hide();
+      break;
+    case 500:    // Open File for Function
+    case 501:    // Open File for Code
+      {
+      int i = msg-500;
+      pfc->AcceptNewFile(false); 
+      pfc->SetMsg(5500+i);
+      dap->SetBlocked();
+      pfc->Show();
+      break;
+      }
+    case 5500:  // Return from open-file dialog for Function
+    case 5501:  // Return from open-file dialog for Code
+      {
+      int i = msg-5500;
+      dap->SetBusy();
+      if(data) {
+	mFName[i] = pfc->GetFileName();
+	mLab[3+i]->SetLabel(mFName[i]);
+        string code = stringfrfile(mFName[i]);
+	mText[i]->SetText(code);
+      }
+      dap->SetReady();
+      break;
+      }
+    case 510:  // Save for Function
+    case 511:  // Save for Code
+    case 520:  // Save-File for Function
+    case 521:  // Save-File for Code
+      {
+      int i = msg%10;
+      if( msg<515 && mFName[i].length()>0 ) {
+        string code = mText[i]->GetText();
+        filefrstring(mFName[i],code);
+      } else {
+	pfc->AcceptNewFile(true); 
+	pfc->SetMsg(5520+i);
+	dap->SetBlocked();
+	pfc->Show();	
+      }
+      break;
+      }
+    case 5520:  // Return from Save-file dialog for Function
+    case 5521:  // Return from Save-file dialog for Code
+      {
+      int i = msg-5520;
+      dap->SetBusy();
+      if (data) {
+	mFName[i] = pfc->GetFileName();
+	mLab[3+i]->SetLabel(mFName[i]);
+        string code = mText[i]->GetText();
+        filefrstring(mFName[i],code);
+      }
+      dap->SetReady();
+      break;
+      }
+    case 530:  // Reset name for Function
+    case 531:  // Reset name for Code
+      {
+      int i = msg-530;
+      mFName[i] = "";
+      mLab[3+i]->SetLabel(mFName[i]);
+      }
+  }
+
+  // In case of compile errors, we end-up here !    
+  mBut[8]->SetSensitive();
+  dap->SetReady();
+  return;
+}
+
+/* --Methode-- */
+void CxxExecWind::filefrstring(string filename,string& code)
+{
+if(filename.size()<1) return;
+if(code.size()<1) return;
+ofstream os(filename.c_str(),ios::out);
+if(!os)
+  {cout<<"CxxExecWind::filefrstring: unable to open "<<filename<<endl;
+   return;}
+os<<code<<endl;
+}
+
+/* --Methode-- */
+string CxxExecWind::stringfrfile(string filename)
+{
+string code = "";
+if(filename.size()<1) return code;
+ifstream is(filename.c_str(),ios::in);
+if(!is)
+  {cout<<"CxxExecWind::stringfrfile: unable to open "<<filename<<endl;
+   return code;}
+char c;
+while(is.get(c)) code += c;
+return code;
+}
+
+// --------------------------------------------------------------------
+// --------------------------------------------------------------------
+// --------------- Fenetre d'option pour le CxxExecutor ---------------
+// --------------------------------------------------------------------
+// --------------------------------------------------------------------
+
+/* --Methode-- */
+CxxOptionWind::CxxOptionWind(PIStdImgApp* par, CxxExecutor * cxxexec)
+: PIWindow((PIMsgHandler *)par, "CxxOption", PIWK_normal, 400, 300, 150, 150)
+{
+
+  dap = par;
+  cxxex = cxxexec;
+
+  int bsx, bsy, szx, szy;
+  int px, py, spx, spy;
+  int xtext;
+  // On definit la taille a partir de la taille par defaut des composantes 
+  PIApplicationPrefCompSize(bsx, bsy);
+  // On redefinit la taille de la fenetre
+  spx = bsx/12; if(spx<2) spx=2;
+  spy = bsy/6;
+  xtext = 7*bsx;
+  szx = (int)(xtext+1.5*bsx+3*spx);
+  szy = 7*bsy+8*spy;
+  SetSize(szx, szy);
+
+// Creation de champs "labels"
+  px = (szx-xtext)/2;
+  py = spy;
+  mTit = new PILabel(this,"CxxExecutor Options",xtext,bsy,px,py);
+  mTit->SetBorderWidth(1);
+
+// Creation des labels et des champs texte
+  px = spx;
+  py += spy+bsy;
+  mLab[0] = new PILabel(this,"Include Files",1.5*bsx,bsy,px,py);
+  px += (int)(1.5*bsx+spx);
+  mText[0] = new PIText(this,"IncFiles",xtext,bsy,px,py);
+  mText[0]->SetText("");
+
+  px = spx;
+  py += spy+bsy;
+  mLab[1] = new PILabel(this,"Compile Opt.",1.5*bsx,bsy,px,py);
+  px += (int)(1.5*bsx+spx);
+  mText[1] = new PIText(this,"CompOpt",xtext,bsy,px,py);
+  mText[1]->SetText("");
+
+  px = spx;
+  py += spy+bsy;
+  mLab[2] = new PILabel(this,"Link Options",1.5*bsx,bsy,px,py);
+  px += (int)(1.5*bsx+spx);
+  mText[2] = new PIText(this,"LinkOpt",xtext,bsy,px,py);
+  mText[2]->SetText("");
+
+  px = spx;
+  py += spy+bsy;
+  mLab[3] = new PILabel(this,"Libraries",1.5*bsx,bsy,px,py);
+  px += (int)(1.5*bsx+spx);
+  mText[3] = new PIText(this,"LinkLib",xtext,bsy,px,py);
+  mText[3]->SetText("");
+
+  px = spx;
+  py += spy+bsy;
+  mLab[4] = new PILabel(this,"Modules",1.5*bsx,bsy,px,py);
+  px += (int)(1.5*bsx+spx);
+  mText[4] = new PIText(this,"ModImp",xtext,bsy,px,py);
+  mText[4]->SetText("");
+
+// Creation de bouton d'action 
+
+  px = (int)(szx/2 - 1.5*bsx - spx - 1.5*bsx/2.);
+  py += spy+bsy;
+  mBut[0] = new PIButton(this,"Set Options",500,1.5*bsx,bsy,px,py);
+  px += (int)(1.5*bsx+spx);
+  mBut[1] = new PIButton(this,"Get Options",600,1.5*bsx,bsy,px,py);
+  px += (int)(1.5*bsx+spx);
+  mBut[2] = new PIButton(this,"Dismiss",700,1.5*bsx, bsy,px,py);
+
+//  Taille et position proportionnelles a la taille de la fenetre pour les elements
+  mTit->SetBinding(PIBK_elastic , PIBK_elastic , PIBK_elastic , PIBK_elastic);
+  int i;
+  for(i=0; i<4; i++)
+    mLab[i]->SetBinding(PIBK_elastic , PIBK_elastic , PIBK_elastic , PIBK_elastic);
+  for(i=0; i<4; i++)
+    mText[i]->SetBinding(PIBK_elastic , PIBK_elastic , PIBK_elastic , PIBK_elastic);
+  for(i=0; i<3; i++) 
+    mBut[i]->SetBinding(PIBK_elastic , PIBK_elastic , PIBK_elastic , PIBK_elastic);
+}
+
+/* --Methode-- */
+CxxOptionWind::~CxxOptionWind()
+{
+  delete mTit;
+  int i;
+  for(i=0; i<5; i++) delete mLab[i];
+  for(i=0; i<3; i++) delete mBut[i];
+  for(i=0; i<5; i++) delete mText[i];
+}
+
+/* --Methode-- */
+void CxxOptionWind::Show()
+{
+  mText[0]->SetText(cxxex->GetInclude());
+  mText[1]->SetText(cxxex->GetCompileOpt());
+  mText[2]->SetText(cxxex->GetLinkOpt());
+  mText[3]->SetText(cxxex->GetLinkLibs());
+  mText[4]->SetText(cxxex->GetModuleImport());
+  PIWindow::Show();
+}
+
+/* --Methode-- */
+void CxxOptionWind::Process(PIMessage msg, PIMsgHandler* /*sender*/, void* /*data*/)
+{
+  string opt;
+  switch (UserMsg(msg))  {
+    case 500:    // Bouton Set Options
+      opt = mText[0]->GetText();
+      cxxex->FillInclude(opt);
+      opt = mText[1]->GetText();
+      cxxex->FillCompileOpt(opt);
+      opt = mText[2]->GetText();
+      cxxex->FillLinkOpt(opt);
+      opt = mText[3]->GetText();
+      cxxex->FillLinkLibs(opt);
+      opt = mText[4]->GetText();
+      cxxex->FillModuleImport(opt);
+      break;
+    case 600:    // Bouton Get Options
+      mText[0]->SetText(cxxex->GetInclude());
+      mText[1]->SetText(cxxex->GetCompileOpt());
+      mText[2]->SetText(cxxex->GetLinkOpt());
+      mText[3]->SetText(cxxex->GetLinkLibs());
+      mText[4]->SetText(cxxex->GetModuleImport());
+      break;
+    case 700:   // Bouton Dismiss - On cache la fenetre
+      this->Hide();
+      break;
+  }
+return;
+}
Index: /tags/V_Dec2002/SophyaPI/PIext/cxxexecwin.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/cxxexecwin.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/cxxexecwin.h	(revision 2309)
@@ -0,0 +1,62 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe CxxExecWind : Control Window for CxxExecutor
+// Classe CxxOptionWind : Option Window for CxxExecutor
+// (c) DAPNIA (CEA)                 LAL (IN2P3/CNRS)
+//                           R. Ansari  C.Magneville 10/2000
+
+#ifndef CXXEXECWIN_H_SEEN
+#define CXXEXECWIN_H_SEEN
+
+#include "machdefs.h"
+
+#include "pisysdep.h"
+#include "pistdimgapp.h"
+
+#include PISTDWDG_H 
+#include PIWIN_H
+
+class CxxExecutor;
+
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+class CxxExecWind : public PIWindow {
+public :
+                CxxExecWind(PIStdImgApp* par, CxxExecutor * cxxexec);
+                ~CxxExecWind();
+  virtual void  Show();
+  virtual void  Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+
+private:
+  virtual void filefrstring(string filename,string& code);
+  virtual string stringfrfile(string filename);
+  PIStdImgApp* dap;
+  CxxExecutor* cxxex;
+  PILabel  * mLab[5];
+  PIButton * mBut[10];
+  PIText   * mText[4];
+  PIFileChooser * pfc;   // Pour les fichiers user C++
+  string mFName[2];
+};
+
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+class CxxOptionWind : public PIWindow {
+public :
+                CxxOptionWind(PIStdImgApp* par, CxxExecutor * cxxexec);
+                ~CxxOptionWind();
+  virtual void  Show();
+  virtual void  Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+
+private:
+  PIStdImgApp * dap;
+  CxxExecutor * cxxex;
+  PILabel  * mTit;
+  PILabel  * mLab[5];
+  PIButton * mBut[3];
+  PIText   * mText[5];
+};
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/dlftypes.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/dlftypes.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/dlftypes.h	(revision 2309)
@@ -0,0 +1,30 @@
+// This may look like C code, but it is really -*- C++ -*-
+// typedef pour link dynamique de piapp  
+// Reza                     Juillet,Aout 98
+// LAL-IN2P3/CNRS
+
+#ifndef DLFTPES_H_SEEN
+#define DLFTYPES_H_SEEN
+
+#include "machdefs.h"
+#include <string>
+#include <vector>
+
+// ------------ Fonctions pour trace de fonctions --------------
+typedef double (* DlFunctionOfX) (double x);
+typedef double (* DlFunctionOfXY) (double x, double y);
+// ---- Fonctions pour trace d'expressions d'objets ------------
+typedef int (* PlotExprFunc) (double* x, double* rx, double* ry, double* rz, double* rt);
+typedef int (* NTLoopExprFunc) (double* x, double* rx, double* ry, double* rz, 
+                                double* rt, int n, int nmax);
+
+// ---------- Fonctions UserFit ----------------
+typedef double (* DlUserFitFunc)(double const*, double const*);
+typedef double (* DlUserFitFuncDer)(double const*, double const*, double*);
+
+// ---------- Fonctions User et gestion de modules chargeables ----
+typedef void (* DlUserProcFunction) (vector<string>& args);
+typedef void (* DlModuleInitEndFunction) ();
+
+#endif
+
Index: /tags/V_Dec2002/SophyaPI/PIext/exclude
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/exclude	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/exclude	(revision 2309)
@@ -0,0 +1,7 @@
+nomtarradapter.cc
+nomtmatvecadapter.cc
+nomskymapadapter.cc
+nomspecrespadapter.cc
+pitvmaad.cc
+modrecst.cc
+userfitfunex.c
Index: /tags/V_Dec2002/SophyaPI/PIext/exclude_dpc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/exclude_dpc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/exclude_dpc	(revision 2309)
@@ -0,0 +1,5 @@
+modrecst.cc
+userfitfunex.c
+nommatvecadapter.cc
+nomstladapter.cc
+pistlist.cc
Index: /tags/V_Dec2002/SophyaPI/PIext/flowmodex.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/flowmodex.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/flowmodex.cc	(revision 2309)
@@ -0,0 +1,154 @@
+#include "flowmodex.h"
+#include "pi2dvec.h"
+
+#include <typeinfo> 
+
+#include <vector>
+#include <string>
+#include "nobjmgr.h"
+#include "ntuple.h"
+
+#include "pidrawer.h"
+#include "nomgadapter.h"
+#include "servnobjm.h"
+
+
+/* --Methode-- */
+FlowModExecutor::FlowModExecutor(PIACmd* mpiac, PIStdImgApp* app)
+{
+
+
+  //cout << " FlowModExecutor::FlowModExecutor() mpiac = " << (unsigned long)mpiac << endl;
+  cout << " registration of flow chart commands "<<endl;
+  string hgrp,kw,usage;
+  hgrp = "Obj. Display";
+  
+  kw = "nt2dvec";
+  usage = "Creates and displays a flow chart from ntuple variables";
+  usage += "\n Usage: nt2dvec x y vx vy [graphic_att] ";
+  mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+
+  hgrp = "Expr. Plotting";
+  kw = "plot2dvec";
+  usage = "Creates and displays a flow chart from ntuple expressions ";
+  usage +=  "\n Usage: plot2dvec ntuple expx expy expvx expvy [cut graphic_att loop_par]"; 
+  
+  mpiac->RegisterCommand(kw, usage, this, hgrp);
+  
+  //cout << " Out of ContModExecutor::ContModExecutor() " << endl;
+
+}
+ 
+
+
+/* --Methode-- */
+FlowModExecutor::~FlowModExecutor()
+{
+}
+
+/* --Methode-- */
+int FlowModExecutor::Execute(string& kw, vector<string>& tokens, string& toks)
+{
+  
+int nz=-1;
+double z0,dz;
+PI2dVecDrawer *p2dv;
+string dopt="";
+NamedObjMgr omg;
+
+if ( kw == "nt2dvec") {
+   
+ 
+   if (tokens.size() < 5) {
+     cout << "Usage: nt2dvec ntuple x y vx vy [graphic_att]" << endl;
+     return(0);
+   }
+   NObjMgrAdapter* obja = omg.GetObjAdapter(tokens[0]);
+   if (obja == NULL) {
+     cout << "contour Error , No object with name " << tokens[0] << endl; 
+     return(0);
+   }
+     
+   if (tokens.size() > 5) dopt = tokens[5];
+   bool adel;
+
+   NTupleInterface *ntin = obja->GetNTupleInterface(adel);
+
+   p2dv = new PI2dVecDrawer(ntin,adel);
+   string expx,expy;
+   expx = tokens[1];
+   expy = tokens[2];
+   int ret = p2dv->SelectXY(expx.c_str(),expy.c_str());
+   if(ret<0){ cout << "Usage: nt2dvec ntuple x y vx vy [graphic_att]" << endl;  return(0);}
+   expx = tokens[3];
+   expy = tokens[4];
+   ret = p2dv->SelectVW(expx.c_str(),expy.c_str());
+   if(ret<0){ cout << "Usage: nt2dvec ntuple x y vx vy [graphic_att ]" << endl;  return(0);}
+
+   // On affiche le Drawer
+   int wrsid = 0;
+   string name = "ChampVec";
+   
+   wrsid = omg.GetImgApp()->DispScDrawer(p2dv , name, dopt); 
+   omg.AddWRsId(tokens[0], wrsid);
+
+}else if(kw == "plot2dvec"){
+
+  
+  if (tokens.size() < 5) {
+    cout << "Usage: plot2dvec ntuple expx expy expvx expvy [cut graphic_att loop_par]" << endl; 
+    return(0); 
+  }
+
+ 
+  NObjMgrAdapter* obja=NULL;
+  obja = omg.GetObjAdapter(tokens[0]);
+  if (obja == NULL) {
+    cout << "plot2dvec Error , No object with name " << tokens[0] << endl; 
+    return(0);
+  }
+
+  Services2NObjMgr* srvo = omg.GetServiceObj();
+
+  bool adel=true;
+  //NTupleInterface *ntin = obja->GetNTupleInterface(adel);
+  
+  // Creation NTuple 
+  char* ntn[4] = {"expx","expy","expex","expey"};
+  NTuple * ntint = NULL;
+  ntint = new NTuple(4,ntn);
+  // remplissage du ntuple 
+  string bidon = "0.";
+  string nocut = "1.";
+  if(tokens.size()>7) bidon = tokens[7];
+  if(tokens.size()>5) nocut = tokens[5];
+  
+
+  srvo->ComputeExpressions(obja,tokens[1],tokens[2],tokens[3],tokens[4],nocut,bidon,ntint,NULL,NULL);
+  
+  if(ntint->NEntry()<=0){
+    cerr << " FlowModExecutor::Execute plot2dvec <=0 evts selectionness "<<endl;
+    return(0);
+  }
+
+  cout << " avant creation de p2dv "<<endl;
+  p2dv = new PI2dVecDrawer(ntint,adel);
+  p2dv->SelectXY(ntn[0],ntn[1]);
+  p2dv->SelectVW(ntn[2],ntn[3]);
+
+  if (tokens.size() > 6) dopt = tokens[6];
+
+  string name = "ChampVec";
+   
+  int wrsid = omg.GetImgApp()->DispScDrawer(p2dv , name, dopt); 
+
+}
+ 
+
+return(0);
+
+}
+
+
+
Index: /tags/V_Dec2002/SophyaPI/PIext/flowmodex.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/flowmodex.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/flowmodex.h	(revision 2309)
@@ -0,0 +1,22 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe   : commands copntour drawing in Peida Interactive
+// (c) DAPNIA (CEA)                 LAL (IN2P3/CNRS)
+//                           R. Ansari O.Perdereau  11/2001
+//                           
+#ifndef FLOWMODEXE_H_SEEN
+#define FLOWMODEXE_H_SEEN
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream.h> 
+#include "piacmd.h"
+#include "nobjmgr.h"
+
+class FlowModExecutor : public CmdExecutor { 
+public:
+                FlowModExecutor(PIACmd* , PIStdImgApp* );
+  virtual       ~FlowModExecutor();
+  virtual int   Execute(string& keyw, vector<string>& args, string& toks);
+};
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/nobjmgr.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/nobjmgr.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/nobjmgr.cc	(revision 2309)
@@ -0,0 +1,1554 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include <typeinfo>
+#include <iostream.h>
+#include <string>
+#include <list>
+#include <map>
+
+#include "strutil.h"
+#include "datatypes.h"
+
+#include "nobjmgr.h"
+#include "servnobjm.h"
+#include "nomgadapter.h"
+#include "pistdimgapp.h"
+
+#include "dvlist.h"
+
+// EVOL-PLANCK
+#ifdef SANS_EVOLPLANCK
+#include "fitsimage.h"  
+#else
+#include "fitsautoreader.h"
+#include "tvector.h"
+#include "pitvmaad.h"
+#include "piyfxdrw.h"
+#endif
+
+#include "pisurfdr.h"
+#include "pipodrw.h"
+
+#include "pintuple.h"
+#include "pintup3d.h"
+#include "pigfd1.h"
+#include "pigfd2.h"
+
+
+//++
+// Class	NamedObjMgr
+// Lib		PI
+// include	nobjmgr.h
+//
+//	Cette classe fournit les services nécéssaires à la gestion des objets
+//	(l'ensemble des objets PPersist de PEIDA++) au sein du programme
+//	d'analyse interactive *piapp* . Elle constitue en outre l'interface
+//	entre les fonctions utilisateur et l'application graphique.
+//--
+//++
+// Links	Voir aussi
+// PIStdImgApp
+// Services2NObjMgr
+// PIACmd
+//--
+
+
+// ..................................................................
+// ......  Gestion des objets nommes, variables globales ............
+struct nobj_diritem {
+  int id;                 // Directory Id
+  int nobj;               // Number of objects in directory
+  bool lock;              // True -> directory locked, No Add, del or rename
+  bool keepold;           // True -> When duplicate object name, old object moved to /old
+};
+
+typedef map<string, nobj_diritem, less<string> > NObjDirList;
+
+struct nobj_item {
+  AnyDataObj* obj;             // Object pointer
+  NObjMgrAdapter* obja;        // Object adapter pointer
+  int oid;                     // object Id
+  int dirid;                   // Directory Id
+  list<int> wrsid;             // List of Window Resource Id (Drawer, PIBaseWdg, ...) 
+                               // (for PIStdImgApp)
+  bool operator==(nobj_item const& b) const
+    { return (this->obj ==  b.obj); }
+};
+
+typedef map<string, nobj_item, less<string> > NObjList;
+
+static NObjDirList* myDirs = NULL;
+static NObjList* myObjs = NULL;
+static int fgOInit = 0;
+static int myNObj = 0;
+static int myDirId = 0;
+static string* currDir;
+
+static PIStdImgApp* myImgApp=NULL;
+static Services2NObjMgr* servnobjm=NULL;
+
+static DVList* myVars = NULL;  // Pour stocker les variables
+
+static string* TmpDir;  // Repertoire pour les compilations / link dynamique
+
+// ..................................................................
+
+//++
+// Titre	Constructeurs
+//--
+//++
+// NamedObjMgr()
+//	Constructeur. Les différents instantiation de la classe "NamedObjMgr" 
+//	dans une même application créent des objets qui travaillent sur la même
+//	liste d'objets. Les objets de cette classe ne possedent en effet pas
+//	de variables membres. 
+//--
+
+/* --Methode-- */
+NamedObjMgr::NamedObjMgr()
+{
+if (fgOInit == 0) { 
+  myNObj = 0;
+  myDirId = 0;
+  myDirs = new NObjDirList;
+  myObjs = new NObjList;  
+  myVars = new DVList;
+  currDir = new string("home");
+  string dirn = "home";
+  CreateDir(dirn);
+  SetKeepOldDirAtt(dirn, false);
+  dirn = "tmp";
+  CreateDir(dirn);
+  SetKeepOldDirAtt(dirn, false);
+  dirn = "autoc";
+  CreateDir(dirn);
+  SetKeepOldDirAtt(dirn, false);
+  dirn = "old";
+  CreateDir(dirn);
+  SetKeepOldDirAtt(dirn, false);
+  dirn = "home";
+  SetCurrentDir(dirn);
+  myDirId = 50;
+  char* varenv;
+  TmpDir = new string("");
+  if ( (varenv=getenv("TMPDIR")) != NULL )  (*TmpDir) = varenv; 
+  int l = (*TmpDir).length();
+  if ( (l>0) && ((*TmpDir)[l-1] != '/') )  (*TmpDir) += '/';
+  servnobjm = new Services2NObjMgr(this, (*TmpDir));
+  }
+fgOInit++;
+}
+
+  
+/* --Methode-- */
+NamedObjMgr::~NamedObjMgr()
+{
+fgOInit--;
+if (fgOInit == 0)  {
+  string patt = "/*/*";
+  DelObjects(patt, true);
+  delete myObjs;
+  delete myDirs;
+  delete myVars;
+}
+}
+
+//++
+// Titre	Méthodes
+//--
+//++
+// void SetImgApp(PIStdImgApp* app)
+//	Spécifie l'objet "PIStdImgApp" associé.
+// PIStdImgApp* GetImgApp()
+//	Accès à l'objet "PIStdImgApp" associé.
+//--
+
+/* --Methode-- */
+void NamedObjMgr::SetImgApp(PIStdImgApp* app)
+{
+myImgApp = app;
+servnobjm->SetImgApp(app);
+
+NObjDirList::iterator it;
+string cn;
+for(it= myDirs->begin(); it != myDirs->end(); it++) {
+  cn = '/' + (*it).first;
+  (myImgApp->ObjMgrW())->AddDirectory(cn.c_str(), (*it).second.id);
+  }
+}
+
+
+static bool verbeux = false;  // true -> plus de message (creation/suppression d'objets)
+void NamedObjMgr::SetVerbose(bool fg)
+{
+verbeux = fg;
+}
+
+/* --Methode-- */
+PIStdImgApp* NamedObjMgr::GetImgApp()
+{
+return(myImgApp);
+}
+
+/* --Methode-- */
+Services2NObjMgr* NamedObjMgr::GetServiceObj()
+{
+return(servnobjm);
+}
+
+/* --Methode-- */
+string const& NamedObjMgr::GetTmpDir()
+{
+return *TmpDir;
+}
+
+/* --Methode-- */
+void NamedObjMgr::SetTmpDir(string const& tmpdir)
+{
+if(tmpdir.length()<1) return;
+*TmpDir = tmpdir;
+int l = (*TmpDir).length();
+if ( (l>0) && ((*TmpDir)[l-1] != '/') )  (*TmpDir) += '/';
+servnobjm->SetTmpDir(*TmpDir);
+}
+
+/* --Methode-- */
+bool NamedObjMgr::SetVar(string const & key, string const & val)
+{
+  if ((key.length() < 1) || (! isalpha(key[0])) )   {
+    cout << "NamedObjMgr::SetVar( " << key << " ...) Bad VarName " << endl;
+    return(false);
+  }
+#ifdef SANS_EVOLPLANCK
+  bool fg = true;
+#else
+  bool fg = myVars->HasKey(key);
+#endif
+  myVars->SetS(key, val);
+  //  cout << " DEBUG::SetVar " << *myVars << endl;
+  return(fg);
+}
+
+/* --Methode-- */
+bool NamedObjMgr::HasVar(string const & key)
+{
+  if ((key.length() < 1) || (! isalpha(key[0])) )   {
+    cout << "NamedObjMgr::HasVar( " << key << ") Bad VarName " << endl;
+    return(false);
+  }
+#ifdef SANS_EVOLPLANCK
+  DVList::ValList::const_iterator it;
+  for(it=myVars->Begin(); it!= myVars->End(); it++)
+    if ((*it).first == key)  return true;
+  return(false);
+#else
+  return(myVars->HasKey(key));
+#endif
+}
+
+/* --Methode-- */
+bool NamedObjMgr::DeleteVar(string const & key)
+{
+  if ((key.length() < 1) || (! isalpha(key[0])) )   {
+    cout << "NamedObjMgr::DeleteVar( " << key << ") Bad VarName " << endl;
+    return(false);
+  }
+#ifdef SANS_EVOLPLANCK
+  return(false);
+#else
+  return(myVars->DeleteKey(key));
+#endif
+}
+
+/* --Methode-- */
+string NamedObjMgr::GetVar(string const & key)
+{
+  if ((key.length() < 1) || (! isalpha(key[0])) )   {
+    cout << "NamedObjMgr::GetVar( " << key << ") Bad VarName " << endl;
+    return("");
+  }
+  //  cout << " DEBUG::GetVar " << *myVars << endl;
+  return(myVars->GetS(key));
+}
+
+/* --Methode-- */
+DVList& NamedObjMgr::GetVarList()
+{
+  //  cout << " DEBUG::GetVarList " << *myVars << endl;
+  return(*myVars);
+}
+
+/* --Methode-- */
+bool NamedObjMgr::CreateDir(string & dirname)
+{
+if ( !CheckDirName(dirname) ) {
+  cout << "NamedObjMgr::CreateDir( " << dirname << ") Error - Invalid name !" << endl;
+  return(false); 
+  }
+NObjDirList::iterator it = myDirs->find(dirname);
+if (it != myDirs->end()) {
+  cout << "NamedObjMgr::CreateDir( " << dirname << ") Error - Existing directory !" << endl;
+  return(false);
+  }
+myDirId++;
+nobj_diritem di;
+di.id = myDirId;
+di.nobj = 0;
+di.lock = false;
+di.keepold = false;
+(*myDirs)[dirname] = di;
+if (myImgApp)  { 
+  string str = '/' + dirname;
+  (myImgApp->ObjMgrW())->AddDirectory(str.c_str(), myDirId);
+  }
+if (verbeux) cout << "NamedObjMgr::CreateDir() " << dirname << " Created " << endl;
+return(true);
+}
+
+/* --Methode-- */
+bool NamedObjMgr::DeleteDir(string & dirname)
+{
+if ( !CheckDirName(dirname) ) {
+  cout << "NamedObjMgr::DeleteDir( " << dirname << ") Error - Invalid name !" << endl;
+  return(false); 
+  }
+NObjDirList::iterator it = myDirs->find(dirname);
+if (it == myDirs->end()) {
+  cout << "NamedObjMgr::DeleteDir( " << dirname << ") Error - No such directory !" << endl;
+  return(false);
+  }
+if ((*it).second.nobj > 0) {
+  cout << "NamedObjMgr::DeleteDir() " << dirname << " not empty ! " << endl;
+  return(false);
+  }
+if ((*it).second.lock ) {
+  cout << "NamedObjMgr::DeleteDir() " << dirname << " locked ! " << endl;
+  return(false);
+  }
+if ((*it).second.id < 50) {
+  cout << "NamedObjMgr::DeleteDir() " << dirname << " cannot be deleted ! " << endl;
+  return(false);
+  }
+
+if (myImgApp)  
+  (myImgApp->ObjMgrW())->DelDirectory((*it).second.id);
+myDirs->erase(it);
+if (verbeux) cout << "NamedObjMgr::DeleteDir() " << dirname << " deleted " << endl;  
+return(true);
+}
+
+/* --Methode-- */
+void NamedObjMgr::LockDir(string & dirname)
+{
+if ( !CheckDirName(dirname) ) return;
+NObjDirList::iterator it = myDirs->find(dirname);
+if (it == myDirs->end()) return;
+(*it).second.lock = true;
+if (verbeux) cout << "NamedObjMgr::LockDir() " << dirname << " Locked " << endl;
+return;
+}
+
+/* --Methode-- */
+void NamedObjMgr::UnlockDir(string & dirname)
+{
+if ( !CheckDirName(dirname) ) return;
+NObjDirList::iterator it = myDirs->find(dirname);
+if (it == myDirs->end()) return;
+(*it).second.lock = true;
+if (verbeux) cout << "NamedObjMgr::UnlockDir() " << dirname << " Unlocked " << endl;
+return;
+}
+
+/* --Methode-- */
+void NamedObjMgr::SetKeepOldDirAtt(string & dirname, bool keepold)
+{
+if ( !CheckDirName(dirname) ) return;
+NObjDirList::iterator it = myDirs->find(dirname);
+if (it == myDirs->end()) return;
+(*it).second.keepold = keepold;
+if (!verbeux) return;
+cout << "NamedObjMgr::SetKeepOldDirAtt() " << dirname << "  ->  ";
+if ( keepold ) cout << " True " << endl;
+else cout << " False " << endl;
+return;
+}
+
+
+/* --Methode-- */
+bool NamedObjMgr::SetCurrentDir(string & dirname)
+{
+if ( !CheckDirName(dirname) ) {
+  cout << "NamedObjMgr::SetCurrentDir( " << dirname << ") Error - Invalid name !" << endl;
+  return(false); 
+  }
+NObjDirList::iterator it = myDirs->find(dirname);
+if (it == myDirs->end()) {
+  cout << "NamedObjMgr::SetCurrentDir( " << dirname << ") Error - No such directory !" << endl;
+  return(false);
+  }
+*currDir = dirname;
+if (verbeux) cout << "NamedObjMgr::SetCurrentDir() -> " << dirname << endl;
+return(true);
+}
+
+/* --Methode-- */
+void NamedObjMgr::GetCurrentDir(string & dirname)
+{
+dirname = *currDir;
+}
+
+/* --Methode-- */
+void NamedObjMgr::ListDirs(string & patt)
+{
+NObjDirList::iterator it;
+string cn;
+cout << "NamedObjMgr::ListDirs( " << patt << " ) " << endl;
+int k = 0;
+for(it= myDirs->begin(); it != myDirs->end(); it++) {
+  cn = (*it).first;
+  if (csh_parse(cn.c_str(), patt.c_str()) == 0) continue;
+  k++;
+  cout << k << "- " << (*it).first;
+  if ( (*it).second.lock )  cout << "  Locked " ;
+  if ( (*it).second.keepold )   cout << "  KeepOld " ;
+  cout << "  (Id= " << (*it).second.id << " NbObj= " << (*it).second.nobj << ")" << endl;
+   
+  }
+}
+
+/* --Methode-- */
+void NamedObjMgr::GetDirList(string & patt, vector<string>& lstd)
+{
+NObjDirList::iterator it;
+string cn;
+for(it= myDirs->begin(); it != myDirs->end(); it++) {
+  cn = (*it).first;
+  if (csh_parse(cn.c_str(), patt.c_str()) == 0) continue;
+  lstd.push_back(cn);
+  }
+}
+
+/* --Methode-- */
+void NamedObjMgr::CleanDir(string & dirname)
+{
+if ( !CheckDirName(dirname) ) {
+  cout << "NamedObjMgr::CleanDir( " << dirname << ") Error - Invalid name !" << endl;
+ // return(false);  $CHECK$ illegal return value in void function
+  }
+NObjDirList::iterator itr = myDirs->find(dirname);
+if (itr == myDirs->end()) {
+  cout << "NamedObjMgr::CleanDir( " << dirname << ") Error - No such directory !" << endl;
+ // return(false);  $CHECK$ illegal return value in void function
+  }
+
+int did = (*itr).second.id;
+NObjList::iterator it;  
+list<int>::iterator iwr;
+bool nodisp = true;
+list<string> odel;
+for(it = myObjs->begin(); it != myObjs->end(); it++) {
+  if ((*it).second.dirid != did) continue;
+  nodisp = true;
+  if (myImgApp) 
+    for(iwr=(*it).second.wrsid.begin(); iwr != (*it).second.wrsid.end(); iwr++) 
+      if (myImgApp->CheckWRsId(*iwr)) { nodisp = false; break; }
+  if (nodisp) odel.push_back((*it).first);
+  }
+list<string>::iterator ii;
+for(ii=odel.begin(); ii != odel.end(); ii++)  DelObj(*ii,true);
+if (myImgApp)  
+  (myImgApp->ObjMgrW())->UpdateList(did);
+}
+
+
+
+//++
+// Titre	Gestion de la liste des objets
+//--
+//++
+// void AddObj(AnyDataObj* obj, string& nom)
+//	Ajoute l'objet "obj" à la liste, identifié par "nom".
+//	Si un objet de même nom existe, l'ancien objet est renommé en concaténant 
+//	un numéro à son nom.
+// void DelObj(string const& nom, bool fgd=true)
+//	Supprime l'objet "nom" de la liste. L'objet est détruit si "fgd==true"	("delete obj")
+// void DelObjects(string const& patt, bool fgd=true)
+//	Supprime l'ensemble des objets dont le nom correspond au patron "patt".
+//	Le patron peut contenir les caractères "*" et "?" . Les objets sont détruits si "fgd==true"
+// AnyDataObj*  GetObj(string const& nom) 
+//	Retourne l'objet identifié par "nom" dans la liste. Retourne "NULL" si "nom" n'est 
+//	pas dans la liste.
+// void  RenameObj(string const& nom, string& nomnew)
+//	Change le nom d'un objet dans la liste.
+// void  CopyObj(string const& nom, string& nomcp)
+//	Copy l'objet "nom" de la liste dans l'objet "nomcp" de la liste.
+//--
+
+
+/* --Methode-- */
+bool NamedObjMgr::AddObj(AnyDataObj* obj, string & nom, bool crd)
+{
+
+if (obj == NULL)  return(false);
+// On verifie si l'objet est deja dans la liste 
+NObjList::iterator it;
+for(it = myObjs->begin(); it != myObjs->end(); it++) {
+  if ((*it).second.obj == obj) {
+    cout << "NamedObjMgr::AddObj() Object already present with name " << (*it).first << endl;
+    return(false);
+    }
+  }
+string nobj;
+string nrep;
+char buff[32];
+int did = ParseObjectName(nom, nrep, nobj);
+if (did == 0) {
+  if (!crd) {
+    cout << "NamedObjMgr::AddObj() No " << nrep << " Directory " << endl;
+    return(false);
+    }
+  else { CreateDir(nrep);  did =  myDirId; }
+  }
+
+// Si c'est le repertoire /autoc, on nettoie
+if (nrep == "autoc")  {
+  CleanDir(nrep);
+  }
+
+myNObj++;
+if ((nobj.length() < 1) || (! isalpha(nobj[0]) ) ) {
+  cout << "NamedObjMgr::AddObj() bad object name " << nobj ;
+  sprintf(buff,"O%d", myNObj);
+  nobj = buff;
+  cout << " changed to " << nobj << endl;
+  }
+
+nom = '/' + nrep + '/' + nobj;  
+NObjDirList::iterator itr = myDirs->find(nrep);
+if ((*itr).second.lock) {
+  cout << "NamedObjMgr::AddObj() " << nrep << " Locked Directory " << endl;
+  return(false);
+  }
+it = myObjs->find(nom);
+if (it != myObjs->end()) { // l'objet existe deja
+  if (nrep == "autoc") {  // Dans /autoc , on garde les objets affiches, donc del. par Clean
+    sprintf(buff, "%d", (*it).second.oid); 
+    string nomnew = "/autoc/" + nobj + buff;
+    RenameObj(nom, nomnew);
+    }                              
+  else if ( (*itr).second.keepold ) { // On met l'ancien objet dans /old
+    string on,od;
+//    ParseObjectName((*it).first, od, on); 
+    sprintf(buff, "%d", (*it).second.oid);
+    string nomnew = "/old/" + nobj + buff;
+    RenameObj(nom, nomnew);
+    }
+  else {  // Sinon, on remplace l'objet
+    cout << "NamedObjMgr::AddObj() - Replacing " << nom << endl;
+    DelObj(nom);
+    }
+  }
+
+nobj_item no;
+no.obj = obj;
+no.obja = servnobjm->GetAdapter(obj);  // L'adaptateur
+no.oid =  myNObj;
+no.dirid = did;
+(*myObjs)[nom] = no;
+
+(*itr).second.nobj++;
+
+if ( (myImgApp != NULL) && (myImgApp->ObjMgrW())->Visible() ) {
+  string oln = nobj + "  (T= " + no.obja->GetDataObjType() + ")" ; 
+  (myImgApp->ObjMgrW())->AddObjList(did, oln.c_str(), no.oid);
+  }
+if (verbeux) cout << "NamedObjMgr::AddObj()  Object " << nom << " ( "  
+     << typeid(*obj).name() << " ) added (Total= " << myObjs->size() << ")" << endl;  
+return(true);
+}
+
+bool NamedObjMgr::AddObj(AnyDataObj& obj, string & nom, bool crd)
+{
+NObjMgrAdapter* adap = GetServiceObj()->GetAdapter(&obj);
+if (adap == NULL) {
+  cout << "NamedObjMgr::AddObj() No Adapter !   " << nom << endl;
+  return(false);
+}
+AnyDataObj * cloneobj = adap->CloneDataObj(true);
+delete adap;
+if (cloneobj == NULL) {
+  cout << "NamedObjMgr::AddObj() Pb cloning object ! " << nom << endl;
+  return(false);
+}
+return ( AddObj(cloneobj , nom, crd) );
+}
+
+/* --Methode-- */
+bool NamedObjMgr::RenameObj(string & nom, string& nomnew)
+{
+string n1,r1,n2,r2;
+int dids = ParseObjectName(nom, r1, n1);
+NObjDirList::iterator itr1 = myDirs->find(r1);
+int did = ParseObjectName(nomnew, r2, n2);
+NObjDirList::iterator itr2 = myDirs->find(r2);
+
+if (did == 0) {
+  cout << "NamedObjMgr::RenameObj() Error - No " << r2 << " directory !" << endl;
+  return(false);
+}
+nom = '/' + r1 + '/' + n1;
+nomnew = '/' + r2 + '/' + n2;
+NObjList::iterator it1 = myObjs->find(nom);
+if (it1 == myObjs->end()) {
+  cout << "NamedObjMgr::RenameObj() Error -  No " << nom << " object !" << endl;
+  return(false);
+}
+if ((n2.length() < 1) || (! isalpha(n2[0])) ) {
+  cout << "NamedObjMgr::RenameObj() Error -  bad new object name" << n2 << endl;
+  return(false);
+}
+NObjList::iterator it2 = myObjs->find(nomnew);
+if (it2 != myObjs->end()) {
+  cout << "NamedObjMgr::RenameObj() Error -  Object " << nomnew << " exist !" << endl;
+  return(false);
+  }
+
+if ( (*itr1).second.lock || (*itr2).second.lock ) {
+  cout << "NamedObjMgr::RenameObj() Error - Source or destination directory locked !" 
+       << endl;
+  return(false);  
+  }
+
+
+nobj_item no = (*it1).second;
+no.dirid = did;
+myObjs->erase(it1);
+NObjDirList::iterator itr = myDirs->find(r1);
+(*itr).second.nobj--;
+(*myObjs)[nomnew] = no;
+itr = myDirs->find(r2);
+(*itr).second.nobj++;
+
+if ( (myImgApp != NULL) && (myImgApp->ObjMgrW())->Visible() ) {
+  (myImgApp->ObjMgrW())->DelObjList(dids, no.oid);
+  string oln = n2 + "  (T= " + no.obja->GetDataObjType() + ")" ; 
+  (myImgApp->ObjMgrW())->AddObjList(did, oln.c_str(), no.oid);
+}
+if (verbeux) 
+  cout << "NamedObjMgr::RenameObj() - Object " << nom << " renamed to " << nomnew << endl;
+return(true);
+}
+
+/* --Methode-- */
+bool NamedObjMgr::CopyObj(string & nom, string& nomcp)
+{
+if(nomcp.length()<=0)
+  {cout<<"NamedObjMgr::CopyObj() Error, copied obj name "<<nomcp<<" not valid"<<endl;
+  return(false);}
+NObjMgrAdapter* obnom = GetObjAdapter(nom);
+if(obnom==NULL)
+  {cout<<"NamedObjMgr::CopyObj() Error -  No "<<nom<<" object !"<<endl;
+  return(false);}
+AnyDataObj* obnomcp = obnom->CloneDataObj();
+if(obnomcp==NULL) return(false);
+if(! AddObj(obnomcp,nomcp) ) {delete obnomcp; return(false);}
+return true;
+}
+
+
+/* --Methode-- */
+bool NamedObjMgr::DelObj(string & nom, bool fgd)
+{
+string n1,r1;
+int did = ParseObjectName(nom, r1, n1);
+nom = '/' + r1 + '/' + n1;
+NObjList::iterator it = myObjs->find(nom);
+if (it == myObjs->end()) return(false); 
+NObjDirList::iterator itr = myDirs->find(r1);
+if ( (*itr).second.lock  ) {
+  cout << "NamedObjMgr::DelObj() Error - Locked directory " << r1 << endl;
+  return(false);
+  }
+list<int>::iterator ii;
+if (myImgApp) {
+//DBG  cerr << " *DBG* NamedObjMgr::DelObj Sz= " << (*it).second.wrsid.size() << endl; 
+  for(ii=(*it).second.wrsid.begin(); ii != (*it).second.wrsid.end(); ii++) 
+      myImgApp->DelWRsId((*ii));
+}
+delete (*it).second.obja;  // destruction de l'adaptateur 
+if (fgd) delete (*it).second.obj;
+
+if ( (myImgApp != NULL) && (myImgApp->ObjMgrW())->Visible() ) {
+  int olid = (*it).second.oid;
+  (myImgApp->ObjMgrW())->DelObjList(did, olid);
+}
+myObjs->erase(it);
+(*itr).second.nobj--;
+
+
+if (!verbeux) return(true);  
+if (fgd) cout << "NamedObjMgr::DelObj()  Object " << nom << " deleted (Total= " << myObjs->size() << ")" << endl;
+else  cout << "NamedObjMgr::DelObj()  Object " << nom << " removed (Total= " << myObjs->size() << ")" << endl;
+return(true);  
+}
+
+/* --Methode-- */
+bool NamedObjMgr::DelObj_Id(int oid)
+{
+NObjList::iterator it;
+string nom;
+bool of = false;
+for(it = myObjs->begin(); it != myObjs->end(); it++) 
+  if ( (*it).second.oid == oid ) { 
+    of = true;  nom = (*it).first;
+    break;
+  }
+if (of) return(DelObj(nom, true));
+else return(false);
+}
+
+/* --Methode-- */
+void NamedObjMgr::DelObjects(string & patt, bool fgd)
+{
+string n1,r1;
+ParseObjectName(patt, r1, n1);
+patt = '/' + r1 + '/' + n1;
+NObjList::iterator it;  
+list<string> odel;
+string cn;
+for(it = myObjs->begin(); it != myObjs->end(); it++) {
+  cn = (*it).first;
+  if (csh_parse(cn.c_str(), patt.c_str()) != 0)  odel.push_back(cn);
+  }
+list<string>::iterator ii;
+for(ii=odel.begin(); ii != odel.end(); ii++)  DelObj(*ii, fgd);
+}
+
+/* --Methode-- */
+AnyDataObj* NamedObjMgr::GetObj(string & nom)
+{
+string n1,r1;
+ParseObjectName(nom, r1, n1);
+nom = '/' + r1 + '/' + n1;
+NObjList::iterator it = myObjs->find(nom);
+if (it == myObjs->end()) return(NULL); 
+return((*it).second.obj);
+}
+
+/* --Methode-- */
+NObjMgrAdapter* NamedObjMgr::GetObjAdapter(string & nom)
+{
+string n1,r1;
+ParseObjectName(nom, r1, n1);
+nom = '/' + r1 + '/' + n1;
+NObjList::iterator it = myObjs->find(nom);
+if (it == myObjs->end()) return(NULL); 
+return((*it).second.obja);
+}
+
+/* --Methode-- */
+void NamedObjMgr::ListObjs(string & patt)
+{
+int k;
+AnyDataObj* obj=NULL;
+string ctyp;
+char strg[256];
+
+string n1,r1;
+ParseObjectName(patt, r1, n1);
+patt = '/' + r1 + '/' + n1;
+ cout << "NamedObjMgr::ListObjs( " << patt << " ) TotNObjs= " << myObjs->size() << "\n" ;
+NObjList::iterator it;  k = 0;
+string cn;
+for(it = myObjs->begin(); it != myObjs->end(); it++) {
+  cn = (*it).first;
+  if (csh_parse(cn.c_str(), patt.c_str()) == 0)  continue;
+  obj = (*it).second.obj;
+  ctyp = typeid(*obj).name();
+  sprintf(strg, "%2d/ %16s : %s", k, typeid(*obj).name(), ((*it).first).c_str()); 
+  ctyp = strg;
+  cout << ctyp << "\n" ;
+  k++;
+}
+cout << endl;
+return;
+}
+
+/* --Methode-- */
+void NamedObjMgr::GetObjList(string & patt, vector<string> &lst)
+{
+string n1,r1;
+if (patt.length() < 1)  return;
+bool fgr = (patt[0] == '/') ? true : false;
+ParseObjectName(patt, r1, n1);
+patt = '/' + r1 + '/' + n1;
+NObjList::iterator it;
+string cn;
+for(it = myObjs->begin(); it != myObjs->end(); it++) {
+  cn = (*it).first;
+  if (csh_parse(cn.c_str(), patt.c_str()) == 0)  continue;
+  if (fgr) lst.push_back(cn);
+  else {
+    ParseObjectName(cn, r1, n1);
+    lst.push_back(n1);
+    }
+  }
+}
+
+//++
+// Titre	Entrées-Sorties (I/O) sur les objets
+//--
+//++
+// void  ReadObj(PInPersist& s, int num=-1)
+//	Lit l'objet à partir avec le tag numéro "num" dans le flot "PInPersist s"
+//	et l'ajoute à la liste. Si "num" est négatif, tous les objets présents
+//	sur le flot "s" sont créés et ajoutés à la liste.
+// void  ReadObj(string const & nomppf, string nobj="")
+//	Lit le premier objet à partir du fichier PPF "nomppf". L'objet est ajouté
+//	à la liste avec le nom "nobj". Si "nobj" est une chaîne vide, un nom est 
+//	composé à partir du nom de fichier. 
+//--
+
+/* --Methode-- */
+void NamedObjMgr::ReadObj(string const & flnm, string & nobj)
+{
+PPersist* ppobj=NULL;
+bool ok = true;
+#ifdef SANS_EVOLPLANCK
+TRY{
+  PInPersist pis(flnm);
+  ppobj = PPersistMgr::ReadObject(pis);
+  if (ppobj == NULL) ok = false;
+}  CATCH(merr) 
+  { printf("NamedObjMgr::ReadObj()/Error Exception= %ld (%s) \n", 
+    (long)merr, PeidaExc(merr));  ok = false; } ENDTRY;
+#else
+try {
+  PInPersist pis(flnm);
+  ppobj = pis.ReadObject();
+  }
+catch (IOExc iox) {
+  cerr << "NamedObjMgr::ReadObj()/Error Exception - Msg= " << iox.Msg() << endl;
+  ok = false;
+  }
+#endif
+if (!ok)  return;
+if (nobj.length()<1)  nobj = servnobjm->FileName2Name(flnm);
+AddObj(ppobj->DataObj(), nobj, true);
+cout << "NamedObjMgr::ReadObj(...) object " << nobj << " read from file " << endl;
+return;
+}
+
+/* --Methode-- */
+void NamedObjMgr::ReadObj(PInPersist& s, int num)
+{
+int_4 i; // $CHECK$ int -> int_4 a cause de TagKey
+#ifdef SANS_EVOLPLANCK
+int_4 cid, key, ln; // $CHECK$ int -> int_4 a cause de TagKey
+#endif
+int n0, n1;
+bool ok = true;
+PPersist* obj=NULL;
+string nom;
+
+int nread = 0;
+if ( (s.NbTags() < 1) || (num >= s.NbTags()) ) {
+  if (num >= 0) { 
+    cerr << "NamedObjMgr::ReadObj(PInPersist, " << num << "  Error! NbTags =" 
+         << s.NbTags() << endl;
+    return;
+  }
+
+#ifdef SANS_EVOLPLANCK
+  TRY {
+    obj = PPersistMgr::ReadObject(s);
+    if (obj == NULL)  ok = false;
+  }  CATCH(merr) { 
+    printf("NamedObjMgr::ReadObj()/Error Exception= %ld (%s) \n", (long)merr, PeidaExc(merr)); 
+    ok = false; 
+  } ENDTRY;
+#else
+try {
+  obj = s.ReadObject();
+  }
+catch (IOExc iox) {
+  cerr << "NamedObjMgr::ReadObj()/Error Exception - Msg= " << iox.Msg() << endl;
+  ok = false;
+  }
+#endif
+
+  if (!ok)  return;
+  nom = "";
+  AddObj(obj->DataObj(), nom);
+  nread++;
+}
+ 
+if (num < 0) { n0 = 0; n1 = s.NbTags(); } 
+else { n0 = num; n1 = num+1; }
+for(i=n0; i<n1; i++) {
+#ifdef SANS_EVOLPLANCK
+  key = s.TagKey(i, cid, ln); 
+  if (ln <= 0)  nom = "";
+  else nom = s.TagName(i);
+  s.GotoTag(i);
+  TRY {
+    obj = PPersistMgr::ReadObject(s);
+    if (obj == NULL)  ok = false;
+  }  CATCH(merr) { 
+    printf("NamedObjMgr::ReadObj()/Error Exception= %ld (%s) \n", (long)merr, PeidaExc(merr)); 
+    ok = false; 
+  } ENDTRY;
+#else
+  s.GotoTagNum(i);
+  nom = s.GetTagName(i);
+  try {
+    obj = s.ReadObject();
+  }
+  catch (IOExc iox) {
+    cerr << "NamedObjMgr::ReadObj()/Error Exception - Msg= " << iox.Msg() << endl;
+    ok = false;
+    }
+#endif
+  if (ok)  { AddObj(obj->DataObj(), nom, true);  nread++; }
+}
+
+cout << "NamedObjMgr::ReadObj(...) " << nread << " Objects read " << endl;
+return;
+}
+/* --Methode-- */
+void NamedObjMgr::ReadAll(string const & flnm)
+{
+bool ok = true;
+PPersist* obj=NULL;
+
+PInPersist* ppin=NULL;
+#ifdef SANS_EVOLPLANCK
+TRY{
+  ppin = new PInPersist(flnm);
+  if (ppin->NbTags() < 1)  obj = PPersistMgr::ReadObject((*ppin));
+  else obj = NULL;
+}  CATCH(merr) 
+  { printf("NamedObjMgr::ReadAll()/Error Exception= %ld (%s) \n", 
+    (long)merr, PeidaExc(merr));  ok = false; } ENDTRY;
+#else
+try {
+  ppin = new PInPersist(flnm);
+  if (ppin->NbTags() < 1)  obj = ppin->ReadObject();
+  else   obj = NULL; 
+}
+catch (IOExc iox) {
+    cerr << "NamedObjMgr::ReadAll()/Error Exception - Msg= " << iox.Msg() << endl;
+    ok = false;
+}
+#endif
+if (!ok)  return;
+if (obj) {
+  string nom = servnobjm->FileName2Name(flnm);
+  AddObj(obj->DataObj(), nom);
+  }
+else ReadObj((*ppin), -1);
+delete ppin;
+return;
+}
+
+/* --Methode-- */
+void NamedObjMgr::ReadFits(string const & flnm, string & nobj)
+{
+
+#ifdef SANS_EVOLPLANCK 
+bool ok = false;
+RzImage* obj=NULL;
+TRY{
+  obj = RzReadFits((char*)flnm.c_str());
+  if (obj == NULL)   ok = false;
+  else ok = true;
+}  CATCH(merr) { 
+  printf("NamedObjMgr::ReadFITS(_Error Exception= %ld (%s) \n", (long)merr, PeidaExc(merr)); 
+  ok = false; 
+} ENDTRY;
+
+if (ok && (obj != NULL)) { 
+  if (nobj.length()<1)  nobj = servnobjm->FileName2Name(flnm);
+  AddObj((AnyDataObj*)obj, nobj);
+}
+#else
+ try {
+   FITS_AutoReader fiar(flnm);
+   char bun[16];
+   int nhdu = fiar.NbBlocks();
+   if (nobj.length()<1)  nobj = servnobjm->FileName2Name(flnm);
+   string name;
+   AnyDataObj* obj;
+   int kon = 1;
+   for(int k=1; k<=nhdu; k++) {
+     obj = fiar.ReadObject(k);
+     if (obj) {
+       cout << " NamedObjMgr::ReadFits() " << (string)typeid(*obj).name()
+	    << "  read From HDU " << k << endl;
+       if (typeid(*obj) == typeid(DVList)) {
+	 delete obj;
+	 continue;
+       }
+       if (kon > 1) { 
+	 sprintf(bun, "%d", kon);
+	 name = nobj + bun;
+       }
+       else name = nobj;
+       AddObj(obj, name);
+       kon++;
+     }
+     else cerr << " NamedObjMgr::ReadFits()  NULL pointer from FITS_AutoReader" << endl;
+   }
+ }
+ catch(PThrowable & exc) {
+   cerr << " NamedObjMgr::ReadFits() / Error - Catched Exception \n " 
+	<< "    Type= " << (string)typeid(exc).name()
+	<< " - Msg= " << exc.Msg() << endl;
+
+   }
+#endif
+
+return;
+}
+
+
+static int key_for_write = 5000;
+/* --Methode-- */
+void NamedObjMgr::SaveObj(string & nom, POutPersist& s, bool keeppath)
+{
+if (nom.length() < 1) return;
+string nob,rep;
+ParseObjectName(nom, rep, nob);
+nom = '/' + rep + '/' + nob;
+NObjMgrAdapter* obja=NULL;
+string nomf = (keeppath) ? nom : nob;
+obja = GetObjAdapter(nom);
+if (obja == NULL)  return;
+printf("NamedObjMgr::SaveObj(%s, )  (Type=%s) \n",  
+       nom.c_str(), typeid(*(obja->GetDataObj())).name());
+obja->SavePPF(s, nomf);
+return; 
+}
+
+/* --Methode-- */
+void NamedObjMgr::SaveObjects(string & patt, string const& flnm)
+{
+string n1,r1;
+if (patt.length() < 1)  return;
+bool keeppath = (patt[0] == '/') ? true : false;
+ParseObjectName(patt, r1, n1);
+patt = '/' + r1 + '/' + n1;
+
+bool ok = true;
+POutPersist* pout=NULL;
+#ifdef SANS_EVOLPLANCK 
+TRY{
+  pout = new POutPersist(flnm);
+}  CATCH(merr) 
+  { printf("NamedObjMgr::SaveObjects()/Error Exception= %ld (%s) \n", 
+    (long)merr, PeidaExc(merr));  ok = false; } ENDTRY;
+#else
+try {
+ pout = new POutPersist(flnm);
+}
+catch (IOExc iox) {
+    cerr << "NamedObjMgr::SaveObjects()/Error Exception - Msg= " << iox.Msg() << endl;
+    ok = false;
+}
+#endif
+if (!ok)  return;
+NObjList::iterator it;
+string cn; 
+for(it = myObjs->begin(); it != myObjs->end(); it++) {
+  cn = (*it).first;
+  if (csh_parse(cn.c_str(), patt.c_str()) == 0)  continue;
+  SaveObj(cn, (*pout), keeppath);
+  }
+delete pout;
+return;
+}
+
+/* --Methode-- */
+void NamedObjMgr::SaveAll(string const& flnm)
+{
+bool ok = true;
+
+POutPersist* pout=NULL;
+#ifdef SANS_EVOLPLANCK 
+TRY{
+  pout = new POutPersist(flnm);
+}  CATCH(merr) 
+  { printf("NamedObjMgr::SaveAll()/Error Exception= %ld (%s) \n", 
+    (long)merr, PeidaExc(merr));  ok = false; } ENDTRY;
+#else
+try {
+ pout = new POutPersist(flnm);
+}
+catch (IOExc iox) {
+    cerr << "NamedObjMgr::SaveAll()/Error Exception - Msg= " << iox.Msg() << endl;
+    ok = false;
+}
+#endif
+if (!ok)  return;
+NObjList::iterator it;
+string no; 
+for(it = myObjs->begin(); it != myObjs->end(); it++) {
+  no = (*it).first;
+  SaveObj(no, (*pout), true);
+  }
+delete pout;
+return;
+}
+
+/* --Methode-- */
+void NamedObjMgr::SaveFits(string& nom, string const & flnm)
+{
+NObjMgrAdapter* obja=NULL;
+obja = GetObjAdapter(nom);
+if (obja == NULL)  return;
+obja->SaveFits(flnm);
+return;
+}
+
+
+
+/* --Methode-- */
+void NamedObjMgr::PrintObj(string& nom)
+{
+NObjMgrAdapter* obja=NULL;
+obja = GetObjAdapter(nom);
+if (obja == NULL)  return;
+AnyDataObj* ob = obja->GetDataObj();
+if (ob == NULL) {
+  cerr << "NamedObjMgr::PrintObj() / Error - NULL object ! in " << nom << endl;
+  return;
+  }
+string ctyp = typeid(*ob).name();
+cout << "NamedObjMgr::PrintObj(" << nom << ") Type: " << ctyp << endl;
+obja->Print(cout);
+
+return;
+}
+
+/* --Methode-- */
+void NamedObjMgr::DisplayObj(string& nom, string dopt) 
+{
+NObjMgrAdapter* obja=NULL;
+obja = GetObjAdapter(nom);
+if (obja == NULL) {
+  cout << "NamedObjMgr::DisplayObj() Error , No object with name " << nom << endl; 
+  return;
+}
+if (obja->GetDataObj() == NULL) {
+  cerr << "NamedObjMgr::DisplayObj() / Error - NULL object ! in " << nom << endl;
+  return;
+  }
+if (!myImgApp)  return;
+ 
+PIDrawer * dr = NULL;
+P2DArrayAdapter* arr = NULL;
+dr = obja->GetDrawer(dopt);
+if (!dr) arr = obja->Get2DArray(dopt);
+
+if (!dr && !arr) { 
+  string ctyp = typeid(*(obja->GetDataObj())).name();
+  cout << "NamedObjMgr::DisplayObj() Error , No display for " << ctyp << endl; 
+  return;
+  }
+
+int wrsid = 0;
+
+string n1,r1;
+ParseObjectName(nom, r1, n1);
+
+if (dr) { 
+  PIDrawer3D * dr3 = dynamic_cast<PIDrawer3D *>(dr);
+  if(dr3)  wrsid = myImgApp->Disp3DDrawer(dr3, n1, dopt);
+  else wrsid = myImgApp->DispScDrawer( dr, n1, dopt); 
+  }
+else if (arr) wrsid = myImgApp->DispImage(arr, n1, dopt);
+
+if(wrsid != 0) {
+  NObjList::iterator it = myObjs->find(nom);
+  if (it == myObjs->end()) return; 
+  (*it).second.wrsid.push_back(wrsid);
+  }
+
+return;
+}
+
+/* --Methode-- */
+void NamedObjMgr::DisplayImage(string& nom, string dopt)
+{
+NObjMgrAdapter* obja=NULL;
+obja = GetObjAdapter(nom);
+if (obja == NULL) {
+  cout << "NamedObjMgr::DisplayImage() Error , No such object " << nom << endl; 
+  return;
+}
+if (obja->GetDataObj() == NULL) {
+  cerr << "NamedObjMgr::DisplayImage() / Error - NULL object ! in " << nom << endl;
+  return;
+  }
+if (!myImgApp)  return;
+ 
+P2DArrayAdapter* arr = obja->Get2DArray(dopt);
+
+if (!arr) { 
+  string ctyp = typeid(*(obja->GetDataObj())).name();
+  cout << "NamedObjMgr::DisplayImage() Error , Not supported for " << ctyp << endl; 
+  return;
+  }
+
+string n1,r1;
+ParseObjectName(nom, r1, n1);
+
+int wrsid = 0;
+wrsid = myImgApp->DispImage(arr, n1, dopt);
+
+if(wrsid != 0) {
+  NObjList::iterator it = myObjs->find(nom);
+  if (it == myObjs->end()) return; 
+  (*it).second.wrsid.push_back(wrsid);
+  }
+return;
+}
+/* --Methode-- */
+void NamedObjMgr::DisplaySurf3D(string& nom, string dopt)
+{
+NObjMgrAdapter* obja=NULL;
+obja = GetObjAdapter(nom);
+if (obja == NULL) {
+  cout << "NamedObjMgr::DisplaySurf3D() Error , No such object " << nom << endl; 
+  return;
+}
+if (obja->GetDataObj() == NULL) {
+  cerr << "NamedObjMgr::DisplaySurf3D() / Error - NULL object ! in " << nom << endl;
+  return;
+  }
+if (!myImgApp)  return;
+ 
+P2DArrayAdapter* arr = obja->Get2DArray(dopt);
+
+if (!arr) { 
+  string ctyp = typeid(*(obja->GetDataObj())).name();
+  cout << "NamedObjMgr::DisplaySurf3D() Error , Not supported " << ctyp << endl; 
+  return;
+  }
+
+if ((arr->XSize() > 250) || (arr->YSize() > 250)) {
+  cout << "NamedObjMgr::DisplaySurf3D() Error , 2D-Array(" <<  arr->XSize() 
+       << "x" << arr->YSize() << ") too big (max=250x250)" << endl; 
+  delete arr;
+  return;
+  }
+
+string n1,r1;
+ParseObjectName(nom, r1, n1);
+
+int wrsid = 0;
+PISurfaceDrawer* sdr = new PISurfaceDrawer(arr, true, true, true);
+wrsid = myImgApp->Disp3DDrawer(sdr, n1, dopt);
+if(wrsid >= 0) {
+  NObjList::iterator it = myObjs->find(nom);
+  if (it == myObjs->end()) return; 
+  (*it).second.wrsid.push_back(wrsid);
+  }
+
+return; 
+}
+
+/* --Methode-- */
+void NamedObjMgr::DisplayNT(string& nom, string& nmx, string& nmy, string& nmz,
+                            string& erx, string& ery, string& erz, string& wt, 
+                            string& label, string dopt, bool fg3d)
+{
+AnyDataObj* obj=GetObj(nom);
+if (obj == NULL) {
+  cout << "NamedObjMgr::DisplayNT() Error , No such object " << nom << endl; 
+  return;
+}
+if (!myImgApp)  return; 
+
+NTupleInterface * nt = dynamic_cast<NTupleInterface *>(obj);
+if (nt == NULL) {
+// if (typeid(*obj) != typeid(NTupleInterface)) { 
+  string ctyp = typeid(*obj).name();
+  cout << "NamedObjMgr::DisplayNT() Error , Object not an NTuple " << ctyp << endl; 
+  return;
+  }
+
+int wrsid = 0;
+dopt = "defline " + dopt;
+
+string n1,r1;
+ParseObjectName(nom, r1, n1);
+
+if ( fg3d && (nmz.length()>0) )  { // Display 3D
+  PINTuple3D* pin = new PINTuple3D(nt, false);
+  pin->SelectXYZ(nmx.c_str(), nmy.c_str(), nmz.c_str());
+  pin->SelectWt(wt.c_str());
+  pin->SelectLabel(label.c_str());
+  pin->SelectErrBar(erx.c_str(), ery.c_str(), erz.c_str());
+  string titre = nmz + "%" + nmy + "%" + nmz;
+  wrsid = myImgApp->Disp3DDrawer(pin, n1, dopt, titre);  
+}
+else {
+  PINTuple* pin = new PINTuple(nt, false);
+  pin->SelectXY(nmx.c_str(), nmy.c_str());
+  pin->SelectWt(wt.c_str());
+  pin->SelectLabel(label.c_str());
+  pin->SelectErrBar(erx.c_str(), ery.c_str());
+  string titre = nmy + "%" + nmx;
+  wrsid = myImgApp->DispScDrawer( (PIDrawer*)pin, n1, dopt, titre);
+  }
+
+if(wrsid >= 0) {
+  NObjList::iterator it = myObjs->find(nom);
+  if (it == myObjs->end()) return; 
+  (*it).second.wrsid.push_back(wrsid);
+  }
+
+return;
+}
+
+/* --Methode-- cmv 13/10/98 : Obsolete mais ne pas virer SVP */
+void NamedObjMgr::DisplayGFD(string& nom, string& numvarx, string& numvary, string& err, string dopt)
+//	Pour le display 2D ou 3D d'un ``GeneralFitData''.
+//|  nom = nom de l'objet GeneralFitData a representer.
+//|  numvarx = numero (nombre entier) de la 1ere variable d'abscisse.
+//|  numvary = numero (nombre entier) de la 2sd variable d'abscisse (3D).
+//|            Pour le display 2D, numvary="" string vide.
+//|  err = qu'elles erreurs faut il representer ?
+//|      - 2D : x y xy   (display y=f(x))
+//|      - 3D : x y z xy xz yz xzy   (display z=f(x,y))
+//|      Ceci n'est suivi que si on a PI_NotDefLineAtt, sinon toutes
+//|      les barres d'erreurs sont representees.
+//|  opt = options generales pour le display.
+{
+AnyDataObj* obj=GetObj(nom);
+if(obj == NULL)
+  {cout << "NamedObjMgr::DisplayGFD() Error , No such object " << nom << endl; 
+   return;}
+if(!myImgApp) return; 
+if(typeid(*obj) != typeid(GeneralFitData))
+  {string ctyp = typeid(*obj).name();
+   cout<<"NamedObjMgr::DisplayGFD() Error , Object not a GeneralFitData "<<ctyp<<endl; 
+   return;}
+
+// Decodage des erreurs a representer
+bool errx=false, erry=false, errz=false;
+if(err.length()>0) {
+  for(int i=0;i<(int_4)err.length();i++)
+    if     (err[i]=='x' || err[i]=='X') errx = true;
+    else if(err[i]=='y' || err[i]=='Y') erry = true;
+    else if(err[i]=='z' || err[i]=='Z') errz = true;
+}
+// Decodage des numeros de variables en abscisse
+ int numvx=-1, numvy=-1;
+ if(numvarx.length()>0) numvx = atoi(numvarx.c_str());
+ if(numvary.length()>0) numvy = atoi(numvary.c_str());
+ 
+ string n1,r1;
+ ParseObjectName(nom, r1, n1);
+
+ int wrsid = 0;
+ if(numvy>=0) {              // display 3D
+  PIGenFitDat3D* pigfd = new PIGenFitDat3D(((GeneralFitData*)obj),false);
+  pigfd->SelectXY(numvx,numvy);
+  pigfd->SelectErrBar(errx,erry,errz);
+  wrsid = myImgApp->Disp3DDrawer(pigfd,n1,dopt);  
+} else {                   // display 2D
+  PIGenFitDat* pigfd = new PIGenFitDat(((GeneralFitData*)obj),false);
+  pigfd->SelectX(numvx);
+  pigfd->SelectErrBar(errx,erry);
+  wrsid = myImgApp->DispScDrawer((PIDrawer*)pigfd,n1,dopt);
+}
+
+if(wrsid >= 0) {
+  NObjList::iterator it = myObjs->find(nom);
+  if (it == myObjs->end()) return; 
+  (*it).second.wrsid.push_back(wrsid);
+}
+
+return;
+}
+
+/* --Methode-- */ 
+void NamedObjMgr::DisplayVector(string & nomvx, string& nomvy, string dopt)
+//	Pour l'affichage 2-D de points avec coordonnees definies par deux vecteurs
+//   nomvx et nomvy
+{
+#ifdef SANS_EVOLPLANCK
+  cerr << " NamedObjMgr::DisplayVector() Error: Not implemented with PEIDA " << endl;
+#else
+
+if(!myImgApp) return; 
+
+AnyDataObj* obj;
+obj = GetObj(nomvx);
+if(obj == NULL) {
+  cout << "NamedObjMgr::DisplayVector() Error , No such object " << nomvx << endl; 
+  return;
+}
+//Vector * vx = dynamic_cast<Vector *>(obj);
+BaseArray* bax = dynamic_cast<BaseArray *>(obj);
+if (bax == NULL) {
+  cout << "NamedObjMgr::DisplayVector() Error " << nomvx << " not a BaseArray ! " << endl;
+  return;  
+}
+
+obj = GetObj(nomvy);
+if(obj == NULL) {
+  cout << "NamedObjMgr::DisplayVector() Error , No such object " << nomvy << endl; 
+  return;
+}
+BaseArray* bay = dynamic_cast<BaseArray *>(obj);
+if (bay == NULL) {
+  cout << "NamedObjMgr::DisplayVector() Error " << nomvy << " not a BaseArray ! " << endl;
+  return;  
+}
+
+Vector vx = *bax;
+Vector vy = *bay;
+Vector * cvx, * cvy;
+
+if (vx.Size() != vy.Size()) {
+  cout << "NamedObjMgr::DisplayVector() Warning / Vx.Size() != Vy.Size() " << endl;
+  if (vx.Size() < vy.Size()) {
+    cvx = new Vector(vx);
+    cvy = new Vector(vy.SubVector(Range(0, 0, vx.Size()-1)));
+  }
+  else {
+    cvx = new Vector(vx.SubVector(Range(0, 0, vy.Size()-1)));
+    cvy = new Vector(vy);
+  }
+}
+else {
+  cvx = new Vector(vx);
+  cvy = new Vector(vy);
+}
+
+POVectorAdapter * avx = new POVectorAdapter(cvx, true);
+POVectorAdapter * avy = new POVectorAdapter(cvy, true);
+PIYfXDrawer * vxydrw = new PIYfXDrawer(avx, avy, true);
+
+string nx,rx;
+ParseObjectName(nomvx, rx, nx);
+string ny,ry;
+ParseObjectName(nomvy, ry, ny);
+
+string title = ny + " (Y) vs. " + nx + " (X)";
+// display 2D
+myImgApp->DispScDrawer(vxydrw, title, dopt);
+
+return;
+
+#endif
+}
+
+/* --Methode-- 
+void NamedObjMgr::DisplayImage(string& nom, string dopt)
+{
+  cout << "NamedObjMgr::DisplayImage() a faire ! " << endl;
+}
+*/
+
+
+
+
+/* --Methode-- 
+void NamedObjMgr::SetGraphicAttributes(string gratt)
+{
+bool fg = false;
+servnobjm->DecodeDispOption(gratt, fg);
+Services2NObjMgr::SetDefaultStatsOption(Services2NObjMgr::GetStatsOption(gratt));
+}
+
+void NamedObjMgr::SetGraphicWinZone(int nzx, int nzy, bool fcr)
+{
+if (!myImgApp)  return; 
+if (fcr)  myImgApp->CreateGraphWin(nzx, nzy);
+else myImgApp->SetZone(nzx, nzy);
+}
+*/
+
+/* --Methode-- */
+void NamedObjMgr::AddWRsId(string & nom, int wrsid)
+{
+if(wrsid != 0) {
+  NObjList::iterator it = myObjs->find(nom);
+  if (it == myObjs->end()) return; 
+  (*it).second.wrsid.push_back(wrsid);
+  }
+return;
+}
+
+/* --Methode-- */
+void NamedObjMgr::UpdateObjMgrWindow(int did)
+{
+if (!myImgApp)  return;
+(myImgApp->ObjMgrW())->ClearObjList();
+
+NObjList::iterator it;  
+string cn;
+for(it = myObjs->begin(); it != myObjs->end(); it++) {
+  if ((*it).second.dirid != did) continue;
+  cn = (*it).first.substr(1);
+  //  cn = cn.substr(cn.find('/')+1) + "  (T= " + typeid(*((*it).second.obj)).name() + ")" ;
+  cn = cn.substr(cn.find('/')+1) + "  (T= " + (*it).second.obja->GetDataObjType() + ")" ;
+  (myImgApp->ObjMgrW())->AddObj(cn.c_str(), (*it).second.oid);
+  }
+}
+
+
+/* Nouvelle-Fonction */
+void NamedObjMgr::RemoveSpacesFromName(string & nom)
+{
+// on supprime les blancs de debut et de fin 
+size_t p = nom.find_first_not_of(" ");
+if(p>nom.length()) { nom = ""; return; }
+nom = nom.substr(p);
+p = nom.find(' ');
+if(p>nom.length()) p=nom.length();
+nom = nom.substr(0, p);
+}
+
+/* Nouvelle-Fonction */
+bool NamedObjMgr::CheckDirName(string & nom)
+{
+RemoveSpacesFromName(nom);
+if (nom.length() < 1)  return(false); 
+if (nom[0] == '/') nom = nom.substr(1) ;
+size_t p = nom.find('/');
+if (p < nom.length()) nom = nom.substr(0,p);
+if ((nom.length() < 1) || (! isalpha(nom[0]) ) )  return(false); 
+return(true);
+}
+
+/* Nouvelle-Fonction */
+int NamedObjMgr::ParseObjectName(string & nom, string & nomrep, string & nomobj)
+{
+RemoveSpacesFromName(nom);
+// Si le nom ne commence pas par un slash, c'est le repertoire courant 
+if (nom[0] != '/') { nomrep = *currDir;  nomobj = nom; }
+else {
+  string xx = nom.substr(1);
+  size_t p = xx.find('/');
+  if (p < xx.length())  { 
+    nomrep = xx.substr(0,p); 
+    nomobj = xx.substr(p+1);
+    }
+  else {
+    nomrep = xx;
+    nomobj = "";
+    }
+  }
+int rc = 0;
+NObjDirList::iterator it = myDirs->find(nomrep);
+if (it != myDirs->end())  rc = (*it).second.id;
+return(rc);
+}
+
Index: /tags/V_Dec2002/SophyaPI/PIext/nobjmgr.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/nobjmgr.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/nobjmgr.h	(revision 2309)
@@ -0,0 +1,112 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe de gestion d objets nommes pour piapp
+// Reza      Aout 97 , Juillet,Aout 98
+// CEA-DAPNIA      LAL-IN2P3/CNRS
+
+#ifndef NOBJMGR_H_SEEN
+#define NOBJMGR_H_SEEN
+
+#include "machdefs.h"
+
+#include <fstream.h>
+#include <string>
+#include <vector>
+
+#include "anydataobj.h"
+#include "ppersist.h"
+#include "dvlist.h"
+#include "dlftypes.h"
+
+
+class NObjMgrAdapter;
+class PIStdImgApp;
+class Services2NObjMgr;
+
+class NamedObjMgr {
+public:
+// Constructeur et destructeur
+			NamedObjMgr();
+  virtual		~NamedObjMgr();
+
+  virtual void 		SetImgApp(PIStdImgApp* app);
+  virtual void 		SetVerbose(bool fg=false);
+
+// Gestion des variables globales (dans un DVList) 
+  virtual bool          SetVar(string const & key, string const & val);
+  virtual bool          HasVar(string const & key);
+  virtual bool          DeleteVar(string const & key);
+  virtual string        GetVar(string const & key);
+  virtual DVList&       GetVarList();
+
+// Gestion des repertoires (Repertoire d'objets en memoire)
+  virtual bool		CreateDir(string & dirname);
+  virtual bool		DeleteDir(string & dirname);
+  virtual void		LockDir(string & dirname); 
+  virtual void		UnlockDir(string & dirname);
+  virtual void		SetKeepOldDirAtt(string & dirname, bool keepold=false); 
+  virtual bool		SetCurrentDir(string & dirname);
+  virtual void		GetCurrentDir(string & dirname);
+  virtual void		ListDirs(string & patt);
+  virtual void		GetDirList(string & patt, vector<string>& );
+  virtual void		CleanDir(string & dirname);
+
+//  Pour ajouter, supprimer et acceder aux objets 
+  virtual bool		AddObj(AnyDataObj* obj, string & nom, bool crd=false);
+  virtual bool		AddObj(AnyDataObj& obj, string & nom, bool crd=false);
+  virtual bool		RenameObj(string & nom, string& nomnew);
+  virtual bool          DelObj(string & nom, bool fgd=true);
+  virtual void		DelObjects(string & patt, bool fgd=true); 
+  virtual bool          DelObj_Id(int oid);
+  virtual AnyDataObj*	GetObj(string & nom);
+// Acces a l'adaptateur
+  virtual NObjMgrAdapter*	GetObjAdapter(string & nom);
+// Liste des objets
+  virtual void          ListObjs(string & patt);  		
+  virtual void          GetObjList(string & patt, vector<string>& );  		
+// Methode CopyObj() a virer probablement (Reza 30/8/200 obsolete ?) 
+  virtual bool          CopyObj(string & nom, string& nomcp);
+
+//  Lecture et sauvegarde des objets sur fichier
+  virtual void		ReadObj(PInPersist& s, int num=-1);
+  virtual void		ReadObj(string const & nomppf, string & nobj);
+  virtual void		ReadAll(string const & nomppf);
+  virtual void		ReadFits(string const & flnm, string & nobj);
+  virtual void          SaveObj(string & nom, POutPersist& s, bool keeppath=false);
+  virtual void          SaveObjects(string & patt, string const& nomppf);
+  virtual void          SaveAll(string const& nomppf);
+  virtual void          SaveFits(string & nom, string const & flnm);
+
+// Info sur les objets 
+  virtual void          PrintObj(string & nom);
+
+//  Affichage des objets 
+  virtual void          DisplayObj(string & nom, string dopt="");
+  virtual void          DisplayImage(string & nom, string dopt="");
+  virtual void          DisplaySurf3D(string & nom, string dopt="");
+  virtual void          DisplayNT(string & nom, string& nmx, string& nmy, string& nmz,  
+                                  string& erx, string& ery, string& erz, string& wt,
+                                  string& label, string dopt="", bool fg3d=false);
+  virtual void          DisplayGFD(string & nom, string& numvarx, string& numvary, 
+                                   string& err, string dopt="");
+
+  virtual void          DisplayVector(string & nomvx, string& nomvy, string dopt="");
+
+
+// Acces au PIApplication et a la classe de service 
+  virtual PIStdImgApp*		GetImgApp();
+  virtual Services2NObjMgr* 	GetServiceObj();
+  virtual string const&         GetTmpDir();
+  virtual void                  SetTmpDir(string const& tmpdir);
+
+  virtual void		AddWRsId(string & nom, int wrsid);
+// Pour utilisation par ObjMgrWind
+  virtual void		UpdateObjMgrWindow(int did);
+
+// Pour completer le nom de l'objet avec le nom du repertoire
+  static void RemoveSpacesFromName(string & nom);
+  static bool CheckDirName(string & nom);
+  static int  ParseObjectName(string & nom, string & nomrep, string & nomobj);
+};
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/nomgadapter.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/nomgadapter.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/nomgadapter.cc	(revision 2309)
@@ -0,0 +1,144 @@
+#include "machdefs.h"
+#include <stdlib.h>
+#include <typeinfo>
+#include <iostream.h>
+#include <string>
+#include "nomgadapter.h"
+
+/* --Methode-- */
+NObjMgrAdapter::NObjMgrAdapter(AnyDataObj* o)
+{
+mObj = o;
+}
+
+/* --Methode-- */
+NObjMgrAdapter::~NObjMgrAdapter()
+{
+}
+
+/* --Methode-- */
+NObjMgrAdapter* NObjMgrAdapter::Clone(AnyDataObj* o)
+{
+return(new NObjMgrAdapter(o));
+}
+
+/* --Methode-- */
+AnyDataObj* NObjMgrAdapter::GetDataObj()
+{
+return(mObj);
+}
+
+/* --Methode-- */
+string NObjMgrAdapter::GetDataObjType()
+{
+  return("AnyDataObj ");
+}
+
+
+/* --Methode-- */
+AnyDataObj* NObjMgrAdapter::CloneDataObj(bool)
+{
+string s = typeid(*mObj).name();
+cout << "NObjMgrAdapter::CloneDataObj() - Error : Not supported for " << s << endl;
+return(NULL);
+}
+
+/* --Methode-- */
+void NObjMgrAdapter::CopyFrom(AnyDataObj *)
+{
+string s = typeid(*mObj).name();
+cout << "NObjMgrAdapter::CopyFrom() - Error : Not supported for " << s << endl;
+}
+
+
+/* --Methode-- */
+string NObjMgrAdapter::ToString()
+{
+char buff[128];
+sprintf("%s@%lx", typeid(*mObj).name(), (long)mObj);
+return(buff);
+}
+
+/* --Methode-- */
+void NObjMgrAdapter::FillFromString()
+{
+string s = typeid(*mObj).name();
+cout << "NObjMgrAdapter::FillFromString() - Error : Not supported for " << s << endl;
+ return;
+}
+
+/* --Methode-- */
+void NObjMgrAdapter::ReadFits(string const & )
+{
+string s = typeid(*mObj).name();
+cout << "NObjMgrAdapter::ReadFits() - Error : Not supported for " << s << endl;
+}
+
+/* --Methode-- */
+void NObjMgrAdapter::SaveFits(string const & )
+{
+string s = typeid(*mObj).name();
+cout << "NObjMgrAdapter::SaveFits() - Error : Not supported for " << s << endl;
+}
+
+/* --Methode-- */
+void NObjMgrAdapter::SavePPF(POutPersist&, string const & )
+{
+string s = typeid(*mObj).name();
+cout << "NObjMgrAdapter::SavePPF() - Error : Not supported for " << s << endl;
+}
+
+/* --Methode-- */
+void NObjMgrAdapter::Print(ostream& )
+{
+string s = typeid(*mObj).name();
+cout << "NObjMgrAdapter::Print() - Error : Not supported for " << s << endl;
+}
+
+/* --Methode-- */
+PIDrawer* NObjMgrAdapter::GetDrawer(string &)
+{
+return(NULL);
+}
+
+/* --Methode-- */
+P2DArrayAdapter* NObjMgrAdapter::Get2DArray(string &)
+{
+return(NULL);
+}
+
+/* --Methode-- */
+NTupleInterface* NObjMgrAdapter::GetNTupleInterface(bool& adel)
+{
+string s = typeid(*mObj).name();
+cout << "NObjMgrAdapter::GetNTupleInterface() - Error : Not supported for " << s << endl;
+adel = false;
+return(NULL);
+}
+
+/* --Methode-- */
+GeneralFitData* NObjMgrAdapter::GetGeneralFitData(bool& adel
+                ,GeneralFitData::FitErrType errtype
+                ,double errscale,double errmin,int i1,int i2,int j1,int j2)
+{
+string s = typeid(*mObj).name();
+cout << "NObjMgrAdapter::GetGeneralFitData() - Error : Not supported for "<<s<<endl;
+adel = false;
+return(NULL);
+}
+
+AnyDataObj* NObjMgrAdapter::FitResidusObj(GeneralFit& mfit)
+{
+string s = typeid(*mObj).name();
+cout << "NObjMgrAdapter::FitResidusObj() - Error : Not supported for "<<s<<endl;
+return(NULL);
+}
+
+
+AnyDataObj* NObjMgrAdapter::FitFunctionObj(GeneralFit& mfit)
+{
+string s = typeid(*mObj).name();
+cout << "NObjMgrAdapter::FitFunctionObj() - Error : Not supported for "<<s<<endl;
+return(NULL);
+}
+
Index: /tags/V_Dec2002/SophyaPI/PIext/nomgadapter.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/nomgadapter.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/nomgadapter.h	(revision 2309)
@@ -0,0 +1,72 @@
+// This may look like C code, but it is really -*- C++ -*-
+//  Adaptateur pour objets gere par   NamedObjMgr (piapp)
+//                                    Reza 05/99
+//  LAL-IN2P3/CNRS               CEA-DAPNIA      
+
+#ifndef NOMGADAPTER_H_SEEN
+#define NOMGADAPTER_H_SEEN
+
+#include "machdefs.h"
+#include "ppersist.h"
+#include "anydataobj.h"
+#include "pidrawer.h"
+#include "parradapter.h"
+#include "ntupintf.h"
+#include "generalfit.h"
+
+
+// Classe d'adaptateur d'objets de donnees pour la gestion d'objets
+// nommes (NamedObjMgr) de piapp
+
+class NObjMgrAdapter {
+public:
+				NObjMgrAdapter(AnyDataObj* o);
+  virtual			~NObjMgrAdapter();
+
+  virtual NObjMgrAdapter*	Clone(AnyDataObj* o);
+
+  // Returns the actual data-object
+  virtual AnyDataObj*		GetDataObj();
+
+  // Returns the actual data-object type (class name)
+  virtual string		GetDataObjType();
+
+  // Returns a new data-object, cloning the original object 
+  virtual AnyDataObj*		CloneDataObj(bool share=false);
+
+  // Copies data from object o 
+  virtual void   		CopyFrom(AnyDataObj* o);
+
+// Returns a string representation of the object
+  virtual string	        ToString();
+// Fills the object from a string
+  virtual void	                FillFromString();
+
+  virtual void			ReadFits(string const & flnm);
+  virtual void			SaveFits(string const & flnm);
+  virtual void			SavePPF(POutPersist& s, string const & nom);
+
+  virtual void			Print(ostream& os);
+  virtual PIDrawer*		GetDrawer(string& dopt);
+  virtual P2DArrayAdapter*	Get2DArray(string& dopt);
+
+// NTupleInterface* nti = GetNTupleInterface(adel)
+// Retourne un objet de type NTupleInterface (nti), ainsi que adel
+// si adel == true, le programme appelant doit faire delete de nti 
+  virtual NTupleInterface*	GetNTupleInterface(bool& adel);
+
+// Methode pour l'interface GeneralFit.
+// Si adel==true:
+// le programme appelant doit faire delete du GeneralFitData retourne
+  virtual GeneralFitData* GetGeneralFitData(bool& adel
+          ,GeneralFitData::FitErrType errtype=GeneralFitData::DefaultError
+          ,double errscale=1.,double errmin=0.
+          ,int i1=0,int i2=-1,int j1=0,int j2=-1);
+  virtual AnyDataObj* FitResidusObj(GeneralFit& mfit);
+  virtual AnyDataObj* FitFunctionObj(GeneralFit& mfit);
+
+protected:
+  AnyDataObj* mObj;
+};
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/nomgfdadapter.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/nomgfdadapter.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/nomgfdadapter.cc	(revision 2309)
@@ -0,0 +1,131 @@
+#include "machdefs.h"
+#include <stdlib.h>
+#include <typeinfo>
+#include <iostream.h>
+#include <string>
+
+#include "nomgfdadapter.h"
+#include "pipodrw.h"
+
+#ifndef SANS_EVOLPLANCK
+#include "objfitter.h"
+#endif
+
+//-------------------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet GeneralFitData
+//-------------------------------------------------------------------------
+
+/* --Methode-- */
+NOMAdapter_GeneralFitData::NOMAdapter_GeneralFitData(GeneralFitData* o)
+  : NObjMgrAdapter(o)
+{
+mG = o;
+}
+
+/* --Methode-- */
+NOMAdapter_GeneralFitData::~NOMAdapter_GeneralFitData()
+{
+}
+
+/* --Methode-- */
+NObjMgrAdapter* NOMAdapter_GeneralFitData::Clone(AnyDataObj* o)
+{
+GeneralFitData* g = dynamic_cast<GeneralFitData *>(o);
+if (g) return ( new NOMAdapter_GeneralFitData(g) );
+return ( new NObjMgrAdapter(o) );
+}
+
+/* --Methode-- */
+string NOMAdapter_GeneralFitData::GetDataObjType()
+{
+return( "GeneralFitData " );
+}
+
+
+/* --Methode-- */
+AnyDataObj* NOMAdapter_GeneralFitData::CloneDataObj(bool /*share*/)
+{
+return( new GeneralFitData(*mG) );
+}
+
+/* --Methode-- */
+void NOMAdapter_GeneralFitData::SavePPF(POutPersist& pos, string const & nom)
+{
+#ifdef SANS_EVOLPLANCK
+string tag = nom;  // A cause de const
+mG->Write(pos,0,tag);
+#else
+ObjFileIO<GeneralFitData> fio(mG);
+fio.Write(pos, nom);
+#endif
+}
+
+/* --Methode-- */
+void NOMAdapter_GeneralFitData::Print(ostream& os)
+{
+os << *(mG);
+}
+
+/* --Methode-- */
+NTupleInterface* NOMAdapter_GeneralFitData::GetNTupleInterface(bool& adel)
+{
+adel = false;
+return(mG);
+}
+
+/* --Methode-- */
+GeneralFitData* NOMAdapter_GeneralFitData::GetGeneralFitData(bool& adel
+ ,GeneralFitData::FitErrType errtype,double errscale,double errmin
+ ,int i1,int i2,int j1,int j2)
+{
+adel = false;
+if(!mG) return(NULL);
+
+int n = mG->NData();
+if(n<=0) return(NULL);
+int nv = mG->NVar();
+if(nv<=0) return(NULL);
+
+i1 = (i1<0||i1>=n)? 0: i1;
+i2 = (i2<0||i2>=n||i2<i1)? n-1: i2;
+n = i2-i1+1;
+
+// Pas de gestion des erreurs sur les Abscisses Xi
+GeneralFitData* mGData = new GeneralFitData(nv,n,0);
+adel = true;
+
+double *x = new double[nv];
+for(int i=i1;i<=i2;i++) {
+  for(int j=0;j<nv;j++) x[j] = mG->Absc(j,i);
+  double f = mG->Val(i);
+  double e = mG->EVal(i);
+  e = GeneralFitData::ComputeError(f,e,errtype,errscale,errmin);
+  mGData->AddData(x,f,e);
+  if(!mG->IsValid(i)) mGData->KillData(i);
+}
+delete [] x;
+
+return mGData;
+}
+
+AnyDataObj* NOMAdapter_GeneralFitData::FitResidusObj(GeneralFit& mfit)
+{
+GeneralFitData* g = NULL;
+#ifdef SANS_EVOLPLANCK
+g = mG->FitResidus(mfit); 
+#else
+g = new GeneralFitData(ObjectFitter::FitResidus(*mG,mfit));
+#endif
+return g;
+}
+
+AnyDataObj* NOMAdapter_GeneralFitData::FitFunctionObj(GeneralFit& mfit)
+{
+GeneralFitData* g = NULL;
+#ifdef SANS_EVOLPLANCK
+g = mG->FitFunction(mfit); 
+#else
+g = new GeneralFitData(ObjectFitter::FitFunction(*mG,mfit));
+#endif
+return g;
+}
Index: /tags/V_Dec2002/SophyaPI/PIext/nomgfdadapter.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/nomgfdadapter.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/nomgfdadapter.h	(revision 2309)
@@ -0,0 +1,44 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Adaptateur d objets (pour NamedObjMgr) pour GeneralFitData
+//                                    cmv 27/7/99
+//  LAL-IN2P3/CNRS               CEA-DAPNIA     
+ 
+#ifndef NOMGFDADAPTER_H_SEEN
+#define NOMGFDADAPTER_H_SEEN
+
+#include "nomgadapter.h"
+#include "generalfit.h"
+
+//-------------------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet GeneralFitData 
+//-------------------------------------------------------------------------
+
+class NOMAdapter_GeneralFitData : public NObjMgrAdapter {
+public:
+			   NOMAdapter_GeneralFitData(GeneralFitData* o = NULL);
+  virtual		   ~NOMAdapter_GeneralFitData();
+
+  virtual NObjMgrAdapter*  Clone(AnyDataObj* o);
+
+  virtual string	   GetDataObjType();
+
+  virtual AnyDataObj*      CloneDataObj(bool share=false);
+
+  virtual void		   SavePPF(POutPersist& s, string const & nom);
+
+  virtual void		   Print(ostream& os);
+  virtual NTupleInterface* GetNTupleInterface(bool& adel);
+
+  virtual GeneralFitData* GetGeneralFitData(bool& adel
+          ,GeneralFitData::FitErrType errtype=GeneralFitData::DefaultError
+          ,double errscale=1.,double errmin=0.
+          ,int i1=0,int i2=-1,int j1=0,int j2=-1);
+  virtual AnyDataObj* FitResidusObj(GeneralFit& mfit);
+  virtual AnyDataObj* FitFunctionObj(GeneralFit& mfit);
+
+protected:
+  GeneralFitData* mG;
+};
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/nomhistadapter.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/nomhistadapter.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/nomhistadapter.cc	(revision 2309)
@@ -0,0 +1,557 @@
+#include "machdefs.h"
+#include <stdlib.h>
+#include <typeinfo>
+#include <iostream.h>
+#include <string>
+
+#include "nomhistadapter.h"
+#include "pihisto.h"
+#include "pihisto2d.h"
+#include "pipodrw.h"
+#include "servnobjm.h"
+
+#ifndef SANS_EVOLPLANCK
+#include "objfitter.h"
+#include "fitsntuple.h"
+#include "fitsxntuple.h"
+#endif
+
+//-------------------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet Histo / HProf
+//-------------------------------------------------------------------------
+
+/* --Methode-- */
+NOMAdapter_Histo::NOMAdapter_Histo(Histo* o)
+  : NObjMgrAdapter(o)
+{
+mHis = o;
+}
+
+/* --Methode-- */
+NOMAdapter_Histo::~NOMAdapter_Histo()
+{
+}
+
+/* --Methode-- */
+NObjMgrAdapter* NOMAdapter_Histo::Clone(AnyDataObj* o)
+{
+Histo* h = dynamic_cast<Histo *>(o);
+if (h) return ( new NOMAdapter_Histo(h) );
+return ( new NObjMgrAdapter(o) );
+}
+
+/* --Methode-- */
+string NOMAdapter_Histo::GetDataObjType()
+{
+HProf * hp = dynamic_cast<HProf *>(mHis);
+if(hp) return("HProf "); else return("Histo ");
+}
+
+/* --Methode-- */
+AnyDataObj* NOMAdapter_Histo::CloneDataObj(bool /*share*/)
+{
+mHis->UpdateHisto();  // pour le cas ou c'est un HProf
+HProf * hp = dynamic_cast<HProf *>(mHis);
+if(hp==NULL) return( new Histo(*mHis) );
+return( new HProf(*hp) );
+}
+
+/* --Methode-- */
+void NOMAdapter_Histo::SavePPF(POutPersist& pos, string const & nom)
+{
+#ifdef SANS_EVOLPLANCK
+// PEIDA-EROS L'histo est lui-meme PPersist
+string tag = nom;  // A cause de const
+mHis->Write(pos,0,tag);
+#else
+ObjFileIO<Histo> fio(mHis);
+fio.Write(pos, nom);
+#endif
+}
+
+/* --Methode-- */
+void NOMAdapter_Histo::Print(ostream& os)
+{
+mHis->Print(60);
+}
+
+/* --Methode-- */
+PIDrawer* NOMAdapter_Histo::GetDrawer(string & dopt)
+{
+if (typeid(*mHis) == typeid(HProf))  dopt = "fcirclemarker5 " + dopt;
+else dopt = "thinline " + dopt;
+PIHisto * pih = new PIHisto(mHis, false);
+return( pih );
+}
+
+/* --Methode-- */
+NTupleInterface* NOMAdapter_Histo::GetNTupleInterface(bool& adel)
+{
+adel = true;
+return( new NTupInt_Histo(mHis) );
+}
+
+/* --Methode-- */
+GeneralFitData* NOMAdapter_Histo::GetGeneralFitData(bool& adel
+ ,GeneralFitData::FitErrType errtype,double errscale,double errmin
+ ,int i1,int i2,int j1,int j2)
+{
+adel = false;
+if(!mHis) return(NULL);
+
+int nx = mHis->NBins();
+if(nx<=0) return(NULL);
+
+i1 = (i1<0||i1>=nx)? 0: i1;
+i2 = (i2<0||i2>=nx||i2<i1)? nx-1: i2;
+
+GeneralFitData* mGData = new GeneralFitData(1,i2-i1+1,0);
+adel = true;
+
+for(int i=i1;i<=i2;i++) {
+  double x = mHis->BinCenter(i);
+  double f = (*mHis)(i);
+  double e = (mHis->HasErrors())? mHis->Error(i) : 1.;
+  e = GeneralFitData::ComputeError(f,e,errtype,errscale,errmin);
+  mGData->AddData1(x,f,e);
+}
+
+return mGData;
+}
+
+AnyDataObj* NOMAdapter_Histo::FitResidusObj(GeneralFit& mfit)
+{
+Histo* h = NULL;
+#ifdef SANS_EVOLPLANCK
+h = mHis->FitResidus(mfit); 
+#else
+h = new Histo(ObjectFitter::FitResidus(*mHis,mfit));
+#endif
+return h;
+}
+
+AnyDataObj* NOMAdapter_Histo::FitFunctionObj(GeneralFit& mfit)
+{
+Histo* h = NULL;
+#ifdef SANS_EVOLPLANCK
+h = mHis->FitFunction(mfit); 
+#else
+h = new Histo(ObjectFitter::FitFunction(*mHis,mfit));
+#endif
+return h;
+}
+
+// -------------------------------------------------------------
+
+/* --Methode-- */
+NTupInt_Histo::NTupInt_Histo(Histo* h)
+{
+mHis = h;
+}
+
+/* --Methode-- */
+NTupInt_Histo::~NTupInt_Histo()
+{
+}
+
+/* --Methode-- */
+uint_4 NTupInt_Histo::NbLines() const 
+{
+return(mHis->NBins());
+}
+
+/* --Methode-- */
+uint_4 NTupInt_Histo::NbColumns() const
+{
+return(4);
+}
+
+/* --Methode-- */
+r_8* NTupInt_Histo::GetLineD(int k) const
+{
+int i;
+if ((k < 0) || (k >= mHis->NBins())) 
+    for(i=0; i<4; i++)  mRet[i] = 0.;
+else { 
+  mRet[0] = k;  mRet[1] = mHis->BinCenter(k);
+  mRet[2] = (*mHis)(k); mRet[3] = mHis->Error(k); 
+  }
+return(mRet);
+}
+
+/* --Methode-- */
+string NTupInt_Histo::VarList_C(const char* nx) const
+{
+string nomx;
+if (nx) nomx = nx;
+else nomx = "_xh_";
+string vardec = "double i,x,val,err; \n";
+vardec += "i = " + nomx + "[0];  x = " + nomx + "[1]; \n";
+vardec += "val = " + nomx + "[2];  err = " + nomx + "[3]; \n";
+return(vardec);
+}
+
+//-------------------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet Histo2D
+//-------------------------------------------------------------------------
+
+
+/* --Methode-- */
+NOMAdapter_Histo2D::NOMAdapter_Histo2D(Histo2D* o)
+  : NObjMgrAdapter(o)
+{
+mHis = o;
+}
+
+/* --Methode-- */
+NOMAdapter_Histo2D::~NOMAdapter_Histo2D()
+{
+}
+
+/* --Methode-- */
+NObjMgrAdapter* NOMAdapter_Histo2D::Clone(AnyDataObj* o)
+{
+Histo2D* h = dynamic_cast<Histo2D *>(o);
+if (h) return ( new NOMAdapter_Histo2D(h) );
+return ( new NObjMgrAdapter(o) );
+}
+
+/* --Methode-- */
+string NOMAdapter_Histo2D::GetDataObjType()
+{
+return ("Histo2D ");
+}
+
+/* --Methode-- */
+AnyDataObj* NOMAdapter_Histo2D::CloneDataObj(bool /*share*/)
+{
+return ( new Histo2D(*mHis) );
+}
+
+/* --Methode-- */
+void NOMAdapter_Histo2D::SavePPF(POutPersist& pos, string const & nom)
+{
+#ifdef SANS_EVOLPLANCK
+// PEIDA-EROS L'histo est lui-meme PPersist
+string tag = nom;  // A cause de const
+mHis->Write(pos,0,tag);
+#else
+ObjFileIO<Histo2D> fio(mHis);
+fio.Write(pos, nom);
+#endif
+}
+
+/* --Methode-- */
+void NOMAdapter_Histo2D::Print(ostream& os)
+{
+mHis->Print();
+}
+
+/* --Methode-- */
+PIDrawer* NOMAdapter_Histo2D::GetDrawer(string & dopt)
+{
+dopt = "thinline " + dopt;
+return( new PIHisto2D(mHis, false) );
+}
+
+/* --Methode-- */
+P2DArrayAdapter* NOMAdapter_Histo2D::Get2DArray(string & dopt)
+{
+return (new POH2DAdapter(mHis, false) );
+}
+
+/* --Methode-- */
+NTupleInterface* NOMAdapter_Histo2D::GetNTupleInterface(bool& adel)
+{
+adel = true;
+return( new NTupInt_Histo2D(mHis) );
+}
+
+
+/* --Methode-- */
+GeneralFitData* NOMAdapter_Histo2D::GetGeneralFitData(bool& adel
+ ,GeneralFitData::FitErrType errtype,double errscale,double errmin
+ ,int i1,int i2,int j1,int j2)
+{
+adel = false;
+if(!mHis) return(NULL);
+
+int nx = mHis->NBinX();
+int ny = mHis->NBinY();
+if(nx<=0 || ny<=0) return(NULL);
+
+i1 = (i1<0||i1>=nx)? 0: i1;
+i2 = (i2<0||i2>=nx||i2<i1)? nx-1: i2;
+j1 = (j1<0||j1>=ny)? 0: j1;
+j2 = (j2<0||j2>=ny||j2<j1)? ny-1: j2;
+
+GeneralFitData* mGData = new GeneralFitData(2,(i2-i1+1)*(j2-j1+1),0);
+adel = true;
+
+for(int i=i1;i<=i2;i++) for(int j=j1;j<=j2;j++) {
+  double x,y; mHis->BinCenter(i,j,x,y);
+  double f = (*mHis)(i,j);
+  double e = (mHis->HasErrors())? mHis->Error(i,j) : 1.;
+  e = GeneralFitData::ComputeError(f,e,errtype,errscale,errmin);
+  mGData->AddData2(x,y,f,e);
+}
+
+return mGData;
+}
+
+AnyDataObj* NOMAdapter_Histo2D::FitResidusObj(GeneralFit& mfit)
+{
+Histo2D* h2 = NULL;
+#ifdef SANS_EVOLPLANCK
+h2 = mHis->FitFunction(mfit);
+#else
+h2 = new Histo2D(ObjectFitter::FitResidus(*mHis,mfit));
+#endif
+return h2;
+}
+
+AnyDataObj* NOMAdapter_Histo2D::FitFunctionObj(GeneralFit& mfit)
+{
+Histo2D* h2 = NULL;
+#ifdef SANS_EVOLPLANCK
+h2 = mHis->FitFunction(mfit);
+#else
+h2 = new Histo2D(ObjectFitter::FitFunction(*mHis,mfit));
+#endif
+return h2;
+}
+
+
+// -------------------------------------------------------------
+
+/* --Methode-- */
+NTupInt_Histo2D::NTupInt_Histo2D(Histo2D* h)
+{
+mHis = h;
+}
+
+/* --Methode-- */
+NTupInt_Histo2D::~NTupInt_Histo2D()
+{
+}
+
+/* --Methode-- */
+uint_4 NTupInt_Histo2D::NbLines() const 
+{
+return(mHis->NBinX()*mHis->NBinY());
+}
+
+/* --Methode-- */
+uint_4 NTupInt_Histo2D::NbColumns() const 
+{
+return(6);
+}
+
+/* --Methode-- */
+r_8* NTupInt_Histo2D::GetLineD(int n) const
+{
+int i,j;
+r_8 f2,f3;
+if ((n < 0) || (n >= mHis->NBinX()*mHis->NBinY())) 
+    for(i=0; i<6; i++)  mRet[i] = 0.;
+else { 
+  i = n%mHis->NBinX();  j = n/mHis->NBinX(); 
+  mRet[0] = i;  mRet[1] = j;
+  mHis->BinCenter(i,j,f2,f3);
+  mRet[2] = f2;  mRet[3] = f3;  
+  mRet[4] =  (*mHis)(i,j);  mRet[5] = mHis->Error(i, j);
+  }
+return(mRet);
+}
+
+/* --Methode-- */
+string NTupInt_Histo2D::VarList_C(const char* nx) const
+{
+string nomx;
+if (nx) nomx = nx;
+else nomx = "_xh_";
+string vardec = "double i,j,x,y,val,err; \n";
+vardec += "i = " + nomx + "[0];  j = " + nomx + "[1]; \n";
+vardec += "x = " + nomx + "[2];  y = " + nomx + "[3]; \n";
+vardec += "val = " + nomx + "[4];  err = " + nomx + "[5]; \n";
+return(vardec);
+}
+
+
+
+//-------------------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet NTuple
+//-------------------------------------------------------------------------
+
+/* --Methode-- */
+NOMAdapter_NTuple::NOMAdapter_NTuple(NTuple* o)
+  : NObjMgrAdapter(o)
+{
+mNt = o;
+}
+
+/* --Methode-- */
+NOMAdapter_NTuple::~NOMAdapter_NTuple()
+{
+}
+
+/* --Methode-- */
+NObjMgrAdapter* NOMAdapter_NTuple::Clone(AnyDataObj* o)
+{
+NTuple* nt = dynamic_cast<NTuple *>(o);
+if (nt) return ( new NOMAdapter_NTuple(nt) );
+return ( new NObjMgrAdapter(o) );
+}
+
+
+/* --Methode-- */
+string NOMAdapter_NTuple::GetDataObjType()
+{
+return ("NTuple ");
+}
+
+/* --Methode-- */
+AnyDataObj* NOMAdapter_NTuple::CloneDataObj(bool /*share*/)
+{
+return ( new NTuple(*mNt) );
+}
+
+/* --Methode-- */
+void NOMAdapter_NTuple::ReadFits(string const & flnm)
+{
+#ifdef SANS_EVOLPLANCK
+  cerr << " NOMAdapter_NTuple::ReadFits() Non disponible !! " << endl;
+#else
+  FitsInFile fis(flnm);
+  fis >> (*mNt);
+#endif
+}
+
+/* --Methode-- */
+void NOMAdapter_NTuple::SaveFits(string const & flnm)
+{
+#ifdef SANS_EVOLPLANCK
+  cerr << " NOMAdapter_NTuple::SaveFits() Non disponible !! " << endl;
+#else
+  FitsOutFile fos(flnm);
+  fos << (*mNt);
+
+#endif
+}
+
+
+/* --Methode-- */
+void NOMAdapter_NTuple::SavePPF(POutPersist& pos, string const & nom)
+{
+#ifdef SANS_EVOLPLANCK
+// PEIDA-EROS L'histo est lui-meme PPersist
+string tag = nom;  // A cause de const
+mNt->Write(pos,0,tag);
+#else
+ObjFileIO<NTuple> fio(mNt);
+fio.Write(pos, nom);
+#endif
+}
+
+/* --Methode-- */
+void NOMAdapter_NTuple::Print(ostream& os)
+{
+os << mNt->Info();
+os << *(mNt);
+}
+
+
+/* --Methode-- */
+NTupleInterface* NOMAdapter_NTuple::GetNTupleInterface(bool& adel)
+{
+adel = false;
+return(mNt);
+// return( new NTupInt_NTuple(mNt) );
+}
+
+//-------------------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet XNTuple
+//-------------------------------------------------------------------------
+
+/* --Methode-- */
+NOMAdapter_XNTuple::NOMAdapter_XNTuple(XNTuple* o)
+  : NObjMgrAdapter(o)
+{
+mNt = o;
+}
+
+/* --Methode-- */
+NOMAdapter_XNTuple::~NOMAdapter_XNTuple()
+{
+}
+
+/* --Methode-- */
+NObjMgrAdapter* NOMAdapter_XNTuple::Clone(AnyDataObj* o)
+{
+XNTuple* nt = dynamic_cast<XNTuple *>(o);
+if (nt) return ( new NOMAdapter_XNTuple(nt) );
+return ( new NObjMgrAdapter(o) );
+}
+
+/* --Methode-- */
+string NOMAdapter_XNTuple::GetDataObjType()
+{
+return ("XNTuple ");
+}
+
+/* --Methode-- */
+AnyDataObj* NOMAdapter_XNTuple::CloneDataObj(bool /*share*/)
+{
+return ( new XNTuple(*mNt) );
+}
+
+/* --Methode-- */
+void NOMAdapter_XNTuple::ReadFits(string const & flnm)
+{
+#ifdef SANS_EVOLPLANCK
+  cerr << " NOMAdapter_XNTuple::ReadFits() Non disponible !! " << endl;
+#else
+  FitsInFile fis(flnm);
+  fis >> (*mNt);
+#endif
+}
+
+/* --Methode-- */
+void NOMAdapter_XNTuple::SaveFits(string const & flnm)
+{
+#ifdef SANS_EVOLPLANCK
+  cerr << " NOMAdapter_XNTuple::SaveFits() Non disponible !! " << endl;
+#else
+  FitsOutFile fos(flnm);
+  fos << (*mNt);
+
+#endif
+}
+
+/* --Methode-- */
+void NOMAdapter_XNTuple::SavePPF(POutPersist& pos, string const & nom)
+{
+#ifdef SANS_EVOLPLANCK
+// PEIDA-EROS L'histo est lui-meme PPersist
+string tag = nom;  // A cause de const
+mNt->Write(pos,0,tag);
+#else
+ObjFileIO<XNTuple> fio(mNt);
+fio.Write(pos, nom);
+#endif
+}
+
+/* --Methode-- */
+void NOMAdapter_XNTuple::Print(ostream& os)
+{
+// os << mNt->Info();
+mNt->Show(os);
+}
+
+
+/* --Methode-- */
+NTupleInterface* NOMAdapter_XNTuple::GetNTupleInterface(bool& adel)
+{
+adel = false;
+return(mNt);
+}
Index: /tags/V_Dec2002/SophyaPI/PIext/nomhistadapter.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/nomhistadapter.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/nomhistadapter.h	(revision 2309)
@@ -0,0 +1,168 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Adaptateur d objets (pour NamedObjMgr) pour Histos/NTuple
+//                                    Reza 05/99
+//  LAL-IN2P3/CNRS               CEA-DAPNIA     
+ 
+#ifndef NOMHISTADAPTER_H_SEEN
+#define NOMHISTADAPTER_H_SEEN
+
+#include "nomgadapter.h"
+#include "histos.h"
+#include "histos2.h"
+#include "hisprof.h"
+#include "ntuple.h"
+#include "xntuple.h"
+
+//-------------------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet Histo / HProf
+//-------------------------------------------------------------------------
+
+class NOMAdapter_Histo : public NObjMgrAdapter {
+public:
+				NOMAdapter_Histo(Histo* h = NULL);
+  virtual			~NOMAdapter_Histo();
+
+  virtual NObjMgrAdapter*	Clone(AnyDataObj* o);
+
+  virtual string		GetDataObjType();
+
+  virtual AnyDataObj*		CloneDataObj(bool share=false);
+
+  //  virtual void			ReadFits(string const & flnm);
+  //  virtual void			SaveFits(string const & flnm);
+  virtual void			SavePPF(POutPersist& s, string const & nom);
+
+  virtual void			Print(ostream& os);
+  virtual PIDrawer*		GetDrawer(string& dopt);
+  virtual NTupleInterface*	GetNTupleInterface(bool& adel);
+
+  virtual GeneralFitData* GetGeneralFitData(bool& adel
+          ,GeneralFitData::FitErrType errtype=GeneralFitData::DefaultError
+          ,double errscale=1.,double errmin=0.
+          ,int i1=0,int i2=-1,int j1=0,int j2=-1);
+  virtual AnyDataObj* FitResidusObj(GeneralFit& mfit);
+  virtual AnyDataObj* FitFunctionObj(GeneralFit& mfit);
+
+protected:
+  Histo* mHis;
+};
+
+// Class Interface NTuple pour Histo / HProf
+class NTupInt_Histo : public NTupleInterface {
+public:
+			NTupInt_Histo(Histo* h);
+  virtual		~NTupInt_Histo();
+  virtual uint_4        NbLines() const ;
+  virtual uint_4        NbColumns() const ;
+  virtual r_8 *         GetLineD(int n) const ;
+  virtual string        VarList_C(const char* nomx=NULL) const ;
+protected:
+  Histo* mHis;
+  mutable r_8 mRet[4];
+};
+
+//-------------------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet Histo2D
+//-------------------------------------------------------------------------
+
+class NOMAdapter_Histo2D : public NObjMgrAdapter {
+public:
+				NOMAdapter_Histo2D(Histo2D* h = NULL);
+  virtual			~NOMAdapter_Histo2D();
+
+  virtual NObjMgrAdapter*	Clone(AnyDataObj* o);
+
+  virtual string		GetDataObjType();
+
+  virtual AnyDataObj*		CloneDataObj(bool share=false);
+
+  //  virtual void			ReadFits(string const & flnm);
+  //  virtual void			SaveFits(string const & flnm);
+  virtual void			SavePPF(POutPersist& s, string const & nom);
+
+  virtual void			Print(ostream& os);
+  virtual PIDrawer*		GetDrawer(string& dopt);
+  virtual P2DArrayAdapter*      Get2DArray(string& dopt);
+  virtual NTupleInterface*	GetNTupleInterface(bool& adel);
+
+  virtual GeneralFitData* GetGeneralFitData(bool& adel
+          ,GeneralFitData::FitErrType errtype=GeneralFitData::DefaultError
+          ,double errscale=1.,double errmin=0.
+          ,int i1=0,int i2=-1,int j1=0,int j2=-1);
+  virtual AnyDataObj* FitResidusObj(GeneralFit& mfit);
+  virtual AnyDataObj* FitFunctionObj(GeneralFit& mfit);
+
+protected:
+  Histo2D* mHis;
+};
+
+// Class Interface NTuple pour Histo2D
+class NTupInt_Histo2D : public NTupleInterface {
+public:
+			NTupInt_Histo2D(Histo2D* h);
+  virtual		~NTupInt_Histo2D();
+  virtual uint_4        NbLines() const ;
+  virtual uint_4        NbColumns() const ;
+  virtual r_8 *         GetLineD(int n) const ;
+  virtual string        VarList_C(const char* nomx=NULL) const ;
+protected:
+  Histo2D* mHis;
+  mutable r_8 mRet[6];
+};
+
+
+//-------------------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet NTuple 
+//-------------------------------------------------------------------------
+
+class NOMAdapter_NTuple : public NObjMgrAdapter {
+public:
+				NOMAdapter_NTuple(NTuple* nt = NULL);
+  virtual			~NOMAdapter_NTuple();
+
+  virtual NObjMgrAdapter*	Clone(AnyDataObj* o);
+
+  virtual string		GetDataObjType();
+
+  virtual AnyDataObj*		CloneDataObj(bool share=false);
+
+  virtual void			ReadFits(string const & flnm);
+  virtual void			SaveFits(string const & flnm);
+  virtual void			SavePPF(POutPersist& s, string const & nom);
+
+  virtual void			Print(ostream& os);
+  virtual NTupleInterface*	GetNTupleInterface(bool& adel);
+
+protected:
+  NTuple* mNt;
+};
+
+//-------------------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet XNTuple 
+//-------------------------------------------------------------------------
+
+class NOMAdapter_XNTuple : public NObjMgrAdapter {
+public:
+				NOMAdapter_XNTuple(XNTuple* nt = NULL);
+  virtual			~NOMAdapter_XNTuple();
+
+  virtual NObjMgrAdapter*	Clone(AnyDataObj* o);
+
+  virtual string		GetDataObjType();
+
+  virtual AnyDataObj*		CloneDataObj(bool share=false);
+
+  virtual void			ReadFits(string const & flnm);
+  virtual void			SaveFits(string const & flnm);
+  virtual void			SavePPF(POutPersist& s, string const & nom);
+
+  virtual void			Print(ostream& os);
+  virtual NTupleInterface*	GetNTupleInterface(bool& adel);
+
+protected:
+  XNTuple* mNt;
+};
+
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/nomimagadapter.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/nomimagadapter.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/nomimagadapter.cc	(revision 2309)
@@ -0,0 +1,290 @@
+#include "machdefs.h"
+#include <stdlib.h>
+#include <typeinfo>
+#include <iostream.h>
+#include <string>
+
+#include "datatype.h"
+
+#include "nomimagadapter.h"
+#include "pimgadapter.h"
+
+#ifdef SANS_EVOLPLANCK
+#include "fitsimage.h"
+#else
+#include "objfitter.h"
+#include "fitstarray.h"
+#endif
+
+
+
+//---------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet Image<T> 
+//---------------------------------------------------------------
+
+
+/* --Methode-- */
+template <class T>
+NOMAdapter_Image<T>::NOMAdapter_Image(Image<T> * o)
+  : NObjMgrAdapter(o)
+{
+mImg = o;
+}
+
+/* --Methode-- */
+template <class T>
+NOMAdapter_Image<T>::~NOMAdapter_Image()
+{
+}
+
+/* --Methode-- */
+template <class T>
+NObjMgrAdapter* NOMAdapter_Image<T>::Clone(AnyDataObj* o)
+{
+Image<T>* im = dynamic_cast<Image<T> *>(o);
+if (im) return ( new NOMAdapter_Image<T>(im) );
+return ( new NObjMgrAdapter(o) );
+}
+
+/* --Methode-- */
+template <class T> 
+string NOMAdapter_Image<T>::GetDataObjType()
+{
+string type = "Image< ";
+// type +=  DecodeTypeIdName(typeid(T).name());
+type += DataTypeInfo<T>::getTypeName();
+type +=  " > ";
+return(type);
+}
+
+/* --Methode-- */
+template <class T>
+AnyDataObj* NOMAdapter_Image<T>::CloneDataObj(bool share)
+{
+#ifdef SANS_EVOLPLANCK
+FitsImage<T> * fima = dynamic_cast<FitsImage<T> *>(mImg);
+if (fima == NULL)   return( new Image<T>(*mImg ) );
+else return ( new FitsImage<T>(*fima) );
+#else
+return( new Image<T>(*mImg, share) );
+#endif
+}
+
+/* --Methode-- */
+template <class T>
+void NOMAdapter_Image<T>::ReadFits(string const & flnm)
+{
+#ifdef SANS_EVOLPLANCK
+  cerr << " NOMAdapter_Image<T>::ReadFits() Non disponible !! " << endl;
+#else
+  FitsInFile fis(flnm);
+  fis >> (*mImg);
+#endif
+}
+
+/* --Methode-- */
+template <class T>
+void NOMAdapter_Image<T>::SaveFits(string const & flnm)
+{
+#ifdef SANS_EVOLPLANCK
+FitsImage<T> fim(*mImg, 1);
+fim.Save(flnm);
+#else
+  FitsOutFile fos(flnm);
+  fos << (*mImg);
+#endif
+}
+
+#ifndef SANS_EVOLPLANCK
+void NOMAdapter_Image< uint_2 >::SaveFits(string const & flnm)
+{
+cout << " NOMAdapter_Image< uint_2 >::SaveFits() - Error " 
+     << " Not supported uint_2 data type ! " << endl;
+}
+
+void NOMAdapter_Image< uint_2 >::ReadFits(string const & flnm)
+{
+cout << " NOMAdapter_Image< uint_2 >::ReadFits() - Error " 
+     << " Not supported uint_2 data type ! " << endl;
+}
+#endif
+
+/* --Methode-- */
+template <class T>
+void NOMAdapter_Image<T>::SavePPF(POutPersist& pos, string const & nom)
+{
+#ifdef SANS_EVOLPLANCK
+// PEIDA-EROS L'histo est lui-meme PPersist
+string tag = nom;  // A cause de const
+mImg->Write(pos,0,tag);
+#else
+string s = typeid(*mObj).name();
+cout << "NOMAdapter_Image<T>::SavePPF() - Error : Not supported for " << s << endl;
+#endif
+}
+
+/* --Methode-- */
+template <class T>
+void NOMAdapter_Image<T>::Print(ostream& os)
+{
+mImg->Print(os);
+}
+
+
+/* --Methode-- */
+template <class T>
+P2DArrayAdapter* NOMAdapter_Image<T>::Get2DArray(string &)
+{
+return ( new ImageAdapter<T>(mImg, false) );
+}
+
+/* --Methode-- */
+template <class T>
+NTupleInterface* NOMAdapter_Image<T>::GetNTupleInterface(bool& adel)
+{
+adel = true;
+return( new NTupInt_Image<T>(mImg) );
+}
+
+/* --Methode-- */
+template <class T>
+GeneralFitData* NOMAdapter_Image<T>::GetGeneralFitData(bool& adel
+ ,GeneralFitData::FitErrType errtype,double errscale,double errmin
+ ,int i1,int i2,int j1,int j2)
+{
+adel = false;
+if(!mImg) return(NULL);
+
+int nx = mImg->XSize();
+int ny = mImg->YSize();
+if(nx<=0 || ny<=0) return(NULL);
+
+i1 = (i1<0||i1>=nx)? 0: i1;
+i2 = (i2<0||i2>=nx||i2<i1)? nx-1: i2;
+j1 = (j1<0||j1>=ny)? 0: j1;
+j2 = (j2<0||j2>=ny||j2<j1)? ny-1: j2;
+
+GeneralFitData* mGData = new GeneralFitData(2,(i2-i1+1)*(j2-j1+1),0);
+adel = true;
+
+for(int i=i1;i<=i2;i++) for(int j=j1;j<=j2;j++) {
+  double x = mImg->XPos(i);
+  double y = mImg->YPos(j);
+  double f = (*mImg)(i,j);
+  double e = 1.;
+  e = GeneralFitData::ComputeError(f,e,errtype,errscale,errmin);
+  mGData->AddData2(x,y,f,e);
+}
+
+return mGData;
+}
+
+template <class T>
+AnyDataObj* NOMAdapter_Image<T>::FitResidusObj(GeneralFit& mfit)
+{
+#ifdef SANS_EVOLPLANCK
+RzImage* rzim = mImg->FitResidus(mfit);  
+ImageR4* im   = new ImageR4(*rzim);
+return im;
+#else
+Image<T>* im = new Image<T>(ObjectFitter::FitResidus(*mImg,mfit));
+return im;
+#endif
+}
+
+template <class T>
+AnyDataObj* NOMAdapter_Image<T>::FitFunctionObj(GeneralFit& mfit)
+{
+#ifdef SANS_EVOLPLANCK
+RzImage* rzim = mImg->FitFunction(mfit);  
+ImageR4* im   = new ImageR4(*rzim);
+return im;
+#else
+Image<T>* im = NULL;
+//im = new Image<T>(ObjectFitter::FitFunction(*mImg,mfit));
+return im;
+#endif
+}
+
+
+// -------------------------------------------------------------
+
+/* --Methode-- */
+template <class T>
+NTupInt_Image<T>::NTupInt_Image(Image<T>* m)
+{
+mImg = m;
+}
+
+/* --Methode-- */
+template <class T>
+NTupInt_Image<T>::~NTupInt_Image()
+{
+}
+
+/* --Methode-- */
+template <class T>
+uint_4 NTupInt_Image<T>::NbLines() const 
+{
+return( mImg->XSize() * mImg->YSize() );
+}
+
+/* --Methode-- */
+template <class T>
+uint_4 NTupInt_Image<T>::NbColumns() const 
+{
+return(3);
+}
+
+/* --Methode-- */
+template <class T>
+r_8* NTupInt_Image<T>::GetLineD(int n) const 
+{
+int i,j;
+if ((n < 0) || (n >= mImg->XSize() * mImg->YSize() )) 
+    for(i=0; i<3; i++)  mRet[i] = 0.;
+else { 
+  i = n%mImg->XSize();  j = n/mImg->XSize(); 
+  mRet[0] = i;  mRet[1] = j;  mRet[2] = (*mImg)(i,j);
+  }
+return(mRet);
+}
+
+/* --Methode-- */
+template <class T>
+string NTupInt_Image<T>::VarList_C(const char* nx) const 
+{
+string nomx;
+if (nx) nomx = nx;
+else nomx = "_xh_";
+string vardec = "double x,y,pix,i,j,val; \n";
+vardec += "x = i = " + nomx + "[0]; y = j = " + nomx + "[1];  pix = val = " + nomx + "[2]; \n";
+return(vardec);
+}
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template NOMAdapter_Image<uint_2>
+#pragma define_template NOMAdapter_Image<int_4>
+#pragma define_template NOMAdapter_Image<r_4>
+#pragma define_template NTupInt_Image<uint_2>
+#pragma define_template NTupInt_Image<int_4>
+#pragma define_template NTupInt_Image<r_4>
+#ifdef SANS_EVOLPLANCK
+#pragma define_template NOMAdapter_Image<int_2>
+#pragma define_template NTupInt_Image<int_2>
+#endif
+#endif
+#if defined(ANSI_TEMPLATES) || defined(__ANSI_TEMPLATES__) || defined(__GNU_TEMPLATES__) 
+template class NOMAdapter_Image<uint_2>;
+template class NOMAdapter_Image<int_4>;
+template class NOMAdapter_Image<r_4>;
+template class NTupInt_Image<uint_2>;
+template class NTupInt_Image<int_4>;
+template class NTupInt_Image<r_4>;
+#ifdef SANS_EVOLPLANCK
+template class NOMAdapter_Image<int_2>;
+template class NTupInt_Image<int_2>;
+#endif
+#endif
+
+
Index: /tags/V_Dec2002/SophyaPI/PIext/nomimagadapter.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/nomimagadapter.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/nomimagadapter.h	(revision 2309)
@@ -0,0 +1,65 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Adaptateur d objets (pour NamedObjMgr) pour Histos/NTuple
+//                                    Reza 05/99
+//  LAL-IN2P3/CNRS               CEA-DAPNIA     
+ 
+#ifndef NOMIMAGADAPTER_H_SEEN
+#define NOMIMAGADAPTER_H_SEEN
+
+#include "nomgadapter.h"
+#include "cimage.h"
+#include "generalfit.h"
+
+
+
+//---------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet  Image<T> 
+//---------------------------------------------------------------
+
+template <class T>
+class NOMAdapter_Image : public NObjMgrAdapter {
+public:
+				NOMAdapter_Image(Image<T> * o = NULL);
+  virtual			~NOMAdapter_Image();
+
+  virtual NObjMgrAdapter*	Clone(AnyDataObj* o);
+  virtual string		GetDataObjType();
+  virtual AnyDataObj*		CloneDataObj(bool share=false);
+
+  virtual void			ReadFits(string const & flnm);
+  virtual void			SaveFits(string const & flnm);
+  virtual void			SavePPF(POutPersist& s, string const & nom);
+
+  virtual void			Print(ostream& os);
+  virtual P2DArrayAdapter*	Get2DArray(string& dopt);
+  virtual NTupleInterface*	GetNTupleInterface(bool& adel);
+
+  virtual GeneralFitData* GetGeneralFitData(bool& adel
+          ,GeneralFitData::FitErrType errtype=GeneralFitData::DefaultError
+          ,double errscale=1.,double errmin=1.
+          ,int i1=0,int i2=-1,int j1=0,int j2=-1);
+  virtual AnyDataObj* FitResidusObj(GeneralFit& mfit);
+  virtual AnyDataObj* FitFunctionObj(GeneralFit& mfit);
+
+protected:
+  Image<T> * mImg;
+};
+
+// Class Interface NTuple pour Image
+
+template <class T>
+class NTupInt_Image : public NTupleInterface {
+public:
+			NTupInt_Image(Image<T> * m);
+  virtual		~NTupInt_Image();
+  virtual uint_4        NbLines() const ;
+  virtual uint_4        NbColumns() const ;
+  virtual r_8 *         GetLineD(int n) const ;
+  virtual string        VarList_C(const char* nomx=NULL) const ;
+protected:
+  Image<T> * mImg;
+  mutable r_8 mRet[3];
+};
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/nommatvecadapter.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/nommatvecadapter.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/nommatvecadapter.cc	(revision 2309)
@@ -0,0 +1,336 @@
+#include "machdefs.h"
+#include <stdlib.h>
+#include <typeinfo>
+#include <iostream.h>
+#include <string>
+
+#include "nommatvecadapter.h"
+#include "piyfxdrw.h"
+#include "pipodrw.h"
+
+//---------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet Vector 
+//---------------------------------------------------------------
+
+/* --Methode-- */
+NOMAdapter_Vector::NOMAdapter_Vector(Vector* o)
+  : NObjMgrAdapter(o)
+{
+mVec = o;
+}
+
+/* --Methode-- */
+NOMAdapter_Vector::~NOMAdapter_Vector()
+{
+}
+
+/* --Methode-- */
+NObjMgrAdapter* NOMAdapter_Vector::Clone(AnyDataObj* o)
+{
+Vector* v = dynamic_cast<Vector *>(o);
+if (v) return ( new NOMAdapter_Vector(v) );
+return ( new NObjMgrAdapter(o) );
+}
+
+/* --Methode-- */
+string NOMAdapter_Vector::GetDataObjType()
+{
+  return("Vector ");
+}
+
+/* --Methode-- */
+AnyDataObj* NOMAdapter_Vector::CloneDataObj(bool /*share*/)
+{
+return ( new Vector(*mVec) );
+}
+
+
+/* --Methode-- */
+void NOMAdapter_Vector::SavePPF(POutPersist& pos, string const & nom)
+{
+#ifdef SANS_EVOLPLANCK
+// PEIDA-EROS L'histo est lui-meme PPersist
+string tag = nom;  // A cause de const
+mVec->Write(pos,0,tag);
+#else
+string s = typeid(*mObj).name();
+cout << "NOMAdapter_Vector::SavePPF() - Error : Not supported for " << s << endl;
+#endif
+}
+
+/* --Methode-- */
+void NOMAdapter_Vector::Print(ostream& os)
+{
+os << (*mVec);
+}
+
+/* --Methode-- */
+PIDrawer* NOMAdapter_Vector::GetDrawer(string & dopt)
+{
+dopt = "thinline " + dopt;
+return( new PIYfXDrawer( new POVectorAdapter(mVec, false), NULL, true) );
+}
+
+/* --Methode-- */
+NTupleInterface* NOMAdapter_Vector::GetNTupleInterface(bool& adel)
+{
+adel = true;
+return( new NTupInt_Vector(mVec) );
+}
+
+
+/* --Methode-- */
+GeneralFitData* NOMAdapter_Vector::GetGeneralFitData(bool& adel
+ ,GeneralFitData::FitErrType errtype,double errscale,double errmin
+ ,int i1,int i2,int j1,int j2)
+{
+adel = false;
+if(!mVec) return(NULL);
+
+int n = mVec->NElts();
+if(n<=0) return(NULL);
+
+i1 = (i1<0||i1>=n)? 0: i1;
+i2 = (i2<0||i2>=n||i2<i1)? n-1: i2;
+
+GeneralFitData* mGData = new GeneralFitData(1,i2-i1+1,0);
+adel = true;
+
+for(int i=i1;i<=i2;i++) {
+  double x = (double) i;
+  double f = (*mVec)(i);
+  double e = 1.;
+  e = GeneralFitData::ComputeError(f,e,errtype,errscale,errmin);
+  mGData->AddData1(x,f,e);
+}
+
+return mGData;
+}
+
+AnyDataObj* NOMAdapter_Vector::FitResidusObj(GeneralFit& mfit)
+{
+Vector* v = NULL;
+v = mVec->FitResidus(mfit); 
+return v;
+}
+
+AnyDataObj* NOMAdapter_Vector::FitFunctionObj(GeneralFit& mfit)
+{
+Vector* v = NULL;
+v = mVec->FitFunction(mfit); 
+return v;
+}
+
+// -------------------------------------------------------------
+
+/* --Methode-- */
+NTupInt_Vector::NTupInt_Vector(Vector* v)
+{
+mVec = v;
+}
+
+/* --Methode-- */
+NTupInt_Vector::~NTupInt_Vector()
+{
+}
+
+/* --Methode-- */
+uint_4 NTupInt_Vector::NbLines() const
+{
+return(mVec->NElts());
+}
+
+/* --Methode-- */
+uint_4 NTupInt_Vector::NbColumns() const 
+{
+return(2);
+}
+
+/* --Methode-- */
+r_8* NTupInt_Vector::GetLineD(int n) const 
+{
+int i;
+if ((n < 0) || (n >= mVec->NElts() )) 
+    for(i=0; i<2; i++)  mRet[i] = 0.;
+else { 
+  mRet[0] = n;  mRet[1] = (*mVec)(n);
+  }
+return(mRet);
+}
+
+/* --Methode-- */
+string NTupInt_Vector::VarList_C(const char* nx) const 
+{
+string nomx;
+if (nx) nomx = nx;
+else nomx = "_xh_";
+string vardec = "double i,val; \n";
+vardec += "i = " + nomx + "[0];  val = " + nomx + "[1]; \n";
+return(vardec);
+}
+
+
+//---------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet Matrix 
+//---------------------------------------------------------------
+
+
+/* --Methode-- */
+NOMAdapter_Matrix::NOMAdapter_Matrix(Matrix* o)
+  : NObjMgrAdapter(o)
+{
+mMtx = o;
+}
+
+/* --Methode-- */
+NOMAdapter_Matrix::~NOMAdapter_Matrix()
+{
+}
+
+/* --Methode-- */
+NObjMgrAdapter* NOMAdapter_Matrix::Clone(AnyDataObj* o)
+{
+Matrix* m = dynamic_cast<Matrix *>(o);
+if (m) return ( new NOMAdapter_Matrix(m) );
+return ( new NObjMgrAdapter(o) );
+}
+
+/* --Methode-- */
+string NOMAdapter_Matrix::GetDataObjType()
+{
+  return("Matrix ");
+}
+
+/* --Methode-- */
+AnyDataObj* NOMAdapter_Matrix::CloneDataObj(bool /*share*/)
+{
+return ( new Matrix(*mMtx) );
+}
+
+/* --Methode-- */
+void NOMAdapter_Matrix::SavePPF(POutPersist& pos, string const & nom)
+{
+#ifdef SANS_EVOLPLANCK
+// PEIDA-EROS L'histo est lui-meme PPersist
+string tag = nom;  // A cause de const
+mMtx->Write(pos,0,tag);
+#else
+string s = typeid(*mObj).name();
+cout << "NOMAdapter_Matrix::SavePPF() - Error : Not supported for " << s << endl;
+#endif
+}
+
+/* --Methode-- */
+void NOMAdapter_Matrix::Print(ostream& os)
+{
+os << (*mMtx);
+}
+
+
+/* --Methode-- */
+P2DArrayAdapter* NOMAdapter_Matrix::Get2DArray(string &)
+{
+return ( new POMatrixAdapter(mMtx, false) );
+}
+
+/* --Methode-- */
+NTupleInterface* NOMAdapter_Matrix::GetNTupleInterface(bool& adel)
+{
+adel = true;
+return( new NTupInt_Matrix(mMtx) );
+}
+
+/* --Methode-- */
+GeneralFitData* NOMAdapter_Matrix::GetGeneralFitData(bool& adel
+ ,GeneralFitData::FitErrType errtype,double errscale,double errmin
+ ,int i1,int i2,int j1,int j2)
+{
+adel = false;
+if(!mMtx) return(NULL);
+
+int nx = mMtx->NRows();
+int ny = mMtx->NCol();
+if(nx<=0 || ny<=0) return(NULL);
+
+i1 = (i1<0||i1>=nx)? 0: i1;
+i2 = (i2<0||i2>=nx||i2<i1)? nx-1: i2;
+j1 = (j1<0||j1>=ny)? 0: j1;
+j2 = (j2<0||j2>=ny||j2<j1)? ny-1: j2;
+
+GeneralFitData* mGData = new GeneralFitData(2,(i2-i1+1)*(j2-j1+1),0);
+adel = true;
+
+for(int i=i1;i<=i2;i++) for(int j=j1;j<=j2;j++) {
+  double x = (double) i;
+  double y = (double) j;
+  double f = (*mMtx)(i,j);
+  double e = 1.;
+  e = GeneralFitData::ComputeError(f,e,errtype,errscale,errmin);
+  mGData->AddData2(x,y,f,e);
+}
+
+return mGData;
+}
+
+AnyDataObj* NOMAdapter_Matrix::FitResidusObj(GeneralFit& mfit)
+{
+Matrix* m = NULL;
+m = mMtx->FitResidus(mfit); 
+return m;
+}
+
+AnyDataObj* NOMAdapter_Matrix::FitFunctionObj(GeneralFit& mfit)
+{
+Matrix* m = NULL;
+m = mMtx->FitFunction(mfit); 
+return m;
+}
+
+// -------------------------------------------------------------
+
+/* --Methode-- */
+NTupInt_Matrix::NTupInt_Matrix(Matrix* m)
+{
+mMtx = m;
+}
+
+/* --Methode-- */
+NTupInt_Matrix::~NTupInt_Matrix()
+{
+}
+
+/* --Methode-- */
+uint_4 NTupInt_Matrix::NbLines() const
+{
+return( mMtx->NRows()*mMtx->NCol() );
+}
+
+/* --Methode-- */
+uint_4 NTupInt_Matrix::NbColumns() const 
+{
+return(3);
+}
+
+/* --Methode-- */
+r_8* NTupInt_Matrix::GetLineD(int n) const 
+{
+int i,j;
+if ((n < 0) || (n >= mMtx->NRows()*mMtx->NCol() )) 
+    for(i=0; i<3; i++)  mRet[i] = 0.;
+else { 
+  i = n/mMtx->NCol(); j = n%mMtx->NCol(); 
+  mRet[0] = i;  mRet[1] = j;  mRet[2] = (*mMtx)(i,j);
+  }
+return(mRet);
+}
+
+/* --Methode-- */
+string NTupInt_Matrix::VarList_C(const char* nx) const 
+{
+string nomx;
+if (nx) nomx = nx;
+else nomx = "_xh_";
+string vardec = "double i,j,val; \n";
+vardec += "i = " + nomx + "[0]; j = " + nomx + "[1];  val = " + nomx + "[2]; \n";
+return(vardec);
+}
Index: /tags/V_Dec2002/SophyaPI/PIext/nommatvecadapter.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/nommatvecadapter.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/nommatvecadapter.h	(revision 2309)
@@ -0,0 +1,120 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Adaptateur d objets (pour NamedObjMgr) pour Histos/NTuple
+//                                    Reza 05/99
+//  LAL-IN2P3/CNRS               CEA-DAPNIA     
+ 
+#ifndef NOMMATVECADAPTER_H_SEEN
+#define NOMMATVECADAPTER_H_SEEN
+
+#include "nomgadapter.h"
+#include "generalfit.h"
+
+#ifdef SANS_EVOLPLANCK
+#include "matrix.h"
+#include "cvector.h"
+#else
+#include "tmatrix.h"
+#include "tvector.h"
+#endif
+
+//---------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet Vector 
+//---------------------------------------------------------------
+
+class NOMAdapter_Vector : public NObjMgrAdapter {
+public:
+				NOMAdapter_Vector(Vector* v = NULL);
+  virtual			~NOMAdapter_Vector();
+
+  virtual NObjMgrAdapter*	Clone(AnyDataObj* o);
+
+  virtual string		GetDataObjType();
+
+  virtual AnyDataObj*		CloneDataObj(bool share=false);
+
+  //  virtual void			ReadFits(string const & flnm);
+  //  virtual void			SaveFits(string const & flnm);
+  virtual void			SavePPF(POutPersist& s, string const & nom);
+
+  virtual void			Print(ostream& os);
+  virtual PIDrawer*		GetDrawer(string& dopt);
+  virtual NTupleInterface*	GetNTupleInterface(bool& adel);
+
+  virtual GeneralFitData* GetGeneralFitData(bool& adel
+          ,GeneralFitData::FitErrType errtype=GeneralFitData::DefaultError
+          ,double errscale=1.,double errmin=0.
+          ,int i1=0,int i2=-1,int j1=0,int j2=-1);
+  virtual AnyDataObj* FitResidusObj(GeneralFit& mfit);
+  virtual AnyDataObj* FitFunctionObj(GeneralFit& mfit);
+
+protected:
+  Vector* mVec;
+};
+
+// Class Interface NTuple pour Vector
+class NTupInt_Vector : public NTupleInterface {
+public:
+			NTupInt_Vector(Vector* v);
+  virtual		~NTupInt_Vector();
+  virtual uint_4        NbLines() const ;
+  virtual uint_4        NbColumns() const ;
+  virtual r_8 *         GetLineD(int n) const ;
+  virtual string        VarList_C(const char* nomx=NULL) const ;
+protected:
+  Vector* mVec;
+  mutable r_8 mRet[2];
+};
+
+
+
+//---------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet Matrix 
+//---------------------------------------------------------------
+
+class NOMAdapter_Matrix : public NObjMgrAdapter {
+public:
+				NOMAdapter_Matrix(Matrix* m = NULL);
+  virtual			~NOMAdapter_Matrix();
+
+  virtual NObjMgrAdapter*	Clone(AnyDataObj* o);
+
+  virtual string		GetDataObjType();
+
+  virtual AnyDataObj*		CloneDataObj(bool share=false);
+
+  //  virtual void			ReadFits(string const & flnm);
+  //  virtual void			SaveFits(string const & flnm);
+  virtual void			SavePPF(POutPersist& s, string const & nom);
+
+  virtual void			Print(ostream& os);
+  virtual P2DArrayAdapter*	Get2DArray(string& dopt);
+  virtual NTupleInterface*	GetNTupleInterface(bool& adel);
+
+  virtual GeneralFitData* GetGeneralFitData(bool& adel
+          ,GeneralFitData::FitErrType errtype=GeneralFitData::DefaultError
+          ,double errscale=1.,double errmin=0.
+          ,int i1=0,int i2=-1,int j1=0,int j2=-1);
+  virtual AnyDataObj* FitResidusObj(GeneralFit& mfit);
+  virtual AnyDataObj* FitFunctionObj(GeneralFit& mfit);
+
+protected:
+  Matrix* mMtx;
+};
+
+// Class Interface NTuple pour Matrix
+
+class NTupInt_Matrix : public NTupleInterface {
+public:
+			NTupInt_Matrix(Matrix* m);
+  virtual		~NTupInt_Matrix();
+  virtual uint_4        NbLines() const ;
+  virtual uint_4        NbColumns() const ;
+  virtual r_8 *         GetLineD(int n) const ;
+  virtual string        VarList_C(const char* nomx=NULL) const ;
+protected:
+  Matrix* mMtx;
+  mutable r_8 mRet[3];
+};
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/nomskymapadapter.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/nomskymapadapter.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/nomskymapadapter.cc	(revision 2309)
@@ -0,0 +1,429 @@
+#include "machdefs.h"
+#include <stdlib.h>
+#include <math.h>
+#include <typeinfo>
+#include <iostream.h>
+#include <string>
+#include <complex>
+
+#include "datatype.h"
+
+#include "nomskymapadapter.h"
+#include "skymap.h"
+#include "pitvmaad.h"
+#include "complexios.h"
+
+#include "fitsspherehealpix.h"
+#include "fitslocalmap.h"
+
+
+//  Classe array adapter pour localMap
+template <class T> 
+class LocalMapArrAdapter : public P2DArrayAdapter {
+public:
+		LocalMapArrAdapter(LocalMap<T>* lm, bool d=false) :
+                    P2DArrayAdapter(lm->SizeX(), lm->SizeY())
+		    { ad = d; map = lm; }
+
+  virtual 	~LocalMapArrAdapter() { if (ad) delete map; }
+  virtual double  Value(int ix, int iy) { return((*map)(ix, iy)); }
+
+protected :
+  bool ad;
+  LocalMap<T>* map;
+};
+
+/* --Methode-- */
+double LocalMapArrAdapter< complex<float> >::Value(int ix, int iy) 
+{
+double re,im;
+re = (*map)(iy, ix).real();
+im = (*map)(iy, ix).imag();
+return(sqrt(re*re+im*im));
+}
+/* --Methode-- */
+double LocalMapArrAdapter< complex<double> >::Value(int ix, int iy) 
+{
+double re,im;
+re = (*map)(iy, ix).real();
+im = (*map)(iy, ix).imag();
+return(sqrt(re*re+im*im));
+}
+
+//----------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet PixelMap<T>
+//----------------------------------------------------------------
+
+
+/* --Methode-- */
+template <class T> 
+NOMAdapter_PixelMap<T>::NOMAdapter_PixelMap(PixelMap<T> * o)
+  : NObjMgrAdapter(o)
+{
+mMap = o;
+}
+
+/* --Methode-- */
+template <class T> 
+NOMAdapter_PixelMap<T>::~NOMAdapter_PixelMap()
+{
+}
+
+/* --Methode-- */
+template <class T> 
+NObjMgrAdapter* NOMAdapter_PixelMap<T>::Clone(AnyDataObj* o)
+{
+PixelMap<T>* m = dynamic_cast<PixelMap<T> *>(o);
+if (m) return ( new NOMAdapter_PixelMap<T>(m) );
+return ( new NObjMgrAdapter(o) );
+}
+
+/* --Methode-- */
+template <class T> 
+string NOMAdapter_PixelMap<T>::GetDataObjType()
+{
+string type = "PixelMap< ";
+LocalMap<T>* lm = dynamic_cast< LocalMap<T> * >(mMap); 
+if (lm != NULL) type = "LocalMap< ";
+SphereThetaPhi<T>* st = dynamic_cast< SphereThetaPhi<T> * >(mMap); 
+if (st != NULL) type = "SphereThetaPhi< ";
+SphereHEALPix<T>* sg = dynamic_cast< SphereHEALPix<T> * >(mMap); 
+if (sg != NULL) type = "SphereHEALPix< ";
+
+// type +=  DecodeTypeIdName(typeid(T).name());
+type += DataTypeInfo<T>::getTypeName();
+type +=  " > ";
+return(type);
+}
+
+/* --Methode-- */
+template <class T> 
+AnyDataObj* NOMAdapter_PixelMap<T>::CloneDataObj(bool share)
+{
+LocalMap<T>* lm = dynamic_cast< LocalMap<T> * >(mMap); 
+if (lm != NULL) return( new LocalMap<T>(*lm, share) );
+SphereThetaPhi<T>* st = dynamic_cast< SphereThetaPhi<T> * >(mMap); 
+if (st != NULL) return( new SphereThetaPhi<T>(*st, share) );
+SphereHEALPix<T>* sg = dynamic_cast< SphereHEALPix<T> * >(mMap); 
+if (sg != NULL) return( new SphereHEALPix<T>(*sg, share) );
+return(NULL);
+}
+
+/* --Methode-- */
+template <class T> 
+void NOMAdapter_PixelMap<T>::ReadFits(string const & flnm)
+{
+LocalMap<T>* lm = dynamic_cast< LocalMap<T> * >(mMap); 
+if (lm != NULL) {
+  FitsInFile fis(flnm);
+  fis >> (*lm);
+  return;
+}
+SphereHEALPix<T>* sg = dynamic_cast< SphereHEALPix<T> * >(mMap); 
+if (sg != NULL) {
+  FitsInFile fis(flnm);
+  fis >> (*sg);
+  return;
+}
+string s = typeid(*mMap).name();
+cout << " NOMAdapter_PixelMap<T>::ReadFits() - Error " 
+     << " Not supported for " << s << endl;
+return;
+}
+
+
+/* --Methode-- */
+template <class T> 
+void NOMAdapter_PixelMap<T>::SaveFits(string const & flnm)
+{
+LocalMap<T>* lm = dynamic_cast< LocalMap<T> * >(mMap); 
+if (lm != NULL) {
+  FitsOutFile fos(flnm);
+  fos << (*lm);
+  return;
+}
+SphereHEALPix<T>* sg = dynamic_cast< SphereHEALPix<T> * >(mMap); 
+if (sg != NULL) {
+  FitsOutFile fos(flnm);
+  fos << (*sg);
+  return;
+}
+string s = typeid(*mMap).name();
+cout << " NOMAdapter_PixelMap<T>::SaveFits() - Error " 
+     << " Not supported for " << s << endl;
+return;
+}
+
+// ---- Specialisation pour complexes -----
+void NOMAdapter_PixelMap< complex<r_4> >::ReadFits(string const & flnm)
+{
+cout << " void NOMAdapter_PixelMap< complex<r_4> >::ReadFits() - Error " 
+     << " Not supported (complex data type)" << endl;
+}
+void NOMAdapter_PixelMap< complex<r_4> >::SaveFits(string const & flnm)
+{
+cout << " void NOMAdapter_PixelMap< complex<r_4> >::SaveFits() - Error " 
+     << " Not supported (complex data type)" << endl;
+}
+void NOMAdapter_PixelMap< complex<r_8> >::ReadFits(string const & flnm)
+{
+cout << " void NOMAdapter_PixelMap< complex<r_4> >::ReadFits() - Error " 
+     << " Not supported (complex data type)" << endl;
+}
+void NOMAdapter_PixelMap< complex<r_8> >::SaveFits(string const & flnm)
+{
+cout << " void NOMAdapter_PixelMap< complex<r_8> >::SaveFits() - Error " 
+     << " Not supported (complex data type)" << endl;
+}
+
+
+/* --Methode-- */
+template <class T> 
+void NOMAdapter_PixelMap<T>::SavePPF(POutPersist& pos, string const & nom)
+{
+LocalMap<T>* lm = dynamic_cast< LocalMap<T> * >(mMap); 
+if (lm != NULL) {
+  FIO_LocalMap<T> fio(lm);
+  fio.Write(pos, nom);
+  return;
+  }
+SphereThetaPhi<T>* st = dynamic_cast< SphereThetaPhi<T> * >(mMap); 
+if (st != NULL) {
+  FIO_SphereThetaPhi<T> fio(st);
+  fio.Write(pos, nom);
+  return;
+  }
+SphereHEALPix<T>* sg = dynamic_cast< SphereHEALPix<T> * >(mMap); 
+if (sg != NULL) {
+  FIO_SphereHEALPix<T> fio(sg);
+  fio.Write(pos, nom);
+  return;
+  }
+string s = typeid(*mMap).name();
+cout << "NOMAdapter_PixelMap<T>::SavePPF() - Error : Not supported for " << s << endl;
+}
+
+/* --Methode-- */
+template <class T> 
+void NOMAdapter_PixelMap<T>::Print(ostream& os)
+{
+string s = typeid(*mMap).name();
+T moy, sig;
+MeanSig(moy, sig);
+cout << "SkyMap Type: " << s << " NbPixels= " << mMap->NbPixels() << endl;
+cout << "  Mean= " << moy << "  Sig2= " << sig << endl;
+}
+
+// -- Fonction pour convertir un X,Y en Theta-Phi sur projection MolleWeide --
+char * _SphMollweideProj_XY2ThetaPhi(P2DArrayAdapter * aa, int ix, int iy);
+
+/* --Methode-- */
+template <class T> 
+P2DArrayAdapter* NOMAdapter_PixelMap<T>::Get2DArray(string &)
+{
+LocalMap<T>* lm = dynamic_cast< LocalMap<T> * >(mMap); 
+if (lm != NULL) return(new LocalMapArrAdapter<T>(lm, false));
+int nr = 250;
+int nc = 500;
+SphericalMap<T>* sm = dynamic_cast< SphericalMap<T> *>(mMap);
+if (sm != NULL) { nr = sqrt(0.75*mMap->NbPixels());  nc = 2*nr; }
+TMatrix<T> * mtx = new TMatrix<T>(nr, nc);
+Project_Mol(*mtx);
+POTMatrixAdapter<T> * potma = new POTMatrixAdapter<T>(mtx, true);
+potma->SetInfoStringFunction(_SphMollweideProj_XY2ThetaPhi);
+return ( potma );
+}
+
+/* --Methode-- */
+template <class T> 
+NTupleInterface* NOMAdapter_PixelMap<T>::GetNTupleInterface(bool& adel)
+{
+adel = true;
+return( new NTupInt_PixelMap<T>(mMap) );
+}
+
+/* --Methode-- */
+template <class T> 
+void NOMAdapter_PixelMap<T>::MeanSig(T& gmoy, T& gsig)
+{
+  gmoy=0.;
+  gsig = 0.;
+  T valok;
+  for(int k=0; k<mMap->NbPixels(); k++) {
+    valok = (*mMap)(k);
+    gmoy += valok;  gsig += valok*valok;
+  }
+  gmoy /= (T)mMap->NbPixels();
+  gsig = gsig/(T)mMap->NbPixels() - gmoy*gmoy;
+
+}
+
+/* --Methode-- */
+template <class T> 
+void NOMAdapter_PixelMap<T>::Project_Mol(TMatrix<T> & mtx, T defval)
+{
+  r_8 xa, yd, teta,phi, facteur;
+  int_4 l,c,k;
+  int_4 nl = mtx.NRows();
+  int_4 nc = mtx.NCols();
+  mtx = defval;   // On met tout a defval
+//  cout << " NRows= " << nl << "  NCols= " << nc  << endl;
+  for(l=0; l<nl; l++) {
+    yd = (r_8)(l+0.5)/(r_8)nl-0.5;
+    facteur=2.*M_PI/sin(acos((double)yd*2));
+    teta = (yd+0.5)*Pi;
+    //    teta = (0.5-yd)*M_PI;
+    for(c=0; c<nc; c++)  {
+      xa = (r_8)(c+0.5)/(r_8)nc-0.5;  
+      phi = xa*facteur+M_PI;
+      if ( (phi <= 2*M_PI) && (phi >= 0.) ) {
+        k = mMap->PixIndexSph(teta, phi);
+        mtx(l,c) = (*mMap)(k);
+      }
+    }
+  }
+}
+
+static char m_buff[128];
+char * _SphMollweideProj_XY2ThetaPhi(P2DArrayAdapter * aa, int ix, int iy)
+{
+  r_8 xa, yd, teta,phi, facteur;
+  int_4 nl = aa->YSize();
+  int_4 nc = aa->XSize();
+  int l, c;
+  aa->IJ2xy(ix, iy, c, l);
+  yd = (r_8)(l+0.5)/(r_8)nl-0.5;
+  facteur=2.*M_PI/sin(acos((double)yd*2));
+  teta = (yd+0.5)*Pi;
+  xa = (r_8)(c+0.5)/(r_8)nc-0.5;  
+  phi = xa*facteur+M_PI;
+  if ( (phi <= 2*M_PI) && (phi >= 0.) ) 
+    sprintf(m_buff,"(l,b=%5.1f,%5.1f)", phi*180./M_PI, 90.-teta*180./M_PI);
+  else 
+    sprintf(m_buff,"(l,b=?,?)");
+
+  return (m_buff);
+}
+
+// -------------------------------------------------------------
+
+/* --Methode-- */
+template <class T> 
+NTupInt_PixelMap<T>::NTupInt_PixelMap(PixelMap<T>* m)
+{
+mMap = m;
+}
+
+/* --Methode-- */
+template <class T> 
+NTupInt_PixelMap<T>::~NTupInt_PixelMap()
+{
+}
+
+/* --Methode-- */
+template <class T> 
+uint_4 NTupInt_PixelMap<T>::NbLines() const
+{
+return( mMap->NbPixels() );
+}
+
+/* --Methode-- */
+template <class T> 
+uint_4 NTupInt_PixelMap<T>::NbColumns() const 
+{
+return(8);
+}
+
+/* --Methode-- */
+template <class T> 
+r_8* NTupInt_PixelMap<T>::GetLineD(int n) const 
+{
+int i;
+if ((n < 0) || (n >= (int)(mMap->NbPixels()) )) 
+    for(i=0; i<8; i++)  mRet[i] = 0.;
+else { 
+  double teta,phi;
+  mMap->PixThetaPhi(n, teta, phi);
+  mRet[0] = n;  mRet[1] = mMap->PixVal(n);
+  mRet[2] = mRet[1];  mRet[3] = 0.;
+  mRet[4] = mRet[1];  mRet[5] = 0.;
+  mRet[6] = teta;     mRet[7] = phi;
+  }
+return(mRet);
+}
+
+/* --Methode-- */
+template <class T> 
+string NTupInt_PixelMap<T>::VarList_C(const char* nx) const 
+{
+string nomx;
+if (nx) nomx = nx;
+else nomx = "_xh_";
+string vardec = "double i,k,val,real,imag,mod,phas,teta,phi; \n";
+vardec += "i = " + nomx + "[0]; k = " + nomx + "[0];  val = " + nomx + "[1]; \n";
+vardec += "real = " + nomx + "[2];  imag = " + nomx + "[3]; \n";
+vardec += "mod  = " + nomx + "[4];  phas = " + nomx + "[5]; \n";
+vardec += "teta = " + nomx + "[6];  phi  = " + nomx + "[7]; \n";
+return(vardec);
+}
+
+r_8* NTupInt_PixelMap< complex<float> >::GetLineD(int n) const 
+{
+int i;
+if ((n < 0) || (n >= (int)(mMap->NbPixels()) )) 
+    for(i=0; i<8; i++)  mRet[i] = 0.;
+else { 
+  double teta,phi;
+  mMap->PixThetaPhi(n, teta, phi);
+  mRet[0] = n;  
+  mRet[2] = mMap->PixVal(n).real();  mRet[3] = mMap->PixVal(n).imag();
+  mRet[1] = mRet[4] = sqrt(mRet[2]*mRet[2]+mRet[3]*mRet[3]);
+  mRet[5] = atan2(mRet[3], mRet[2]);
+  mRet[6] = teta;     mRet[7] = phi;
+  }
+return(mRet);
+}
+
+r_8* NTupInt_PixelMap< complex<double> >::GetLineD(int n) const 
+{
+int i;
+if ((n < 0) || (n >= (int)(mMap->NbPixels()) )) 
+    for(i=0; i<8; i++)  mRet[i] = 0.;
+else { 
+  double teta,phi;
+  mMap->PixThetaPhi(n, teta, phi);
+  mRet[0] = n;  
+  mRet[2] = mMap->PixVal(n).real();  mRet[3] = mMap->PixVal(n).imag();
+  mRet[1] = mRet[4] = sqrt(mRet[2]*mRet[2]+mRet[3]*mRet[3]);
+  mRet[5] = atan2(mRet[3], mRet[2]);
+  mRet[6] = teta;     mRet[7] = phi;
+  }
+return(mRet);
+}
+
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template NOMAdapter_PixelMap<int_4>
+#pragma define_template NOMAdapter_PixelMap<r_4>
+#pragma define_template NOMAdapter_PixelMap<r_8>
+#pragma define_template NOMAdapter_PixelMap< complex<float> >
+#pragma define_template NOMAdapter_PixelMap< complex<double> >
+#pragma define_template NTupInt_PixelMap<int_4>
+#pragma define_template NTupInt_PixelMap<r_4>
+#pragma define_template NTupInt_PixelMap<r_8>
+#pragma define_template NTupInt_PixelMap< complex<float> >
+#pragma define_template NTupInt_PixelMap< complex<double> >
+#endif
+
+#if defined(ANSI_TEMPLATES) 
+template class NOMAdapter_PixelMap<int_4>;
+template class NOMAdapter_PixelMap<r_4>;
+template class NOMAdapter_PixelMap<r_8>;
+template class NOMAdapter_PixelMap< complex<float> >;
+template class NOMAdapter_PixelMap< complex<double> >;
+template class NTupInt_PixelMap<int_4>;
+template class NTupInt_PixelMap<r_4>;
+template class NTupInt_PixelMap<r_8>;
+template class NTupInt_PixelMap< complex<float> >;
+template class NTupInt_PixelMap< complex<double> >;
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/nomskymapadapter.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/nomskymapadapter.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/nomskymapadapter.h	(revision 2309)
@@ -0,0 +1,64 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Adaptateur d objets (pour NamedObjMgr) pour les classes 
+// PixelMap/SphericalMap/LocalMap  de Sophya
+//                                      Reza 11/99
+//  LAL-IN2P3/CNRS               CEA-DAPNIA     
+ 
+#ifndef NOMSKYMAPADAPTER_H_SEEN
+#define NOMSKYMAPADAPTER_H_SEEN
+
+#include "nomgadapter.h"
+#include "tmatrix.h"
+#include "pixelmap.h"
+
+
+
+//----------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet PixelMap<T> 
+//----------------------------------------------------------------
+
+template <class T> 
+class NOMAdapter_PixelMap : public NObjMgrAdapter {
+public:
+				NOMAdapter_PixelMap(PixelMap<T>* m = NULL);
+  virtual			~NOMAdapter_PixelMap();
+
+  virtual NObjMgrAdapter*	Clone(AnyDataObj* o);
+
+  virtual string		GetDataObjType();
+
+  virtual AnyDataObj*		CloneDataObj(bool share=false);
+
+  virtual void			ReadFits(string const & flnm);
+  virtual void			SaveFits(string const & flnm);
+  virtual void			SavePPF(POutPersist& s, string const & nom);
+
+  virtual void			Print(ostream& os);
+  virtual P2DArrayAdapter*	Get2DArray(string& dopt);
+  virtual NTupleInterface*	GetNTupleInterface(bool& adel);
+
+  virtual void			MeanSig(T& gmoy, T& gsig);
+  virtual void			Project_Mol(TMatrix<T> & mtx, T defval=0.);
+
+protected:
+  PixelMap<T>* mMap;
+};
+
+// Class Interface NTuple pour PixelMap<T>
+
+template <class T> 
+class NTupInt_PixelMap : public NTupleInterface {
+public:
+			NTupInt_PixelMap(PixelMap<T>* m);
+  virtual		~NTupInt_PixelMap();
+  virtual uint_4        NbLines() const ;
+  virtual uint_4        NbColumns() const ;
+  virtual r_8 *         GetLineD(int n) const ;
+  virtual string        VarList_C(const char* nomx=NULL) const ;
+protected:
+  PixelMap<T>* mMap;
+  mutable r_8 mRet[8];
+};
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/nomspecrespadapter.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/nomspecrespadapter.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/nomspecrespadapter.cc	(revision 2309)
@@ -0,0 +1,140 @@
+#include "machdefs.h"
+#include <stdlib.h>
+#include <typeinfo>
+#include <iostream.h>
+#include <string>
+
+#include "nomspecrespadapter.h"
+#include "specrespvector.h"
+#include "gaussfilt.h"
+#include "pidrawer.h"
+
+// ------ Classe de Drawer pour tracer Y = Transmission(nu = X) 
+class PISpectralResponseDrawer : public PIDrawer {
+public :
+ 	       PISpectralResponseDrawer(SpectralResponse* sr, bool ad=false);
+ 	       ~PISpectralResponseDrawer();
+  virtual void Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax);
+  virtual void UpdateLimits();
+
+protected:
+SpectralResponse * mSR;
+bool mAd;
+};
+
+PISpectralResponseDrawer::PISpectralResponseDrawer(SpectralResponse* sr, bool ad)
+{
+mSR = sr;
+mAd = ad;
+}
+
+PISpectralResponseDrawer::~PISpectralResponseDrawer()
+{
+if (mAd && mSR)  delete mSR;
+}
+
+void
+PISpectralResponseDrawer::Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax)
+{
+  if (!mSR) return;
+  PIGrCoord x1, x2, y1, y2;
+  g->GetGrSpace(x1, x2, y1, y2);
+  double xMax = x2;
+  double xMin = x1;
+  double yMax = y2;
+  double yMin = y1;
+  double xStep = (xMax - xMin)/100;
+  double xOld = xMin;
+  double yOld = mSR->transmission(xMin);
+  double x,y;
+  for (x = xMin+xStep; x<xMax; x+=xStep) {
+    y = mSR->transmission(x);
+    if (y>yMin && yOld>yMin && 
+        y<yMax && yOld<yMax) 
+           g->DrawLine(xOld, yOld, x, y);
+    xOld = x;
+    yOld = y;
+  }
+}
+
+void
+PISpectralResponseDrawer::UpdateLimits()
+{
+  if (!mSR) return;
+  double xmin, xmax;
+  double ymin, ymax;
+  xmin = mSR->minFreq();
+  xmax = mSR->maxFreq();
+  double dx = (xmax-xmin)*0.025;
+  xmin -= dx;  xmax += dx;
+  ymin = 0.;
+  ymax = mSR->peakTransmission()*1.05;
+  SetLimits(xmin, xmax, ymin, ymax);
+//  cout << " DBG - " << xmin << "," << xmax << "   " << ymin << "," << ymax << endl;
+}
+//-------------------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet SpectralResponse
+//-------------------------------------------------------------------------
+
+/* --Methode-- */
+NOMAdapter_SpectralResponse::NOMAdapter_SpectralResponse(SpectralResponse* o)
+  : NObjMgrAdapter(o)
+{
+mSR = o;
+}
+
+/* --Methode-- */
+NOMAdapter_SpectralResponse::~NOMAdapter_SpectralResponse()
+{
+}
+
+/* --Methode-- */
+NObjMgrAdapter* NOMAdapter_SpectralResponse::Clone(AnyDataObj* o)
+{
+SpectralResponse* sr = dynamic_cast<SpectralResponse *>(o);
+if (sr) return ( new NOMAdapter_SpectralResponse(sr) );
+return ( new NObjMgrAdapter(o) );
+}
+
+
+/* --Methode-- */
+void NOMAdapter_SpectralResponse::SavePPF(POutPersist& pos, string const & nom)
+{
+  GaussianFilter* gf = dynamic_cast<GaussianFilter *> (mSR);
+  SpecRespVec*    vecFilt   = dynamic_cast<SpecRespVec    *> (mSR);
+  if (gf) { // C'est un GaussianFilter ....
+    ObjFileIO<GaussianFilter> oio(gf);
+    oio.Write(pos, nom);
+  }
+  else if (vecFilt) {
+    ObjFileIO<SpecRespVec> oio(vecFilt);
+    oio.Write(pos, nom);
+  }
+  else {
+   string s = typeid(*mSR).name();
+   cout << "NOMAdapter_SpectralResponse::SavePPF() - Error : Not supported for " << s << endl;
+  }
+}
+
+/* --Methode-- */
+void NOMAdapter_SpectralResponse::Print(ostream& os)
+{
+os << (*mSR);
+}
+
+/* --Methode-- */
+PIDrawer* NOMAdapter_SpectralResponse::GetDrawer(string & dopt)
+{
+return(new PISpectralResponseDrawer(mSR, false));
+}
+
+
+/* --Methode-- 
+NTupleInterface* NOMAdapter_SpectralResponse::GetNTupleInterface(bool& adel)
+{ 
+adel = true;
+return( new NTupInt_SpectralResponse(mSR) );
+}
+*/
+
+
Index: /tags/V_Dec2002/SophyaPI/PIext/nomspecrespadapter.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/nomspecrespadapter.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/nomspecrespadapter.h	(revision 2309)
@@ -0,0 +1,38 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Adaptateur d objets (pour NamedObjMgr) pour Histos/NTuple
+//                                    Reza 05/99
+//  LAL-IN2P3/CNRS               CEA-DAPNIA     
+ 
+#ifndef NOMSPECRESPADAPTER_H_SEEN
+#define NOMSPECRESPADAPTER_H_SEEN
+
+#include "nomgadapter.h"
+#include "specresp.h"
+
+
+//-------------------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet SpectralResponse
+//-------------------------------------------------------------------------
+
+class NOMAdapter_SpectralResponse : public NObjMgrAdapter {
+public:
+				NOMAdapter_SpectralResponse(SpectralResponse* sr = NULL);
+  virtual			~NOMAdapter_SpectralResponse();
+
+  virtual NObjMgrAdapter*	Clone(AnyDataObj* o);
+
+  //  virtual void			ReadFits(string const & flnm);
+  //  virtual void			SaveFits(string const & flnm);
+  virtual void			SavePPF(POutPersist& s, string const & nom);
+
+  virtual void			Print(ostream& os);
+  virtual PIDrawer*		GetDrawer(string& dopt);
+//  virtual NTupleInterface*	GetNTupleInterface(bool& adel);
+
+protected:
+  SpectralResponse* mSR;
+};
+
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/nomstladapter.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/nomstladapter.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/nomstladapter.cc	(revision 2309)
@@ -0,0 +1,137 @@
+#include "machdefs.h"
+#include <stdlib.h>
+#include <typeinfo>
+#include <iostream.h>
+#include <string>
+
+#include "nomstladapter.h"
+#include "stlist.h"
+#include "pistlist.h"
+
+
+
+
+//-------------------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet StarList
+//-------------------------------------------------------------------------
+
+/* --Methode-- */
+NOMAdapter_StarList::NOMAdapter_StarList(StarList* o)
+  : NObjMgrAdapter(o)
+{
+mStl = o;
+}
+
+/* --Methode-- */
+NOMAdapter_StarList::~NOMAdapter_StarList()
+{
+}
+
+/* --Methode-- */
+NObjMgrAdapter* NOMAdapter_StarList::Clone(AnyDataObj* o)
+{
+StarList* stl = dynamic_cast<StarList *>(o);
+if (stl) return ( new NOMAdapter_StarList(stl) );
+return ( new NObjMgrAdapter(o) );
+}
+
+
+/* --Methode-- */
+void NOMAdapter_StarList::SavePPF(POutPersist& pos, string const & nom)
+{
+#ifdef SANS_EVOLPLANCK
+// PEIDA-EROS L'objet est lui-meme PPersist
+string tag = nom;  // A cause de const
+mStl->Write(pos,0,tag);
+#else
+string s = typeid(*mStl).name();
+cout << "NOMAdapter_StarList::SavePPF() - Error : Not supported for " << s << endl;
+#endif
+}
+
+/* --Methode-- */
+void NOMAdapter_StarList::Print(ostream& os)
+{
+os << (*mStl);
+}
+
+/* --Methode-- */
+PIDrawer* NOMAdapter_StarList::GetDrawer(string & dopt)
+{
+return(new PIStarList(mStl, false));
+}
+
+
+/* --Methode-- */
+NTupleInterface* NOMAdapter_StarList::GetNTupleInterface(bool& adel)
+{
+adel = true;
+return( new NTupInt_StarList(mStl) );
+}
+
+
+// -------------------------------------------------------------
+
+/* --Methode-- */
+NTupInt_StarList::NTupInt_StarList(StarList* stl)
+{
+mStl = stl;
+}
+
+/* --Methode-- */
+NTupInt_StarList::~NTupInt_StarList()
+{
+}
+
+/* --Methode-- */
+uint_4 NTupInt_StarList::NbLines() const
+{
+return(mStl->NbStars());
+}
+
+/* --Methode-- */
+uint_4 NTupInt_StarList::NbColumns() const 
+{
+return(11);
+}
+
+/* --Methode-- */
+r_8* NTupInt_StarList::GetLineD(int n) const 
+{
+BStar* bst = mStl->Star(n);
+if (bst == NULL)  
+  for(int k=0; k<11; k++)  mRet[k] = -9999.0;
+else {
+  mRet[0] = bst->PosX();
+  mRet[1] = bst->PosY();
+  mRet[2] = bst->Flux();
+  mRet[3] = bst->Fond();
+  mRet[4] = bst->PixMax();
+  mRet[5] = bst->PosXRef();
+  mRet[6] = bst->PosYRef();
+  mRet[7] = bst->FluxRef();
+  mRet[8] = bst->FondRef();
+  mRet[9] = bst->PixMaxRef();
+  mRet[10] = bst->Flags();
+  }
+return(mRet);
+}
+
+/* --Methode-- */
+string NTupInt_StarList::VarList_C(const char* nx) const 
+{
+string nomx;
+if (nx) nomx = nx;
+else nomx = "_xstl_";
+string vardec = "double x,y,flux,fond,pixmax; \n";
+vardec += "double xref,yref,fluxref,fondref,pixmaxref; \n";
+vardec += "double flags; \n"; 
+vardec += "x = " + nomx + "[0];  y = " + nomx + "[1]; \n";
+vardec += "flux = " + nomx + "[2];  fond = " + nomx + "[3]; \n";
+vardec += "pixmax = " + nomx + "[4]; \n";
+vardec += "xref = " + nomx + "[5];  yref = " + nomx + "[6]; \n";
+vardec += "fluxref = " + nomx + "[7];  fondref = " + nomx + "[8]; \n";
+vardec += "pixmaxref = " + nomx + "[9]; \n";
+vardec += "flags = " + nomx + "[10]; \n";
+return(vardec);
+}
Index: /tags/V_Dec2002/SophyaPI/PIext/nomstladapter.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/nomstladapter.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/nomstladapter.h	(revision 2309)
@@ -0,0 +1,51 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Adaptateur d objets (pour NamedObjMgr) pour Histos/NTuple
+//                                    Reza 05/99
+//  LAL-IN2P3/CNRS               CEA-DAPNIA     
+ 
+#ifndef NOMSTLISTADAPTER_H_SEEN
+#define NOMSTLISTADAPTER_H_SEEN
+
+#include "nomgadapter.h"
+#include "stlist.h"
+
+
+//-------------------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet StarList 
+//-------------------------------------------------------------------------
+
+class NOMAdapter_StarList : public NObjMgrAdapter {
+public:
+				NOMAdapter_StarList(StarList* stl = NULL);
+  virtual			~NOMAdapter_StarList();
+
+  virtual NObjMgrAdapter*	Clone(AnyDataObj* o);
+
+  //  virtual void			ReadFits(string const & flnm);
+  //  virtual void			SaveFits(string const & flnm);
+  virtual void			SavePPF(POutPersist& s, string const & nom);
+
+  virtual void			Print(ostream& os);
+  virtual PIDrawer*		GetDrawer(string& dopt);
+  virtual NTupleInterface*	GetNTupleInterface(bool& adel);
+
+protected:
+  StarList* mStl;
+};
+
+// Class Interface NTuple pour StarList 
+class NTupInt_StarList : public NTupleInterface {
+public:
+			NTupInt_StarList(StarList* stl);
+  virtual		~NTupInt_StarList();
+  virtual uint_4        NbLines() const ;
+  virtual uint_4        NbColumns() const ;
+  virtual r_8 *         GetLineD(int n) const ;
+  virtual string        VarList_C(const char* nomx=NULL) const ;
+protected:
+  StarList* mStl;
+  mutable r_8 mRet[12];
+};
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/nomtarradapter.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/nomtarradapter.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/nomtarradapter.cc	(revision 2309)
@@ -0,0 +1,294 @@
+#include "machdefs.h"
+#include <stdlib.h>
+#include <typeinfo>
+#include <iostream.h>
+#include <string>
+#include <complex>
+
+#include "datatype.h"
+
+#include "nomtarradapter.h"
+#include "tvector.h"
+#include "pitvmaad.h"
+#include "piyfxdrw.h"
+
+#include "fioarr.h"
+#include "fitstarray.h"
+
+
+
+//----------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet TMatrix<T> 
+//----------------------------------------------------------------
+
+
+/* --Methode-- */
+template <class T> 
+NOMAdapter_TArray<T>::NOMAdapter_TArray(TArray<T>* o)
+  : NObjMgrAdapter(o)
+{
+mArr = o;
+}
+
+/* --Methode-- */
+template <class T> 
+NOMAdapter_TArray<T>::~NOMAdapter_TArray()
+{
+}
+
+/* --Methode-- */
+template <class T> 
+NObjMgrAdapter* NOMAdapter_TArray<T>::Clone(AnyDataObj* o)
+{
+TArray<T>* a = dynamic_cast<TArray<T> *>(o);
+if (a) return ( new NOMAdapter_TArray<T>(a) );
+return ( new NObjMgrAdapter(o) );
+}
+
+/* --Methode-- */
+template <class T> 
+string NOMAdapter_TArray<T>::GetDataObjType()
+{
+string type = "TArray< ";
+
+// type +=  DecodeTypeIdName(typeid(T).name());
+type += DataTypeInfo<T>::getTypeName();
+type +=  " > ";
+return(type);
+}
+
+/* --Methode-- */
+template <class T> 
+AnyDataObj* NOMAdapter_TArray<T>::CloneDataObj(bool share)
+{
+return ( new TArray<T>(*mArr, share) );
+}
+
+/* --Methode-- */
+template <class T> 
+void NOMAdapter_TArray<T>::ReadFits(string const & flnm)
+{
+  FitsInFile fis(flnm);
+  fis >> (*mArr);
+}
+
+/* --Methode-- */
+template <class T> 
+void NOMAdapter_TArray<T>::SaveFits(string const & flnm)
+{
+  FitsOutFile fos(flnm);
+  fos << (*mArr);
+}
+
+// ---- Specialisation pour complexes -----
+void NOMAdapter_TArray< complex<r_4> >::ReadFits(string const & flnm)
+{
+cout << " NOMAdapter_TArray< complex<r_4> >::ReadFits() - Error " 
+     << " Not supported (complex data type)" << endl;
+}
+void NOMAdapter_TArray< complex<r_4> >::SaveFits(string const & flnm)
+{
+cout << " NOMAdapter_TArray< complex<r_4> >::SaveFits() - Error " 
+     << " Not supported (complex data type)" << endl;
+}
+
+void NOMAdapter_TArray< complex<r_8> >::ReadFits(string const & flnm)
+{
+cout << " NOMAdapter_TArray< complex<r_8> >::ReadFits() - Error " 
+     << " Not supported (complex data type)" << endl;
+}
+void NOMAdapter_TArray< complex<r_8> >::SaveFits(string const & flnm)
+{
+cout << " NOMAdapter_TArray< complex<r_8> >::SaveFits() - Error " 
+     << " Not supported (complex data type)" << endl;
+}
+
+/* --Methode-- */
+template <class T> 
+void NOMAdapter_TArray<T>::SavePPF(POutPersist& pos, string const & nom)
+{
+FIO_TArray<T> fio(mArr);
+fio.Write(pos, nom);
+}
+
+/* --Methode-- */
+template <class T> 
+void NOMAdapter_TArray<T>::Print(ostream& os)
+{
+os << (*mArr);
+}
+
+/* --Methode-- */
+template <class T> 
+PIDrawer * NOMAdapter_TArray<T>::GetDrawer(string & dopt)
+{
+if (mArr->NbDimensions() == 1) {
+  // On peut en faire un vecteur ...
+  TVector<T>* v = new TVector<T>(*mArr, true);  // on partage les donnees
+  dopt = "thinline," + dopt;
+  return( new PIYfXDrawer( new POTVectorAdapter<T>(v, true), NULL, true) );
+}
+ else return(NULL);
+}
+
+/* --Methode-- */
+template <class T> 
+P2DArrayAdapter* NOMAdapter_TArray<T>::Get2DArray(string &)
+{
+if (mArr->NbDimensions() <= 2) {
+  // On peut en faire un tableau 2-D ...
+  TMatrix<T>* m = new TMatrix<T>(*mArr, true);  // on partage les donnees
+  return ( new POTMatrixAdapter<T>(m, true) );
+}
+else return(NULL);
+}
+
+/* --Methode-- */
+template <class T> 
+NTupleInterface* NOMAdapter_TArray<T>::GetNTupleInterface(bool& adel)
+{
+adel = true;
+return( new NTupInt_TArray<T>(mArr) );
+}
+
+
+
+
+// -------------------------------------------------------------
+
+/* --Methode-- */
+template <class T> 
+NTupInt_TArray<T>::NTupInt_TArray(TArray<T>* a)
+{
+mArr = a;
+}
+
+/* --Methode-- */
+template <class T> 
+NTupInt_TArray<T>::~NTupInt_TArray()
+{
+}
+
+/* --Methode-- */
+template <class T> 
+uint_4 NTupInt_TArray<T>::NbLines() const
+{
+return( mArr->Size() );
+}
+
+/* --Methode-- */
+template <class T> 
+uint_4 NTupInt_TArray<T>::NbColumns() const 
+{
+return(11);
+}
+
+/* --Methode-- */
+template <class T> 
+r_8* NTupInt_TArray<T>::GetLineD(int n) const 
+{
+if ((n < 0) || (n >= (int)(mArr->Size()) ) ) {
+  mRet[0] = n;
+  for(int i=1; i<11; i++)  mRet[i] = 0.;
+}
+else { 
+  sa_size_t ix, iy, iz, it, iu;
+  mArr->IndexAtPosition(n, ix, iy, iz, it, iu);
+  mRet[0] = n;   mRet[1] = ix;  mRet[2] = iy;  
+  mRet[3] = iz;  mRet[4] = it;  mRet[5] = iu;  
+  mRet[6] = (*mArr)(ix,iy,iz,it,iu);
+  mRet[7] = mRet[2];  mRet[8] = 0.;
+  mRet[9] = mRet[2];  mRet[10] = 0.;
+  }
+return(mRet);
+}
+
+/* --Methode-- */
+template <class T> 
+string NTupInt_TArray<T>::VarList_C(const char* nx) const 
+{
+string nomx;
+if (nx) nomx = nx;
+else nomx = "_xh_";
+string vardec = "double n,x,y,z,t,u,val,real,imag,mod,phas; \n";
+vardec += "n = " + nomx + "[0];  x = " + nomx + "[1]; y = " + nomx + "[2]; \n"; 
+vardec += "z = " + nomx + "[3];  t = " + nomx + "[4]; u = " + nomx + "[5]; \n"; 
+vardec += "val = " + nomx + "[6]; \n";
+vardec += "real = " + nomx + "[7];  imag = " + nomx + "[8]; \n";
+vardec += "mod  = " + nomx + "[9];  phas = " + nomx + "[10]; \n";
+return(vardec);
+}
+
+/* --Methode-- */
+r_8* NTupInt_TArray< complex<r_4> >::GetLineD(int n) const 
+{
+if ((n < 0) || (n >= (int)(mArr->Size()) ) ) {
+  mRet[0] = n;
+  for(int i=1; i<11; i++)  mRet[i] = 0.;
+}
+else { 
+  sa_size_t ix, iy, iz, it, iu;
+  mArr->IndexAtPosition(n, ix, iy, iz, it, iu);
+  mRet[0] = n;   mRet[1] = ix;  mRet[2] = iy;  
+  mRet[3] = iz;  mRet[4] = it;  mRet[5] = iu;  
+  mRet[7] = (*mArr)(ix,iy,iz,it,iu).real();
+  mRet[8] = (*mArr)(ix,iy,iz,it,iu).imag();
+  mRet[3] = mRet[6] = sqrt(mRet[7]*mRet[7]+mRet[8]*mRet[8]);
+  mRet[7] = atan2(mRet[8], mRet[7]);
+}
+return(mRet);
+}
+
+r_8* NTupInt_TArray< complex<r_8> >::GetLineD(int n) const 
+{
+if ((n < 0) || (n >= (int)(mArr->Size()) ) ) {
+  mRet[0] = n;
+  for(int i=1; i<11; i++)  mRet[i] = 0.;
+}
+else { 
+  sa_size_t ix, iy, iz, it, iu;
+  mArr->IndexAtPosition(n, ix, iy, iz, it, iu);
+  mRet[0] = n;   mRet[1] = ix;  mRet[2] = iy;  
+  mRet[3] = iz;  mRet[4] = it;  mRet[5] = iu;  
+  mRet[7] = (*mArr)(ix,iy,iz,it,iu).real();
+  mRet[8] = (*mArr)(ix,iy,iz,it,iu).imag();
+  mRet[3] = mRet[6] = sqrt(mRet[7]*mRet[7]+mRet[8]*mRet[8]);
+  mRet[7] = atan2(mRet[8], mRet[7]);
+}
+return(mRet);
+}
+
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+//#pragma define_template NOMAdapter_TArray<uint_2>
+//#pragma define_template NOMAdapter_TArray<int_2>
+#pragma define_template NOMAdapter_TArray<int_4>
+#pragma define_template NOMAdapter_TArray<r_4>
+#pragma define_template NOMAdapter_TArray<r_8>
+#pragma define_template NOMAdapter_TArray< complex<r_4> >
+#pragma define_template NOMAdapter_TArray< complex<r_8> >
+//#pragma define_template NTupInt_TArray<uint_2>
+//#pragma define_template NTupInt_TArray<int_2>
+#pragma define_template NTupInt_TArray<int_4>
+#pragma define_template NTupInt_TArray<r_4>
+#pragma define_template NTupInt_TArray<r_8>
+#pragma define_template NTupInt_TArray< complex<r_4> >
+#pragma define_template NTupInt_TArray< complex<r_8> >
+#endif
+
+#if defined(ANSI_TEMPLATES) 
+//template class NOMAdapter_TArray<uint_2>;
+//template class NOMAdapter_TArray<int_2>;
+template class NOMAdapter_TArray<int_4>;
+template class NOMAdapter_TArray<r_4>;
+template class NOMAdapter_TArray<r_8>;
+template class NOMAdapter_TArray< complex<r_4> >;
+template class NOMAdapter_TArray< complex<r_8> >;
+// template class NTupInt_TArray<uint_2>;
+// template class NTupInt_TArray<int_2>;
+template class NTupInt_TArray<int_4>;
+template class NTupInt_TArray<r_4>;
+template class NTupInt_TArray<r_8>;
+template class NTupInt_TArray< complex<r_4> >;
+template class NTupInt_TArray< complex<r_8> >;
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/nomtarradapter.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/nomtarradapter.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/nomtarradapter.h	(revision 2309)
@@ -0,0 +1,59 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Adaptateur d objets (pour NamedObjMgr) 
+// pour les classes TMatrix<T>, TVector<T> de Sophya
+//                                      Reza 11/99
+//  LAL-IN2P3/CNRS               CEA-DAPNIA     
+ 
+#ifndef NOMTARRAYADAPTER_H_SEEN
+#define NOMTARRAYADAPTER_H_SEEN
+
+#include "nomgadapter.h"
+#include "tarray.h"
+
+//---------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet TArray 
+//---------------------------------------------------------------
+
+template <class T> 
+class NOMAdapter_TArray : public NObjMgrAdapter {
+public:
+				NOMAdapter_TArray(TArray<T>* m = NULL);
+  virtual			~NOMAdapter_TArray();
+
+  virtual NObjMgrAdapter*	Clone(AnyDataObj* o);
+
+  virtual string		GetDataObjType();
+
+  virtual AnyDataObj*		CloneDataObj(bool share=false);
+
+  virtual void			ReadFits(string const & flnm);
+  virtual void			SaveFits(string const & flnm);
+  virtual void			SavePPF(POutPersist& s, string const & nom);
+
+  virtual void			Print(ostream& os);
+  virtual PIDrawer*		GetDrawer(string& dopt);
+  virtual P2DArrayAdapter*	Get2DArray(string& dopt);
+  virtual NTupleInterface*	GetNTupleInterface(bool& adel);
+
+protected:
+  TArray<T>* mArr;
+};
+
+// Class Interface NTuple pour TArray<T>
+
+template <class T> 
+class NTupInt_TArray : public NTupleInterface {
+public:
+			NTupInt_TArray(TArray<T>* m);
+  virtual		~NTupInt_TArray();
+  virtual uint_4        NbLines() const ;
+  virtual uint_4        NbColumns() const ;
+  virtual r_8 *         GetLineD(int n) const ;
+  virtual string        VarList_C(const char* nomx=NULL) const ;
+protected:
+  TArray<T>* mArr;
+  mutable r_8 mRet[11];
+};
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/nomtmatvecadapter.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/nomtmatvecadapter.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/nomtmatvecadapter.cc	(revision 2309)
@@ -0,0 +1,410 @@
+#include "machdefs.h"
+#include <stdlib.h>
+#include <typeinfo>
+#include <iostream.h>
+#include <string>
+#include <complex>
+
+#include "datatype.h"
+
+#include "tvector.h"
+#include "objfitter.h"
+#include "nomtmatvecadapter.h"
+#include "piyfxdrw.h"
+#include "pitvmaad.h"
+
+#include "fioarr.h"
+#include "fitstarray.h"
+
+
+//----------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet TMatrix<T> 
+//----------------------------------------------------------------
+
+
+/* --Methode-- */
+template <class T> 
+NOMAdapter_TMatrix<T>::NOMAdapter_TMatrix(TMatrix<T>* o)
+  : NObjMgrAdapter(o)
+{
+mMtx = o;
+}
+
+/* --Methode-- */
+template <class T> 
+NOMAdapter_TMatrix<T>::~NOMAdapter_TMatrix()
+{
+}
+
+/* --Methode-- */
+template <class T> 
+NObjMgrAdapter* NOMAdapter_TMatrix<T>::Clone(AnyDataObj* o)
+{
+TMatrix<T>* m = dynamic_cast<TMatrix<T> *>(o);
+if (m) return ( new NOMAdapter_TMatrix<T>(m) );
+return ( new NObjMgrAdapter(o) );
+}
+
+/* --Methode-- */
+template <class T> 
+string NOMAdapter_TMatrix<T>::GetDataObjType()
+{
+string type = "TMatrix< ";
+
+TVector<T>* v = dynamic_cast<TVector<T> *>(mMtx);
+if (v != NULL) type = "TVector< ";
+
+// type +=  DecodeTypeIdName(typeid(T).name());
+type += DataTypeInfo<T>::getTypeName();
+type +=  " > ";
+return(type);
+}
+
+/* --Methode-- */
+template <class T> 
+AnyDataObj* NOMAdapter_TMatrix<T>::CloneDataObj(bool share)
+{
+if (mMtx == NULL)  return(NULL);
+TVector<T>* v = dynamic_cast<TVector<T> *>(mMtx);
+if (v != NULL) return( new TVector<T>(*v, share) );
+else return ( new TMatrix<T>(*mMtx, share) );
+}
+
+/* --Methode-- */
+template <class T> 
+void NOMAdapter_TMatrix<T>::ReadFits(string const & flnm)
+{
+  FitsInFile fis(flnm);
+  fis >> (*mMtx);
+}
+
+/* --Methode-- */
+template <class T> 
+void NOMAdapter_TMatrix<T>::SaveFits(string const & flnm)
+{
+  FitsOutFile fos(flnm);
+  fos << (*mMtx);
+}
+// ---- Specialisation pour complexes -----
+void NOMAdapter_TMatrix< complex<r_4> >::ReadFits(string const & flnm)
+{
+cout << " NOMAdapter_TMatrix< complex<r_4> >::ReadFits() - Error " 
+     << " Not supported (complex data type)" << endl;
+}
+void NOMAdapter_TMatrix< complex<r_4> >::SaveFits(string const & flnm)
+{
+cout << " NOMAdapter_TMatrix< complex<r_4> >::SaveFits() - Error " 
+     << " Not supported (complex data type)" << endl;
+}
+
+void NOMAdapter_TMatrix< complex<r_8> >::ReadFits(string const & flnm)
+{
+cout << " NOMAdapter_TMatrix< complex<r_8> >::ReadFits() - Error " 
+     << " Not supported (complex data type)" << endl;
+}
+void NOMAdapter_TMatrix< complex<r_8> >::SaveFits(string const & flnm)
+{
+cout << " NOMAdapter_TMatrix< complex<r_8> >::SaveFits() - Error " 
+     << " Not supported (complex data type)" << endl;
+}
+
+/* --Methode-- */
+template <class T> 
+void NOMAdapter_TMatrix<T>::SavePPF(POutPersist& pos, string const & nom)
+{
+if (mMtx == NULL)  return;
+TVector<T>* v = dynamic_cast<TVector<T> *>(mMtx);
+if (v != NULL) {
+  FIO_TArray<T> fio(v);
+  fio.Write(pos, nom);
+  }
+else {
+  FIO_TArray<T> fio(mMtx);
+  fio.Write(pos, nom);
+  }
+}
+
+/* --Methode-- */
+template <class T> 
+void NOMAdapter_TMatrix<T>::Print(ostream& os)
+{
+TVector<T>* v = dynamic_cast<TVector<T> *>(mMtx);
+if (v != NULL)  os << (*v);
+else os << (*mMtx);
+}
+
+/* --Methode-- */
+template <class T> 
+PIDrawer* NOMAdapter_TMatrix<T>::GetDrawer(string & dopt)
+{
+TVector<T>* v = dynamic_cast<TVector<T> *>(mMtx);
+if (v == NULL) return(NULL);
+else {
+  dopt = "thinline " + dopt;
+  return( new PIYfXDrawer( new POTVectorAdapter<T>(v, false), NULL, true) );
+  }
+}
+
+/* --Methode-- */
+template <class T> 
+P2DArrayAdapter* NOMAdapter_TMatrix<T>::Get2DArray(string &)
+{
+return ( new POTMatrixAdapter<T>(mMtx, false) );
+}
+
+/* --Methode-- */
+template <class T> 
+NTupleInterface* NOMAdapter_TMatrix<T>::GetNTupleInterface(bool& adel)
+{
+adel = true;
+return( new NTupInt_TMatrix<T>(mMtx) );
+}
+
+
+/* --Methode-- */
+template <class T> 
+GeneralFitData* NOMAdapter_TMatrix<T>::GetGeneralFitData(bool& adel
+ ,GeneralFitData::FitErrType errtype,double errscale,double errmin
+ ,int i1,int i2,int j1,int j2)
+{
+adel = false;
+if(!mMtx) return(NULL);
+
+int nx,ny;
+TVector<T>* vec = dynamic_cast<TVector<T> *>(mMtx);
+
+if(vec) {  // C'est un TVector
+  nx = vec->NElts();
+  ny = 1;
+} else {
+  nx = mMtx->NRows();
+  ny = mMtx->NCol();
+  if(nx<=0 || ny<=0) return(NULL);
+}
+
+i1 = (i1<0||i1>=nx)? 0: i1;
+i2 = (i2<0||i2>=nx||i2<i1)? nx-1: i2;
+j1 = (j1<0||j1>=ny)? 0: j1;
+j2 = (j2<0||j2>=ny||j2<j1)? ny-1: j2;
+
+GeneralFitData* mGData = NULL;
+
+if(vec) {  // C'est un TVector
+  mGData = new GeneralFitData(1,(i2-i1+1),0);
+  adel = true;
+  for(int i=i1;i<=i2;i++) {
+    double x = (double) i;
+    double f = (*vec)(i);
+    double e = 1.;
+    e = GeneralFitData::ComputeError(f,e,errtype,errscale,errmin);
+    mGData->AddData1(x,f,e);
+  }
+} else {
+  mGData = new GeneralFitData(2,(i2-i1+1)*(j2-j1+1),0);
+  adel = true;
+  for(int i=i1;i<=i2;i++) for(int j=j1;j<=j2;j++) {
+    double x = (double) i;
+    double y = (double) j;
+    double f = (*mMtx)(i,j);
+    double e = 1.;
+    e = GeneralFitData::ComputeError(f,e,errtype,errscale,errmin);
+    mGData->AddData2(x,y,f,e);
+  }
+}
+
+return mGData;
+}
+
+template <class T> 
+AnyDataObj* NOMAdapter_TMatrix<T>::FitResidusObj(GeneralFit& mfit)
+{
+TVector<T>* vec = dynamic_cast<TVector<T> *>(mMtx);
+if(vec) {
+  TVector<T>* v = new TVector<T>(ObjectFitter::FitResidus(*vec,mfit),true);
+  return v;
+} else {
+  TMatrix<T>* m = new TMatrix<T>(ObjectFitter::FitResidus(*mMtx,mfit),true);
+  return m;
+}
+}
+
+template <class T> 
+AnyDataObj* NOMAdapter_TMatrix<T>::FitFunctionObj(GeneralFit& mfit)
+{
+TVector<T>* vec = dynamic_cast<TVector<T> *>(mMtx);
+if(vec) {
+  TVector<T>* v = new TVector<T>(ObjectFitter::FitFunction(*vec,mfit),true);
+  return v;
+} else {
+  TMatrix<T>* m = new TMatrix<T>(ObjectFitter::FitFunction(*mMtx,mfit),true);
+  return m;
+}
+}
+
+// ---- Specialisation pour complexes -----
+GeneralFitData* NOMAdapter_TMatrix< complex<r_4> >::GetGeneralFitData(bool& adel
+ ,GeneralFitData::FitErrType errtype,double errscale,double errmin
+ ,int i1,int i2,int j1,int j2)
+{
+  return(NULL);
+}
+
+AnyDataObj* NOMAdapter_TMatrix< complex<r_4> >::FitResidusObj(GeneralFit& mfit)
+{
+  return(NULL);
+}
+
+AnyDataObj* NOMAdapter_TMatrix< complex<r_4> >::FitFunctionObj(GeneralFit& mfit)
+{
+  return(NULL);
+}
+
+GeneralFitData* NOMAdapter_TMatrix< complex<r_8> >::GetGeneralFitData(bool& adel
+ ,GeneralFitData::FitErrType errtype,double errscale,double errmin
+ ,int i1,int i2,int j1,int j2)
+{
+  return(NULL);
+}
+
+AnyDataObj* NOMAdapter_TMatrix< complex<r_8> >::FitResidusObj(GeneralFit& mfit)
+{
+  return(NULL);
+}
+
+AnyDataObj* NOMAdapter_TMatrix< complex<r_8> >::FitFunctionObj(GeneralFit& mfit)
+{
+  return(NULL);
+}
+
+// -------------------------------------------------------------
+
+/* --Methode-- */
+template <class T> 
+NTupInt_TMatrix<T>::NTupInt_TMatrix(TMatrix<T>* m)
+{
+mMtx = m;
+}
+
+/* --Methode-- */
+template <class T> 
+NTupInt_TMatrix<T>::~NTupInt_TMatrix()
+{
+}
+
+/* --Methode-- */
+template <class T> 
+uint_4 NTupInt_TMatrix<T>::NbLines() const
+{
+return( mMtx->NRows()*mMtx->NCols() );
+}
+
+/* --Methode-- */
+template <class T> 
+uint_4 NTupInt_TMatrix<T>::NbColumns() const 
+{
+return(8);
+}
+
+/* --Methode-- */
+template <class T> 
+r_8* NTupInt_TMatrix<T>::GetLineD(int n) const 
+{
+int i,j;
+if ((n < 0) || (n >= (int)(mMtx->NRows()*mMtx->NCols()) )) {
+  mRet[0] = n;
+  for(i=1; i<8; i++)  mRet[i] = 0.;
+}
+else { 
+  i = n/mMtx->NCols(); j = n%mMtx->NCols(); 
+  mRet[0] = n;  mRet[1] = i;  mRet[2] = j;  
+  mRet[3] = (*mMtx)(i,j);
+  mRet[4] = mRet[2];  mRet[5] = 0.;
+  mRet[6] = mRet[2];  mRet[7] = 0.;
+  }
+return(mRet);
+}
+
+/* --Methode-- */
+template <class T> 
+string NTupInt_TMatrix<T>::VarList_C(const char* nx) const 
+{
+string nomx;
+if (nx) nomx = nx;
+else nomx = "_xh_";
+string vardec = "double n,r,c,val,real,imag,mod,phas; \n";
+vardec += "n = " + nomx + "[0];  r = " + nomx + "[1]; c = " + nomx + "[2]; \n"; 
+vardec += "val = " + nomx + "[3]; \n";
+vardec += "real = " + nomx + "[4];  imag = " + nomx + "[5]; \n";
+vardec += "mod  = " + nomx + "[6];  phas = " + nomx + "[7]; \n";
+return(vardec);
+}
+
+/* --Methode-- */
+r_8* NTupInt_TMatrix< complex<r_4> >::GetLineD(int n) const 
+{
+int i,j;
+if ((n < 0) || (n >= (int)(mMtx->NRows()*mMtx->NCols()) )) {
+  mRet[0] = n;
+  for(i=1; i<8; i++)  mRet[i] = 0.;
+}
+else { 
+  i = n/mMtx->NCols(); j = n%mMtx->NCols(); 
+  mRet[0] = n;   mRet[1] = i;  mRet[2] = j;  
+  mRet[4] = (*mMtx)(i,j).real();  mRet[5] = (*mMtx)(i,j).imag();
+  mRet[3] = mRet[6] = sqrt(mRet[4]*mRet[4]+mRet[5]*mRet[5]);
+  mRet[7] = atan2(mRet[5], mRet[4]);
+}
+return(mRet);
+}
+
+r_8* NTupInt_TMatrix< complex<r_8> >::GetLineD(int n) const 
+{
+int i,j;
+if ((n < 0) || (n >= (int)(mMtx->NRows()*mMtx->NCols()) )) {
+  mRet[0] = n;
+  for(i=1; i<8; i++)  mRet[i] = 0.;
+}
+else { 
+  i = n/mMtx->NCols(); j = n%mMtx->NCols(); 
+  mRet[0] = n;   mRet[1] = i;  mRet[2] = j;  
+  mRet[4] = (*mMtx)(i,j).real();  mRet[5] = (*mMtx)(i,j).imag();
+  mRet[3] = mRet[6] = sqrt(mRet[4]*mRet[4]+mRet[5]*mRet[5]);
+  mRet[7] = atan2(mRet[5], mRet[4]);
+}
+return(mRet);
+}
+
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+//#pragma define_template NOMAdapter_TMatrix<uint_2>
+//#pragma define_template NOMAdapter_TMatrix<int_2>
+#pragma define_template NOMAdapter_TMatrix<int_4>
+#pragma define_template NOMAdapter_TMatrix<r_4>
+#pragma define_template NOMAdapter_TMatrix<r_8>
+#pragma define_template NOMAdapter_TMatrix< complex<r_4> >
+#pragma define_template NOMAdapter_TMatrix< complex<r_8> >
+//#pragma define_template NTupInt_TMatrix<uint_2>
+//#pragma define_template NTupInt_TMatrix<int_2>
+#pragma define_template NTupInt_TMatrix<int_4>
+#pragma define_template NTupInt_TMatrix<r_4>
+#pragma define_template NTupInt_TMatrix<r_8>
+#pragma define_template NTupInt_TMatrix< complex<r_4> >
+#pragma define_template NTupInt_TMatrix< complex<r_8> >
+#endif
+
+#if defined(ANSI_TEMPLATES) 
+//template class NOMAdapter_TMatrix<uint_2>;
+//template class NOMAdapter_TMatrix<int_2>;
+template class NOMAdapter_TMatrix<int_4>;
+template class NOMAdapter_TMatrix<r_4>;
+template class NOMAdapter_TMatrix<r_8>;
+template class NOMAdapter_TMatrix< complex<r_4> >;
+template class NOMAdapter_TMatrix< complex<r_8> >;
+// template class NTupInt_TMatrix<uint_2>;
+// template class NTupInt_TMatrix<int_2>;
+template class NTupInt_TMatrix<int_4>;
+template class NTupInt_TMatrix<r_4>;
+template class NTupInt_TMatrix<r_8>;
+template class NTupInt_TMatrix< complex<r_4> >;
+template class NTupInt_TMatrix< complex<r_8> >;
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/nomtmatvecadapter.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/nomtmatvecadapter.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/nomtmatvecadapter.h	(revision 2309)
@@ -0,0 +1,67 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Adaptateur d objets (pour NamedObjMgr) 
+// pour les classes TMatrix<T>, TVector<T> de Sophya
+//                                      Reza 11/99
+//  LAL-IN2P3/CNRS               CEA-DAPNIA     
+ 
+#ifndef NOMTMATVECADAPTER_H_SEEN
+#define NOMTMATVECADAPTER_H_SEEN
+
+#include "nomgadapter.h"
+#include "tmatrix.h"
+#include "generaldata.h"
+
+//---------------------------------------------------------------
+// Class Adaptateur d'objet (Pour NamedObjMgr) d'objet TMatrix 
+//---------------------------------------------------------------
+
+template <class T> 
+class NOMAdapter_TMatrix : public NObjMgrAdapter {
+public:
+				NOMAdapter_TMatrix(TMatrix<T>* m = NULL);
+  virtual			~NOMAdapter_TMatrix();
+
+  virtual NObjMgrAdapter*	Clone(AnyDataObj* o);
+
+  virtual string		GetDataObjType();
+
+  virtual AnyDataObj*		CloneDataObj(bool share=false);
+
+  virtual void			ReadFits(string const & flnm);
+  virtual void			SaveFits(string const & flnm);
+  virtual void			SavePPF(POutPersist& s, string const & nom);
+
+  virtual void			Print(ostream& os);
+  virtual PIDrawer*		GetDrawer(string& dopt);
+  virtual P2DArrayAdapter*	Get2DArray(string& dopt);
+  virtual NTupleInterface*	GetNTupleInterface(bool& adel);
+
+  virtual GeneralFitData* GetGeneralFitData(bool& adel
+          ,GeneralFitData::FitErrType errtype=GeneralFitData::DefaultError
+          ,double errscale=1.,double errmin=0.
+          ,int i1=0,int i2=-1,int j1=0,int j2=-1);
+  virtual AnyDataObj* FitResidusObj(GeneralFit& mfit);
+  virtual AnyDataObj* FitFunctionObj(GeneralFit& mfit);
+
+protected:
+  TMatrix<T>* mMtx;
+};
+
+// Class Interface NTuple pour TMatrix<T>
+
+template <class T> 
+class NTupInt_TMatrix : public NTupleInterface {
+public:
+			NTupInt_TMatrix(TMatrix<T>* m);
+  virtual		~NTupInt_TMatrix();
+  virtual uint_4        NbLines() const ;
+  virtual uint_4        NbColumns() const ;
+  virtual r_8 *         GetLineD(int n) const ;
+  virtual string        VarList_C(const char* nomx=NULL) const ;
+protected:
+  TMatrix<T>* mMtx;
+  mutable r_8 mRet[8];
+};
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/objlist.list
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/objlist.list	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/objlist.list	(revision 2309)
@@ -0,0 +1,30 @@
+basexecut.o
+contmodex.o
+cxxexecutor.o
+cxxexecwin.o
+flowmodex.o
+nobjmgr.o
+nomgadapter.o
+nomgfdadapter.o
+nomhistadapter.o
+nomimagadapter.o
+nomskymapadapter.o
+nomspecrespadapter.o
+nomtarradapter.o
+nomtmatvecadapter.o
+pawexecut.o
+pi2dvec.o
+piacmd.o
+piafitting.o
+pigfd1.o
+pigfd2.o
+pihisto.o
+pihisto2d.o
+piinit.o
+pintup3d.o
+pintuple.o
+pipodrw.o
+pisiadw.o
+pistdimgapp.o
+pitvmaad.o
+servnobjm.o
Index: /tags/V_Dec2002/SophyaPI/PIext/pawexecut.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/pawexecut.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/pawexecut.cc	(revision 2309)
@@ -0,0 +1,1523 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <iostream.h>
+#include <typeinfo>
+
+#include "strutil.h"
+#include "histos.h"
+#include "histos2.h"
+#include "hisprof.h"
+#include "ntuple.h"
+
+#include "pawexecut.h"
+#include "nobjmgr.h"
+#include "servnobjm.h"
+#include "nomgadapter.h"
+#include "pistdimgapp.h"
+
+#ifdef SANS_EVOLPLANCK
+#include "cvector.h"
+#include "matrix.h"
+#else
+#include "tmatrix.h"
+#include "tvector.h"
+#endif
+
+/* Reza + cmv  13/10/99 */
+
+uint_4 PAWExecutor::autoc_counter_ = 0;
+
+/* methode */
+PAWExecutor::PAWExecutor(PIACmd *piac, PIStdImgApp* app)
+: mApp(app)
+{
+string kw, usage;
+string hgrp = "pawCmd";
+
+kw = "reset";
+usage = "Reset histograms vectors or matrix";
+usage += "\n reset nameobj";
+piac->RegisterCommand(kw,usage,this,hgrp);
+
+kw = "n/plot";
+usage = "Plot NTuple variables a la paw (alias n/pl)";
+usage += "\n n/plot nameobj.x_exp [cut] [w_exp] [loop] [gratt]";
+usage += "\n n/plot nameobj.y_exp%x_exp [cut] [loop] [gratt]";
+usage += "\n n/plot nameobj.z_exp%y_exp%x_exp [cut] [loop] [gratt]";
+usage += "\n        for default use ! , loop=i1[:i2[:di]]";
+usage += "\n  Related commands: plot2dw plot3d";  
+piac->RegisterCommand(kw,usage,this,hgrp);
+
+kw = "n/proj";
+usage = "Project NTuple in histogram (1D or 2D) a la paw";
+usage += "\n n/proj nameproj nameobj.x_exp [cut] [w_exp] [loop] [gratt]";
+usage += "\n n/proj nameproj nameobj.y_exp%x_exp [cut] [w_exp] [loop] [gratt]";
+usage += "\n        for default use ! , loop=i1[:i2[:di]]";
+usage += "\n  Related commands: projh1d projh2d projprof exptovec";  
+piac->RegisterCommand(kw,usage,this,hgrp);
+
+kw = "n/scan";
+usage = "Scan NTuple a la paw";
+usage += "\n n/scan nameobj[.exp1%exp2%exp3] cut loop";
+usage += "\n               [-f:filename] [list_of_variables]";
+usage += "\n  loop : iev1[:iev2[:diev]] or !";
+usage += "\n  cut  : cut expression or 1. or !";
+usage += "\n  list_of_variables : default is all variables";
+usage += "\n                    : var1 var2 var3 ... varn";
+usage += "\n                    : var1 : var2   (from var1 to var2)";
+usage += "\n                    :  : var2   (from first variable to var2)";
+usage += "\n                    : var1 :    (from var1 to last variable)";
+usage += "\n                  ex: \"v1 : v3 v7 v4 : v6 v2 v9 :\"";
+usage += "\n exp1%exp2%exp3 :";
+usage += "\n           if given add exp1,exp2,exp3 to the variable list";
+usage += "\n -f:filename : write into \"filename\", Default is to stdout";
+piac->RegisterCommand(kw,usage,this,hgrp);
+
+kw = "h/integ";
+usage = "Integrate a 1D histogram";
+usage += "\n h/integ nameh1d [norm]";
+usage += "\n norm<=0 means no normalisation (def norm=1)";
+usage += "\n  Related commands: h/deriv v/integ v/deriv";
+piac->RegisterCommand(kw,usage,this,hgrp);
+
+//#ifndef SANS_EVOLPLANCK
+kw = "v/integ";
+usage = "Integrate a TVector / vector";
+usage += "\n v/integ namevec [norm]";
+usage += "\n norm<=0 means no normalisation (def norm=0)";
+usage += "\n  Related commands: h/integ h/deriv v/deriv";
+piac->RegisterCommand(kw,usage,this,hgrp);
+//#endif
+
+kw = "h/deriv";
+usage = "Derivate a 1D histogram";
+usage += "\n h/deriv nameh1d";
+usage += "\n  Related commands: h/integ v/integ v/deriv";
+piac->RegisterCommand(kw,usage,this,hgrp);
+
+//#ifndef SANS_EVOLPLANCK
+kw = "v/deriv";
+usage = "Derivate a TVector / vector";
+usage += "\n v/deriv namevec [deriv_option]";
+usage += "\n deriv_option -1 replace v[i] with v[i]-v[i-1]";
+usage += "\n               0 replace v[i] with (v[i+1]-v[i-1])/2 (default)";
+usage += "\n              +1 replace v[i] with v[i+1]-v[i]";
+usage += "\n  Related commands: h/integ h/deriv v/integ";
+piac->RegisterCommand(kw,usage,this,hgrp);
+//#endif
+
+kw = "h/rebin";
+usage = "Rebin a 1D histogram or profile";
+usage += "\n h/rebin nameh1d nbin";
+piac->RegisterCommand(kw,usage,this,hgrp);
+
+kw = "h/cadd";
+usage = "Add a constant to an histogram, a vector or a matrix";
+usage += "\n h/cadd namehisto val";
+usage += "\n  Related commands: h/cmult h/oper";  
+piac->RegisterCommand(kw,usage,this,hgrp);
+
+kw = "h/cmult";
+usage = "Multiply an histogram, a vector or a matrix by a constant";
+usage += "\n h/cmult namehisto val";
+usage += "\n  Related commands: h/cadd h/oper";  
+piac->RegisterCommand(kw,usage,this,hgrp);
+
+kw = "h/oper";
+usage = "Operation on histograms vectors or matrices";
+usage += "\n h/oper @ h1 h2 hres";
+usage += "\n        hres = h1 @ h2   with @ = (+,-,*,/)";
+usage += "\n For vectors and matrices, operations are elements by elements";
+usage += "\n  Related commands: h/cadd h/cmult";  
+piac->RegisterCommand(kw,usage,this,hgrp);
+
+kw = "h/plot/2d";
+usage = "Specific plot for 2D histogrammes";
+usage += "\n h/plot/2d nameh2d show        : infos on 2D histogramme";
+usage += "\n h/plot/2d nameh2d h    [dopt] : plot 2D histogramme";
+usage += "\n h/plot/2d nameh2d px   [dopt] : plot X projection";
+usage += "\n h/plot/2d nameh2d py   [dopt] : plot Y projection";
+usage += "\n h/plot/2d nameh2d bx n [dopt] : plot X band number n";
+usage += "\n h/plot/2d nameh2d by n [dopt] : plot Y band number n";
+usage += "\n h/plot/2d nameh2d sx n [dopt] : plot X slice number n";
+usage += "\n h/plot/2d nameh2d sy n [dopt] : plot Y slice number n";
+usage += "\n                      n < 0 means Show Info";
+piac->RegisterCommand(kw,usage,this,hgrp);
+
+kw = "h/put_vec";
+usage = "Put content of vector (matrix) into content of histogram 1D or 2D";
+usage += "\n h/put_vec nameh1d namevector [cont,err2]";
+usage += "\n h/put_vec nameh2d namematrix [cont,err2]";
+usage += "\n     cont : put into histogramme content";
+usage += "\n     err2 : put into histogramme error^2";
+usage += "\n  Related commands: h/get_vec";  
+piac->RegisterCommand(kw,usage,this,hgrp);
+
+kw = "h/get_vec";
+usage = "Get content of histogram 1D profile or 2D into vector (matrix)";
+usage += "\n h/get_vec nameh1d namevector [cont,err2,absc] [proj]";
+usage += "\n h/get_vec nameh2d namematrix [cont,err2,absc]";
+usage += "\n   cont : get histogramme content";
+usage += "\n   err2 : get histogramme error^2";
+usage += "\n   absc : get histogramme low bin abscissa (1D only)";
+usage += "\n     proj :";
+usage += "\n            show  : show available projections for Histo2D";
+usage += "\n            px    : get X projection";
+usage += "\n            py    : get Y projection";
+usage += "\n            bx n  : get X band number n";
+usage += "\n            by n  : get Y band number n";
+usage += "\n            sx n  : get X slice number n";
+usage += "\n            sy n  : get Y slice number n";
+usage += "\n  Related commands: h/put_vec";  
+piac->RegisterCommand(kw,usage,this,hgrp);
+
+kw = "h/copy";
+usage = "Copy content of object1 into object2";
+usage += "\n objects are Vector,Matrix,Histo,Histo2D";
+usage += "\n h/copy namefrom nametocopy [i1[:i2]] [j1[:j2]] [ic1[:jc1]]";
+usage += "\n   copy obj1Dfrom(i1->i2) into obj1Dto(ic1->)";
+usage += "\n   copy obj2Dfrom(i1,j1->i2,j2) into obj2Dto(ic1,jc1->)";
+usage += "\n Warning: elements from i1 to i2 included are copied";
+usage += "\n If obj1Dto does not exist, is is created with size i2-i1+1";
+usage += "\n    or obj2Dto with size i2-i1+1,j2-j1+1";
+usage += "\n The adressed content of obj?Dfrom is overwritten";
+usage += "\n The non-adressed content of obj?Dfrom is left unchanged";
+usage += "\n  Related commands: copy";  
+piac->RegisterCommand(kw,usage,this,hgrp);
+
+kw = "h/set/err";
+usage = "Set Histo,Histo2D errors for range of bins or range of values";
+usage += "\n h/set/err namehisto setvalue i1[:i2]  [j1[:j2]]";
+usage += "\n     set error to setvalue for bin range i1:i2  j1:j2";
+usage += "\n h/set/err namehisto setvalue v v1:v2";
+usage += "\n     set error to setvalue for content values range v1:v2";
+usage += "\n h/set/err namehisto setvalue e e1:e2";
+usage += "\n     set error to setvalue for error values range v1:v2";
+usage += "\n  Related commands: h/set/cont";  
+piac->RegisterCommand(kw,usage,this,hgrp);
+
+kw = "h/set/cont";
+usage = "Set Histo,Histo2D content for range of bins or range of values";
+usage += "\n h/set/cont namehisto setvalue i1[:i2]  [j1[:j2]]";
+usage += "\n     set content to setvalue for bin range i1:i2  j1:j2";
+usage += "\n h/set/cont namehisto setvalue v v1:v2";
+usage += "\n     set content to setvalue for content values range v1:v2";
+usage += "\n h/set/cont namehisto setvalue e e1:e2";
+usage += "\n     set content to setvalue for error values range v1:v2";
+usage += "\n  Related commands: h/set/err";  
+piac->RegisterCommand(kw,usage,this,hgrp);
+
+kw = "h/err";
+usage = "Set Histo,Histo2D error to function of bin content value";
+usage += "\n h/err namehisto expr_func";
+usage += "\n  Related commands: h/set/err";  
+piac->RegisterCommand(kw,usage,this,hgrp);
+
+}
+
+/* methode */
+PAWExecutor::~PAWExecutor()
+{
+}
+
+/* methode */
+int PAWExecutor::Execute(string& kw, vector<string>& tokens, string& toks)
+{
+if(kw == "reset") {
+  reset(tokens); return(0);
+} else if(kw == "n/plot" || kw == "n/pl") {
+  n_plot(tokens); return(0);
+} else if(kw == "n/proj") {
+  n_proj(tokens); return(0);
+} else if(kw == "n/scan") {
+  n_scan(tokens); return(0);
+} else if(kw == "h/integ") {
+  h_integ(tokens); return(0);
+  //#ifndef SANS_EVOLPLANCK
+} else if(kw == "v/integ") {
+  v_integ(tokens); return(0);
+  //#endif
+} else if(kw == "h/deriv") {
+  h_deriv(tokens); return(0);
+  //#ifndef SANS_EVOLPLANCK
+} else if(kw == "v/deriv") {
+  v_deriv(tokens); return(0);
+  //#endif
+} else if(kw == "h/rebin") {
+  h_rebin(tokens); return(0);
+} else if(kw == "h/cadd") {
+  h_cadd(tokens); return(0);
+} else if(kw == "h/cmult") {
+  h_cmult(tokens); return(0);
+} else if(kw == "h/oper") {
+  h_oper(tokens); return(0);
+} else if(kw == "h/plot/2d") {
+  h_plot_2d(tokens); return(0);
+} else if(kw == "h/put_vec") {
+  h_put_vec(tokens); return(0);
+} else if(kw == "h/get_vec") {
+  h_get_vec(tokens); return(0);
+} else if(kw == "h/copy") {
+  h_copy(tokens); return(0);
+} else if(kw == "h/set/err") {
+  string dum = "err";
+  h_set(dum,tokens); return(0);
+} else if(kw == "h/set/cont") {
+  string dum = "cont";
+  h_set(dum,tokens); return(0);
+} else if(kw == "h/err") {
+  h_err(tokens); return(0);
+} else return(1); 
+}
+
+/* methode */
+void PAWExecutor::reset(vector<string>& tokens)
+// Reset d'histogrammes, vecteurs et matrices
+{
+if(tokens.size() < 1)
+  {cout<<"Usage: reset nameobj"<<endl; return;}
+NamedObjMgr omg;
+AnyDataObj* mobj = omg.GetObj(tokens[0]);
+if(mobj == NULL)
+  {cout<<"PAWExecutor::reset Error , Pas d'objet de nom "<<tokens[0]<<endl;
+   return;}
+string ctyp = typeid(*mobj).name();
+
+#ifdef SANS_EVOLPLANCK
+if(typeid(*mobj)==typeid(Vector))       {Vector*  ob=(Vector*) mobj; ob->Zero();}
+else if(typeid(*mobj)==typeid(Matrix))  {Matrix*  ob=(Matrix*) mobj; ob->Zero();}
+#else
+ if(typeid(*mobj)==typeid(Vector))       {Vector*  ob=(Vector*) mobj; (*ob) = 0.; }
+// ob->DataBlock().Reset(0.);}
+ else if(typeid(*mobj)==typeid(Matrix))   {Matrix*  ob=(Matrix*) mobj; (*ob) = 0.; }
+//ob->DataBlock().Reset(0.);}
+#endif
+else if(typeid(*mobj)==typeid(Histo))   {Histo*   ob=(Histo*)  mobj; ob->Zero();}
+else if(typeid(*mobj)==typeid(HProf))   {HProf*   ob=(HProf*)  mobj; ob->Zero();}
+else if(typeid(*mobj)==typeid(Histo2D)) {Histo2D* ob=(Histo2D*)mobj; ob->Zero();}
+else {
+  cout<<"PAWExecutor::reset Error , No reset possible on "<<ctyp<<endl;
+  return;
+}
+
+return;
+}
+
+/* methode */
+void PAWExecutor::n_plot(vector<string>& tokens)
+// Equivalent n/plot de paw
+// Plot 1D
+//   n/plot nameobj.x_exp [cut] [w_exp] [gratt]
+// Plot 2D (plot2dw)
+//   n/plot nameobj.y_exp%x_exp [cut] [w_exp] [gratt]
+// Plot 3D (plot3d)
+//   n/plot nameobj.z_exp%y_exp%x_exp [cut] [gratt]
+{
+if(tokens.size() < 1) {
+  cout
+  <<"Usage: n/plot nameobj.x_exp [cut] [w_exp] [loop] [gratt] [nomh1]"<<endl
+  <<"       n/plot nameobj.y_exp%x_exp [cut] [loop] [gratt]"<<endl
+  <<"       n/plot nameobj.z_exp%y_exp%x_exp [cut] [loop] [gratt]"<<endl
+  <<"              for default use ! , loop=i1[:i2[:di]]"<<endl;
+  return;
+}
+string nameobj,expx,expy,expz;
+int_4 nvar = decodepawstring(tokens[0],nameobj,expx,expy,expz);
+string expcut = "1"; string expwt = "1."; string loop = "";
+string dopt = ""; string nameproj="";
+if(tokens.size()>=2) expcut = tokens[1]; if(expcut=="!") expcut="1";
+
+NamedObjMgr omg;
+Services2NObjMgr* srvo = omg.GetServiceObj();
+
+if(nvar<=0) {
+  cout<<"PAWExecutor::n_plot Error: bad coding "<<tokens[0]<<endl;
+} else if(nvar==1) { // c'est un plot 1D
+  if(tokens.size()>=3) expwt    = tokens[2]; if(expwt=="!") expwt="1.";
+  if(tokens.size()>=4) loop     = tokens[3]; if(loop=="!") loop="";
+  if(tokens.size()>=5) dopt     = tokens[4]; if(dopt=="!") dopt="";
+  if(tokens.size()>=6) nameproj = tokens[5];
+  if(nameproj.length()<=0 || nameproj=="!") {
+    nameproj = "/autoc/paw_n_plot1D_";
+    AnyDataObj* mobj = omg.GetObj(nameproj);
+    if(mobj!=NULL) {
+      char buff[16]; autoc_counter_++; sprintf(buff,"%d",autoc_counter_);
+      nameproj += buff;
+    }
+  }
+  srvo->ProjectH1(nameobj,expx,expwt,expcut,nameproj,dopt,loop);
+} else if(nvar==2) { // c'est un plot 2D
+  if(tokens.size()>=3) loop = tokens[2]; if(loop=="!") loop="";
+  if(tokens.size()>=4) dopt = tokens[3];
+  string err = "";
+  srvo->DisplayPoints2D(nameobj,expx,expy,err,err,expcut,dopt,loop);
+} else {             // c'est un plot 3D
+  if(tokens.size()>=3) loop = tokens[2]; if(loop=="!") loop="";
+  if(tokens.size()>=4) dopt = tokens[3];
+  srvo->DisplayPoints3D(nameobj,expx,expy,expz,expcut,dopt,loop);
+}
+
+return;
+}
+
+/* methode */
+void PAWExecutor::n_proj(vector<string>& tokens)
+// Equivalent n/proj de paw
+// Project NTuple in histogram a la paw
+// Dans un Histo 1D
+//   n/proj nameproj nameobj.x_exp [cut] [w_exp] [gratt]
+// Dans un Histo 2D ou un HProf (dans ce cas nameproj doit etre cree).
+//   n/proj nameproj nameobj.y_exp%x_exp [cut] [w_exp] [gratt]
+{
+if(tokens.size()<2)
+  {cout<<"Usage: n/proj nameproj nameobj.[y_exp%]x_exp [cut] [w_exp] [loop] [gratt]"<<endl
+       <<"              for default use ! , loop=i1[:i2[:di]]"<<endl; return;}
+string nameproj = tokens[0];
+string nameobj,expx,expy,expz;
+int_4 nvar = decodepawstring(tokens[1],nameobj,expx,expy,expz);
+string expcut = "1"; string expwt = "1."; string loop = ""; string dopt = "";
+if(tokens.size()>=3) expcut = tokens[2]; if(expcut=="!") expcut="1";
+if(tokens.size()>=4) expwt  = tokens[3]; if(expwt=="!") expwt="1.";
+if(tokens.size()>=5) loop   = tokens[4]; if(loop=="!") loop="";
+if(tokens.size()>=6) dopt   = tokens[5];
+
+NamedObjMgr omg;
+Services2NObjMgr* srvo = omg.GetServiceObj();
+
+if(nvar==1) {
+  // c'est une projection dans un histo 1D
+  srvo->ProjectH1(nameobj,expx,expwt,expcut,nameproj,dopt,loop);
+} else if(nvar==2) {
+  // c'est une projection dans un histo2D
+  // OU un HProf si nameproj est un HProf un deja defini
+  AnyDataObj* mobj = omg.GetObj(nameproj);
+  if(mobj==NULL)
+    srvo->ProjectH2(nameobj,expx,expy,expwt,expcut,nameproj,dopt,loop);
+  else if(dynamic_cast<HProf*>(mobj))
+    srvo->ProjectHProf(nameobj,expx,expy,expwt,expcut,nameproj,dopt,loop);
+  else
+    srvo->ProjectH2(nameobj,expx,expy,expwt,expcut,nameproj,dopt,loop);
+} else {
+  cout<<"PAWExecutor::n_proj Error: bad coding "<<tokens[1]<<" nvar="<<nvar<<endl;
+}
+
+return;
+}
+
+/* methode */
+void PAWExecutor::n_scan(vector<string>& tokens)
+{
+if(tokens.size()<3)
+  {cerr<<"Usage: n/scan nameobj[.exp1%exp2%exp3] cut loop\n"
+       <<"       [-f:filename] [list_of_variables]"<<endl; return;}
+
+// decodage des premiers arguments
+string nameobj,expr[4];
+int_4 nexpr = decodepawstring(tokens[0],nameobj,expr[0],expr[1],expr[2]);
+if(nexpr<4) {for(int_4 i=nexpr;i<4;i++) expr[i]="1.";}
+string expcut = tokens[1]; if(expcut=="!") expcut="1";
+string loop   = tokens[2]; if(loop=="!") loop="";
+FILE* fout = NULL;
+uint_4 ldebvar = 3;
+if(tokens.size()>3) {
+  if(tokens[3].find("-f:") == 0) {
+    string filename = tokens[3].substr(3);
+    if(filename.size()>0) {
+      fout = fopen(filename.c_str(),"w");
+      if(fout==NULL) 
+        {cerr<<"PAWExecutor::n_scan Error, file "<<filename
+             <<" not opened"<<endl; return;}
+    }
+    ldebvar++;
+  }
+}
+
+// ntuple adaptateur
+NamedObjMgr omg;
+Services2NObjMgr& srvo = *omg.GetServiceObj();
+NObjMgrAdapter* obja = omg.GetObjAdapter(nameobj); // Ne pas deleter
+if(obja == NULL)
+  {cerr<<"PAWExecutor::n_scan Error, ObjAdapter==NULL for "
+       <<nameobj<<endl; return;}
+bool adel = true;
+NTupleInterface* objnt = obja->GetNTupleInterface(adel);
+if(objnt == NULL)
+  {cerr<<"PAWExecutor::n_scan Error, NTupleInterface==NULL for "
+       <<nameobj<<endl; return;}
+
+// function pour le choix
+string  vardec = objnt->VarList_C("_zz6qi_");
+PlotExprFunc f = srvo.LinkExprFunc(vardec,expr[0],expr[1],expr[2],expr[3],expcut);
+if(!f)
+  {cerr<<"PAWExecutor::n_scan Error, Creation PlotExprFunc"<<endl; 
+   if(adel) delete objnt; if(fout) fclose(fout); return;}
+
+// variables a imprimer
+// "rien"          --> de 0 a ncol-1 (toutes les variables)
+// : v1            --> de 0 a v1
+// v1 :            --> de v1 a ncol-1
+// v1 : v2         --> de v1 a v2 (si v2 apres v1)
+//                     v1 et v2   (si v2 avant v1)
+// v1 v2 v3 v4     --> v1 v2 v3 v4 (ordre indifferent)
+// et toute combinaison : "v1 : v3 v7 v4 : v6 v2 v9 :"
+//        --> v1 v2 v3  v7  v4 v5 v6  v2  v9 v10...v(ncol-1)
+int_4 ncol = objnt->NbColumns();
+if(ncol<=0)
+  {cerr<<"PAWExecutor::n_scan Error, no columns for NTuple"<<endl;
+   return;}
+vector<int_4> varnum;
+if(ldebvar>=tokens.size()) {   // Toutes les variables
+  for(int_4 i=0;i<ncol;i++) varnum.push_back(i);
+} else {   // Choix de certaines variables
+  int_4 k,klast,kk; bool frlast=false;
+  if(tokens[ldebvar]==":") {varnum.push_back(0); frlast=true;}
+  else {k = objnt->ColumnIndex(tokens[ldebvar]); varnum.push_back(k);}
+  ldebvar++;
+  if(ldebvar<tokens.size()) for(uint_4 i=ldebvar;i<tokens.size();i++) {
+    if(tokens[i]!=":") {  // pas un separateur
+      k = klast = objnt->ColumnIndex(tokens[i]);
+      if(frlast) klast = varnum[varnum.size()-1] + 1;
+      if(klast>k) klast=k;
+      for(kk=klast;kk<=k;kk++) varnum.push_back(kk);
+      frlast=false;
+    } else if(i==tokens.size()-1) {  // separateur a la fin
+      k = ncol-1;
+      klast = varnum[varnum.size()-1] + 1;
+      if(klast>k) klast=k;
+      for(kk=klast;kk<=k;kk++) varnum.push_back(kk);
+    } else frlast=true;  // separateur pas a la fin
+  }
+}
+
+vector<string> varname;
+if(varnum.size()>0) for(int_4 i=0;i<(int)varnum.size();i++) {
+  if(varnum[i]<0 || varnum[i]>=ncol)
+    {cerr<<"PAWExecutor::n_scan Error, bad variable name at pos "
+         <<i<<endl; if(adel) delete objnt; if(fout) fclose(fout); return;}
+  string dum = objnt->ColumnName(varnum[i]);
+  varname.push_back(dum);
+}
+
+// evenements a utiliser
+int_4 k1=0, k2=objnt->NbLines(), dk=1;
+srvo.DecodeLoopParameters(loop,k1,k2,dk);
+if (k1<0) k1=0;
+if (k2<0) k2=objnt->NbLines();
+if (k2>(int)objnt->NbLines()) k2=objnt->NbLines();
+if (dk<=0) dk=1;
+
+// boucle sur les evenements et print
+try  {
+  int_4 i;
+  if(fout) fprintf(fout,"#ev "); else printf("#ev ");
+  for(i=0;i<(int)varname.size();i++)
+    if(fout) fprintf(fout,"%s ",varname[i].c_str());
+    else      printf(     "%s ",varname[i].c_str());
+  if(nexpr>0) for(i=0;i<nexpr;i++)
+    if(fout) fprintf(fout,"%s ",expr[i].c_str());
+    else      printf(     "%s ",expr[i].c_str());
+  if(fout) fprintf(fout,"\n"); else printf("\n");
+ 
+  double xnt[5]={0,0,0,0,0};
+  double* xn;
+  for(int_4 k=k1; k<k2; k += dk)    {
+    xn = objnt->GetLineD(k);
+    if(f(xn,xnt,xnt+1,xnt+2,xnt+3) != 0) {
+      if(fout) fprintf(fout,"%d ",k); else printf("%d ",k);
+      for(i=0;i<(int)varnum.size();i++) {
+        if(fout) fprintf(fout,"%g ",*(xn+varnum[i]));
+        else      printf(     "%g ",*(xn+varnum[i]));
+      }
+      if(nexpr>0) for(i=0;i<nexpr;i++) {
+        if(fout) fprintf(fout,"%g ",*(xnt+i));
+        else      printf(     "%g ",*(xnt+i));
+      }
+      if(fout) fprintf(fout,"\n"); else printf("\n");
+    }
+  }
+}   // fin du try
+#ifdef SANS_EVOLPLANCK
+CATCH(merr) {
+  fflush(stdout); cout<<endl; cerr<<endl;
+  string es = PeidaExc(merr);
+  cerr<<"Services2NObjMgr::ComputeExpressions()  Exception :"<<merr<<es;
+} ENDTRY;
+#else
+catch ( PException exc ) {
+  fflush(stdout); cout<<endl; cerr<<endl;
+  cerr<<"Services2NObjMgr::ComputeExpressions()  Exception :"<<exc.Msg()<<endl; 
+}
+#endif
+
+if(adel) delete objnt;
+if(fout) fclose(fout);
+srvo.CloseDLL(); // Fermeture du fichier .so
+return;
+}
+
+/* methode */
+void PAWExecutor::h_integ(vector<string>& tokens)
+// Pour remplacer le contenu d'un histo 1D par son integrale
+{
+if(tokens.size()<1)
+  {cout<<"Usage: h/integ nameh1d [norm]"<<endl; return;}
+NamedObjMgr omg;
+AnyDataObj* mobj = omg.GetObj(tokens[0]);
+if(mobj==NULL)
+  {cout<<"PAWExecutor::h_integ Error: unknow object"<<tokens[0]<<endl;
+  return;}
+r_8 norm = 1.;
+if(tokens.size()>=2) norm = atof(tokens[1].c_str());
+// attention: dynamic_cast<Histo*>(HProf)=Vrai!
+Histo* h1 = dynamic_cast<Histo*>(mobj);
+HProf* hp = dynamic_cast<HProf*>(mobj);
+if(hp || !h1)
+  {cout<<"PAWExecutor::h_integ Error: "<<tokens[0]<<" not an Histo"<<endl;
+  return;}
+h1->HInteg(norm);
+}
+
+/* methode */
+void PAWExecutor::v_integ(vector<string>& tokens)
+// Pour remplacer le contenu d'un TVector<r_8> par son integrale
+//   normalisee a norm:
+// Si norm <= 0 : pas de normalisation, integration seule
+{
+if(tokens.size()<1)
+  {cout<<"Usage: v/integ namevec [norm]"<<endl; return;}
+NamedObjMgr omg;
+AnyDataObj* mobj = omg.GetObj(tokens[0]);
+if(mobj==NULL)
+  {cout<<"PAWExecutor::v_integ Error: unknow object"<<tokens[0]<<endl;
+  return;}
+r_8 norm=-1.;
+if(tokens.size()>=2) norm = atof(tokens[1].c_str());
+#ifdef SANS_EVOLPLANCK
+Vector* v = dynamic_cast<Vector*>(mobj);
+#else
+TVector<r_8>* v = dynamic_cast<TVector<r_8>*>(mobj);
+#endif
+
+if(!v)
+  {cout<<"PAWExecutor::v_integ Error: "<<tokens[0]<<" not a TVector/Vector"<<endl;
+  return;}
+
+#ifdef SANS_EVOLPLANCK
+uint_4 n = v->NElts();
+#else
+uint_4 n = v->Size();
+#endif
+
+if(n==0)
+  {cout<<"PAWExecutor::v_integ Error: "<<tokens[0]<<" is an empty vector"<<endl;
+  return;}
+if(n>1) for(uint_4 i=1;i<n;i++) (*v)(i)+=(*v)(i-1);
+if(norm<=0. || (*v)(n-1)==0.) return;
+norm /= (*v)(n-1);
+for(uint_4 i=0;i<n;i++) (*v)(i) *= norm;
+}
+
+/* methode */
+void PAWExecutor::h_deriv(vector<string>& tokens)
+// Pour remplacer le contenu d'un histo 1D par sa derivee
+{
+if(tokens.size()<1)
+  {cout<<"Usage: h/deriv nameh1d"<<endl; return;}
+NamedObjMgr omg;
+AnyDataObj* mobj = omg.GetObj(tokens[0]);
+if(mobj==NULL)
+  {cout<<"PAWExecutor::h_deriv Error: unknow object"<<tokens[0]<<endl;
+  return;}
+// attention: dynamic_cast<Histo*>(HProf)=Vrai!
+Histo* h1 = dynamic_cast<Histo*>(mobj);
+HProf* hp = dynamic_cast<HProf*>(mobj);
+if(hp || !h1)
+  {cout<<"PAWExecutor::h_deriv Error: "<<tokens[0]<<" not an Histo"<<endl;
+  return;}
+h1->HDeriv();
+}
+
+/* methode */
+void PAWExecutor::v_deriv(vector<string>& tokens)
+// Pour remplacer le contenu d'un TVector<r_8> par sa derivee
+// deriv_option = -1 replace v[i] with v[i]-v[i-1]
+//              =  0 replace v[i] with (v[i+1]-v[i-1])/2 (default)
+//              = +1 replace v[i] with v[i+1]-v[i]
+{
+if(tokens.size()<1)
+  {cout<<"Usage: v/deriv namevec [deriv_option(-1,0,+1)]"<<endl; return;}
+NamedObjMgr omg;
+AnyDataObj* mobj = omg.GetObj(tokens[0]);
+if(mobj==NULL)
+  {cout<<"PAWExecutor::v_deriv Error: unknow object"<<tokens[0]<<endl;
+  return;}
+int_4 deriv_option = 0;
+if(tokens.size()>=2) deriv_option = atoi(tokens[1].c_str());
+
+#ifdef SANS_EVOLPLANCK
+Vector* v = dynamic_cast<Vector*>(mobj);
+#else
+TVector<r_8>* v = dynamic_cast<TVector<r_8>*>(mobj);
+#endif
+
+if(!v)
+  {cout<<"PAWExecutor::v_deriv Error: "<<tokens[0]<<" not a TVector/Vector"<<endl;
+  return;}
+
+
+#ifdef SANS_EVOLPLANCK
+uint_4 n = v->NElts();
+#else
+uint_4 n = v->Size();
+#endif
+
+if(n==0)
+  {cout<<"PAWExecutor::v_deriv Error: "<<tokens[0]<<" is an empty vector"<<endl;
+  return;}
+if(n<=1) return;
+
+#ifdef SANS_EVOLPLANCK
+Vector vsave(*v);
+#else
+TVector<r_8> vsave(*v,false);
+#endif
+
+if(deriv_option<0) {
+  for(uint_4 i=1;i<n;i++) (*v)(i) = vsave(i)-vsave(i-1);
+  (*v)(0) = (*v)(1);
+} else if(deriv_option>0) {
+  for(uint_4 i=0;i<n-1;i++) (*v)(i) = vsave(i+1)-vsave(i);
+  (*v)(n-1) = (*v)(n-2);
+} else {
+  for(uint_4 i=1;i<n-1;i++) (*v)(i) = (vsave(i+1)-vsave(i-1))/2.;
+  (*v)(0)   = vsave(1)-vsave(0);
+  (*v)(n-1) = vsave(n-1)-vsave(n-2);
+}
+}
+
+
+/* methode */
+void PAWExecutor::h_rebin(vector<string>& tokens)
+// Pour re-binner un histogramme 1D
+{
+if(tokens.size()<2)
+  {cout<<"Usage: h/rebin nameh1d nbin"<<endl; return;}
+NamedObjMgr omg;
+AnyDataObj* mobj = omg.GetObj(tokens[0]);
+if(mobj==NULL)
+  {cout<<"PAWExecutor::h_rebin Error: unknow object"<<tokens[0]<<endl;
+  return;}
+int_4 nbin = atoi(tokens[1].c_str());
+Histo* h1 = dynamic_cast<Histo*>(mobj);
+// Ca marche aussi pour les HProf, HRebin a ete passe virtuel
+//HProf* hp = dynamic_cast<HProf*>(mobj); if(hp || !h1)
+if(!h1)
+  {cout<<"PAWExecutor::h_rebin Error: "<<tokens[0]<<" not an Histo/HProf"<<endl;
+  return;}
+h1->HRebin(nbin);
+}
+
+/* methode */
+void PAWExecutor::h_cadd(vector<string>& tokens)
+// Additionne une constante a un histogramme
+{
+if(tokens.size()<2)
+  {cout<<"Usage: h/cadd nameh1d val"<<endl; return;}
+NamedObjMgr omg;
+AnyDataObj* mobj = omg.GetObj(tokens[0]);
+if(mobj==NULL)
+  {cout<<"PAWExecutor::h_cadd Error: unknow object"<<tokens[0]<<endl;
+  return;}
+r_8 val = atof(tokens[1].c_str());
+Histo*   h1 = dynamic_cast<Histo*>(mobj);
+HProf*   hp = dynamic_cast<HProf*>(mobj);
+Histo2D* h2 = dynamic_cast<Histo2D*>(mobj);
+Vector*  v  = dynamic_cast<Vector*>(mobj);
+Matrix*  m  = dynamic_cast<Matrix*>(mobj);
+if(h1 && !hp) *h1 += val;
+else if(h2)   *h2 += val;
+else if(v)    *v  += val;
+else if(m)    *m  += val;
+else cout<<"PAWExecutor::h_cadd Error: not implemented for "<<typeid(*mobj).name()<<endl;
+}
+
+/* methode */
+void PAWExecutor::h_cmult(vector<string>& tokens)
+// Multiplie un histogramme par une constante
+{
+if(tokens.size()<2)
+  {cout<<"Usage: h/cmult nameh1d val"<<endl; return;}
+NamedObjMgr omg;
+AnyDataObj* mobj = omg.GetObj(tokens[0]);
+if(mobj==NULL)
+  {cout<<"PAWExecutor::h_cmult Error: unknow object"<<tokens[0]<<endl;
+  return;}
+r_8 val = atof(tokens[1].c_str());
+Histo*   h1 = dynamic_cast<Histo*>(mobj);
+HProf*   hp = dynamic_cast<HProf*>(mobj);
+Histo2D* h2 = dynamic_cast<Histo2D*>(mobj);
+Vector*  v  = dynamic_cast<Vector*>(mobj);
+Matrix*  m  = dynamic_cast<Matrix*>(mobj);
+if(h1 && !hp) *h1 *= val;
+else if(h2)   *h2 *= val;
+else if(v)    *v  += val;
+else if(m)    *m  += val;
+else cout<<"PAWExecutor::h_mult Error: not implemented for "<<typeid(*mobj).name()<<endl;
+}
+
+/* methode */
+void PAWExecutor::h_oper(vector<string>& tokens)
+// Equivalent h/oper/add sub,mul,div de paw
+// Operation entre 2 histogrammes ou 2 vecteurs ou 2 matrices
+// h/oper @ h1 h2 hres
+// hres = h1 @ h2    with @ = (+,-,*,/)
+// Pour les vecteurs et les matrices, il sagit d'operations elements a elements
+{
+if(tokens.size()<4)
+  {cout<<"Usage: n/oper @ h1 h2 hres with @=(+,-,*,/,@)"<<endl;
+   return;}
+
+// Decode arguments
+const char * oper = tokens[0].c_str();
+if( oper[0]!='+' && oper[0]!='-' && oper[0]!='*' && oper[0]!='/' )
+  {cout<<"PAWExecutor::h_oper Error: unknow operation "<<oper<<endl;
+  return;}
+string h1name = tokens[1];
+string h2name = tokens[2];
+string h3name = tokens[3];
+
+// Get objects
+NamedObjMgr omg;
+AnyDataObj* mobjh1 = omg.GetObj(h1name);
+AnyDataObj* mobjh2 = omg.GetObj(h2name);
+if( mobjh1==NULL || mobjh2==NULL )
+  {cout<<"PAWExecutor::h_oper Error: unknow object(s) "<<h1name<<" or "<<h2name<<endl;
+  return;}
+AnyDataObj* mobjh3 = omg.GetObj(h3name);
+
+// Operations on HProf, only + is working
+if( dynamic_cast<HProf*>(mobjh1) != NULL ) {
+  if( oper[0]!='+' )
+    { cout<<"PAWExecutor::h_oper Error: operation "<<oper
+          <<" not implemented for HProf"<<endl; return;}
+  if( dynamic_cast<HProf*>(mobjh2) == NULL )
+    {cout<<"PAWExecutor::h_oper Error: type mismatch between h1 and h2\n"
+         <<typeid(*mobjh1).name()<<" , "<<typeid(*mobjh2).name()<<endl;
+    return;}
+  HProf* h1 =(HProf*) mobjh1;
+  HProf* h2 =(HProf*) mobjh2;
+  if( h1->NBins() != h2->NBins() )
+    {cout<<"PAWExecutor::h_oper Error: size mismatch between h1, h2 "
+         <<h1->NBins()<<" "<<h2->NBins()<<endl; return;}
+  HProf* h3 = NULL;
+  if( mobjh3 == NULL ) // l'objet n'existe pas, on le cree
+    {h3 = new HProf(*h1); h3->Zero(); omg.AddObj(h3,h3name); mobjh3 = omg.GetObj(h3name);}
+  h3 = dynamic_cast<HProf*>(mobjh3);
+  if(h3 == NULL)  // ce n'est pas un HProf
+    {cout<<"PAWExecutor::h_oper Error: type mismatch between h1 and h3\n"
+         <<typeid(*mobjh1).name()<<" , "<<typeid(*mobjh3).name()<<endl; return;}
+  if(h1->NBins() != h3->NBins())
+    {cout<<"PAWExecutor::h_oper Error: size mismatch between h1, h3 "
+         <<h1->NBins()<<" "<<h3->NBins()<<endl; return;}
+  *h3 = *h1 + *h2;
+  h3->UpdateHisto();
+
+// Operations on Histo
+} else if( dynamic_cast<Histo*>(mobjh1) != NULL ) {
+  if( dynamic_cast<Histo*>(mobjh2) == NULL )
+    {cout<<"PAWExecutor::h_oper Error: type mismatch between h1 and h2\n"
+         <<typeid(*mobjh1).name()<<" , "<<typeid(*mobjh2).name()<<endl;
+    return;}
+  Histo* h1 =(Histo*) mobjh1;
+  Histo* h2 =(Histo*) mobjh2;
+  if( h1->NBins() != h2->NBins() )
+    {cout<<"PAWExecutor::h_oper Error: size mismatch between h1, h2 "
+         <<h1->NBins()<<" "<<h2->NBins()<<endl; return;}
+  Histo* h3 = NULL;
+  if( mobjh3 == NULL ) // l'objet n'existe pas, on le cree
+    {h3 = new Histo(*h1); h3->Zero(); omg.AddObj(h3,h3name); mobjh3 = omg.GetObj(h3name);}
+  h3 = dynamic_cast<Histo*>(mobjh3);
+  if(h3 == NULL)  // ce n'est pas un Histo
+    {cout<<"PAWExecutor::h_oper Error: type mismatch between h1 and h3\n"
+         <<typeid(*mobjh1).name()<<" , "<<typeid(*mobjh3).name()<<endl; return;}
+  if(h1->NBins() != h3->NBins())
+    {cout<<"PAWExecutor::h_oper Error: size mismatch between h1, h3 "
+         <<h1->NBins()<<" "<<h3->NBins()<<endl; return;}
+  if( oper[0]=='+')      *h3 = *h1 + *h2;
+  else if( oper[0]=='-') *h3 = *h1 - *h2;
+  else if( oper[0]=='*') *h3 = *h1 * *h2;
+  else if( oper[0]=='/') *h3 = *h1 / *h2;
+
+// Operations on Histo2D
+} else if( dynamic_cast<Histo2D*>(mobjh1) != NULL ) {
+  if( dynamic_cast<Histo2D*>(mobjh2) == NULL )
+    {cout<<"PAWExecutor::h_oper Error: type mismatch between h1 and h2\n"
+         <<typeid(*mobjh1).name()<<" , "<<typeid(*mobjh2).name()<<endl;
+    return;}
+  Histo2D* h1 =(Histo2D*) mobjh1;
+  Histo2D* h2 =(Histo2D*) mobjh2;
+  if( h1->NBinX() != h2->NBinX() || h1->NBinY() != h2->NBinY() )
+    {cout<<"PAWExecutor::h_oper Error: size mismatch between h1, h2 "
+         <<h1->NBinX()<<","<<h1->NBinY()<<"   "
+         <<h2->NBinX()<<","<<h2->NBinY()<<endl; return;}
+  Histo2D* h3 = NULL;
+  if( mobjh3 == NULL ) // l'objet n'existe pas, on le cree
+    {h3 = new Histo2D(*h1); h3->Zero(); omg.AddObj(h3,h3name); mobjh3 = omg.GetObj(h3name);}
+  h3 = dynamic_cast<Histo2D*>(mobjh3);
+  if(h3 == NULL)  // ce n'est pas un Histo2D
+    {cout<<"PAWExecutor::h_oper Error: type mismatch between h1 and h3\n"
+         <<typeid(*mobjh1).name()<<" , "<<typeid(*mobjh3).name()<<endl; return;}
+  if( h1->NBinX() != h3->NBinX() || h1->NBinY() != h3->NBinY() )
+    {cout<<"PAWExecutor::h_oper Error: size mismatch between h1, h3 "
+         <<h1->NBinX()<<","<<h1->NBinY()<<"   "
+         <<h3->NBinX()<<","<<h3->NBinY()<<endl; return;}
+  if( oper[0]=='+')      *h3 = *h1 + *h2;
+  else if( oper[0]=='-') *h3 = *h1 - *h2;
+  else if( oper[0]=='*') *h3 = *h1 * *h2;
+  else if( oper[0]=='/') *h3 = *h1 / *h2;
+
+// Operations on Vector
+} else if( dynamic_cast<Vector*>(mobjh1) != NULL ) {
+  if( dynamic_cast<Vector*>(mobjh2) == NULL )
+    {cout<<"PAWExecutor::h_oper Error: type mismatch between h1 and h2\n"
+         <<typeid(*mobjh1).name()<<" , "<<typeid(*mobjh2).name()<<endl;
+    return;}
+  Vector* h1 =(Vector*) mobjh1;
+  Vector* h2 =(Vector*) mobjh2;
+  if( h1->NElts() != h2->NElts() )
+    {cout<<"PAWExecutor::h_oper Error: size mismatch between h1, h2 "
+         <<h1->NElts()<<" "<<h2->NElts()<<endl; return;}
+  Vector* h3 = NULL;
+  if( mobjh3 == NULL ) {  // l'objet n'existe pas, on le cree
+#ifdef SANS_EVOLPLANCK
+    h3 = new Vector(*h1);
+#else
+    h3 = new Vector(*h1,false);
+#endif
+    *h3 = 0.; omg.AddObj(h3,h3name); mobjh3 = omg.GetObj(h3name);
+  }
+  h3 = dynamic_cast<Vector*>(mobjh3);
+  if(h3 == NULL)  // ce n'est pas un Vector
+    {cout<<"PAWExecutor::h_oper Error: type mismatch between h1 and h3\n"
+         <<typeid(*mobjh1).name()<<" , "<<typeid(*mobjh3).name()<<endl; return;}
+  if(h1->NElts() != h3->NElts())
+    {cout<<"PAWExecutor::h_oper Error: size mismatch between h1, h3 "
+         <<h1->NElts()<<" "<<h3->NElts()<<endl; return;}
+  if( oper[0]=='+')      *h3 = *h1 + *h2;
+  else if( oper[0]=='-') *h3 = *h1 - *h2;
+#ifdef SANS_EVOLPLANCK
+  else if(oper[0]=='*' || oper[0]=='/')
+    cout<<"PAWExecutor::h_oper Error: operation "<<oper[0]
+        <<" not implemented for Vector in Peida"<<endl;
+#else
+  else if( oper[0]=='*') {h3->Clone(*h1); h3->MulElt(*h2);}
+  else if( oper[0]=='/') {h3->Clone(*h1); h3->DivElt(*h2,false,true);}
+#endif
+
+// Operations on Matrix
+} else if( dynamic_cast<Matrix*>(mobjh1) != NULL ) {
+  if( dynamic_cast<Matrix*>(mobjh2) == NULL )
+    {cout<<"PAWExecutor::h_oper Error: type mismatch between h1 and h2\n"
+         <<typeid(*mobjh1).name()<<" , "<<typeid(*mobjh2).name()<<endl;
+    return;}
+  Matrix* h1 =(Matrix*) mobjh1;
+  Matrix* h2 =(Matrix*) mobjh2;
+  if( h1->NRows() != h2->NRows() || h1->NCol() != h2->NCol() )
+    {cout<<"PAWExecutor::h_oper Error: size mismatch between h1, h2 "
+         <<h1->NRows()<<","<<h1->NCol()<<"   "
+         <<h2->NRows()<<","<<h2->NCol()<<endl; return;}
+  Matrix* h3 = NULL;
+  if( mobjh3 == NULL ) {  // l'objet n'existe pas, on le cree
+#ifdef SANS_EVOLPLANCK
+    h3 = new Matrix(*h1);
+#else
+    h3 = new Matrix(*h1,false);
+#endif
+    *h3 = 0.; omg.AddObj(h3,h3name); mobjh3 = omg.GetObj(h3name);
+  }
+  h3 = dynamic_cast<Matrix*>(mobjh3);
+  if(h3 == NULL)  // ce n'est pas un Matrix
+    {cout<<"PAWExecutor::h_oper Error: type mismatch between h1 and h3\n"
+         <<typeid(*mobjh1).name()<<" , "<<typeid(*mobjh3).name()<<endl; return;}
+  if( h1->NRows() != h3->NRows() || h1->NCol() != h3->NCol() )
+    {cout<<"PAWExecutor::h_oper Error: size mismatch between h1, h3 "
+         <<h1->NRows()<<","<<h1->NCol()<<"   "
+         <<h3->NRows()<<","<<h3->NCol()<<endl; return;}
+  if( oper[0]=='+')      *h3 = *h1 + *h2;
+  else if( oper[0]=='-') *h3 = *h1 - *h2;
+#ifdef SANS_EVOLPLANCK
+  else if(oper[0]=='*' || oper[0]=='/')
+    cout<<"PAWExecutor::h_oper Error: operation "<<oper[0]
+        <<" not implemented for Vector in Peida"<<endl;
+#else
+  else if( oper[0]=='*') {h3->Clone(*h1); h3->MulElt(*h2);}
+  else if( oper[0]=='/') {h3->Clone(*h1); h3->DivElt(*h2,false,true);}
+#endif
+
+// Doesn't work for other objects
+} else {
+  cout<<"PAWExecutor::h_oper Error: not implemented for "
+      <<typeid(*mobjh1).name()<<endl;
+  return;
+}
+
+return;
+}
+
+/* methode */
+void PAWExecutor::h_plot_2d(vector<string>& tokens)
+// plot for 2D histogramme: plot histo, bandx/y, slicex/y or projx/y
+{
+if(tokens.size()<1)
+  {cout<<"Usage: h/plot/2d nameh2d to_plot [n/s] [dopt]"<<endl; return;}
+string proj = "h"; if(tokens.size()>1) proj = tokens[1];
+NamedObjMgr omg;
+AnyDataObj* mobj = omg.GetObj(tokens[0]);
+if(mobj==NULL)
+  {cout<<"PAWExecutor::h_plot_2d Error: unknow object"<<tokens[0]<<endl;
+  return;}
+Histo2D* h2 = dynamic_cast<Histo2D*>(mobj);
+if(!h2)
+  {cout<<"PAWExecutor::h_plot_2d Error: "<<tokens[0]<<" not an Histo2D"<<endl;
+  return;}
+
+Histo* h1p = NULL; string nametoplot = "/autoc/h_plot_2d_h1";
+
+string dopt = ""; if(tokens.size()>=3) dopt = tokens[2];
+if(proj == "show") {
+  h2->ShowProj();
+  h2->ShowBand(2);
+  h2->ShowSli(2);
+  return;
+} else if(proj == "h") {
+  nametoplot = tokens[0];
+} else if(proj == "px") {  
+  if((h1p=h2->HProjX())) {Histo* h1=new Histo(*h1p); omg.AddObj(h1,nametoplot);}
+    else {h2->ShowProj(); return;}
+} else if(proj == "py") {
+  if((h1p=h2->HProjY())) {Histo* h1=new Histo(*h1p); omg.AddObj(h1,nametoplot);}
+    else {h2->ShowProj(); return;}
+} else {
+  if(tokens.size()<3)
+    {cout<<"Usage: h/plot/2d nameh2d bx/by/sx/sy n [dopt]"<<endl; return;}
+  int_4 n = atoi(tokens[2].c_str());
+  dopt = ""; if(tokens.size()>=4) dopt = tokens[3];
+  if(proj == "bx") {
+    if((h1p=h2->HBandX(n))) {Histo* h1=new Histo(*h1p); omg.AddObj(h1,nametoplot);}
+    else {h2->ShowBand(); return;}
+  } else if(proj == "by") {
+    if((h1p=h2->HBandY(n))) {Histo* h1=new Histo(*h1p); omg.AddObj(h1,nametoplot);}
+    else {h2->ShowBand(); return;}
+  } else if(proj == "sx") {
+    if((h1p=h2->HSliX(n))) {Histo* h1=new Histo(*h1p); omg.AddObj(h1,nametoplot);}
+    else {h2->ShowSli(); return;}
+  } else if(proj == "sy") {
+    if((h1p=h2->HSliY(n))) {Histo* h1=new Histo(*h1p); omg.AddObj(h1,nametoplot);}
+    else {h2->ShowSli(); return;}
+  }
+}
+
+omg.DisplayObj(nametoplot,dopt);
+}
+
+/* methode */
+int_4 PAWExecutor::decodepawstring(string tokens,string& nameobj
+                                ,string& xexp,string& yexp,string& zexp)
+// Decodage general de "nameobj.xexp"
+//                     "nameobj.yexp%xexp"
+//                     "nameobj.zexp%yexp%xexp"
+// Return: nombre de variables trouvees, -1 si probleme
+{
+nameobj = ""; xexp= ""; yexp= ""; zexp= "";
+
+int_4 lt = (int) tokens.length();
+if(lt<=0) return -1;
+
+// decodage de la chaine de type PAW.
+char *str = new char[lt+2];
+strcpy(str,tokens.c_str()); strip(str,'B',' '); lt = strlen(str);
+//cout<<"chaine1["<<lt<<"] :"<<str<<":"<<endl;
+char *c[3] = {NULL,NULL,NULL};
+int_4 i, np=0; bool namefound = false;
+for(i=0;i<lt;i++) {
+  if(!namefound && str[i]=='.') {
+    str[i]='\0';
+    namefound=true;
+    c[np] = str+i+1; np++;
+  }
+  if( namefound && str[i]=='%') {
+    str[i]='\0';
+    if(np<3) {c[np] = str+i+1; np++;}
+  }
+}
+//cout<<"chaine2 :"; for(i=0;i<lt;i++) cout<<str[i]; cout<<":"<<endl;
+
+// Remplissage du nom et des variables
+nameobj = str;
+if(np==1)  xexp=c[0];
+if(np==2) {yexp=c[0]; xexp=c[1];}
+if(np==3) {zexp=c[0]; yexp=c[1]; xexp=c[2];}
+//cout<<"pawstring str,c[0-2] "<<str<<" "<<c[0]<<" "<<c[1]<<" "<<c[2]<<endl;
+delete [] str;
+
+// Comptage des variables
+np = -1;
+if(nameobj.length()>0) 
+  {np = 0; if(xexp.length()>0)
+             {np++; if(yexp.length()>0)
+                      {np++; if(zexp.length()>0) np++;}}}
+//cout<<"pawstring["<<np<<"] name="<<nameobj
+//    <<" xexp="<<xexp<<" yexp="<<yexp<<" zexp="<<zexp<<endl;
+return np;
+}
+
+/* methode */
+void PAWExecutor::h_put_vec(vector<string>& tokens)
+// Pour remplir un histo avec le contenu d'un vecteur ou d'une matrice
+// L'histogramme doit deja exister. Le nombre de bins remplit
+// depend des tailles respectives des 2 objets.
+// tokens[2] = "cont" : on remplit les valeurs de l'histogramme (ou "!")
+//           = "err2" : on remplit les erreurs de l'histogramme
+{
+if(tokens.size()<2)
+  {cout<<"Usage: h/put_vec  namehisto namevector"<<endl;
+   return;}
+string toput = "cont"; if(tokens.size()>2) toput = tokens[2];
+if(toput=="!") toput = "cont";
+if(toput!="cont" && toput!="err2")
+  {cout<<"PAWExecutor::h_put_vec Error: unknow filling "<<toput<<endl;
+   return;}
+string hname = tokens[0];
+string vname = tokens[1];
+
+// Get objects
+NamedObjMgr omg;
+AnyDataObj* mobjh = omg.GetObj(hname);
+AnyDataObj* mobjv = omg.GetObj(vname);
+if( mobjh==NULL || mobjv==NULL )
+  {cout<<"PAWExecutor::h_put_vec Error: unknow object(s) "<<hname<<" or "<<vname<<endl;
+  return;}
+
+// Fill Histo from Vector
+if(typeid(*mobjh) == typeid(Histo) && typeid(*mobjv) == typeid(Vector)) {
+  Histo*  h = dynamic_cast<Histo*>(mobjh);
+  Vector* v = dynamic_cast<Vector*>(mobjv);
+  if(toput=="cont")      h->PutValue(*v);
+  else if(toput=="err2") h->PutError2(*v);
+
+// Fill Histo2D from Matrix
+} else if(typeid(*mobjh) == typeid(Histo2D) && typeid(*mobjv) == typeid(Matrix)) {
+  Histo2D* h = dynamic_cast<Histo2D*>(mobjh);
+  Matrix*  v = dynamic_cast<Matrix*>(mobjv);
+  if(toput=="cont")      h->PutValue(*v);
+  else if(toput=="err2") h->PutError2(*v);
+
+} else {
+  cout<<"PAWExecutor::h_put_vec Error: type mismatch between histogram and vector/matrix\n"
+      <<typeid(*mobjh).name()<<" , "<<typeid(*mobjv).name()<<endl;
+  return;
+}
+
+}
+
+/* methode */
+void PAWExecutor::h_get_vec(vector<string>& tokens)
+// Pour copier un histo dans un vecteur ou une matrice
+// Si le vecteur (matrice) n'existe pas, il est cree.
+// Le vecteur ou la matrice est re-dimensionne correctement.
+// tokens[2] = "cont" : on copie les valeurs de l'histogramme (ou "!")
+//           = "err2" : on copie les erreurs de l'histogramme
+//           = "absc" : on copie les erreurs de l'histogramme (1D only)
+// tokens[3[,4]] = show : show available projections for Histo2D
+//                 px   : get X projection
+//                 py   : get Y projection
+//                 bx n : get X band number n
+//                 by n : get Y band number n
+//                 sx n : get X slice number n
+//                 sy n : get Y slice number n
+{
+if(tokens.size()<2)
+  {cout<<"Usage: h/get_vec namehisto namevector"<<endl;
+   return;}
+string toget = "cont"; if(tokens.size()>2) toget = tokens[2];
+if(toget=="!") toget = "cont";
+if(toget!="cont" && toget!="err2" && toget!="absc")
+  {cout<<"PAWExecutor::h_get_vec Error: unknow filling "<<toget<<endl;
+   return;}
+string proj = "h";  if(tokens.size()>3) proj = tokens[3];
+int_4 nproj = -1;   if(tokens.size()>4) nproj = atoi(tokens[4].c_str());
+string hname = tokens[0];
+string vname = tokens[1];
+
+// Get objects
+NamedObjMgr omg;
+AnyDataObj* mobjh = omg.GetObj(hname);
+AnyDataObj* mobjv = omg.GetObj(vname);
+if( mobjh==NULL)
+  {cout<<"PAWExecutor::h_put_vec Error: unknow object(s) "<<hname<<endl;
+  return;}
+
+// Copy Histo/Histo2D/Projection to Vector/Matrix
+Histo*   h  = dynamic_cast<Histo*>(mobjh);
+Histo2D* h2 = dynamic_cast<Histo2D*>(mobjh);
+if( h != NULL ) {  // Histo ou HProf
+  h->UpdateHisto();  // pour le cas ou c'est un HProf
+  Vector* v = NULL;
+  if(mobjv==NULL)   // le vecteur n'existe pas
+    {v = new Vector(1); omg.AddObj(v,vname); mobjv = omg.GetObj(vname);}
+  if(typeid(*mobjv) != typeid(Vector))
+    {cout<<"PAWExecutor::h_get_vec Error: type mismatch between Histo/HProf and vector\n"
+         <<typeid(*mobjv).name()<<endl; return;}
+  v = dynamic_cast<Vector*>(mobjv);
+  if(toget=="cont")      h->GetValue(*v);
+  else if(toget=="err2") h->GetError2(*v);
+  else if(toget=="absc") h->GetAbsc(*v);
+
+} else if( h2 != NULL) {  // Histo2D
+
+  if(proj == "h") {   // On veut les valeurs de l'histogramme 2D
+    Matrix*  v = NULL;
+    if(mobjv==NULL)   // la matrice n'existe pas
+      {v = new Matrix(1,1); omg.AddObj(v,vname); mobjv = omg.GetObj(vname);}
+    if(typeid(*mobjv) != typeid(Matrix))
+      {cout<<"PAWExecutor::h_get_vec Error: type mismatch between Histo2D and matrix\n"
+           <<typeid(*mobjv).name()<<endl; return;}
+    v = dynamic_cast<Matrix*>(mobjv);
+    if(toget=="cont")      h2->GetValue(*v);
+    else if(toget=="err2") h2->GetError2(*v);
+    else
+      {cout<<"PAWExecutor::h_get_vec Error: option "<<toget<<" not valid for Histo2D"<<endl;
+      return;}
+
+  } else {   // On veut les valeurs d'une projection de l'histo 2D
+    h = NULL;
+    if(proj == "show") {h2->ShowProj(); h2->ShowBand(2); h2->ShowSli(2);}
+    else if(proj == "px") h = h2->HProjX();
+    else if(proj == "py") h = h2->HProjY();
+    else if(proj == "bx") h = h2->HBandX(nproj);
+    else if(proj == "by") h = h2->HBandY(nproj);
+    else if(proj == "sx") h = h2->HSliX(nproj);
+    else if(proj == "sy") h = h2->HSliY(nproj);
+    if(h==NULL)
+      {cout<<"PAWExecutor::h_get_vec Error: unknown projection "<<proj
+           <<" number "<<nproj<<endl; return;}
+    Vector* v = NULL;
+    if(mobjv==NULL)   // le vecteur n'existe pas
+      {v = new Vector(1); omg.AddObj(v,vname); mobjv = omg.GetObj(vname);}
+    if(typeid(*mobjv) != typeid(Vector))
+      {cout<<"PAWExecutor::h_get_vec Error: type mismatch between Histo2D "<<proj
+       <<" and vector\n"<<typeid(*mobjv).name()<<endl; return;}
+    v = dynamic_cast<Vector*>(mobjv);
+    if(toget=="cont")      h->GetValue(*v);
+    else if(toget=="err2") h->GetError2(*v);
+    else if(toget=="absc") h->GetAbsc(*v);
+  }
+
+} else {
+  cout<<"PAWExecutor::h_get_vec Error: type mismatch for histogram\n"
+      <<typeid(*mobjh).name()<<endl;
+  return;
+}
+
+}
+
+/* methode */
+void PAWExecutor::h_copy(vector<string>& tokens)
+// Pour copier un object dans un object
+// objects are Vector,Matrix,Histo,Histo2D
+//   h/copy namefrom nametocopy [i1[:i2]] [j1[:j2]] [ic1[:jc1]]
+//   copy obj1Dfrom(i1->i2) into obj1Dto(ic1->)
+//   copy obj2Dfrom(i1,j1->i2,j2) into obj2Dto(ic1,jc1->)
+// Attention: elements depuis i1 jusqu'a i2 COMPRIS
+// Si obj1Dto n'existe pas, il est cree avec une taille i2-i1+1
+//    ou obj2Dto avec une taille i2-i1+1,j2-j1+1
+// Le contenu de obj?Dfrom adresse est surecrit
+// Le contenu de obj?Dfrom non adresse reste le meme
+{
+int_4 tks = tokens.size();
+if(tks<2)
+  {cout<<"Usage: h_copy namefrom nametocopy [i1[:i2]] [j1[:j2]] [ic1[:jc1]]"<<endl;
+   return;}
+
+NamedObjMgr omg;
+AnyDataObj* mobjv1 = omg.GetObj(tokens[0]);
+if( mobjv1==NULL)
+  {cout<<"PAWExecutor::h_copy Error: unknow object "<<tokens[0]<<endl;
+  return;}
+AnyDataObj* mobjv2 = omg.GetObj(tokens[1]);
+
+int_4 i1=0,i2=0, j1=0,j2=0, ic1=0,jc1=0, i,ii, j,jj, nx1,ny1, nx2,ny2;
+
+// Cas d'un Vector
+if(typeid(*mobjv1) == typeid(Vector)) {
+  Vector* v1 = dynamic_cast<Vector*>(mobjv1); nx1 = (int_4)v1->NElts();
+  i2=nx1-1;
+  if(tks>2) if(tokens[2]!="!") sscanf(tokens[2].c_str(),"%d:%d",&i1,&i2);
+  if(i1<0) i1=0; if(i2>=nx1) i2=nx1-1;
+  if(i2<i1)
+    {cout<<"PAWExecutor::h_copy Error: wrong range ["<<i1<<":"<<i2<<"] for NElts="
+         <<nx1<<endl; return;}
+  Vector* v2 = NULL;
+  if(mobjv2==NULL)
+    {v2 = new Vector(i2-i1+1); omg.AddObj(v2,tokens[1]); mobjv2 = omg.GetObj(tokens[1]);}
+  if(typeid(*mobjv2) != typeid(Vector))
+    {cout<<"PAWExecutor::h_copy Error: type mismatch for Vector "
+         <<typeid(*mobjv2).name()<<endl; return;}
+  v2 = dynamic_cast<Vector*>(mobjv2); nx2 = (int_4)v2->NElts();
+  if(tks>4) if(tokens[4]!="!") sscanf(tokens[4].c_str(),"%d",&ic1);
+  if(ic1<0) ic1=0;
+  if(ic1>=nx2)
+    {cout<<"PAWExecutor::h_copy Error: wrong pointer to copy ["<<ic1<<"] for NElts="
+         <<nx2<<endl; return;}
+  cout<<"copy "<<tokens[0]<<"("<<i1<<":"<<i2<<") to "<<tokens[1]<<"("<<ic1<<"->...)"<<endl;
+  for(i=i1,ii=ic1; i<=i2 && i<nx1 && ii<nx2; i++,ii++) (*v2)(ii) = (*v1)(i);
+  return;
+}
+
+// Cas d'un Histo
+if(typeid(*mobjv1) == typeid(Histo)) {
+  Histo* v1 = dynamic_cast<Histo*>(mobjv1); nx1 = (int_4)v1->NBins();
+  i2=nx1-1;
+  if(tks>2) if(tokens[2]!="!") sscanf(tokens[2].c_str(),"%d:%d",&i1,&i2);
+  if(i1<0) i1=0; if(i2>=nx1) i2=nx1-1;
+  if(i2<i1)
+    {cout<<"PAWExecutor::h_copy Error: wrong range ["<<i1<<":"<<i2<<"] for NBins="
+         <<nx1<<endl; return;}
+  Histo* v2 = NULL;
+  if(mobjv2==NULL)
+    {v2 = new Histo(0.,(r_8)(i2-i1+1),i2-i1+1);
+     omg.AddObj(v2,tokens[1]); mobjv2 = omg.GetObj(tokens[1]);}
+  if(typeid(*mobjv2) != typeid(Histo))
+    {cout<<"PAWExecutor::h_copy Error: type mismatch for Histo "
+         <<typeid(*mobjv2).name()<<endl; return;}
+  v2 = dynamic_cast<Histo*>(mobjv2); nx2 = (int_4)v2->NBins();
+  if(v1->HasErrors() && !(v2->HasErrors())) v2->Errors();
+  if(tks>4) if(tokens[4]!="!") sscanf(tokens[4].c_str(),"%d",&ic1);
+  if(ic1<0) ic1=0;
+  if(ic1>=nx2)
+    {cout<<"PAWExecutor::h_copy Error: wrong pointer to copy ["<<ic1<<"] for NBins="
+         <<nx2<<endl; return;}
+  cout<<"copy "<<tokens[0]<<"("<<i1<<":"<<i2<<") to "<<tokens[1]<<"("<<ic1<<"->...)"<<endl;
+  for(i=i1,ii=ic1; i<=i2 && i<nx1 && ii<nx2; i++,ii++)
+    {(*v2)(ii) = (*v1)(i); if(v1->HasErrors()) v2->Error2(ii) = v1->Error2(i);}
+  return;
+}
+
+// Cas d'une Matrix
+if(typeid(*mobjv1) == typeid(Matrix)) {
+  Matrix* v1 = dynamic_cast<Matrix*>(mobjv1); nx1=v1->NRows(); ny1=v1->NCol();
+  i2=nx1-1; j2=ny1-1;
+  if(tks>2) if(tokens[2]!="!") sscanf(tokens[2].c_str(),"%d:%d",&i1,&i2);
+  if(tks>3) if(tokens[3]!="!") sscanf(tokens[3].c_str(),"%d:%d",&j1,&j2);
+  if(i1<0) i1=0; if(i2>=nx1) i2=nx1-1; if(j1<0) j1=0; if(j2>=ny1) j2=ny1-1;
+  if(i2<i1 || j2<j1)
+    {cout<<"PAWExecutor::h_copy Error: wrong range ["<<i1<<":"<<i2
+         <<"] , ["<<j1<<":"<<j2<<"] for NRows,NCol="
+         <<nx1<<" , "<<ny1<<endl; return;}
+  Matrix* v2 = NULL;
+  if(mobjv2==NULL)
+    {v2 = new Matrix(i2-i1+1,j2-j1+1);
+     omg.AddObj(v2,tokens[1]); mobjv2 = omg.GetObj(tokens[1]);}
+  if(typeid(*mobjv2) != typeid(Matrix))
+    {cout<<"PAWExecutor::h_copy Error: type mismatch for Matrix "
+         <<typeid(*mobjv2).name()<<endl; return;}
+  v2 = dynamic_cast<Matrix*>(mobjv2); nx2=v2->NRows(); ny2=v2->NCol();
+  if(tks>4) if(tokens[4]!="!") sscanf(tokens[4].c_str(),"%d:%d",&ic1,&jc1);
+  if(ic1<0) ic1=0; if(jc1<0) jc1=0;
+  if(ic1>=nx2 || jc1>=ny2)
+    {cout<<"PAWExecutor::h_copy Error: wrong pointer to copy ["<<ic1<<","<<jc1
+         <<"] for NRows,NCol="<<nx2<<","<<ny2<<endl; return;}
+  cout<<"copy "<<tokens[0]<<"("<<i1<<":"<<i2<<","<<j1<<":"<<j2
+      <<") to "<<tokens[1]<<"("<<ic1<<","<<jc1<<"->...)"<<endl;
+  for(i=i1,ii=ic1; i<=i2 && i<nx1 && ii<nx2; i++,ii++)
+    for(j=j1,jj=jc1; j<=j2 && j<ny1 && jj<ny2; j++,jj++) (*v2)(ii,jj) = (*v1)(i,j);
+  return;
+}
+
+// Cas d'un Histo2D
+if(typeid(*mobjv1) == typeid(Histo2D)) {
+  Histo2D* v1 = dynamic_cast<Histo2D*>(mobjv1); nx1=v1->NBinX(); ny1=v1->NBinY();
+  i2=nx1-1; j2=ny1-1;
+  if(tks>2) if(tokens[2]!="!") sscanf(tokens[2].c_str(),"%d:%d",&i1,&i2);
+  if(tks>3) if(tokens[3]!="!") sscanf(tokens[3].c_str(),"%d:%d",&j1,&j2);
+  if(i1<0) i1=0; if(i2>=nx1) i2=nx1-1; if(j1<0) j1=0; if(j2>=ny1) j2=ny1-1;
+  if(i2<i1 || j2<j1)
+    {cout<<"PAWExecutor::h_copy Error: wrong range ["<<i1<<":"<<i2
+         <<"] , ["<<j1<<":"<<j2<<"] for NBinX,NBinY="
+         <<nx1<<" , "<<ny1<<endl; return;}
+  Histo2D* v2 = NULL;
+  if(mobjv2==NULL)
+    {v2 = new Histo2D(0.,(r_8)(i2-i1+1),i2-i1+1,0.,(r_8)(j2-j1+1),j2-j1+1);
+     omg.AddObj(v2,tokens[1]); mobjv2 = omg.GetObj(tokens[1]);}
+  if(typeid(*mobjv2) != typeid(Histo2D))
+    {cout<<"PAWExecutor::h_copy Error: type mismatch for Histo2D"
+         <<typeid(*mobjv2).name()<<endl; return;}
+  v2 = dynamic_cast<Histo2D*>(mobjv2); nx2=v2->NBinX(); ny2=v2->NBinY();
+  if(v1->HasErrors() && !(v2->HasErrors())) v2->Errors();
+  if(tks>4) sscanf(tokens[4].c_str(),"%d:%d",&ic1,&jc1);
+  if(ic1<0) ic1=0; if(jc1<0) jc1=0;
+  if(ic1>=nx2 || jc1>=ny2)
+    {cout<<"PAWExecutor::h_copy Error: wrong pointer to copy ["<<ic1<<","<<jc1
+         <<"] for NBinX,NBinY="<<nx2<<","<<ny2<<endl; return;}
+  cout<<"copy "<<tokens[0]<<"("<<i1<<":"<<i2<<","<<j1<<":"<<j2
+      <<") to "<<tokens[1]<<"("<<ic1<<","<<jc1<<"->...)"<<endl;
+  for(i=i1,ii=ic1; i<=i2 && i<nx1 && ii<nx2; i++,ii++)
+    for(j=j1,jj=jc1; j<=j2 && j<ny1 && jj<ny2; j++,jj++)
+      {(*v2)(ii,jj) = (*v1)(i,j); if(v1->HasErrors()) v2->Error2(ii,jj) = v1->Error2(i,j);}
+  return;
+}
+
+// Cas non prevu
+cout<<"PAWExecutor::h_copy Error: type mismatch for Vector/Matrix/Histo/Histo2D\n"
+    <<typeid(*mobjv1).name()<<endl;
+return;
+}
+
+/* methode */
+void PAWExecutor::h_set(string dum,vector<string>& tokens)
+// Mise de valeurs/erreurs d'un histo 1D ou 2D a une valeur donnee
+// dum = err  : on change les valeurs des erreurs
+//       cont : on change les valeurs du contenu des bins
+// tokens[0] : nom de l'histogramme
+// tokens[1] : valeur de remplacement
+// tokens[2-3] : i1:i2 j1:j2  intervalle des bins qui doivent etre remplace
+//             : v v1:v2  remplacement des bins ayant une valeur dans cet intervalle
+//             : e e1:e2  remplacement des bins ayant une erreur dans cet intervalle
+{
+int_4 tks = tokens.size();
+if(tks<3)
+  {cout<<"Usage: h/set/[err,cont] namehisto setvalue i1[:i2]  [j1[:j2]]\n"
+       <<"                                           v v1:v2\n"
+       <<"                                           e e1:e2"
+       <<endl; return;}
+
+// Decodage arguments
+bool replerr = false; if(dum=="err") replerr = true;
+r_8 setval = atof(tokens[1].c_str());
+int_4 testcont=0; if(tokens[2]=="v") testcont=1; if(tokens[2]=="e") testcont=2;
+int_4 i1=-1, i2=-1, j1=-1, j2=-1;
+r_8 v1=0., v2=0.;
+if(testcont==0) {
+  sscanf(tokens[2].c_str(),"%d:%d",&i1,&i2);
+  if(tks>3) sscanf(tokens[3].c_str(),"%d:%d",&j1,&j2);
+} else {
+  if(tks<=3)
+    {cout<<"PAWExecutor::h_set Error: h/set/... v v1:v2, please give v1:v2"<<endl;
+    return;}
+  sscanf(tokens[3].c_str(),"%lf:%lf",&v1,&v2);
+}
+
+if(replerr) {if(setval<0.) setval = 0.; else setval *= setval;}
+if(testcont!=0 && v2<v1)
+  {cout<<"PAWExecutor::h_set Error: bad value range="<<v1<<","<<v2<<endl; return;}
+
+// identification objet
+NamedObjMgr omg;
+AnyDataObj* mobj = omg.GetObj(tokens[0]);
+if( mobj==NULL)
+  {cout<<"PAWExecutor::h_set Error: unknow object "<<tokens[0]<<endl;
+  return;}
+
+// Traitement
+if(typeid(*mobj) == typeid(Histo)) {  // Histo 1D
+  Histo* h  = dynamic_cast<Histo*>(mobj);
+  if( (replerr || testcont==2) && !(h->HasErrors()) )
+    {cout<<"PAWExecutor::h_set Error: histogram has no errors"<<endl; return;}
+  if(testcont!=0) {i1=0; i2=h->NBins()-1;}
+  if(i1<0 || i1>=h->NBins())
+    {cout<<"PAWExecutor::h_set Error: bad bin range i1="<<i1<<endl; return;}
+  if(i2<i1) i2=i1; if(i2>=h->NBins()) i2=h->NBins()-1;
+  for(int_4 i=i1;i<=i2;i++) {
+    bool change = true;
+    if(testcont==1) {if((*h)(i)<v1 || (*h)(i)>v2) change = false;}
+    else if(testcont==2) {if(h->Error(i)<v1 || h->Error(i)>v2) change = false;}
+    if(!change) continue;
+    if(replerr) h->Error2(i) = setval; else (*h)(i) = setval;
+  }
+
+} else if(typeid(*mobj) == typeid(Histo2D)) {  // Histo 2D
+  Histo2D* h2 = dynamic_cast<Histo2D*>(mobj);
+  if( (replerr || testcont==2) && !(h2->HasErrors()) )
+    {cout<<"PAWExecutor::h_set Error: histogram has no errors"<<endl; return;}
+  if(testcont!=0) {i1=0; i2=h2->NBinX()-1;j1=0; j2=h2->NBinY()-1;}
+  if(i1<0 || i1>=h2->NBinX() || j1<0 || j1>=h2->NBinY())
+    {cout<<"PAWExecutor::h_set Error: bad bin range i1,j1="<<i1<<","<<j1<<endl; return;}
+  if(i2<i1) i2=i1; if(i2>=h2->NBinX()) i2=h2->NBinX()-1;
+  if(j2<j1) j2=j1; if(j2>=h2->NBinY()) j2=h2->NBinY()-1;
+  for(int_4 i=i1;i<=i2;i++) for(int_4 j=j1;j<=j2;j++) {
+    bool change = true;
+    if(testcont==1) {if((*h2)(i,j)<v1 || (*h2)(i,j)>v2) change = false;}
+    else if(testcont==2) {if(h2->Error(i,j)<v1 || h2->Error(i,j)>v2) change = false;}
+    if(!change) continue;
+    if(replerr) h2->Error2(i,j) = setval; else (*h2)(i,j) = setval;
+  }
+
+} else {
+  cout<<"PAWExecutor::h_set Error: type mismatch for Histo/Histo2D\n"
+    <<typeid(*mobj).name()<<endl;
+  return;
+}
+
+}
+
+/* methode */
+void PAWExecutor::h_err(vector<string>& tokens)
+// Mise des erreurs d'un histo 1D ou 2D a une valeur
+// donnee par une fonction de la valeur du bin
+// tokens[0] : nom de l'histogramme
+// tokens[1] : expression de la fonction
+{
+if(tokens.size()<2)
+  {cout<<"Usage: h/err namehisto expr_func"<<endl; return;}
+
+// identification objet
+NamedObjMgr omg;
+AnyDataObj* mobj = omg.GetObj(tokens[0]);
+if( mobj==NULL)
+  {cout<<"PAWExecutor::h_err Error: unknow object "<<tokens[0]<<endl;
+  return;}
+
+// Fonction
+FILE *fip = NULL;
+string expfunc = ""; {for(int_4 i=1;i<(int)tokens.size();i++) expfunc += tokens[i];}
+string fname = "func1or2_pia_dl.c";
+string func = "func1or2_pia_dl_func";
+if((fip = fopen(fname.c_str(), "w")) == NULL)
+  {cout<<"PAWExecutor::h_err Error: open function file "<<fname<<endl;
+  return;}
+fprintf(fip,"#include <math.h>\n");
+fprintf(fip,"double %s(double x) \n{\n",func.c_str());
+fprintf(fip,"return(%s); \n}\n", expfunc.c_str());
+fclose(fip);
+DlFunctionOfX f = (DlFunctionOfX) omg.GetServiceObj()->LinkFunctionFromFile(fname,func);
+if(!f) 
+  {cout<<"PAWExecutor::h_err Error: bad function "<<func<<","<<fname<<endl;
+  return;}
+
+// Traitement
+if(typeid(*mobj) == typeid(Histo)) {  // Histo 1D
+  Histo* h  = dynamic_cast<Histo*>(mobj);
+  if(!(h->HasErrors())) h->Errors();
+  for(int_4 i=0;i<h->NBins();i++) {
+    r_8 x = (*h)(i);
+    r_8 e = f(x);
+    h->SetErr2(i,e*e); 
+  }
+
+} else if(typeid(*mobj) == typeid(Histo2D)) {  // Histo 2D
+  Histo2D* h2 = dynamic_cast<Histo2D*>(mobj);
+  if(!(h2->HasErrors())) h2->Errors();
+  for(int_4 i=0;i<h2->NBinX();i++) for(int_4 j=0;j<h2->NBinY();j++) {
+    r_8 x = (*h2)(i,j);
+    r_8 e = f(x);
+    h2->Error2(i,j) = e*e; 
+  }
+
+} else {
+  cout<<"PAWExecutor::h_err Error: type mismatch for Histo/Histo2D\n"
+    <<typeid(*mobj).name()<<endl;
+  return;
+}
+
+}
Index: /tags/V_Dec2002/SophyaPI/PIext/pawexecut.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/pawexecut.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/pawexecut.h	(revision 2309)
@@ -0,0 +1,46 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe d ajustement pour  piapp
+// cmv                            98-99
+// CEA-DAPNIA      LAL-IN2P3/CNRS
+
+#ifndef PAWEXECUTOR_H_SEEN
+#define PAWEXECUTOR_H_SEEN
+
+#include "machdefs.h"
+#include <string>
+#include <vector>
+
+#include "anydataobj.h"
+#include "piacmd.h"
+
+class PAWExecutor : public CmdExecutor {
+public:
+              PAWExecutor(PIACmd* piac, PIStdImgApp* app);
+  virtual     ~PAWExecutor();
+  virtual int Execute(string& keyw, vector<string>& args, string& toks);
+protected:
+  void  reset(vector<string>& tokens);
+  void  n_plot(vector<string>& tokens);
+  void  n_proj(vector<string>& tokens);
+  void  n_scan(vector<string>& tokens);
+  void  h_integ(vector<string>& tokens);
+  void  v_integ(vector<string>& tokens);
+  void  h_deriv(vector<string>& tokens);
+  void  v_deriv(vector<string>& tokens);
+  void  h_rebin(vector<string>& tokens);
+  void  h_cadd(vector<string>& tokens);
+  void  h_cmult(vector<string>& tokens);
+  void  h_oper(vector<string>& tokens);
+  void  h_plot_2d(vector<string>& tokens);
+  void  h_put_vec(vector<string>& tokens);
+  void  h_get_vec(vector<string>& tokens);
+  void  h_copy(vector<string>& tokens);
+  void  h_set(string dum,vector<string>& tokens);
+  void  h_err(vector<string>& tokens);
+  int_4 decodepawstring(string tokens,string& nameobj
+                       ,string& xexp,string& yexp,string& zexp);
+  PIStdImgApp* mApp;
+  static uint_4 autoc_counter_;
+};
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/pi2dvec.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/pi2dvec.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/pi2dvec.cc	(revision 2309)
@@ -0,0 +1,170 @@
+// This may look like C code, but it is really -*- C++ -*-
+// classe pour tracer des flow chart (champs de vecteurs) 2d
+// NB herite de PIDrawer 
+// O. Perdereau 01/2002
+// 
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream.h>
+#include <math.h>
+
+#include "histos.h"
+#include "ntuple.h"
+
+#include "nbtri.h" 
+
+#include "pi2dvec.h"
+
+#include <sys/time.h>
+#include <sys/resource.h>
+
+//++
+// Class	PI2dVecDrawer
+// Lib		PIGcont
+// include	pigncont.h2dvec.h
+// 
+// 
+// Classe de trace d'un champ de vecteurs (flow chart) en 2 dimensions
+//
+//
+//--
+//++ 
+// Links        Parents
+// PIDrawer
+//--
+//
+//++
+// Titre	Constructeurs et Méthodes 
+//--
+
+//++
+// PI2dVecDrawer::PI2dVecDrawer(NTupleInterface* nti,bool autodel)
+//  Constructeur 
+// 
+//--
+PI2dVecDrawer::PI2dVecDrawer(NTupleInterface* nti,bool autodel)
+{
+  _nti = nti;
+  
+  _autodel = autodel;
+  SelectXY(NULL, NULL);
+  SelectVW(NULL, NULL);
+
+  // This drawer has *NO* specific control tools 
+  mFgSpecContWind = false;
+
+}
+
+
+/* --Methode-- */
+PI2dVecDrawer::~PI2dVecDrawer()
+{
+  
+  if(_autodel){ //cout << " destructeur de PI2dVecDrawer / autodel "<<endl;
+    if(_nti!=NULL){delete _nti ; _nti=NULL;}
+  }
+
+}
+
+/* --Methode-- */
+void PI2dVecDrawer::Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax){
+
+  if(_nti==NULL){cout << " PI2dVecDrawer::Draw : null ntuple "<<endl; return;}
+  if ( (xK < 0) || (yK < 0) ){cout << " PI2dVecDrawer::Draw : no X/Y "<<endl;  return;}
+  if ( (vK < 0) || (wK < 0) ){cout << " PI2dVecDrawer::Draw : no VX/VY "<<endl;  return;}
+
+  int npt = _nti->NbLines();
+  int i=0;
+  double x,y,vx,vy;
+  double xa[2];
+  double ya[2];
+  g->SaveGraphicAtt();
+
+  // choix de la couleur   
+  g->SelForeground(GetGraphicAtt().GetFgColor());
+
+  // choix de la ligne 
+  PILineAtt mlatt = GetGraphicAtt().GetLineAtt() ;
+  if(mlatt==PI_NotDefLineAtt) GetGraphicAtt().SetLineAtt(PI_NormalLine);
+
+  g->SelLine(GetGraphicAtt().GetLineAtt() );
+
+  // choix du marker 
+  if(GetGraphicAtt().GetMarker()==PI_NotDefMarker)
+    GetGraphicAtt().SetMarkerAtt(5,PI_FCircleMarker);
+  g->SelMarker(GetGraphicAtt().GetMarkerSize(),GetGraphicAtt().GetMarker());
+
+  // choix de la fleche 
+  
+  if(GetGraphicAtt().GetArrowMarker()==PI_NotDefArrowMarker)
+    GetGraphicAtt().SetArrowMarkerAtt(5,PI_BasicArrowMarker);
+
+  
+
+   g->SelArrowMarker(GetGraphicAtt().GetArrowMarkerSize(),GetGraphicAtt().GetArrowMarker());
+ 
+
+
+  for(i=0 ; i<npt ; i++){
+    x = _nti->GetCell(i,xK) ;
+    y = _nti->GetCell(i,yK) ;
+    vx = _nti->GetCell(i,vK) + x;
+    vy = _nti->GetCell(i,wK) + y;
+    g->DrawMarker(x,y);
+    
+    //g->DrawLine(x,y,vx,vy);
+    
+    g->DrawArrowMarker(x,y,vx,vy);
+
+  }
+
+  g->RestoreGraphicAtt();
+
+}
+/* --Methode-- */
+void PI2dVecDrawer::UpdateLimits()
+{
+  // Doit calculer les limites
+
+  double xmn,xmx,ymn,ymx;
+  double vmn,vmx;
+
+  _nti->GetMinMax(0,xmn,xmx);
+  _nti->GetMinMax(1,ymn,ymx);
+  
+  SetLimits(xmn, xmx, ymn, ymx);
+}
+
+/* --Methode-- */
+int   PI2dVecDrawer::SelectXY(const char* px, const char* py)
+{
+  string name;
+  if (_nti == NULL)  xK = yK = -1;
+  if (px == NULL) xK = -1;
+  else { name = px; xK = _nti->ColumnIndex(name); }
+  if (py == NULL) yK = -1;
+  else { name = py; yK = _nti->ColumnIndex(name); }
+  
+  int ret = xK;
+  if( ret > yK) ret = yK;
+  return(ret);
+}
+
+/* --Methode-- */
+int  PI2dVecDrawer::SelectVW(const char* px, const char* py)
+{
+  string name;
+  if (_nti == NULL)  vK = vK = -1;
+  if (px == NULL) vK = -1;
+  else { name = px; vK = _nti->ColumnIndex(name); }
+  if (py == NULL) wK = -1;
+  else { name = py; wK = _nti->ColumnIndex(name); }
+  
+  int ret = vK;
+  if( ret > wK) ret = wK;
+  return(ret);
+}
+
Index: /tags/V_Dec2002/SophyaPI/PIext/pi2dvec.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/pi2dvec.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/pi2dvec.h	(revision 2309)
@@ -0,0 +1,38 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe  PI2dVecDrawer  : trace de flow chart 
+// (c) DAPNIA (CEA)                 LAL (IN2P3/CNRS)
+//                           R. Ansari O.Perdereau  01/2002
+//
+//=========================================================//
+
+#ifndef PI2DVEC_H_SEEN 
+#define PI2DVEC_H_SEEN 
+#include "pistdimgapp.h"
+#include "piscdrawwdg.h"
+#include "ntupintf.h"
+
+class PI2dVecDrawer : public PIDrawer{
+public:
+
+  PI2dVecDrawer(NTupleInterface* nti,bool autodel);
+  virtual           ~PI2dVecDrawer();
+  virtual void      Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax);
+  virtual void      UpdateLimits();
+  virtual int       SelectXY(const char* px, const char* py);
+  virtual int       SelectVW(const char* px, const char* py);
+
+ 
+protected:
+  bool _autodel;
+  NTupleInterface* _nti;
+  
+  int xK, yK;            // Index du nom de variable en X/Y ds le ntuple
+  int vK, wK;          // Index du nom de variable des longueurs des vecteurs ds le ntuple
+
+};
+
+//
+//
+//
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/piacmd.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/piacmd.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/piacmd.cc	(revision 2309)
@@ -0,0 +1,1972 @@
+#include "piacmd.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <math.h>
+
+#include "basexecut.h"
+
+#include "pdlmgr.h"
+#include "ctimer.h"
+#include "strutil.h"
+#include "strutilxx.h"
+// #include "dlftypes.h"
+#ifdef SANS_EVOLPLANCK
+#include "nbrandom.h"
+#else
+#include "srandgen.h"
+#endif
+
+#include "pistdimgapp.h"
+#include "nobjmgr.h"
+#include "piafitting.h"
+#include "pawexecut.h"
+#include "cxxexecutor.h"
+#include "cxxexecwin.h"
+#include "contmodex.h" 
+#include "flowmodex.h"
+
+#include PISTDWDG_H 
+#include PILIST_H 
+
+// ------------------------------------------------------------
+//         Gestion d'une fenetre d'aide interactive  
+//                    Classe   PIAHelpWind   
+// ------------------------------------------------------------
+
+class PIAHelpWind : public PIWindow {
+public :
+		PIAHelpWind(PIStdImgApp* par, PIACmd* piacmd);
+  virtual	~PIAHelpWind();
+  virtual void  Show();
+  virtual void  Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+  inline  void  AddHelpGroup(const char * hgrp, int gid)
+                    { hgrpom->AppendItem(hgrp, 20000+gid); }
+  inline  void  ClearHelpList() 
+                    { mNitem=0; hitemlist->DeleteAllItems(); }
+  inline  void	AddHelpItem(const char * hitem) 
+		    { mNitem++;  hitemlist->AppendItem(hitem, 100+mNitem); }
+protected :
+  PIStdImgApp* dap;
+  PIACmd* piac;
+  int mNitem;
+  PIList* hitemlist;
+  PIOptMenu* hgrpom;
+  PIButton * mBut;
+  PILabel * mLab;
+  PIText* mTxt;
+};
+
+/* --Methode-- */
+PIAHelpWind::PIAHelpWind(PIStdImgApp *par, PIACmd* piacmd)
+  : PIWindow((PIMsgHandler *)par, "Help-PIApp", PIWK_normal,  400, 300, 100, 350)
+{
+dap = par;
+piac = piacmd;
+mNitem = 0;
+SetMsg(77);
+
+int bsx, bsy;
+int tsx, tsy;
+int spx, spy;
+PIApplicationPrefCompSize(bsx, bsy);
+spx = bsx/6;   spy = bsy/6;
+tsx = 10*bsx+2*spx;  tsy = 7*bsy+3*spy;
+SetSize(tsx,tsy);
+hgrpom = new PIOptMenu(this, "hgrpoptmen", bsx*2.0, bsy, spx/2, spy);
+hgrpom->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+hitemlist = new PIList(this, "hitemlist", bsx*2.0, tsy-3*spy-bsy, spx/2, 2*spy+bsy);
+hitemlist->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+// hitemlist->SetBorderWidth(2);
+mTxt = new PIText(this, "helptext", true, true, bsx*8.0, 6*bsy, bsx*2.0+1.5*spx, spy);
+// mTxt->SetMutiLineMode(true);
+mTxt->SetTextEditable(false);
+mTxt->SetText("");
+mTxt->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+mLab = new PILabel(this, "helpitem", bsx*4, bsy, bsx*2.5+2*spx, tsy-spy-bsy);
+mLab->SetBorderWidth(1);
+mLab->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+mLab->SetLabel("");
+mBut = new PIButton(this, "Close", 70, bsx, bsy, tsx-bsx*1.5-spx, tsy-spy-bsy);
+mBut->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+}
+
+/* --Methode-- */
+PIAHelpWind::~PIAHelpWind()
+{
+delete hgrpom;
+delete hitemlist;
+delete mTxt;
+delete mLab;
+delete mBut;
+}
+
+/* --Methode-- */
+void PIAHelpWind::Process(PIMessage msg, PIMsgHandler* sender, void* /*data*/)
+{
+PIMessage um = UserMsg(msg);
+if (((um == 77) && (ModMsg(msg) == PIMsg_Close)) || (um == 70) ) {
+  Hide();
+  return;
+  }
+else if ( (um >= 20000) && (sender == hgrpom)) {  // Selection de groupe de Help
+  mTxt->SetText("");
+  mLab->SetLabel("");
+  piac->UpdateHelpList(this, um-20000);
+}
+else if ( (um > 100) && (sender == hitemlist) && (ModMsg(msg) == PIMsg_Select) ) {
+  string s = hitemlist->GetSelectionStr();
+  mTxt->SetText(piac->GetUsage(s));
+  mLab->SetLabel(s);
+  }  
+}
+
+/* --Methode-- */
+void PIAHelpWind::Show()
+{
+hgrpom->SetValue(20000);   // Groupe All
+mTxt->SetText("");
+mLab->SetLabel("");
+piac->UpdateHelpList(this, 0); 
+PIWindow::Show();
+}
+
+// ------------------------------------------------------------
+//         Bloc de commandes (Foreach, ...)    
+//               Classe  PIACmdBloc    
+// ------------------------------------------------------------
+
+class PIACmdBloc {
+public:
+  enum BType { BT_None, BT_ForeachList, BT_ForeachInt, BT_ForeachFloat };
+
+  PIACmdBloc(PIACmd* piac, PIACmdBloc* par, string& kw, vector<string>& args); 
+  ~PIACmdBloc();
+  inline PIACmdBloc*   Parent() { return(parent); }
+  inline bool   CheckOK() { return blkok; }
+  inline void	AddLine(string& line)  
+    { lines.push_back(line); bloclineid.push_back(lines.size()); }
+  void	        AddLine(string& line, string& kw);  
+  inline void	AddBloc(PIACmdBloc* blk)  
+    { blocs.push_back(blk); bloclineid.push_back(-blocs.size()); }
+  PIACmdBloc*	Execute();
+  inline int&   TestLevel()  { return testlevel; }
+  inline int&   LoopLevel()  { return looplevel; }
+  inline bool   CheckBloc() 
+    { return ((testlevel == 0)&&(looplevel == 0)&&(!scrdef)); }
+  
+protected:
+  PIACmd* piacmd;
+  PIACmdBloc* parent;
+  bool blkok;        // true -> block OK
+  BType typ;         // foreach , integer loop, float loop, test 
+  string varname;
+  vector<string> strlist;
+  vector<string> lines;
+  vector<PIACmdBloc *> blocs;
+  vector<int> bloclineid;
+  int i1,i2,di;
+  float f1,f2,df;
+  int testlevel;   // niveau d'imbrication des if 
+  int looplevel;   // niveau d'imbrication des for/foreach 
+  bool scrdef;     // true -> commande defscript ds for/foreach 
+};
+
+/* --Methode-- */
+PIACmdBloc::PIACmdBloc(PIACmd* piac, PIACmdBloc* par, string& kw, vector<string>& args)
+{
+piacmd = piac;
+parent = par;
+blkok = false;
+typ = BT_None;
+i1 = 0;  i2 = -1;  di = 1;
+f1 = 0.; f2 = -1.; df = 1.;
+testlevel = looplevel = 0;
+scrdef = false;
+
+if ((args.size() < 2) ||  !isalpha((int)args[0][0]) )  return; 
+if ((kw != "foreach") && (kw != "for"))  return;
+varname = args[0];  // $CHECK$ Variable name should be checked 
+//if (isalpha((int)args[1][0]) ) {  This is a foreach bloc with string list
+if (kw == "foreach" ) { // This is a foreach bloc with string list
+  if ((args[1] != "(") || (args[args.size()-1] != ")") ) return;
+  for(int kk=2; kk<args.size()-1; kk++) strlist.push_back(args[kk]);
+  typ = BT_ForeachList;
+  blkok = true;
+  }
+else { // This is an integer or float loop
+  size_t l = args[1].length();
+  size_t p = args[1].find(':');
+  size_t pp = args[1].find('.');
+  bool fl = (pp < l) ? true : false;  // Float loop or integer loop
+  if (p >= l) return;  // Syntaxe error
+  string a1 = args[1].substr(0, p);
+  string aa = args[1].substr(p+1);
+  p = aa.find(':');
+  string a2, a3;
+  bool hasa3 = false;
+  if (p < aa.length() ) { 
+    a2 = aa.substr(0,p);
+    a3 = aa.substr(p+1);
+    hasa3 = true;
+    }
+  else  a2 = aa; 
+  if (fl) { 
+    typ = BT_ForeachFloat;
+    blkok = true;
+    f1 = atof(a1.c_str());
+    f2 = atof(a2.c_str());
+    if (hasa3)  df = atof(a3.c_str());
+    else df = 1.;
+    }
+  else { 
+    typ = BT_ForeachInt;
+    blkok = true;
+    i1 = atoi(a1.c_str());
+    i2 = atoi(a2.c_str());
+    if (hasa3)  di = atoi(a3.c_str());
+    else di = 1;
+    }
+  }
+}
+
+/* --Methode-- */
+PIACmdBloc::~PIACmdBloc()
+{
+for(int k=0; k<blocs.size(); k++) delete blocs[k];
+}
+
+/* --Methode-- */
+void PIACmdBloc::AddLine(string& line, string& kw)
+{
+  AddLine(line);
+  if (kw == "if")  testlevel++;
+  else if (kw == "endif")  testlevel--; 
+  else if ((kw == "for") || (kw == "foreach"))  looplevel++;
+  else if (kw == "end")  looplevel--; 
+  else if (kw == "defscript")  scrdef = true; 
+}
+
+/* --Methode-- */
+PIACmdBloc* PIACmdBloc::Execute()
+{
+// cout << " DBG * PIACmdBloc::Execute() " << typ << " - " << bloclineid.size() <<
+//      " I1,I2=" << i1 << " , " << i2 << " , " << di << endl;
+string cmd;
+int k=0;
+int kj=0;
+int kk=0;
+char buff[32];
+int rcc = 0;
+
+if (typ == BT_ForeachList)   // foreach string loop
+  for(k=0; k<strlist.size(); k++) {
+    cmd = "set " + varname + " '" + strlist[k] + "'";
+    piacmd->Interpret(cmd);
+    for(kj=0; kj<bloclineid.size(); kj++) {
+      kk = bloclineid[kj]; 
+      if (kk > 0)  { 
+	rcc = piacmd->Interpret(lines[kk-1]);
+	if (rcc == 77766)  break;
+      }
+      else blocs[-kk-1]->Execute();
+    }
+    if (rcc == 77766)  break;
+  }
+else if (typ == BT_ForeachInt)  // Integer loop
+  for(int i=i1; i<i2; i+=di) {
+    k++;
+    if (++k > 9999) {
+      cout << ">>> Maximum PIACmdBloc loop limit (9999) -> break " << endl;
+      break;
+      }
+    sprintf(buff, " %d", i);
+    cmd = "set " + varname + buff;
+    piacmd->Interpret(cmd);
+    for(kj=0; kj<bloclineid.size(); kj++) {
+      kk = bloclineid[kj]; 
+      if (kk > 0)  { 
+	rcc = piacmd->Interpret(lines[kk-1]);
+	if (rcc == 77766)  break;
+      }
+      else blocs[-kk-1]->Execute();
+    }
+    if (rcc == 77766)  break;
+  }
+else if (typ == BT_ForeachFloat)  // float loop
+  for(float f=f1; f<f2; f+=df) {
+    k++;
+    if (++k > 9999) {
+      cout << ">>> Maximum PIACmdBloc loop limit (9999) -> break " << endl;
+      break;
+      }
+    sprintf(buff, " %g", f);
+    cmd = "set " + varname + buff;
+    piacmd->Interpret(cmd);
+    for(kj=0; kj<bloclineid.size(); kj++) {
+      kk = bloclineid[kj]; 
+      if (kk > 0)  { 
+	rcc = piacmd->Interpret(lines[kk-1]);
+	if (rcc == 77766)  break;
+      }
+      else blocs[-kk-1]->Execute();
+    }
+    if (rcc == 77766)  break;
+  }
+
+return(parent); 
+}
+
+// ---------------------------------------------------------------
+//                  Classe PIACmdScript 
+//   Definition et execution d'un script de PIACmd
+//   script : Une liste de commande PIACmd - Lors de l'execution, 
+//   les variables-argument $# $0 $1 sont definies. 
+// ---------------------------------------------------------------
+
+class PIACmdScript {
+public:
+  PIACmdScript(PIACmd* piac, string const& name, string const& comm);
+  virtual ~PIACmdScript();
+
+  void	        AddLine(string& line, string& kw);  
+  virtual int   Execute(vector<string>& args);
+
+  inline string& Name() { return mName; }
+  inline string& Comment() { return mComm; }
+  inline int&   TestLevel()  { return testlevel; }
+  inline int&   LoopLevel()  { return looplevel; }
+  inline bool   CheckScript() 
+    { return ((testlevel == 0)&&(looplevel == 0)&&(!scrdef)&&fgok); }
+
+protected:
+  PIACmd* piacmd;
+  string mName;
+  string mComm;
+  vector<string> lines;
+  int testlevel;   // niveau d'imbrication des if 
+  int looplevel;   // niveau d'imbrication des for/foreach 
+  bool scrdef;     // true -> commande defscript ds for/foreach 
+  bool fgok;       // Script name OK
+  
+};
+
+/* --Methode-- */
+PIACmdScript::PIACmdScript(PIACmd* piac, string const& name, 
+			   string const& comm)
+{
+piacmd = piac;
+testlevel = looplevel = 0;
+scrdef = false;
+mName = name;
+if (!isalpha(name[0]))  fgok = false;
+else fgok = true;
+mComm = comm;
+}
+
+/* --Methode-- */
+PIACmdScript::~PIACmdScript()
+{
+}
+
+/* --Methode-- */
+void PIACmdScript::AddLine(string& line, string& kw)
+{
+  if (kw == "if")  testlevel++;
+  else if (kw == "endif")  testlevel--; 
+  else if ((kw == "for") || (kw == "foreach"))  looplevel++;
+  else if (kw == "end")  looplevel--; 
+  else if (kw == "defscript")  scrdef = true; 
+  lines.push_back(line);
+}
+
+/* --Methode-- */
+int PIACmdScript::Execute(vector<string>& args)
+{
+  if (!CheckScript()) return(-1);
+  cout << " PIACmdScript::Execute() - Executing script " << Name() << endl;
+  for(int k=0; k<lines.size(); k++) {
+    if (piacmd->Interpret(lines[k]) == 77777) break;
+  }
+  return(0);
+}
+
+// ------------------------------------------------------------
+//         Classe PIACmd
+// ------------------------------------------------------------
+
+static PIACmd* curpiacmd = NULL;
+/* --Methode-- */
+PIACmd::PIACmd(NamedObjMgr* omg, PIStdImgApp* app)
+{
+mObjMgr = omg; 
+mImgApp = app;
+system("cp history.pic hisold.pic");
+hist.open("history.pic");
+histon = true;
+trace = false;   timing = false;
+gltimer = NULL;
+felevel = 0;
+
+mulinecmd = "";
+mulinefg = false;
+spromptmul = "Cmd> ";
+if (mImgApp) mImgApp->GetConsole()->SetPrompt(spromptmul);
+curscript = NULL;
+
+CmdBlks.push(NULL);
+list<char> xtx;
+TestsStack.push(xtx);
+curtestresult = true;
+
+cmdhgrp["All"] = 0;
+cmdgrpid = 1;
+cmdhgrp["PIACmd"] = 1;
+helpwin = new PIAHelpWind(app, this);
+helpwin->AddHelpGroup("All", 0);
+helpwin->AddHelpGroup("PIACmd", 1);
+
+string kw = "Interpreter";
+string usage;
+usage = ">>> (piacmd) Interpreter's keywords : \n";
+usage += "  > set varname string   # To set a variable, $varname \n";
+usage += "  > get newvarname varname # To set a newvariable, equal to $varname \n";
+usage += "  > setol varname patt     # Fills varname with object list \n";
+usage += "  > unset varname          # clear variable definition \n";
+usage += "  > rpneval varname RPNExpression # Reverse Polish Notation evaluation \n";
+usage += "  > varname = 'string string ...' # To set a variable, $varname  \n";
+usage += "  > varname = RPNExpression # RPN evaluation / result -> varname \n";
+usage += "  > echo string            # output string \n";
+usage += "  > echo2file filename string # Append the string to the specified file \n";
+usage += "  > alias name string      # define a command alias \n";
+usage += "  > readstdin varname      # reads a line from stdin into $varname \n";
+usage += "  > foreach varname ( string-list ) # Loop \n"; 
+usage += "  > for varname i1:i2[:di]      # Integer loop  \n"; 
+usage += "  > for varname f1:f2[:df]      # Float loop  \n";
+usage += "  > end                         # end loops \n"; 
+usage += "  > if ( test ) then  # Conditional test : a == != < > <= >= b \n";
+usage += "  > else          # Conditional  \n";
+usage += "  > endif         # End of conditional if bloc \n"; 
+usage += "  > break         # Delete (clears) all test and loop blocs \n";
+usage += "  > return        # Stops command execution from a file \n";
+usage += "  > defscript endscript # Command script definition \n";
+usage += "  > listvars      # List of variable names and values \n";
+usage += "  > listalias     # List of alias names and values \n";
+usage += "  > listcommands  # List of all known commands \n";
+usage += "  > listscripts   # List of all known scripts \n";
+usage += "  > clearcript    # Clear a script definition \n";
+usage += "  > exec filename # Execute commands from file \n";
+usage += "  > help <command_name>  # <command_name> usage info \n"; 
+usage += "  > helpwindow           # Displays help window \n";
+usage += "  > timingon  timingoff traceon  traceoff \n";
+string grp = "PIACmd";
+RegisterHelp(kw, usage, grp);
+
+kw = "RPNEvaluator";
+usage = " Reverse Polish Notation (HP calculator like) expression evaluation \n";
+usage += "  >> Stack: \n";
+usage += "     ... (4) (3) z=(2) y=(1) x=(0)=Stack.Top() \n";
+usage += "  >> Examples:  \n";
+usage += "  - sin(PI/6): pi 6 / sin \n";
+usage += "  - 1*2*...*5: 1 2 3 4 5 product \n";
+usage += "  - x=x+y: x = $x $y * \n";
+usage += "  >>> Stack operations : \n";
+usage += "      print x<>y pop push (duplicate x) \n";
+usage += "  >>> Constants (Cst pushed to stack): \n";
+usage += "      pi e \n";
+usage += "  >>> Arithmetic operators (x,y) --> x@y \n";
+usage += "      + - * / % ( (int)y % (int)x )\n";
+usage += "  >>> F(X): x --> F(x) \n";
+usage += "      chs sqrt sq log log10 exp  \n"; 
+usage += "      fabs  floor ceil \n"; 
+usage += "      cos sin tan acos asin atan deg2rad rad2deg \n"; 
+usage += "  >>> F(X,Y): (x,y) --> F(x,y) \n";
+usage += "      pow atan2 \n"; 
+usage += "  >>> F(): random number generators \n";
+usage += "      rand (flat 0..1) norand (normal/gaussian) \n"; 
+usage += "  >>> Stack sum/product/mean/sigma/sigma^2 \n";
+usage += "      sum product mean sigma sigma2 sigmean (y->sigma x->mean) \n"; 
+RegisterHelp(kw, usage, grp);
+
+kw = "autoiniranf";
+usage  = "> Automatic random number generator initialisation\n";
+usage += "   by Auto_Ini_Ranf(int lp) \n";
+usage += "   Usage: autoiniranf";
+RegisterHelp(kw, usage, grp);
+
+kw = "shell execute";
+usage  = "> shell  command_string  # Execute  shell command\n";
+usage += "> cshell command_string  # Execute cshell command\n";
+usage += "---Examples:\n";
+usage += "  > shell ls\n";
+usage += "  > cshell echo '$LD_LIBRARY_PATH'; map2cl -h; ls\n";
+usage += "  > shell myfile.csh [arg1] [arg2] [...]\n";
+usage += "    (where the first line of \"myfile.csh\" is \"#!/bin/csh\")\n";
+RegisterHelp(kw, usage, grp);
+
+kw = "exitpiapp";
+usage = "To end the piapp session (Interpreter's command)";
+RegisterHelp(kw, usage, grp);
+
+basexec = new PIABaseExecutor(this, omg, app);
+fitexec = new PIAFitter(this, app);
+pawexec = new PAWExecutor(this, app);
+CxxExecutor * cxxe = new CxxExecutor(this, app);
+cxxexec = cxxe;
+
+ContModExecutor *cntxx = new ContModExecutor(this, app);//_OP_
+cntexec = cntxx; //_OP_
+FlowModExecutor *flwxx = new FlowModExecutor(this, app);//_OP_
+flwexec = flwxx; //_OP_
+
+cxxoptwin = new  CxxOptionWind(app, cxxe);
+cxxexwin  = new  CxxExecWind(app, cxxe);
+
+AddInterpreter(this);
+curcmdi = this;
+}
+
+/* --Methode-- */
+PIACmd::~PIACmd()
+{
+hist.close();
+if (gltimer) { delete gltimer;  gltimer = NULL; }
+Modmap::iterator it;
+for(it = modmap.begin(); it != modmap.end(); it++) {
+  string name = (*it).first + "_end";
+  DlModuleInitEndFunction fend = (*it).second->GetFunction(name);
+  if (fend) fend();
+  delete (*it).second;
+  }
+
+for(ScriptList::iterator sit = mScripts.begin();
+    sit != mScripts.end(); sit++) delete (*sit).second; 
+ 
+delete helpwin;
+delete cxxexwin;
+delete cxxoptwin;
+if (curpiacmd == this)  curpiacmd = NULL;
+delete basexec;
+delete fitexec;
+delete pawexec;
+delete cxxexec;
+}
+
+/* --Methode-- */
+PIACmd* PIACmd::GetInterpreter()
+{
+return(curpiacmd);
+}
+
+/* --Methode-- */
+string PIACmd::Name()
+{
+return("piacmd");
+}
+
+/* --Methode-- */
+void PIACmd::RegisterCommand(string& keyw, string& usage, CmdExecutor * ce, string grp)
+{
+if (!ce) { 
+  RegisterHelp(keyw, usage, grp);
+  return;
+  }
+int gid = CheckHelpGrp(grp);
+cmdex cme;
+cme.group = gid;
+cme.us = usage;
+cme.cex = ce;
+cmdexmap[keyw] = cme;
+}
+
+/* --Methode-- */
+void PIACmd::RegisterHelp(string& keyw, string& usage, string& grp)
+{
+int gid = CheckHelpGrp(grp);
+cmdex cme;
+cme.group = gid;
+cme.us = usage;
+cme.cex = NULL;
+helpexmap[keyw] = cme;
+}
+
+/* --Methode-- */
+int PIACmd::CheckHelpGrp(string& grp)
+{
+int gid=0;
+CmdHGroup::iterator it = cmdhgrp.find(grp);
+if (it == cmdhgrp.end()) {
+  cmdgrpid++;   gid = cmdgrpid;
+  cmdhgrp[grp] = gid;
+  helpwin->AddHelpGroup(grp.c_str(), gid);
+  }
+else gid = (*it).second;
+return(gid);
+}
+
+/* --Methode-- */
+void PIACmd::UpdateHelpList(PIAHelpWind* hw, int gid)
+{
+helpwin->ClearHelpList();
+CmdExmap::iterator it;
+for(it = helpexmap.begin(); it != helpexmap.end(); it++) {
+  if ( (gid != 0) && ((*it).second.group != gid) ) continue;
+  helpwin->AddHelpItem((*it).first.c_str());
+  }
+for(it = cmdexmap.begin(); it != cmdexmap.end(); it++) {
+  if ( (gid != 0) && ((*it).second.group != gid) ) continue;
+  helpwin->AddHelpItem((*it).first.c_str());
+  }
+}
+
+/* --Methode-- */
+void PIACmd::LoadModule(string& fnameso, string& name)
+{
+PDynLinkMgr * dynlink = new PDynLinkMgr(fnameso, false);
+if (dynlink == NULL) {
+  cerr << "PIACmd/LoadModule_Error: Pb opening SO " << fnameso << endl;
+  return;
+  }
+string fname = name + "_init";
+DlModuleInitEndFunction finit = dynlink->GetFunction(fname);
+if (!finit) {
+  cerr << "PIACmd/LoadModule_Error: Pb linking " << fname << endl;
+  return;
+  }
+cout << "PIACmd/LoadModule_Info: Initialisation module" << name 
+     << "  " << fname << "() ..." << endl;
+finit();
+modmap[name] = dynlink;
+return;
+}
+
+/* --Methode-- */
+void PIACmd::AddInterpreter(CmdInterpreter * cl)
+{
+if (!cl) return;
+interpmap[cl->Name()] = cl;}
+
+/* --Methode-- */
+void PIACmd::SelInterpreter(string& name)
+{
+InterpMap::iterator it = interpmap.find(name);
+if (it == interpmap.end())   return;
+curcmdi = (*it).second;
+}
+
+
+
+/* Fonction */
+static string GetStringFrStdin(PIACmd* piac)
+{
+PIStdImgApp* piapp = piac->GetImgApp();
+if (piapp) {
+  PIBaseWdg* wdg = piapp->CurrentBaseWdg();
+  if (wdg)  wdg->Refresh();
+#ifndef __mac__
+  /* On vide le buffer X-Window */
+  XSync(PIXDisplay(),False);
+#endif
+}
+char buff[128];
+fgets(buff, 128, stdin);
+buff[127] = '\0';
+return((string)buff);
+}
+
+/* --Methode-- */
+int PIACmd::Interpret(string& s)
+{
+int rc = 0;
+NamedObjMgr omg;
+ScriptList::iterator sit;
+
+// On saute de commandes vides
+size_t l;
+l = s.length();
+if (!mulinefg && (l < 1))  return(0);
+
+// On enregistre les commandes 
+if (histon) hist << s << endl;   
+
+if (s[0] == '#') return(0); // si c'est un commentaire
+
+// Logique de gestion des lignes suite
+// un \ en derniere position indique la presence d'une ligne suite
+size_t lnb = s.find_last_not_of(' ');
+if (s[lnb] == '\\' ) { // Lignes suite ...
+  mulinecmd += s.substr(0,lnb);
+  if (!mulinefg) {
+    spromptmul = mImgApp->GetConsole()->GetPrompt();
+    mImgApp->GetConsole()->SetPrompt("...? ");
+    mulinefg = true;
+  }
+  return(0);
+}
+
+if (mulinefg) {  // Il y avait des lignes suite
+  s = mulinecmd + s;
+  mulinecmd = "";
+  mulinefg = false;
+  mImgApp->GetConsole()->SetPrompt(spromptmul);
+}
+
+// Removing leading blanks
+size_t p,q;
+
+p=s.find_first_not_of(" \t");
+if (p < l) s = s.substr(p);
+
+// >>>> Substitution d'alias (1er mot)
+CmdStrList::iterator it;
+p = 0;
+q = s.find_first_of(" \t");
+l = s.length();
+string w1 =  (q < l) ? s.substr(p,q-p) : s.substr(p);
+it = mAliases.find(w1);
+if (it != mAliases.end())  { 
+  s =  (q < l) ? ((*it).second + s.substr(q)) : (*it).second ;
+  l = s.length();
+  p=s.find_first_not_of(" \t");
+  if (p < l) s = s.substr(p);
+  p = 0;
+  q = s.find_first_of(" ");
+  }
+
+// >>>> Separating keyword 
+string toks,kw;
+if (q < l)
+  {  kw = s.substr(p,q-p);  toks = s.substr(q, l-q); }
+else { kw = s.substr(p,l-p);  toks = ""; }
+
+// les mot-cle end else endif doivent etre le seul mot de la ligne
+if ( (kw == "end") || (kw == "else") || (kw == "endif") || (kw == "endscript") ) {
+  size_t ltk = toks.length();
+  if (toks.find_first_not_of(" \t") < ltk) {
+    cerr << "PIACmd::Interpret()/syntax error near end else endif endscript \n"
+	 << "line: " << s << endl;
+    return(1);
+  }
+}
+
+// On verifie si on est en train de definir un script
+if (curscript) {
+  if (kw == "endscript") {
+    if (curscript->CheckScript()) {
+      sit = mScripts.find(curscript->Name());
+      if (sit != mScripts.end()) {
+	cout << "PIACmd::Interpret() replacing script " 
+	     << curscript->Name() << endl;
+	PIACmdScript* scr = mScripts[curscript->Name()];
+	mScripts.erase(sit);
+	delete scr;
+      }
+      cout << "PIACmd::Interpret() Script " << curscript->Name() 
+	   << " defined successfully" << endl;
+      mScripts[curscript->Name()] = curscript;
+      mImgApp->GetConsole()->SetPrompt("Cmd> ");
+      curscript = NULL;
+      return(0);
+    }
+    else {
+      cout << "PIACmd::Interpret() Error in Script " << curscript->Name() 
+	   << " definition " << endl;
+      mImgApp->GetConsole()->SetPrompt("Cmd> ");
+      curscript = NULL;
+      return(2);
+    }
+  }
+  else curscript->AddLine(s, kw);
+  return(0);
+}
+// On verifie si nous sommes dans un bloc (for , foreach)
+if (CmdBlks.top() != NULL)  { // On est dans un bloc
+  if ( (kw == "for") || (kw == "foreach")) felevel++;
+  else if (kw == "end") felevel--;
+  if (felevel == 0) { // Il faut executer le bloc
+    PIACmdBloc* curb = CmdBlks.top();
+    CmdBlks.top() = curb->Parent();
+    mImgApp->GetConsole()->SetPrompt("Cmd> ");
+    if (!curb->CheckBloc()) {
+      cerr << "PIACmd::Interpret()/syntax error - unbalenced if ... endif"
+	   << " within for/foreach bloc ! " << endl;
+      delete curb;
+      return(2);  
+    }
+       //       cout << " *DBG* Executing bloc " << endl;
+    bool ohv = histon;
+    histon = false;
+    if (curtestresult) { 
+      // We push also PIACmdBloc and testresult on the stack
+      CmdBlks.push(NULL);
+      list<char> xtx;
+      TestsStack.push(xtx);
+      curb->Execute();
+      // And PIACmdBloc and TestResult from the corresponding stacks
+      PopStack(false);
+    }
+    delete curb;
+    histon = ohv;
+  }
+  else CmdBlks.top()->AddLine(s, kw); 
+  return(0);
+}
+else if (kw == "end") {
+  cerr << "PIACmd::Interpret()/syntax error - end outside for/foreach bloc \n"
+       << "line: " << s << endl;
+  return(1);  
+}
+
+// Sommes-nous dans un bloc de test if then else 
+if (TestsStack.top().size() > 0) {  // Nous sommes ds un bloc if 
+  if (kw == "else") {
+    if ((*tresit) & 2) {
+      cerr << "PIACmd::Interpret()/syntax error - multiple else in if bloc \n"
+	   << "line: " << s << endl;
+      return(1);
+    }
+    else { 
+      const char * npr = ((*tresit)&1) ? "else-F> " : "else-T> ";
+      if ((*tresit)&1)  curtestresult = false;
+      mImgApp->GetConsole()->SetPrompt(npr);
+      (*tresit) |= 2;
+      return(0);
+    }
+  }
+  else if (kw == "endif") {
+    list<char>::iterator dbit = tresit;
+    tresit--;
+    TestsStack.top().erase(dbit);
+    const char * npr = "Cmd> ";
+    if (TestsStack.top().size() > 1) {
+      curtestresult = true;
+      list<char>::iterator it;
+      for(it=TestsStack.top().begin(); it!=TestsStack.top().end(); it++) {
+	// Si on n'est pas ds le else et le if est faux
+	if ( !((*it)&2) && !((*it)&1) ) curtestresult = false;
+	// Si on est ds else et le if etait vrai !
+	if ( ((*it)&2) && ((*it)&1) )  curtestresult = false;
+	if (!curtestresult)  break;
+      }
+      
+      if (!((*tresit)&2)) 
+	npr = ((*tresit)&1) ? "if-T> " : "if-F> ";
+      else 
+	npr = ((*tresit)&1) ? "else-F> " : "else-T> ";
+    }
+    else curtestresult = true;
+    mImgApp->GetConsole()->SetPrompt(npr);
+    return(0);
+  }
+} 
+else if ((kw == "else") || (kw == "endif")) {
+  cerr << "PIACmd::Interpret()/syntax error - else,endif outside if bloc \n"
+       << "line: " << s << endl;
+  return(1);  
+}
+
+bool fgcont = true;
+if (TestsStack.top().size() > 0) { // Resultat de if ou else
+  list<char>::iterator it;
+  for(it=TestsStack.top().begin(); it!=TestsStack.top().end(); it++) {
+    // Si on n'est pas ds le else et le if est faux
+    if ( !((*it)&2) && !((*it)&1) )  fgcont = false;
+    // Si on est ds else et le if etait vrai !
+    if ( ((*it)&2) && ((*it)&1) )  fgcont = false;
+    if (!fgcont)  break;
+  }
+} 
+
+if ((!fgcont) && (kw != "if"))  return(0);
+
+
+// Les mots cles break et return peuvent de sortir de boucles/scripts/execfile
+if (kw == "break") return(77766);
+else if (kw == "return")  return(77777);
+
+// Nous ne sommes donc pas dans un bloc ....  Substitution de variables
+string s2;
+int rcs ;
+// Execution de code C++
+
+if (kw == "@@") {
+  CxxExecutor * cxxe = dynamic_cast<CxxExecutor *>(cxxexec);
+  if (cxxe == NULL) {
+    cerr << "PIACmd::Interpret() - BUG !!! Not a CxxExecutor " << endl;
+    return(99);
+  }
+  return(cxxe->ExecuteCXX(s.substr(2)));
+}
+
+
+rcs = SubstituteVars(s, s2);
+if (rcs) { 
+  cerr << "PIACmd::Interpret()/syntax error in SubstituteVars() \n"
+       << "line: " << s << endl;
+  return(rcs);
+}
+// >>>> Separating keyword and tokens 
+vector<string> tokens;
+/* decoupage en mots */
+LineToWords(s2, kw, tokens, toks, true);
+
+// Si c'est un for/foreach, on cree un nouveau bloc
+if ((kw == "foreach") || (kw == "for")) {
+  //     cout << " *DBG* We got a foreach... " << endl;
+  PIACmdBloc* bloc = new PIACmdBloc(this, CmdBlks.top(), kw, tokens);
+  if (!bloc->CheckOK()) {
+    cerr << "PIACmd::Interpret() for/foreach syntax Error ! " << endl;
+    delete bloc;
+    return(1);
+    }
+  felevel++;
+  if (CmdBlks.top())  CmdBlks.top()->AddBloc(bloc);
+  else  mImgApp->GetConsole()->SetPrompt("for...> ");
+  CmdBlks.top() = bloc;
+  //  cout << " *DBG* New Bloc created ... " << endl;
+  return(0);
+  }
+else if (kw == "if") {  // Un test if
+  bool restst = true;
+  int rct = EvaluateTest(tokens, s, restst);
+  if (rct) {
+    cerr << "PIACmd::Interpret() if syntax Error ! " << "line: " << s << endl;
+    return(1);
+  }
+  char res_tst = (restst) ? 1 : 0;
+  TestsStack.top().push_back(res_tst);
+  if (TestsStack.top().size() == 1) tresit = TestsStack.top().begin();
+  else tresit++;
+  const char * npr = (restst) ? "if-T> " : "if-F> ";
+  mImgApp->GetConsole()->SetPrompt(npr);
+}
+else if ((tokens.size() > 0) && (tokens[0] == "=")) {  
+  // x = RPNExpression (Evaluation d'expression RPN)
+  tokens[0] = kw;
+  int rcev = EvalRPNExpr(tokens, s);
+  if (rcev) {
+    cerr << "PIACmd::Interpret() evaluation (RPN) syntax Error ! " << "line: " << s << endl;
+    return(1);
+  }
+  return(0);
+}
+else if (kw == "defscript") {  // definition de script
+  if (tokens.size() > 0) {
+    if (tokens.size() < 2)  tokens.push_back("");
+    curscript = new PIACmdScript(this, tokens[0], tokens[1]);
+    mImgApp->GetConsole()->SetPrompt("Script...> ");
+    return(0);
+  }
+  else {
+    cerr << "PIACmd::Interpret() No script name in defscript" << "line: " << s << endl;
+    return(1);
+  }
+}
+else {
+  //  Si c'est le nom d'un script 
+  sit = mScripts.find(kw);
+  if (sit != mScripts.end()) {
+    bool ohv = histon;
+    histon = false; 
+    tokens.insert(tokens.begin(), kw);
+    PushStack(tokens);
+    (*sit).second->Execute(tokens);
+    PopStack(true);
+    histon = ohv;
+  }
+  //  Execution de commandes 
+  else rc = ExecuteCommandLine(kw, tokens, toks);
+  return(rc);
+}  
+// cout << "PIACmd::Do() DBG  KeyW= " << kw << " NbArgs= " << tokens.size() << endl;
+//  for(int ii=0; ii<tokens.size(); ii++)
+//  cout << "arg[ " << ii << " ] : " << tokens[ii] << endl;
+
+return(0);
+}
+
+
+/* --Methode-- */
+int PIACmd::LineToWords(string& line, string& kw, vector<string>& tokens, 
+			string& toks, bool uq)
+{
+if (line.length() < 1)  return(0);
+int nw = 1;
+size_t p = line.find_first_not_of(" ");
+line = line.substr(p);
+p = 0;
+size_t q = line.find_first_of(" ");
+size_t l = line.length();
+
+if (q < l)
+  {  kw = line.substr(p,q-p);  toks = line.substr(q, l-q); }
+else { kw = line.substr(p,l-p);  toks = ""; }
+
+q = 0;
+while (q < l)  {
+  p = toks.find_first_not_of(" \t",q+1); // au debut d'un token
+  if (p>=l) break;
+  if ( uq && ((toks[p] == '\'') || (toks[p] == '"')) ) {
+    q = toks.find(toks[p],p+1);
+    if (q>=l)  { 
+      cerr << "PIACmd::LineToWords/Syntax Error - Unbalenced quotes " << toks[p] << '.' << endl;
+      return(-1);
+    }
+    p++;
+  }
+  else {
+    q = toks.find_first_of(" \t",p); // la fin du token;
+  }
+  string token = toks.substr(p,q-p);
+  tokens.push_back(token);  nw++;
+  }
+
+return(nw);
+}
+
+/* --Methode-- */
+int PIACmd::SubstituteVars(string & s, string & s2)
+//  Variable substitution  
+{
+NamedObjMgr& omg = *mObjMgr;
+
+int iarr = -1;  // index d'element de tableau
+size_t p,q,q2,q3,l;
+
+s2="";
+p = 0;
+l = s.length();
+string vn, vv;
+while (p < l) {
+  iarr = -1;
+  q = s.find('$',p);
+  if (q > l) break;
+  q2 = s.find('\'',p);
+  if ((q2 < l) && (q2 < q)) {  // On saute la chaine delimitee par ' '
+    q2 = s.find('\'',q2+1);
+    if (q2 >= l) {
+      cerr << " Syntax error - Unbalenced  quotes !!! " << endl;
+      return(1);
+      }
+    s2 += s.substr(p, q2-p+1);
+    p = q2+1;  continue;  
+  }
+  //  cout << "DBG: " << s2 << " p= " << p << " q= " << q << " L= " << l << endl;
+  if ((q>0) && (s[q-1] == '\\')) {   // Escape character \$
+     s2 += (s.substr(p,q-1-p) + '$') ; p = q+1;
+     continue;
+     }
+  if (q >= l-1) {
+      cerr << " Syntax error - line ending with $ !!! " << endl;
+      return(2);
+      }
+  vn = "";
+  if ( s[q+1] == '{' ) {  // Variable in the form ${name}
+    q2 = s.find('}',q+1);
+    if (q2 >= l) {
+      cerr << " Syntax error -  Unbalenced  brace {} !!! " << endl;
+      return(3);
+      }
+    vn = s.substr(q+2,q2-q-2);
+    q2++;
+  }
+  else if ( s[q+1] == '(' ) {  // Variable in the form $(name)
+    q2 = s.find(')',q+1);
+    if (q2 >= l) {
+      cerr << " Syntax error -  Unbalenced  parenthesis () !!! " << endl;
+      return(3);
+      }
+    vn = s.substr(q+2,q2-q-2);
+    q2++;
+  }
+  else if ( s[q+1] == '[' ) {  // Variable in the form $[varname]  -> This is $$varname
+    q2 = s.find(']',q+1);
+    if (q2 >= l) {
+      cerr << " Syntax error - Unbalenced  brace [] !!! " << endl;
+      return(4);
+      }
+    vn = s.substr(q+2,q2-q-2);
+    if (!GetVar(vn, vv)) return(5);
+    vn = vv;
+    q2++;
+    }
+  else { 
+    q2 = s.find_first_of(" .:+-*/,[](){}&|!$\"'",q+1); 
+    if (q2 > l) q2 = l;
+    q3 = q2;
+    vn = s.substr(q+1, q2-q-1); 
+    // Si variable de type $varname[index] : element de tableau
+    if ((q2 < l) && (s[q2] == '[') ) {
+      q3 = s.find_first_of("]",q2+1);
+      string sia = s.substr(q2+1, q3-q2-1);
+      if (sia.length() < 1) {
+	cerr << " Syntax error - in $varname[index] : $"  
+	     << vn << "[" << sia <<"]" << endl;
+	return(4);
+      }
+      if (isalpha(sia[0])) {
+	string sia2;
+	if (!GetVar(sia, sia2) || (sia2.length() < 1)) {
+	  cerr << " Syntax error - in $varname[index] : $"  
+	       << vn << "[" << sia <<"]" << endl;
+	return(4);	  
+	}
+	sia = sia2;
+      }
+      int rcdia = ctoi(sia.c_str(), &iarr);
+      if (rcdia < 0) {
+	cerr << " Syntax error - in $varname[iarr] : $" 
+	     << vn << "[" << sia <<"]" << endl;
+	return(4);
+      }
+    }
+  }
+  if (!GetVar(vn, vv)) return(5);
+  if (iarr < 0) {
+    s2 += (s.substr(p, q-p) + vv);
+    p = q2;
+  }
+  else {
+    vector<string> vs;
+    FillVStringFrString(vv, vs);
+    if (iarr >= vs.size()) {
+      cerr << " Substitution error - word index out of range in "
+	   << "$varname[iarr] : $" << vn << "[" << iarr <<"]" << endl;
+      return(4);
+    }
+    else s2 += (s.substr(p, q-p) + vs[iarr]);
+    p = q3+1;
+  }
+} 
+if (p < l) s2 += s.substr(p);
+
+p = s2.find_first_not_of(" \t");
+if (p < l) s2 = s2.substr(p);
+
+return(0);
+}
+
+/* --Methode-- */
+bool PIACmd::GetVar(string & vn, string & vv)
+{
+NamedObjMgr& omg = *mObjMgr;
+if (vn.length() < 1) {
+  cerr << " PIACmd::SubstituteVar/Error: length(varname=" << vn << ")<1 !" << endl;
+  vv = "";    return(false);
+}
+// Variable de type $# $0 $1 ... (argument de .pic ou de script)
+int ka = 0;
+if (vn == "#") {
+  if (ArgsStack.empty()) {
+    cerr << " PIACmd::SubstituteVar/Error: ArgsStack empty ! " 
+	 << " ($" << vn << ")" << endl;
+    vv = "";  return(false);
+  }
+  char buff[32];
+  long an = ArgsStack.top().size();
+  sprintf(buff,"%ld", an);
+  vv = buff;  return(true);
+}
+else if (ctoi(vn.c_str(), &ka) > 0) {  // $0 $1 $2 ...
+  if (ArgsStack.empty()) {
+    cerr << " PIACmd::SubstituteVar/Error: ArgsStack empty ! " 
+	 << " ($" << vn << ")" << endl;
+    vv = ""; return(false);
+  }
+  if ( (ka < 0) || (ka >= ArgsStack.top().size()) ) {
+    cerr << " PIACmd::SubstituteVar/Error: Undefined variable ! " 
+	 << " ($" << vn << ")" << endl;
+    vv = ""; return(false);
+  }
+  vv = ArgsStack.top()[ka];  return(true);
+}
+else if (vn[0] == '#') {  // Variable de type $#vname --> size(vname) 
+  vn = vn.substr(1);
+  if (!omg.HasVar(vn) ) {
+    cerr << " PIACmd::SubstituteVarError: Undefined variable " 
+	 << vn << " ! " << endl;
+    vv = "";  return(false);
+  }
+  vn = omg.GetVar(vn);
+  vector<string> vs;
+  FillVStringFrString(vn, vs);
+  char buff[32];
+  sprintf(buff,"%d", (int)vs.size());
+  vv = buff; return(true);
+  } 
+else {  // variable ordinaire geree par NamedObjMgr
+  if ( (!omg.HasVar(vn)) )  {
+    cerr << " PIACmd::SubstituteVarError: Undefined variable " 
+	 << vn << " ! " << endl;
+    vv = "";  return(false);
+  }
+  vv = omg.GetVar(vn);  return(true);
+}
+
+return(false);
+}
+
+/* --Methode-- */
+int PIACmd::EvaluateTest(vector<string> & args, string & line, bool & res)
+{
+  res = true;
+  if ((args.size() != 6) || (args[5] != "then") || 
+      (args[0] != "(") || (args[4] != ")") ) return(1);
+  if (args[2] == "==") res = (args[1] == args[3]);
+  else if (args[2] == "!=") res = (args[1] != args[3]);
+  else if (args[2] == "<") 
+    res = (atof(args[1].c_str()) < atof(args[3].c_str()));
+  else if (args[2] == ">") 
+    res = (atof(args[1].c_str()) > atof(args[3].c_str()));
+  else if (args[2] == "<=") 
+    res = (atof(args[1].c_str()) <= atof(args[3].c_str()));
+  else if (args[2] == ">=") 
+    res = (atof(args[1].c_str()) >= atof(args[3].c_str()));
+  else return(2);
+  return(0);
+}
+
+/* Operations sur le stack RPN */
+inline bool Check_myRPNStack_(stack<double>& s, double& x, string& line) 
+{
+  if (s.empty()) { 
+    cerr << "PIACmd::EvalRPNExpr: syntax error / empty RPN stack " << line << endl; 
+    return true; 
+  } 
+  else x = s.top();
+  return false;
+}
+inline bool Check_myRPNStack_(stack<double>& s, double& x, double& y, string& line) 
+{
+  if (s.size() < 2) { 
+    cerr << "PIACmd::EvalRPNExpr: syntax error / RPN stack size < 2  " << line << endl; 
+    return true; 
+  }  
+ else { 
+   x = s.top(); s.pop(); y = s.top(); 
+ }
+  return false;
+}
+
+inline void Print_myRPNStack_(stack<double> s)
+{
+  if (s.empty()) 
+    cout << "PIACmd::EvalRPNExpr/PrintStack: Empty stack " << endl;
+  else {
+    int k = 0;
+    cout << "PIACmd::EvalRPNExpr/PrintStack: Size()= " << s.size() << endl;
+    while( !s.empty() ) {
+      cout << "    " << k << ":  " << s.top() << "  ";
+      if (k == 0)  cout << " (x) " << endl;
+      else if (k == 1) cout << " (y) " << endl;
+      else if (k == 2) cout << " (z) " << endl;
+      else cout << endl;
+      s.pop(); k++;
+    }
+  }
+  
+} 
+
+int Sum_RPNStack_(stack<double>& s, double& sx, double& sx2, string& line) 
+{
+  sx = sx2 = 0.;
+  int nn = 0;
+  double x = 0.;
+  while( !s.empty() ) {
+    x = s.top(); s.pop();
+    sx += x; sx2 += x*x;
+    nn++;
+  } 
+  return(nn);  
+}
+
+int Product_RPNStack_(stack<double>& s, double& px, string& line) 
+{
+  px = 1.;
+  int nn = 0;
+  double x = 0.;
+  while( !s.empty() ) {
+    x = s.top(); s.pop();
+    px *= x;  nn++;
+  } 
+  return(nn);  
+}
+  
+/* --Methode-- */
+int PIACmd::EvalRPNExpr(vector<string> & args, string & line)
+{
+  NamedObjMgr& omg = *mObjMgr;
+  
+  if (args.size() < 2) { 
+    cerr << "PIACmd::EvalRPNExpr: syntax error / missing arguments " << line << endl; 
+    return(1);
+  }
+  else if (args.size() == 2) { 
+    omg.SetVar(args[0], args[1]);
+    return(0); 
+  }
+
+  double x,y;
+  x = y = 0.;
+  stack<double> rpnstack;  // Stack des operations en RPN 
+  for(int k=1; k<args.size(); k++) {
+    // Les 4 operations de base + - * / 
+    if (args[k] == "+") { 
+      if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1);
+      rpnstack.top() = y+x;
+    }
+    else if (args[k] == "-") { 
+      if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1);
+      rpnstack.top() = y-x;
+    }
+    else if (args[k] == "*") { 
+      if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1);
+      rpnstack.top() = y*x;
+    }
+    else if (args[k] == "/") { 
+      if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1);
+      rpnstack.top() = y/x;
+    }
+    else if (args[k] == "%") { 
+      if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1);
+      rpnstack.top() = (int)y % (int)x;
+    }
+    // Les constantes : e , pi
+    else if (args[k] == "e") {
+      rpnstack.push(M_E);
+    }
+    else if (args[k] == "pi") {
+      rpnstack.push(M_PI);
+    }
+    // Les fonctions usuelles a 1 argument f(x)
+    else if (args[k] == "cos") {
+      if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
+      rpnstack.top() = cos(x);
+    }
+    else if (args[k] == "sin") {
+      if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
+      rpnstack.top() = sin(x);
+    }
+    else if (args[k] == "tan") {
+      if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
+      rpnstack.top() = tan(x);
+    }
+    else if (args[k] == "acos") {
+      if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
+      rpnstack.top() = acos(x);
+    }
+    else if (args[k] == "asin") {
+      if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
+      rpnstack.top() = asin(x);
+    }
+    else if (args[k] == "atan") {
+      if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
+      rpnstack.top() = atan(x);
+    }
+    else if (args[k] == "chs") {
+      if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
+      rpnstack.top() = -x;
+    }
+    else if (args[k] == "sqrt") {
+      if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
+      rpnstack.top() = sqrt(x);
+    }
+    else if (args[k] == "sq") {  // x^2 
+      if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
+      rpnstack.top() = x*x;
+    }
+    else if (args[k] == "log") {
+      if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
+      rpnstack.top() = log(x);
+    }
+    else if (args[k] == "log10") {
+      if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
+      rpnstack.top() = log10(x);
+    }
+    else if (args[k] == "exp") {
+      if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
+      rpnstack.top() = exp(x);
+    }
+    else if (args[k] == "fabs") {
+      if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
+      rpnstack.top() = fabs(x);
+    }
+    else if (args[k] == "floor") {
+      if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
+      rpnstack.top() = floor(x);
+    }
+    else if (args[k] == "ceil") {
+      if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
+      rpnstack.top() = ceil(x);
+    }
+    // trunc et nint vire - ca ne compile pas sous linux - Reza 01/2003
+    else if (args[k] == "deg2rad") {
+      if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
+      rpnstack.top() = x*M_PI/180.;
+    }
+    else if (args[k] == "rad2deg") {
+      if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
+      rpnstack.top() = x*180./M_PI;
+    }
+    // Les fonctions usuelles a 2 argument f(x,y)
+    else if (args[k] == "pow") { 
+      if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1);
+      rpnstack.top() = pow(y,x);
+    }
+    else if (args[k] == "atan2") { 
+      if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1);
+      rpnstack.top() = atan2(x,y);
+    }
+    // generateur aleatoire
+    else if (args[k] == "rand") { 
+      double rnd = drand01();
+      rpnstack.push(rnd);
+    }
+    else if (args[k] == "norand") { 
+      double rnd = GauRnd(0., 1.);
+      rpnstack.push(rnd);
+    }
+    // Fonction a N arguments  - Somme, produit, etc ...
+    else if ((args[k] == "sum") || (args[k] == "mean") || (args[k] == "sigmean") || 
+	     (args[k] == "sigma") || (args[k] == "sigma2") ) {
+      double sx, sx2;
+      int nn = Sum_RPNStack_(rpnstack, sx, sx2, line);
+      if (args[k] == "sum") rpnstack.push(sx);
+      else { 
+	if (nn == 0) {
+	  cerr << "PIACmd::EvalRPNExpr: mean/sigma error- RPN stack empty: " 
+	       << line << endl; 
+	  return(1);
+	}
+	double fnn = nn;
+	if ((args[k] == "sigma") || (args[k] == "sigmean")) 
+	  rpnstack.push(sqrt(sx2/fnn-(x*x/(fnn*fnn))));
+	else if ((args[k] == "mean") || (args[k] == "sigmean"))  rpnstack.push(sx/fnn);
+	else rpnstack.push(sx2/fnn-(x*x/(fnn*fnn)));
+      }
+    }
+    else if (args[k] == "product") { 
+      double px;
+      int nn = Product_RPNStack_(rpnstack, px, line);
+      if (nn == 0) {
+	cerr << "PIACmd::EvalRPNExpr: product error- RPN stack empty: " 
+	     << line << endl; 
+	return(1);
+      }
+      rpnstack.push(px);
+    }
+    // Fonctions de manipulation de stack
+    else if (args[k] == "print") { 
+      Print_myRPNStack_(rpnstack);
+    }
+    else if (args[k] == "x<>y") {
+      if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1);
+      rpnstack.top() = x;  rpnstack.push(y);
+    }
+    else if (args[k] == "pop") {
+      rpnstack.pop();
+    }
+    else if (args[k] == "push") {
+      if (rpnstack.empty()) rpnstack.push(0.);
+      else rpnstack.push(rpnstack.top());
+    }
+    // On met un nombre sur le stack 
+    else {
+      char * esptr;
+      x = strtod(args[k].c_str(), &esptr);
+      //      if (ctof(args[k].c_str(),&x) < 0) {
+      if (esptr == args[k].c_str()) {
+	cerr << "PIACmd::EvalRPNExpr: syntax error near " << args[k] 
+	     << " in expression: \n" << line << endl; 
+	return(2);
+      }
+      rpnstack.push(x);
+    }
+
+  }
+
+  if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
+  char buff[64];
+  sprintf(buff, "%g", x);
+  string res = buff;
+  omg.SetVar(args[0], res);
+  return(0);
+}
+
+/* --Methode-- */
+void PIACmd::PushStack(vector<string>& args)
+{
+  // We push the argument list (args) on the stack
+  ArgsStack.push(args);
+  // We push also PIACmdBloc and testresult on the stack
+  CmdBlks.push(NULL);
+  list<char> xtx;
+  TestsStack.push(xtx);
+
+}
+
+/* --Methode-- */
+void PIACmd::PopStack(bool psta)
+{
+  // We remove the argument list (args) from the stack
+  if (psta) ArgsStack.pop();
+  // And PIACmdBloc and TestResult from the corresponding stacks
+  PIACmdBloc* curb = CmdBlks.top();
+  while (curb != NULL) {
+    PIACmdBloc* parb = curb->Parent();
+    delete curb;  curb = parb;
+  }
+  CmdBlks.pop();
+  TestsStack.pop();
+}
+
+/* --Methode-- */
+int PIACmd::ExecuteCommandLine(string & kw, vector<string> & tokens, string & toks)
+{
+int rc = 0;
+NamedObjMgr omg;
+
+// >>>>>>>>>>> Commande d'interpreteur
+if (kw == "helpwindow") ShowHelpWindow();
+else if (kw == "help") {
+  if (tokens.size() > 0) cout << GetUsage(tokens[0]) << endl;
+  else {  
+    string kwh = "piacmd";
+    cout << GetUsage(kwh) << endl;
+    }
+  }
+
+else if (kw == "set") {
+  if (tokens.size() < 2) { cout << "PIACmd::Interpret() Usage: set varname string" << endl;  return(0); }
+  if ((tokens[0].length() < 1) || !isalpha((int)tokens[0][0]) ) {
+    cerr << "PIACmd::Interpret()/Error Variable name should start with alphabetic" << endl;
+    return(0);
+    }
+  //  string xx = tokens[1];
+  //  for (int kk=2; kk<tokens.size(); kk++)  xx += (' ' + tokens[kk] );
+  omg.SetVar(tokens[0], tokens[1]);
+  }
+
+else if (kw == "getvar") {
+  if (tokens.size() < 2) { cout << "PIACmd::Interpret() Usage: getvar newvarname varname" << endl;  return(0); }
+  if (!omg.HasVar(tokens[1])) {
+    cerr << "Error - No " << tokens[1] << " Variable " << endl;
+    return(0);
+    } 
+  if ((tokens[0].length() < 1) || !isalpha((int)tokens[0][0]) ) {
+    cerr << "PIACmd::Interpret()/Error Variable name should start with alphabetic" << endl;
+    return(0);
+    }
+  omg.SetVar(tokens[0], omg.GetVar(tokens[1]) );
+  }
+
+else if (kw == "alias") {
+  if (tokens.size() < 2) { cout << "PIACmd::Interpret() Usage: alias aliasname string" << endl;  return(0); }
+  if ((tokens[0].length() < 1) || !isalpha((int)tokens[0][0]) ) {
+    cerr << "PIACmd::Interpret()/Error alias name should start with alphabetic" << endl;
+    return(0);
+    }
+  string xx = tokens[1];
+  for (int kk=2; kk<tokens.size(); kk++)  xx += (' ' + tokens[kk]);
+  mAliases[tokens[0]] = xx;
+  }
+
+else if (kw == "setol") {
+  if (tokens.size() < 2) { cout << "PIACmd::Interpret() Usage: setol varname objnamepattern" << endl;  return(0); }
+  if ((tokens[0].length() < 1) || !isalpha((int)tokens[0][0]) ) {
+    cerr << "PIACmd::Interpret()/Error Variable name should start with alphabetic" << endl;
+    return(0);
+    }
+  vector<string> ol;
+  mObjMgr->GetObjList(tokens[1], ol);
+  string vol; 
+  if (ol.size() < 1) vol = "";
+  else { 
+     vol = ol[0]; 
+    for (int kk=1; kk<ol.size(); kk++)  vol += (' ' + ol[kk]);
+    }
+  omg.SetVar(tokens[0], vol);
+  }
+else if (kw == "unset") {
+  if (tokens.size() < 1) { cout << "PIACmd::Interpret() Usage: unset varname" << endl;  return(0); }
+  if (omg.HasVar(tokens[0])) omg.DeleteVar(tokens[0]) ;
+  else cerr << "PIACmd::Interpret() No variable with name " << tokens[0] << endl;
+  }
+ else if (kw == "rpneval") {  // Evaluation d'expression en notation polonaise inverse
+  return(EvalRPNExpr(tokens, toks));
+}
+else if (kw == "echo") {
+  for (int ii=0; ii<tokens.size(); ii++)
+    cout << tokens[ii] << " " ;
+  cout << endl;
+ }
+else if (kw == "echo2file") {
+  if (tokens.size() < 1) {
+    cout << "PIACmd::Interpret() Usage: echo2file filename [string ] " << endl;  
+    return(0);
+  }
+  ofstream ofs(tokens[0].c_str(), ios::app);
+  for (int ii=1; ii<tokens.size(); ii++)
+    ofs << tokens[ii] << " " ;
+  ofs << endl;
+ }
+else if (kw == "readstdin") {
+  if (tokens.size() < 1) { cout << "PIACmd::Interpret() Usage: readstdin varname" << endl;  return(0); }
+  if ((tokens[0].length() < 1) || !isalpha((int)tokens[0][0]) ) {
+    cerr << "PIACmd::Interpret()/Error Variable name should start with alphabetic" << endl;
+    return(0);
+    }
+  mImgApp->GetConsole()->AddStr(">>> Reading From StdIn \n", PIVA_Magenta);
+  cout << tokens[0] << " ? " << endl;
+  omg.SetVar(tokens[0], GetStringFrStdin(this) );
+  }
+
+else if (kw == "listvars") {
+  cout << "PIACmd::Interpret()  Variable List , VarName = Value \n";
+  DVList& varlist = omg.GetVarList();
+  DVList::ValList::const_iterator it;
+  string value;
+  for(it = varlist.Begin(); it != varlist.End(); it++) {
+#ifdef SANS_EVOLPLANCK
+    MuTyV mtv = (*it).second;
+    value = (string)(mtv);
+#else
+    value = (string)((*it).second.elval);
+#endif
+    cout << (*it).first << " = " <<  value << "\n";
+    }
+  cout << endl;
+  }
+else if (kw == "listalias") {
+  cout << "PIACmd::Interpret()  Alias List , AliasName = Value \n";
+  CmdStrList::iterator it;
+  for(it = mAliases.begin(); it != mAliases.end(); it++)  
+    cout << (*it).first << " = " <<  (*it).second << "\n";
+  cout << endl;
+  }
+else if (kw == "listcommands") {
+  cout << "---- PIACmd::Interpret() Command List ----- \n";
+  CmdExmap::iterator it;
+  int kc = 0;
+  for(it = cmdexmap.begin(); it != cmdexmap.end(); it++) {
+    cout << (*it).first << "  ";
+    kc++;
+    if (kc >= 5) { cout << "\n"; kc = 0; }
+    }
+  cout << endl;
+  }
+else if (kw == "listscripts") {
+  cout << "---- PIACmd::Interpret() Script List ----- \n";
+  for(ScriptList::iterator sit = mScripts.begin(); 
+      sit != mScripts.end(); sit++)
+    cout << " Script: " << (*sit).second->Name() << " - " 
+	 << (*sit).second->Comment() << endl;
+}
+else if (kw == "clearscript") {
+  if (tokens.size() < 1) { 
+    cout << "PIACmd::Interpret() Usage: clearscript scriptname" << endl;  
+    return(0); 
+  }
+  ScriptList::iterator sit = mScripts.find(tokens[0]);
+  if (sit == mScripts.end()) {
+    cout << "PIACmd::Interpret() No script with name" << tokens[0] << endl;
+    return(0);
+  }
+  else {
+    delete (*sit).second;
+    mScripts.erase(sit);
+    cout << "PIACmd::Interpret() script " << tokens[0] << " cleared" << endl;
+    return(0);
+  }
+}
+else if (kw == "traceon")  { cout << "PIACmd::Interpret()  -> Trace ON mode " << endl; trace = true; }
+else if (kw == "traceoff") { cout << "PIACmd::Interpret()  -> Trace OFF mode " << endl; trace = false; }
+else if (kw == "timingon") { 
+  cout << "PIACmd::Interpret()  -> Timing ON mode " << endl; 
+  if (gltimer)   delete gltimer;   gltimer = new Timer("PIA-CmdInterpreter ");   timing = true; 
+  }
+else if (kw == "timingoff") { 
+  cout << "PIACmd::Interpret()  -> Timing OFF mode " << endl; 
+  if (gltimer)  delete gltimer;  gltimer = NULL;  timing = false; 
+  }
+else if (kw == "exec") {
+  if (tokens.size() < 1) { cout << "PIACmd::Interpret() Usage: exec filename" << endl;  return(0); }
+  ExecFile(tokens[0], tokens);
+  }
+else if (kw == "autoiniranf") { 
+  Auto_Ini_Ranf(1);
+  return(0);
+}
+// ----> Sortie d'application
+else if (kw == "exitpiapp") {
+  mImgApp->Stop();
+  return(0);
+}
+else if (kw == "shell") {
+  if (tokens.size() < 1) { cout << "PIACmd::Interpret() Usage: shell cmdline" << endl;  return(0); }
+  string cmd;
+  for (int ii=0; ii<tokens.size(); ii++)
+    cmd += (tokens[ii] + ' ');
+  system(cmd.c_str());
+  }
+else if (kw == "cshell") {
+  if(tokens.size()<1) {cout<<"PIACmd::Interpret() Usage: cshell cmdline"<<endl; return(0);}
+  string cmd="";
+  for(int ii=0;ii<tokens.size();ii++) cmd+=(tokens[ii]+' ');
+  CShellExecute(cmd);
+  }
+
+//  Execution d'une commande enregistree
+else rc = ExecuteCommand(kw, tokens, toks);
+
+if (timing)  gltimer->Split();
+return(rc);
+}
+
+/* --Methode-- */
+int PIACmd::ParseLineExecute(string& line, bool qw)
+  // Si qw == true, on decoupe entre '' ou "" ou espaces
+{
+vector<string> tokens;
+string kw, toks;
+if (line.length() < 1)  return(0);
+LineToWords(line, kw, tokens, toks, qw);
+return(ExecuteCommand(kw, tokens, toks));  
+}
+
+/* --Methode-- */
+int PIACmd::ExecuteCommand(string& keyw, vector<string>& args, string& toks)
+{
+  int rc = -1;
+  CmdExmap::iterator it = cmdexmap.find(keyw);
+  if (it == cmdexmap.end())  cout << "No such command : " << keyw << " ! " << endl;
+  else { 
+    if ((*it).second.cex) rc = (*it).second.cex->Execute(keyw, args, toks);
+    else cout << "Dont know how to execute " << keyw << " ? " << endl;
+    }
+  return(rc);
+}
+
+/* --Methode-- */
+int PIACmd::ExecFile(string& file, vector<string>& args)
+{
+char line_buff[512];
+FILE *fip;
+
+if ( (fip = fopen(file.c_str(),"r")) == NULL ) {
+  if (file.find('.') >= file.length()) {
+    cout << "PIACmd::Exec(): Error opening file " << file << endl;
+    file += ".pic";
+    cout << "                Trying file " << file << endl;
+    fip = fopen(file.c_str(),"r");
+    }
+  }
+
+if(fip == NULL) {
+  cerr << "PIACmd::Exec() Error opening file " << file << endl;
+  hist << "##! PIACmd::Exec() Error opening file " << file << endl;
+  return(0);
+  }
+
+// hist << "### Executing commands from " << file << endl;
+
+PushStack(args);
+if (trace) { 
+  mImgApp->GetConsole()->AddStr("### Executing commands from ", PIVA_Magenta);
+  mImgApp->GetConsole()->AddStr(file.c_str(), PIVA_Magenta);
+  mImgApp->GetConsole()->AddStr("\n", PIVA_Magenta);
+  }
+
+bool ohv = histon;
+histon = false; 
+while (fgets(line_buff,511,fip) != NULL)
+  {
+  if (trace) mImgApp->GetConsole()->AddStr(line_buff, PIVA_Magenta);
+  line_buff[strlen(line_buff)-1] = '\0';   /*  LF/CR de la fin */
+  string line(line_buff);
+  if (Interpret(line) == 77777) break;
+  }
+histon = ohv; 
+
+// hist << "### End of Exec( " << file << " ) " << endl;
+if (trace) { 
+  mImgApp->GetConsole()->AddStr("### End of Exec( ", PIVA_Magenta);
+  mImgApp->GetConsole()->AddStr(file.c_str(), PIVA_Magenta);
+  mImgApp->GetConsole()->AddStr(" ) \n", PIVA_Magenta);
+  }
+
+PopStack(true);
+
+return(0);
+}
+
+/* --Methode-- */
+int PIACmd::CShellExecute(string cmd)
+{
+ if(cmd.size()<=0) return -1;
+
+ NamedObjMgr omg;
+ string fname = omg.GetTmpDir(); fname += "cshell_exec_pia.csh";
+
+ string cmdrm = "rm -f " + fname;
+ system(cmdrm.c_str());
+
+ FILE *fip = fopen(fname.c_str(),"w");
+ if(fip==NULL)   { 
+   cout << "PIACmd/CShellExecute_Error: fopen("<<fname<<") failed"<<endl; 
+   return -2; 
+ }
+ fprintf(fip,"#!/bin/csh\n\n");
+ fprintf(fip,"%s\n",cmd.c_str());
+ fprintf(fip,"\nexit 0\n");
+ fclose(fip);
+
+ cmd = "csh "; cmd += fname;
+ system(cmd.c_str());
+
+ system(cmdrm.c_str());
+
+ return 0;
+}
+
+static string* videstr = NULL;
+/* --Methode-- */
+string& PIACmd::GetUsage(const string& kw)
+{
+bool fndok = false;
+CmdExmap::iterator it = cmdexmap.find(kw);
+if (it == cmdexmap.end()) {
+  it = helpexmap.find(kw);
+  if (it != helpexmap.end())  fndok = true;
+  }
+  else  fndok = true; 
+if (fndok)   return( (*it).second.us ); 
+// Keyword pas trouve
+if (videstr == NULL) videstr = new string("");
+*videstr =  "Nothing known about " + kw + " ?? ";
+return(*videstr);
+ 
+}
+
+/* --Methode-- */
+void PIACmd::ShowHelpWindow()
+{
+helpwin->Show();
+}
+
+/* --Methode-- */
+void PIACmd::ShowCxxOptionWindow()
+{
+cxxoptwin->Show();
+}
+
+/* --Methode-- */
+void PIACmd::ShowCxxExecWindow()
+{
+cxxexwin->Show();
+}
+
+/*  Les definitions suivantes doivent se trouver ds l'en-tete du fichier LaTeX 
+  \newcommand{\piacommand}[1]{
+    \framebox{\bf \Large #1 } \index{#1} % (Command) 
+  }
+
+  \newcommand{\piahelpitem}[1]{
+    \framebox{\bf \Large #1 } \index{#1} (Help item)
+  }
+
+  \newcommand{\myppageref}[1]{ (p. \pageref{#1} ) }
+*/
+
+/* --Methode-- */
+void PIACmd::HelptoLaTeX(string const & fname)
+{
+FILE *fip;
+if ((fip = fopen(fname.c_str(), "w")) == NULL)   { 
+  cout << "PIACmd::HelptoLaTex_Error: fopen( " << fname << endl; 
+  return;
+  }
+
+fputs("% ----- Liste des groupes de Help ----- \n",fip);
+fputs("List of {\\bf piapp} on-line Help groups: \n", fip);
+fputs("\\begin{itemize} \n",fip);
+CmdHGroup::iterator it;
+for(it = cmdhgrp.begin(); it != cmdhgrp.end(); it++) {
+  if ((*it).first == "All") continue;
+  fprintf(fip,"\\item {\\bf %s }  (p. \\pageref{%s}) \n", 
+         (*it).first.c_str(), (*it).first.c_str());
+}
+
+fputs("\\end{itemize} \n",fip);
+
+fputs("\\vspace*{10mm} \n",fip);
+
+CmdExmap::iterator ite;
+fputs("% ----- Liste de toutes les commandes ----- \n",fip);
+fputs("\\begin{center} \n ", fip);
+fputs("\\rule{2cm}{1mm} List of {\\bf piapp} Help items \\rule{2cm}{1mm} \n", fip);
+fputs("\n \n  \\vspace{5mm} \n",fip);
+fputs("\\begin{tabular}{llllll}  \n", fip);
+int kt = 0;
+for(ite = helpexmap.begin(); ite != helpexmap.end(); ite++) {
+  fprintf(fip,"%s & p. \\pageref{%s} ", (*ite).first.c_str(),  (*ite).first.c_str() );
+  kt++;
+  if (kt < 3) fputs(" & ", fip);
+  else  { fputs(" \\\\  \n", fip);  kt = 0; }
+  }
+if (kt == 1) fputs("  &  &  &   \\\\  \n", fip);
+else if (kt == 2)  fputs("  &   \\\\  \n", fip);
+fputs("\\end{tabular} \n", fip);
+fputs("\\end{center} \n", fip);
+fputs("\n \n \\newpage  \\vspace{1cm} \n",fip);
+
+fputs("\\begin{center} \n ", fip);
+fputs("\\rule{2cm}{1mm} List of {\\bf piapp} Commands \\rule{2cm}{1mm} \n", fip);
+fputs("\n \n  \\vspace{5mm} \n",fip);
+fputs("\\begin{tabular}{llllll} \n", fip);
+kt = 0;
+for(ite = cmdexmap.begin(); ite != cmdexmap.end(); ite++) {
+  fprintf(fip,"%s & p. \\pageref{%s} ", (*ite).first.c_str(), (*ite).first.c_str() );
+  kt++;
+  if (kt < 3) fputs(" & ", fip);
+  else  { fputs(" \\\\  \n", fip);  kt = 0; }
+  }
+if (kt == 1) fputs("  &  &  &   \\\\  \n", fip);
+else if (kt == 2)  fputs("  &   \\\\  \n", fip);
+fputs("\\end{tabular} \n", fip);
+fputs("\\end{center} \n", fip);
+// fputs("\\newline \n",fip);
+
+fputs("% ----- Liste des commandes dans chaque groupe ----- \n",fip);
+fputs("\\newpage \n",fip);
+int gid;
+for(it = cmdhgrp.begin(); it != cmdhgrp.end(); it++) {
+  gid = (*it).second;
+  if (gid == 0)  continue;
+  fprintf(fip,"\\subsection{%s} \\label{%s} \n", 
+          (*it).first.c_str(), (*it).first.c_str());
+  fprintf(fip,"\\noindent \n");
+  for(ite = helpexmap.begin(); ite != helpexmap.end(); ite++) {
+    if ((*ite).second.group != gid)  continue;
+    fprintf(fip,"\\piahelpitem{%s} \\label{%s} \n", 
+            (*ite).first.c_str(), (*ite).first.c_str());
+    fputs("\\begin{verbatim} \n",fip);
+    fprintf(fip,"%s\n", (*ite).second.us.c_str());
+    fputs("\\end{verbatim} \n",fip);
+    }
+  for(ite = cmdexmap.begin(); ite != cmdexmap.end(); ite++) {
+    if ((*ite).second.group != gid)  continue;
+    fprintf(fip,"\\piacommand{%s} \\label{%s} \n", 
+            (*ite).first.c_str(), (*ite).first.c_str());
+    fputs("\\begin{verbatim} \n",fip);
+    fprintf(fip,"%s\n", (*ite).second.us.c_str());
+    fputs("\\end{verbatim} \n",fip);
+    }
+}
+
+fclose(fip);
+return;
+}
+
+
+
Index: /tags/V_Dec2002/SophyaPI/PIext/piacmd.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/piacmd.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/piacmd.h	(revision 2309)
@@ -0,0 +1,185 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe interpreteur de commande pour piapp 
+// Reza      Aout 97 , Juillet,Aout 98
+// LAL-IN2P3/CNRS
+
+#ifndef PIACMD_H_SEEN
+#define PIACMD_H_SEEN
+
+#include "machdefs.h"
+#include <iostream.h>
+#include <fstream.h>
+#include <string>
+#include <vector>
+#include <list>
+#include <stack>
+#include <map>
+#include <functional>
+
+#include "dlftypes.h"
+#include "pdlmgr.h"
+#include "ctimer.h"
+
+// Classe definissant l'interface pour un executeur de commande
+class CmdExecutor {
+public:
+  virtual	~CmdExecutor() {} ;
+  // keyw : Le mot cle associe , args: Arguments de la commande
+  virtual int	Execute(string& keyw, vector<string>& args, string& toks)=0;
+};
+
+// Classe definissant l'interface pour un interpreteur de commande
+class CmdInterpreter {
+public:
+  virtual		~CmdInterpreter() {} ;
+  virtual string	Name()=0;
+  virtual int		Interpret(string& line)=0;
+};
+
+
+
+// Forward declaration of some classes ...
+class NamedObjMgr;
+class PIStdImgApp;
+#ifdef SANS_EVOLPLANCK
+class Timer;
+#else
+namespace SOPHYA { 
+class Timer;
+}
+#endif
+
+class PIAHelpWind;   // Fenetre d'aide en ligne 
+class CxxExecWind;   // Fenetre pour CxxExecutor
+class CxxOptionWind; // Option de CxxExecutor
+
+class PIACmdBloc;    // Bloc de type foreach / for de l'interpreteur PIACmd
+class PIACmdScript;  // Script de commandes defini ds l'interpreteur PIACmd
+
+// ---------------------------------------------------------------------
+// Classe Interpreteur de commande, gestionnaire de module chargeable,
+// et de fonctions dynamiquement linke pour PIStdImgApp
+// Permet de gerer plusieurs Interpreter differents 
+// ---------------------------------------------------------------------
+
+
+class PIACmd : public CmdInterpreter  {
+public:
+  static PIACmd*	GetInterpreter();
+
+			PIACmd(NamedObjMgr* omg, PIStdImgApp* app);
+  virtual		~PIACmd();
+  virtual string	Name();
+
+  virtual void		RegisterCommand(string& keyw, string& usage, CmdExecutor * ce, 
+                                        string grp="Commands");
+  virtual void		RegisterHelp(string& keyw, string& usage, string& grp);
+  virtual void		LoadModule(string& fnameso, string& name);
+
+  virtual void		AddInterpreter(CmdInterpreter * cl);
+  virtual void		SelInterpreter(string& name);
+
+  virtual int		Interpret(string& line);
+  virtual int		ParseLineExecute(string& line, bool qw=true);
+  virtual int		ExecuteCommand(string& keyw, vector<string>& args, string& toks);
+  virtual int		ExecFile(string& file, vector<string>& args);
+  virtual int		CShellExecute(string cmd);
+  virtual string&	GetUsage(const string& kw);
+
+          void		ShowHelpWindow();
+          void          ShowCxxOptionWindow();
+          void          ShowCxxExecWindow();
+
+  virtual void 		HelptoLaTeX(string const & flnm);
+
+  inline  CmdInterpreter* CurrentInterpreter() { return(curcmdi); }
+  inline  CmdExecutor*    BaseExecutor()  { return(basexec); }
+  inline  CmdExecutor*    ContExecutor()  { return(cntexec); } //_OP_
+  inline  PIStdImgApp*    GetImgApp() { return(mImgApp); }
+
+//   Pour utilisation par PIAHelpWind uniquement 
+  virtual void		UpdateHelpList(PIAHelpWind* hw, int gid);
+
+//   Utilitaire pour decoupage en mot
+  static  int   LineToWords(string& line, string& kw, vector<string>& tokens,
+			    string& toks, bool uq=true);
+protected:
+  virtual int	CheckHelpGrp(string& grp);
+  int           ExecuteCommandLine(string & keyw, vector<string> & args,
+				   string & toks);
+
+  int           SubstituteVars(string & s, string & s2);  
+  int	        EvaluateTest(vector<string> & args, 
+			     string & line, bool & res);
+  int	        EvalRPNExpr(vector<string> & args, string & line);
+
+  bool          GetVar(string & vn, string & vv);
+  void          PushStack(vector<string> & args);
+  void          PopStack(bool psta=true);
+
+  NamedObjMgr* mObjMgr;
+  PIStdImgApp* mImgApp;
+
+  CmdInterpreter* curcmdi;
+  CmdExecutor* basexec;  // basic command executor
+  CmdExecutor* fitexec;  // Fit command executor
+  CmdExecutor* pawexec;  // paw-like command executor
+  CmdExecutor* cxxexec;  // on-line c++ compile/execution command executor
+
+  CmdExecutor *cntexec; // contour executor _OP_
+  CmdExecutor *flwexec; // flow chart executor _OP_
+ 
+// Pour enregistrer la liste de commandes et leurs executeurs et le help
+  struct cmdex {int group; string us; CmdExecutor * cex; } ;
+  typedef map<string, int, less<string> > CmdHGroup;   // Liste des groupes de commandes
+  CmdHGroup cmdhgrp;
+  int cmdgrpid;                                     // Numero de groupe courant
+  typedef map<string, cmdex, less<string> > CmdExmap;
+  CmdExmap cmdexmap;
+  CmdExmap helpexmap;                               // Pour les helps sans commande
+
+// Pour garder la liste des modules 
+  typedef map<string, PDynLinkMgr* , less<string> > Modmap;
+  Modmap modmap;
+
+// Pour garder la liste des interpreteur
+  typedef map<string, CmdInterpreter*, less<string> > InterpMap;
+  InterpMap interpmap;
+ 
+//  Pour stocker les scripts definis ds l'interpreteur
+  typedef map<string, PIACmdScript*, less<string> > ScriptList;
+  ScriptList mScripts;  // Liste des scripts
+  PIACmdScript* curscript; // Script en cours de definition
+
+//  Pour stocker les alias definies par l'interpreteur
+  typedef map<string, string, less<string> > CmdStrList;
+  CmdStrList mAliases;  // Liste des alias 
+
+// Le stack pour les arguments des .pic et des scripts
+  stack< vector<string> > ArgsStack;
+
+  stack< PIACmdBloc * > CmdBlks;  // Bloc de commande courant (foreach, ...)
+  int felevel;                    // foreach-for level 
+  stack< list<char> > TestsStack; // Stack des resultats de test
+  list<char>::iterator tresit;       // Test courant
+  bool curtestresult;             // Resultat courant des tests 
+
+  bool mulinefg;            // Bloc multi-lignes (ligne suite)
+  string mulinecmd;         // Commande multi-lignes
+  string spromptmul;        // Prompt console avant multi-ligne
+
+  ofstream hist;       //  History file 
+  bool histon;        //  True ->  history file
+  bool trace;          // Trace flag
+  bool timing;         // Display CPU Time
+  Timer* gltimer;      // pour Display CPU Time
+
+// Fenetre d'aide interactive 
+  PIAHelpWind* helpwin;
+  CxxExecWind* cxxexwin;
+  CxxOptionWind* cxxoptwin;
+};
+
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/piafitting.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/piafitting.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/piafitting.cc	(revision 2309)
@@ -0,0 +1,1638 @@
+//CMVBUG reste pb suivant sous Linux-egcs (OSF1-cxx c'est ok):
+//openppf cmvwppf.ppf
+//fitw h1g g2 p:4500,45,10,900
+//delobjs h1g
+//clic sur FIT  -> OK
+//clic sur FIT 2sd fois -> core dump!!!
+//
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <iostream.h>
+#include <typeinfo>
+
+#include "strutil.h"
+#include "nbtri.h"
+#include "generalfit.h"
+#include "fct1dfit.h"
+#include "fct2dfit.h"
+#include "ntuple.h"
+#include "cimage.h"
+#include "histos.h"
+#include "histos2.h"
+#include "ntuple.h"
+#include "hisprof.h"
+
+#ifdef SANS_EVOLPLANCK
+#include "matrix.h"
+#include "cvector.h"
+#else
+#include "tmatrix.h"
+#include "tvector.h"
+#include "objfitter.h"
+#endif
+
+#include "piafitting.h"
+#include "nobjmgr.h"
+#include "anydataobj.h"
+#include "pistdimgapp.h"
+
+#include "nomhistadapter.h"
+#include "nomgfdadapter.h"
+#include "nomimagadapter.h"
+#ifdef SANS_EVOLPLANCK
+#include "nommatvecadapter.h"
+#else
+#include "nomtmatvecadapter.h"
+#endif
+
+////////////////////////////////////////////////////////////////////
+////---------- Classe de fenetre de fit interactive ------------////
+////////////////////////////////////////////////////////////////////
+class PIAFitterWind :  public PIWindow {
+public :
+		PIAFitterWind(PIStdImgApp* par, PIAFitter* fiter,string func);
+  virtual	~PIAFitterWind();
+  virtual void  Show();
+  virtual void  Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+  void SetState(void);
+protected :
+  PIStdImgApp* mDap;
+  PIAFitter*   mFitter;
+  string mFunc;
+  PILabel**    lab; int nlab;
+  PIText**     txt; int ntxt;
+  PIButton**   but; int nbut;
+  PICheckBox** ckb; int nckb;
+  PIOptMenu**  pom; int npom;
+  bool ReFillGData,ReDecodeFunc;
+  int saveI1,saveI2, saveJ1, saveJ2;
+  double saveErrScale,saveErrMin,saveXC,saveYC;
+};
+
+////////////////////////////////////////////////////////////////////////
+// --- Generation automatique du "usage" pour helpfit:
+// 1-/ copier le texte ci-dessous de piafitting.cc dans toto
+// 2-/ cat toto | sed 's?^//?usage+="\\n?' | sed 's?$?    ";?'
+// NE PAS EFFACER LA SUITE: c'est elle qui doit etre modifiee,
+// le usage du helpfit sera regenere a l'aide des commandes ci-dessus.
+////////////////////////////////////////////////////////////////////////
+//| --------------- Fit Lineaire a 1 et 2 dimensions ---------------
+//| Syntaxe:
+//| fitlin nom pnn [o:.aa,bb,cc, o:dd,ee,ff o:gg,hh,jj,kk etc...]
+//| avec:
+//| nom  : cf commentaire ordre ''fit''
+//| pnn  : fit polynome degre nn avec classe Poly (lineaire) 1D ou 2D
+//| o:aa,...,bb : cf commentaires ordre ''fit''
+//|
+////////////////////////////////////////////////////////////////////////
+//| --------------- Fit d'objets a 1 et 2 dimensions ---------------
+//|                 avec interface d'aide graphique
+//| Syntaxe:
+//| fitw nom func
+//|     [p:p1,p2,...,pn s:s1,s2,...,sn m:m1,m2,...,mn M:M1,mM2,...,Mn f:f1,...,fn]
+//|     [o:.aa,bb,cc, o:dd,ee,ff o:gg,hh,jj,kk etc...]
+//| cf commentaire ordre ''fit''
+//|
+////////////////////////////////////////////////////////////////////////
+//| --------------- Fit d'objets a 1 et 2 dimensions ---------------
+//| Syntaxe:
+//| fit nom func
+//|     [p:p1,p2,...,pn s:s1,s2,...,sn m:m1,m2,...,mn M:M1,mM2,...,Mn f:f1,...,fn]
+//|     [o:.aa,bb,cc, o:dd,ee,ff o:gg,hh,jj,kk etc...]
+//|----- OBJET -----
+//| nom  : nom de l'objet qui peut etre:
+//|        fit-1D:  Vector,Histo1D,HProf ou GeneraFitData(1D)
+//|        fit-2D:  Matrix,Histo2D,Image<T> ou GeneraFitData(2D)
+//|
+//|----- FUNCTION -----
+//| func : pnn : fit polynome degre nn avec GeneralFit (non-lineaire) 1D ou 2D
+//|      : gnn : fit gaussienne (hauteur) + polynome de degre nn 1D
+//|      : g   : fit gaussienne (hauteur) 1D
+//|      : enn : fit exponentielle + polynome de degre nn 1D
+//|      : e   : fit exponentielle 1D
+//|      : Gnn : fit gaussienne (volume) + polynome de degre nn 1D
+//|      : G   : fit gaussienne (volume) 1D
+//|      :     : fit gaussienne+fond (volume) 2D
+//|      : Gi  : fit gaussienne+fond integree (volume) 2D
+//|      : d   : fit DL de gaussienne+fond (volume) 2D
+//|      : di  : fit DL de gaussienne+fond integree (volume) 2D
+//|      : D   : fit DL de gaussienne+fond avec coeff variable p6 (volume) 2D
+//|      : Di  : fit DL de gaussienne+fond integree avec coeff variable p6 (volume) 2D
+//|      : M   : fit Moffat+fond (expos=p6) (volume) 2D
+//|      : Mi  : fit Moffat+fond integree (expos=p6) (volume) 2D
+//|      : Autre : fonction definie par l'utilisateur (cf commentaires ci apres)
+//|
+//|----- INIT PARAMETRES ET ETAT DU FIT -----
+//| p    : p1,...,pn : valeur d'initialisation des parametres (def=0)
+//| s    : s1,...,sn : valeur des steps de depart (def=1)
+//| m    : m1,...,mn : valeur des minima (def=1)
+//| M    : M1,...,Mn : valeur des maxima (def=-1) (max<=min : pas de limite)
+//| f    : f1,...,fn : si >=1 parametre fixe sinon libre (def=0)
+//| - Remarque: si pi,si,mi ou Mi = '!' la valeur correspondante n'est pas changee
+//|
+//|----- OPTIONS -----
+//| o    : options ''o:Eaa.b,eaa.b,f,r,caa.b,Xaa.b''
+//|      F : initialisation a partir des resultats et de l'etat du fit precedent
+//|          (option non prioritaire sur les definitions p:,s:,m:,M:,f:o:)
+//|      a : initialisation automatique des parametres du fit (si disponible)
+//|          (option non prioritaire sur les definitions p:,s:,m:,M:,f:o:
+//|           et sur l'initialisation pa l'option ''F'')
+//|      f : generation d'un Objet identique contenant la fonction fittee
+//|      r : generation d'un Objet identique contenant les residus
+//|      Xaa.b : aa.b valeur du DXi2 d'arret (def=1.e-3)
+//|      Naa : aa nombre maximum d'iterations (def=100)
+//|      la : niveau ''a'' de print: a=niveau de print Fit1/2D
+//|      da : niveau ''a'' de debug: a=niveau de GeneralFit
+//|      Ii1/i2 : numeros des bins X de l'histos utilises pour le fit [i1,i2]
+//|2D    Jj1/j2 : numeros des bins Y de l'histos utilises pour le fit [j1,j2]
+//|    - Traitement des erreurs :
+//|      Par defaut, l'erreur est celle associee a l'objet (si elle existe),
+//|        elle est mise a 1 sinon.
+//|      haa.b/cc.d : erreur = aa.bb*(erreur associee a l'objet cf ci-dessus)
+//|      Haa.b/cc.d : erreur = aa.b*|val|
+//|      eaa.b/cc.d : erreur = aa.b
+//|      Eaa.b/cc.d : erreur = aa.b*sqrt(|val|)
+//|           aa.b<0 (ou non precise) est equivalent aa.b=1.0
+//|           cc.d non precise est equivalent a cc.d=0
+//|           si cc.d>=0  si erreur>0 erreur = max(erreur,cc.d)
+//|                       si erreur<=0 alors erreur
+//|           si cc.d<0   si erreur>0 erreur = max(erreur,|cc.d|)
+//|                       si erreur<=0 alors erreur=|cc.d|
+//|      xaa.b : demande de centrage: on fit x-aa.b au lieu de x)
+//|      x : demande de centrage: on fit x-xc au lieu de x
+//|          avec xc=abscisse du ''milieu logique'' de l'objet.
+//|          Actif pour  exp+poly 1D, poly 1D
+//|          Pour gauss+poly 1D, xc est le centre de la gaussienne.
+//|2D    yaa.b et y : idem ''xaa.b et x'' mais pour y
+//|
+////////////////////////////////////////////////////////////////////////
+//| --------------- Def des fcts de fit par l'utilisateur ---------------
+//| Pour definir une fonction parametree utilisateur:
+//| Un exemple de fichier contenant des fonctions a fitter: PIext/userfitfunex.c
+//| > crfitfil nom_fichier nom_fonction nvar npar
+//|     pour creer un squelette de fichier C contenant la fonction a fitter
+//|            nom_fichier : nom du fichier ou est le code de la fonction
+//|                          c'est un fichier C de nom blabla.c
+//|            nom_fonction : nom de la fonction ex: gauss2
+//|            nvar : nombre de variables x[] (1D=1, 2D=2, etc...)
+//|            npar : nombre de parametre p[]
+//|   - La fonction est donc F(x[];p[]), soit par ex:
+//|            double gauss2(double const* x,double const* p)
+//|   - L'utilisateur a la possibilite de donner egalement la fonction
+//|     retournant les derivees de la fonction par rapport aux parametres
+//|            double gauss2_der(double const* x,double const* p,double* dp)
+//|     ou dp[i] = dF(x[];p[])/dp[i]
+//|     Par convention, cette fonction a le meme nom suivi de ''_der''
+//| > crfitfun nom_fichier nom_fonction nvar npar
+//|     Permet de compiler le fichier ''nom_fichier'' et de linker
+//|     la fonction ''nom_fonction''
+//|   - Un meme fichier peut contenir plusieurs fonctions a fitter
+//|
+////////////////////////////////////////////////////////////////////////
+
+/* --Methode-- */
+PIAFitter::PIAFitter(PIACmd *piac, PIStdImgApp* app)
+: mApp(app), FWindFit(NULL)
+, mNObj(""), mAdObj(NULL), mGData(NULL), delmGData(false)
+, mNPar(0), mNVar(0), mNData(0)
+, mPar(1), mStep(1), mMin(1), mMax(1), mFix(1)
+, mParSave(1), mStepSave(1), mMinSave(1), mMaxSave(1), mFixSave(1)
+, mFit(NULL)
+, mFunction(NULL), mFName(""), mFunc(NULL)
+, mDlUFunc(NULL), mNameFitFunc(""), mFitFunc(NULL), mFitFuncDer(NULL)
+, mUFNVar(0), mUFNPar(0)
+{
+// Init et Set des options
+mPar=0.; mStep=1.; mMin=1.; mMax=-1.; mFix=0.;
+mParSave=0.; mStepSave=1.; mMinSave=1.; mMaxSave=-1.; mFixSave=0.;
+ResetOptions();
+mOptSave = mOpt;
+
+// enregistrement des ordres de fit
+string kw, usage, grp = "Fitting";
+
+kw = "helpfit";
+usage="";
+usage+="\n//////////////////////////////////////////////////////////////////////    ";
+usage+="\n| --------------- Fit Lineaire a 1 et 2 dimensions ---------------    ";
+usage+="\n| Syntaxe:    ";
+usage+="\n| fitlin nom pnn [o:.aa,bb,cc, o:dd,ee,ff o:gg,hh,jj,kk etc...]    ";
+usage+="\n| avec:    ";
+usage+="\n| nom  : cf commentaire ordre ''fit''    ";
+usage+="\n| pnn  : fit polynome degre nn avec classe Poly (lineaire) 1D ou 2D    ";
+usage+="\n| o:aa,...,bb : cf commentaires ordre ''fit''    ";
+usage+="\n|    ";
+usage+="\n//////////////////////////////////////////////////////////////////////    ";
+usage+="\n| --------------- Fit d'objets a 1 et 2 dimensions ---------------    ";
+usage+="\n|                 avec interface d'aide graphique    ";
+usage+="\n| Syntaxe:    ";
+usage+="\n| fitw nom func    ";
+usage+="\n|     [p:p1,p2,...,pn s:s1,s2,...,sn m:m1,m2,...,mn M:M1,mM2,...,Mn f:f1,...,fn]    ";
+usage+="\n|     [o:.aa,bb,cc, o:dd,ee,ff o:gg,hh,jj,kk etc...]    ";
+usage+="\n| cf commentaire ordre ''fit''    ";
+usage+="\n|    ";
+usage+="\n//////////////////////////////////////////////////////////////////////    ";
+usage+="\n| --------------- Fit d'objets a 1 et 2 dimensions ---------------    ";
+usage+="\n| Syntaxe:    ";
+usage+="\n| fit nom func    ";
+usage+="\n|     [p:p1,p2,...,pn s:s1,s2,...,sn m:m1,m2,...,mn M:M1,mM2,...,Mn f:f1,...,fn]    ";
+usage+="\n|     [o:.aa,bb,cc, o:dd,ee,ff o:gg,hh,jj,kk etc...]    ";
+usage+="\n|----- OBJET -----    ";
+usage+="\n| nom  : nom de l'objet qui peut etre:    ";
+usage+="\n|        fit-1D:  Vector,Histo1D,HProf ou GeneraFitData(1D)    ";
+usage+="\n|        fit-2D:  Matrix,Histo2D,Image<T> ou GeneraFitData(2D)    ";
+usage+="\n|    ";
+usage+="\n|----- FUNCTION -----    ";
+usage+="\n| func : pnn : fit polynome degre nn avec GeneralFit (non-lineaire) 1D ou 2D    ";
+usage+="\n|      : gnn : fit gaussienne (hauteur) + polynome de degre nn 1D    ";
+usage+="\n|      : g   : fit gaussienne (hauteur) 1D    ";
+usage+="\n|      : enn : fit exponentielle + polynome de degre nn 1D    ";
+usage+="\n|      : e   : fit exponentielle 1D    ";
+usage+="\n|      : Gnn : fit gaussienne (volume) + polynome de degre nn 1D    ";
+usage+="\n|      : G   : fit gaussienne (volume) 1D    ";
+usage+="\n|      :     : fit gaussienne+fond (volume) 2D    ";
+usage+="\n|      : Gi  : fit gaussienne+fond integree (volume) 2D    ";
+usage+="\n|      : d   : fit DL de gaussienne+fond (volume) 2D    ";
+usage+="\n|      : di  : fit DL de gaussienne+fond integree (volume) 2D    ";
+usage+="\n|      : D   : fit DL de gaussienne+fond avec coeff variable p6 (volume) 2D    ";
+usage+="\n|      : Di  : fit DL de gaussienne+fond integree avec coeff variable p6 (volume) 2D    ";
+usage+="\n|      : M   : fit Moffat+fond (expos=p6) (volume) 2D    ";
+usage+="\n|      : Mi  : fit Moffat+fond integree (expos=p6) (volume) 2D    ";
+usage+="\n|      : Autre : fonction definie par l'utilisateur (cf commentaires ci apres)    ";
+usage+="\n|    ";
+usage+="\n|----- INIT PARAMETRES ET ETAT DU FIT -----    ";
+usage+="\n| p    : p1,...,pn : valeur d'initialisation des parametres (def=0)    ";
+usage+="\n| s    : s1,...,sn : valeur des steps de depart (def=1)    ";
+usage+="\n| m    : m1,...,mn : valeur des minima (def=1)    ";
+usage+="\n| M    : M1,...,Mn : valeur des maxima (def=-1) (max<=min : pas de limite)    ";
+usage+="\n| f    : f1,...,fn : si >=1 parametre fixe sinon libre (def=0)    ";
+usage+="\n| - Remarque: si pi,si,mi ou Mi = '!' la valeur correspondante n'est pas changee    ";
+usage+="\n|    ";
+usage+="\n|----- OPTIONS -----    ";
+usage+="\n| o    : options ''o:Eaa.b,eaa.b,f,r,caa.b,Xaa.b''    ";
+usage+="\n|      F : initialisation a partir des resultats et de l'etat du fit precedent    ";
+usage+="\n|          (option non prioritaire sur les definitions p:,s:,m:,M:,f:o:)    ";
+usage+="\n|      a : initialisation automatique des parametres du fit (si disponible)    ";
+usage+="\n|          (option non prioritaire sur les definitions p:,s:,m:,M:,f:o:    ";
+usage+="\n|           et sur l'initialisation pa l'option ''F'')    ";
+usage+="\n|      f : generation d'un Objet identique contenant la fonction fittee    ";
+usage+="\n|      r : generation d'un Objet identique contenant les residus    ";
+usage+="\n|      Xaa.b : aa.b valeur du DXi2 d'arret (def=1.e-3)    ";
+usage+="\n|      Naa : aa nombre maximum d'iterations (def=100)    ";
+usage+="\n|      la : niveau ''a'' de print: a=niveau de print Fit1/2D    ";
+usage+="\n|      da : niveau ''a'' de debug: a=niveau de GeneralFit    ";
+usage+="\n|      Ii1/i2 : numeros des bins X de l'histos utilises pour le fit [i1,i2]    ";
+usage+="\n|2D    Jj1/j2 : numeros des bins Y de l'histos utilises pour le fit [j1,j2]    ";
+usage+="\n|    - Traitement des erreurs :    ";
+usage+="\n|      Par defaut, l'erreur est celle associee a l'objet (si elle existe),    ";
+usage+="\n|        elle est mise a 1 sinon.    ";
+usage+="\n|      haa.b/cc.d : erreur = aa.bb*(erreur associee a l'objet cf ci-dessus)    ";
+usage+="\n|      Haa.b/cc.d : erreur = aa.b*|val|    ";
+usage+="\n|      eaa.b/cc.d : erreur = aa.b    ";
+usage+="\n|      Eaa.b/cc.d : erreur = aa.b*sqrt(|val|)    ";
+usage+="\n|           aa.b<0 (ou non precise) est equivalent aa.b=1.0    ";
+usage+="\n|           cc.d non precise est equivalent a cc.d=0    ";
+usage+="\n|           si cc.d>=0  si erreur>0 erreur = max(erreur,cc.d)    ";
+usage+="\n|                       si erreur<=0 alors erreur    ";
+usage+="\n|           si cc.d<0   si erreur>0 erreur = max(erreur,|cc.d|)    ";
+usage+="\n|                       si erreur<=0 alors erreur=|cc.d|    ";
+usage+="\n|      xaa.b : demande de centrage: on fit x-aa.b au lieu de x)    ";
+usage+="\n|      x : demande de centrage: on fit x-xc au lieu de x    ";
+usage+="\n|          avec xc=abscisse du ''milieu logique'' de l'objet.    ";
+usage+="\n|          Actif pour  exp+poly 1D, poly 1D    ";
+usage+="\n|          Pour gauss+poly 1D, xc est le centre de la gaussienne.    ";
+usage+="\n|2D    yaa.b et y : idem ''xaa.b et x'' mais pour y    ";
+usage+="\n|    ";
+usage+="\n//////////////////////////////////////////////////////////////////////    ";
+usage+="\n| --------------- Def des fcts de fit par l'utilisateur ---------------    ";
+usage+="\n| Pour definir une fonction parametree utilisateur:    ";
+usage+="\n| Un exemple de fichier contenant des fonctions a fitter: PIext/userfitfunex.c    ";
+usage+="\n| > crfitfil nom_fichier nom_fonction nvar npar    ";
+usage+="\n|     pour creer un squelette de fichier C contenant la fonction a fitter    ";
+usage+="\n|            nom_fichier : nom du fichier ou est le code de la fonction    ";
+usage+="\n|                          c'est un fichier C de nom blabla.c    ";
+usage+="\n|            nom_fonction : nom de la fonction ex: gauss2    ";
+usage+="\n|            nvar : nombre de variables x[] (1D=1, 2D=2, etc...)    ";
+usage+="\n|            npar : nombre de parametre p[]    ";
+usage+="\n|   - La fonction est donc F(x[];p[]), soit par ex:    ";
+usage+="\n|            double gauss2(double const* x,double const* p)    ";
+usage+="\n|   - L'utilisateur a la possibilite de donner egalement la fonction    ";
+usage+="\n|     retournant les derivees de la fonction par rapport aux parametres    ";
+usage+="\n|            double gauss2_der(double const* x,double const* p,double* dp)    ";
+usage+="\n|     ou dp[i] = dF(x[];p[])/dp[i]    ";
+usage+="\n|     Par convention, cette fonction a le meme nom suivi de ''_der''    ";
+usage+="\n| > crfitfun nom_fichier nom_fonction nvar npar    ";
+usage+="\n|     Permet de compiler le fichier ''nom_fichier'' et de linker    ";
+usage+="\n|     la fonction ''nom_fonction''    ";
+usage+="\n|   - Un meme fichier peut contenir plusieurs fonctions a fitter    ";
+usage+="\n|    ";
+usage+="\n//////////////////////////////////////////////////////////////////////    ";
+piac->RegisterHelp(kw,usage,grp);
+
+kw = "fit";
+usage = "Fitting function to DataObjects (Histo, Histo2D, Vector, ...)";
+usage += "\n Usage: fit nomobj func [Options]";
+usage += "\n [p:p1,...,pn s:s1,...,sn m:m1,...,mn M:M1,...,Mn o:... o:...]";
+usage += "\n  Related commands: fitw fitlin crfitfun crfitfil";  
+piac->RegisterCommand(kw,usage,this,grp);
+
+kw = "fitw";
+usage = "Fitting function to DataObjects with Interactive Window Help";
+usage += "\n Usage: fitw nomobj func [Options]";
+usage += "\n [p:p1,...,pn s:s1,...,sn m:m1,...,mn M:M1,...,Mn o:... o:...]";
+usage += "\n  Related commands: fit fitlin crfitfun crfitfil";  
+piac->RegisterCommand(kw,usage,this,grp);
+
+kw = "fitlin";
+usage = "Linear Fitting of Polynoms to DataObjects";
+usage += "\n Usage: fitlin nomobj func [o:... o:...]";
+usage += "\n  Related commands: fit fitw crfitfun crfitfil";  
+piac->RegisterCommand(kw,usage,this,grp);
+
+kw = "crfitfun";
+usage = "Creation et link de function utilisateur pour le fit";
+usage += "\n Usage: crfitfun file func nvar npar";
+usage += "\n  Related commands: fit fitw fitlin crfitfil";  
+piac->RegisterCommand(kw,usage,this,grp);
+
+kw = "crfitfil";
+usage = "Creation de fichier C pour function utilisateur du fit";
+usage += "\n Usage: crfitfil file func nvar npar";
+usage += "\n  Related commands: fit fitw fitlin crfitfun";  
+piac->RegisterCommand(kw,usage,this,grp);
+}
+
+/* --Methode-- */
+PIAFitter::~PIAFitter()
+{
+if(delmGData && mGData != NULL) {delete mGData;    mGData=NULL; delmGData=false;}
+if(mFit != NULL)                {delete mFit;      mFit=NULL;}
+if(mFunction != NULL)           {delete mFunction; mFunction=NULL;}
+if(mFunc != NULL)               {delete mFunc;     mFunc=NULL;}
+if(FWindFit != NULL)            {delete FWindFit;  FWindFit=NULL;}
+if(mDlUFunc != NULL)            {delete mDlUFunc;  mDlUFunc=NULL;}
+}
+
+/* --Methode-- */
+void PIAFitter::ResetOptions(void)
+// Reset des options
+{
+mOpt.okres = mOpt.okfun = false;
+
+mOpt.polcx = mOpt.polcy = 0;
+mOpt.xc = mOpt.yc = 0.;
+
+mOpt.stc2 = 1.e-3;
+mOpt.nstep = 100;
+
+mOpt.err_type = GeneralFitData::DefaultError;
+mOpt.err_scale = 1.; mOpt.err_min = 0.;
+
+mOpt.lp = 1; mOpt.lpg = 0;
+
+mOpt.i1 = mOpt.j1 = 0;
+mOpt.i2 = mOpt.j2 = -1;
+
+mOpt.fromlastfit = false;
+mOpt.autoinifit = false;
+}
+
+/* --Methode-- */
+void PIAFitter::DecodeOptions(string opt)
+// Decodage des options a partir des chaines de caracteres
+{
+ResetOptions();
+if(opt.length()<=0) return;
+
+size_t p,q; string dum;
+opt = "," + opt + ",";
+
+if(strstr(opt.c_str(),",F,"))  // init options/param a partir du fit precedent
+  {mOpt = mOptSave; mOpt.fromlastfit = true;}
+if(strstr(opt.c_str(),",a,")) mOpt.autoinifit = true; // init auto par fit
+if(strstr(opt.c_str(),",r,")) mOpt.okres = true;  // residus
+if(strstr(opt.c_str(),",f,")) mOpt.okfun = true;  // fonction fittee
+if(strstr(opt.c_str(),",x")) { // Demande de centrage (fit X=x-xc)
+  mOpt.polcx = 2; // Le centrage est calcule automatiquement
+  p = opt.find(",x"); q = opt.find_first_of(',',p+1);
+  dum = opt.substr(p,q-p);
+  if(dum.length()>2) {
+    sscanf(dum.c_str(),",x%lf",&mOpt.xc);
+    mOpt.polcx = 1; // Le centrage est fixe par la valeur lue
+  }
+}
+if(strstr(opt.c_str(),",y")) { // Demande de centrage (fit Y=y-yc)
+  mOpt.polcy = 2; // Le centrage est calcule automatiquement
+  p = opt.find(",y"); q = opt.find_first_of(',',p+1);
+  dum = opt.substr(p,q-p);
+  if(dum.length()>2) {
+    sscanf(dum.c_str(),",y%lf",&mOpt.yc);
+    mOpt.polcy = 1; // Le centrage est fixe par la valeur lue
+  }
+}
+if(strstr(opt.c_str(),",h")) {
+  mOpt.err_type = GeneralFitData::DefaultError;
+  p = opt.find(",h"); q = opt.find_first_of(',',p+1);
+  dum = opt.substr(p,q-p);
+  if(dum.length()>2) sscanf(dum.c_str(),",h%lf/%lf",&mOpt.err_scale,&mOpt.err_min);
+}
+if(strstr(opt.c_str(),",H")) {
+  mOpt.err_type = GeneralFitData::ProporError;
+  p = opt.find(",H"); q = opt.find_first_of(',',p+1);
+  dum = opt.substr(p,q-p);
+  if(dum.length()>2) sscanf(dum.c_str(),",H%lf/%lf",&mOpt.err_scale,&mOpt.err_min);
+}
+if(strstr(opt.c_str(),",e")) {
+  mOpt.err_type = GeneralFitData::ConstantError;
+  p = opt.find(",e"); q = opt.find_first_of(',',p+1);
+  dum = opt.substr(p,q-p);
+  if(dum.length()>2) sscanf(dum.c_str(),",e%lf/%lf",&mOpt.err_scale,&mOpt.err_min);
+}
+if(strstr(opt.c_str(),",E")) {
+  mOpt.err_type = GeneralFitData::SqrtError;
+  p = opt.find(",E"); q = opt.find_first_of(',',p+1);
+  dum = opt.substr(p,q-p);
+  if(dum.length()>2) sscanf(dum.c_str(),",E%lf/%lf",&mOpt.err_scale,&mOpt.err_min);
+}
+if(strstr(opt.c_str(),",X")) { // Valeur du StopChi2
+  p = opt.find(",X"); q = opt.find_first_of(',',p+1);
+  dum = opt.substr(p,q-p);
+  if(dum.length()>2) sscanf(dum.c_str(),",X%lf",&mOpt.stc2);
+}
+if(strstr(opt.c_str(),",N")) { // Nombre maximum d'iterations
+  p = opt.find(",N"); q = opt.find_first_of(',',p+1);
+  dum = opt.substr(p,q-p);
+  if(dum.length()>2) sscanf(dum.c_str(),",N%d",&mOpt.nstep);
+}
+if(strstr(opt.c_str(),",l")) { // niveau de print
+  p = opt.find(",l"); q = opt.find_first_of(',',p+1);
+  dum = opt.substr(p,q-p);
+  if(dum.length()>2) sscanf(dum.c_str(),",l%d",&mOpt.lp);
+}
+if(strstr(opt.c_str(),",d")) { // niveau de debug du fit
+  p = opt.find(",d"); q = opt.find_first_of(',',p+1);
+  dum = opt.substr(p,q-p);
+  if(dum.length()>2) sscanf(dum.c_str(),",d%d",&mOpt.lpg);
+}
+if(strstr(opt.c_str(),",I")) { // intervalle de fit selon X
+  p = opt.find(",I"); q = opt.find_first_of(',',p+1);
+  dum = opt.substr(p,q-p);
+  if(dum.length()>2) sscanf(dum.c_str(),",I%d/%d",&mOpt.i1,&mOpt.i2);
+}
+if(strstr(opt.c_str(),",J")) { // intervalle de fit selon Y
+  p = opt.find(",J"); q = opt.find_first_of(',',p+1);
+  dum = opt.substr(p,q-p);
+  if(dum.length()>2) sscanf(dum.c_str(),",J%d/%d",&mOpt.j1,&mOpt.j2);
+}
+
+return;
+}
+
+/* --Methode-- */
+void PIAFitter::DecodeObject(string obj)
+// Decodage de l'objet a fitter
+{
+mNObj = "";
+NamedObjMgr omg;
+AnyDataObj* mobj = omg.GetObj(obj);
+if(mobj == NULL)
+  {cout<<"PIAFitter::DecodeObject Error , Pas d'objet de nom "<<obj<<endl;
+   return;}
+
+mNObj = obj;
+
+return;
+}
+
+/* --Methode-- */
+void PIAFitter::CheckOptions(void)
+// Check consistence des choix des options
+// ATTENTION: cette methode a besoin que l'objet a fitter soit deja lu
+{
+if(mOpt.lp<0) mOpt.lp = 0;
+if(mOpt.lpg<0) mOpt.lpg = 0;
+if(mOpt.stc2<=0.) mOpt.stc2 = 1.e-3;
+if(mOpt.nstep<2) mOpt.nstep = 100;
+return;
+}
+
+/* --Methode-- */
+void PIAFitter::PrintOptions(void)
+// Print des options
+{
+cout<<"Fit("<<mNData<<") dim="<<mNVar<<":"
+    <<" Int=["<<mOpt.i1<<","<<mOpt.i2<<"],["<<mOpt.j1<<","<<mOpt.j2<<"]"<<endl
+    <<" Cent="<<mOpt.polcx<<","<<mOpt.polcy<<","<<mOpt.xc<<"+x"<<","<<mOpt.yc<<"+y"
+    <<" TypE="<<mOpt.err_type<<","<<mOpt.err_scale<<","<<mOpt.err_min
+    <<" StpX2="<<mOpt.stc2<<" Nstep="<<mOpt.nstep<<endl
+    <<" Init.LFit="<<mOpt.fromlastfit<<" AutoIni.Fit="<<mOpt.autoinifit
+    <<" lp,lpg="<<mOpt.lp<<","<<mOpt.lpg<<endl;
+return;
+}
+
+/* --Methode-- */
+void PIAFitter::FillGData(void)
+// Fill generalfitdata pour le fit
+// ATTENTION: cette methode a besoin que les options soient decodees et checkees
+{
+if(delmGData && mGData!=NULL) {delete mGData; mGData=NULL; delmGData=false;}
+mNVar = mNData = 0;
+
+NamedObjMgr omg;
+mAdObj = omg.GetObjAdapter(mNObj); // Ne pas deleter
+if(mAdObj == NULL) {
+  cout<<"PIAFitter::DecodeObject Error , ObjAdapter==NULL for "<<mNObj<<endl;
+  return;
+}
+mGData = mAdObj->GetGeneralFitData(delmGData
+                 ,mOpt.err_type,mOpt.err_scale,mOpt.err_min
+                 ,mOpt.i1,mOpt.i2,mOpt.j1,mOpt.j2);
+if(mGData == NULL) {
+  cout<<"PIAFitter::DecodeObject Error , No adaptor for "<<mNObj<<endl;
+  return;
+}
+mNData = mGData->NData();
+if(mNData<=0) {
+  cout<<"No data in GeneralFitData: "<<mNData<<endl;
+  return;
+}
+mNVar = mGData->NVar();
+if(mNVar<=0 || mNVar>2) {
+  cout<<"Fit only support 1 and 2D :  NVar = "<<mNVar<<endl;
+  return;
+}
+
+// Gestion du centrage automatique si demande
+GetCentering();
+
+// Prints
+if(mOpt.lp>2) {
+  mGData->PrintStatus();
+  mGData->PrintData(0);
+  mGData->PrintData(mNData-1);
+  double mini,maxi;
+  mGData->GetMnMx(2,mini,maxi);
+    cout<<"Limites ...x0 = ["<<mini<<","<<maxi<<"]"<<endl;
+  if(mNVar==2)
+    {mGData->GetMnMx(12,mini,maxi);
+     cout<<"Limites ...x1 = ["<<mini<<","<<maxi<<"]"<<endl;}
+  mGData->GetMnMx(0,mini,maxi);
+    cout<<"Limites ...y  = ["<<mini<<","<<maxi<<"]"<<endl;
+  mGData->GetMnMx(1,mini,maxi);
+    cout<<"Limites ...ey = ["<<mini<<","<<maxi<<"]"<<endl;
+}
+
+return;
+}
+
+/* --Methode-- */
+void PIAFitter::GetCentering(void)
+// Calcul le centrage automatique
+{
+if(!mGData) return;
+if(mOpt.polcx==2) {
+  double mini,maxi;
+  mGData->GetMnMx(2,mini,maxi);
+  mOpt.xc=(mini+maxi)/2.;
+}
+if(mOpt.polcy==2 && mNVar>=2) {
+  double mini,maxi;
+  mGData->GetMnMx(12,mini,maxi);
+  mOpt.yc=(mini+maxi)/2.;
+}
+}
+
+/* --Methode-- */
+void PIAFitter::DecodeFunction(string func)
+// Fonction a fitter
+// ATTENTION: cette methode a besoin que les donnees soient lues
+//                                    (pour mOpt.xc,yc et mNVar)
+{
+if(func.length()<=0)
+  {cout<<"PIAFitter::DecodeFunction Donnez un nom de fonction a fitter."<<endl;
+   return;}
+if(mFunction!=NULL) {delete mFunction; mFunction=NULL;}
+if(mFunc    !=NULL) {delete mFunc;     mFunc=NULL;}
+mNPar=0; mFName = "";
+
+if(func == mNameFitFunc) { // Fonction utilisateur
+  mFunc = new GeneralFunc(mUFNVar,mUFNPar,mFitFunc,mFitFuncDer);
+  mNPar = mUFNPar;
+  cout<<"Fonction utilisateur nvar="<<mUFNVar<<", npar="<<mNPar<<endl;
+} else if(func[0]=='p' && mNVar==1) { //polynome
+  int degre=0; if(func.length()>1) sscanf(func.c_str()+1,"%d",&degre);
+  cout<<"Fit polynome 1D de degre "<<degre<<endl;
+  Polyn1D* myf = new Polyn1D(degre,((mOpt.polcx>0)?mOpt.xc:0.));
+  mFunction = myf; mNPar = mFunction->NPar(); mFName = func;
+
+} else if(func[0]=='e' && mNVar==1) { //exponentielle
+  int degre=-1; if(func.length()>1) sscanf(func.c_str()+1,"%d",&degre);
+  cout<<"Fit d'exponentielle+polynome 1D de degre "<<degre<<endl;
+  Exp1DPol* myf;
+  if(degre>=0) myf = new Exp1DPol((unsigned int)degre,((mOpt.polcx>0)?mOpt.xc:0.));
+       else    myf = new Exp1DPol(((mOpt.polcx>0)?mOpt.xc:0.));
+  mFunction = myf; mNPar = mFunction->NPar(); mFName = func;
+
+} else if(func[0]=='g' && mNVar==1) { //gaussienne en hauteur
+  int degre=-1; if(func.length()>1) sscanf(func.c_str()+1,"%d",&degre);
+  cout<<"Fit de Gaussienne_en_hauteur+polynome 1D de degre "<<degre<<endl;
+  Gauss1DPol* myf;
+  if(degre>=0) myf = new Gauss1DPol((unsigned int)degre,((mOpt.polcx)?true:false));
+  else { bool bfg = (mOpt.polcx)?true:false;   myf = new Gauss1DPol(bfg); }
+  mFunction = myf; mNPar = mFunction->NPar(); mFName = func;
+
+} else if(func[0]=='G' && mNVar==1) { //gaussienne en volume
+  int degre=-1; if(func.length()>1) sscanf(func.c_str()+1,"%d",&degre);
+  cout<<"Fit de Gaussienne_en_volume+polynome 1D de degre "<<degre<<endl;
+  GaussN1DPol* myf;
+  if(degre>=0) myf = new GaussN1DPol((unsigned int)degre,((mOpt.polcx)?true:false));
+  else  { bool bfg = (mOpt.polcx)?true:false;   myf = new GaussN1DPol(bfg); }
+  mFunction = myf; mNPar = mFunction->NPar(); mFName = func;
+
+} else if(func[0]=='p' && mNVar==2) { //polynome 2D
+  int degre=0; if(func.length()>1) sscanf(func.c_str()+1,"%d",&degre);
+  cout<<"Fit polynome 2D de degre "<<degre<<endl;
+  Polyn2D* myf =
+    new Polyn2D(degre,((mOpt.polcx>0)?mOpt.xc:0.),((mOpt.polcy>0)?mOpt.yc:0.));
+  mFunction = myf; mNPar = mFunction->NPar(); mFName = func;
+
+} else if(func[0]=='G' && mNVar==2) { //gaussienne+fond en volume
+  int integ=0; if(func.length()>1) if(func[1]=='i') integ=1;
+  cout<<"Fit de Gaussienne+Fond 2D integ="<<integ<<endl;
+  if(integ) {GauRhInt2D* myf = new GauRhInt2D; mFunction = myf;}
+    else    {GauRho2D*   myf = new GauRho2D;   mFunction = myf;}
+  mNPar = mFunction->NPar(); mFName = func;
+
+} else if(func[0]=='d' && mNVar==2) { //DL gaussienne+fond en volume
+  int integ=0; if(func.length()>1) if(func[1]=='i') integ=1;
+  cout<<"Fit de DL de Gaussienne+Fond 2D integ="<<integ<<endl;
+  if(integ) {GdlRhInt2D* myf = new GdlRhInt2D; mFunction = myf;}
+    else    {GdlRho2D*   myf = new GdlRho2D;   mFunction = myf;}
+  mNPar = mFunction->NPar(); mFName = func;
+
+} else if(func[0]=='D' && mNVar==2) { //DL gaussienne+fond avec coeff variable p6 en volume
+  int integ=0; if(func.length()>1) if(func[1]=='i') integ=1;
+  cout<<"Fit de DL de Gaussienne+Fond avec coeff variable (p6) 2D integ="<<integ<<endl;
+  if(integ) {Gdl1RhInt2D* myf = new Gdl1RhInt2D; mFunction = myf;}
+    else    {Gdl1Rho2D*   myf = new Gdl1Rho2D;   mFunction = myf;}
+  mNPar = mFunction->NPar(); mFName = func;
+
+} else if(func[0]=='M' && mNVar==2) { //Moffat+fond (volume)
+  int integ=0; if(func.length()>1) if(func[1]=='i') integ=1;
+  cout<<"Fit de Moffat+Fond (expos=p6) 2D integ="<<integ<<endl;
+  if(integ) {MofRhInt2D* myf = new MofRhInt2D; mFunction = myf;}
+    else    {MofRho2D*   myf = new MofRho2D;   mFunction = myf;}
+   mNPar = mFunction->NPar(); mFName = func;
+
+} else {
+  cout<<"Fonction "<<func<<" inconnue pour la dim "<<mNVar<<endl;
+  return;
+}
+
+return;
+}
+
+/* --Methode-- */
+void PIAFitter::ReSetParam(void)
+// Pour (re)dimensionner les tableaux des parametres
+// ATTENTION: cette methode a besoin que la fonction soit connue
+{
+if(mNPar==0) return;
+mPar.Realloc(mNPar);  mPar=0.;
+mStep.Realloc(mNPar); mStep=1.;
+mMin.Realloc(mNPar);  mMin=1.;
+mMax.Realloc(mNPar);  mMax=-1.;
+mFix.Realloc(mNPar);  mFix=0.;
+return;
+}
+
+/* --Methode-- */
+void PIAFitter::AutoIniFit(void)
+// Initialisation automatique des parametres du fit
+{
+if(mFunc) { // Fonction utilisateur
+  cout<<"PIAFitter::AutoIniFit : Fonction utilisateur, pas d'init auto"<<endl;
+} else if(mFName[0]=='p' && mNVar==1) { //poly 1D
+  cout<<"PIAFitter::AutoIniFit : Auto Init type polynome 1D"<<endl;
+  IniFitP1ou2D();
+
+} else if(mFName[0]=='g' && mNVar==1) { //gauss en haut 1D
+  cout<<"PIAFitter::AutoIniFit : Auto Init type gauss_haut+pol 1D"<<endl;
+  IniFitGhP1D();
+
+} else if(mFName[0]=='G' && mNVar==1) { //gauss en vol 1D
+  cout<<"PIAFitter::AutoIniFit : Auto Init type gauss_vol+pol 1D"<<endl;
+  IniFitGvP1D();
+
+} else if(mFName[0]=='p' && mNVar==2) { //poly 2D
+  cout<<"PIAFitter::AutoIniFit : Auto Init type polynome 2D"<<endl;
+  IniFitP1ou2D();
+
+} else if((mFName[0]=='G'||mFName[0]=='d') && mNVar==2) { //gauss+fond en vol
+  cout<<"PIAFitter::AutoIniFit : Auto Init type gauss_vol+fond 2D"<<endl;
+  IniFitGv2D();
+
+} else if(mFName[0]=='D' && mNVar==2) { //DLgauss+fond en vol 2D
+  cout<<"PIAFitter::AutoIniFit : Auto Init type DLgauss_vol+fond 2D"<<endl;
+  IniFitGv2D();
+  Vector dum(mNPar);
+  dum = mPar;  mPar(6)=0.5;   mPar(7)=dum(6);
+  dum = mStep; mStep(6)=0.05; mStep(7)=dum(6);
+  dum = mMin;  mMin(6)=0.;    mMin(7)=dum(6);
+  dum = mMax;  mMax(6)=10.;   mMax(7)=dum(6);
+  dum = mFix;  mFix(6)=1.1;   mFix(7)=dum(6);
+
+} else if(mFName[0]=='M' && mNVar==2) { //Moffat+fond en vol 2D
+  cout<<"PIAFitter::AutoIniFit : Auto Init type moffat_vol+fond 2D"<<endl;
+  IniFitGv2D();
+  Vector dum(mNPar);
+  dum = mPar;  mPar(6)=2.5;   mPar(7)=dum(6);
+  dum = mStep; mStep(6)=0.05; mStep(7)=dum(6);
+  dum = mMin;  mMin(6)=1.2;   mMin(7)=dum(6);
+  dum = mMax;  mMax(6)=10.;   mMax(7)=dum(6);
+  dum = mFix;  mFix(6)=1.1;   mFix(7)=dum(6);
+
+} else {
+  cout<<"PIAFitter::AutoIniFit : Fonction "<<mFName
+      <<", \n  pas d'init auto en dim "<<mNVar<<endl;
+  return;
+}
+
+return;
+}
+
+/* --Methode-- */
+void PIAFitter::InitParFromLastFit(void)
+// Initialisation du fit a partir des resultats du fit precedent
+// (Les arguments de la ligne de commande sont prioritaires)
+// ATTENTION: cette methode a besoin que la fonction soit connue
+{
+if(mNPar==0) return;
+int n = mParSave.NElts();
+if(n==0) return;
+
+for(int i=0;i<mNPar;i++) {
+  if(i>=n) break;
+  mPar(i)  = mParSave(i);
+  mStep(i) = mStepSave(i);
+  mMin(i)  = mMinSave(i);
+  mMax(i)  = mMaxSave(i);
+  mFix(i)  = mFixSave(i);
+}
+
+return;
+}
+
+/* --Methode-- */
+void PIAFitter::DecodeParam(string par,string step,string min,string max,string fix)
+// Decodage des parametres
+// ATTENTION: cette methode a besoin que la fonction soit connue
+//                            et que les options soient decodees
+{
+if(mNPar==0) return;
+ReSetParam();
+if(mOpt.autoinifit)  AutoIniFit();
+if(mOpt.fromlastfit) InitParFromLastFit();
+Vector* v=NULL; string* s=NULL;
+for(int j=0;j<5;j++) {
+  if(j==0) {v=&mPar; s=&par;} else if(j==1) {v=&mStep; s=&step;}
+  else if(j==2) {v=&mMin; s=&min;} else if(j==3) {v=&mMax; s=&max;}
+  else if(j==4) {v=&mFix; s=&fix;}
+  if(s->length()>0) *s += ",";
+  for(int i=0;i<mNPar;i++) {
+    if(s->length()<=0) break;
+    if((*s)[0]!='!') sscanf(s->c_str(),"%lf",&(*v)(i));
+    size_t p = s->find_first_of(',') + 1;
+    if(p>=s->length()) *s = ""; else *s = s->substr(p);
+  }
+}
+return;
+}
+
+/* --Methode-- */
+int PIAFitter::DoFit(void)
+// Fit avec generalfit
+{
+if(mNPar==0) return -1000;
+if((mFunction==NULL && mFunc==NULL) || mGData==NULL) {
+  cout<<"PIAFitter::DoFit error: mFunction,mFunc="<<mFunction<<","<<mFunc
+      <<" mGData="<<mGData<<endl;
+  return -1001;
+}
+// classe GeneraFit
+if(mFit != NULL) {delete mFit; mFit= NULL;}
+if(mFunction)    mFit = new GeneralFit(mFunction);
+  else if(mFunc) mFit = new GeneralFit(mFunc);
+if(!mFit) return(-1002);
+
+// Options et Set de GeneralFit
+mFit->SetDebug(mOpt.lpg);
+mFit->SetData(mGData);
+mFit->SetStopChi2(mOpt.stc2);
+mFit->SetMaxStep(mOpt.nstep);
+{for(int i=0;i<mNPar;i++) {
+  char str[10];
+  sprintf(str,"P%d",i);
+  mFit->SetParam(i,str,mPar(i),mStep(i),mMin(i),mMax(i));
+  if((int)(mFix(i)+0.001)>=1.) mFit->SetFix(i);
+}}
+if(mOpt.lp>1) mFit->PrintFit();
+
+// Fit
+#ifdef SANS_EVOLPLANCK
+mParSave = mPar; mStepSave = mStep; mFixSave = mFix;
+mMinSave = mMin; mMaxSave = mMax;
+#else
+mParSave.Clone(mPar); mStepSave.Clone(mStep); mFixSave.Clone(mFix);
+mMinSave.Clone(mMin); mMaxSave.Clone(mMax);
+#endif
+mOptSave = mOpt;
+double c2r = -1.;
+int rcfit = mFit->Fit();
+if(mOpt.lp>0) mFit->PrintFit();
+if(rcfit>0) {
+  c2r = mFit->GetChi2Red();
+  cout<<"C2r_Reduit = "<<c2r<<" nstep="<<mFit->GetNStep()<<" rc="<<rcfit<<endl;
+  for(int i=0;i<mNPar;i++) mParSave(i)=mFit->GetParm(i);
+} else {
+  cout<<"echec Fit, rc = "<<rcfit<<"  nstep="<<mFit->GetNStep()<<endl;
+  mFit->PrintFitErr(rcfit);
+}
+
+return rcfit;
+}
+
+/* --Methode-- */
+void PIAFitter::FitFunRes(void)
+// Mise a disposition des resultats (fonction fitee et residus)
+{
+if(!mFit) return;
+
+NamedObjMgr omg;
+string nomresfun = "__dummy__";
+
+if(mOpt.okres) {
+  nomresfun = mNObj + "_res";
+  AnyDataObj* ob = mAdObj->FitResidusObj(*mFit);
+  if(ob) omg.AddObj(ob,nomresfun);
+}
+
+if(mOpt.okfun) {
+  nomresfun = mNObj + "_fun";
+  AnyDataObj* ob = mAdObj->FitFunctionObj(*mFit);
+  if(ob) omg.AddObj(ob,nomresfun);
+}
+
+return;
+}
+
+/* --Methode-- */
+void PIAFitter::LinFit(void)
+// Fit lineaire de polynomes
+{
+if(mFName.length()<=0)
+  {cout<<"PIAFitter::LinFit Donnez un nom de fonction a fitter."<<endl;
+   return;}
+if(!mGData)
+  {cout<<"PIAFitter::LinFit pas de Data."<<endl; return;}
+if(mFName[0]!='p') 
+  {cout<<"PIAFitter::LinFit fonction non prevue "<<mFName<<endl;
+   return;}
+int degre = 0;
+if(mFName.length()>1) sscanf(mFName.c_str()+1,"%d",&degre);
+
+double xc = (mOpt.polcx>0) ? mOpt.xc : 0.;
+double yc = (mOpt.polcy>0) ? mOpt.yc : 0.;
+
+if(mNVar==1) {  // Fit lineaire de polynome 1D
+  cout<<"Fit (lineaire) 1D polynome de degre "<<degre
+      <<" (xc="<<xc<<")"<<endl;
+  Poly p1(0);
+  double c2rl = mGData->PolFit(0,p1,degre,true,xc);
+  cout<<"C2r_lineaire = "<<c2rl<<endl;
+  if(mOpt.lp>0) cout<<p1<<endl;
+} else if(mNVar==2) {  // Fit lineaire de polynome 2D
+  cout<<"Fit (lineaire) polynome 2D de degre "<<degre
+      <<" (xc,yc="<<xc<<","<<yc<<")"<<endl;
+  Poly2 p2(0);
+  double c2rl = mGData->PolFit(0,1,p2,degre,-1,true,xc,yc);
+  cout<<"C2r_lineaire = "<<c2rl<<endl;
+  if(mOpt.lp>0) cout<<p2<<endl;
+}
+
+return;
+}
+
+/* --Methode-- */
+void PIAFitter::LinkFitFunc(string const& fname, string const& funcname
+                           ,int nvar,int npar)
+// Compilation et link dynamique de la fonction a fitter
+{
+if(nvar<1 || npar<1) return;
+if(mDlUFunc != NULL) {delete mDlUFunc;  mDlUFunc=NULL;}
+mFitFunc = NULL; mFitFuncDer = NULL; 
+mUFNVar= mUFNPar = 0; mNameFitFunc = "";
+
+// On compile le fichier C, on fabrique un .so et on l'ouvre
+mDlUFunc = PDynLinkMgr::BuildFromCFile(fname);
+if(mDlUFunc == NULL)
+  {cerr<<"PIAFitter::LinkFitFunc() Erreur building .so "<<endl; return;}
+
+// On recupere la fonction de fit
+mFitFunc = (DlUserFitFunc) mDlUFunc->GetFunction(funcname);
+if(mFitFunc == NULL)  // Probleme, on n'a pas trouve etc ... 
+  {cerr<<"PIAFitter::LinkFitFunc() Erreur linking function"<<funcname<<endl;
+   delete mDlUFunc; mDlUFunc = NULL; return;}
+
+// On recupere la fonction des derivees
+string fnameder = funcname+"_der";
+mFitFuncDer = (DlUserFitFuncDer) mDlUFunc->GetFunction(fnameder);
+if(mFitFuncDer == NULL)
+  {cout<<"PIAFitter::LinkFitFunc() No derive for"<<fnameder<<endl;}
+
+// Variables et pointeurs definissant le link a la fonction utilisateur
+mNameFitFunc = funcname;
+mUFNVar = nvar;
+mUFNPar = npar;
+cout<<"PIAFitter::LinkFitFunc() UserFitFunc="<<mNameFitFunc
+    <<" NVar="<<mUFNVar<<" NPar="<<mUFNPar<<endl;
+
+return;
+}
+
+/* --Methode-- */
+void PIAFitter::PrepareFitFuncCFile(string const& fname, string const& funcname
+                                   , int nvar, int npar)
+// Pour ecrire un squelette des fichier C avec pour une fonction a fitter
+{
+if(fname.length()<=0 || funcname.length()<=0 || nvar<=0 || npar <=0) {
+  cerr<<"PIAFitter::PrepareFitFuncCFile: error "
+      <<" nvar="<<nvar<<" npar="<<npar<<endl
+      <<" file_name="<<fname<<" func_name="<<funcname<<endl
+      <<" ---- No File Created ! ----"<<endl;
+  return;
+}
+
+FILE* fip = fopen(fname.c_str(),"w");
+if(fip==NULL)
+  {cerr<<"PIAFitter::PrepareFitFuncCFile: error opening file for writing\n"
+       <<fname<<endl; return;}
+
+fprintf(fip,"#include <stdio.h>\n#include <stdlib.h>\n#include <math.h>\n\n");
+fprintf(fip,"/* - many functions can be written in this file: */\n");
+fprintf(fip,"/*   here is an exemple for creation of function %s */\n\n"
+       ,funcname.c_str());
+fprintf(fip,"double %s(double const* x,double const* p)\n",funcname.c_str());
+fprintf(fip,"/* Function : F(x[0-%d];p[0-%d]) */\n",nvar-1,npar-1);
+fprintf(fip,"/* variables  x1=x[0],x2=x[1],...,x%d=x[%d] */\n",nvar,nvar-1);
+fprintf(fip,"/* parameters p1=p[0],p2=p[1],...,p%d=p[%d] */\n",nvar,nvar-1);
+fprintf(fip,"{\n  val = F(x[];p[]);\n  return(val);\n}\n\n");
+string fder = funcname + "_der";
+fprintf(fip,"/* That function is optional */\n");
+fprintf(fip,"/*\n");
+fprintf(fip,"double %s(double const* x,double const* p,double* dp)\n",fder.c_str());
+fprintf(fip,"{\n");
+for(int i=0;i<npar;i++) fprintf(fip,"  dp[%d] = dF(x[];p[])/dp[%d]\n",i,i);
+fprintf(fip,"  val = F(x[];p[]);\n  return(val);\n}\n\n");
+fprintf(fip,"*/\n");
+
+fclose(fip);
+}
+
+/* --Methode-- */
+int PIAFitter::Execute(string& kw, vector<string>& tokens, string& toks)
+// Execution des commandes de fit : "fit" et "fitw"
+{
+////// Les commandes pour creer les fonctions de fit utilisateur
+if(kw == "crfitfil") {
+  if (tokens.size() < 4)
+    {cout<<"Usage:crfitfil filename funcname nvar npar"<<endl;return(-1);}
+  int nvar = atoi(tokens[2].c_str()), npar = atoi(tokens[3].c_str());
+  PrepareFitFuncCFile(tokens[0],tokens[1],nvar,npar);
+  return(0);
+} else if (kw == "crfitfun") {
+  if (tokens.size() < 4)
+    {cout<<"Usage:crfitfun filename funcname nvar npar"<<endl;return(-1);}
+  int nvar = atoi(tokens[2].c_str()), npar = atoi(tokens[3].c_str());
+  LinkFitFunc(tokens[0],tokens[1],nvar,npar);
+  return(0);
+}
+
+////// Les commandes pour fitter
+if(tokens.size() < 2) {
+  cout
+  <<"Usage:fit  nomobj func [Options]\n"
+  <<" ou   fitw nomobj func [Options]\n"
+  <<" avec Options: [p:p1,...,pn s:s1,...,sn m:m1,...,mn \n"
+  <<"                M:M1,...,Mn f:f1,...,fn o:.,.,. o:.,.,.]\n"
+  <<" ou   fitlin nomobj pnn [o:.,.,. o:.,.,.]\n";
+  return(-1);
+}
+
+// decodage des arguments de la commande
+string mSp,mSs,mSm,mSM,mSf,mSo;
+mSp=""; mSs=""; mSm=""; mSM=""; mSf=""; mSo="";
+if(tokens.size()>2)
+  for(int ip=2;ip<(int)tokens.size();ip++) {
+    if(tokens[ip].length()<=2) continue;
+    const char *c = tokens[ip].c_str();
+    if(c[1]!=':') continue;
+    if(c[0]=='p')      mSp=c+2;
+    else if(c[0]=='s') mSs=c+2;
+    else if(c[0]=='m') mSm=c+2;
+    else if(c[0]=='M') mSM=c+2;
+    else if(c[0]=='f') mSf=c+2;
+    else if(c[0]=='o') {mSo += ","; mSo += c+2;}
+  }
+
+// Execution des commandes
+DecodeOptions(mSo);
+DecodeObject(tokens[0]);
+CheckOptions();
+FillGData();
+if(mOpt.lp>0) PrintOptions();
+DecodeFunction(tokens[1]);
+DecodeParam(mSp,mSs,mSm,mSM,mSf);
+if(kw == "fit") {
+  int rc = DoFit();
+  if(rc>=0) FitFunRes();
+} else if(kw == "fitlin") {
+  LinFit();
+} else if(kw == "fitw") {
+  if(FWindFit!=NULL) {delete FWindFit; FWindFit=NULL;}
+  FWindFit = new PIAFitterWind(mApp,this,tokens[1]);
+  FWindFit->Show();
+}
+
+return(0);
+}
+
+/* --Methode-- */
+void PIAFitter::IniFitP1ou2D(void)
+{
+if(mNPar==0) return;
+mPar=0.; mStep=1.; mMin=1.; mMax=-1.; mFix=0.;
+if(!mGData) return;
+double mean,sigma;
+int rc = mGData->GetMeanSigma(0,mean,sigma);
+if(rc<=0) return;
+mPar(0) = mean;
+return;
+}
+
+void PIAFitter::IniFitGhP1D(void)
+{
+if(mNPar==0) return;
+mPar=0.; mStep=1.; mMin=1.; mMax=-1.; mFix=0.;
+if(mNVar!=1 || mNPar<3) return;
+double h,v,x0,y0,sx,sy,f;
+int rc = IniFitGaus(*mGData,h,v,x0,y0,sx,sy,f);
+if(rc!=0) return;
+mPar(0)=h;  mStep(0)=h/1000.;
+mPar(1)=x0; mStep(1)=sx/10.;
+mPar(2)=sx; mStep(2)=sx/10.; mMin(2)=0.; mMax(2)=20.*sx; 
+if(mNPar>3) {mPar(3)=f; mStep(3)=f/1000.;} else mPar(0)=h+f;
+}
+
+void PIAFitter::IniFitGvP1D(void)
+{
+if(mNPar==0) return;
+mPar=0.; mStep=1.; mMin=1.; mMax=-1.; mFix=0.;
+if(mNVar!=1 || mNPar<3) return;
+double h,v,x0,y0,sx,sy,f;
+int rc = IniFitGaus(*mGData,h,v,x0,y0,sx,sy,f);
+if(rc!=0) return;
+mPar(0)=v;  mStep(0)=v/1000.;
+mPar(1)=x0; mStep(1)=sx/10.;
+mPar(2)=sx; mStep(2)=sx/10.; mMin(2)=0.; mMax(2)=20.*sx; 
+if(mNPar>3) {mPar(3)=f; mStep(3)=f/1000.;} else mPar(0)=v+mNData*f;
+}
+
+void PIAFitter::IniFitGv2D(void)
+{
+if(mNPar==0) return;
+mPar=0.; mStep=1.; mMin=1.; mMax=-1.; mFix=0.;
+if(mNVar!=2 || mNPar<6) return;
+double h,v,x0,y0,sx,sy,f;
+int rc = IniFitGaus(*mGData,h,v,x0,y0,sx,sy,f);
+if(rc!=0) return;
+mPar(0)=v;  mStep(0)=v/1000.;
+mPar(1)=x0; mStep(1)=sx/10.;
+mPar(2)=y0; mStep(2)=sy/10.;
+mPar(3)=sx; mStep(3)=sx/10.; mMin(3)=0.;  mMax(3)=20.*sx; 
+mPar(4)=sy; mStep(4)=sy/10.; mMin(4)=0.;  mMax(4)=20.*sy; 
+mPar(5)=0.; mStep(5)=0.005;  mMin(5)=-1.; mMax(5)=1.; 
+if(mNPar>6) {mPar(6)=f; mStep(6)=f/1000.;} else mPar(0)=v+mNData*f;
+}
+
+int PIAFitter::IniFitGaus(GeneralFitData& g,double& h,double& v
+    ,double& x0,double& y0,double& sx,double& sy,double& f)
+// Pour initialiser une gaussienne 1D ou 2D
+// return code =0 si OK
+{
+h=v=x0=y0=sx=sy=f=0.;
+if(!&g) return(-1);
+int nvar = g.NVar();
+int ndata = g.NData();
+if(nvar<1 || 2<nvar || ndata<=0) return(-2);
+
+// X et Y ordonnees croissant
+double *X=NULL, *Y=NULL;
+X = new double[ndata];
+if(nvar==2) Y = new double[ndata];
+{for(int i=0;i<ndata;i++) {X[i] = g.X(i); if(Y) Y[i] = g.Y(i);}}
+qsort(X,(size_t) ndata,sizeof(double),qSort_Dble);
+if(Y) qsort(Y,(size_t) ndata,sizeof(double),qSort_Dble);
+
+// determination des zones externes=[0,1/3] et [2/3,1]
+//            et des zones internes=[1/3,2/3]
+int k1=ndata/3,k2=2*ndata/3;
+double xmin,xmax, ymin=-1.,ymax=1.;
+xmin = X[k1]; xmax = X[k2];
+if(Y) {ymin = Y[k1]; ymax = Y[k2];}
+
+// recherche des parametres
+double nb=0, nc=0;
+{for(int i=0;i<ndata;i++) {
+   double val,x,y=0.;
+   x = g.X(i); if(Y) y = g.Y(i); val = g.Val(i);
+   if(xmin<x && x<xmax && ymin<y && y<ymax) { // c'est le centre
+     if(nc==0 || val>h) {h=val; x0=x; y0=y;}
+     v += val; nc++;
+   } else {f += val; nb++;} // c'est le bord
+
+}}
+if(nb==0 || nc==0) {delete [] X; if(Y) delete [] Y; return(-3);}
+
+// Calcul des parametres
+f /= (double) nb; h -= f; v -= f*nc;
+sx = (xmax-xmin)/2.; if(Y) sy = (ymax-ymin)/2.; 
+
+delete [] X; if(Y) delete [] Y;
+return(0);
+}
+
+
+////////////////////////////////////////////////////////////////////
+////---------- Classe de fenetre de fit interactive ------------////
+////////////////////////////////////////////////////////////////////
+
+/* --Methode-- */
+PIAFitterWind::PIAFitterWind(PIStdImgApp* par, PIAFitter* fiter,string func)
+: PIWindow((PIMsgHandler*)par, "PIAFitter", PIWK_normal, 240, 240, 150, 150)
+, mDap(par), mFitter(fiter), mFunc(func)
+, ReFillGData(false), ReDecodeFunc(false)
+, saveI1(0), saveI2(0), saveJ1(0), saveJ2(0)
+, saveErrScale(1.),saveErrMin(0.), saveXC(0.), saveYC(0.)
+{
+#ifdef SANS_EVOLPLANCK
+COMPATIBLE_ASSERT(mFitter);
+#else
+ASSERT(mFitter);
+#endif
+
+int npar = mFitter->mNPar;
+
+// Alloc de la taille
+nlab = 15+npar;   lab = new PILabel*[nlab];    {for(int i=0;i<nlab;i++) lab[i]=NULL;}
+ntxt = 15+4*npar; txt = new PIText*[ntxt];     {for(int i=0;i<ntxt;i++) txt[i]=NULL;}
+nbut = 6;         but = new PIButton*[nbut];   {for(int i=0;i<nbut;i++) but[i]=NULL;}
+nckb = 2+npar;    ckb = new PICheckBox*[nckb]; {for(int i=0;i<nckb;i++) ckb[i]=NULL;}
+npom = 3;         pom = new PIOptMenu*[npom];  {for(int i=0;i<npom;i++) pom[i]=NULL;}
+
+// On definit la taille a partir de la taille par defaut des composantes
+// bsx,bsy = environ 6 lettres
+int bsx,bsy;
+par->PrefCompSize(bsx, bsy);
+int spx = (bsx>=10) ? bsx/10 : 1;  // intervalle entre lettres X
+int spy = (bsy>=6) ? bsy/6 : 1;    // intervalle entre lettres Y
+
+int wszx = (5*bsx+5*spx)+spx;
+int wszy = 8*(bsy+spy)+npar*(bsy+spy)+2*spy;
+SetSize(wszx, wszy);
+int cpx,cpy;
+
+// new ligne
+cpx = spx; cpy = spy;
+string dum = "Object: "+mFitter->mNObj+" , Fun: ";
+if(mFitter->mFunc) dum+=mFitter->mNameFitFunc; else dum+=mFitter->mFName;
+lab[0] = new PILabel(this,dum.c_str(),4*bsx,bsy,cpx,cpy);
+lab[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+// new ligne
+cpx = spx; cpy += bsy+spy;
+but[0] = new PIButton(this,"Fr.Last",111,bsx,bsy,cpx,cpy);
+but[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += bsx+spx;
+but[1] = new PIButton(this,"Default",222,bsx,bsy,cpx,cpy);
+but[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += bsx+spx;
+ckb[0] = new PICheckBox(this,"Gen Fun",1001,bsx,bsy,cpx,cpy);
+ckb[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += bsx+2*spx;
+ckb[1] = new PICheckBox(this,"Res",1002,bsx,bsy,cpx,cpy);
+ckb[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+// new ligne
+cpx = spx; cpy += bsy+spy;
+pom[0] = new PIOptMenu(this,"Err def",1.25*bsx,bsy,cpx,cpy);
+  pom[0]->AppendItem("Err def",2101);
+  pom[0]->AppendItem("Err cste",2102);
+  pom[0]->AppendItem("Err sqrt",2103);
+  pom[0]->AppendItem("Err prop",2104);
+  pom[0]->SetValue(2101);
+pom[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += int(1.25*bsx+spx);
+lab[1] = new PILabel(this,"E_Scale",bsx, bsy, cpx, cpy);
+lab[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += bsx+spx;
+txt[0] = new PIText(this,"",bsx,bsy,cpx,cpy);
+txt[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += bsx+spx;
+lab[2] = new PILabel(this,"E_Min",0.75*bsx,bsy,cpx,cpy);
+lab[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += int(0.75*bsx+spx);
+txt[1] = new PIText(this,"",0.75*bsx,bsy,cpx,cpy);
+txt[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+// new ligne
+cpx = spx; cpy += bsy+spy;
+lab[3] = new PILabel(this,"Prt,dbg",bsx,bsy,cpx,cpy);
+lab[3]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += bsx+spx;
+txt[2] = new PIText(this,"",0.5*bsx,bsy,cpx,cpy);
+txt[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += int(0.5*bsx+spx);
+lab[4] = new PILabel(this,"Stop X2",bsx,bsy,cpx,cpy);
+lab[4]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += bsx+spx;
+txt[3] = new PIText(this,"",bsx,bsy,cpx,cpy);
+txt[3]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += bsx+spx;
+lab[5] = new PILabel(this,"Iter",0.5*bsx, bsy, cpx, cpy);
+lab[5]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += int(0.5*bsx+spx);
+txt[4] = new PIText(this,"",0.75*bsx,bsy,cpx,cpy);
+txt[4]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+// new ligne
+cpx = spx; cpy += bsy+spy;
+lab[6] = new PILabel(this,"Range X",bsx,bsy,cpx,cpy);
+lab[6]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += bsx+spx;
+txt[5] = new PIText(this,"",0.75*bsx,bsy,cpx,cpy);
+txt[5]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += int(0.75*bsx+spx);
+txt[6] = new PIText(this,"",0.75*bsx,bsy,cpx,cpy);
+txt[6]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += int(0.75*bsx+spx);
+lab[7] = new PILabel(this,"Y",bsx/2,bsy,cpx,cpy);
+lab[7]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += int(bsx/2.+spx);
+txt[7] = new PIText(this,"",0.75*bsx,bsy,cpx,cpy);
+txt[7]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += int(0.75*bsx+spx);
+txt[8] = new PIText(this,"",0.75*bsx,bsy,cpx,cpy);
+txt[8]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+// new ligne
+cpx = spx; cpy += bsy+spy;
+lab[8] = new PILabel(this,"Cent",bsx/2,bsy,cpx,cpy);
+lab[8]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += int(bsx/2.+spx);
+pom[1] = new PIOptMenu(this,"X.No",1.25*bsx,bsy,cpx,cpy);
+  pom[1]->AppendItem("X.No",2001);
+  pom[1]->AppendItem("X.Value",2002);
+  pom[1]->AppendItem("X.Auto",2003);
+  pom[1]->SetValue(2001);
+pom[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += int(1.25*bsx+spx);
+txt[9] = new PIText(this,"",bsx,bsy,cpx,cpy);
+txt[9]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += bsx+spx;
+pom[2] = new PIOptMenu(this,"Y.No",1.25*bsx,bsy,cpx,cpy);
+  pom[2]->AppendItem("Y.No",2011);
+  pom[2]->AppendItem("Y.Value",2012);
+  pom[2]->AppendItem("Y.Auto",2013);
+  pom[2]->SetValue(2011);
+pom[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += int(1.25*bsx+spx);
+txt[10] = new PIText(this,"",bsx,bsy,cpx,cpy);
+txt[10]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+// new ligne
+cpx = spx; cpy += bsy+spy;
+but[2] = new PIButton(this, "Dismiss",777,bsx,bsy,cpx,cpy);
+but[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += bsx+spx;
+but[3] = new PIButton(this, "Check",666,bsx,bsy,cpx,cpy);
+but[3]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += bsx+spx;
+but[4] = new PIButton(this, "Fit",333,bsx,bsy,cpx,cpy);
+but[4]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += bsx+spx;
+but[5] = new PIButton(this, "Ini Auto",444,bsx,bsy,cpx,cpy);
+but[5]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+// new ligne
+cpx = spx; cpy += bsy+spy;
+lab[9] = new PILabel(this,"Par",bsx/2,bsy,cpx,cpy);
+lab[9]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += int(bsx/2.+spx);
+lab[10] = new PILabel(this,"Fx",bsx/3,bsy,cpx,cpy);
+lab[10]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += int(bsx/3.+spx);
+lab[11] = new PILabel(this,"Init",bsx,bsy,cpx,cpy);
+lab[11]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += bsx+spx;
+lab[12] = new PILabel(this,"Step",bsx,bsy,cpx,cpy);
+lab[12]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += bsx+spx;
+lab[13] = new PILabel(this,"Min",bsx,bsy,cpx,cpy);
+lab[13]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += bsx+spx;
+lab[14] = new PILabel(this,"Max",bsx,bsy,cpx,cpy);
+lab[14]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+// new lines: Parametres (npar lignes)
+if(npar>0) {
+  for(int i=0;i<npar;i++) {
+    cpx = spx; cpy += bsy+spy;
+    char str[8]; sprintf(str,"P%d",i);
+    lab[15+i] = new PILabel(this,str,bsx/2,bsy,cpx,cpy);
+    lab[15+i]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+    cpx += int(bsx/2.+spx);
+    // Attention pas de message entre 1500 et 2000 (permet 500 parametres!)
+    ckb[2+i] = new PICheckBox(this,"",1500+i,bsx/3,bsy,cpx,cpy+spy);
+    ckb[2+i]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+    cpx+=int(bsx/3.+spx);
+    for(int j=0;j<4;j++) {
+      txt[15+4*i+j] = new PIText(this,"",bsx,bsy,cpx,cpy);
+      txt[15+4*i+j]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+      cpx += bsx+spx;
+    }
+  }
+}
+
+return;
+}
+
+/* --Methode-- */
+PIAFitterWind::~PIAFitterWind()
+{
+int i;
+for(i=0;i<nlab;i++) if(lab[i]) {delete lab[i]; lab[i]=NULL;}
+for(i=0;i<ntxt;i++) if(txt[i]) {delete txt[i]; txt[i]=NULL;}
+for(i=0;i<nbut;i++) if(but[i]) {delete but[i]; but[i]=NULL;}
+for(i=0;i<nckb;i++) if(ckb[i]) {delete ckb[i]; ckb[i]=NULL;}
+for(i=0;i<npom;i++) if(pom[i]) {delete pom[i]; pom[i]=NULL;}
+if(lab) {delete lab; lab=NULL; nlab=0;}
+if(txt) {delete txt; txt=NULL; ntxt=0;}
+if(but) {delete but; but=NULL; nbut=0;}
+if(ckb) {delete ckb; ckb=NULL; nckb=0;}
+if(pom) {delete pom; pom=NULL; npom=0;}
+}
+
+/* --Methode-- */
+void PIAFitterWind::Show()
+{
+//mDap->SetBlocked();
+SetState();
+PIWindow::Show();
+return;
+}
+
+/* --Methode-- */
+void PIAFitterWind::SetState(void)
+// Ecriture et positionnement des ckb et txt
+{
+int npar = mFitter->mNPar;
+
+// Les menus d'options
+if(mFitter->mOpt.err_type==GeneralFitData::DefaultError)  pom[0]->SetValue(2101);
+if(mFitter->mOpt.err_type==GeneralFitData::ConstantError) pom[0]->SetValue(2102);
+if(mFitter->mOpt.err_type==GeneralFitData::SqrtError)     pom[0]->SetValue(2103);
+if(mFitter->mOpt.err_type==GeneralFitData::ProporError)   pom[0]->SetValue(2104);
+
+// Les check-boxes
+ckb[0]->SetState(mFitter->mOpt.okfun);
+ckb[1]->SetState(mFitter->mOpt.okres);
+if(npar>0)
+  for(int i=0;i<npar;i++) ckb[2+i]->SetState((mFitter->mFix(i)>=1.)?true:false);
+
+// Les champs textes
+char str[128]; string dum;
+sprintf(str,"%g",mFitter->mOpt.err_scale); dum=str; txt[0]->SetText(dum);
+sprintf(str,"%g",mFitter->mOpt.err_min);   dum=str; txt[1]->SetText(dum);
+sprintf(str,"%d,%d",mFitter->mOpt.lp,mFitter->mOpt.lpg); dum=str; txt[2]->SetText(dum);
+sprintf(str,"%g",mFitter->mOpt.stc2);  dum=str; txt[3]->SetText(dum);
+sprintf(str,"%d",mFitter->mOpt.nstep); dum=str; txt[4]->SetText(dum);
+sprintf(str,"%d",mFitter->mOpt.i1);    dum=str; txt[5]->SetText(dum);
+sprintf(str,"%d",mFitter->mOpt.i2);    dum=str; txt[6]->SetText(dum);
+sprintf(str,"%d",mFitter->mOpt.j1);    dum=str; txt[7]->SetText(dum);
+sprintf(str,"%d",mFitter->mOpt.j2);    dum=str; txt[8]->SetText(dum);
+sprintf(str,"%g",mFitter->mOpt.xc);    dum=str; txt[9]->SetText(dum);
+sprintf(str,"%g",mFitter->mOpt.yc);    dum=str; txt[10]->SetText(dum);
+if(npar>0) {
+  for(int i=0;i<npar;i++) {
+    sprintf(str,"%g",mFitter->mPar(i));  dum=str; txt[15+4*i+0]->SetText(dum);
+    sprintf(str,"%g",mFitter->mStep(i)); dum=str; txt[15+4*i+1]->SetText(dum);
+    sprintf(str,"%g",mFitter->mMin(i));  dum=str; txt[15+4*i+2]->SetText(dum);
+    sprintf(str,"%g",mFitter->mMax(i));  dum=str; txt[15+4*i+3]->SetText(dum);
+  }
+}
+
+return;
+}
+
+/* --Methode-- */
+void PIAFitterWind::Process(PIMessage msg, PIMsgHandler* sender, void* data)
+{
+int lp = (mFitter->mOpt.lp>2)?1:0;
+int npar = mFitter->mNPar;
+
+// Decodage des messages, init et dismiss
+msg = UserMsg(msg);
+if(msg ==777) {
+  if(lp) cout<<"Dismiss"<<endl;
+  //mDap->SetReady();
+  Hide();
+  return;
+}
+
+// L'objet existe t-il encore?
+NamedObjMgr omg;
+if(omg.GetObj(mFitter->mNObj) == NULL) {
+  cout<<"PIAFitterWind::Process Error , Pas d'objet de nom "
+      <<mFitter->mNObj<<endl;
+  return;
+}
+
+// On recupere les champs textes
+string dum; char str[128];
+// Attention gestion du type d'erreur (scale et min)
+dum=txt[0]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+  sscanf(str,"%lf",&(mFitter->mOpt.err_scale));
+  if(saveErrScale!=mFitter->mOpt.err_scale) {
+    if(lp) cout<<"ErrScale changed: "<<mFitter->mOpt.err_scale<<endl;
+    ReFillGData = true;
+    saveErrScale = mFitter->mOpt.err_scale;
+  }
+dum=txt[1]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+  sscanf(str,"%lf",&(mFitter->mOpt.err_min));
+  if(saveErrMin!=mFitter->mOpt.err_min) {
+    if(lp) cout<<"ErrMin changed: "<<mFitter->mOpt.err_min<<endl;
+    ReFillGData = true;
+    saveErrMin = mFitter->mOpt.err_min;
+  }
+dum=txt[2]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+  sscanf(str,"%d,%d",&(mFitter->mOpt.lp),&(mFitter->mOpt.lpg));
+dum=txt[3]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+  sscanf(str,"%lf",&(mFitter->mOpt.stc2));
+dum=txt[4]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+  sscanf(str,"%d",&(mFitter->mOpt.nstep));
+// Attention si les valeurs de mOpt.i1/.i2/.j1/.j2 ont ete changees
+dum=txt[5]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+  sscanf(str,"%d",&(mFitter->mOpt.i1));
+dum=txt[6]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+  sscanf(str,"%d",&(mFitter->mOpt.i2));
+dum=txt[7]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+  sscanf(str,"%d",&(mFitter->mOpt.j1));
+dum=txt[8]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+  sscanf(str,"%d",&(mFitter->mOpt.j2));
+  if(saveI1!=mFitter->mOpt.i1 || saveI2!=mFitter->mOpt.i2 ||
+     saveJ1!=mFitter->mOpt.j1 || saveJ2!=mFitter->mOpt.j2 ) {
+    if(lp)
+      cout<<"Range changed: I("<<saveI1<<","<<saveI2
+          <<") -> I("<<mFitter->mOpt.i1<<","<<mFitter->mOpt.i2
+          <<")  ou   J("<<saveJ1<<","<<saveJ2
+          <<") -> J("<<mFitter->mOpt.j1<<","<<mFitter->mOpt.j2
+          <<")"<<endl;
+    ReFillGData = true;
+    saveI1=mFitter->mOpt.i1; saveI2=mFitter->mOpt.i2;
+    saveJ1=mFitter->mOpt.j1; saveJ2=mFitter->mOpt.j2;
+  }
+dum=txt[9]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+  sscanf(str,"%lf",&(mFitter->mOpt.xc));
+dum=txt[10]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+  sscanf(str,"%lf",&(mFitter->mOpt.yc));
+  if(saveXC!=mFitter->mOpt.xc || saveYC!=mFitter->mOpt.yc) {
+    if(lp) cout<<"mOpt.xc,yc changed: "<<mFitter->mOpt.xc
+               <<" , "<<mFitter->mOpt.xc<<endl;
+    ReDecodeFunc = true;
+    saveXC = mFitter->mOpt.xc; saveYC = mFitter->mOpt.yc;
+  }
+
+if(npar>0) {
+  for(int i=0;i<npar;i++) {
+    dum=txt[15+4*i+0]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+      sscanf(str,"%lf",&(mFitter->mPar(i)));
+    dum=txt[15+4*i+1]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+      sscanf(str,"%lf",&(mFitter->mStep(i)));
+    dum=txt[15+4*i+2]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+      sscanf(str,"%lf",&(mFitter->mMin(i)));
+    dum=txt[15+4*i+3]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+      sscanf(str,"%lf",&(mFitter->mMax(i)));
+  }
+}
+
+// Decodage des messages, suite
+if(msg ==666) {
+  if(lp) cout<<"Check"<<endl;
+  mFitter->CheckOptions();
+  if(ReFillGData) mFitter->FillGData();
+  ReFillGData = false;
+  if(ReDecodeFunc) mFitter->DecodeFunction(mFunc);
+  ReDecodeFunc = false;
+}
+else if(msg ==111) {
+  if(lp) cout<<"Update from last"<<endl;
+  mFitter->mOpt = mFitter->mOptSave;
+  mFitter->ReSetParam();
+  mFitter->InitParFromLastFit();
+  ReFillGData = ReDecodeFunc = true;
+}
+else if(msg ==222) {
+  if(lp) cout<<"Default options/par"<<endl;
+  mFitter->ResetOptions();
+  mFitter->ReSetParam();
+  ReFillGData = ReDecodeFunc = true;
+}
+else if(msg ==333) {
+  if(lp) cout<<"Do the fit"<<endl;
+  mFitter->CheckOptions();
+  if(ReFillGData) mFitter->FillGData();
+  ReFillGData = false;
+  if(ReDecodeFunc) mFitter->DecodeFunction(mFunc);
+  ReDecodeFunc = false;
+  int rc = mFitter->DoFit();
+  if(rc>=0) mFitter->FitFunRes();
+}
+else if(msg ==444) {
+  if(lp) cout<<"Automatic initialisation"<<endl;
+  mFitter->AutoIniFit();
+}
+else if(msg==1001) {
+  if(ckb[0]->GetState()) {
+    if(lp) cout<<"Gen fitted function"<<endl;
+    mFitter->mOpt.okfun = true;
+  } else if(!ckb[0]->GetState()) {
+    if(lp) cout<<"No Gen fitted function"<<endl;
+    mFitter->mOpt.okfun = false;
+  }
+}
+else if(msg==1002) {
+  if(ckb[1]->GetState()) {
+    if(lp) cout<<"Gen fitted residus"<<endl;
+    mFitter->mOpt.okres = true;
+  } else if(!ckb[1]->GetState()) {
+    if(lp) cout<<"No Gen fitted residus"<<endl;
+    mFitter->mOpt.okres = false;
+  }
+}
+else if(2101<=msg && msg<=2104) {
+  if(msg==2101)
+    {mFitter->mOpt.err_type = GeneralFitData::DefaultError; dum="DefaultError";}
+  if(msg==2102)
+    {mFitter->mOpt.err_type = GeneralFitData::ConstantError; dum="ConstantError";}
+  if(msg==2103)
+    {mFitter->mOpt.err_type = GeneralFitData::SqrtError; dum="SqrtError";}
+  if(msg==2104)
+    {mFitter->mOpt.err_type = GeneralFitData::ProporError; dum="ProporError";}
+  if(lp) cout<<"Err_type="<<dum
+             <<" Err_scale="<<mFitter->mOpt.err_scale
+             <<" Err_min="<<mFitter->mOpt.err_min<<endl;
+  ReFillGData = true;
+}
+else if(2001<=msg && msg<=2003) {
+  mFitter->mOpt.polcx = msg-2001;
+  if(lp) cout<<"Centrage X polcx="<<mFitter->mOpt.polcx
+             <<" xc="<<mFitter->mOpt.xc<<endl;
+  mFitter->GetCentering();
+  ReDecodeFunc = true;
+}
+else if(2011<=msg && msg<=2013) {
+  mFitter->mOpt.polcy = msg-2011;
+  if(lp) cout<<"Centrage Y polcy="<<mFitter->mOpt.polcy
+             <<" yc="<<mFitter->mOpt.yc<<endl;
+  mFitter->GetCentering();
+  ReDecodeFunc = true;
+}
+else if(msg>=1500 && msg<2000) {
+  int ip = msg-1500;
+  if(ckb[2+ip]->GetState()) {
+    if(lp) cout<<"Fix Param "<<ip<<endl;
+    mFitter->mFix(ip) = 1.001;
+  } else if(!ckb[2+ip]->GetState()) {
+    if(lp) cout<<"Not Fix Param "<<ip<<endl;
+    mFitter->mFix(ip) = 0.;
+  }
+}
+
+mFitter->CheckOptions();
+SetState();
+if(mFitter->mOpt.lp>1) mFitter->PrintOptions();
+
+return;
+}
Index: /tags/V_Dec2002/SophyaPI/PIext/piafitting.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/piafitting.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/piafitting.h	(revision 2309)
@@ -0,0 +1,110 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe d ajustement pour  piapp 
+// cmv                            98-99
+// CEA-DAPNIA      LAL-IN2P3/CNRS
+
+#ifndef PIAFITTING_H_SEEN
+#define PIAFITTING_H_SEEN
+
+#include "machdefs.h"
+#include <string>
+#include <vector>
+
+#include "nomgadapter.h"
+
+#include "pdlmgr.h"
+#include "dlftypes.h"
+#include "piacmd.h"
+
+class PIStdImgApp;
+class PIAFitterWind;
+
+#ifdef SANS_EVOLPLANCK
+#include "cvector.h"
+class GeneralFunction; class GeneralFunc; class GeneralFit;
+class GeneralFitData;
+#else
+#include "tvector.h"
+namespace SOPHYA { 
+class GeneralFunction; class GeneralFunc; class GeneralFit;
+class GeneralFitData;
+}
+#endif
+
+class PIAFitter : public CmdExecutor {
+public :
+  PIAFitter(PIACmd* piac, PIStdImgApp* app);
+  virtual ~PIAFitter();
+  virtual int Execute(string& keyw, vector<string>& args, string& toks);
+  virtual void LinkFitFunc(string const& fname, string const& funcname
+                          ,int nvar,int npar);
+  virtual void PrepareFitFuncCFile(string const& fname, string const& funcname
+                                  ,int nvar,int npar);
+
+friend class PIAFitterWind;
+
+protected :
+
+typedef struct DFOptions {
+  bool okres, okfun;
+  int polcx,polcy; double xc,yc;
+  GeneralFitData::FitErrType err_type;
+  double err_scale,err_min;
+  double stc2;
+  int nstep;
+  int lp,lpg;
+  int_4 i1,i2,j1,j2;
+  bool fromlastfit,autoinifit;
+} DFOPTIONS ;
+
+void ResetOptions(void);
+void DecodeOptions(string opt);
+void DecodeObject(string obj);
+void CheckOptions(void);
+void PrintOptions(void);
+void FillGData(void);
+void GetCentering(void);
+void DecodeFunction(string func);
+void ReSetParam(void);
+void AutoIniFit(void);
+void InitParFromLastFit(void);
+void DecodeParam(string par,string step,string min,string max,string fix);
+int  DoFit(void);
+void FitFunRes(void);
+void LinFit(void);
+
+// pour initialiser les parametres du fit
+void IniFitP1ou2D(void);
+void IniFitGhP1D(void);
+void IniFitGvP1D(void);
+void IniFitGv2D(void);
+static int IniFitGaus(GeneralFitData& g,double& h,double& v
+       ,double& x0,double& y0,double& sx,double& sy,double& f);
+
+// Graphique
+PIStdImgApp* mApp; // Do not delete
+PIAFitterWind* FWindFit; // Fenetre de config interactive
+// Objet a fitter
+string mNObj;
+NObjMgrAdapter* mAdObj; // Ne pas deleter
+// Structure de data pour le fit, parametres et options
+GeneralFitData* mGData;
+bool delmGData;
+int_4 mNPar,mNVar,mNData;
+Vector mPar; Vector mStep; Vector mMin; Vector mMax; Vector mFix;
+Vector mParSave; Vector mStepSave; Vector mMinSave; Vector mMaxSave; Vector mFixSave;
+GeneralFit* mFit;
+DFOPTIONS mOpt;
+DFOPTIONS mOptSave;
+// Gestion des fonctions de fit predefinies
+GeneralFunction* mFunction; string mFName;
+// Gestion de fonction de fit definie par l'utilisateur
+GeneralFunc* mFunc;
+PDynLinkMgr* mDlUFunc;
+string mNameFitFunc;
+DlUserFitFunc mFitFunc;
+DlUserFitFuncDer mFitFuncDer;
+int_4 mUFNVar, mUFNPar; 
+};
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/piaversion.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/piaversion.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/piaversion.h	(revision 2309)
@@ -0,0 +1,6 @@
+#ifndef PIAPPVERSION_H_SEEN
+#define PIAPPVERSION_H_SEEN
+
+#define PIAPP_VERSIONNUMBER  3.90
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/pigfd1.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/pigfd1.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/pigfd1.cc	(revision 2309)
@@ -0,0 +1,77 @@
+// Cette classe est maintenant obsolete: generaldata <==> ntuple pour le dessin
+
+#include <stdio.h>
+#include "pigfd1.h"
+ 
+/* --Methode-- */
+PIGenFitDat::PIGenFitDat(GeneralFitData* gfd, bool ad)
+: PIDrawer(), mGFD(gfd), mAdDO(ad), VarX(0), ErrX(false), ErrY(false)
+{
+SelectX(0);
+SelectErrBar(false,false);
+}
+
+PIGenFitDat::~PIGenFitDat()
+{
+if(mAdDO && mGFD)  delete mGFD;
+}
+
+/* --Methode-- */
+void  PIGenFitDat::SelectX(int varx)
+{
+VarX = -1;
+if(mGFD == NULL) return;
+if(varx<0 || varx>=mGFD->NVar()) return;
+VarX = varx;
+}
+
+/* --Methode-- */
+void  PIGenFitDat::SelectErrBar(bool erbx,bool erby)
+{
+ErrX = erbx; ErrY = erby;
+if(mGFD == NULL) {ErrX = ErrY = false; return;}
+if(!mGFD->HasXErrors()) ErrX = false;
+}
+
+/* --Methode-- */
+void PIGenFitDat::UpdateLimits()
+{
+if(!mGFD) return;
+if(mGFD->NData()<=0) return;
+if(VarX<0) return;
+double xmin=9.e19, xmax=-9.e19, ymin=9.e19, ymax=-9.e19;
+mGFD->GetMnMx(10*VarX+2,xmin,xmax);
+mGFD->GetMnMx(0,ymin, ymax);
+if(xmax<=xmin) xmax = xmin+1.;
+if(ymax<=ymin) ymax = ymin+1.;
+PIAxes::ReSizeMinMax(isLogScaleX(),xmin,xmax);
+PIAxes::ReSizeMinMax(isLogScaleY(),ymin,ymax);
+SetLimits(xmin,xmax,ymin,ymax);
+SetAxesFlags(kBoxAxes | kExtTicks | kLabels);
+}
+
+/* --Methode-- */
+void PIGenFitDat::Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax)
+{
+if (!mGFD) return;
+if(mGFD->NData()<=0) return;
+if(VarX<0) return;
+// On plotte les barre d'erreurs ligne demandee explicitement
+if(GetGraphicAtt().GetLineAtt()!=PI_NotDefLineAtt) SelectErrBar(true,true);
+double xp,yp,er;
+for (int i=0; i<mGFD->NData(); i++) {
+  xp = mGFD->Absc(VarX,i);
+  yp = mGFD->Val(i);
+  if(xp<xmin || xp>xmax || yp<ymin || yp>ymax)  continue;
+  if(ErrX) {
+    er = mGFD->EAbsc(VarX,i);
+    if(er>0.) g->DrawLine(xp-er,yp,xp+er,yp);
+  }
+  if(ErrY) {
+    er = mGFD->EVal(i);
+    if(er>0.) g->DrawLine(xp,yp-er,xp,yp+er);
+  }
+  g->DrawMarker(xp, yp); 
+}
+return;
+}
Index: /tags/V_Dec2002/SophyaPI/PIext/pigfd1.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/pigfd1.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/pigfd1.h	(revision 2309)
@@ -0,0 +1,28 @@
+// Cette classe est maintenant obsolete: generaldata <==> ntuple pour le dessin
+
+#ifndef PIGFD1_H
+#define PIGFD1_H
+
+#include "generaldata.h"
+#include "pidrawer.h"
+
+class PIGenFitDat : public PIDrawer {
+public:
+                     PIGenFitDat(GeneralFitData* gfd, bool ad);
+  virtual           ~PIGenFitDat();
+  
+  virtual void       Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax);
+  virtual void       UpdateLimits();
+  
+          void       SelectX(int varx);
+          void       SelectErrBar(bool erbx,bool erby);
+       
+protected:
+  GeneralFitData* mGFD;
+  bool mAdDO;
+  int VarX;          // numero de variable X ds le GeneralFitData
+  bool ErrX,ErrY;    // Erreur en X et Y ?
+};
+
+#endif
+
Index: /tags/V_Dec2002/SophyaPI/PIext/pigfd2.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/pigfd2.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/pigfd2.cc	(revision 2309)
@@ -0,0 +1,107 @@
+// Cette classe est maintenant obsolete: generaldata <==> ntuple pour le dessin
+
+#include <stdio.h>
+#include "pigfd2.h"
+
+/* --Methode-- */
+PIGenFitDat3D::PIGenFitDat3D(GeneralFitData* gfd, bool ad)
+: PIDrawer3D(), mGFD(gfd), mAdDO(ad)
+, VarX(0), VarY(1), ErrX(false), ErrY(false), ErrZ(false)
+{
+SelectXY(0,1);
+SelectErrBar(false,false,false);
+}
+
+PIGenFitDat3D::~PIGenFitDat3D()
+{
+if(mAdDO && mGFD)  delete mGFD;
+}
+
+/* --Methode-- */
+void  PIGenFitDat3D::SelectXY(int varx,int vary)
+{
+VarX = VarY = -1;
+if(mGFD == NULL) return;
+if(varx<0 || varx>=mGFD->NVar()) return;
+if(vary<0 || vary>=mGFD->NVar()) return;
+VarX = varx; VarY = vary;
+}
+
+/* --Methode-- */
+void  PIGenFitDat3D::SelectErrBar(bool erbx,bool erby,bool erbz)
+{
+ErrX = erbx; ErrY = erby; ErrZ = erbz;
+if(mGFD == NULL) {ErrX = ErrY = ErrZ = false; return;}
+if(!mGFD->HasXErrors()) ErrX = ErrY = false;
+}
+
+/* --Methode-- */
+void PIGenFitDat3D::UpdateLimits()
+{
+if(!mGFD) return;
+if(mGFD->NData()<=0) return;
+if(VarX<0 || VarY<0) return;
+double xmin=9.e19, xmax=-9.e19, ymin=9.e19, ymax=-9.e19, zmin=9.e19, zmax=-9.e19;
+mGFD->GetMnMx(10*VarX+2,xmin,xmax);
+mGFD->GetMnMx(10*VarY+2,ymin,ymax);
+mGFD->GetMnMx(0,zmin, zmax);
+if(xmax<=xmin) xmax = xmin+1.;
+if(ymax<=ymin) ymax = ymin+1.;
+if(zmax<=zmin) zmax = zmin+1.;
+// Voir commentaires pintuple3d.cc
+double D = xmax-xmin;
+if (D < (ymax-ymin))  D = ymax-ymin;
+D *= 1.4;
+Set3DView((xmin+xmax)/2., (ymin+ymax)/2, (zmin+zmax)/2., 
+          (xmin+xmax)/2.+D , (ymin+ymax)/2.-2.5*D , zmin+(zmax-zmin)*0.85, 0.25, 0.25);  
+
+x3Min = xmin;    x3Max = xmax;
+y3Min = ymin;    y3Max = ymax;
+z3Min = zmin;    z3Max = zmax;
+
+}
+
+/* --Methode-- */
+void PIGenFitDat3D::Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax)
+{
+// On trace les axes - En attendant de faire mieux - Reza 8/12/98
+if (axesFlags != kAxesNone)  DrawAxes(g);
+
+if (!mGFD) return;
+if(mGFD->NData()<=0) return;
+if(VarX<0 || VarY<0) return;
+
+// On plotte les barre d'erreurs ligne demandee explicitement
+if(GetGraphicAtt().GetLineAtt()!=PI_NotDefLineAtt) SelectErrBar(true,true,true);
+
+#if defined(CC_HAS_RTTI_SUPPORT)
+PIGraphic3D* g3 = dynamic_cast<PIGraphic3D*>(g);
+#else
+PIGraphic3D* g3 = (PIGraphic3D*)(g);
+#endif
+
+if (GetGraphicAtt().GetLineAtt() == PI_NotDefLineAtt)  g3->SelLine(PI_ThinLine);
+
+double xp,yp,zp,er;
+for (int i=0; i<mGFD->NData(); i++) {
+  xp = mGFD->Absc(VarX,i);
+  yp = mGFD->Absc(VarY,i);
+  zp = mGFD->Val(i);
+  if(ErrX) {
+    er = mGFD->EAbsc(VarX,i);
+    if(er>0.) g3->DrawLine3D(xp-er,yp,zp,xp+er,yp,zp);
+  }
+  if(ErrY) {
+    er = mGFD->EAbsc(VarY,i);
+    g3->DrawLine3D(xp,yp-er,zp,xp,yp+er,zp);
+  }
+  if(ErrZ) {
+    er = mGFD->EVal(i);
+    g3->DrawLine3D(xp,yp,zp-er,xp,yp,zp+er);
+  }
+  g3->DrawMarker3D(xp,yp,zp); 
+}
+
+return;
+}
+
Index: /tags/V_Dec2002/SophyaPI/PIext/pigfd2.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/pigfd2.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/pigfd2.h	(revision 2309)
@@ -0,0 +1,29 @@
+// Cette classe est maintenant obsolete: generaldata <==> ntuple pour le dessin
+
+#ifndef PIGFD2_H
+#define PIGFD2_H
+
+#include "generaldata.h"
+#include "pi3ddrw.h"
+
+class PIGenFitDat3D : public PIDrawer3D {
+public:
+                     PIGenFitDat3D(GeneralFitData* gfd, bool ad);
+  virtual           ~PIGenFitDat3D();
+  
+  virtual void       Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax);
+  virtual void       UpdateLimits();
+  
+          void       SelectXY(int varx,int vary);
+          void       SelectErrBar(bool erbx,bool erby,bool erbz);
+
+       
+protected:
+  GeneralFitData* mGFD;
+  bool mAdDO;
+  int VarX,VarY;         // numero de variable X,Y ds le GeneralFitData
+  bool ErrX,ErrY,ErrZ;   // Erreur en X,Y et Z?
+};
+
+#endif
+
Index: /tags/V_Dec2002/SophyaPI/PIext/pihisto.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/pihisto.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/pihisto.cc	(revision 2309)
@@ -0,0 +1,244 @@
+// Classe traceur d histogramme                 96-99
+// CEA-DAPNIA      LAL-IN2P3/CNRS
+
+#include <stdio.h>
+#include <typeinfo>
+
+#include "pihisto.h"
+#include "hisprof.h"
+
+//++
+// Class	PIHisto
+// Lib		PIext
+// include	pihisto.h
+//
+//	Classe traceur d'objet histogramme (classe *Histo*)
+//--
+//++
+// Links	Parents
+// PIDrawer
+//--
+//++
+// Titre	Constructeur, méthodes
+//--
+//++
+// PIHisto(Histo* histo, bool ad=false)
+//	Constructeur. Si "ad == true", l'objet "histo" est détruit par 
+//	le destructeur de l'objet "PIHisto"
+//	Note : "histo" doit être créé par new
+//
+// void  SetStats(bool fg=true) 
+//	Active/ désactive l'indication des statistiques d'histogramme
+//--
+
+
+PIHisto::PIHisto(Histo* histo, bool ad)
+: PIDrawer(), mHisto(histo)
+{
+  mAdDO = ad;     // Flag pour suppression automatique de mHisto
+  SetStats();
+  SetError();
+  SetName("HistoDrw");
+}
+
+PIHisto::~PIHisto()
+{
+  if(mAdDO) delete mHisto;
+}
+
+void
+PIHisto::UpdateLimits()
+{
+  if (!mHisto)  return;
+  float hmin = mHisto->VMin();
+  float hmax = mHisto->VMax()+0.2*(mHisto->VMax()-mHisto->VMin());
+  // si HBProf min,max calcules en tenant compte des erreurs
+  if( typeid(*mHisto) == typeid(HProf) ) {
+    float v1,v2;
+    for (int i=1; i<mHisto->NBins(); i++) {
+      v1 = (*mHisto)(i) - mHisto->Error(i);
+      v2 = (*mHisto)(i) + mHisto->Error(i);
+      if(v1<hmin) hmin = v1;
+      if(v2>hmax) hmax = v2;
+    }
+    v1 = 0.1*(hmax-hmin);
+    hmin -= v1;   hmax += v1;
+  }
+  if(hmax<=hmin) hmax = hmin+1.;
+  SetLimits(mHisto->XMin(), mHisto->XMax(), hmin, hmax);
+}
+
+void
+PIHisto::Draw(PIGraphicUC* g, double /*xmin*/, double /*ymin*/, double /*xmax*/, double /*ymax*/)
+{
+  if (axesFlags != kAxesNone) DrawAxes(g);
+
+  if (!mHisto)  return;
+ 
+  if( typeid(*mHisto)==typeid(HProf) ) mHisto->UpdateHisto();
+
+  bool drawmarker=false, drawerr=false, oktrace=false;
+  // Tracer les marqueurs si demande ou si HProf
+  if( (GetGraphicAtt().GetMarker() != PI_NotDefMarker) ||  
+      (typeid(*mHisto) == typeid(HProf)) ) drawmarker = true;
+  if(error==0) {  // Gestion automatique des erreurs
+    // Tracer les erreurs si HProf
+    if( typeid(*mHisto)==typeid(HProf) ) drawerr=true;
+    // Trace les erreurs si marqueurs demandes
+    if(drawmarker) drawerr=true;
+  } else if(error>0) drawerr=true;
+
+  // Trace des marqeurs
+  if(drawmarker) {
+    double x1,y1; oktrace = true;
+    for(int i=0; i<mHisto->NBins(); i++) {
+      x1 = mHisto->BinCenter(i);
+      y1 = (*mHisto)(i);
+      g->DrawMarker(x1,y1);
+    }
+  }
+
+  // Trace des erreurs
+  // Si Marqeurs definis OU HProf => marqueurs+Erreurs si il y en a
+  if(drawerr) {
+    if(GetGraphicAtt().GetLineAtt()==PI_NotDefLineAtt) g->SelLine(PI_ThinLine);
+    double x1,x2,y1,y2;  oktrace = true;
+    double bw = mHisto->BinWidth();
+    for(int i=0; i<mHisto->NBins(); i++) {
+      if(mHisto->Error(i)>0.) {
+        // barres d'erreur verticales
+        x1 = x2 = mHisto->BinCenter(i);
+        y1 = (*mHisto)(i) - mHisto->Error(i);
+        y2 = (*mHisto)(i) + mHisto->Error(i);
+        g->DrawLine(x1,y1, x1, y2);
+        // limites de barres d'erreurs (horizontales)
+        x1 -= bw/3.;  x2 += bw/3.;
+        g->DrawLine(x1,y1, x2, y1);
+        g->DrawLine(x1,y2, x2, y2);
+      }
+    }
+  }
+
+  // Trace de la ligne continue
+  if(GetGraphicAtt().GetLineAtt() != PI_NotDefLineAtt) {
+    double x1,y1, x2, y2; oktrace = true;
+    x1 = mHisto->BinLowEdge(0);
+    y1 = 0;
+    for(int i=0; i<mHisto->NBins(); i++) {
+      x2 = x1;
+      y2 = (*mHisto)(i);
+      g->DrawLine(x1,y1, x2, y2);
+      y1 = y2;
+      x2 = mHisto->BinHighEdge(i);
+      g->DrawLine(x1,y1, x2, y2);
+      x1 = x2;
+    }
+    y2 = 0; g->DrawLine(x1,y1, x2, y2);
+  }
+
+  // Si rien n'a ete trace
+  if( !oktrace ) {
+    for(int i=0; i<mHisto->NBins(); i++) {
+      double left   = mHisto->BinLowEdge(i);
+      double width  = mHisto->BinWidth();
+      double bottom = 0;
+      double height = (*mHisto)(i);
+      g->DrawFBox(left,bottom,width,height);
+      g->DrawLine(left, bottom, left, bottom+height); // Au moins une ligne...
+    }
+  }
+
+  // Trace/Ecriture des statistiques
+  // A faire a la fin - DrawStats change l'attribut de ligne 
+  if(stats) DrawStats(g);
+}
+
+int
+PIHisto::DecodeOptionString(vector<string> & opt, bool rmdecopt)
+{
+  int optsz1 = opt.size();
+  if(optsz1<1) return(0); 
+  int ndec1 = PIDrawer::DecodeOptionString(opt, rmdecopt);
+  if(optsz1-ndec1<1) return(ndec1);  // si tout a ete decode
+
+  vector<string> udopt;  // On gardera ici les options non decodees
+  unsigned int k = 0;
+  int ndec = opt.size();
+  for( k=0; k<opt.size(); k++ ) {
+    string opts = opt[k];
+    if(opts=="sta" || opts=="stat" || opts=="stats") SetStats(true);
+    else if(  opts=="nsta"   || opts=="nstat"
+           || opts=="nostat" || opts=="nostats") SetStats(false);
+    else if(opts=="err")      SetError(1);
+    else if(opts=="noerr")    SetError(-1);
+    else if(opts=="autoerr")  SetError(0);
+    else {
+      ndec--;
+      // S'il faut supprimer les options decodees
+      if (rmdecopt)  udopt.push_back(opts);
+    }
+  }
+  // S'il faut supprimer les options decodees, on remplace l'argument opt
+  // par le vecteur des options non decodees.
+  if (rmdecopt)  opt = udopt;
+  return(ndec+ndec1);
+}
+
+void
+PIHisto::GetOptionsHelpInfo(string& info)
+{
+// On recupere d'abord la chaine info de la classe de base
+PIDrawer::GetOptionsHelpInfo(info);
+info += " ---- PIHisto options help info : \n" ;
+info += "- sta,stat,stats:            activate   statistic display\n";
+info += "  nsta,nstat,nostat,nostats: deactivate statistic display\n";
+info += "- err / nerr : draw, do not draw error bars\n";
+info += "  autoerr : draw error bars if Marker drawing requested OR Profile histo\n";
+return;
+}
+
+void
+PIHisto::DrawStats(PIGraphicUC* g)
+{
+  if (!mHisto) return;
+  //  if (mLAtt == PI_NotDefLineAtt)  g->SelLine(PI_ThinLine);
+  g->SelLine(PI_ThinLine);
+  g->SelFontSz((YMax() - YMin())/30);
+
+  // La hauteur de la cellule
+  PIGrCoord a, d;
+  double cH = (double)g->GetFontHeight(a,d);
+  double cellHeight = 3.6 * cH;
+
+  // Les labels et leurs longueurs -> largeur de la cellule
+  char *label, label1[64], label2[64], label3[64];
+  sprintf(label1, "N= %-g",mHisto->NData());
+  sprintf(label2, "m= %-g",mHisto->Mean());
+  sprintf(label3, "s= %-g",mHisto->Sigma());
+  label = label1;
+  if(strlen(label)<strlen(label2)) label = label2;
+  if(strlen(label)<strlen(label3)) label = label3;
+  double cellWidth =  1.1 * (double)g->CalcStringWidth(label);
+
+  double xu, yu, cw;
+  // Les limites du cadre
+  xu = g->DeltaUCX(XMax(), -cellWidth);
+  yu = g->DeltaUCY(YMax(), -cellHeight);
+  g->DrawLine(xu,YMax(),xu,yu);
+  g->DrawLine(xu,yu,XMax(),yu);
+
+  // L'ecriture des labels (attention aux inversions possibles des axes!)
+  cw = (g->isAxeXDirRtoL()) ? -0.05*cellWidth : -0.95*cellWidth;
+  xu = g->DeltaUCX(XMax(),cw);
+
+  cw = (g->isAxeYDirUpDown()) ? -0.15*cH : -1.15*cH;
+  yu = g->DeltaUCY(YMax(),cw);
+  g->DrawString(xu, yu,label1);
+    cw +=  -1.15*cH;
+    yu = g->DeltaUCY(YMax(),cw);
+    g->DrawString(xu, yu,label2);
+      cw +=  -1.15*cH;
+      yu = g->DeltaUCY(YMax(),cw);
+      g->DrawString(xu, yu,label3);
+                       
+}
Index: /tags/V_Dec2002/SophyaPI/PIext/pihisto.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/pihisto.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/pihisto.h	(revision 2309)
@@ -0,0 +1,33 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe traceur d histogramme                 96-99
+// CEA-DAPNIA      LAL-IN2P3/CNRS
+#ifndef PIHISTO_H
+#define PIHISTO_H
+
+#include "histos.h"
+#include "pidrawer.h"
+
+class PIHisto : public PIDrawer {
+public:
+                     PIHisto(Histo* histo, bool ad=false);
+  virtual           ~PIHisto();
+  virtual void       Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax);
+  virtual void       UpdateLimits();
+  inline  void       SetStats(bool fg=true) {stats=fg;}
+  // fg=-1 pas de barre d'erreur, 1=barres d'erreurs,
+  // 0=barres d'erreurs automatiques: trace si HProf ou markeur demande
+  inline  void       SetError(unsigned short fg=0) {error=fg;}
+  inline  Histo*     Histogram() {return(mHisto);}
+
+//   Methode de decodage des options
+  virtual int        DecodeOptionString(vector<string> & opt, bool rmdecopt=true);
+  virtual void       GetOptionsHelpInfo(string& info);
+
+protected:
+  virtual void       DrawStats(PIGraphicUC* g);
+  Histo* mHisto;
+  bool mAdDO;
+  bool stats,error;
+};
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/pihisto2d.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/pihisto2d.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/pihisto2d.cc	(revision 2309)
@@ -0,0 +1,941 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <pisysdep.h>
+#include PIAPP_H
+#include "pihisto2d.h"
+#include "nbrandom.h"
+
+static int dbg = 0;
+
+//++
+// Class	PIHisto2D
+// Lib		PIext
+// include	pihisto2d.h
+//
+//	Classes de dessin des histogrammes a 2 dimensions pour 
+//	objets *Histo2D* 
+//--
+
+//++
+// Links	Parents
+// PIDrawer
+//--
+
+//++
+// Titre	Constructeur, méthodes
+//--
+
+//++
+PIHisto2D::PIHisto2D(Histo2D* histo, bool ad)
+//
+//	Createur d'une classe de dessin pour l'histogramme 2D histo.
+//--
+: PIDrawer(), mHisto(histo), mAdDO(ad), mLogScale(10.), mFPoints(0.5)
+{
+// mAdDO : Flag pour suppression automatique de mHisto
+// Attention: mFPoints n'est initialise que si on display par nuages de points
+//            mLogScale n'est initialise que si on utilise une echelle log
+UseScale();
+UseColors();
+UseDisplay();
+UseDyn();
+UseFrac();
+SetStats();
+SetName("Histo2DDrw"); 
+// PIHisto2D has specific control tools
+mFgSpecContWind = true;
+}
+
+//++
+PIHisto2D::~PIHisto2D()
+//
+//	Destructeur.
+//--
+{
+// La fonction virtuelle DeactivateControlWindow() doit etre appele
+// a ce niveau - En effet au niveau du destructeur de base, il 
+// semble pointer sur la fonction de la classe de base
+//                    Reza - Octobre 2002 
+// Desactivation totale de la fenetre de controle specialise 
+// ---> parametre d'appel PIBaseWdgGen* wdg=NULL
+DeactivateControlWindow(NULL);
+if(mAdDO && mHisto!=NULL) delete mHisto;
+}
+
+//++
+void PIHisto2D::UseColors(bool fg,CMapId cmap,bool revcmap)
+//
+//	Choix de la couleur si fg=true avec la color map cmap.
+//	(pour la couleur cmap cf picmap.h).
+//      Independamment du choix du display, la dynamique est
+//      codee sur la color map donnant ainsi une double
+//      information. Par exemple, carres de tailles variables
+//      en couleur. Cette option est incontournable dans le cas
+//      d'un display par des carres de taille fixe.
+//      revcmap doit etre mis a "true" si on veut avoir une color map
+//      inversee.
+//| -**- gestion dans H2WinArg par menu deroulant Black&White etc...
+//--
+{
+mFgCol = fg; mCmap = cmap; mRevCmap = revcmap;
+}
+
+//++
+void PIHisto2D::UseScale(unsigned short type,float logscale)
+//
+//	Pour changer les echelles (lineaire ou logarithmique)
+//| Type = 0 : echelle lineaire
+//|      = 1 : echelle log10
+//| -**- Explication du codage en type=0 (lineaire) :
+//|   1. [hmin,hmax] -> [0,1]
+//|           h      ->   f = (h-hmin)/(hmax-hmin)
+//|   2. codage de f=[0,1] sur la dynamique du display choisi
+//| -**- Explication du codage en type=1 (logarithmique base 10) :
+//|   1. map lineaire entre 0 et 1:
+//|      [hmin,hmax] -> [0,1]
+//|           h      ->   f = (h-hmin)/(hmax-hmin)
+//|   2. transformation logarithmique de base 10 :
+//|      [0,1] -> [0,1]
+//|        f   -> lf = log10(1.+f*(logscale-1))/log10(logscale)
+//|   3. codage de lf=[0,1] sur la dynamique du display choisi
+//| -**- gestion dans H2WinArg par menu deroulant Lineaire/Log10
+//|         et "logscale" par saisie de valeur dans champ LogScal
+//--
+{
+if(type==0)       mTypScal=0;
+else if(type==1) {mTypScal=1; if(logscale>1.) mLogScale=logscale;}
+else              mTypScal=0;
+}
+
+//++
+void PIHisto2D::UseDisplay(unsigned short type,float fnpt)
+//
+//	Type de Display
+//| Type = 0 : carres de tailles variables
+//| Type = 1 : nuages de points
+//|            Le nombre de points a utiliser est fnpt*N
+//|            ou N est le nombre de pixels ecran contenu
+//|            dans un bin de l'histogramme.
+//| Type = 2 : code a la "hbook2" " .+123...9AB...YZ*"
+//|            (cf detail PIHisto2D::HPrint2)
+//| Type = 3 : carres de taille fixe (couleur).
+//| -**- gestion dans H2WinArg par menu deroulant Carres_Var etc...
+//|         et "fnpt" par saisie de valeur dans champ PerPt
+//--
+{
+if(type==0) mTypDisp = 0;
+else if(type==1) {
+  mTypDisp = 1;
+  if(fnpt<0.) mFPoints = 0.;
+    else if(fnpt>1.) mFPoints = 1.;
+      else mFPoints = fnpt;
+}
+else if(type==2) mTypDisp = 2;
+else if(type==3) mTypDisp = 3;
+else             mTypDisp = 1;
+}
+
+//++
+void PIHisto2D::UseDyn(float hmin,float hmax)
+//
+//	Gestion de la dynamique a representer:
+//|  La dynamique va etre transformee de [hmin,hmax] vers [0,1] selon
+//|  [hmin,hmax] -> [0,1]
+//|       h      ->   f = (h-hmin)/(hmax-hmin)
+//|  Par la suite, selon ce qui est demande, f va coder le display 
+//|  ou etre transforme en une autre echelle [0,1] (ex: echelle log10).
+//|  Si hmax<=hmin, ils sont forces a la dynamique totale de l'histo2D.
+//| -**- gestion dans H2WinArg par saisie de valeurs dans champ Dyn
+//--
+{
+if(mHisto)
+  if(hmin>=hmax) {hmin = mHisto->VMin(); hmax = mHisto->VMax();}
+if(hmin>=hmax) hmax = hmin+1.;
+mHMin = hmin; mHMax = hmax;
+}
+
+//++
+void PIHisto2D::UseFrac(float frmin,float frmax)
+//
+//	Pour definir la fraction de la dynamique a dessiner:
+//| Selon le type de display (f=[0,1] cf PIHisto2D::UseDyn),
+//|  - on ne dessine rien si f <= frmin dans les cas de display avec
+//|    des nuages de points ou des carres de tailles variables.
+//|    Pour un display "a la hbook2" on force frmin = 0.
+//|  - frmax n'est utilise que pour la representation avec
+//|    des carres de tailles variables: c'est la taille
+//|    maximum que peut avoir le carre exprimee en unite
+//|    de la taille du bin (ex: si frmax=0.8 le carre
+//|    le + grand qui pourra etre dessine dans un bin
+//|    aura une taille egale a 0.8*(taille du bin)).
+//| -**- gestion dans H2WinArg par saisie de valeurs dans champ Frac
+//--
+{
+if(frmin<0.  || frmin>=1.) frmin = 0.;
+if(frmax<=0. || frmax>1. ) frmax = 1.;
+if(frmin>=frmax) {frmin=0.1; frmax=0.9;}
+mFracMin = frmin; mFracMax = frmax;
+}
+
+//++
+void PIHisto2D::Print(int lp)
+//
+//	Print de l'etat des options du display.
+//--
+{
+printf("PIHisto2D::Print FgCol=%d Cmap=%d (Rev=%d) TypScal=%d TypDisp=%d (FPoints=%g)\n"
+      ,(int)mFgCol,(int)mCmap,(int)mRevCmap,mTypScal,mTypDisp,mFPoints);
+printf("                 Dyn=%g,%g Frac=%g,%g LogSc=%g H=%p\n"
+      ,mHMin,mHMax,mFracMin,mFracMax,mLogScale,mHisto);
+if(lp>=1) mHisto->PrintStatus();
+fflush(stdout);
+}
+
+//++
+void PIHisto2D::UpdateLimits()
+//
+//	Definition des tailles graphiques en fonction
+//	des caracteristiques de l'histogramme a dessiner.
+//--
+{
+ if(!mHisto) return;
+ SetLimits(mHisto->XMin(), mHisto->XMax(), mHisto->YMin() , mHisto->YMax());
+}
+
+//++
+void PIHisto2D::ShowControlWindow(PIBaseWdgGen* wdg)
+//
+//	Affichage de la fenetre de controle H2WinArg
+//--
+{
+  H2WinArg::SetCurrentPIHisto2D(this);
+  H2WinArg::ShowPIHisto2DTools(wdg);
+}
+
+//++
+void PIHisto2D::DeactivateControlWindow(PIBaseWdgGen* wdg)
+//
+//	Desactivation de la fenetre de controle specialisee
+//--
+{
+  if (H2WinArg::GetCurrentPIHisto2D() == this) { 
+    // si wdg != NULL, c'est un Detach (Drawer detache du PIBaseWdg
+    // si wdg == NULL, c'est un delete du PIHisto2D (du PIDrawer)
+    if ((wdg == NULL) || (H2WinArg::GetCurrentBaseWdg() == wdg)) {
+      H2WinArg::SetCurrentBaseWdg(NULL);
+      H2WinArg::SetCurrentPIHisto2D(NULL);
+      H2WinArg::HidePIHisto2DTools();
+    }
+  }
+  PIDrawer::DeactivateControlWindow(wdg);
+  return;
+}
+
+//++
+void PIHisto2D::Draw(PIGraphicUC* g,double xmin,double ymin,double xmax,double ymax)
+//
+//	Dessin de l'histogramme.
+//| -**- Code de dessin selon choix des options:
+//|  (detail voir UseColors UseScale UseDisplay UseDyn UseFrac)
+//|  - [hmin,hmax] -> f=[0,1]
+//|    (Choix hmin,hmax champ Dyn de H2WinArg)
+//|  - Eventuellement ech Log -> re-codage log10 entre f=[0,1]
+//|    (Choix menu deroulant et champ LogScal de H2WinArg)
+//|  - Restriction de f=[0,1] -> f=[Frac(min),Frac(max)]
+//|    (Choix champ Frac de H2WinArg)
+//| -**- Puis selon display:
+//|  0 carres variables, menu "Carres Var." de H2WinArg:
+//|      if(f>Frac(min)) taille carre = f * Frac(max) * taille_du_bin
+//|  1 nuage de points, menu "....." et champ PerPt de H2WinArg:
+//|      if(f>Frac(min)) npoints = f * PerPt * npoints_ecran_dans_bin
+//|  2 code hbook2, menu ".12..Z*" de H2WinArg:
+//|      if(f>0) map de f=]0,1] dans ".+...Z*"
+//|  3 carres pleins, menu "Carres Pleins" et couleurs de H2WinArg):
+//|      couleur = lut[ f * nombre_d_entree_dans_la_lut ]
+//--
+{
+if (axesFlags != kAxesNone) DrawAxes(g);
+
+if(!mHisto) return;
+// Caracteristiques histogramme
+double dx = mHisto->WBinX(),dy = mHisto->WBinY();
+double p1dx,p1dy;
+g->DGrC2UC(1.,1.,p1dx,p1dy);
+
+// Gamme a representer entre [0,1] mais >=fracmin et scale fracmax
+float fracmin=FMin(), fracmax=FMax();
+float llscale = (float) log10((double)LogScale());
+
+// gestion Couleurs.
+PIColors fgcoul = GetGraphicAtt().GetFgColor();
+PIColors bgcoul = GetGraphicAtt().GetBgColor();
+PIColorMap* cmap=NULL;
+int ncol = 0;
+if (mFgCol) {
+  cmap = new PIColorMap(mCmap);
+  cmap->ReverseColorIndex(mRevCmap);
+  ncol = cmap->NCol();
+  if(mTypDisp==3) fracmin=-1.;
+}
+
+// gestion epaisseur de ligne
+PILineAtt LineAtt = GetGraphicAtt().GetLineAtt();
+if(LineAtt == PI_NotDefLineAtt) GetGraphicAtt().SetLineAtt(PI_ThinLine);
+
+// gestion Markers ou plot avec des points.
+PIMarker Mk = GetGraphicAtt().GetMarker();
+int MkSz = GetGraphicAtt().GetMarkerSize();
+int npt = 1;
+if(mTypDisp==1) {
+  g->SelMarker(1,PI_DotMarker);
+  npt = (int) ((float)NPixBin(g)*FPoints()); if(npt<=0) npt = 2;
+}
+
+// gestion Font.
+PIFontAtt FontAtt = GetGraphicAtt().GetFontAtt();
+int FontSize = GetGraphicAtt().GetFontSzPt();
+if(mTypDisp==2) {
+  double dxg,dyg,dg;
+  g->DUC2GrC(dx,dy,dxg,dyg);
+  dg =(dxg<dyg) ? dxg : dyg;
+  int npix = (int) (dg*0.9); if(npix<8) npix = 8;
+  g->SelFontSzPt(npix,FontAtt);
+  fracmin = 0;
+}
+
+// Plot de l'histogramme
+for(int i=0; i<mHisto->NBinX(); i++)
+  for(int j=0; j<mHisto->NBinY(); j++) {
+
+  r_8 left0,bottom0;
+  mHisto->BinLowEdge(i,j,left0,bottom0);
+
+  // Gestion de la dynamique a dessiner
+  float frac = ((*mHisto)(i,j)-HMin())/(HMax()-HMin());
+  if(frac<0.) continue;
+  if(mTypScal==1) {              // echelle log10
+    frac = log10(1.+frac*(LogScale()-1.))/llscale;
+    if(frac<0.) continue;
+  }
+  if(frac<=fracmin) continue;
+  if(frac>1.) frac = 1.;
+  float fracred = frac * fracmax;
+
+  // Gestion de la couleur
+  int icol = 0;
+  if (cmap) {
+    icol = int( (float) ncol*frac );
+    if(icol>=ncol) icol = ncol-1; else if(icol<0) icol=0;
+    g->SelForeground(*cmap,icol);
+  }
+
+// Pour ne pas dessiner en dehors des axes 
+  if ( (left0+dx/2. < xmin) || (left0+dx/2. > xmax) || 
+         (bottom0+dy/2. < ymin) || (bottom0+dy/2. > ymax) ) continue;
+
+  // Dessin proprement dit selon le choix graphique.
+  if(mTypDisp==0) {
+    //..... carres de tailles variables
+    double left   = left0   + 0.5*(1.-fracred)*dx, width  = fracred*dx;
+    double bottom = bottom0 + 0.5*(1.-fracred)*dy, height = fracred*dy;
+    if (cmap) g->DrawFBox(left,bottom,width,height);
+    else      g->DrawBox(left,bottom,width,height);
+  } else if(mTypDisp==1) {
+    //..... nuage de points .....
+    int ipt  = int( (float) npt *frac );
+    for(int k=0;k<ipt;k++) {
+      double x = left0 + frand01()*dx;
+      double y = bottom0 + frand01()*dy;
+      g->DrawMarker(x,y);
+    }
+  } else if(mTypDisp==2) {
+    //..... type hbook2/hprint .+23-Z*
+    char c[2];
+    c[0] = HPrint2(frac); c[1]='\0';
+    double x = left0 + dx/2.;
+    double y = bottom0 + dy/2.;
+    g->DrawString(x,y,c,PI_HorizontalCenter|PI_VerticalCenter);
+  } else if(mTypDisp==3) {
+    //..... carres de tailles fixes (avec gestion de continuite)
+    if (cmap) g->DrawFBox(left0,bottom0,dx+p1dx,dy+p1dy);
+    else      g->DrawBox(left0,bottom0,dx+p1dx,dy+p1dy);
+  }
+
+}
+
+// Remise dans les conditions ulterieures pour la suite du graphique.
+GetGraphicAtt().SetMarkerAtt(MkSz,Mk);
+GetGraphicAtt().SetColAtt(fgcoul,bgcoul);
+g->SelFontSzPt(FontSize,FontAtt);
+GetGraphicAtt().SetLineAtt(LineAtt);
+if (cmap) delete cmap;
+
+// Fin du dessin, ecriture de la statistique.
+if(stats) DrawStats(g);
+}
+
+//++
+void PIHisto2D::GetClickInfo(string& info,double x,double y,double x0,double y0,bool fgdiff)
+//
+//	Info specifique du drawer pour la position x,y
+//--
+{
+Histo2D* h = Histogram();
+if(h == NULL) return;
+
+int i,j;
+h->FindBin(x,y,i,j);
+if(i>=0 && i<h->NBinX() && j>=0 && j<h->NBinY()) {
+  char str[64];
+  if(fgdiff) {
+    int i0,j0;
+    h->FindBin(x0,y0,i0,j0);
+    if(i0>=0 && i0<h->NBinX() && j0>=0 && j0<h->NBinY()) {
+      sprintf(str," DV=%g",(*h)(i,j)-(*h)(i0,j0));
+      info += str;
+    } else {
+      info += " DV=?";
+    }
+  }
+  sprintf(str," V=%g",(*h)(i,j));
+  info += str;
+} else {
+  info += " V=?";
+}
+
+return;
+}
+
+//++
+void PIHisto2D::DrawStats(PIGraphicUC* g)
+//
+//	Dessin des informations statistiques de l'histogramme.
+//--
+{
+  if (!mHisto) return;
+  if (GetGraphicAtt().GetLineAtt() == PI_NotDefLineAtt)  g->SelLine(PI_ThinLine);
+  g->SelFontSz((YMax() - YMin())/30);
+
+  // La hauteur de la cellule
+  PIGrCoord a, d;
+  double cH = (double)g->GetFontHeight(a,d);
+  double cellHeight = 1.2 * cH;
+
+  // Les labels et leurs longueurs -> largeur de la cellule
+  char label[64];
+  sprintf(label,"N= %-g", mHisto->NData());
+  double cellWidth =  1.1 * (double)g->CalcStringWidth(label);
+
+  double xu, yu, cw;
+  // Les limites du cadre
+  xu = g->DeltaUCX(XMax(), -cellWidth);
+  yu = g->DeltaUCY(YMax(), -cellHeight);
+  g->DrawLine(xu,YMax(),xu,yu);
+  g->DrawLine(xu,yu,XMax(),yu);
+
+  // L'ecriture des labels
+  cw = (g->isAxeXDirRtoL()) ? -0.05*cellWidth : -0.95*cellWidth;
+  xu = g->DeltaUCX(XMax(),cw);
+  cw = (g->isAxeYDirUpDown()) ? -0.1*cH : -1.1*cH;
+  yu = g->DeltaUCY(YMax(),cw);
+  g->DrawString(xu,yu,label);
+
+  //  printf("H[%d,%d] Dynamique: [%g,%g] Frac [%g,%g]\n"
+  //        ,mHisto->NBinX(),mHisto->NBinY(),HMin(),HMax(),FMin(),FMax());
+}
+
+//++
+char PIHisto2D::HPrint2(float f)
+//
+//	Codage des valeurs en caracteres (fct privee).
+//| f entre [0,1] mappee entre valeur=[0,37]
+//| si <0 alors =0, si >1 alors 1
+//| Display 4   ==> 4<=valeur<5
+//|         C   ==> 12<=valeur<13
+//|             ==> valeur<=0
+//|         *   ==> valeur>=1
+//|         .   ==> 0<valeur<1
+//|------------------------------------------
+//|             1         2         3
+//|   01234567890123456789012345678901234567
+//|   .+23456789ABCDEFGHIJKLMNOPQRSTUVWXYZ* 
+//|------------------------------------------
+//--
+{
+char str[39] = " .+23456789ABCDEFGHIJKLMNOPQRSTUVWXYZ*";
+int i;
+if(f<=0.) i = 0;
+else if(f>=1.) i = 37;
+else { i = (int) (f*36.); i++;}
+if(i<0) i=0; else if (i>=38) i = 37;
+return str[i];
+}
+
+//++
+int PIHisto2D::NPixBin(PIGraphicUC* g)
+//
+//	Nombre de pixels ecran dans un bin d'histogramme
+//	(fct privee).
+//--
+{
+double dx = mHisto->WBinX(),dy = mHisto->WBinY();
+double dxg,dyg;
+g->DUC2GrC(dx,dy,dxg,dyg);
+int np = (int) dxg * (int) dyg;
+//printf("PIHisto2D::NPixBin H dx=%g dy=%g, G dx=%g dy=%g, np = %d\n"
+//      ,dx,dy,dxg,dyg,np);
+return np;
+}
+
+//++
+int PIHisto2D::DecodeOptionString(vector<string> & opt, bool rmdecopt)
+//
+//	Decodage des options
+//--
+{
+  // Decodage des options generales pidrawer
+  int optsz1 = opt.size();
+  if(optsz1<1) return(0); 
+  int ndec1 = PIDrawer::DecodeOptionString(opt, rmdecopt);
+  if(optsz1-ndec1<1) return(ndec1);  // si tout a ete decode
+
+  // Options generales pidrawer interessant le display Histo2D
+  bool rev; 
+  if(GetGraphicAtt().GetColMapId(rev) != CMAP_OTHER) {
+    UseColors(true,GetGraphicAtt().GetColMapId(),rev);
+  } else UseColors(false);
+
+  // Decodage des options propres au display Histo2D
+  vector<string> udopt;  // On gardera ici les options non decodees
+  unsigned int k = 0;
+  int ndec = opt.size();
+  bool listopt=false;
+  for( k=0; k<opt.size(); k++ ) {
+    string opts = opt[k];
+    if(opts=="h2help") {
+      string info; GetOptionsHelpInfo(info);
+      size_t q = info.find("PIHisto2D");
+      if(q<info.length()-1) cout<<info.substr(q)<<endl;
+    } else if(opts=="h2list") {
+      listopt=true;
+    } else if(opts=="sta" || opts=="stat" || opts=="stats") {
+      SetStats(true);
+    } else if(  opts=="nsta"   || opts=="nstat"
+             || opts=="nostat" || opts=="nostats") {
+      SetStats(false);
+    } else if(opts.substr(0,8)=="h2scale=") {
+      unsigned short t=TypScale(); float ls=LogScale();
+      if(opts.substr(8,3)=="lin") t=0;
+      else if(opts.substr(8,3)=="log")
+        {t=1; sscanf(opts.c_str(),"h2scale=log,%g",&ls);}
+      UseScale(t,ls);
+    } else if(opts.substr(0,7)=="h2disp=") {
+      unsigned short t=TypDisplay(); float fpts=FPoints();
+      if(opts.substr(7,3)=="var") t=0;
+      else if(opts.substr(7,3)=="hbk") t=2;
+      else if(opts.substr(7,3)=="img") t=3;
+      else if(opts.substr(7,3)=="pts")
+        {t=1; sscanf(opts.c_str(),"h2disp=pts,%g",&fpts);}
+      UseDisplay(t,fpts);
+    } else if(opts.substr(0,6)=="h2dyn=") {
+      float hmin=HMin(),hmax=HMax(); size_t q = opts.find(',');
+      sscanf(opts.c_str(),"h2dyn=%g",&hmin);
+      if(q<opts.length()-1) sscanf(opts.substr(q+1).c_str(),"%g",&hmax);
+      UseDyn(hmin,hmax);
+    } else if(opts.substr(0,7)=="h2frac=") {
+      float fmin=FMin(),fmax=FMax(); size_t q = opts.find(',');
+      sscanf(opts.c_str(),"h2frac=%g",&fmin);
+      if(q<opts.length()-1) sscanf(opts.substr(q+1).c_str(),"%g",&fmax);
+      UseFrac(fmin,fmax);
+   } else {
+      ndec--;
+      // S'il faut supprimer les options decodees
+      if (rmdecopt)  udopt.push_back(opts);
+    }
+  }
+
+  // S'il faut supprimer les options decodees, on remplace l'argument opt
+  // par le vecteur des options non decodees.
+  if (rmdecopt)  opt = udopt;
+
+  // Liste des options si demande
+  if(listopt) Print();
+
+  return(ndec+ndec1);
+}
+
+//++
+void PIHisto2D::GetOptionsHelpInfo(string& info)
+//
+//	Help relatif au options
+//--
+{
+// On recupere d'abord la chaine info de la classe de base
+PIDrawer::GetOptionsHelpInfo(info);
+info += " ---- PIHisto2D options help info (see also ALT-O): \n" ;
+info += "- h2help: get this help text\n";
+info += "- h2list: list choosen options\n";
+info += "- sta,stat,stats:            activate   statistic display\n";
+info += "  nsta,nstat,nostat,nostats: deactivate statistic display\n";
+info += "- h2disp=typ[,fracpts]: choose display type\n";
+info += "    typ=var: variable size boxes\n";
+info += "    typ=hbk: \"a la hbook2\"\n";
+info += "    typ=img: image like (use \"h2col\" for color map)\n";
+info += "    typ=pts: point clouds (fracpts=max possible fraction\n";
+info += "             of used pixels per bin [0,1])\n";
+info += "- h2scale=lin/log[,logscale]: choose linear or logarithmic scale\n";
+info += "- h2dyn=[hmin][,hmax]: choose histogramme range for display\n";
+info += "- use general key to define color table (ex: grey32,midas_heat,...)\n";
+info += "            (see general graphicatt description)\n";
+info += "- use key \"revcmap\" to reverse color table\n";
+info += "- h2frac=[fmin][,fmax]: choose sub-range display [0,1]\n";
+return;
+}
+
+/////////////////////////////////////////////////////////////////
+//  Classe H2WinArg
+/////////////////////////////////////////////////////////////////
+//++
+// Class	H2WinArg
+// Lib		PIext
+// include	pihisto2d.h
+//
+//	Fenêtre de dialogue pour le choix des options de tracé pour "PIHisto2D"
+//	Classe de fenêtre de dialogue permettant de modifier interactivement
+//	Les différents attributs de visualisation pour les *PIImage* .
+//--
+//++
+// Links	Parents
+// PIWindow
+//--
+//++
+// Links	Voir aussi
+// PIHisto2D
+// PIH2DWdg
+//--
+
+//++
+// Titre	Constructeur, méthodes
+//--
+
+PIBaseWdgGen* H2WinArg::mBWdg = NULL;
+PIHisto2D* H2WinArg::mH2DDrw = NULL;
+static H2WinArg* cur_h2winarg = NULL;
+
+void H2WinArg::ShowPIHisto2DTools()
+{
+  if (cur_h2winarg == NULL)  cur_h2winarg = new H2WinArg(PIApplicationGetApp());
+  cur_h2winarg->Show();
+}
+
+void H2WinArg::ShowPIHisto2DTools(PIBaseWdgGen* cbw)
+{
+  if (cur_h2winarg == NULL)  cur_h2winarg = new H2WinArg(PIApplicationGetApp());
+  mBWdg = cbw;
+  cur_h2winarg->Show();
+}
+
+void H2WinArg::HidePIHisto2DTools()
+{
+  if (cur_h2winarg != NULL)  cur_h2winarg->Hide();
+}
+
+void H2WinArg::SetCurrentBaseWdg(PIBaseWdgGen* cbw)
+{
+  mBWdg = cbw;
+}
+
+void H2WinArg::SetCurrentPIHisto2D(PIHisto2D* h2ddrw)
+{
+  mH2DDrw = h2ddrw;
+}
+
+PIBaseWdgGen* H2WinArg::GetCurrentBaseWdg()
+{
+  return(mBWdg);
+}
+
+PIHisto2D* H2WinArg::GetCurrentPIHisto2D()
+{
+  return(mH2DDrw);
+}
+
+//++
+H2WinArg::H2WinArg(PIMsgHandler* par)
+//
+//	Creation de la fenetre de gestion des parametres
+//	des dessins des histogrammes 2D. Cette fenetre de
+//	dialogue est partagee par tous les widget de dessin
+//	des histogrammes 2D. Pour faire apparaitre la fenetre
+//      tapez ALT-O.
+//--
+//++
+//| - Menu 1: Choix du type de display
+//|     Carres variables, nuages de points, caracteres a la hbook2
+//|     et carres de tailles fixe (couleur ou niveauz de gris).
+//| - Menu 2: Choix du type d'echelle
+//|     Lineaire ou logarithmique
+//| - Menu 3: Choix de la couleur
+//|     noir et blanc, niveau de gris et couleurs diverses.
+//| - Champ texte Dyn: Pour donner la dynamique, si min>=max
+//|     alors prend le min et le max de l'histogramme
+//|     (cf PIHisto2D::UseDyn)
+//| - Champ texte Frac: fraction mini et maxi
+//|     (cf PIHisto2D::UseFrac)
+//| - Champ texte LogScal: niveau de scaling pour le choix d'une
+//|     echelle logarithmique (cf PIHisto2D::UseScale)
+//--
+//++
+//| - Curseur interactif PerPt: pourcentage de points a dessiner
+//|     dans chaque bin (cf PIHisto2D::UseDisplay)
+//| - Bouton Apply: dessiner avec les options affichees
+//| - Bouton Dismiss: fermeture de la fenetre de dialogue.
+//| - Bouton Get: re-prendre les valeurs de display stoquees
+//|     pour un histogramme donne.
+//| - Bouton Print: Imprimer les caracteristiques du display
+//|     et de l'histogramme.
+//--
+: PIWindow((PIMsgHandler *)par,"Options",PIWK_dialog,250,260,150,150)
+, mFgCol(false), mCmap(CMAP_GREYINV32), mRevCmap(false)
+, mTypScal(0)  , mLogScale(10.)
+, mTypDisp(0)  , mFPoints(0.5)
+, mHMin(1.)    , mHMax(-1.)
+, mFracMin(0.1), mFracMax(0.9)
+{
+if(dbg) printf("H2WinArg::H2WinArg %p par=%p\n",this,par);
+
+// Taille automatique
+int bsx, bsy;
+PIApplicationPrefCompSize(bsx, bsy);  // environ 6 lettres
+int spx = (bsx>=10) ? bsx/10 : 1;  // intervalle entre lettres X
+int spy = (bsy>=5) ? bsy/5 : 1;    // intervalle entre lettres Y
+int wszx = 5*spx+bsx+int(2.5*bsx); // Taille fenetre en X
+int wszy = 11*spy+int(8.5*bsy);    // Taille fenetre en Y
+SetSize(wszx, wszy);
+
+// menu du style de display des bins
+  int cpx = 2*spx, cpy = 2*spy;
+mOPop[0] = new PIOptMenu(this,"optmen-h2d-1",2*bsx,bsy,cpx,cpy);
+mOPop[0]->AppendItem("Carres Var."  ,6101);
+mOPop[0]->AppendItem("....."        ,6102);
+mOPop[0]->AppendItem(".+12..Z*"     ,6103);
+mOPop[0]->AppendItem("Carres Pleins",6104);
+mOPop[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+// Menu du choix de la dynamique
+  cpy += bsy+spy;
+mOPop[1] = new PIOptMenu(this,"optmen-h2d-2",2*bsx,bsy,cpx,cpy);
+mOPop[1]->AppendItem("Lineaire",6201);
+mOPop[1]->AppendItem("Log10"   ,6202);
+mOPop[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+// Menu du choix de la table des couleurs
+  cpy += bsy+spy;
+mOPop[2] = new PIOptMenu(this,"optmen-h2d-3",2*bsx,bsy,cpx,cpy);
+mOPop[2]->AppendItem("Black&White",7000);
+mCasc[0] = new PIMenu(mOPop[2]->Menu(),"PIStd-128Col");
+mCasc[1] = new PIMenu(mOPop[2]->Menu(),"MIDAS-CMap");
+int kcc,nsct1=5,nsct2=9,nsct3=PIColorMap::NumberStandardColorMaps()-1;
+for(kcc=0; kcc<nsct1; kcc++) 
+  mOPop[2]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(),7001+kcc);
+for(kcc=nsct1; kcc<nsct2; kcc++) 
+  mCasc[0]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(),7001+kcc);
+mOPop[2]->AppendPDMenu(mCasc[0]);
+for(kcc=nsct2; kcc<nsct3; kcc++) 
+  mCasc[1]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(),7001+kcc);
+mOPop[2]->AppendPDMenu(mCasc[1]);
+for(kcc=nsct3; kcc<PIColorMap::NumberStandardColorMaps(); kcc++) 
+  mOPop[2]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(),7001+kcc);
+//mOPop[2]->SetValue(7000);
+mOPop[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+// Reverse color map
+  cpy += bsy+spy;
+mCkb = new PICheckBox(this,"Reverse CMap",8001,2*bsx,bsy,cpx,cpy);
+mCkb->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+// Labels et zones de saisie texte
+  cpy += bsy+spy;
+mLab[0] = new PILabel(this,"     Dyn: ",bsx,bsy,cpx,cpy); 
+mLab[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+mText[0] = new PIText(this,"Dynamique",int(2.5*bsx),bsy,cpx+bsx+spx,cpy);
+mText[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+  cpy += bsy+spy;
+mLab[1] = new PILabel(this,"    Frac: ",bsx,bsy,cpx,cpy);
+mLab[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+mText[1] = new PIText(this,"Fraction",int(2.5*bsx),bsy,cpx+bsx+spx,cpy);
+mText[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+  cpy += bsy+spy;
+mLab[2] = new PILabel(this," LogScal: ",bsx,bsy,cpx,cpy);
+mLab[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+mText[2] = new PIText(this,"LogScale",int(2.5*bsx),bsy,cpx+bsx+spx,cpy);
+mText[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+// Labels et curseur mobile
+cpy += bsy+spy;
+mLab[3] = new PILabel(this,"   PerPt: ",bsx,bsy,cpx,cpy+int(0.25*bsy));
+mLab[3]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+mPScal = new PIScale(this,"FracPoints",6401,kSDirLtoR
+                        ,int(2.5*bsx),int(1.25*bsy),cpx+bsx+spx,cpy);
+mPScal->SetMinMax(0,100);
+mPScal->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+//
+SetText();
+//
+
+// Boutons
+  cpx = 2*bsx+5*spx, cpy = 2*spy;
+mBut[0] = new PIButton(this,"Apply",6001,bsx,bsy,cpx,cpy);
+mBut[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+  cpy += bsy+spy;
+mBut[1] = new PIButton(this,"Dismiss",6002,bsx,bsy,cpx,cpy);
+mBut[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+  cpy += bsy+spy;
+mBut[2] = new PIButton(this,"Get",6003,bsx,bsy,cpx,cpy);
+mBut[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+  cpy += bsy+spy;
+mBut[3] = new PIButton(this,"Print",6004,bsx,bsy,cpx,cpy);
+mBut[3]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+// FinishCreate();
+}
+
+//++
+H2WinArg::~H2WinArg()
+//
+//	Destructeur.
+//--
+{
+int i;
+if(dbg) printf("H2WinArg::~H2WinArg %p\n",this);
+for(i=0;i<2;i++) delete mCasc[i];
+for(i=0;i<3;i++) delete mOPop[i];
+for(i=0;i<4;i++) delete mBut[i];
+for(i=0;i<4;i++) delete mLab[i];
+for(i=0;i<3;i++) delete mText[i];
+delete mCkb;
+delete mPScal;
+}
+
+//++
+void H2WinArg::Show()
+//
+//	Initialisation sur ouverture ALT-O
+//--
+{
+ if(dbg) printf("H2WinArg::Show() mH2DDrw=%p\n",mH2DDrw);
+ // Pour recuperer les valeurs du Drawer sur lequel on fait ALT-O
+ PIWindow::Show();
+ return;
+}
+
+//++
+void H2WinArg::SetText()
+//
+//	Gestion des fenetres de saisie de texte et des pop-menus.
+//--
+{
+if(dbg) printf("H2WinArg::SetText()\n");
+string sdum;
+char str[256];
+
+sprintf(str,"%g %g",mHMin,mHMax);
+mText[0]->SetText(str);
+
+sprintf(str,"%g %g",mFracMin,mFracMax);
+mText[1]->SetText(str);
+
+sprintf(str,"%g",mLogScale);
+mText[2]->SetText(str);
+if(mTypScal==1) mText[2]->SetSensitive();
+  else          mText[2]->SetUnSensitive();
+
+if(mTypDisp==0)      {sdum="Carres Var.";   mOPop[0]->SetValueStr(sdum);}
+else if(mTypDisp==1) {sdum=".....";         mOPop[0]->SetValueStr(sdum);}
+else if(mTypDisp==2) {sdum=".+12..Z*";      mOPop[0]->SetValueStr(sdum);}
+else if(mTypDisp==3) {sdum="Carres Pleins"; mOPop[0]->SetValueStr(sdum);}
+
+if(mTypScal==0)      {sdum="Lineaire"; mOPop[1]->SetValueStr(sdum);}
+else if(mTypScal==1) {sdum="Log10";    mOPop[1]->SetValueStr(sdum);}
+
+if(!mFgCol) {mOPop[2]->SetValue(7000);}
+else {
+  for(int kk=0;kk<PIColorMap::NumberStandardColorMaps();kk++)
+    if(mCmap == PIColorMap::GetStandardColorMapId(kk))
+      {mOPop[2]->SetValue(7001+kk); break;}
+}
+mCkb->SetState(mRevCmap);
+
+mPScal->SetValue(int(mFPoints*100.));
+if(mTypDisp==1) mPScal->SetSensitive();
+  else          mPScal->SetUnSensitive();
+}
+
+//++
+void H2WinArg::Process(PIMessage msg, PIMsgHandler* sender, void*)
+//
+//	Gestions des messages.
+//--
+{
+if(dbg) printf("H2WinArg::Process(%d-%d , %p ...) \n"
+              ,(int)UserMsg(msg),(int)ModMsg(msg),sender);
+
+// if(!mH2Wdg) return;
+if(!mBWdg) return;
+// PIHisto2D* mpih = mH2Wdg->GetPIHisto();
+PIHisto2D* mpih = mH2DDrw;
+if(!mpih) return;
+
+int opt = UserMsg(msg);
+
+     if(opt == 6101) {mTypDisp = 0;}
+else if(opt == 6102) {mTypDisp = 1;}
+else if(opt == 6103) {mTypDisp = 2;}
+else if(opt == 6104) {mTypDisp = 3;}
+
+else if(opt == 6201) {mTypScal = 0;}
+else if(opt == 6202) {mTypScal = 1;}
+
+else if(opt == 7000) {mFgCol = false;}
+else if(opt >= 7001 && opt <8000) {
+  int k  = opt-7001;
+  mFgCol = true;
+  mCmap  = PIColorMap::GetStandardColorMapId(k);
+}
+
+else if(opt == 8001) mRevCmap = mCkb->GetState();
+
+else if(opt == 6401) mFPoints = mPScal->GetValue()/100.;
+
+else if(opt==6001) {
+  sscanf(mText[0]->GetText().c_str(),"%g %g",&mHMin,&mHMax);
+  sscanf(mText[1]->GetText().c_str(),"%g %g",&mFracMin,&mFracMax);
+  sscanf(mText[2]->GetText().c_str(),"%g",&mLogScale);
+  mpih->UseColors(mFgCol,mCmap,mRevCmap);
+  mpih->UseScale(mTypScal,mLogScale);
+  mpih->UseDisplay(mTypDisp,mFPoints);
+  mpih->UseDyn(mHMin,mHMax);
+  mpih->UseFrac(mFracMin,mFracMax);
+  mBWdg->Refresh();  // On rafraichit le dessin (tout le PIScDrawWdg)
+}
+else if(opt==6002) this->Hide();
+else if (opt==6003) {
+  mFgCol = mpih->Color(); mCmap = mpih->ColMap();
+                          mRevCmap = mpih->IsColMapRev();
+  mTypScal = mpih->TypScale(); mLogScale = mpih->LogScale();
+  mTypDisp = mpih->TypDisplay(); mFPoints = mpih->FPoints();
+  mHMin = mpih->HMin(); mHMax = mpih->HMax();
+  mFracMin = mpih->FMin(); mFracMax = mpih->FMax();
+}
+else if(opt==6004) mpih->Print(2);
+
+SetText();
+
+if(dbg) {
+  printf("H2WinArg::Process opt=%d col=%d,%d,%d scal=%d disp=%d npt=%g\n"
+        ,opt,(int)mFgCol,(int)mCmap,(int)mRevCmap,mTypScal,mTypDisp,mFPoints);
+  printf("                  min,max= %g,%g frac= %g,%g logsc= %g\n"
+        ,mHMin,mHMax,mFracMin,mFracMax,mLogScale);
+}
+
+}
Index: /tags/V_Dec2002/SophyaPI/PIext/pihisto2d.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/pihisto2d.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/pihisto2d.h	(revision 2309)
@@ -0,0 +1,120 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PIext :   PIHisto2D PIH2DWdg 
+// Traceur Histo-2D    C. Magneville 97-98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PIHISTO2D_H
+#define PIHISTO2D_H
+
+#include "pisysdep.h"
+#include PIMENU_H 
+#include PIMENUBAR_H 
+#include PIOPTMENU_H
+
+#include "histos2.h"
+#include "pidrawer.h"
+#include "piscdrawwdg.h"
+
+////////////////////////////////////////////////////////////////////
+class PIHisto2D : public PIDrawer {
+public:
+  PIHisto2D(Histo2D* histo, bool ad=false);
+  virtual ~PIHisto2D();
+
+  void UseColors(bool fg=false,CMapId cmap=CMAP_GREYINV32,bool revcmap=false);
+  void UseScale(unsigned short type=0,float logscale=10.);
+  void UseDisplay(unsigned short type=0,float fnpt=0.5);
+  void UseDyn(float hmin=1.,float hmax=-1.);
+  void UseFrac(float frmin=0.1,float frmax=0.9);
+  void Print(int lp=0);
+
+  virtual void Draw(PIGraphicUC* g,double xmin,double ymin,double xmax,double ymax);
+
+  //AppendTextInfo a faire un jour - Reza 21/01/2002 
+  //virtual void AppendTextInfo(string& info,double xmin,double ymin
+  //                           ,double xmax,double ymax);
+
+  // Ce que fait l'action de clic avec la souris
+  virtual void GetClickInfo(string& info, double x, double y
+                           ,double x0=0.,double y0=0.,bool fgdiff=false); 
+
+  virtual void UpdateLimits();
+  virtual void DrawStats(PIGraphicUC* g);
+  inline  void SetStats(bool fg=true) {stats=fg;}
+
+  //  Methode permettant l'affichage d'une fenetre de controle specialisee 
+  virtual void ShowControlWindow(PIBaseWdgGen* wdg);
+  //  Desactivation de la fenetre de controle specialisee
+  virtual void DeactivateControlWindow(PIBaseWdgGen* wdg);
+
+  //   Methode de decodage des options
+  virtual int  DecodeOptionString(vector<string> & opt, bool rmdecopt=true);
+  virtual void GetOptionsHelpInfo(string& info);
+
+  // Methodes inline
+  inline Histo2D*       Histogram()   {return(mHisto);}
+  inline bool           Color()       {return(mFgCol);}
+  inline CMapId         ColMap()      {return(mCmap);}
+  inline bool           IsColMapRev() {return(mRevCmap);}
+  inline unsigned short TypScale()    {return(mTypScal);}
+  inline unsigned short TypDisplay()  {return(mTypDisp);}
+  inline float          FPoints()     {return(mFPoints);}
+  inline float          HMax()        {return(mHMax);}
+  inline float          HMin()        {return(mHMin);}
+  inline float          FMax()        {return(mFracMax);}
+  inline float          FMin()        {return(mFracMin);}
+  inline float          LogScale()    {return(mLogScale);}
+
+protected:
+  int NPixBin(PIGraphicUC* g);
+  char HPrint2(float f);
+
+  Histo2D* mHisto;
+  bool mAdDO; bool stats;
+  bool mFgCol; CMapId mCmap; bool mRevCmap;
+  unsigned short mTypScal; float mLogScale;
+  unsigned short mTypDisp; float mFPoints;
+  float mHMin,mHMax;
+  float mFracMin,mFracMax;
+};
+
+////////////////////////////////////////////////////////////////////
+class H2WinArg : public PIWindow {
+public :
+  H2WinArg(PIMsgHandler* par);
+  ~H2WinArg();
+
+  static void ShowPIHisto2DTools();
+  static void ShowPIHisto2DTools(PIBaseWdgGen* cbw);
+  static void HidePIHisto2DTools();
+  static void SetCurrentBaseWdg(PIBaseWdgGen* cbw);
+  static void SetCurrentPIHisto2D(PIHisto2D* h2ddrw);
+
+  static PIBaseWdgGen* GetCurrentBaseWdg();
+  static PIHisto2D* GetCurrentPIHisto2D();
+
+  void SetText();
+
+  virtual void Show();
+  virtual void Process(PIMessage msg,PIMsgHandler* sender,void* data=NULL);
+
+protected:
+  static PIBaseWdgGen * mBWdg;
+  static PIHisto2D*  mH2DDrw;
+
+  PIOptMenu * mOPop[3];
+  PIMenu    * mCasc[2];
+  PIButton  * mBut[4];
+  PILabel   * mLab[4];
+  PIText    * mText[3];
+  PIScale   * mPScal;
+  PICheckBox* mCkb;
+
+  bool mFgCol; CMapId mCmap; bool mRevCmap;
+  unsigned short mTypScal; float mLogScale;
+  unsigned short mTypDisp; float mFPoints;
+  float mHMin,mHMax;
+  float mFracMin,mFracMax;
+};
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/piinit.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/piinit.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/piinit.cc	(revision 2309)
@@ -0,0 +1,119 @@
+#include "machdefs.h"
+#include "piinit.h"
+#include "nobjmgr.h"
+#include "servnobjm.h"
+#include "nomhistadapter.h"
+#include "nomgfdadapter.h"
+#include "nomimagadapter.h"
+
+#ifdef SANS_EVOLPLANCK
+#include "nommatvecadapter.h"
+#include "fitsimage.h"
+#include "nomstladapter.h"
+#else
+#include <complex>
+#include "nomtmatvecadapter.h"
+#include "nomtarradapter.h"
+#include "nomskymapadapter.h"
+#include "spherethetaphi.h"
+#include "spherehealpix.h"
+#include "localmap.h"
+
+#include "specrespvector.h"
+#include "gaussfilt.h"
+#include "nomspecrespadapter.h"
+
+#endif
+
+int PIAppInitiator::FgInit = 0;
+
+PIAppInitiator::PIAppInitiator(PIStdImgApp * app)
+#ifdef SANS_EVOLPLANCK
+ : PeidaStarRecoInitiator()
+#else
+ : SambaInitiator()
+#endif
+{
+  FgInit++;
+  if (FgInit > 1)  return;
+
+  Services2NObjMgr* serv = app->ObjMgr()->GetServiceObj();
+
+  serv->RegisterClass(new Histo, new NOMAdapter_Histo );
+  serv->RegisterClass(new HProf, new NOMAdapter_Histo );
+  serv->RegisterClass(new Histo2D, new NOMAdapter_Histo2D );
+  serv->RegisterClass(new NTuple, new NOMAdapter_NTuple );
+
+  serv->RegisterClass(new XNTuple, new NOMAdapter_XNTuple );
+  char* varenv=NULL;
+  if ( (varenv=getenv("PEIDA_TMP")) == NULL )   varenv=getenv("TMPDIR") ;
+  if (varenv)  XNTuple::SetSwapPath(varenv);
+
+  serv->RegisterClass(new GeneralFitData, new NOMAdapter_GeneralFitData );
+
+#ifdef SANS_EVOLPLANCK
+  serv->RegisterClass(new Vector, new NOMAdapter_Vector );
+  serv->RegisterClass(new Matrix, new NOMAdapter_Matrix );
+#else
+  serv->RegisterClass(new TArray<int_4>, new NOMAdapter_TArray<int_4> );
+  serv->RegisterClass(new TArray<r_4>, new NOMAdapter_TArray<r_4> );
+  serv->RegisterClass(new TArray<r_8>, new NOMAdapter_TArray<r_8> );
+  serv->RegisterClass(new TArray<complex<r_4> >, new NOMAdapter_TArray<complex<r_4> > );
+  serv->RegisterClass(new TArray<complex<r_8> >, new NOMAdapter_TArray<complex<r_8> > );
+
+  serv->RegisterClass(new TVector<int_4>, new NOMAdapter_TMatrix<int_4> );
+  serv->RegisterClass(new TMatrix<int_4>, new NOMAdapter_TMatrix<int_4> );
+  serv->RegisterClass(new TVector<r_4>, new NOMAdapter_TMatrix<r_4> );
+  serv->RegisterClass(new TMatrix<r_4>, new NOMAdapter_TMatrix<r_4> );
+  serv->RegisterClass(new TVector<r_8>, new NOMAdapter_TMatrix<r_8> );
+  serv->RegisterClass(new TMatrix<r_8>, new NOMAdapter_TMatrix<r_8> );
+  serv->RegisterClass(new TVector<complex<r_4> >, new NOMAdapter_TMatrix<complex<r_4> > );
+  serv->RegisterClass(new TMatrix<complex<r_4> >, new NOMAdapter_TMatrix<complex<r_4> > );
+  serv->RegisterClass(new TVector<complex<r_8> >, new NOMAdapter_TMatrix<complex<r_8> > );
+  serv->RegisterClass(new TMatrix<complex<r_8> >, new NOMAdapter_TMatrix<complex<r_8> > );
+#endif
+
+  serv->RegisterClass(new Image<uint_2>, new  NOMAdapter_Image<uint_2> );
+  serv->RegisterClass(new Image<int_4>, new  NOMAdapter_Image<int_4> );
+  serv->RegisterClass(new Image<r_4>, new  NOMAdapter_Image<r_4> );
+ 
+#ifdef SANS_EVOLPLANCK
+  serv->RegisterClass(new Image<int_2>, new  NOMAdapter_Image<int_2> );
+
+  serv->RegisterClass(new FitsImage<uint_2>, new  NOMAdapter_Image<uint_2> );
+  serv->RegisterClass(new FitsImage<int_2>, new  NOMAdapter_Image<int_2> );
+  serv->RegisterClass(new FitsImage<int_4>, new  NOMAdapter_Image<int_4> );
+  serv->RegisterClass(new FitsImage<r_4>, new  NOMAdapter_Image<r_4> );
+
+  serv->RegisterClass(new StarList, new NOMAdapter_StarList );
+#else
+  serv->RegisterClass(new LocalMap<int_4>, new NOMAdapter_PixelMap<int_4> );
+  serv->RegisterClass(new SphereThetaPhi<int_4>, new NOMAdapter_PixelMap<int_4> );
+  serv->RegisterClass(new SphereHEALPix<int_4>, new NOMAdapter_PixelMap<int_4> );
+  serv->RegisterClass(new LocalMap<r_4>, new NOMAdapter_PixelMap<r_4> );
+  serv->RegisterClass(new SphereThetaPhi<r_4>, new NOMAdapter_PixelMap<r_4> );
+  serv->RegisterClass(new SphereHEALPix<r_4>, new NOMAdapter_PixelMap<r_4> );
+  serv->RegisterClass(new LocalMap<r_8>, new NOMAdapter_PixelMap<r_8> );
+  serv->RegisterClass(new SphereThetaPhi<r_8>, new NOMAdapter_PixelMap<r_8> );
+  serv->RegisterClass(new SphereHEALPix<r_8>, new NOMAdapter_PixelMap<r_8> );
+  serv->RegisterClass(new LocalMap<complex<float> >, new NOMAdapter_PixelMap<complex<float> > );
+  serv->RegisterClass(new SphereThetaPhi<complex<float> >, new NOMAdapter_PixelMap<complex<float> > );
+  serv->RegisterClass(new SphereHEALPix<complex<float> >, new NOMAdapter_PixelMap<complex<float> > );
+  serv->RegisterClass(new LocalMap<complex<double> >, new NOMAdapter_PixelMap<complex<double> > );
+  serv->RegisterClass(new SphereThetaPhi<complex<double> >, new NOMAdapter_PixelMap<complex<double> > );
+  serv->RegisterClass(new SphereHEALPix<complex<double> >, new NOMAdapter_PixelMap<complex<double> > );
+
+  serv->RegisterClass(new GaussianFilter, new NOMAdapter_SpectralResponse );
+  serv->RegisterClass(new SpecRespVec, new NOMAdapter_SpectralResponse );
+#endif
+
+}
+
+PIAppInitiator::~PIAppInitiator()
+{
+  FgInit--;
+/*  if (FgInit == 0)
+    {
+    }  */
+}
+
Index: /tags/V_Dec2002/SophyaPI/PIext/piinit.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/piinit.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/piinit.h	(revision 2309)
@@ -0,0 +1,27 @@
+#ifndef PIINIT_H_SEEN
+#define PIINIT_H_SEEN
+
+#ifdef SANS_EVOLPLANCK
+#include "strecinit.h"
+#else
+#include "sambainit.h"
+#endif
+
+#include "pistdimgapp.h"
+
+// Classe d initialisation pour le module PIext de PEIDA
+
+#ifdef SANS_EVOLPLANCK
+class PIAppInitiator : public PeidaStarRecoInitiator {
+#else
+class PIAppInitiator : public SambaInitiator {
+#endif
+private:
+  static int FgInit;
+public:
+  		PIAppInitiator(PIStdImgApp *);
+ virtual	~PIAppInitiator();
+};
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/pimgadapter.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/pimgadapter.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/pimgadapter.h	(revision 2309)
@@ -0,0 +1,40 @@
+#ifndef PIMGADAPTER_SEEN
+#define PIMGADAPTER_SEEN
+
+#include "cimage.h"
+#include "parradapter.h"
+
+#ifdef SANS_EVOLPLANCK 
+class RzImageAdapter : public P2DArrayAdapter {
+public:
+                  RzImageAdapter(RzImage* rzi, bool ad=false) :
+                    P2DArrayAdapter(rzi->XSize(), rzi->YSize())
+                    { aDel = ad; mImg = rzi; 
+                    DefineXYCoordinates(rzi->XOrg(), rzi->YOrg(), 1., 1. ); }
+
+  virtual 	  ~RzImageAdapter() { if (aDel) delete mImg; }
+  virtual double  Value(int ix, int iy) { return mImg->FValue(ix, iy); }
+
+protected :
+  bool aDel;
+  RzImage* mImg;
+};
+#endif
+
+template <class T> 
+class ImageAdapter : public P2DArrayAdapter {
+public:
+                  ImageAdapter(Image<T>* img, bool ad=false) :
+                    P2DArrayAdapter(img->XSize(), img->YSize())
+                    { aDel = ad; mImg = img; 
+                    DefineXYCoordinates(img->XOrg(), img->YOrg(), 1., 1. ); }
+
+  virtual 	  ~ImageAdapter() { if (aDel) delete mImg; }
+  virtual double  Value(int ix, int iy) { return((*mImg)(ix, iy)); }
+
+protected :
+  bool aDel;
+  Image<T>* mImg;
+};
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/pintup3d.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/pintup3d.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/pintup3d.cc	(revision 2309)
@@ -0,0 +1,242 @@
+// Peida Interactive   -   PI            R. Ansari 97-99
+// Traceur3D (Drawer) pour NTupleInterface  
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include <stdio.h>
+#include "pintup3d.h"
+
+//#define PERC_GARDE 0.05
+
+//++
+// Class	PINTuple3D
+// Lib		PIext
+// include	pintup3d.h
+//
+//	Classe de traceur 3D à partir des données
+//	d'un objet implémentant l'interface *NTupleInterface*.
+//	Les objets "PINTuple3D" peuvent tracer des signes (markers)
+//	éventuellement avec des barres d'erreur et une étiquette
+//	pour chaque point. Si un attribut de ligne, autre que
+//	"PI_NotDefLineAtt" est spécifié, les points sont connectés
+//	par une ligne.
+//--
+//++
+// Links	Parents
+// PIDrawer3D
+//--
+//++
+// Links	Voir aussi
+// NTupleInterface
+// PINTuple
+//--
+
+//++
+// Titre	Constructeur
+//--
+//++
+// PINTuple3D(NTupleInterface* nt, bool ad=false)
+//	Constructeur. Si "ad == true", l'objet "nt" est détruit par 
+//	le destructeur de l'objet "PINTuple".
+//	Note : nt doit être créé par new
+//--
+
+ 
+/* --Methode-- */
+PINTuple3D::PINTuple3D(NTupleInterface* nt, bool ad)
+: PIDrawer3D()
+{
+  mNT = nt;
+  mAdDO = ad; 
+  SelectXYZ(NULL, NULL, NULL);
+  SelectWt(NULL, 1);
+  SelectErrBar();
+  SelectLabel(NULL);
+  SetName("NTup3DDrw");
+}
+
+PINTuple3D::~PINTuple3D()
+{
+  if (mAdDO && mNT)  delete mNT;
+}
+
+//++
+// Titre	Méthodes
+//--
+//++
+// void  SelectXYZ(const char* px, const char* py, const char* pz)
+//	Choix des noms de colonnes X,Y,Z définissant les coordonnées des points. 
+//	Ces trois colonnes doivent être spécifiées pour obtenir un tracé.
+// void  SelectErrBar(const char* erbx=NULL, const char* erby=NULL, const char* erbz=NULL)
+//	Choix des noms de colonnes pour le tracé des barres d'erreur.
+// void  SelectWt(const char* pw=NULL, int nbins=10)
+//	Choix du nom de colonne poids. Dans ce cas, la taille du signe
+//	(marker) sera proportionnel à la valeur de cette colonne pour 
+//	chaque point.
+// void  SelectLabel(const char* plabel)
+//	Choix du nom de colonne correspondant à l'étiquette.
+//--
+
+/* --Methode-- */
+void  PINTuple3D::SelectXYZ(const char* px, const char* py, const char* pz)
+{
+string name;
+if (mNT == NULL)  xK = yK = zK = -1;
+if (px == NULL) xK = -1;
+else { name = px; xK = mNT->ColumnIndex(name); }
+if (py == NULL) yK = -1;
+else { name = py; yK = mNT->ColumnIndex(name); }
+if (pz == NULL) zK = -1;
+else { name = pz; zK = mNT->ColumnIndex(name); }
+}
+
+/* --Methode-- */
+void  PINTuple3D::SelectWt(const char* pw, int nbins)
+{
+nWbins = (nbins > 0) ? nbins : 10;
+if (pw == NULL) wK = -1;  
+else { string name = pw;   wK = mNT->ColumnIndex(name);  }
+ 
+if (wK >= 0) mNT->GetMinMax(wK, wMin, wMax);
+else  { wMin = 0.; wMax = 1.; }
+}
+
+/* --Methode-- */
+void  PINTuple3D::SelectLabel(const char* plabel)
+{
+if (plabel == NULL) lK = -1;
+else {  string name = plabel;  lK = mNT->ColumnIndex(name);  }
+}
+
+/* --Methode-- */
+void  PINTuple3D::SelectErrBar(const char* erbx, const char* erby, const char* erbz)
+{
+string name;
+if (mNT == NULL)  xebK = yebK = zebK = -1;
+if (erbx == NULL) xebK = -1;
+else { name = erbx;  xebK = mNT->ColumnIndex(name); }
+if (erby == NULL) yebK = -1;
+else { name = erby;  yebK = mNT->ColumnIndex(name); }
+if (erbz == NULL) zebK = -1;
+else { name = erbz;  zebK = mNT->ColumnIndex(name); }
+}
+
+
+/* --Methode-- */
+void PINTuple3D::UpdateLimits()
+{
+  if (!mNT) return; 
+  if (mNT->NbLines() <= 0)  return;
+  if ( (xK < 0) || (yK < 0)  || (zK < 0) )   return;
+
+  // Commencer par trouver nos limites
+  double xmin, xmax, ymin, ymax, zmin, zmax;
+  xmin = ymin = 9.e19;
+  xmax = ymax = -9.e19;
+  zmax = zmax = -9.e19;
+  mNT->GetMinMax(xK, xmin, xmax);
+  mNT->GetMinMax(yK, ymin, ymax);
+  mNT->GetMinMax(zK, zmin, zmax);
+
+// Centre du champ en C = (xmin+xmax)/2., (ymin+ymax)/2  (zmin+zmax)*0.5
+// Distance D = Max(xmax-xmin,ymin-ymax)*2
+// Observateur en O = X+D, Yc+2*D 
+  double D = xmax-xmin;
+  if (D < (ymax-ymin))  D = ymax-ymin;
+  D *= 1.4;
+  
+  Set3DView((xmin+xmax)/2., (ymin+ymax)/2, (zmin+zmax)/2., 
+            (xmin+xmax)/2.+D , (ymin+ymax)/2.-2.5*D , zmin+(zmax-zmin)*0.85, 0.25, 0.25);  
+
+  /*
+  x3Min = xmin;  // - PERC_GARDE*(xmax-xmin);
+  x3Max = xmax;  // + PERC_GARDE*(xmax-xmin);
+  y3Min = ymin;  // - PERC_GARDE*(ymax-ymin);
+  y3Max = ymax;  // + PERC_GARDE*(ymax-ymin);
+  z3Min = zmin;  // - PERC_GARDE*(zmax-zmin);
+  z3Max = zmax;  // + PERC_GARDE*(zmax-zmin);
+  */
+
+  Set3DBox(xmin, xmax, ymin, ymax, zmin, zmax);
+
+//  printf("PINTuple3D::UpdateLimits() : %g .. %g  %g .. %g  %g .. %g (%g) \n", xmin,xmax,ymin,ymax,zmin,zmax,D);
+//  printf("PINTuple3D::UpdateLimits() :  %g %g %g << %g %g %g \n", 
+//         (xmin+xmax)/2., (ymin+ymax)/2, (zmin+zmax)*0.5, 
+//         (xmin+xmax)/2.+D , (ymin+ymax)/2.+2.*D , zmin+(zmax-zmin)*0.1);
+}
+
+
+/* --Methode-- */
+void PINTuple3D::Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax)
+{
+double xp,yp,zp,wp,xer,yer,zer;
+double xl,yl,zl;
+int nok;
+
+// On trace les axes - En attendant de faire mieux - Reza 8/12/98
+if (axesFlags != kAxesNone)  DrawAxes(g);
+
+if (!mNT) return;
+if ( (xK < 0) || (yK < 0) || (zK < 0) )  return;
+
+#if defined(CC_HAS_RTTI_SUPPORT)
+PIGraphic3D* g3 = dynamic_cast<PIGraphic3D*>(g);
+#else
+PIGraphic3D* g3 = (PIGraphic3D*)(g);
+#endif
+
+if (GetGraphicAtt().GetLineAtt() == PI_NotDefLineAtt)  g3->SelLine(PI_ThinLine);
+
+//  Pour tracer des markers avec taille fonction de Wt (poids)
+double dw = (wMax-wMin)/nWbins;
+if (dw < 1.e-19) dw = 1.e19;
+int msz,sz;
+
+PIMarker mmrk = GetGraphicAtt().GetMarker();
+PIMarker mrk;
+if (wK >= 0)  mrk = (mmrk != PI_NotDefMarker) ? mmrk : PI_CircleMarker;
+else   mrk = (mmrk != PI_NotDefMarker) ? mmrk : PI_DotMarker;
+msz = GetGraphicAtt().GetMarkerSz();
+if (msz < 1) msz = 1;
+g->SelMarker(msz, mrk);
+
+nok = 0;  
+xp = yp = zp = xl = yl = zl = 0;
+for (int i=0; i<mNT->NbLines(); i++) {
+  xl = xp;  yl = yp;  zl = zp;
+  xp = mNT->GetCell(i, xK);
+  yp = mNT->GetCell(i, yK);
+  zp = mNT->GetCell(i, zK);
+  if ( (i > 0) && 
+       (GetGraphicAtt().GetLineAtt() != PI_NotDefLineAtt) )   // On relie les points ...
+    g3->DrawLine3D(xl, yl, zl, xp, yp, zp);
+  nok++;
+  if ( xebK >= 0 ) {
+    xer = mNT->GetCell(i, xebK);
+    g3->DrawLine3D(xp-xer, yp, zp, xp+xer, yp, zp);
+  }
+  if ( yebK >= 0 ) {
+    yer = mNT->GetCell(i, yebK);
+    g3->DrawLine3D(xp, yp-yer, zp, xp, yp+yer, zp);
+  }
+  if ( zebK >= 0 ) {
+    zer = mNT->GetCell(i, zebK);
+    g3->DrawLine3D(xp, yp, zp-zer, xp, yp, zp+zer);
+  }
+  if (wK >= 0) { // Taille de marker en fonction du poids
+    wp = mNT->GetCell(i, wK);
+    sz = (int)((wp-wMin)/dw);
+    if (sz < 0) sz = 0;
+    if (sz > nWbins)  sz = nWbins;
+    sz += msz;
+    if (sz < 2)  g->SelMarker(sz, PI_DotMarker);
+    else g->SelMarker(sz, mrk);
+  }
+  // Trace du marker
+  if ((wK >= 0)||(lK < 0)||(mmrk != PI_NotDefMarker))  g3->DrawMarker3D(xp, yp, zp); 
+  // Trace eventuel du label
+  if (lK >= 0) g3->DrawString3D(xp, yp, zp, mNT->GetCelltoString(i, lK).c_str());
+}
+
+return;
+}
+
Index: /tags/V_Dec2002/SophyaPI/PIext/pintup3d.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/pintup3d.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/pintup3d.h	(revision 2309)
@@ -0,0 +1,37 @@
+#ifndef PINTUPLE3D_H
+#define PINTUPLE3D_H
+
+#include "ntupintf.h"
+#include "pi3ddrw.h"
+
+class PINTuple3D : public PIDrawer3D {
+public:
+                     PINTuple3D(NTupleInterface* nt, bool ad=false);
+  virtual           ~PINTuple3D();
+  
+  virtual void       Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax);
+  virtual void       UpdateLimits();
+  
+  virtual void       SelectXYZ(const char* px, const char* py, const char* pz);
+  virtual void       SelectWt(const char* pw=NULL, int nbins=10);
+  virtual void       SelectErrBar(const char* erbx=NULL, const char* erby=NULL, const char* erbz=NULL);
+  virtual void       SelectLabel(const char* plabel);
+
+       
+protected:
+  NTupleInterface* mNT;
+  bool mAdDO;
+  int xK, yK, zK;           // Index du nom de variable en X/Y/Z ds le ntuple
+  int xebK, yebK, zebK;     // Index du nom de variable en ErrBarX/Y/Z ds le ntuple
+  int wK;                   // Index du nom de variable poids
+  int lK;                   // Index du nom de variable label (affiche en texte)
+  double wMin, wMax;        // Valeurs de poids min/max
+  int nWbins;               // Nombre de bins pour le poids (Wt)
+
+};
+
+#endif
+
+
+
+
Index: /tags/V_Dec2002/SophyaPI/PIext/pintuple.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/pintuple.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/pintuple.cc	(revision 2309)
@@ -0,0 +1,316 @@
+// Peida Interactive   -   PI        R. Ansari 97-99
+// Traceur (Drawer) pour NTupleInterface  
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include <stdio.h>
+#include "pintuple.h"
+
+//++
+// Class	PINTuple
+// Lib		PIext
+// include	pintuple.h
+//
+//	Classe de traceur 2D (dans un plan) à partir des données
+//	d'un objet implémentant l'interface *NTupleInterface*.
+//	Les objets "PINTuple" peuvent tracer des signes (markers)
+//	éventuellement avec des barres d'erreur et une étiquette
+//	pour chaque point. Si un attribut de ligne, autre que
+//	"PI_NotDefLineAtt" est spécifié, les points sont connectés
+//	par une ligne.
+//--
+//++
+// Links	Parents
+// PIDrawer
+//--
+//++
+// Links	Voir aussi
+// NTupleInterface
+// PINTuple3D
+//--
+
+//++
+// Titre	Constructeur
+//--
+//++
+// PINTuple(NTupleInterface* nt, bool ad)
+//	Constructeur. Si "ad == true", l'objet "nt" est détruit par 
+//	le destructeur de l'objet "PINTuple"
+//	Note : "nt" doit être créé par new
+//--
+ 
+/* --Methode-- */
+PINTuple::PINTuple(NTupleInterface* nt, bool ad)
+: PIDrawer()
+{
+  mNT = nt;
+  mAdDO = ad; 
+  SetStats(true);
+  SelectXY(NULL, NULL);
+  SelectWt(NULL, 1);
+  SelectErrBar();
+  SelectLabel(NULL);
+  SetName("NTupleDrw");
+}
+
+PINTuple::~PINTuple()
+{
+  if (mAdDO && mNT)  delete mNT;
+}
+
+//++
+// Titre	Méthodes
+//--
+//++
+// void  SelectXY(const char* px, const char* py)
+//	Choix des noms de colonnes X,Y définissant les coordonnées des points. 
+//	Ces deux colonnes doivent être spécifiées pour obtenir un tracé.
+// void  SelectErrBar(const char* erbx=NULL, const char* erby=NULL)
+//	Choix des noms de colonnes pour le tracé des barres d'erreur.
+// void  SelectWt(const char* pw=NULL, int nbins=10)
+//	Choix du nom de colonne poids. Dans ce cas, la taille du signe
+//	(marker) sera proportionnel à la valeur de cette colonne pour 
+//	chaque point.
+// void  SelectLabel(const char* plabel=NULL)
+//	Choix du nom de colonne correspondant à l'étiquette.
+//--
+
+/* --Methode-- */
+void  PINTuple::SelectXY(const char* px, const char* py)
+{
+string name;
+if (mNT == NULL)  xK = yK = -1;
+if (px == NULL) xK = -1;
+else { name = px; xK = mNT->ColumnIndex(name); }
+if (py == NULL) yK = -1;
+else { name = py; yK = mNT->ColumnIndex(name); }
+}
+
+/* --Methode-- */
+void  PINTuple::SelectWt(const char* pw, int nbins)
+{
+nWbins = (nbins > 0) ? nbins : 10;
+if (pw == NULL) wK = -1;  
+else { string name = pw;   wK = mNT->ColumnIndex(name);  }
+ 
+if (wK >= 0) mNT->GetMinMax(wK, wMin, wMax);
+else  { wMin = 0.; wMax = 1.; }
+}
+
+/* --Methode-- */
+void  PINTuple::SelectLabel(const char* plabel)
+{
+if (plabel == NULL) lK = -1;
+else {  string name = plabel;  lK = mNT->ColumnIndex(name);  }
+}
+
+/* --Methode-- */
+void  PINTuple::SelectErrBar(const char* erbx, const char* erby)
+{
+string name;
+if (mNT == NULL)  xebK = yebK = -1;
+if (erbx == NULL) xebK = -1;
+else { name = erbx;  xebK = mNT->ColumnIndex(name); }
+if (erby == NULL) yebK = -1;
+else { name = erby;  yebK = mNT->ColumnIndex(name); }
+}
+
+
+/* --Methode-- */
+void PINTuple::UpdateLimits()
+{
+  if (!mNT) return;
+  if (mNT->NbLines() <= 0)  return;
+  if ( (xK < 0) || (yK < 0) )   return;
+
+  // Commencer par trouver nos limites
+  double xmin, xmax, ymin, ymax;
+  xmin = ymin = 9.e19;
+  xmax = ymax = -9.e19;
+  mNT->GetMinMax(xK, xmin, xmax);
+  mNT->GetMinMax(yK, ymin, ymax);
+  PIAxes::ReSizeMinMax(isLogScaleX(),xmin,xmax);
+  PIAxes::ReSizeMinMax(isLogScaleY(),ymin,ymax);
+  SetLimits(xmin,xmax,ymin,ymax);
+//  SetAxesFlags(kBoxAxes | kExtTicks | kLabels);  Ne pas faire - Reza 11/99
+}
+
+
+/* --Methode-- */
+void PINTuple::Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax)
+{
+double xp,yp,xer,yer,wp;
+double xl,yl;
+int nok;
+
+if (!mNT) return;
+if (axesFlags != kAxesNone) DrawAxes(g);
+if ( (xK < 0) || (yK < 0) )  return;
+if (GetGraphicAtt().GetLineAtt() == PI_NotDefLineAtt)  g->SelLine(PI_ThinLine);
+
+//  Pour tracer des markers avec taille fonction de Wt (poids)
+double dw = (wMax-wMin)/nWbins;
+if (dw < 1.e-19) dw = 1.e19;
+int msz,sz;
+
+PIMarker mmrk = GetGraphicAtt().GetMarker();
+PIMarker mrk;
+if (wK >= 0)  mrk = (mmrk != PI_NotDefMarker) ? mmrk : PI_CircleMarker;
+else   mrk = (mmrk != PI_NotDefMarker) ? mmrk : PI_DotMarker;
+ msz = GetGraphicAtt().GetMarkerSz(); 
+if (msz < 1) msz = 1;
+g->SelMarker(msz, mrk);
+
+PIGrCoord uxmin, uxmax, uymin, uymax;
+g->GetGrSpace(uxmin, uxmax, uymin, uymax);
+double xmin2 = uxmin;
+double ymin2 = uymin;
+double xmax2 = uxmax;
+double ymax2 = uymax;
+
+nok = 0;  
+xp = yp = xl = yl = 0;
+for (long i=0; i<(long)mNT->NbLines(); i++) {
+  xl = xp;  yl = yp; 
+  xp = mNT->GetCell(i, xK);
+  yp = mNT->GetCell(i, yK);
+  if ( (xp < xmin2) || (xp > xmax2) || (yp < ymin2) || (yp > ymax2) )  continue;
+  nok++;
+  if ( (xp < xmin) || (xp > xmax) || (yp < ymin) || (yp > ymax) )  continue;
+  if ( (i > 0) && (GetGraphicAtt().GetLineAtt() != PI_NotDefLineAtt) )   
+    g->DrawLine(xl, yl, xp, yp);  // On relie les points ...
+  if ( xebK >= 0 ) {
+    xer = mNT->GetCell(i, xebK);
+    if(xer>0.) g->DrawLine(xp-xer, yp, xp+xer, yp);
+  }
+  if ( yebK >= 0 ) {
+    yer = mNT->GetCell(i, yebK);
+    if(yer>0.) g->DrawLine(xp, yp-yer, xp, yp+yer);
+  }
+  if (wK >= 0) { // Taille de marker en fonction du poids
+    wp = mNT->GetCell(i, wK);
+    sz = (int)((wp-wMin)/dw);
+    if (sz < 0) sz = 0;
+    if (sz > nWbins)  sz = nWbins;
+    sz += msz;
+    if (sz < 2)  g->SelMarker(sz, PI_DotMarker);
+    else g->SelMarker(sz, mrk);
+  }
+  // Trace du marker
+  if ((wK >= 0)||(lK < 0)||(mmrk != PI_NotDefMarker))  g->DrawMarker(xp, yp); 
+  // Trace eventuel du label
+  if (lK >= 0) g->DrawString(xp, yp, mNT->GetCelltoString(i, lK).c_str());
+
+}
+
+if (stats) { // Trace de stats 
+  g->SelFontSz((YMax() - YMin())/30);  
+  // La hauteur de la cellule
+  PIGrCoord a,d;
+  double cH = (double)g->GetFontHeight(a,d);
+  double cellHeight = 1.2 * cH;
+  // Les labels et leurs longueurs -> largeur de la cellule
+  char label[64];
+  sprintf(label, "Nd= %d / Ntot= %d", nok, mNT->NbLines());
+  double cellWidth =   1.1 * (double)g->CalcStringWidth(label);
+  double xu, yu, cw;
+  // Les limites du cadre
+  xu = g->DeltaUCX(XMax(), - cellWidth);
+  yu = g->DeltaUCY(YMax(), - cellHeight);
+  g->DrawLine(xu, YMax(), xu, yu);
+  g->DrawLine(xu, yu, XMax(), yu);
+  // L'ecriture des labels (attention aux inversions possibles des axes!)
+  cw = (g->isAxeXDirRtoL()) ? -0.05*cellWidth : -0.95*cellWidth;
+  xu = g->DeltaUCX(XMax(),cw);
+  cw = (g->isAxeYDirUpDown()) ? -0.1*cH : -1.1*cH;
+  yu = g->DeltaUCY(YMax(),cw);
+  g->DrawString(xu,yu,label);
+}
+
+return;
+}
+
+/* --Methode-- */
+void PINTuple::AppendTextInfo(string& info, double xmin, double ymin, double xmax, double ymax)
+{
+if (!mNT) return;
+if ( (xK < 0) || (yK < 0) )  return;
+
+int ncnt = 0;
+double xp,yp;
+char buff[128];
+sprintf(buff,"PINTuple: NLines= %d  NCol= %d \n", mNT->NbLines(),  mNT->NbColumns());
+info += buff;
+info += mNT->LineHeaderToString();
+for(long i=0; i<(long)mNT->NbLines(); i++) {
+  xp = mNT->GetCell(i, xK);
+  yp = mNT->GetCell(i, yK);
+  if ( (xp < xmin) || (xp > xmax) || (yp < ymin) || (yp > ymax) )  continue;
+  ncnt++;
+  if (ncnt > 101) continue;
+  info += mNT->LineToString(i);
+  }
+if (ncnt >= 101) info += " .... \n";
+sprintf(buff," %d points inside selected region \n", ncnt);
+info += buff;
+// printf("PINTuple::AppendTextInfo()-DBG %g %g %g %g - %d\n", xmin, ymin, xmax, ymax, ncnt); 
+return;
+}
+
+/*  La methode DecodeOptionString permet de decoder un ensemble d'options 
+    et de parametre d'affichage specifie sous forme d'un vecteur de string.
+    Si rmdecopt == true, les options decodees sont supprimees du vecteur 
+    de string fourni en entree - ce qui permet l'enchainement eventuel 
+    de plusieurs decodages de string.
+    Les options peuvent etre sous forme de flag : "stat" "nostat" 
+    ou plus complexes, par exemple "dynamic=-3,3"
+    Rc: La methode renvoie le nombre d'options decodees 
+*/
+
+/* --Methode-- */
+int PINTuple::DecodeOptionString(vector<string> & opt, bool rmdecopt)
+{
+  int optsz1 = opt.size();
+  if(optsz1<1)  return(0);  
+  // On appelle d'abord le decodage de la classe PIDrawer de laquelle
+  // on herite. (Pas obligatoire) on decode donc ici les attributs de
+  // couleur, fontes ...
+  int ndec1 = PIDrawer::DecodeOptionString(opt, rmdecopt);
+  if(optsz1-ndec1<1) return(ndec1);  // si tout a ete decode
+
+  vector<string> udopt;  // On gardera ici les options non decodees
+  unsigned int k = 0;
+  int ndec = opt.size();
+  for( k=0; k<opt.size(); k++ ) {
+    string opts = opt[k];
+    if(opts=="sta" || opts=="stat" || opts=="stats") SetStats(true);
+    else if(  opts=="nsta"   || opts=="nstat"
+           || opts=="nostat" || opts=="nostats") SetStats(false);
+    else {
+      // Si option non decode
+      ndec--;
+      // S'il faut supprimer les options decodees
+      if (rmdecopt)  udopt.push_back(opts);
+    }
+  }  
+  // S'il faut supprimer les options decodees, on remplace l'argument opt
+  // par le vecteur des options non decodees.
+  if (rmdecopt)  opt = udopt;
+  return(ndec+ndec1);  
+}
+
+/* La methode GetOptionsHelpInfo(string& info) renvoie une chaine 
+   avec la description des options comprises par ce drawer  
+   Note: Il est preferable de ne pas initialiser la chaine 
+   string info au depart, afin de permettre de mettre bout a 
+   bout les aides de differents Drawer */
+
+/* --Methode-- */
+void PINTuple::GetOptionsHelpInfo(string& info)
+{
+// On recupere d'abord la chaine info de la classe de base
+PIDrawer::GetOptionsHelpInfo(info);
+info += " ---- PINTuple options help info : \n" ;
+info += "- sta,stat,stats:            activate   statistic display\n";
+info += "  nsta,nstat,nostat,nostats: deactivate statistic display\n";
+return;
+}
Index: /tags/V_Dec2002/SophyaPI/PIext/pintuple.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/pintuple.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/pintuple.h	(revision 2309)
@@ -0,0 +1,49 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Module PI : Peida Interactive  PINTuple et PINTupleWdg
+// Traceur d objet de type NTupleInterface
+
+#ifndef PINTUPLE_H
+#define PINTUPLE_H
+
+#include "ntupintf.h"
+#include "pidrawer.h"
+
+class PINTuple : public PIDrawer {
+public:
+                     PINTuple(NTupleInterface* nt, bool ad);
+  virtual           ~PINTuple();
+  
+
+  virtual void       Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax);
+  virtual void       UpdateLimits();
+  
+  virtual void       SelectXY(const char* px, const char* py);
+  virtual void       SelectWt(const char* pw=NULL, int nbins=10);
+  virtual void       SelectErrBar(const char* erbx=NULL, const char* erby=NULL);
+  virtual void       SelectLabel(const char* plabel=NULL);
+
+  inline  void       SetStats(bool fg=true) { stats = fg; }
+  virtual void       AppendTextInfo(string& info, double xmin, double ymin, double xmax, double ymax);
+
+//   Methode de decodage des options
+  virtual int        DecodeOptionString(vector<string> & opt, bool rmdecopt=true);
+//   Texte d'aide des options disponibles
+  virtual void       GetOptionsHelpInfo(string& info);
+       
+protected:
+  NTupleInterface* mNT;
+  bool mAdDO;
+  int xK, yK;          // Index du nom de variable en X/Y ds le ntuple
+  int xebK, yebK;      // Index du nom de variable en ErrBarX/Y ds le ntuple
+  int wK;              // Index du nom de variable poids
+  int lK;              // Index du nom de variable label (affiche en texte)
+  double wMin, wMax;        // Valeurs de poids min/max
+  int nWbins;               // Nombre de bins pour le poids (Wt)
+  bool stats;               // true -> indication du nb de points
+};
+
+#endif
+
+
+
+
Index: /tags/V_Dec2002/SophyaPI/PIext/pipodrw.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/pipodrw.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/pipodrw.cc	(revision 2309)
@@ -0,0 +1,133 @@
+//  Adaptateurs et Drawers divers pour Outils PEIDA++
+//                             R. Ansari  06-08/98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "pipodrw.h"
+#include "generalfit.h"
+
+
+//================================================================
+// PIGFFDrawer
+//================================================================
+
+PIGFFDrawer::PIGFFDrawer(GeneralFunction* f)
+: mFunc(f), mNParms(f->NPar()), mParms(new double[mNParms])
+{
+  ASSERT(f->NVar() == 1);
+}
+
+PIGFFDrawer::~PIGFFDrawer()
+{
+  delete[] mParms;
+}
+
+void
+PIGFFDrawer::SetParms(double const* p)
+{
+  for (int i=0; i<mNParms; i++)
+    mParms[i] = p[i];
+}
+
+
+void
+PIGFFDrawer::Draw(PIGraphicUC* g, double /*xmin*/, double/*ymin*/, double/*xmax*/, double/*ymax*/)
+{
+  PIGrCoord x1, x2, y1, y2;
+  g->GetGrSpace(x1, x2, y1, y2);
+  double xMax = x2;
+  double xMin = x1;
+  double yMax = y2;
+  double yMin = y1;
+  double xStep = (xMax - xMin)/100;
+  double xOld = xMin;
+  double yOld = 0;
+//  double yOld = f->Value(&xMin, mParms);
+  for (double x = xMin+xStep; x<xMax; x+=xStep) {
+   double y = 0; // $CHECK$
+//    double y = f->Value(&x, mParms);
+    if (y>yMin && yOld>yMin && 
+        y<yMax && yOld<yMax) 
+           g->DrawLine(xOld, yOld, x, y);
+    xOld = x;
+    yOld = y;
+  }
+}
+
+
+// ----------------------------------------------------------
+// Adaptateur d'Histo-2D Peida++ a P2DArrayAdapter
+// ----------------------------------------------------------
+
+/* --Methode-- */
+POH2DAdapter::POH2DAdapter(Histo2D* h2d, bool ad)
+        : P2DArrayAdapter(h2d->NBinX(), h2d->NBinY())
+{
+aDel = ad; mH2d = h2d;
+DefineXYCoordinates(h2d->XMin(), h2d->YMin(), h2d->WBinX(), h2d->WBinY() );
+}
+
+/* --Methode-- */
+POH2DAdapter::~POH2DAdapter()
+{
+if (aDel)  delete mH2d;
+}
+
+/* --Methode-- */
+double POH2DAdapter::Value(int ix, int iy)
+{
+return((*mH2d)(ix, iy));
+}
+
+
+#ifdef SANS_EVOLPLANCK
+
+// ----------------------------------------------------------
+// Adaptateur de vecteurs Peida++ a P1DArrayAdapter
+// ----------------------------------------------------------
+
+/* --Methode-- */
+POVectorAdapter::POVectorAdapter(Vector* v, bool ad)
+        : P1DArrayAdapter(v->NElts())
+{
+aDel = ad; mVec = v;
+}
+
+/* --Methode-- */
+POVectorAdapter::~POVectorAdapter()
+{
+if (aDel) delete mVec;
+}
+
+/* --Methode-- */
+double POVectorAdapter::Value(int i)
+{ 
+return((*mVec)(i)); 
+}
+
+// ----------------------------------------------------------
+// Adaptateur de matrice Peida++ a P2DArrayAdapter
+// Attention  Y: Lignes (rows)  X: Colonnes
+// ----------------------------------------------------------
+
+/* --Methode-- */
+POMatrixAdapter::POMatrixAdapter(Matrix* mtx, bool ad)
+        : P2DArrayAdapter(mtx->NCol(), mtx->NRows())
+{
+aDel = ad; mMtx = mtx;
+}
+
+/* --Methode-- */
+POMatrixAdapter::~POMatrixAdapter()
+{
+if (aDel)  delete mMtx;
+}
+
+/* --Methode-- */
+double POMatrixAdapter::Value(int ix, int iy)
+{
+// Attention MatrixAdapter(X=Colonne, Y= Row) = Matrix(row, col)  
+return((*mMtx)(iy, ix));
+}
+
+#endif   // SANS_EVOLPLANCK
+
Index: /tags/V_Dec2002/SophyaPI/PIext/pipodrw.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/pipodrw.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/pipodrw.h	(revision 2309)
@@ -0,0 +1,80 @@
+// This may look like C code, but it is really -*- C++ -*-
+//  Adaptateurs et Drawers divers pour Outils PEIDA++
+//                             R. Ansari  06-08/98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PIPODRW_H_SEEN
+#define PIPODRW_H_SEEN
+
+#include "machdefs.h"
+#include "pidrawer.h"
+#include "parradapter.h"
+#include "histos2.h"
+
+#ifdef SANS_EVOLPLANCK
+class GeneralFunction;
+#else
+namespace SOPHYA {class GeneralFunction;} 
+#endif
+
+class PIGFFDrawer : public PIDrawer {
+public:
+                     PIGFFDrawer(GeneralFunction*);
+  virtual           ~PIGFFDrawer();
+  
+  virtual void       Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax);
+  virtual void       SetParms(double const*);
+protected:
+  GeneralFunction*    mFunc;
+  int                 mNParms;
+  double*             mParms;
+};
+
+
+
+// Adaptateur d'Histo-2D Peida++ a P2DArrayAdapter
+class POH2DAdapter :  public P2DArrayAdapter {
+public :
+                  POH2DAdapter(Histo2D* h2d, bool ad=false);
+  virtual         ~POH2DAdapter();
+
+  virtual double  Value(int ix, int iy);   
+
+protected:
+  bool aDel;
+  Histo2D* mH2d;
+};
+
+#ifdef SANS_EVOLPLANCK
+#include "cvector.h"
+#include "matrix.h"
+
+// Adaptateur de vecteurs Peida++ a P1DArrayAdapter
+class POVectorAdapter : public P1DArrayAdapter {
+public :
+                  POVectorAdapter(Vector* v, bool ad=false);
+  virtual         ~POVectorAdapter();
+  virtual double  Value(int i);
+
+protected:
+  bool aDel;
+  Vector* mVec;
+};
+
+// Adaptateur de matrice Peida++ a P2DArrayAdapter
+// Attention MatrixAdapter(X=Colonne, Y= Row) = Matrix(row, col)  
+class POMatrixAdapter :  public P2DArrayAdapter {
+public :
+                  POMatrixAdapter(Matrix* mtx, bool ad=false);
+  virtual         ~POMatrixAdapter();
+
+  virtual double  Value(int ix, int iy);   
+
+protected:
+  bool aDel;
+  Matrix* mMtx;
+};
+
+#endif   // SANS_EVOLPLANCK
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/pisiadw.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/pisiadw.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/pisiadw.cc	(revision 2309)
@@ -0,0 +1,337 @@
+#include "machdefs.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <typeinfo>
+
+#include "perrors.h"
+#include "ctimer.h"
+
+#include "nbmath.h"
+
+#include "pistdimgapp.h"
+#include "nobjmgr.h"
+#include "servnobjm.h"
+
+
+
+/* ........................................................... */
+/*  Classe ObjMgrWind  interface de gestion d'objets nommes    */
+/* ........................................................... */
+
+/* --Methode-- */
+ObjMgrWind::ObjMgrWind(PIStdImgApp *par)
+: PIWindow((PIMsgHandler *)par, "objmgr", PIWK_normal, 
+           400, 300, 250, 250)
+{
+int i;
+dap = par;
+
+int bsx, bsy;
+int tsx, tsy;
+int spx, spy;
+// On definit la taille a partir de la taille par defaut des composantes 
+PIApplicationPrefCompSize(bsx, bsy);
+spx = bsx/4;   spy = bsy/4;
+tsx = 4.0*bsx+3*spx;  tsy = 6*bsy+7*spy;
+SetSize(tsx,tsy);
+dirlist = new PIOptMenu(this, "dirlist", 2.5*bsx, bsy, spx+0.25*bsx, spy); 
+dirlist->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+objlist = new PIList(this, "objlist", 3*bsx, tsy-3*spy-bsy, spx, 2*spy+bsy);
+objlist->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+// objlist->SetBorderWidth(2);
+
+int py = spy;
+int px = 2*spx+3*bsx;
+mBut[0] = new PIButton(this, "SetCurObj", 10, bsx, bsy, px, py);   py += (bsy+spy);
+mBut[1] = new PIButton(this, "Display", 20, bsx, bsy, px, py);   py += (bsy+spy);
+mBut[2] = new PIButton(this, "Print",   30, bsx, bsy, px, py);   py += (bsy+spy);
+mBut[3] = new PIButton(this, "SavePPF", 40, bsx, bsy, px, py);   py += (bsy+spy);
+mBut[4] = new PIButton(this, "Delete",  50, bsx, bsy, px, py);   py += (bsy+spy);
+mBut[5] = new PIButton(this, "Dismiss", 90, bsx, bsy, px, py);   py += (bsy+spy);
+
+for(i=0; i<6; i++)
+  mBut[i]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+// FinishCreate(); pas necessaire ?
+}
+
+/* --Methode-- */
+ObjMgrWind::~ObjMgrWind()
+{
+int i;
+delete dirlist;
+delete objlist;
+for(i=0; i<6; i++)  delete mBut[i];
+}
+
+/* --Methode-- */
+void ObjMgrWind::Show()
+{
+// dap->SetBlocked();  Ce n'est plus necessaire - Reza 11/12/99
+string cdir;
+dap->ObjMgr()->GetCurrentDir(cdir);
+cdir = '/' + cdir;
+dirlist->SetValueStr(cdir);
+dap->ObjMgr()->UpdateObjMgrWindow(dirlist->GetValue()-30000);
+PIWindow::Show();
+return;
+}
+
+
+/* --Methode-- */
+void ObjMgrWind::Process(PIMessage msg, PIMsgHandler* /*sender*/, void* /*data*/)
+{
+
+  // PIMessage ssg = ModMsg(msg);
+msg = UserMsg(msg);
+if (msg == 90)  {
+  dap->SetReady();
+  this->Hide();
+  return;
+  }
+else if (msg >= 30000) {
+  dap->ObjMgr()->UpdateObjMgrWindow(msg-30000);
+  return;
+  }
+/*
+ else if (msg == 10) {
+  string cdir = dirlist->GetValueStr();
+  dap->ObjMgr()->SetCurrentDir(cdir);
+  return;
+  }
+*/
+
+string nom = "";
+string sel = "";
+if ( (msg == 10) || (msg == 20) || (msg == 30) || (msg == 40) || (msg == 50) ) {
+  sel = objlist->GetSelectionStr();
+  //  size_t p = sel.find_first_not_of(" \t");
+  //  if (p<0) p = 0;
+  size_t l = sel.length(); 
+  size_t q = sel.find_first_of(" \t");
+  if (q > l)   q = l; 
+  nom = dirlist->GetValueStr() + '/' + sel.substr(0, q);
+  }
+
+NamedObjMgr* om = dap->ObjMgr();
+if (om == NULL)  return;
+if (sel.length() < 1)  return;
+if (nom.length() < 1)  return;
+
+switch (msg)
+  {
+  case 10:
+    {
+    string cmd = "set cobj " + nom ;
+    cout << " Setting current object ($cobj) to " << nom << endl;
+    dap->CmdInterpreter()->Interpret(cmd);
+    }
+    break;
+  case 20:
+    om->DisplayObj(nom);
+    break;
+  case 30:
+    om->PrintObj(nom);
+    break;
+  case 40:
+    if (dap->mPpfout)  om->SaveObj(nom, *(dap->mPpfout), false);
+    break;
+  case 50:
+    om->DelObj(nom);
+    //    objlist->DeleteItemMsg(objlist->GetSelection());
+    //    dap->ObjMgr()->UpdateObjMgrWindow(dirlist->GetValue()-30000);
+    break;
+
+  default:    
+    //    printf("DEBUG/ObjMgrW::Process %d %d \n", (int)msg, (int)ssg); 
+    break;
+  }
+    
+return;
+}
+
+/* --Methode-- */
+void ObjMgrWind::UpdateList(int did)
+{
+if (!Visible()) return;
+if (did != (dirlist->GetValue()-30000) )  return;
+dap->ObjMgr()->UpdateObjMgrWindow(did);
+return;
+}
+
+/* --Methode-- */
+void ObjMgrWind::AddObjList(int did, const char * objn, int oid)
+{
+if (!Visible()) return;
+if (did != (dirlist->GetValue()-30000) )  return;
+mNitem++;  objlist->AppendItem(objn, oid);
+}
+
+/* --Methode-- */
+void ObjMgrWind::DelObjList(int did, int oid)
+{
+if (!Visible()) return;
+//DBG printf("DBG-DelObjList %d , %d , (%d) \n", did, dirlist->GetValue()-30000, oid);
+if (did != (dirlist->GetValue()-30000) )  return;
+objlist->DeleteItemMsg(oid);
+}
+
+/* ........................................................... */
+/*  Classe PPInMgrWind  interface de gestion d'objets nommes    */
+/* ........................................................... */
+
+/* --Methode-- */
+PPInMgrWind::PPInMgrWind(PIStdImgApp *par)
+: PIWindow((PIMsgHandler *)par, "PPF-FileManager", PIWK_dialog, 
+           400, 300, 250, 250)
+{
+int i;
+dap = par;
+
+int bsx, bsy;
+int tsx, tsy;
+int spx, spy;
+// On definit la taille a partir de la taille par defaut des composantes 
+PIApplicationPrefCompSize(bsx, bsy);
+spx = bsx/4;   spy = bsy/3;
+bsx *= 1.25;
+ttx = tsx = 3*bsx+8*spx;   tty = tsy = 7*bsy+5*spy;
+SetSize(tsx,tsy);
+
+mLab[0] = new PILabel(this, "filename", tsx-spx, bsy-spy, spx/2, spy/2);
+mLab[0]->SetLabel("");
+mLab[0]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic,PIBK_elastic);
+mLab[0]->SetBorderWidth(1);
+
+polx = spx/2;  poly = bsy+1.5*spy;
+tolx = tsx-spx;   toly = tsy-2*bsy-5*spy;
+int py = tsy-2*spy-bsy;
+int px = 2*spx;
+mBut[0] = new PIButton(this, "Read", 2500, bsx, bsy, px, py);   px += (bsx+2*spx);
+mBut[1] = new PIButton(this, "ReadAll", 2600, bsx, bsy, px, py);   px += (bsx+2*spx);
+mBut[2] = new PIButton(this, "Close", 2700, bsx, bsy, px, py);   px += (bsx+2*spx);
+
+for(i=0; i<3; i++)
+  mBut[i]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+  
+objlist = NULL;
+mLab[1] = NULL;
+mPin = NULL;
+
+//   FinishCreate(); pas necessaire 
+}
+
+/* --Methode-- */
+PPInMgrWind::~PPInMgrWind()
+{
+int i;
+if (objlist) delete objlist;
+delete mLab[0];
+for(i=0; i<3; i++)  delete mBut[i];
+}
+
+/* --Methode-- */
+void PPInMgrWind::SetFile(string flnm)
+{
+char strg[128];
+char* nom;
+char  noms[32];
+int i, cid, key, ln;
+
+bool ok = true;
+#ifdef SANS_EVOLPLANCK
+TRY {
+  mPin = new PInPersist(flnm);
+}  CATCH(merr) 
+  { printf("ObjMgrWind::SetFile Exception= %ld (%s) \n", (long)merr, PeidaExc(merr)); 
+  ok = false; } ENDTRY;
+#else
+try {
+  mPin = new PInPersist(flnm);
+  }
+catch (IOExc iox) {
+  cerr << "ObjMgrWind::SetFile/Error Exception - Msg= " << iox.Msg() << endl;
+  ok = false;
+  }
+#endif
+
+if (!ok) { mPin = NULL;  dap->SetReady(); return; }
+
+if (mPin->NbTags() < 1) {
+  delete mPin;   mPin = NULL;
+  string no="";
+  dap->ObjMgr()->ReadObj(flnm,no);
+  return;
+}
+if (objlist)  delete objlist;
+SetSize(ttx,tty);
+mLab[0]->SetLabel(flnm);
+objlist = new PIList(this, "infileobjlist", tolx, toly, polx, poly);
+objlist->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+objlist->SetBorderWidth(2);
+
+
+#ifdef SANS_EVOLPLANCK
+for(i=0; i<mPin->NbTags(); i++) {
+  key = mPin->TagKey(i, cid, ln);  // $CHECK$ non-const & reference initialized to temporary, car int -> long&
+  if (ln <= 0)  nom = "?";
+  else { strncpy(noms, mPin->TagName(i).c_str(), 31);  noms[31] = '\0'; nom = noms; }
+  sprintf(strg, "%s  (T=%s, Key=%d)",  nom, dap->ObjMgr()->GetServiceObj()->PClassIdToClassName(cid), key);
+  //  sprintf(strg, "%s  (T=%s, Key=%d)",  nom, " DataObject ?", key);  Attention SANS_EVOLPLANCK
+  objlist->AppendItem(strg, 5000+i);
+}
+#else
+string tn;
+for(i=0; i<mPin->NbTags(); i++) {
+  tn = mPin->GetTagName(i);
+  objlist->AppendItem(tn.c_str(), 5000+i);
+}
+#endif
+
+}
+
+/* --Methode-- */
+void PPInMgrWind::Show()
+{
+if (mPin == NULL)   return;
+dap->SetBlocked();
+PIWindow::Show();
+return;
+}
+
+/* --Methode-- */
+void PPInMgrWind::Process(PIMessage msg, PIMsgHandler* /*sender*/, void* /*data*/)
+{
+
+int sel;
+msg = UserMsg(msg);
+
+if (msg == 2700)  {
+  delete mPin;  mPin = NULL;
+  delete objlist; objlist = NULL;
+  dap->SetReady();
+  this->Hide();
+  return;
+}
+
+NamedObjMgr* om = dap->ObjMgr();
+switch (msg)
+  {
+  case 2500:
+    sel = (PIMessage)objlist->GetSelection() - 5000;
+    if (sel >= 0) om->ReadObj((*mPin), sel);
+    break;
+  case 2600:
+    om->ReadObj((*mPin), -1);
+    dap->SetReady();
+    this->Hide();
+    break;
+
+  default:    
+    break;
+  }
+    
+return;
+}
Index: /tags/V_Dec2002/SophyaPI/PIext/pisiadw.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/pisiadw.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/pisiadw.h	(revision 2309)
@@ -0,0 +1,72 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe de fenetre pour gestion d'objet et PPF-In
+// Reza      Aout 97 , Juillet,Aout 98, Ete 99
+// CEA-DAPNIA      LAL-IN2P3/CNRS
+
+#ifndef PISIADW_H_SEEN
+#define PISIADW_H_SEEN
+
+#include <string.h>
+
+#include "pisysdep.h"
+
+#include PIAPP_H
+#include PIWIN_H 
+#include PIMENU_H 
+#include PIOPTMENU_H 
+#include PISTDWDG_H 
+#include PILIST_H 
+
+
+class PIStdImgApp;
+
+
+
+/* --------------------------------------------------------------------------- */
+class ObjMgrWind : public PIWindow {
+public :
+  ObjMgrWind(PIStdImgApp *par);
+  ~ObjMgrWind();
+  virtual void  Show();
+  virtual void  Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+  inline  void  AddDirectory(const char * dir, int did)
+                    { dirlist->AppendItem(dir, 30000+did); }
+  inline  void  DelDirectory(int did)
+                    { dirlist->Menu()->DeleteItemMsg(30000+did); }
+  inline  void  ClearObjList() 
+                    { mNitem=0; objlist->DeleteAllItems(); }
+  inline  void	AddObj(const char * objn, int oid) 
+		    { mNitem++;  objlist->AppendItem(objn, oid); }
+
+  virtual void  UpdateList(int did);
+  virtual void	AddObjList(int did, const char * objn, int oid); 
+  virtual void	DelObjList(int did, int oid); 
+
+private:
+  PIStdImgApp* dap;
+  PIOptMenu* dirlist;
+  int mNitem;
+  PIList* objlist;
+  PIButton * mBut[6];
+};
+
+/* --------------------------------------------------------------------------- */
+class PPInMgrWind :  public PIWindow {
+public:
+   PPInMgrWind(PIStdImgApp *par);
+   ~PPInMgrWind();
+   virtual void  Show();
+   virtual void  Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+   void SetFile(string flnm);
+private:
+  PIStdImgApp* dap;
+  PIList* objlist;
+  PILabel * mLab[2];
+  PIButton* mBut[3];
+  PInPersist* mPin;
+  int tolx, toly, polx, poly;  // Taille et position de  objlist
+  int ttx, tty;   // Taille globale par defaut
+
+};
+ 
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/pistdimgapp.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/pistdimgapp.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/pistdimgapp.cc	(revision 2309)
@@ -0,0 +1,1983 @@
+#include "machdefs.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <typeinfo>
+
+#include <string>
+#include <vector>
+
+#include "strutil.h"
+#include "timing.h"
+#include "perrors.h"
+#include "ctimer.h"
+
+#include "psighand.h"
+
+#include "cimage.h" // pour pouvoir faire extract 
+
+#include "pistdimgapp.h"
+#include "servnobjm.h"
+// #include "pihisto2d.h"
+#include "psfile.h"
+#include "piimgtools.h"
+#include "pidrwtools.h"
+#include "piaxestools.h"
+
+#include "pistzwin.h"
+
+#include "piinit.h"
+#include "piversion.h"
+#include "piaversion.h"
+
+
+static char ImgDir[256];
+static char WorkDir[256];
+// Initialiseur
+static PIAppInitiator * glst_piai = NULL; 
+
+// Pour la creation de fenetre info (about piapp)
+static void createInfoWindow(PIStdImgApp* app);
+static void deleteInfoWindow();
+static void showInfoWindow(PIStdImgApp* app);
+static void hideInfoWindow(PIStdImgApp* app);
+
+
+/* ........................................................... */
+/*    Classe SIA_RU__Periodic : mise a jour periodique de      */
+/*    la fenetre Stat/Ressource info                           */
+/*    + execution de commande soumis de l'exterieur            */
+/* ........................................................... */
+
+class SIA_RU__Periodic : public PIPeriodic 
+{
+public:
+  SIA_RU__Periodic(PIStdImgApp* app);
+  virtual ~SIA_RU__Periodic();
+  virtual void DoPeriodic();
+private:
+  PIStdImgApp* _app;
+};
+
+SIA_RU__Periodic::SIA_RU__Periodic(PIStdImgApp* app)
+  : PIPeriodX(1)
+{
+  _app = app;
+}
+
+SIA_RU__Periodic::~SIA_RU__Periodic()
+{
+}
+
+void SIA_RU__Periodic::DoPeriodic()
+{
+  if (_app) { 
+    _app->ExecuteExtCommand();
+    _app->UpdateStatResourceInfo();
+  }
+}
+
+/* ............................................................. */
+
+
+/* ........................................................... */
+/*                    Classe PIStdImgApp                         */
+/* ........................................................... */
+
+/* --Methode-- */
+PIStdImgApp::PIStdImgApp(int narg, char* arg[])
+: PIApplication(420, 320, narg, arg)
+{
+
+// Les menus
+m[0] = new PIMenu(Menubar(),"Fichier");
+m[0]->AppendItem("About piapp", 10150);
+m[0]->AppendItem("Open-Fits", 10120);
+m[0]->AppendItem("Open-PPF", 10130);
+#ifndef SANS_EVOLPLANCK
+m[0]->AppendItem("Open-ASCII", 10140);
+#endif
+// m[0]->AppendItem("Options", 10101);
+m[0]->AppendItem("Help", 10100);
+m[0]->AppendSeparator();
+m[0]->AppendItem("Exit", 10105);
+
+m[1] = new PIMenu(Menubar(),"Objets");
+m[1]->AppendItem("ObjectManager", 10201);
+m[1]->AppendItem("OpenOutPPF", 10220);
+m[1]->AppendItem("CloseOutPPF", 10230);
+m[1]->AppendItem("Delete CurWdg", 10270);
+
+m[2] = new PIMenu(Menubar(),"Tools");
+m[2]->AppendItem("Show ImageTools", 10301);
+m[2]->AppendItem("Show DrawerTools", 10302);
+m[2]->AppendItem("Show AxesTools", 10303);
+m[2]->AppendItem("CxxExecutorWindow", 10304);
+m[2]->AppendItem("Ext.Pave", 10311);
+m[2]->SetSensitivityMsg(10311, false);
+m[2]->AppendItem("Ext.Pave+Org", 10312);
+m[2]->SetSensitivityMsg(10312, false);
+m[2]->AppendItem("Cuts X,Y", 10313);
+m[2]->SetSensitivityMsg(10313, false);
+mc = new PIMenu(m[2], "StackTools");
+mc->AppendItem("DispNext", 10320);
+mc->AppendItem("Blink 0.5s", 10321);
+mc->AppendItem("Blink 1s", 10322);
+mc->AppendItem("Blink 2s", 10324);
+mc->AppendItem("Stop Blink", 10329);
+mc->AppendItem("RemoveCurrent", 10330);
+m[2]->AppendPDMenu(mc);
+m[2]->SetSensitivity("StackTools", false);
+
+m[3] = new PIMenu(Menubar(),"Window");
+m[3]->AppendItem("StackWindow", 10400);
+m[3]->AppendItem("Window", 10411);
+m[3]->AppendItem("Window 2x1", 10421);
+// m[3]->AppendItem("Window 1x2", 10412);
+m[3]->AppendItem("Window 2x2", 10422);
+// m[3]->AppendItem("Window 3x1", 10431);
+m[3]->AppendItem("Window 3x3", 10433);
+m[3]->AppendItem("Cur->LastWdg", 10441);
+m[3]->AppendItem("Close CurWin", 10460);
+m[3]->AppendCheckItem("StatZoomWin", 10470);
+m[3]->SetStateMsg(10470, true);
+
+m[4] = new PIMenu(Menubar(),"PostScript");
+m[4]->AppendItem("OpenPS", 10501);
+m[4]->AppendItem("ClosePS", 10505);
+m[4]->AppendItem("Window->PS", 10511);
+m[4]->AppendItem("Image->PS", 10515);
+m[4]->AppendItem("Window->EPS", 10512);
+m[4]->AppendItem("Image->EPS", 10516);
+m[4]->SetSensitivityMsg(10515, false);
+m[4]->SetSensitivityMsg(10516, false);
+
+m[5] = new PIMenu(Menubar(),"Special");
+m[5]->AppendItem("CloseAll", 10601);
+m[5]->AppendCheckItem("Red.Out/Err", 10602);
+m[5]->AppendCheckItem("Catch SigFPE", 10603);
+m[5]->AppendCheckItem("Catch SigSEGV", 10604);
+m[5]->AppendCheckItem("ObjMgr Verb", 10605);
+m[5]->AppendItem("CxxExecOption", 10606);
+
+m[6] = new PIMenu(Menubar(),"Modules");
+
+AppendMenu(m[0]);
+AppendMenu(m[1]);
+AppendMenu(m[2]);
+AppendMenu(m[3]);
+AppendMenu(m[4]);
+AppendMenu(m[5]);
+// AppendMenu(m[6]);  Menu Modules vide pour le moment 
+
+int scsx, scsy;
+ScreenSize(scsx, scsy);
+if (scsy <= 600)  mFgScSz = 0;
+else if (scsy <= 800)  mFgScSz = 1;
+else if (scsy <= 1024)  mFgScSz = 2;
+else   mFgScSz = 3;
+int msx = 420+mFgScSz*60;
+int msy = 320+mFgScSz*40;
+MainWin()->SetSize(msx, msy);
+
+//------------------------------------------------------
+// On cree un container intermediaire permettant de gerer 
+// le widget zoom, colormap, stats, ...
+
+int bss = 100+mFgScSz*15;
+
+int statc_szy = bss+10+14+mFgScSz*2+5; 
+statcont = new PIContainer(MainWin(), "ZGCSCont", msx, statc_szy, 0, 0);
+statcont->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_fixed, PIBK_free);
+
+gimv = new PIPixmap(statcont, "GloV", bss, bss, 5, 5);
+gimv->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_free, PIBK_free); 
+zoom = new PIPixmap(statcont, "Zoom", bss, bss, bss+10, 5);
+zoom->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_free, PIBK_free); 
+cmapv = new PICMapView(statcont, "CMapView", msx-10, 14+mFgScSz*2, 5, bss+10); 
+cmapv->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_fixed, PIBK_free); 
+
+// Widget pour affichage des stats / ressources 
+lab_mem = new PILabel(statcont, "memlab", msx-2*(bss+20), 20, 2*bss+20, 10);
+lab_mem->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_fixed, PIBK_free); 
+lab_mem->SetLabel("MemoryUsage");
+lab_mem->SetForegroundColor(PI_Red);
+lab_mem->SetBorderWidth(1);
+therm_mem = new PIThermometer(statcont, "memtherm", msx-2*(bss+20), 20, 2*bss+20, 35);
+therm_mem->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_fixed, PIBK_free); 
+therm_mem->SetThreshold(0.5, 0.75);
+
+lab_cpu = new PILabel(statcont, "cpulab", msx-2*(bss+20), 20, 2*bss+20, 60);
+lab_cpu->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_fixed, PIBK_free); 
+lab_cpu->SetLabel("CPUUsage");
+lab_cpu->SetForegroundColor(PI_Black);
+lab_cpu->SetBorderWidth(1);
+therm_cpu = new PIThermometer(statcont, "cputherm", msx-2*(bss+20), 20, 2*bss+20, 85);
+therm_cpu->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_fixed, PIBK_free); 
+therm_cpu->SetThreshold(0.75, 0.90);
+
+ fg_exc_cmd = false;
+UpdateStatResourceInfo();
+resupd_periodic = new SIA_RU__Periodic(this);
+//resupd_periodic->SetIntervalms(500);
+resupd_periodic->Start();
+
+statcont->Show();
+// StatZoomWindowSetVisible(true);
+//------------------------------------------------------
+
+//int cpy = bss+10+14+mFgScSz*2+5;
+int cpy = statc_szy;
+
+// Creation d'une console avec gestion des commandes  
+consolecont = new PIContainer(MainWin(), "ConsoleCont", msx, msy-cpy, 0, cpy );
+consolecont->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_fixed, PIBK_fixed); 
+mCons = new PIConsole(consolecont, "Console", 30200, 512, 132, msx, msy-cpy, 0, 0 );
+mCons->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_fixed, PIBK_fixed); 
+mCons->AcceptCmd(true, 50);
+consolecont->Show();
+redirecout = false;
+// RedirectStdOutErr(true);  pas par defaut 
+ 
+mObjMgr = new NamedObjMgr;
+mCmd = new PIACmd(mObjMgr, this);
+
+// Pas trop de message de la part de NamedObjMgr
+m[5]->SetStateMsg(10605, false);
+mObjMgr->SetVerbose(false);
+
+char* varenv;
+ImgDir[0] = WorkDir[0] = '\0';
+if ( (varenv=getenv("PEIDA_IMAGES")) != NULL )   strncpy(ImgDir, varenv, 256);
+if ( (varenv=getenv("PEIDA_WORK")) != NULL )  strncpy(WorkDir, varenv, 256);
+
+pfc_fits = new PIFileChooser(this,"FITS-FileChooser", 10125); 
+pfc_ppf = new PIFileChooser(this,"PPF-FileChooser", 10135); 
+pfc_ascii = new PIFileChooser(this,"ASCII-FileChooser", 10145); 
+pfc_ps = new PIFileChooser(this,"PS-FileChooser", 10525); 
+
+mObjmgrw = new ObjMgrWind(this);
+mPpinmgrw = new PPInMgrWind(this);
+
+// Attention : A faire apres creation de ObjMgrWind !!! 
+mObjMgr->SetImgApp(this);
+
+// Gestion des feneteres widgets et drawers
+mWId = mDId = mBWId = 0;
+mCurWin = NULL;  
+mCurWdg = NULL;
+mLastWdg = NULL;
+mGrW = NULL;
+mStW = NULL;
+mGrIdx = mStIdx = -1;
+
+mFCMsg = 0;
+mFgCWImg = false;
+
+// Gestion fichiers PS
+num_eps = 0;
+name_ps = "";
+name_ps = "pia.ps";
+mpsfile = new PSFile(name_ps.c_str(),PI_Portrait, PI_A4, 2., 2.);
+
+// Gestion OUT-PPF
+mPpfout = NULL;
+name_outppf = "";
+
+// Attributs graphiques courants
+mAxesFlags = kBoxAxes | kExtTicks | kLabels;
+SetInsetLimits(0.4, 0.6, 0.4, 0.6);
+mAddTitle = true;
+
+// Initialisation 
+glst_piai = new PIAppInitiator(this);
+
+char buff[128];
+mCons->AddStr("  ............  starting piapp .............\n", PIVA_Blue );
+#ifdef SANS_EVOLPLANCK
+sprintf(buff, "Version: piapp=%g  PI=%g  PEIDA=%g \n", (double)PIAPP_VERSIONNUMBER, 
+              (double)PI_VERSIONNUMBER, (float)PeidaVersion());
+#else
+sprintf(buff, "Version: piapp=%g  PI=%g  SOPHYA=%g \n", (double)PIAPP_VERSIONNUMBER, 
+              (double)PI_VERSIONNUMBER, glst_piai->Version());
+#endif
+mCons->AddStr(buff, PIVA_Blue );
+mCons->AddStr("  ..........................................\n", PIVA_Blue );
+// PrintPeidaVersion();
+
+pfc_fits->SetPath(ImgDir);
+pfc_ppf->SetPath(WorkDir);
+pfc_ps->SetPath(WorkDir);
+
+SetReady();
+}
+
+/* --Methode-- */
+PIStdImgApp::~PIStdImgApp()
+{
+int i;
+
+// On inactive la fenetre principale
+//  Sinon, ca peut provoquer un SEGV ds delete de console ?? - Reza 07/2000
+MainWin()->Hide();  
+
+// Destrucion de tous les objets de NameObjMgr
+string patt = "/*/*";
+mObjMgr->DelObjects(patt, true);
+
+delete mc;
+for(i=0; i<7; i++)  
+  if (m[i]) delete m[i];
+
+WindMList::iterator it;
+for(it = mWList.begin(); it != mWList.end(); it++)  delete (*it).second;
+
+delete mObjMgr;
+delete mCmd;
+
+delete zoom;
+delete gimv;
+delete cmapv;
+
+delete lab_mem;
+delete therm_mem;
+delete lab_cpu;
+delete therm_cpu;
+
+delete statcont;
+
+delete pfc_fits;
+delete pfc_ppf;
+delete pfc_ascii;
+delete pfc_ps;
+
+delete mCons;
+delete consolecont;
+
+delete mObjmgrw;
+delete mPpinmgrw;
+
+deleteInfoWindow();
+
+// Les fichiers 
+if (mpsfile) delete mpsfile;
+if (mPpfout) delete mPpfout;
+
+if (resupd_periodic) delete resupd_periodic;
+
+if (glst_piai) delete glst_piai;   glst_piai = NULL;
+
+}  
+
+/* --Methode-- */
+void PIStdImgApp::Process(PIMessage msg, PIMsgHandler* sender, void* data)
+{
+PIWdg *sndw;
+PIMessage tmsg, smm;
+
+tmsg = msg;
+msg = UserMsg(msg);
+smm = ModMsg(tmsg);
+
+//printf("SuperDebug: msg=%d Mod=%d  State=%d\n", (int)msg, (int)smm, (int)GetState());
+if  ((GetState()) && (msg != mFCMsg)) { PIBeep(); return; }
+
+//   Messages active-window
+if (smm == PIMsg_Active)
+  {
+  sndw = dynamic_cast<PIWdg *>(sender);
+  switch(sndw->kind())
+    {
+    case PIWindow::ClassId :
+      mCurWin = dynamic_cast<PIWindow *>(sndw);
+      break;
+
+    case PIScDrawWdg::ClassId :
+    case PIDraw3DWdg::ClassId :
+      mCurWdg = dynamic_cast<PIBaseWdg *>(sender);
+//      cerr << "*DBG11* ImgTools -> NonSensitive " << sndw->kind() << endl;
+      if (mFgCWImg) {
+//        cerr << "*DBG* ImgTools -> NonSensitive " << endl;
+        m[2]->SetSensitivityMsg(10311, false);
+        m[2]->SetSensitivityMsg(10312, false);
+        m[2]->SetSensitivityMsg(10313, false);
+        m[4]->SetSensitivityMsg(10515, false);
+        m[4]->SetSensitivityMsg(10516, false);
+        mFgCWImg = false;
+        }
+      break;
+    case PIImage::ClassId :
+      mCurWdg = dynamic_cast<PIBaseWdg *>(sender);
+      if (!mFgCWImg) {
+//        cerr << "*DBG* ImgTools -> Sensitive " << endl;
+        m[2]->SetSensitivityMsg(10311, true);
+        m[2]->SetSensitivityMsg(10312, true);
+        m[2]->SetSensitivityMsg(10313, true);
+        m[4]->SetSensitivityMsg(10515, true);
+        m[4]->SetSensitivityMsg(10516, true);
+        mFgCWImg = true;
+        }
+      break;
+      /*
+    default :
+      mCurWdg = NULL;
+      if (mFgCWImg) {
+        m[2]->SetSensitivityMsg(10311, false);
+        m[2]->SetSensitivityMsg(10312, false);
+        m[2]->SetSensitivityMsg(10313, false);
+        m[4]->SetSensitivityMsg(10515, false);
+        m[4]->SetSensitivityMsg(10516, false);
+        mFgCWImg = false;
+        }
+      break;
+      */
+    }
+  }
+//  Message window-close
+else if (smm == PIMsg_Close)
+  {
+  sndw = (PIWdg *)sender;
+  if(sndw->kind() == PIWindow::ClassId)
+    {
+    mCurWin = (PIWindow *)sender;
+    if (mCurWin == mStW) m[2]->SetSensitivity("StackTools", false); 
+    DeleteWindow(mCurWin);
+    }
+  else  
+    printf("PIStdImgApp/Bug ? CloseMsd received from NonWindow (%d %d %lx) \n",
+           (int)tmsg,  (int)sndw->kind(), (long)sender);       
+  }
+
+// Traitement des messages des menus 
+else if ( (msg >= 10100) && (msg < 10200) )  MBProcess1(msg, sender, data);
+else if ( (msg >= 10200) && (msg < 10300) )  MBProcess2(msg, sender, data);
+else if ( (msg >= 10300) && (msg < 10400) )  MBProcess3(msg, sender, data);
+else if ( (msg >= 10400) && (msg < 10500) )  MBProcess4(msg, sender, data);
+else if ( (msg >= 10500) && (msg < 10600) )  MBProcess5(msg, sender, data);
+else if ( (msg >= 10600) && (msg < 10700) )  MBProcess6(msg, sender, data);
+else if ( msg == 30200  ) {    // Objet PIConsole 
+  string s = mCons->GetCmdString();
+  //  string s2 = "\nExecuting " + s + "\n";
+  mCons->AddStr("Cmd> ", PIVA_Blue, false);
+  //  s2 = s + "\n";
+  mCons->AddStr(s.c_str(), PIVA_Blue|PIVA_Bold, false);
+  mCons->AddChar('\n', PIVA_Def, true);
+  SetBusy();
+#ifdef SANS_EVOLPLANCK
+  TRY {
+    mCmd->Interpret(s);
+    }  CATCH(merr) { 
+    fflush(stdout); 
+    cout << endl; 
+    cerr << endl;
+    string es = PeidaExc(merr);
+    cerr << "PIStdImgApp::Process()/ Cmd->Do() Exception :" << es << " (" << merr << ")" << endl ;
+    }
+#else
+  try {
+    mCmd->Interpret(s);
+    }  
+  catch ( PThrowable & exc ) {
+    cerr << "\n PIStdImgApp::Process()/ Cmd->Interpret() Exception :" 
+	 << (string)typeid(exc).name() << " Msg= " 
+	 << exc.Msg() << endl;
+    cout << endl; 
+  }
+  catch ( ... ) {
+    cerr << "\n PIStdImgApp::Process()/ Cmd->Interpret() Catched Exception ..." 
+	 << endl;
+    cout << endl; 
+  }
+
+#endif
+  SetReady();
+  }
+
+else printf("PIStdImgApp::Process() BUG?? Msg %d (%d-%d) \n", 
+            (int)tmsg,(int)msg,(int)smm);
+
+
+return;
+}
+
+/* --Methode-- */
+void PIStdImgApp::SetReady()
+{
+mCons->SetSensitive();
+gimv->SetSensitive();
+PIApplication::SetReady();
+}
+
+/* --Methode-- */
+void PIStdImgApp::SetBusy()
+{
+mCons->SetUnSensitive();
+gimv->SetUnSensitive();
+PIApplication::SetBusy();
+// Attention : Appel XSync specifique X11 -  en attendant multi-thread
+XSync(PIXDisplay(), False);  
+}
+
+/* --Methode-- */
+void PIStdImgApp::SetBlocked()
+{
+mCons->SetUnSensitive();
+gimv->SetUnSensitive();
+PIApplication::SetBlocked();
+// Attention : Appel XSync specifique X11 -  en attendant multi-thread
+XSync(PIXDisplay(), False);  
+}
+
+
+/* --Methode-- */
+int PIStdImgApp::DispImage(P2DArrayAdapter* nouv, string const & name, string const& sop, int oid)
+{
+PIImage* pii;
+PIWindow* win;
+int sx, sy, px, py, flag;
+
+if (nouv == NULL)
+  {
+  printf("PIStdImgApp::DispImage_Error  Cannot Display  NULL image \n");
+  return(-1);
+  }
+
+if ( (nouv->XSize() <= 0)  || (nouv->YSize() <= 0))
+  {
+  printf("PIStdImgApp::DispImage_Error Pb Size Sz=%d*%d  \n", 
+          nouv->XSize(), nouv->YSize());
+  return(-1);
+  }
+
+// On decode les options graphiques
+vector<string> opts;
+DispWinEnum dwopt = ParseDisplayOption(sop, opts);
+
+// Pas de same ou inset pour DispImage
+if ((dwopt == Disp_Same) || (dwopt == Disp_Inset) ) dwopt = Disp_Next;
+
+// Choix de la taille de fenetre
+#define MINPIIMGSIZE 100
+sx = (nouv->XSize() > MINPIIMGSIZE) ? nouv->XSize() : MINPIIMGSIZE;
+sy = (nouv->YSize() > MINPIIMGSIZE) ? nouv->XSize() : MINPIIMGSIZE;
+if (sx > 400+mFgScSz*100) sx = 400+mFgScSz*100;
+if (sy > 400+mFgScSz*100) sy = 400+mFgScSz*100;
+px = py = 0;
+win = GetWindow(dwopt, sx, sy, px, py, flag, (char *)name.c_str());
+pii = new PIImage(win, (char *)name.c_str(), sx, sy, px,py);
+pii->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+pii->SetZoomWin(zoom, false);
+pii->SetGloVWin(gimv, false);
+pii->SetCMapWin(cmapv, false);
+pii->ShowCursor(true);
+pii->SetUserData(NULL, oid);
+
+
+// On recalcule la taille de la fenetre si Disp_Win
+if (dwopt == Disp_Win) {
+  int sx2 = (int)((float)nouv->XSize()*pii->GetZoomF());
+  int sy2 = (int)((float)nouv->YSize()*pii->GetZoomF());
+  
+  if (sx2 > 400+mFgScSz*100) sx2 = 400+mFgScSz*100;
+  if (sy2 > 400+mFgScSz*100) sy2 = 400+mFgScSz*100;
+  if (sx2 < MINPIIMGSIZE) sx = MINPIIMGSIZE;
+  if (sy2 < MINPIIMGSIZE) sy = MINPIIMGSIZE;
+  if ((sx2 != sx) || (sy2 != sy))  win->SetSize(sx2, sy2);
+}
+
+pii->SetImage(nouv, true, false);
+
+// decode des options en chaine de caracteres
+if (mAxesAtt.size() > 0) 
+  pii->DecodeOptionString(mAxesAtt, false);   // Les options d'axe
+if (mDefaultAtt.size() > 0) 
+  pii->DecodeOptionString(mDefaultAtt, false);  // d'abord les options par defaut
+if (opts.size() > 0) 
+  pii->DecodeOptionString(opts);    // ensuite, les options specifies en argument
+
+// printf("!!DBG!! PIImage Pos= %d %d  Size= %d %d \n", pii->XPos(), pii->YPos(), pii->XSize(), pii->YSize()   );
+mCurWin = win;
+mCurWdg = pii;
+mLastWdg = pii;
+mBWId++;
+mBWList[mBWId] = pii;
+// pii->Refresh();
+pii->Apply();
+cmapv->Refresh();
+return(mBWId); 
+}
+
+
+/* --Methode-- */
+int PIStdImgApp::DispScDrawer(PIDrawer* scd, string const & name, string const& sop, 
+			      string title, int oid)
+{
+if (scd == NULL)
+  {
+  printf("PIStdImgApp::DispScDrawer_Error  Cannot Add NULL ScDrawer \n");
+  return(-1);
+  }
+
+// On decode les options graphiques
+vector<string> opts;
+DispWinEnum dwopt = ParseDisplayOption(sop, opts);
+if ( (!mLastWdg) && ( (dwopt == Disp_Same) || (dwopt == Disp_Inset) ) )  dwopt = Disp_Next;
+// Trace en superpoistion
+if ( (dwopt == Disp_Same) && (mLastWdg) ) {  
+  // Les options 
+  scd->DecodeOptionString(mDefaultAtt, false);
+  scd->DecodeOptionString(opts, true);
+
+  if (mLastWdg->kind() == PIScDrawWdg::ClassId)  ((PIScDrawWdg*)mLastWdg)->AddScDrawer(scd, true);
+  else mLastWdg->AddDrawer(scd, true, true, true);
+  scd->Refresh(); 
+  mDId++;
+  mDrwList[mDId] = scd;
+  return(-mDId);   
+}
+// Trace en medaillon
+else if ( (dwopt == Disp_Inset) && (mLastWdg) ) {
+  PIGrCoord x1, x2, y1, y2;
+  x1 = mIXmin;  x2 = mIXmax;
+  y2 = 1.-mIYmin;  y1 = 1.-mIYmax;
+  // Les options 
+  scd->DecodeOptionString(mDefaultAtt, false);
+  scd->DecodeOptionString(opts, true);
+
+  scd->SetAxesFlags(mAxesFlags);
+  scd->UpdateLimits();
+  mLastWdg->AddDrawer(scd, x1, y1, x2, y2, true, false, true);
+  scd->Refresh();
+  mDId++;
+  mDrwList[mDId] = scd;
+  return(-mDId);   
+}
+
+// Creation d'un nouveau PIScDrawWdg
+PIWindow* win;
+PIScDrawWdg* scw;
+int sx, sy, px, py, flag;
+sx = 200+mFgScSz*100;
+sy = 200+mFgScSz*100;
+win = GetWindow(dwopt, sx, sy, px, py, flag, (char *)name.c_str());
+
+scw = new PIScDrawWdg(win, (char *)name.c_str(), sx, sy, px, py);
+scw->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+scw->SetUserData(NULL, oid);
+
+// Decodage des options :
+vector<string> scwatt;
+scw->SetAxesFlags(mAxesFlags);
+if ( mDefaultAtt.size() > 0) { 
+  scwatt = mDefaultAtt;
+  scd->DecodeOptionString(scwatt, true);
+  scw->DecodeOptionString(scwatt, true);
+}
+if ( mAxesAtt.size() > 0) { 
+  scwatt = mAxesAtt;
+  scw->DecodeOptionString(scwatt, true);
+}
+if (opts.size() > 0) 
+  scd->DecodeOptionString(opts, true);
+if (opts.size() > 0) 
+  scw->DecodeOptionString(opts, false);
+
+//   Titre du plot
+if (mAddTitle) {
+  if (title.length() <= 0)  title = name;  string t2="";   
+  scw->SetTitles(title, t2);    
+}
+
+scw->AddScDrawer(scd, true);
+// scw->Refresh();   ? Pas necessaire  Reza 19/08/98, 05/05/99 $CHECK$ 
+
+mCurWin = win;
+mCurWdg = scw;
+mLastWdg = scw;
+mBWId++;
+mBWList[mBWId] = scw;
+return(mBWId); 
+}
+
+/* --Methode-- */
+int PIStdImgApp::Disp3DDrawer(PIDrawer3D* dr3, string const & name, string const& sop, 
+			      string title, int oid)
+{
+if (dr3 == NULL)
+  {
+  printf("PIStdImgApp::Disp3DDrawer_Error  Cannot Add NULL 3DDrawer \n");
+  return(-1);
+  }
+
+// On decode les options graphiques
+vector<string> opts;
+DispWinEnum dwopt = ParseDisplayOption(sop, opts);
+
+if ( (!mLastWdg) && ( (dwopt == Disp_Same) || (dwopt == Disp_Inset) ) )  dwopt = Disp_Next;
+// Trace en superpoistion
+if ( (dwopt == Disp_Same) && (mLastWdg) ) {
+  // Les options 
+  dr3->DecodeOptionString(mDefaultAtt, false);
+  dr3->DecodeOptionString(opts, true);
+
+  if (mLastWdg->kind() == PIDraw3DWdg::ClassId)  ((PIDraw3DWdg*)mLastWdg)->AddDrawer3D(dr3, true);
+  else mLastWdg->AddDrawer(dr3, true, true, true);
+  dr3->Refresh();
+  mDId++;
+  mDrwList[mDId] = dr3;
+  return(-mDId);   
+}
+// Trace en medaillon
+else if ( (dwopt == Disp_Inset) && (mLastWdg) ) {
+  PIGrCoord x1, x2, y1, y2;
+  x1 = mIXmin;  x2 = mIXmax;
+  y2 = 1.-mIYmin;  y1 = 1.-mIYmax;
+  // Les options 
+  dr3->DecodeOptionString(mDefaultAtt, false);
+  dr3->DecodeOptionString(opts, true);
+
+  dr3->SetAxesFlags(mAxesFlags);
+  dr3->UpdateLimits();
+  mLastWdg->AddDrawer(dr3, x1, y1, x2, y2, true, false, true);
+  dr3->Refresh();
+  mDId++;
+  mDrwList[mDId] = dr3;
+  return(-mDId);   
+}
+
+
+PIWindow* win;
+int sx, sy, px, py, flag;
+sx = 200+mFgScSz*100;
+sy = 200+mFgScSz*100;
+win = GetWindow(dwopt, sx, sy, px, py, flag, (char *)name.c_str());
+PIDraw3DWdg* wd3 = new PIDraw3DWdg(win, (char *)name.c_str(), sx, sy, px, py);
+wd3->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
+wd3->SetUserData(NULL, oid);
+
+// Decodage des options :
+vector<string> scwatt;
+// wd3->SetAxesFlags(mAxesFlags);  Attributs d'axes 3D a faire 
+if ( mDefaultAtt.size() > 0) { 
+  scwatt = mDefaultAtt;
+  dr3->DecodeOptionString(scwatt, true);
+  wd3->DecodeOptionString(scwatt, true);
+}
+if ( mAxesAtt.size() > 0) { 
+  scwatt = mAxesAtt;
+  wd3->DecodeOptionString(scwatt, true);
+}
+if (opts.size() > 0)  
+  dr3->DecodeOptionString(opts, true);
+if (opts.size() > 0)  
+  wd3->DecodeOptionString(opts, false);
+
+//   Titre du plot
+if (mAddTitle) {
+  if (title.length() <= 0)  title = name;  string t2="";   
+  wd3->SetTitles(title, t2);    
+}
+
+wd3->AddDrawer3D(dr3, true);
+// wd3->Refresh();   ?Pas necessaire   $CHECK$ 05/05/99
+
+mCurWin = win;
+mCurWdg = wd3;
+mLastWdg = wd3;
+mBWId++;
+mBWList[mBWId] = wd3;
+return(mBWId); 
+}
+
+/* --Methode-- */
+int PIStdImgApp::ExecuteExtCommand() 
+{ 
+if (!fg_exc_cmd) return(0); 
+else {
+  fg_exc_cmd = false; 
+  return CmdInterpreter()->Interpret(exc_command); 
+  }
+}
+
+/* --Methode-- */
+void PIStdImgApp::AddText(string const & txt, double xp, double yp, string const& sop, bool fgcn)
+{
+PIDrawer *eld=CurrentElDrawer();
+if (eld == NULL) return;
+PIElDrawer* eld2 = dynamic_cast<PIElDrawer *>(eld);
+PIElDrawer3D* eld3 = dynamic_cast<PIElDrawer3D *>(eld);
+if ((eld2 == NULL) && (eld3 == NULL)) return;
+PIElDrwMgr* elmgr;
+if (eld2) elmgr = &(eld2->ElDrwMgr());
+else if (eld3) elmgr = &(eld3->ElDrwMgr());
+if (elmgr == NULL) return;
+
+vector<string> opts;
+ParseDisplayOption(sop, opts);
+PIGraphicAtt gratt(opts);
+unsigned long tpd = 0;
+gratt.DecodeTextPosDirAtt(opts, tpd, false);
+elmgr->ElAddText(xp,yp,txt.c_str(), gratt, tpd, fgcn);
+eld->Refresh();
+}
+
+/* --Methode-- */
+void PIStdImgApp::AddCompText(string const & txt, string const & txtup, string const & txtdn, 
+			      double xp, double yp, string const& sop, 
+			      string const& optss, bool fgcn)
+{
+PIDrawer *eld=CurrentElDrawer();
+if (eld == NULL) return;
+PIElDrawer* eld2 = dynamic_cast<PIElDrawer *>(eld);
+PIElDrawer3D* eld3 = dynamic_cast<PIElDrawer3D *>(eld);
+if ((eld2 == NULL) && (eld3 == NULL)) return;
+PIElDrwMgr* elmgr;
+if (eld2) elmgr = &(eld2->ElDrwMgr());
+else if (eld3) elmgr = &(eld3->ElDrwMgr());
+if (elmgr == NULL) return;
+
+vector<string> opts;
+ParseDisplayOption(sop, opts);
+PIGraphicAtt gratt(opts);
+unsigned long tpd = 0;
+gratt.DecodeTextPosDirAtt(opts, tpd, false);
+ParseDisplayOption(optss, opts);
+PIGraphicAtt grattss(opts);
+elmgr->ElAddCompText(xp,yp,txt.c_str(), gratt, txtup, txtdn, grattss, tpd, fgcn);
+eld->Refresh();
+}
+
+/* --Methode-- */
+void PIStdImgApp::AddLine(double xp1, double yp1, double xp2, double yp2, 
+			  string const& sop, bool fgarrow, bool fgcn)
+{
+PIDrawer *eld=CurrentElDrawer();
+if (eld == NULL) return;
+PIElDrawer* eld2 = dynamic_cast<PIElDrawer *>(eld);
+PIElDrawer3D* eld3 = dynamic_cast<PIElDrawer3D *>(eld);
+if ((eld2 == NULL) && (eld3 == NULL)) return;
+PIElDrwMgr* elmgr = NULL;
+if (eld2) elmgr = &(eld2->ElDrwMgr());
+else if (eld3) elmgr = &(eld3->ElDrwMgr());
+if (elmgr == NULL) return;
+
+vector<string> opts;
+ParseDisplayOption(sop, opts);
+PIGraphicAtt gratt(opts);
+if (fgarrow) 
+  elmgr->ElAddArrow(xp1, yp1, xp2, yp2, gratt, fgcn);
+else elmgr->ElAddLine(xp1, yp1, xp2, yp2, gratt, fgcn);
+eld->Refresh();
+}
+
+/* --Methode-- */
+void PIStdImgApp::AddRectangle(double xp1, double yp1, double xp2, double yp2, 
+			       string const& sop, bool fgfill, bool fgcn)
+{
+PIDrawer *eld=CurrentElDrawer();
+if (eld == NULL) return;
+PIElDrawer* eld2 = dynamic_cast<PIElDrawer *>(eld);
+PIElDrawer3D* eld3 = dynamic_cast<PIElDrawer3D *>(eld);
+if ((eld2 == NULL) && (eld3 == NULL)) return;
+PIElDrwMgr* elmgr = NULL;
+if (eld2) elmgr = &(eld2->ElDrwMgr());
+else if (eld3) elmgr = &(eld3->ElDrwMgr());
+
+double xp,yp;
+double dx, dy;
+if (xp1 < xp2) {
+  xp = xp1; dx = xp2-xp1;
+}
+else {
+  xp = xp2; dx = xp1-xp2;
+}
+if (yp1 < yp2) {
+  yp = yp1; dy = yp2-yp1;
+}
+else {
+  yp = yp2; dy = yp1-yp2;
+}
+
+vector<string> opts;
+ParseDisplayOption(sop, opts);
+PIGraphicAtt gratt(opts);
+
+if (fgfill) elmgr->ElAddFRect(xp, yp, dx, dy, gratt, fgcn);
+else elmgr->ElAddRect(xp, yp, dx, dy, gratt, fgcn);
+eld->Refresh();
+}
+
+/* --Methode-- */
+void PIStdImgApp::AddCircle(double xc, double yc, double r, string const& sop, 
+			    bool fgfill, bool fgcn)
+{
+PIDrawer *eld=CurrentElDrawer();
+if (eld == NULL) return;
+PIElDrawer* eld2 = dynamic_cast<PIElDrawer *>(eld);
+PIElDrawer3D* eld3 = dynamic_cast<PIElDrawer3D *>(eld);
+if ((eld2 == NULL) && (eld3 == NULL)) return;
+PIElDrwMgr* elmgr = NULL;
+if (eld2) elmgr = &(eld2->ElDrwMgr());
+else if (eld3) elmgr = &(eld3->ElDrwMgr());
+
+vector<string> opts;
+ParseDisplayOption(sop, opts);
+PIGraphicAtt gratt(opts);
+if (r < -0.5)
+  elmgr->ElAddMarker(xc, yc, gratt);
+else {
+  if (fgfill) elmgr->ElAddFCirc(xc, yc, r, gratt, fgcn);
+  else elmgr->ElAddCirc(xc, yc, r, gratt, fgcn);
+}
+eld->Refresh();
+}
+/* --Methode-- */
+void PIStdImgApp::AddArc(double xc, double yc, double r, double a, double da, 
+			 string const& sop, bool fgfill, bool fgcn)
+{
+PIDrawer *eld=CurrentElDrawer();
+if (eld == NULL) return;
+PIElDrawer* eld2 = dynamic_cast<PIElDrawer *>(eld);
+PIElDrawer3D* eld3 = dynamic_cast<PIElDrawer3D *>(eld);
+if ((eld2 == NULL) && (eld3 == NULL)) return;
+PIElDrwMgr* elmgr = NULL;
+if (eld2) elmgr = &(eld2->ElDrwMgr());
+else if (eld3) elmgr = &(eld3->ElDrwMgr());
+
+vector<string> opts;
+ParseDisplayOption(sop, opts);
+PIGraphicAtt gratt(opts);
+if (fgfill) elmgr->ElAddFArc(xc, yc, r, a, da, gratt, fgcn);
+else elmgr->ElAddArc(xc, yc, r, a, da, gratt, fgcn);
+eld->Refresh();
+}
+
+/* --Methode-- */
+void PIStdImgApp::AddArc(double x1, double y1, double x2, double y2,
+			 double x3, double y3, string const& sop, bool fgfill, bool fgcn)
+{
+PIDrawer *eld=CurrentElDrawer();
+if (eld == NULL) return;
+PIElDrawer* eld2 = dynamic_cast<PIElDrawer *>(eld);
+PIElDrawer3D* eld3 = dynamic_cast<PIElDrawer3D *>(eld);
+if ((eld2 == NULL) && (eld3 == NULL)) return;
+PIElDrwMgr* elmgr = NULL;
+if (eld2) elmgr = &(eld2->ElDrwMgr());
+else if (eld3) elmgr = &(eld3->ElDrwMgr());
+if (elmgr == NULL) return;
+
+vector<string> opts;
+ParseDisplayOption(sop, opts);
+PIGraphicAtt gratt(opts);
+if (fgfill) 
+  elmgr->ElAddFArc(x1, y1, x2, y2, x3, y3, gratt, fgcn);
+else  elmgr->ElAddArc(x1, y1, x2, y2, x3, y3, gratt, fgcn);
+eld->Refresh();
+}
+
+/* --Methode-- */
+void PIStdImgApp::AddPoly(vector<double>& xpol, vector<double>& ypol, 
+			  string const& sop, bool fgfill, bool fgcn)
+{
+PIDrawer *eld=CurrentElDrawer();
+if (eld == NULL) return;
+PIElDrawer* eld2 = dynamic_cast<PIElDrawer *>(eld);
+PIElDrawer3D* eld3 = dynamic_cast<PIElDrawer3D *>(eld);
+if ((eld2 == NULL) && (eld3 == NULL)) return;
+PIElDrwMgr* elmgr = NULL;
+if (eld2) elmgr = &(eld2->ElDrwMgr());
+else if (eld3) elmgr = &(eld3->ElDrwMgr());
+if (elmgr == NULL) return;
+
+vector<string> opts;
+ParseDisplayOption(sop, opts);
+PIGraphicAtt gratt(opts);
+if (fgfill) 
+  elmgr->ElAddFPoly(xpol, ypol, gratt, fgcn);
+else  elmgr->ElAddPoly(xpol, ypol, gratt, fgcn);
+eld->Refresh();
+
+}
+
+
+/* --Methode-- */
+void PIStdImgApp::SetTitle(string const & titletop, string const & titlebottom, string const& sop)
+{
+PIDrawer *eld=CurrentElDrawer();
+if (eld == NULL) return;
+PIElDrawer* eld2 = dynamic_cast<PIElDrawer *>(eld);
+PIElDrawer3D* eld3 = dynamic_cast<PIElDrawer3D *>(eld);
+if ((eld2 == NULL) && (eld3 == NULL)) return;
+
+vector<string> opts;
+ParseDisplayOption(sop, opts);
+PIGraphicAtt gratt(opts);
+
+if (eld2) { 
+  eld2->SetTitles(titletop, titlebottom, gratt);
+  eld2->ShowTitles(true);
+}
+else if (eld3) { 
+  eld3->SetTitles(titletop, titlebottom, gratt);
+  eld3->ShowTitles(true);
+}
+eld->Refresh();
+}
+/* --Methode-- */
+void PIStdImgApp::SetAxeLabels(string const & xLabel, string const & yLabel, string const& sop)
+{
+PIDrawer *eld=CurrentElDrawer();
+if (eld == NULL) return;
+PIElDrawer* eld2 = dynamic_cast<PIElDrawer *>(eld);
+if (eld2 == NULL) return;
+
+vector<string> opts;
+ParseDisplayOption(sop, opts);
+PIGraphicAtt gratt(opts);
+
+eld2->SetAxesLabels(xLabel, yLabel, gratt);
+eld2->ShowAxesLabels(true);
+
+eld->Refresh();
+}
+
+/* --Methode-- */
+PIDrawer* PIStdImgApp::CurrentElDrawer()
+{
+PIDrawer *eld=NULL;
+if (!mLastWdg)  return(eld);
+PIScDrawWdg* sdw=NULL;
+PIDraw3DWdg* w3d=NULL;
+PIImage* imgw;
+switch(mLastWdg->kind()) {
+  case PIScDrawWdg::ClassId :
+    sdw = dynamic_cast<PIScDrawWdg *>(mLastWdg);
+    if (sdw) eld = sdw->BaseDrawer();
+    break;
+  case PIDraw3DWdg::ClassId :
+    w3d = dynamic_cast<PIDraw3DWdg *>(mLastWdg);
+    if (w3d) eld = w3d->BaseDrawer();
+    break;
+  case PIImage::ClassId :
+    imgw = dynamic_cast<PIImage *>(mLastWdg);
+    if (imgw) eld = imgw->BaseDrawer();
+    break;
+  default :
+    break;
+  }
+return(eld);
+}
+
+/* --Methode-- */
+void PIStdImgApp::CreateGraphWin(int nx, int ny, int sx, int sy)
+{
+if (nx < 1)  nx = 1;
+if (ny < 1)  ny = 1;
+if (nx > 8)  nx = 8;    
+if (ny > 8)  ny = 8;
+if ( (sx < 50) && (sy < 50) )   sx = sy = 400+mFgScSz*100; 
+char buff[64];
+mWId++;
+int px, py; 
+MainWin()->GetScreenPos(px, py);
+sprintf(buff, "PI-GraphicWin (%d)",mWId);
+PIZoneWindow* win = new PIZoneWindow(this,  buff, PIWK_normal, nx, ny, sx, sy, px+MainWin()->XSize()+30, 0);
+win->SetUserData(NULL, ny*10+nx);  // UserFlag= nY*10 + nX  
+mWList[mWId*10+1] = (PIWindow*)win;
+win->SetAutoDelChilds(true);
+// win->Show();
+mGrW = win; 
+mGrIdx = 0;
+}
+
+/* --Methode-- */
+void PIStdImgApp::CreateStackWin(int sx, int sy)
+{
+if ( (sx < 50) && (sy < 50) )   sx = sy = 300+mFgScSz*100; 
+char buff[64];
+mWId++;
+int px, py; 
+MainWin()->GetScreenPos(px, py);
+sprintf(buff, "PI-StackWin (%d)",mWId); 
+PIStackWindow* win = new PIStackWindow(this,  buff, PIWK_normal, sx, sy, px+MainWin()->XSize()+30, 100);
+win->SetUserData(NULL, 9999);  // UserFlag= 9999 
+mWList[mWId*10+2] = (PIWindow*)win;
+win->SetAutoDelChilds(true);
+// win->Show();
+mStW = win;
+m[2]->SetSensitivity("StackTools", true); 
+mStIdx = 0;
+}
+
+/* --Methode-- */
+PIWindow* PIStdImgApp::GetWindow(DispWinEnum typ, int& sx, int& sy, int& px, int& py, int& flag, char * nom)
+{
+PIWindow* rw;
+
+switch (typ) {
+  case Disp_Next :  // Fenetre graphique courante
+  case Disp_Default :
+    {
+    if (mGrW == NULL) CreateGraphWin();
+    int nx, ny;
+    mGrW->NbZone(nx, ny);
+    PIWdg* nw = mGrW->NextChildPosSize(px, py, sx, sy);
+//    cerr << "**DBG** PIStdImgApp::GetWindow() DispNext : nw = " << (long)nw << endl;
+    if (nw) DeleteBaseWidget((PIBaseWdg*)nw, false, false);
+    flag = mGrIdx;
+    mGrIdx = (mGrIdx+1)%(nx*ny);
+    rw = mGrW;
+    break;
+    }
+
+  case Disp_Stack :  // Fenetre de type stack (empilement)
+    {
+    if (mStW == NULL) CreateStackWin(sx, sy);
+    px = py = 0;
+    sx = mStW->XSize();
+    sy = mStW->YSize();
+    flag = mStIdx;
+    mStIdx++;
+    rw = mStW;
+    }
+    break;
+
+  default :      // Fenetre ordinaire
+    {
+    int pwx, pwy; 
+    MainWin()->GetScreenPos(pwx, pwy);
+    if ( (sx < 50) && (sy < 50) )   sx = sy = 300+mFgScSz*100; 
+    rw = new PIWindow(this,  nom, PIWK_normal, sx, sy, pwx+MainWin()->XSize()+30, 300);
+    rw->SetUserData(NULL, 0);  // UserFlag= 0 
+    mWId++;
+    mWList[mWId*10] = rw;
+    rw->SetAutoDelChilds(true);
+    //    rw->Show();
+    px = py = 0;
+    flag = 0;
+    break;
+    }
+  }
+
+rw->Show();
+mCurWin = rw;
+return(rw);
+}
+
+/* --Methode-- */
+void PIStdImgApp::SetZone(int nzx, int nzy)
+{
+if (!mGrW) CreateGraphWin(nzx, nzy);
+else { 
+  int k;
+  PIWdg* cwd;
+  for(k=0; k<mGrW->NbChilds(); k++) {
+    if ((cwd = mGrW->GetChild(k)) == NULL)  continue; 
+    DeleteBaseWidget((PIBaseWdg*)cwd, false, false);
+    }
+  mGrW->SetZone(nzx, nzy);
+  }
+}
+
+/* --Methode-- */
+void PIStdImgApp::StackWinNext()
+{
+if (mStW)  mStW->DispNext();
+}
+
+/* --Methode-- */
+void PIStdImgApp::DeleteWindow(PIWindow* w)
+{
+if (w == NULL)  return;
+w->Hide();
+bool ownwindow=false;  // To Check if this is one of our windows
+WindMList::iterator it;
+for(it = mWList.begin(); it != mWList.end(); it++) 
+  if ((*it).second == w)  { mWList.erase(it);  ownwindow = true; break; }
+if (w == mGrW) { mGrW = NULL;  mGrIdx = -1; }
+if (w == mStW) { mStW = NULL;  mStIdx = -1; m[2]->SetSensitivity("StackTools", false); }
+if (w == mCurWin) mCurWin = NULL;
+
+if (!ownwindow) return; // We do nothing if this is not a window we have created ...
+
+int k;
+PIWdg* cwd;
+for(k=0; k<w->NbChilds(); k++) {
+  if ((cwd = w->GetChild(k)) == NULL)  continue; 
+  DeleteBaseWidget((PIBaseWdg*)cwd,false,false);
+  }
+delete w;
+return;
+}
+
+/* --Methode-- */
+void PIStdImgApp::DeleteBaseWidget(PIBaseWdg* w, bool dw, bool dwin)
+{
+if (w == NULL)  return;
+BWMList::iterator it;
+for(it = mBWList.begin(); it != mBWList.end(); it++) 
+  if ((*it).second == w)  { mBWList.erase(it);  break; }
+int k;
+PIDrawer* drw;
+for(k=0; k<w->NbDrawers(); k++) {
+  if ((drw = w->GetDrawer(k)) == NULL)  continue; 
+  DrwMList::iterator itt;
+  for(itt = mDrwList.begin(); itt != mDrwList.end(); itt++) 
+    if ((*itt).second == drw)  { mDrwList.erase(itt);  break; }
+  }
+
+if (w == mCurWdg) {  
+  mCurWdg = NULL;
+  if (mFgCWImg) {
+    m[4]->SetSensitivityMsg(10515, false);
+    m[4]->SetSensitivityMsg(10516, false);
+    mFgCWImg = false;
+    }
+  }
+
+if (w == mLastWdg)  mLastWdg = NULL;
+
+PIWdg* pw=NULL;
+if (dwin)  pw = (PIWdg*)(w->Parent());
+//DBG printf("DeleteBaseWidget(%lx)-DBG kind = %d - %d %d \n", (long)w, w->kind(), (int)dw, (int)dwin); 
+if (dw) delete w;
+if (pw && (pw->kind() == PIWindow::ClassId )) {
+ PIWindow* pww = (PIWindow*) pw;
+ if ((pww != (PIWindow*)mGrW) && (pww != (PIWindow*)mStW) && (pww->NbChilds()==0)) 
+    DeleteWindow((PIWindow*)pw);
+ } 
+return;
+}
+
+
+
+/* --Methode-- */
+void PIStdImgApp::DelWRsId(int k)
+{
+//DBG cerr << "-DBG- PIStdImgApp::DelWRsId(" << k << ")" << endl; 
+if (k > 0) { // C'est un BaseWidget
+  BWMList::iterator it;
+  it  = mBWList.find(k);
+  if (it == mBWList.end())  return;
+  PIBaseWdg* wd = (*it).second;
+//DBG cerr << "-DBG- PIStdImgApp::DelWRsId Deleting BaseWidget " << (long)(wd) << endl ; 
+  DeleteBaseWidget(wd, true, true);
+  }
+else {  // C'est un drawer
+  DrwMList::iterator it;
+  it  = mDrwList.find(-k);
+  if (it == mDrwList.end())  return;
+  (*it).second->SetAutoRefreshOnDelete(true);
+  delete (*it).second;  
+  mDrwList.erase(it);
+//  cerr << "+DBG+ PIStdImgApp::DelWRsId Deleting Drawer " << (long)((*it).second) << endl ; 
+  }
+}
+/* --Methode-- */
+bool PIStdImgApp::CheckWRsId(int k)
+{
+if (k > 0) { // C'est un BaseWidget
+  BWMList::iterator it;
+  it  = mBWList.find(k);
+  if (it == mBWList.end())  return(false);
+  else return(true);
+  }
+else {  // C'est un drawer
+  DrwMList::iterator it;
+  it  = mDrwList.find(-k);
+  if (it == mDrwList.end())  return(false);
+  else return(true);
+  }
+}
+
+/* --Methode-- */
+void PIStdImgApp::StatZoomWindowSetVisible(bool fg)
+{
+
+  if (fg) {
+    consolecont->SetBinding(PIBK_free,PIBK_free,PIBK_free, PIBK_free); 
+    int szy = MainWin()->YSize();
+    MainWin()->SetSize(MainWin()->XSize(), szy+statcont->YSize());
+    consolecont->SetPos(0, statcont->YSize());
+    consolecont->SetSize(MainWin()->XSize(), szy);
+    consolecont->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_fixed, PIBK_fixed); 
+    statcont->Show();
+    m[3]->SetStateMsg(10470, true);
+  }
+  else {
+    statcont->Hide();
+    consolecont->SetBinding(PIBK_free,PIBK_free,PIBK_free, PIBK_free); 
+    MainWin()->SetSize(MainWin()->XSize(), MainWin()->YSize()-statcont->YSize());
+    consolecont->SetPos(0, 0);
+    consolecont->SetSize(MainWin()->XSize(), MainWin()->YSize());
+    consolecont->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_fixed, PIBK_fixed); 
+    m[3]->SetStateMsg(10470, false);    
+  }
+  
+}
+
+/* --Methode-- */
+void PIStdImgApp::UpdateStatResourceInfo()
+{
+  resusg.Update();
+  char buff[256];
+  string lab;
+  double frac;
+  sprintf(buff, "Mem: %ld/Max= %ld kb" , (long)resusg.getMemorySize(), 
+	  (long)resusg.getMaxMemorySize());
+  lab = buff;
+  lab_mem->SetLabel(lab);
+  frac = (double)resusg.getMemorySize()/(double)resusg.getMaxMemorySize();
+  therm_mem->SetValue(frac);
+
+  sprintf(buff, "CPU: %ld/elap= %ld ms" , (long)resusg.getCPUTime(), 
+	  (long)resusg.getElapsedTime());
+  lab = buff;
+  lab_cpu->SetLabel(lab);
+  if (resusg.getCPULoad() > resusg.getAverageCPULoad()) 
+    therm_cpu->SetValue(resusg.getCPULoad());
+  else 
+    therm_cpu->SetValue(resusg.getAverageCPULoad());
+}
+
+/* --Methode-- */
+void PIStdImgApp::RedirectStdOutErr(bool fg)
+{
+if (fg) { 
+  RedirectOutStream(mCons);
+  RedirectErrStream(mCons);
+  m[5]->SetStateMsg(10602, true);
+  redirecout = true;
+  }
+else {
+  RedirectOutStream(NULL);
+  RedirectErrStream(NULL);
+  m[5]->SetStateMsg(10602, false);
+  redirecout = false;
+  }
+return;
+}
+
+/* --Methode-- */
+void PIStdImgApp::CatchSignals(bool fgfpe, bool fgsegv)
+{    
+#ifdef SANS_EVOLPLANCK
+PeidaConfigureSignalhandling(fgfpe, fgsegv, true, true);  
+#else
+SophyaConfigureSignalhandling(fgfpe, fgsegv, true, true);  
+#endif
+m[5]->SetStateMsg(10603, fgfpe);
+m[5]->SetStateMsg(10604, fgsegv);
+}
+
+/* --Methode-- */
+void PIStdImgApp::CloseAllWindows()
+{
+WindMList::iterator it;
+for(it = mWList.begin(); it != mWList.end(); it++)   delete (*it).second;
+mWList.clear();
+mBWList.clear();
+mDrwList.clear(); 
+mGrW = NULL;
+mStW = NULL;
+mCurWin = NULL;
+mCurWdg = NULL;
+mLastWdg = NULL;
+m[4]->SetSensitivityMsg(10515, false);
+m[4]->SetSensitivityMsg(10516, false);
+}
+
+//---------------------------------------------------------------------------
+//--------- Gestion des attributs graphiques et autres options de trace -----
+
+/* --Methode-- */
+void PIStdImgApp::SetInsetLimits(double xmin, double xmax, double ymin, double ymax)
+{
+  mIXmin = xmin;  mIXmax= xmax;
+  mIYmin = ymin;  mIYmax= ymax;
+}
+
+/* --Methode-- */
+void PIStdImgApp::SetDefaultGraphicAttributes(string const & opt)
+{
+  ParseDisplayOption(opt, mDefaultAtt);
+}
+
+/* --Methode-- */
+void PIStdImgApp::SetDefaultAxesAttributes(string const & opt)
+{
+  ParseDisplayOption(opt, mAxesAtt);
+}
+
+/* --Methode-- */
+DispWinEnum PIStdImgApp::ParseDisplayOption(string const & sop, vector<string>& opts)
+{
+  DispWinEnum rc = Disp_Next;
+  //DBG  cerr << " DBG-Parse-A sop=" << sop << " sop.length()= " << sop.length() << endl;
+  if (opts.size() > 0)  opts.erase(opts.begin(), opts.end());
+  if (sop.length() < 1) return(rc);
+  string gratt = sop;
+  for(int i=0; i<gratt.length(); i++) gratt[i] = tolower(gratt[i]);
+  if ( (gratt == "def") || (gratt == "default") ) return(rc);
+// On separe en mots espaces par des blancs ou tabulation 
+  size_t p = 0;
+  size_t q = 0;
+  size_t l = gratt.length();
+  string token;
+  while (q < l)  {
+    p = gratt.find_first_not_of(" \t",q);   // au debut d'un token
+    if (p >= l) break;
+    q = gratt.find_first_of(" \t",p);       // Premier blanc ou tab suivant
+    if (q<l) token = gratt.substr(p,q-p);
+    else token = gratt.substr(p);
+    if (token == "") continue;
+    // Decodage option fenetre d'affichage (win, next, ...)
+    if (token == "win")   rc =  Disp_Win;
+    else if (token == "same")  rc = Disp_Same;
+    else if (token == "inset")   rc = Disp_Inset;
+    else  if (token == "stack")   rc = Disp_Stack;
+    else  if (token == "next")   rc = Disp_Next;
+    // Option a etre decode par les drawers, etc ...
+    else  opts.push_back(token); 
+  }
+
+  //DBG  cerr << " DBG-Parse-B opts.size()=" << opts.size() << endl;
+  return (rc);
+}
+
+//---------------------------------------------------------------------------
+//------------       Methodes privees (MBProcessx, ...)    ----------
+
+/* --Methode-- */
+void PIStdImgApp::MBProcess1(PIMessage msg, PIMsgHandler* /*sender*/, void* data)
+{
+
+  switch(msg)
+    {
+    case 10150 :
+      showInfoWindow(this);
+      break;
+
+    case 10155 :
+      hideInfoWindow(this);
+      break;
+
+    case 10100 :
+      mCmd->ShowHelpWindow();
+      break;
+
+    case 10120 :
+      pfc_fits->AcceptNewFile(false);
+      mFCMsg = 10125; 
+      pfc_fits->SetMsg(mFCMsg);
+      SetBlocked();
+      pfc_fits->Show();
+      break;
+
+    case 10125 :
+      SetBusy();
+      if (data)  { 
+        string nomobj="";
+        ObjMgr()->ReadFits(pfc_fits->GetFileName(), nomobj);
+        ObjMgr()->DisplayObj(nomobj, "win");
+      }
+      mFCMsg = 0;
+      SetReady();
+      break;
+
+    case 10130 :
+      pfc_ppf->AcceptNewFile(false); 
+      mFCMsg = 10135; 
+      pfc_ppf->SetMsg(mFCMsg);
+      SetBlocked();
+      pfc_ppf->Show();
+      break;
+
+    case 10135 :
+      mFCMsg = 0;
+      if (data)  { 
+        PPInMgrW()->SetFile(pfc_ppf->GetFileName());
+        PPInMgrW()->Show();
+      }
+      SetReady();
+      break;
+        
+#ifndef SANS_EVOLPLANCK
+    case 10140 :
+      pfc_ascii->AcceptNewFile(false);
+      mFCMsg = 10145; 
+      pfc_ascii->SetMsg(mFCMsg);
+      SetBlocked();
+      pfc_ascii->Show();
+      break;
+
+    case 10145 :
+      SetBusy();
+      if (data)  { 
+	string afname = pfc_ascii->GetFileName();
+        string nomobj = ObjMgr()->GetServiceObj()->FileName2Name(afname);
+	string cmd = "mtxfrascii ";
+	cmd += nomobj;  cmd += " ";  cmd += afname;
+	try {
+	  mCmd->Interpret(cmd);
+	}  
+	catch ( PThrowable & exc ) {
+	  cerr << "\n PIStdImgApp::Process()/ Cmd->Interpret() Exception :" 
+	       << (string)typeid(exc).name() << " Msg= " 
+	       << exc.Msg() << endl;
+	  cout << endl; 
+	}
+	catch ( ... ) {
+	  cerr << "\n PIStdImgApp::Process()/ Cmd->Interpret() Catched Exception ... " << endl;
+	  cout << endl; 
+	}
+	
+      }
+      mFCMsg = 0;
+      SetReady();
+      break;
+#endif
+
+    case 10105:
+      Stop();
+      break;
+
+  }
+return;
+}
+
+
+
+/* --Methode-- */
+void PIStdImgApp::MBProcess2(PIMessage msg, PIMsgHandler* /*sender*/, void* data)
+{
+
+switch (msg)  { 
+  case 10201 :
+     ObjMgrW()->Show();
+     break;
+
+  case 10220 :
+     pfc_ppf->AcceptNewFile(true);
+     mFCMsg = 10225;
+     pfc_ppf->SetMsg(mFCMsg);
+     SetBlocked();
+     pfc_ppf->Show();
+     break;
+
+   case 10225 :
+     SetBusy();
+     if (data) {
+       if (mPpfout) {  
+         printf("PIStdImg/Info: Closing POutPersist-File %s \n", name_outppf.c_str());
+         delete mPpfout;  
+       }
+       name_outppf = pfc_ppf->GetFileName();
+       mPpfout = NULL;
+       printf("PIStdImg/Info: Opening POutPersist-File %s \n", name_outppf.c_str());
+       mPpfout = new POutPersist(name_outppf);
+    }
+    mFCMsg = 0;
+    SetReady();
+    break;
+
+  case 10230 :
+    if (!mPpfout)  break;
+    printf("PIStdImg/Info: Closing POutPersist-File %s \n", name_outppf.c_str());
+    delete mPpfout;  
+    name_outppf = "";
+    mPpfout = NULL;
+    break;
+
+  case 10270 :
+    if (mCurWdg) {
+      int oid = mCurWdg->UserFlag();
+      DeleteBaseWidget(mCurWdg);
+      mObjMgr->DelObj_Id(oid);
+      }
+    break;
+
+  default:
+    cerr << "PIStdImgApp::MBProcess2() BUG?? Msg= " <<  msg << endl;    
+    break;
+}
+
+return;
+}
+
+/* --Methode-- */
+void PIStdImgApp::MBProcess3(PIMessage msg, PIMsgHandler* /*sender*/, void* /*data*/)
+{
+
+switch (msg)  { 
+  case 10301 :
+    PIImgTools::ShowPIImgTools();
+    break; 
+  case 10302 :
+    PIDrwTools::ShowPIDrwTools();
+    break;
+  case 10303 :
+    PIAxesTools::ShowPIAxesTools();
+    break;
+
+  case 10304 :
+    mCmd->ShowCxxExecWindow();
+    break;
+
+  case 10311 :
+  case 10312 :
+    {
+    PIImage* curpimg = NULL;
+    if (!mCurWdg)  return;
+    if (mCurWdg->kind() != PIImage::ClassId)  return;
+    curpimg = (PIImage*)mCurWdg;
+    if (curpimg == NULL)   return;
+    P2DArrayAdapter* img = curpimg->Image();
+    if (img == NULL) return;
+    int dx = curpimg->XSzPave();
+    int dy = curpimg->YSzPave();  
+    int x0 = curpimg->XPave()-dx/2;
+    int y0 = curpimg->YPave()-dy/2;
+    if (x0 < 0)  x0 = 0;
+    if (y0 < 0)  y0 = 0;
+    int x1 = x0+dx;
+    int y1 = y0+dy;
+    if (x1 > img->XSize()) x1 = img->XSize();
+    if (y1 > img->YSize()) y1 = img->YSize();
+    dx = x1-x0;  dy = y1-y0;
+    ImageR4* pim = new ImageR4(dx, dy); 
+    int ii, jj;
+    for(jj=0; jj<dy; jj++) 
+      for(ii=0; ii<dx; ii++) (*pim)(ii,jj) = (*img)(ii+x0, jj+y0);
+    if (msg == 10305) {  // Calcul des coordonnees du sous-pave
+      double xc1, yc1;
+      img->Coord(x0, y0, xc1, yc1);
+      pim->SetOrg((int)xc1, (int)yc1);
+    }
+    string nom = mCurWdg->Nom() + "_pave";
+    ObjMgr()->AddObj(pim, nom);
+    ObjMgr()->DisplayObj(nom, "w");
+    break;
+    }
+
+  case 10313 :
+    {
+    PIImage* curpimg = NULL;
+    if (!mCurWdg)  return;
+    if (mCurWdg->kind() != PIImage::ClassId)  return;
+    curpimg = (PIImage*)mCurWdg;
+    if (curpimg == NULL)   return;
+    curpimg->ShowCuts(true);
+    break;
+    }
+
+  case 10320 :
+    if (mStW)  mStW->DispNext();
+    break;
+
+  case 10321 :
+  case 10322 :
+  case 10324 :
+//  case 10328 :
+    if (mStW) mStW->StartAutoDisp((msg-10320)*500);
+    break;
+
+  case 10329 :
+    if (mStW) mStW->StopAutoDisp();
+    break;
+
+  case 103330 :
+    if (mStW) {
+      PIWdg* cw =  mStW->CurrentWdg();
+      if (cw) DeleteBaseWidget((PIBaseWdg*)cw);
+      }
+    break;
+
+  default:
+    cerr << "PIStdImgApp::MBProcess3() BUG?? Msg= " <<  msg << endl;    
+    break;
+  }
+return;
+}
+
+/* --Methode-- */
+void PIStdImgApp::MBProcess4(PIMessage msg, PIMsgHandler* /*sender*/, void* /*data*/)
+{
+
+switch (msg)  { 
+
+  case 10400 :
+    CreateStackWin();
+    break;
+
+  case 10411 :
+    CreateGraphWin(1,1);
+    break;
+  case 10421 :
+    CreateGraphWin(1,2);
+    break;
+  case 10412 :
+    CreateGraphWin(2,1);
+    break;
+  case 10422 :
+    CreateGraphWin(2,2);
+    break;
+  case 10431 :
+    CreateGraphWin(1,3);
+    break;
+  case 10433 :
+    CreateGraphWin(3,3);
+    break;
+  case 10441 :
+    if (mCurWdg)  { 
+      mLastWdg = mCurWdg;
+      cout << " Using current widget as last-widget (display same) " << endl;
+      }
+    else  cout << " No current widget - select widget with mouse " << endl;
+    break;
+    case 10460 :
+      DeleteWindow(mCurWin);
+      break;
+    case 10470 :
+      StatZoomWindowSetVisible(m[3]->GetStateMsg(10470));
+      break;
+  default:
+    cerr << "PIStdImgApp::MBProcess4() BUG?? Msg= " <<  msg << endl;    
+    break;
+  }
+return;
+}
+
+
+/* --Methode-- */
+void PIStdImgApp::MBProcess5(PIMessage msg, PIMsgHandler* /*sender*/, void* data)
+{
+char nomps[64],strg[512];
+PSFile *mps;
+int sxt, syt, syo, syo1, sx[4], sy[4];
+
+switch (msg)
+  { 
+  case 10501 :
+     pfc_ps->AcceptNewFile(true); 
+     mFCMsg = 10525; 
+     pfc_ps->SetMsg(mFCMsg);
+     SetBlocked();
+     pfc_ps->Show();
+     break;
+
+   case 10525 :
+     SetBusy();
+     if (data) {
+       if (mpsfile) {  
+         printf("PIStdImg/Info: Closing PS-File %s \n", name_ps.c_str());
+         delete mpsfile;  
+         }
+        name_ps = pfc_ps->GetFileName();
+        printf("PIStdImg/Info: Opening PS-File %s \n", name_ps.c_str());
+        mpsfile = new PSFile(name_ps.c_str(), PI_Portrait, PI_A4, 2., 2.);
+        }
+      mFCMsg = 0;
+      SetReady();
+      break;
+
+  case 10505 :
+    if (!mpsfile)  break;
+    printf("PIStdImg/Info: Closing PS-File %s \n", name_ps.c_str());
+    delete mpsfile;
+    mpsfile = NULL;
+    name_ps = "";
+    break;
+
+  case 10511 :     // Window -> PS
+  case 10512 :     // Window -> EPS 
+    if (CurrentWindow() == NULL)  break;
+    if (msg == 10512) 
+      { 
+      num_eps++;
+      sprintf(nomps,"pia%d.eps", num_eps);
+      printf("PIStdImg/Info: Creating EPSFile %s (CurWin-> EPS) \n", nomps);
+      mps = new PSFile(nomps);
+      }
+    else {
+      if (mpsfile == NULL) {
+        name_ps = "pia.ps";
+        mpsfile = new PSFile(name_ps.c_str(), PI_Portrait, PI_A4, 0., 0.);
+        printf("PIStdImg/Info: File PS %s opened \n", name_ps.c_str());
+      }
+      printf("PIStdImg/Info: CurWin-> PSFile %s\n", name_ps.c_str());      
+      mps = mpsfile; 
+      }
+    CurrentWindow()->PSPrint(mps,0,0);
+
+    if (msg == 10512)   delete mps;   // fichier eps
+    break;
+
+  case 10515 :    // Image -> PS
+  case 10516 :    // Image -> EPS 
+     {
+     PIImage* curpimg = NULL;
+     if (!mCurWdg)  return;
+     if (mCurWdg->kind() != PIImage::ClassId)  return;
+     curpimg = (PIImage*)mCurWdg;
+     if (curpimg == NULL)   return;
+     if (msg == 10516) 
+      { 
+      num_eps++;
+      sprintf(nomps,"pia%d.eps", num_eps);
+      printf("PIStdImg/Info: Creating EPSFile %s (CurImage-> EPS)\n", nomps);
+      mps = new PSFile(nomps);
+      }
+    else {
+      if (mpsfile == NULL) {
+        name_ps = "pia.ps";
+        mpsfile = new PSFile(name_ps.c_str(),PI_Portrait, PI_A4, 2., 2.);
+        printf("PIStdImg/Info: File PS %s opened \n", name_ps.c_str());
+      }
+      printf("PIStdImg/Info: CurImage-> PSFile %s\n", name_ps.c_str());       
+      mps = mpsfile; 
+      }
+
+    sx[0] = gimv->XSize(); 
+    sy[0] = gimv->YSize();
+    sx[1] = zoom->XSize(); 
+    sy[1] = zoom->YSize();
+    sx[2] = cmapv->XSize(); 
+    sy[2] = cmapv->YSize();
+    sx[3] = curpimg->XSize(); 
+    sy[3] = curpimg->YSize();
+    if (sy[1] > sy[0])  { syo1 = sy[1]+50;  syo = sy[1]+sy[2]+60; }
+    else  { syo1 = sy[0]+50;  syo = sy[0]+sy[2]+60; }
+    syt = sy[3]+syo;
+    sxt = sx[3];
+    if (sxt < (sx[0]+sx[1]+20))  sxt = sx[0]+sx[1]+20;
+    if (sxt < sx[2])  sxt = sx[2];
+
+    // Pour ecrire le titre 
+    mps->NewPage((float)sxt, (float)syt, PI_Portrait);
+    mps->NewBloc(0,0, (float)sxt, 30., (float)sxt, 30.);
+    sprintf(strg,"Image: %s -  Pave %d %d \n",  curpimg->Nom().c_str(), 
+            curpimg->XPave(),  curpimg->YPave());     
+    mps->DrawString(10., 25., strg, PI_Black, PI_DefaultFont, PI_BoldFont, 20);
+    mps->EndBloc();
+
+    // Les quatre fenetres glovimage, zoom, cmap, image 
+    gimv->PSPrint(mps, -gimv->XPos(), -gimv->YPos()+40);
+    zoom->PSPrint(mps, -zoom->XPos()+sx[0]+20, -zoom->YPos()+40);
+    cmapv->PSPrint(mps, -cmapv->XPos(), -cmapv->YPos()+syo1);
+    curpimg->PSPrint(mps, -curpimg->XPos(), -curpimg->YPos()+syo);
+     
+    if (msg == 10516)   delete mps;    // fichier eps
+    break;
+    }
+
+  default:
+    cerr << "PIStdImgApp::MBProcess5() BUG?? Msg= " <<  msg << endl;    
+    break;
+  }
+
+}
+
+
+/* --Methode-- */
+void PIStdImgApp::MBProcess6(PIMessage msg, PIMsgHandler* /*sender*/, void* data)
+{
+switch (msg)  { 
+  case 10601:
+    CloseAllWindows();
+    break;
+  case 10602:
+    RedirectStdOutErr(*((bool*)data));
+    break;
+  case 10603:
+  case 10604:
+    CatchSignals(m[5]->GetStateMsg(10603), m[5]->GetStateMsg(10604));
+    break;
+  case 10605:
+    mObjMgr->SetVerbose(m[5]->GetStateMsg(10605));
+    break;
+  case 10606:
+    mCmd->ShowCxxOptionWindow();
+    break;
+  default:
+    cerr << "PIStdImgApp::MBProcess6() BUG?? Msg= " <<  msg << endl;    
+    break;
+  }
+return;
+}
+
+
+
+//  -------------------------------------------------
+//        Fenetre info piapp (About piapp) 
+//  -------------------------------------------------
+static PIWindow* infow_win = NULL;
+static PIText* infow_txt = NULL;
+static PICMapView* infow_cmap = NULL;
+static PIButton* infow_but = NULL;
+
+/* Nouvelle-Fonction */
+static void createInfoWindow(PIStdImgApp* app)
+{
+if (infow_win) return;
+
+int bsx, bsy;
+PIApplicationPrefCompSize(bsx, bsy);
+int spx, spy;
+spx = bsx/6;   spy = bsy/6;
+
+infow_win = new PIWindow((PIMsgHandler *)app, "About piapp", 
+                         PIWK_dialog, bsx*5+3*spx, bsy*4+spy*3, 200, 200);
+infow_win->SetAutoDelChilds(true);
+infow_txt = new PIText(infow_win,"about_piapp_text", bsx*5+spx, bsy*3, spx, spy);
+infow_txt->SetMutiLineMode(true);
+infow_txt->SetTextEditable(false);
+infow_txt->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+infow_cmap = new PICMapView(infow_win, "about_piapp_cmap", bsx*4, bsy*0.7, spx, 2*spy+bsy*3.15); 
+infow_cmap->SetColMapId(CMAP_COLBR32, 1., -1., false); 
+infow_cmap->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+infow_but = new PIButton(infow_win,"OK", 10155, bsx, bsy, bsx*4+2*spx, 2*spy+bsy*3);
+infow_but->SetMsgParent((PIMsgHandler *)app);
+infow_but->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+char buff[128];
+#ifdef SANS_EVOLPLANCK
+sprintf(buff, "Version: piapp=%g  PI=%g  PEIDA=%g \n", (double)PIAPP_VERSIONNUMBER, 
+              (double)PI_VERSIONNUMBER, (float)PeidaVersion());
+#else
+{
+sprintf(buff, "Version: piapp=%g  PI=%g  SOPHYA=%g \n", (double)PIAPP_VERSIONNUMBER, 
+              (double)PI_VERSIONNUMBER, glst_piai->Version());
+}
+#endif
+string info = "piapp : Interactive analysis program\n";
+info += buff;
+info += "(C) LAL-IN2P3/CNRS  1996-2002\n";
+info += "(C) SPP-DAPNIA/CEA  1996-2002\n";
+infow_txt->SetText(info);
+}
+
+/* Nouvelle-Fonction */
+static void showInfoWindow(PIStdImgApp* app)
+{
+if (!infow_win) createInfoWindow(app);
+if (infow_win) infow_win->Show();
+}
+/* Nouvelle-Fonction */
+static void hideInfoWindow(PIStdImgApp* app)
+{
+if (infow_win) infow_win->Hide();
+}
+
+/* Nouvelle-Fonction */
+static void deleteInfoWindow()
+{
+if (!infow_win) return;
+delete infow_win;
+infow_win = NULL;
+infow_txt = NULL;
+infow_cmap = NULL;
+infow_but = NULL;
+}
+
+
Index: /tags/V_Dec2002/SophyaPI/PIext/pistdimgapp.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/pistdimgapp.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/pistdimgapp.h	(revision 2309)
@@ -0,0 +1,228 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Standard Image App      R. Ansari  97-98
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PISTIMGAPP_H_SEEN
+#define PISTIMGAPP_H_SEEN
+
+#include <string.h>
+#include <string>
+#include <map>
+#include <functional>
+
+#include "pisysdep.h"
+
+#include PIAPP_H
+#include PIWIN_H 
+#include PIMENU_H 
+#include PIOPTMENU_H 
+
+#include PISTDWDG_H 
+
+#include PIFILECHO_H 
+#include PIPERIODIC_H
+
+#include "picons.h"
+
+#include "piimage.h"
+#include "pi3dwdg.h"
+#include "nobjmgr.h"
+#include "piacmd.h"
+#include "pisiadw.h"
+#include "pistzwin.h"
+
+#include "pitherm.h"
+
+#include "resusage.h"
+
+
+enum DispWinEnum {Disp_Default, Disp_Next, Disp_Win, Disp_Same, Disp_Stack, Disp_Inset};
+
+typedef map<long, PIWindow*, less<long> > WindMList;
+typedef map<long, PIBaseWdg*, less<long> > BWMList;
+typedef map<long, PIDrawer*, less<long> > DrwMList;
+
+class PIStdImgApp : public PIApplication  {
+public:
+     PIStdImgApp(int narg=0, char* arg[]=NULL);
+     ~PIStdImgApp();
+
+     virtual void   Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+     virtual void   SetReady();
+     virtual void   SetBusy(); 
+     virtual void   SetBlocked();
+
+     int  DispImage(P2DArrayAdapter* nouv, string const & name, string const & opt, int oid=0);
+     int  DispScDrawer(PIDrawer* scd, string const & name, string const & opt, 
+		       string title="", int oid=0);
+     int  Disp3DDrawer(PIDrawer3D* scd, string const & name, string const & opt, 
+		       string title="", int oid=0);
+
+  //  Specification (de l'exterieur) de commande a executer 
+     inline void SubmitCommand(string const& cmd) 
+            { exc_command = cmd;  fg_exc_cmd = true; }
+  //  Execution de commande soumis de l'exterieur
+     int  ExecuteExtCommand();
+     
+  //  Fonction d'ajout de texte (provisoire - Aout 99) 
+     void AddText(string const & txt, double xp, double yp, string const& opt, bool fgcn=false);
+     void AddCompText(string const & txt, string const & txtup, string const & txtdn, 
+		      double xp, double yp, string const& opt, 
+		      string const& optss, bool fgcn=false);
+  //  Ajout de lignes, rectangles, cercles (provisoires - Aout 2001)
+     void AddLine(double xp1, double yp1, double xp2, double yp2, 
+		  string const& opt, bool fgarrow=false, bool fgcn=false);
+     void AddRectangle(double xp1, double yp1, double xp2, double yp2, string const& opt, 
+		       bool fgfill=false, bool fgcn=false);
+     void AddCircle(double xc, double yc, double r, string const& opt, 
+		    bool fgfill=false, bool fgcn=false);
+     void AddArc(double xc, double yc, double r, double a, double da, 
+		 string const& opt, bool fgfill=false, bool fgcn=false);
+     void AddArc(double x1, double y1, double x2, double y2,
+		 double x3, double y3, string const& opt, bool fgfill=false, bool fgcn=false);
+     void AddPoly(vector<double>& x, vector<double>& y, 
+		  string const& opt, bool fgfill=false, bool fgcn=false);
+
+  //  Fonction Ajout de titre de trace
+     void SetTitle(string const & titleup, string const & titledown, string const& opt);
+  //  Fonction d'Ajout label d'axe X,Y 
+     void SetAxeLabels(string const & xLabel, string const & yLabel, string const& opt);
+
+  //  Acces au BaseDrawer (PIElDrawer) du PIBaseWdg courant
+     PIDrawer* CurrentElDrawer();
+
+     void CreateGraphWin(int nx=1, int ny=1, int sx=0, int sy = 0);
+     void CreateStackWin(int sx=0, int sy = 0);
+     PIWindow * GetWindow(DispWinEnum typ, int& sx, int& sy, int& px, int& py, int& flag, char * nom);
+     void SetZone(int nzx=1, int nzy=1);
+     void StackWinNext();
+
+     void DeleteWindow(PIWindow* w);
+     void DeleteBaseWidget(PIBaseWdg* w, bool dw=true, bool dwin=true);
+     void DelWRsId(int k);
+     bool CheckWRsId(int k);
+     void CloseAllWindows();
+
+     inline NamedObjMgr* ObjMgr() { return mObjMgr; }
+     inline PIACmd* CmdInterpreter() { return mCmd; }
+
+     PIWindow* CurrentWindow() { return (mCurWin); };
+     PIBaseWdg* CurrentBaseWdg() { return (mCurWdg); };
+
+     inline PIPixmap* ZoomW() { return zoom; }
+     inline PIPixmap* GloVW() { return gimv; }
+     inline PICMapView* CMapVW() { return cmapv; }
+     inline PIConsole* GetConsole() { return mCons; }
+
+     inline PIMenu* SpecialMenu() { return m[5]; }
+     inline PIMenu* ModulesMenu() { return m[6]; }
+
+     inline ObjMgrWind* ObjMgrW() { return mObjmgrw; }
+     inline PPInMgrWind* PPInMgrW() { return mPpinmgrw; }
+
+// Gestion (show/hide) de la fenetre Stat/ZoomWindow 
+    void   StatZoomWindowSetVisible(bool fg=true);
+
+// Update de l'info de la fenetre stats/ressources
+    void   UpdateStatResourceInfo();
+
+// Redirection ou Non de StdOut/StdErr
+     void  RedirectStdOutErr(bool fg = true);
+     inline bool HasRedirectedStdOutErr() { return(redirecout); }
+// Gestion des signaux
+     void  CatchSignals(bool fgfpe=true, bool fgsegv=true);
+
+     void  SetInsetLimits(double xmin=0.4, double xmax=0.6, double ymin=0.4, double ymax=0.6);
+     inline void  SetAutoAddTitle(bool aatit=true) { mAddTitle = aatit; }
+     void  SetAxesAtt(unsigned int axfl) { mAxesFlags = axfl; }
+  //     void  SaveGraphicAtt();
+  //     void  RestoreGraphicAtt();
+     void  SetDefaultGraphicAttributes(string const & opt);
+     void  SetDefaultAxesAttributes(string const & opt);
+     DispWinEnum ParseDisplayOption(string const & opt, vector<string>& opts);
+
+// Gestion fichiers PS
+    int num_eps;
+    PSFile *mpsfile;
+    string name_ps;
+
+// Gestion OUT-PPF
+    POutPersist* mPpfout;
+    string name_outppf;    
+
+private:
+    void MBProcess1(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+    void MBProcess2(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+    void MBProcess3(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+    void MBProcess4(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+    void MBProcess5(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+    void MBProcess6(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+
+    
+
+    NamedObjMgr* mObjMgr;
+    PIACmd* mCmd;
+
+    PIMenu* m[7];
+    PIMenu* mc;
+
+    PIContainer* statcont;    // Container pour les widgets zoom, gimv, cmapv ...
+    PIPixmap* zoom;
+    PIPixmap* gimv;
+    PICMapView* cmapv;
+  // Pour afficher des stats
+    PILabel* lab_mem;
+    PIThermometer* therm_mem;
+    PILabel* lab_cpu;
+    PIThermometer* therm_cpu;
+
+    PIFileChooser * pfc_fits;   // Pour les fichiers FITS
+    PIFileChooser * pfc_ppf;    //  Pour les PPF 
+    PIFileChooser * pfc_ascii;  //  Pour les fichiers ASCII 
+    PIFileChooser * pfc_ps;     // Pour les PostScript
+
+    PIContainer* consolecont;    // Container pour la PIConsole
+    PIConsole* mCons;
+    bool redirecout;    // true if stdout/err redirected to mCons;
+
+    WindMList mWList;
+    BWMList mBWList;
+    DrwMList mDrwList;
+
+    int mWId,mDId,mBWId;
+
+    PIBaseWdg* mCurWdg;
+    PIBaseWdg* mLastWdg;
+    PIWindow* mCurWin;
+    PIZoneWindow* mGrW;
+    PIStackWindow* mStW;
+    int mGrIdx;
+    int mStIdx;
+
+    ObjMgrWind* mObjmgrw;
+    PPInMgrWind* mPpinmgrw;
+
+  // Attributs graphiques, etc ...
+    double	 mIXmin, mIXmax, mIYmin, mIYmax;
+    bool         mAddTitle;
+    unsigned int mAxesFlags;
+
+    vector<string> mDefaultAtt;
+    vector<string> mAxesAtt;  
+
+  //  Controles et gestion divers 
+    PIMessage mFCMsg;  // Message for processing FileOpen
+    int mFgScSz;   // Flag ScreenSize
+    bool mFgCWImg; // true -> Current Widget is PIImage
+
+  // Pour comptabiliser l'utilisation des ressources
+    ResourceUsage resusg;
+    PIPeriodic* resupd_periodic;
+
+  // Commande specifie de l'exterieur a executer 
+  // Pris en charge par resupd_periodic
+    string exc_command;
+    bool fg_exc_cmd;
+};
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/pistlist.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/pistlist.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/pistlist.cc	(revision 2309)
@@ -0,0 +1,181 @@
+// Classe traceur de StarList               97-99
+// CEA-DAPNIA      LAL-IN2P3/CNRS
+
+#include <stdio.h>
+#include "pistlist.h"
+
+//++
+// Class	PIStarList
+// Lib		PIext
+// include	pistlist.h
+//
+//	Classe traceur d'objets de la classe *StarList* 
+//--
+//++
+// Links	Parents
+// PIDrawer
+//--
+//++
+// Titre	Constructeur
+//--
+
+//++
+//  PIStarList(StarList* stl, bool ad)
+//	Constructeur. Si "ad == true", l'objet "stl" est détruit par 
+//	le destructeur de l'objet "PIStarList"
+//	Note : "stl" doit être créé par new 
+//--
+
+/* --Methode-- */
+PIStarList::PIStarList(StarList* stl, bool ad)
+: PIDrawer(), mStL(stl)
+{
+  mAdDO = ad;   
+  if (stl == NULL) return;
+  SetFluxLimits(1., -1.);
+}
+
+PIStarList::~PIStarList()
+{
+  if (mAdDO && mStL)  delete mStL;
+}
+
+//++
+// Titre	Méthodes
+//--
+//++
+//  void  SetFluxLimits(float min=1., float max=-1., int nl=5, bool dispflx=false, bool refr=false)
+//	Modifie les paramètres de visualisation (limites en flux). Si "dispflx==true"
+//	les valeurs de flux sont affichées pour chaque étoile.
+//  StarList*  StList()
+//	Retourne l'objet "StarList" associé.
+//  float FluxMin()
+//	Retourne le paramètre de visualisation flux minimum
+//  float FluxMax()
+//	Retourne le paramètre de visualisation flux maximum
+//--
+
+/* --Methode-- */
+void  PIStarList::SetFluxLimits(float fmin, float fmax, int nl, bool dispflx, bool refr)
+{
+  if (!mStL)  return;  
+  if (fmin < fmax)  { mFmin = fmin;  mFmax = fmax; }
+  else mStL->CalcFluxLimits(mFmin, mFmax);
+  if (mFmin < 1.e-10)  mFmin = 1.e-10;
+  if (mFmax <= mFmin)  mFmax = 1.5*mFmin;
+  mDLgF = log10((double)mFmax/(double)mFmin);
+  if (mDLgF < 1.e-10)  mDLgF = 1.e-10;
+  mF0 = mFmin;
+  if (nl < 1)  nl = 1;
+  if (nl > 20)  nl = 20;
+  mNLev = nl;  
+  mDspFV = dispflx;
+  if (refr)  Refresh();
+  return;
+}
+
+
+/* --Methode-- */
+void PIStarList::UpdateLimits()
+{
+  if (!mStL) return;
+
+  // Commencer par trouver nos limites
+  double x1,x2,y1,y2;
+  mStL->CalcXYLimits(x1, x2, y1, y2);
+  PIAxes::ReSizeMinMax(isLogScaleX(),x1,x2);
+  PIAxes::ReSizeMinMax(isLogScaleY(),y1,y2);
+  SetLimits(x1,x2,y1,y2); 
+  SetAxesFlags(kBoxAxes | kExtTicks | kLabels);
+}
+
+
+/* --Methode-- */
+void PIStarList::Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax)
+{
+BStar *sti;
+double xp,yp;
+float flx;
+int sz;
+char buff[128];
+int nok, nl2;
+
+if (!mStL) return;
+
+PIGrCoord uxmin, uxmax, uymin, uymax;
+g->GetGrSpace(uxmin, uxmax, uymin, uymax);
+double xmin2 = uxmin;
+double ymin2 = uymin;
+double xmax2 = uxmax;
+double ymax2 = uymax;
+
+// int msz = mMSz; //OP
+int  msz = GetGraphicAtt().GetMarkerSz(); 
+
+if (msz < 1) msz = 1;
+//PIMarker mrk = (mMrk != PI_NotDefMarker) ? mMrk : PI_FCircleMarker; //OP
+PIMarker mmrk = GetGraphicAtt().GetMarker();
+PIMarker mrk = (mmrk != PI_NotDefMarker) ? mmrk : PI_FCircleMarker;
+
+// g->SelFont();
+nok = 0;  nl2 = mNLev*2-1;
+for (int i=0; i<mStL->NbStars(); i++) {
+  sti = mStL->Star(i);
+  if ( !(sti->Nice(BStar::flagOK)) )  continue;
+  flx = sti->Flux();
+  if ( (flx < mFmin) || (flx > mFmax) )  continue;
+  xp = sti->PosX();   yp = sti->PosY();
+  if ( (xp < xmin2) || (xp > xmax2) || (yp < ymin2) || (yp > ymax2) )  continue;
+  nok++;
+  if ( (xp < xmin) || (xp > xmax) || (yp < ymin) || (yp > ymax) )  continue;
+  sz = (int)((log10((double)flx/mF0))/mDLgF*(double)nl2-0.01) + msz;
+  if (sz < 2)  g->SelMarker(sz, PI_DotMarker);
+  else g->SelMarker(sz, mrk);
+  g->DrawMarker((double)xp,(double)yp ); 
+  if (mDspFV) {  
+    sprintf(buff," F=%g", flx);
+    double dx,dy;
+    g->DGrC2UC(sz, 4, dx, dy);
+    g->DrawString(xp+dx, yp-dy, buff);
+    } 
+  }
+
+/*
+sprintf(buff, "StarList:  NbStars= %d  NDisp= %d", (int)mStL->NbStars(), nok);
+g->BaseGraphic()->DrawString(15,15,buff);
+sprintf(buff, "FMin= %g  FMax= %g Nl= %d Sz0= %d", mFmin, mFmax, mNLev, mMSz0);
+g->BaseGraphic()->DrawString(15,30,buff);
+*/
+
+}
+
+/* --Methode-- */
+void PIStarList::AppendTextInfo(string& info, double xmin, double ymin, double xmax, double ymax)
+{
+BStar *sti;
+double xp,yp;
+double flx,fnd;
+char buff[128];
+int ncnt = 0;
+sprintf(buff,"PIStarList: NStars %d \n", mStL->NbStars() );
+info += buff;
+info += "  Num:     XPos     YPos     Flux     Fond \n";
+for (int i=0; i<mStL->NbStars(); i++) {
+  sti = mStL->Star(i);
+  if ( !(sti->Nice(BStar::flagOK)) )  continue;
+  flx = sti->Flux();
+  fnd = sti->Fond();
+  if ( (flx < mFmin) || (flx > mFmax) )  continue;
+  xp = sti->PosX();   yp = sti->PosY();
+  if ( (xp < xmin) || (xp > xmax) || (yp < ymin) || (yp > ymax) )  continue;
+  ncnt++;
+  if (ncnt > 101) continue;
+  fnd = sti->Fond();
+  sprintf(buff,"%6d: %8.3g %8.3g %8.3g %8.3g \n", i, xp, yp, flx, fnd); 
+  info += buff;
+  }
+if (ncnt >= 101) info += " .... \n";
+sprintf(buff," %d stars inside selected region \n", ncnt);
+info += buff;
+return;
+}
Index: /tags/V_Dec2002/SophyaPI/PIext/pistlist.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/pistlist.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/pistlist.h	(revision 2309)
@@ -0,0 +1,32 @@
+#ifndef PISTLIST_H
+#define PISTLIST_H
+
+#include "stlist.h"
+#include "pidrawer.h"
+
+class PIStarList : public PIDrawer {
+public:
+                     PIStarList(StarList* stl, bool ad);
+  virtual           ~PIStarList();
+  
+  virtual void       Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax);
+  virtual void       UpdateLimits();
+  
+  virtual void       AppendTextInfo(string& info, double xmin, double ymin, double xmax, double ymax);
+
+  void               SetFluxLimits(float min=1., float max=-1., int nl=5, bool dispflx=false, bool refr=false);
+
+  inline StarList*   StList()  { return(mStL); }  
+  inline float       FluxMin() { return(mFmin); }       
+  inline float       FluxMax() { return(mFmax); }
+       
+protected:
+  StarList* mStL;
+  bool mAdDO;
+  float mFmin, mFmax;
+  int mNLev;
+  double mF0, mDLgF;
+  bool mDspFV;
+};
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/pitvmaad.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/pitvmaad.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/pitvmaad.cc	(revision 2309)
@@ -0,0 +1,117 @@
+//  Adaptateurs pour TMatrix TVector du package Sophya
+//                             R. Ansari  1/99
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#include "pitvmaad.h"
+#include <math.h>
+
+/* --Methode-- */
+template <class T> 
+POTVectorAdapter<T>::POTVectorAdapter(TVector<T>* v, bool ad)
+        : P1DArrayAdapter(v->NElts())
+{
+aDel = ad; 
+mVec = v; 
+}
+/* --Methode-- */
+template <class T> 
+POTVectorAdapter<T>::~POTVectorAdapter()
+{
+if (aDel) delete mVec;
+}
+
+/* --Methode-- */
+template <class T> 
+double POTVectorAdapter<T>::Value(int i)
+{
+return((*mVec)(i));
+}
+
+/* --Methode-- */
+double POTVectorAdapter< complex<float> >::Value(int i)
+{
+double re,im;
+re = (*mVec)(i).real();
+im = (*mVec)(i).imag();
+return(sqrt(re*re+im*im));
+}
+
+/* --Methode-- */
+double POTVectorAdapter< complex<double> >::Value(int i)
+{
+double re,im;
+re = (*mVec)(i).real();
+im = (*mVec)(i).imag();
+return(sqrt(re*re+im*im));
+}
+
+/* --Methode-- */
+template <class T> 
+POTMatrixAdapter<T>::POTMatrixAdapter(TMatrix<T>* mtx, bool ad)
+        : P2DArrayAdapter(mtx->NCols(), mtx->NRows())
+{
+aDel = ad; 
+mMtx = mtx;
+}
+/* --Methode-- */
+template <class T> 
+POTMatrixAdapter<T>::~POTMatrixAdapter()
+{
+if (aDel)  delete mMtx;
+}
+/* --Methode-- */
+template <class T> 
+double POTMatrixAdapter<T>::Value(int ix, int iy)
+{
+return((double)(*mMtx)(iy, ix));
+}
+
+/* --Methode-- */
+double POTMatrixAdapter< complex<float> >::Value(int ix, int iy)
+{
+double re,im;
+re = (*mMtx)(iy, ix).real();
+im = (*mMtx)(iy, ix).imag();
+return(sqrt(re*re+im*im));
+}
+
+/* --Methode-- */
+double POTMatrixAdapter< complex<double> >::Value(int ix, int iy)
+{
+double re,im;
+re = (*mMtx)(iy, ix).real();
+im = (*mMtx)(iy, ix).imag();
+return(sqrt(re*re+im*im));
+}
+
+#ifdef __CXX_PRAGMA_TEMPLATES__
+#pragma define_template POTVectorAdapter< int_4 >
+#pragma define_template POTVectorAdapter< int_8 >
+#pragma define_template POTVectorAdapter< float >
+#pragma define_template POTVectorAdapter< double >
+#pragma define_template POTVectorAdapter< complex<float> > 
+#pragma define_template POTVectorAdapter< complex<double> > 
+
+#pragma define_template POTMatrixAdapter< int_4 >
+#pragma define_template POTMatrixAdapter< int_8 >
+#pragma define_template POTMatrixAdapter< float >
+#pragma define_template POTMatrixAdapter< double >
+#pragma define_template POTMatrixAdapter< complex<float> > 
+#pragma define_template POTMatrixAdapter< complex<double> > 
+#endif
+
+#if defined(ANSI_TEMPLATES)
+template class POTVectorAdapter< int_4 >;
+template class POTVectorAdapter< int_8 >;
+template class POTVectorAdapter< float >;
+template class POTVectorAdapter< double >;
+template class POTVectorAdapter< complex<float> >;
+template class POTVectorAdapter< complex<double> >;
+
+template class POTMatrixAdapter< int_4 >;
+template class POTMatrixAdapter< int_8 >;
+template class POTMatrixAdapter< float >;
+template class POTMatrixAdapter< double >;
+template class POTMatrixAdapter< complex<float> >;
+template class POTMatrixAdapter< complex<double> >;
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/pitvmaad.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/pitvmaad.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/pitvmaad.h	(revision 2309)
@@ -0,0 +1,48 @@
+// This may look like C code, but it is really -*- C++ -*-
+//  Adaptateurs pour TMatrix TVector du package Sophya
+//                             R. Ansari  1/99
+// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
+
+#ifndef PITVMAAD_H_SEEN
+#define PITVMAAD_H_SEEN
+
+#include "machdefs.h"
+#include "parradapter.h"
+
+#include "tmatrix.h"
+#include "tvector.h"
+
+
+// Adaptateur de vecteurs SOPHYA a P1DArrayAdapter
+template <class T> 
+class POTVectorAdapter : public P1DArrayAdapter {
+public :
+		  POTVectorAdapter(TVector<T>* v, bool ad=false); 
+  virtual         ~POTVectorAdapter();
+  virtual double  Value(int i);
+
+protected:
+  bool aDel;
+  TVector<T>* mVec;
+};
+
+typedef POTVectorAdapter<r_8> POVectorAdapter;
+
+
+// Adaptateur de matrice SOPHYA a P2DArrayAdapter
+// Attention MatrixAdapter(X=Colonne, Y= Row) = Matrix(row, col)  
+template <class T> 
+class POTMatrixAdapter :  public P2DArrayAdapter {
+public :
+                  POTMatrixAdapter(TMatrix<T>* mtx, bool ad=false);
+  virtual         ~POTMatrixAdapter();
+  virtual double  Value(int ix, int iy);
+
+protected:
+  bool aDel;
+  TMatrix<T>* mMtx;
+};
+
+typedef POTMatrixAdapter<r_8> POMatrixAdapter;
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/servnobjm.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/servnobjm.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/servnobjm.cc	(revision 2309)
@@ -0,0 +1,1437 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include <typeinfo>
+#include <iostream.h>
+#include <string>
+#include <list>
+#include <map>
+
+#include "strutil.h"
+
+#include "nobjmgr.h"
+#include "servnobjm.h"
+#include "nomgadapter.h"
+#include "pistdimgapp.h"
+
+#include "fct1dfit.h"
+#include "fct2dfit.h"
+
+#ifdef SANS_EVOLPLANCK
+#include "matrix.h"
+#include "cvector.h"
+#else
+#include "tmatrix.h"
+#include "tvector.h"
+#include "pitvmaad.h"
+#endif
+
+#include "ntuple.h"
+#include "cimage.h"
+
+#include "histos.h"
+#include "histos2.h"
+#include "ntuple.h"
+#include "hisprof.h"
+
+#include "piyfxdrw.h"
+#include "pisurfdr.h"
+
+#include "pintuple.h"
+#include "pintup3d.h"
+
+#include "pipodrw.h"
+
+
+
+/* --Methode-- */
+Services2NObjMgr::Services2NObjMgr(NamedObjMgr* omg, string& tmpdir)
+{
+SetTmpDir(tmpdir);
+mImgapp = NULL;
+mOmg = omg;
+dynlink = NULL;
+}
+  
+/* --Methode-- */
+Services2NObjMgr::~Services2NObjMgr()
+{
+CloseDLL();
+}
+
+/* --Methode-- */
+void Services2NObjMgr::RegisterClass(AnyDataObj* o, NObjMgrAdapter* oa)
+{
+ObjAdaptList::iterator it;
+for(it = objadaplist.begin(); it != objadaplist.end(); it++) 
+#ifdef SANS_EVOLPLANCK
+    if (typeid(*o) == typeid(*((*it).obj)))  THROW(dupIdErr);
+#else
+    if (typeid(*o) == typeid(*((*it).obj)))  
+     throw(DuplicateIdExc("Services2NObjMgr::RegisterClass() - Duplicate class"));
+#endif
+dataobj_adapter oba;
+oba.obj = o;
+oba.obja = oa;
+objadaplist.push_back(oba);
+}
+
+/* --Methode-- */
+NObjMgrAdapter* Services2NObjMgr::GetAdapter(AnyDataObj* o)
+{
+ObjAdaptList::iterator it;
+for(it = objadaplist.begin(); it != objadaplist.end(); it++) 
+  if (typeid(*o) == typeid(*((*it).obj)))  return((*it).obja->Clone(o));
+return(new NObjMgrAdapter(o));
+}
+
+/* --Methode-- */
+void Services2NObjMgr::SetTmpDir(string const & tmpdir)
+{
+TmpDir = tmpdir;
+PDynLinkMgr::SetTmpDir(tmpdir);
+return;
+}
+
+/* --Methode-- */
+void Services2NObjMgr::PlotFunc(string const & expfunc, string & nom, double xmin, double xmax, int np, string dopt)
+{
+FILE *fip;
+string fname = TmpDir + "func1_pia_dl.c";
+string  cmd;
+int rc;
+
+if (!mImgapp)  return; 
+
+cmd = "rm -f " + fname;
+rc = system(cmd.c_str());
+// printf("PlotFunc_Do> %s  (Rc=%d)\n", cmd.c_str(), rc); 
+
+if ((fip = fopen(fname.c_str(), "w")) == NULL)   { 
+  string sn = fname; 
+  cout << "Services2NObjMgr/PlotFunc_Error: fopen( " << sn << endl; 
+  return; 
+  }
+
+// constitution du fichier a compiler
+fputs("#include <math.h> \n", fip);
+fputs("double func1_pia_dl_func(double x) \n{\n", fip);
+fprintf(fip,"return(%s); \n}\n", expfunc.c_str());
+fclose(fip);
+
+string func = "func1_pia_dl_func";
+DlFunctionOfX f = (DlFunctionOfX) LinkFunctionFromFile(fname, func);
+if (!f) return; 
+PlotFunc(f, nom, xmin, xmax, np, dopt);
+CloseDLL();
+return;
+}
+
+/* --Methode-- */
+void Services2NObjMgr::PlotFunc2D(string const & expfunc, string & nom, double xmin, double xmax, 
+                                  double ymin, double ymax, int npx, int npy, string dopt)
+{
+FILE *fip;
+string fname = TmpDir + "func2_pia_dl.c";
+string cmd;
+int rc;
+
+if (!mImgapp)  return; 
+
+cmd = "rm " + fname;
+rc = system(cmd.c_str());
+// printf("PlotFunc2D_Do> %s  (Rc=%d)\n", cmd.c_str(), rc); 
+
+if ((fip = fopen(fname.c_str(), "w")) == NULL)   { 
+  string sn = fname; 
+  cout << "Services2NObjMgr/PlotFunc2D_Error:  fopen( " << sn << endl; 
+  return; 
+  }
+
+// constitution du fichier a compiler
+fputs("#include <math.h> \n", fip);
+fputs("double func2_pia_dl_func(double x, double y) \n{\n", fip);
+fprintf(fip,"return(%s); \n}\n", expfunc.c_str());
+fclose(fip);
+
+string func = "func2_pia_dl_func";
+DlFunctionOfXY f = (DlFunctionOfXY) LinkFunctionFromFile(fname, func);
+if (!f)  return;
+PlotFunc2D(f, nom, xmin, xmax, ymin, ymax, npx, npy, dopt);
+CloseDLL();
+return;
+}
+
+/* --Methode-- */
+void Services2NObjMgr::PlotFuncFrCFile(string const & fname, string const & func, string & nom, 
+                                       double xmin, double xmax, int np, string dopt)
+{
+DlFunctionOfX f = (DlFunctionOfX) LinkFunctionFromFile(fname, func);
+if (!f) return; 
+PlotFunc(f, nom, xmin, xmax, np, dopt);
+CloseDLL();
+return;
+}
+
+/* --Methode-- */
+void Services2NObjMgr::PlotFunc2DFrCFile(string const & fname, string const & func, string & nom, 
+                                         double xmin, double xmax, double ymin, double ymax, int npx, int npy, string dopt)
+{
+DlFunctionOfXY f = (DlFunctionOfXY) LinkFunctionFromFile(fname, func);
+if (!f)  return;
+PlotFunc2D(f, nom, xmin, xmax, ymin, ymax, npx, npy, dopt);
+CloseDLL();
+return;
+}
+
+/* --Methode-- */
+void Services2NObjMgr::PlotFunc(DlFunctionOfX f, string & nom, double xmin, double xmax, int np, string dopt)
+{
+if (!mImgapp)  return; 
+
+int k;
+if (np < 1) np = 1;
+if (xmax <= xmin) xmax = xmin+1.;
+Vector* vpy = new Vector(np);
+
+double xx;
+double dx = (xmax-xmin)/np;
+
+try {
+  for(k=0; k<np; k++) { xx = xmin+dx*k; (*vpy)(k) = f(xx); }
+} 
+#ifdef SANS_EVOLPLANCK
+CATCH(merr) {
+  fflush(stdout); 
+  cout << endl; 
+  cerr << endl;
+  string es = PeidaExc(merr);
+  cerr << "Services2NObjMgr::PlotFunc()  Exception :" << merr << es;
+  delete vpy;
+  vpy = NULL;
+  } ENDTRY;
+#else
+catch ( PException exc ) {
+  fflush(stdout); 
+  cout << endl; 
+  cerr << endl;
+  cerr << "Services2NObjMgr::PlotFunc()  Exception :"  << exc.Msg() << endl; 
+  delete vpy;
+  vpy = NULL;
+}
+#endif
+
+if (vpy) {
+  string titre;
+  if (nom.length() < 1) {
+     titre = "Function f(x)";
+     nom = "/autoc/f_x";
+    }
+  else titre = nom;
+  
+  P1DArrayAdapter* vya = new POVectorAdapter(vpy, false);
+  vya->DefineXCoordinate(xmin, (xmax-xmin)/np);
+  PIYfXDrawer* dr = new   PIYfXDrawer(vya, NULL, true) ; 
+  dopt = "thinline " + dopt;
+  int rsid = mImgapp->DispScDrawer(dr, titre, dopt);
+  if (nom.length() > 0) { 
+    mOmg->AddObj(vpy, nom);
+    mOmg->AddWRsId(nom, rsid);
+    }
+  }
+return;
+}
+
+/* --Methode-- */
+void Services2NObjMgr::PlotFunc2D(DlFunctionOfXY f, string & nom, double xmin, double xmax, double ymin, double ymax, 
+                             int npx, int npy, string dopt)
+{
+if (!mImgapp)  return; 
+
+if (npx < 3) npx = 3;
+if (npy < 3) npy = 3;
+if (npx > 250) npx = 250;
+if (npy > 250) npy = 250;
+if (xmax <= xmin) xmax = xmin+1.;
+if (ymax <= ymin) ymax = ymin+1.;
+
+Matrix* mtx = new Matrix(npy, npx);
+
+int i,j;
+double xx, yy;
+double dx = (xmax-xmin)/npx;
+double dy = (ymax-ymin)/npy;
+// printf(" -- DBG -- %d %d , %g %g , %g %g \n", npx, npy, xmin, xmax, ymin, ymax);
+try {
+  for(j=0; j<npy; j++) {
+    yy = ymin+dy*j; 
+    for(i=0; i<npx; i++) {
+      xx = xmin+dx*i;
+      (*mtx)(j, i) = f(xx, yy);
+    }
+  }
+}
+#ifdef SANS_EVOLPLANCK
+CATCH(merr) {
+  fflush(stdout); 
+  cout << endl; 
+  cerr << endl;
+  string es = PeidaExc(merr);
+  cerr << "Services2NObjMgr::PlotFunc2D()  Exception :" << merr << es;
+  delete mtx;  mtx = NULL;
+  } ENDTRY;
+#else
+catch ( PException exc ) {
+  fflush(stdout); 
+  cout << endl; 
+  cerr << endl;
+  cerr << "Services2NObjMgr::PlotFunc2D()  Exception :"  << exc.Msg() << endl; 
+  delete mtx;  mtx = NULL;
+}
+#endif
+
+if (mtx) {
+  string titre;
+  if (nom.length() < 1) {
+     titre = "Function f(x,y)";
+     nom = "/autoc/f2d_xy";
+    }
+  else titre = nom;
+  P2DArrayAdapter* arr = new POMatrixAdapter(mtx, false);
+  arr->DefineXYCoordinates(xmin, ymin, dx, dy);
+  PISurfaceDrawer* sdr = new PISurfaceDrawer(arr, true, true, true);
+  int rsid = mImgapp->Disp3DDrawer(sdr, titre, dopt);
+  if (nom.length() > 0)  { 
+    mOmg->AddObj(mtx, nom);
+    mOmg->AddWRsId(nom, rsid);
+    }
+  }
+
+return;
+}
+
+/* --Methode-- */
+void Services2NObjMgr::ExpVal(string expval,string resultvarname)
+{
+ // Fill C-file to be executed
+ FILE *fip;
+ string func = "eval_pia_dl_func";
+ string fname = TmpDir + func; fname += ".c";
+ string  cmd = "rm -f " + fname; system(cmd.c_str());
+ if((fip=fopen(fname.c_str(), "w"))==NULL) { 
+   cout << "Services2NObjMgr/EvalExp_Error: fopen("<<fname<<")"<<endl; 
+   return; 
+ }
+ fprintf(fip,"#include <math.h>\n");
+ fprintf(fip,"double %s(double ___dummy_variable___) \n{\n",func.c_str());
+ // Add all variables already declared
+ DVList& varlist = mOmg->GetVarList();
+ DVList::ValList::const_iterator it;
+ for(it = varlist.Begin(); it != varlist.End(); it++) {
+#ifdef SANS_EVOLPLANCK
+   MuTyV mtv = (*it).second;
+   double value = (double)(mtv);
+#else
+   double value = (double)((*it).second.elval);
+#endif
+   string name_var = (*it).first;
+   fprintf(fip,"double %s = %.17f;\n",name_var.c_str(),value);
+ }
+ fprintf(fip,"return %s;\n}\n",expval.c_str());
+ fclose(fip);
+
+ // Dynamically link function
+ DlFunctionOfX f = (DlFunctionOfX) LinkFunctionFromFile(fname,func);
+ if(!f) {
+   cout<<"Services2NObjMgr/EvalExp_Error: linking DlFunctionOfX"<<endl;
+   cout<<"...expval = "<<expval<<endl;
+   return;
+ }
+
+ // Evaluate function and close dynamic link
+ double result;
+ try {
+   result = f(0.);
+   CloseDLL();
+ } catch ( ... ) {
+   cout<<"Services2NObjMgr/EvalExp_Error: Arithmetic exception"<<endl;
+   CloseDLL();
+   return;
+ }
+
+ // Eventually store the result into variable or just print it
+ if(resultvarname.size()>0) {
+   if(mOmg->HasVar(resultvarname)) mOmg->DeleteVar(resultvarname);
+   char str[512];
+   if(result==0.) sprintf(str,"%f",result);
+   else {
+     double lr = log10(fabs(result));
+     if(lr>-17. && lr<17.) sprintf(str,"%17f",result);
+     else                   sprintf(str,"%.17e",result);
+   }
+   mOmg->SetVar(resultvarname,(string)str);
+ } else cout<<result<<" = "<<expval<<endl;
+
+}
+
+/* --Methode-- */
+void Services2NObjMgr::DisplayPoints2D(string& nom,  string& expx, string& expy,
+                                       string& experrx, string& experry,
+                                       string& expcut, string dopt, string loop)
+{
+NObjMgrAdapter* obja=NULL;
+obja = mOmg->GetObjAdapter(nom);
+if (obja == NULL) {
+  cout << "Services2NObjMgr::DisplayPoints2D() Error , No such object " << nom << endl; 
+  return;
+  }
+if (!mImgapp)  return; 
+
+// Creation NTuple 
+char* ntn[4] = {"expx","expy","expex","expey",};
+NTuple* nt = NULL;
+bool haserr = false;
+
+if ( (experrx.length() > 0 ) && (experry.length() > 0 ) ) {  haserr = true;   nt = new NTuple(4, ntn); }
+else {  haserr = false;  experrx = experry = "0."; nt = new NTuple(2, ntn); }
+
+ComputeExpressions(obja, expx, expy, experrx, experry, expcut, loop, nt, NULL, NULL);
+
+if (nt->NEntry() < 1) {
+  cout << "Services2NObjMgr::DisplayPoints2D() Warning  Zero points satisfy cut !" << endl; 
+  delete nt;
+  return;
+  }
+
+// nt->Show();
+// nt->Print(0,10);
+PINTuple* pin = new PINTuple(nt, true);
+pin->SelectXY(ntn[0], ntn[1]);
+if ( haserr ) pin->SelectErrBar(ntn[2], ntn[3]);
+
+dopt = "defline " + dopt;
+string titre =  nom + ":" + expy + "%" + expx;
+mImgapp->DispScDrawer( (PIDrawer*)pin, titre, dopt);
+return;
+}
+
+/* --Methode-- */
+void Services2NObjMgr::DisplayPoints3D(string& nom,  string& expx, string& expy, 
+                                       string& expz, string& expcut, string dopt, string loop)
+{
+NObjMgrAdapter* obja=NULL;
+obja = mOmg->GetObjAdapter(nom);
+if (obja == NULL) {
+  cout << "Services2NObjMgr::DisplayPoints3D() Error , No such object " << nom << endl; 
+  return;
+  }
+if (!mImgapp)  return; 
+
+char* ntn[3] = {"expx","expy","expz"};
+NTuple* nt = new NTuple(3,ntn);  // Creation NTuple
+
+string expwt = "1.";
+ComputeExpressions(obja, expx, expy, expz, expwt, expcut, loop, nt, NULL, NULL);
+
+if (nt->NEntry() < 1) {
+  cout << "Services2NObjMgr::DisplayPoints3D() Warning  Zero points satisfy cut !" << endl;
+  delete nt;
+  return;
+  }
+nt->Show();
+nt->Print(0,10);
+PINTuple3D* pin = new PINTuple3D(nt, true);
+pin->SelectXYZ(ntn[0], ntn[1], ntn[2]);
+dopt = "defline " + dopt;
+
+// Pour plot a partir de DispScDrawer
+// string nomdisp = "_NT3D_";
+// mImgapp->DispScDrawer( (PIDrawer*)pin, nomdisp, opt);
+// Pour plot a partir de Disp3DDrawer
+string titre =  nom + ":" + expy + "%" + expx;
+mImgapp->Disp3DDrawer(pin, titre, dopt);
+
+return;
+}
+
+/* --Methode-- */
+void Services2NObjMgr::DisplayPoints2DW(string& nom, string& expx, string& expy, 
+                                        string& expwt, string& expcut, string dopt, string loop)
+{
+NObjMgrAdapter* obja=NULL;
+obja = mOmg->GetObjAdapter(nom);
+if (obja == NULL) {
+  cout << "Services2NObjMgr::DisplayPoints2DW() Error , No such object " << nom << endl; 
+  return;
+  }
+if (!mImgapp)  return; 
+
+char* ntn[3] = {"expx","expy","expw"};
+NTuple* nt = new NTuple(3,ntn);  // Creation NTuple
+
+string exp = "1.";
+ComputeExpressions(obja, expx, expy, expwt, exp, expcut, loop, nt, NULL, NULL);
+
+if (nt->NEntry() < 1) {
+  cout << "Services2NObjMgr::DisplayPoints2DW() Warning  Zero points satisfy cut !" << endl;
+  delete nt;
+  return;
+  }
+
+PINTuple* pin = new PINTuple(nt, true);
+pin->SelectXY(ntn[0], ntn[1]);
+pin->SelectWt(ntn[2]);
+
+string titre =  nom + ":" + expwt + "_" + expy + "%" + expx ;
+mImgapp->DispScDrawer( (PIDrawer*)pin, titre, dopt);
+return;
+}
+
+/* --Methode-- */
+void Services2NObjMgr::ProjectH1(string& nom, string& expx, string& expwt, 
+                                 string& expcut, string& nomh1, string dopt, string loop)
+{
+NObjMgrAdapter* obja=NULL;
+obja = mOmg->GetObjAdapter(nom);
+if (obja == NULL) {
+  cout << "Services2NObjMgr::ProjectH1() Error , No such object " << nom << endl; 
+  return;
+  }
+if (!mImgapp)  return; 
+
+Histo* h1 = NULL;
+NTuple* nt = NULL;
+AnyDataObj* oh = NULL; 
+if (nomh1.length() > 0) oh=mOmg->GetObj(nomh1);
+else nomh1 = "/tmp/projh1d";
+if ( (oh != NULL) && (typeid(*oh) == typeid(Histo)) )  h1 = (Histo*)oh;  // Pas de remise a zero ! h1->Zero();
+else {
+  char* ntn[2]= {"hxval", "hwt"};
+  nt = new NTuple(2,ntn);  // Creation NTuple 
+  }
+string expz = "0.";   
+ComputeExpressions(obja, expx, expwt, expz, expwt, expcut, loop, nt, h1, NULL);
+
+if ((!h1) && (!nt)) return;
+if (!h1) {
+  if (nt->NEntry() < 1) {
+    cout << "Services2NObjMgr::ProjectH1() Warning  Zero points satisfy cut !" << endl; 
+    delete nt;
+    return;
+    }
+  double xmin, xmax;
+  nt->GetMinMax(0, xmin, xmax);
+  h1 = new Histo(xmin, xmax, 100);
+  int k;
+  float* xn;
+  for(k=0; k<nt->NEntry(); k++)    {
+    xn = nt->GetVec(k);
+    h1->Add(xn[0], xn[1]);    
+    }
+  delete nt;
+  mOmg->AddObj(h1, nomh1);
+  }
+
+mOmg->DisplayObj(nomh1, dopt);
+return;  
+}
+
+/* --Methode-- */
+void Services2NObjMgr::ProjectH2(string& nom, string& expx, string& expy, string& expwt, 
+                                 string& expcut, string& nomh2, string dopt, string loop)
+{
+NObjMgrAdapter* obja=NULL;
+obja = mOmg->GetObjAdapter(nom);
+if (obja == NULL) {
+  cout << "Services2NObjMgr::ProjectH2() Error , No such object " << nom << endl; 
+  return;
+  }
+if (!mImgapp)  return; 
+
+Histo2D* h2 = NULL;
+NTuple* nt = NULL;
+AnyDataObj* oh = NULL;
+if (nomh2.length() > 0)  oh=mOmg->GetObj(nomh2);
+else nomh2 = "/tmp/projh2d";
+if ( (oh != NULL) && (typeid(*oh) == typeid(Histo2D)) )  h2 = (Histo2D*)oh;  // Pas de remise a zero ! h2->Zero();
+else {
+  char* ntn[3]= {"hxval", "hyval", "hwt"};
+  nt = new NTuple(3,ntn);  // Creation NTuple 
+  }
+string expz = "0.";   
+ComputeExpressions(obja, expx, expy, expwt, expwt, expcut, loop, nt, NULL, h2);
+
+if ((!h2) && (!nt)) return;
+if (!h2) {
+  if (nt->NEntry() < 1) {
+    cout << "Services2NObjMgr::ProjectH2() Warning  Zero points satisfy cut !" << endl; 
+    delete nt;
+    return;
+    }
+  double xmin, xmax, ymin, ymax;
+  nt->GetMinMax(0, xmin, xmax);
+  nt->GetMinMax(1, ymin, ymax);
+  h2 = new Histo2D(xmin, xmax, 50, ymin, ymax, 50);
+  int k;
+  float* xn;
+  for(k=0; k<nt->NEntry(); k++)    {
+    xn = nt->GetVec(k);
+    h2->Add(xn[0], xn[1], xn[2]);    
+    }
+  delete nt;
+  mOmg->AddObj(h2, nomh2);
+  }
+
+mOmg->DisplayObj(nomh2, dopt);
+return;  
+
+}
+
+/* --Methode-- cmv 13/10/98 */
+void Services2NObjMgr::ProjectHProf(string& nom, string& expx, string& expy, string& expwt,
+                                    string& expcut, string& nomprof, string dopt, string loop)
+//	Pour remplir un ``GeneralFitData'' a partir de divers objets: 
+//| nom = nom de l'objet a projeter dans un HProf.
+//| expx = expression X de definition du bin.
+//| expy = expression Y a additionner dans le bin.
+//| expwt = expression W du poids a additionner.
+//| expcut = expression du test de selection.
+//| nomprof = nom du HProf engendre (optionnel). Si l'objet n'existe pas
+//|           les limites Xmin,Xmax sont calculees automatiquement.
+//|           sinon ce sont celles de l'objet preexistant.
+//| opt = options generales pour le display.
+{
+NObjMgrAdapter* obja=NULL;
+obja = mOmg->GetObjAdapter(nom);
+if (obja == NULL) {
+  cout << "Services2NObjMgr::ProjectHProf() Error , No such object " << nom << endl; 
+  return;
+  }
+if (!mImgapp)  return; 
+
+HProf* hprof = NULL;
+NTuple* nt = NULL;
+AnyDataObj* oh = NULL;
+if (nomprof.length() > 0)  oh=mOmg->GetObj(nomprof);
+else nomprof = "/tmp/projprof";
+if( (oh!=NULL) && (typeid(*oh) == typeid(HProf)) )  hprof = (HProf*)oh;
+else {
+  char* ntn[3]= {"hxval", "hyval", "hwt"};
+  nt = new NTuple(3,ntn);  // Creation NTuple 
+}
+string expz = "0.";
+ComputeExpressions(obja, expx, expy, expwt, expwt, expcut, loop, nt, NULL, NULL, hprof);
+
+if((!hprof) && (!nt)) return;
+if(!hprof) {
+  if (nt->NEntry() < 1) {
+    cout << "Services2NObjMgr::ProjectHProf() Warning  Zero points satisfy cut !" << endl;
+    delete nt;
+    return;
+  }
+  r_8 xmin, xmax;
+  nt->GetMinMax(0, xmin, xmax);
+  hprof = new HProf(xmin, xmax, 100);
+  int k;
+  float* xn;
+  for(k=0; k<nt->NEntry(); k++)    {
+    xn = nt->GetVec(k);
+    hprof->Add(xn[0], xn[1], xn[2]);
+    }
+  delete nt;
+  mOmg->AddObj(hprof, nomprof);
+  }
+hprof->UpdateHisto();
+
+mOmg->DisplayObj(nomprof, dopt);
+return;
+}
+
+
+/* --Methode-- */
+void Services2NObjMgr::FillVect(string& nom, string& expx, string& expv, 
+                                   string& expcut, string& nomvec, string dopt, string loop)
+{
+NObjMgrAdapter* obja=NULL;
+obja = mOmg->GetObjAdapter(nom);
+if (obja == NULL) {
+  cout << "Services2NObjMgr::FillVect() Error , No such object: " << nom << endl; 
+  return;
+  }
+if (!mImgapp)  return; 
+
+Vector* v1 = NULL;
+AnyDataObj* ov = NULL; 
+ov=mOmg->GetObj(nomvec);
+if (ov != NULL) v1 = dynamic_cast<Vector *>(ov);
+if (v1 == NULL) {
+  cout << "Services2NObjMgr::FillVect() Error , No such object or not a vector: " << nomvec << endl; 
+  return;
+  }
+
+char* ntn[2]= {"vi", "vv"};
+NTuple* nt = new NTuple(2,ntn);  // Creation NTuple 
+
+string expz = "0.";   
+ComputeExpressions(obja, expx, expv, expz, expz, expcut, loop, nt);
+
+if (!nt) return;
+if (nt->NEntry() < 1) {
+  cout << "Services2NObjMgr::FillVect() Warning  Zero points satisfy cut !" << endl; 
+  delete nt;
+  return;
+  }
+
+  int i,k;
+  double* xn;
+  for(k=0; k<nt->NEntry(); k++)    {
+    xn = nt->GetLineD(k);
+    i = int(xn[0]+0.5);
+    if ( (i < 0) || i >= v1->NElts() ) continue;
+    (*v1)(i) = xn[1];
+    }
+  delete nt;
+  
+
+mOmg->DisplayObj(nomvec, dopt);
+return;  
+}
+
+/* --Methode-- */
+void Services2NObjMgr::FillMatx(string& nom, string& expx, string& expy, string& expv, 
+                                string& expcut, string& nommtx, string dopt, string loop)
+{
+NObjMgrAdapter* obja=NULL;
+obja = mOmg->GetObjAdapter(nom);
+if (obja == NULL) {
+  cout << "Services2NObjMgr::FillMatx() Error , No such objet " << nom << endl; 
+  return;
+  }
+if (!mImgapp)  return; 
+
+Matrix* mtx = NULL;
+AnyDataObj* om = NULL; 
+om=mOmg->GetObj(nommtx);
+if (om != NULL) mtx = dynamic_cast<Matrix *>(om);
+if (mtx == NULL) {
+  cout << "Services2NObjMgr::FillMatx() Error , No such object or not a matrix " << nommtx << endl; 
+  return;
+  }
+
+char* ntn[3]= {"mi", "mj", "mv"};
+NTuple* nt = new NTuple(3,ntn);  // Creation NTuple 
+
+string expz = "0.";   
+ComputeExpressions(obja, expx, expy, expv, expz, expcut, loop, nt);
+
+if (!nt) return;
+if (nt->NEntry() < 1) {
+  cout << "Services2NObjMgr::FillMatx() Warning  Zero points satisfy cut !" << endl; 
+  delete nt;
+  return;
+  }
+
+  int ic, jl, k;
+  double* xn;
+  for(k=0; k<nt->NEntry(); k++)    {
+    xn = nt->GetLineD(k);
+    ic = int(xn[0]+0.5);
+    jl = int(xn[1]+0.5);
+    if ( (ic < 0) || ic >= mtx->NCol() ) continue;
+    if ( (jl < 0) || jl >= mtx->NRows() ) continue;
+    (*mtx)(jl, ic) = xn[2];
+    }
+  delete nt;
+  
+
+mOmg->DisplayObj(nommtx, dopt);
+return;  
+
+}
+
+/* --Methode-- */
+void Services2NObjMgr::ExpressionToVector(string& nom, string& expx, string& expcut, 
+                                          string& nomvec, string dopt, string loop)
+{
+NObjMgrAdapter* obja=NULL;
+obja = mOmg->GetObjAdapter(nom);
+if (obja == NULL) {
+  cout << "Services2NObjMgr::ExpressionToVector() Error , No such object " << nom << endl; 
+  return;
+  }
+if (!mImgapp)  return; 
+
+NTuple* nt = NULL;
+if (nomvec.length() < 1) nomvec = "/tmp/expvec";
+
+char* ntn[2]= {"vecval", "vecwt"};
+nt = new NTuple(1,ntn);  // Creation NTuple
+ 
+string expwt = "1.";
+string expz = "0.";
+string dumexpcut = expcut; if(dumexpcut.size()<=0) dumexpcut = "1.";
+ComputeExpressions(obja,expx,expz,expz,expwt,dumexpcut,loop,nt,NULL,NULL);
+
+if (!nt) return;
+if (nt->NEntry() < 1) {
+  cout << "Services2NObjMgr::ExpressionToVector() Warning  Zero points satisfy cut !" << endl; 
+  delete nt;
+  return;
+  }
+  
+Vector* vec = new Vector(nt->NEntry());
+int k;
+float* xn;
+for(k=0; k<nt->NEntry(); k++)    {
+  xn = nt->GetVec(k);
+  (*vec)(k) = xn[0];
+  }
+delete nt;
+mOmg->AddObj(vec, nomvec); 
+mOmg->DisplayObj(nomvec, dopt);
+return;  
+}
+
+/* --Methode-- */
+void Services2NObjMgr::NtFromASCIIFile(string& nom,string& filename,double def_val)
+//	Pour remplir un ntuple "nom" existant a partir du fichier
+//	ASCII table "filename". Si il y a plus de variables dans le
+//	ntuple que dans le fichier "filename",
+//	les sur-numeraires sont mises a "def_val" par defaut.
+{
+AnyDataObj* mobj = mOmg->GetObj(nom);
+if(mobj == NULL)
+  {cout<<"NtFromASCIIFile() Error, object "<<nom<<" not existing"<<endl;
+   return;}
+if(typeid(*mobj) != typeid(NTuple))
+  {cout<<"NtFromASCIIFile() Error, object "<<nom<<" not an NTuple"<<endl;
+   return;}
+if (!mImgapp)  return; 
+
+NTuple* nt = (NTuple*) mobj;
+nt->FillFromASCIIFile(filename, def_val);
+return;
+}
+
+/* --Methode-- */
+void Services2NObjMgr::FillNT(string& nom, string& expx, string& expy, string& expz, 
+                              string& expt, string& expcut, string& nomnt, string loop)
+{
+NObjMgrAdapter* obja=NULL;
+obja = mOmg->GetObjAdapter(nom);
+if (obja == NULL) {
+  cout << "Services2NObjMgr::FillNT() Error , No such object " << nom << endl; 
+  return;
+  }
+if (!mImgapp)  return; 
+
+bool fgnnt = false;
+NTuple* nt = NULL;
+AnyDataObj* oh = NULL;
+if (nomnt.length() > 0)  oh=mOmg->GetObj(nomnt);
+else nomnt = "/tmp/fillnt";
+if ( (oh != NULL) && (typeid(*oh) == typeid(NTuple)) )  { 
+  nt = (NTuple*)oh;
+  if (nt->NVar() > 10) {
+    cout << "Services2NObjMgr::FillNT() Warning , Max 10 var in NTuple -> new NTuple" << endl;
+    nt = NULL;
+    }
+  }  
+if (nt == NULL) {
+  char* ntn[4]= {"x", "y","z","t"};
+  nt = new NTuple(4,ntn);  // Creation NTuple 
+  fgnnt = true;
+  }
+
+ComputeExpressions(obja, expx, expy, expz, expt, expcut, loop, nt, NULL, NULL);
+
+if (fgnnt) mOmg->AddObj(nt, nomnt);
+return;  
+
+}
+
+/* --Methode-- */
+void Services2NObjMgr::FillNTFrCFile(string & nom, string const & fname, 
+                                     string const & funcname, string & nomnt, string loop)
+{
+if (!mImgapp)  return; 
+
+NObjMgrAdapter* obja=NULL;
+obja = mOmg->GetObjAdapter(nom);
+if (obja == NULL) {
+  cout << "Services2NObjMgr::FillNTFrCFile( " << nom << "...) No such object" <<endl;
+  return;
+  }
+bool adel = true;
+NTupleInterface* objnt = obja->GetNTupleInterface(adel);
+if (objnt == NULL)  {
+  cout << "Services2NObjMgr::FillNTFrCFile( " << nom << "...) Not an NTupleInterface !" <<endl;
+  return;
+  }
+
+NTLoopExprFunc f = (NTLoopExprFunc)LinkFunctionFromFile(fname, funcname);
+if (!f) { 
+  cerr << "Services2NObjMgr::FillNTFrCFile Error Creation  NTLoopExprFunc" <<  endl; 
+  if (adel) delete objnt;   // Delete de l'objet NTupleInterface si necessaire
+  return;
+  }
+
+bool fgnnt = false;
+NTuple* nt = NULL;
+if (nomnt.length() > 0) {
+  AnyDataObj* oh = NULL;
+  oh=mOmg->GetObj(nomnt);
+  if ( (oh != NULL) && (typeid(*oh) == typeid(NTuple)) )  { 
+    nt = (NTuple*)oh;
+    if (nt->NVar() > 10) {
+      cout << "Services2NObjMgr::FillNTFrCFile() Warning , Max 10 var in NTuple -> new NTuple" << endl;
+      nt = NULL;
+      }
+    }  
+  if (nt == NULL) {
+    char* ntn[4]= {"x", "y","z","t"};
+    nt = new NTuple(4,ntn);  // Creation NTuple 
+    fgnnt = true;
+    }
+  }
+
+double xnt[10];
+float  fxnt[10];
+
+int i,k;
+for(i=0; i<10; i++) fxnt[i] = xnt[i] = 0.;
+
+
+// $CHECK$ A virer des que possible  - Pb blocage application quand trop d'impression
+// redirige -    On redirige la sortie sur le terminal 
+bool red = mImgapp->HasRedirectedStdOutErr();
+mImgapp->RedirectStdOutErr(false);
+
+int k1,k2,dk;
+k1 = 0;  k2 = objnt->NbLines();  dk = 1;
+DecodeLoopParameters(loop, k1, k2, dk);
+if (k1 < 0) k1 = 0;
+if (k2 < 0) k2 = objnt->NbLines();
+if (k2 > (int_4)objnt->NbLines()) k2 = objnt->NbLines();
+if (dk <= 0) dk = 1;
+
+try  {
+  double* xn;
+  int kmax = k2;
+  for(k=k1; k<kmax; k+=dk)    {
+    xn = objnt->GetLineD(k);
+    if (f(xn, xnt, xnt+1, xnt+2, xnt+3, k, kmax) != 0) {
+      if (nt) { 
+         for(i=0; i<4; i++) fxnt[i] = xnt[i]; 
+         nt->Fill(fxnt);
+         }
+      }
+    }
+ }
+#ifdef SANS_EVOLPLANCK
+CATCH(merr) {
+  fflush(stdout); 
+  cout << endl; 
+  cerr << endl;
+  string es = PeidaExc(merr);
+  cerr << "Services2NObjMgr::FillNTFrCFile()  Exception :" << merr << es;
+  } ENDTRY;
+#else
+catch ( PException exc ) {
+  fflush(stdout); 
+  cout << endl; 
+  cerr << endl;
+  cerr << "Services2NObjMgr::FillNTFrCFile()  Exception :" << exc.Msg() << endl; 
+}
+#endif
+
+if (adel) delete objnt;   // Delete de l'objet NTupleInterface si necessaire
+CloseDLL();
+
+// $CHECK$ A virer des que possible  On redirige la sortie sur la fenetre PIConsole 
+mImgapp->RedirectStdOutErr(red);
+
+if (fgnnt) mOmg->AddObj(nt, nomnt);
+return;
+}
+
+/* --Methode-- */
+void Services2NObjMgr::PrepareNTExpressionCFile(string & nom, string const & fname, 
+                                                string const & funcname)
+{
+NObjMgrAdapter* obja=NULL;
+obja = mOmg->GetObjAdapter(nom);
+if (obja == NULL) {
+  cout << "Services2NObjMgr::PrepareNTExpressionCFile( " << nom << "...) No such object" <<endl;
+  return;
+  }
+bool adel = true;
+NTupleInterface* objnt = obja->GetNTupleInterface(adel);
+if (objnt == NULL)  {
+  cout << "Services2NObjMgr::PrepareNTExpressionCFile( " << nom 
+       << "...) No NTupleInterface !" <<endl;
+  return;
+  }
+string  vardec = objnt->VarList_C("_xnti_");
+
+FILE *fip;
+if ((fip = fopen(fname.c_str(), "w")) == NULL)   { 
+  cout << "Services2NObjMgr::PrepareNTExpressionCFile()_Error: fopen " << fname << endl; 
+  if (adel) delete objnt;   // Delete de l'objet NTupleInterface si necessaire
+  return; 
+  }
+
+// constitution du fichier des decalarations des variables de l'interface NTuple
+fputs("#include <stdlib.h> \n", fip);
+fputs("#include <stdio.h> \n", fip);
+fputs("#include <math.h> \n\n", fip);
+
+fputs("/* ------ Compare bits on double --------- */ \n", fip);
+fputs("typedef long long int_8;\n", fip);
+fputs("int_8 BitCmp64(double v,int_8 flg)\n", fip);
+fputs("{return ((int_8)((v<0.) ? v-0.1 : v+0.1))&flg;}\n", fip);
+fputs("/* ------ Some random number generators --------- */ \n", fip);
+fputs("#if defined(__ppc__) && defined(__MACH__) \n",fip);
+fputs("#include <limits.h> \n", fip);
+fputs("#define drand48() ((double)(random())/LONG_MAX) \n",fip);
+fputs("#endif \n",fip);
+fputs("#define frand01() ( (float) drand48() ) \n", fip);
+fputs("#define drand01() drand48()  \n", fip);
+fputs("#define rand01()  drand48()  \n", fip);
+fputs("#define frandpm1() ( 2. * frand01() - 1.) \n", fip);
+fputs("#define drandpm1() ( 2. * drand01() - 1.) \n", fip);
+fputs("#define randpm1() ( 2. * drand01() - 1.) \n", fip);
+fputs("double NorRand(void) \n", fip);
+fputs(" { \n double x,A,B; \n LAB10: \n A = drand01(); \n", fip);
+fputs(" if ( A == 0. ) goto LAB10; \n B = drand01(); \n", fip);
+fputs(" x = sqrt(-2.*log(A))*cos(2.*M_PI*B); \n", fip);
+fputs(" return(x); \n } \n", fip);
+fputs("#define GauRand() NorRand() \n", fip);
+fputs("#define gaurand() NorRand() \n\n", fip);
+
+fputs("/* NTupleInterface Variable declaration - Generated by piapp  \n", fip);
+fputs("      -- Services2NObjMgr::PrepareNTExpressionCFile()  --     */ \n\n", fip);
+fprintf(fip,"int %s(double* _xnti_, double* _rx_, double* _ry_, double* _rz_, \n", 
+        funcname.c_str());
+fprintf(fip,"       double* _rt_, int _n_, int _nmax_) \n");
+fprintf(fip, "{ \n %s \n", vardec.c_str());
+fputs("  if (!1) { /* Cut Expression failed */ \n", fip);
+fputs("    *_rx_ = *_ry_ = *_rz_ = *_rt_ = 0.;  return(0);", fip);
+fputs("  } \n  /* Cut expression satisfied */ \n", fip);
+fputs("  *_rx_ = 1.; \n  *_ry_ = 1.; \n  *_rz_ = 1.; \n  *_rt_ = 1.; \n", fip);
+fputs("  return(1); \n} \n", fip);
+
+fclose(fip);
+
+if (adel) delete objnt;   // Delete de l'objet NTupleInterface si necessaire
+return;
+}
+
+/* --Methode-- cmv 13/10/98 */
+void Services2NObjMgr::FillGFD(string& nom, string& expx, string& expy, string& expz,
+                               string& experr, string& expcut, string& nomgfd, string loop)
+//	Pour remplir un ``GeneralFitData'' a partir de divers objets:
+//| nom = nom de l'objet a transcrire selon 1D: Z=f(X) ou 2D: Z=f(X,Y) .
+//|       Vector,Matrix,Histo,HProf,Histo2D,Image<T>,StarList,NTuple,GeneralFitData
+//| expx = expression X du GeneralFitData (1er abscisse)
+//| expy = expression Y du GeneralFitData (2sd abscisse si non "", Z=f(X,Y))
+//| expz = expression Z du GeneralFitData (valeur de l'ordonnee)
+//| experr = expression de l'erreur sur l'ordonnee Z
+//| expcut = expression du test de selection
+//| nomgfd = nom du GeneralFitData engendre (optionnel)
+{
+NObjMgrAdapter* obja=NULL;
+obja = mOmg->GetObjAdapter(nom);
+if (obja == NULL) {
+  cout << "Services2NObjMgr::FillGFD() Error , No such object "<<nom<<endl;
+  return;
+  }
+if(!mImgapp)  return;
+
+// 2D ou 3D?
+int nvar = 2;
+if(expy.length()<=0) {nvar = 1; expy = "0.";}
+
+// Creation NTuple Buffer
+char* ntn[4]= {"x","y","f","e"};
+NTuple*nt = new NTuple(4,ntn);
+
+// Remplissage NTuple buffer
+ComputeExpressions(obja, expx, expy, expz, experr, expcut, loop, nt, NULL, NULL);
+if(nt->NEntry() < 1)
+  {cout<<"Services2NObjMgr::FillGFD() Warning  Zero points satisfy cut !"<<endl; 
+   delete nt; return;}
+
+//Remplissage de la structure GeneraFitData
+if (nt->NEntry() <= 0) {
+  cout<<"Services2NObjMgr::FillGFD() Warning - NData= " << nt->NEntry() << endl;
+  delete nt;
+  return;
+  }
+
+GeneralFitData* gfd = new GeneralFitData(nvar,nt->NEntry(),0);
+int k;
+float* xn;
+for(k=0; k<nt->NEntry(); k++) {
+  xn = nt->GetVec(k);
+  gfd->AddData(xn,xn[2],xn[3]);
+}
+
+// Menage et table d'objets
+delete nt;
+mOmg->AddObj(gfd, nomgfd);
+return;
+}
+
+/* --Methode-- cmv 12/07/00 */
+void Services2NObjMgr::FillGFDfrVec(string nomgfd,string namx,string namy,string namz,string name)
+//	Pour remplir un ``GeneralFitData'' a partir de vecteurs
+//| gdfrvec nomgd X Y ! !
+//| gdfrvec nomgd X Y ! EY
+//| gdfrvec nomgd X Y Z !
+//| gdfrvec nomgd X Y Z EZ
+//| - nomgfd = nom du generaldata a remplir
+//| - namx = nom du vecteur contenant les valeurs X
+//| - namy = nom du vecteur contenant les valeurs Y
+//| - namz = nom du vecteur contenant les valeurs Z (ou "!")
+//| - name = nom du vecteur contenant les valeurs des erreurs EY ou EZ
+{
+// Decodage des noms des vecteurs pour le remplissage du generaldata
+if(nomgfd=="!" || nomgfd.length()<1)
+  {cout<<"FillGFDfrVec_Error: bad GenaralData name "<<nomgfd<<endl; return;}
+if(namx=="!" || namx.length()<1)
+  {cout<<"FillGFDfrVec_Error: bad X vector name "<<namx<<endl; return;}
+if(namy=="!" || namy.length()<1)
+  {cout<<"FillGFDfrVec_Error: bad Y vector name "<<namy<<endl; return;}
+if(namz.length()<1) namz = "!";
+if(name.length()<1) name = "!";
+int nvar = 0;
+if(namz=="!") nvar = 1; else nvar = 2;
+
+// Identify data
+NamedObjMgr omg;
+AnyDataObj* mobj = NULL;
+Vector* v;
+int nel = 0;
+r_8 *x=NULL, *y=NULL, *z=NULL,* ez=NULL;
+
+if( (mobj=omg.GetObj(namx)) == NULL) {
+  cout<<"FillGFDfrVec_Error: unknown X object "<<namx<<endl; return;
+} else {
+  v = (Vector*) mobj; x = v->Data(); nel=v->NElts();
+}
+
+if( (mobj=omg.GetObj(namy)) == NULL) {
+  cout<<"FillGFDfrVec_Error: unknown Y object "<<namy<<endl; return;
+} else {
+  v = (Vector*) mobj; y = z = v->Data(); if(v->NElts()<nel) nel=v->NElts();
+}
+
+if( nvar==2 && (mobj=omg.GetObj(namz)) == NULL) {
+  cout<<"FillGFDfrVec_Error: unknown Z object "<<namz<<endl; return;
+} else {
+  v = (Vector*) mobj; z = v->Data(); if(v->NElts()<nel) nel=v->NElts();
+}
+
+if(name!="!") {
+  if( (mobj=omg.GetObj(name)) == NULL) {
+    cout<<"FillGFDfrVec_Error: unknown EZ object "<<name<<endl; return;
+  } else {
+    v = (Vector*) mobj; ez = v->Data(); if(v->NElts()<nel) nel=v->NElts();
+  }
+}
+
+if(nel<=0)
+  {cout<<"FillGFDfrVec_Error: bad number of elements "<<nel<<endl; return;}
+
+// Create GeneralData and fill it with vectors
+GeneralFitData* gfd = new GeneralFitData(nvar,nel+5,0);
+if(nvar==1) gfd->SetData1(nel,x,z,ez);     // On remplit Y=f(X)
+else        gfd->SetData2(nel,x,y,z,ez);   // On remplit Z=f(X,y)
+
+// Menage et table d'objets
+if( omg.GetObj(nomgfd) != NULL ) omg.DelObj(nomgfd);
+mOmg->AddObj(gfd,nomgfd);
+return;
+}
+
+/* --Methode-- */
+void Services2NObjMgr::ComputeExpressions(NObjMgrAdapter* obja, string& expx, 
+                          string& expy, string& expz, string& expt, string& expcut, string& loop, 
+                          NTuple* nt, Histo* h1, Histo2D* h2, HProf* hp)
+{
+if (obja == NULL) return;
+bool adel = true;
+NTupleInterface* objnt = obja->GetNTupleInterface(adel);
+if (objnt == NULL)  return;
+string  vardec = objnt->VarList_C("_zz6qi_");
+
+PlotExprFunc f = LinkExprFunc(vardec, expx, expy, expz, expt, expcut);
+if (!f) { 
+  cerr << "Services2NObjMgr::::ComputeExpressions() Error Creation PlotExprFunc " <<  endl; 
+  if (adel) delete objnt;  // Delete de l'objet NTupleInterface si necessaire
+  return;
+  }
+
+double xnt[10];
+float  fxnt[10];
+
+int i,k;
+for(i=0; i<10; i++) xnt[i] = 0.;
+int k1,k2,dk;
+k1 = 0;  k2 = objnt->NbLines();  dk = 1;
+DecodeLoopParameters(loop, k1, k2, dk);
+if (k1 < 0) k1 = 0;
+if (k2 < 0) k2 = objnt->NbLines();
+if (k2 > (int_4)objnt->NbLines()) k2 = objnt->NbLines();
+if (dk <= 0) dk = 1;
+
+try  {
+  double* xn;
+  for(k=k1; k<k2; k += dk)    {
+    xn = objnt->GetLineD(k);
+    if (f(xn, xnt, xnt+1, xnt+2, xnt+3) != 0) {
+      if (nt) { 
+         for(i=0; i<4; i++) fxnt[i] = xnt[i]; 
+         nt->Fill(fxnt);
+         }
+      if (h1) h1->Add(xnt[0], xnt[3]);
+      if (h2) h2->Add(xnt[0], xnt[1], xnt[3]);
+      if (hp) hp->Add(xnt[0], xnt[1], xnt[3]);
+      }
+    }
+ }
+#ifdef SANS_EVOLPLANCK
+CATCH(merr) {
+  fflush(stdout); 
+  cout << endl; 
+  cerr << endl;
+  string es = PeidaExc(merr);
+  cerr << "Services2NObjMgr::ComputeExpressions()  Exception :" << merr << es;
+  } ENDTRY;
+#else
+catch ( PException exc ) {
+  fflush(stdout); 
+  cout << endl; 
+  cerr << endl;
+  cerr << "Services2NObjMgr::ComputeExpressions()  Exception :" << exc.Msg() << endl; 
+}
+#endif
+
+if (adel) delete objnt;  // Delete de l'objet NTupleInterface si necessaire
+// Fermeture du fichier .so 
+CloseDLL();
+return;
+}
+
+
+/* --Methode-- */
+PlotExprFunc Services2NObjMgr::LinkExprFunc(string& vardec, string& expx, string& expy, 
+                                            string& expz, string& expt, string& cut)
+{
+FILE *fip;
+string fname = TmpDir + "expf_pia_dl.c";
+string cmd;
+int rc;
+
+cmd = "rm -f " + fname;
+rc = system(cmd.c_str());
+//DBG printf("LinkExprFunc_Do> %s  (Rc=%d)\n", cmd.c_str(), rc); 
+
+if ((fip = fopen(fname.c_str(), "w")) == NULL)   { 
+  string sn = fname; 
+  cout << "Services2NObjMgr/LinkExprFunc_Error: fopen( " << sn << endl; 
+  return(NULL); 
+  }
+
+// constitution du fichier a compiler
+fputs("#include <stdlib.h> \n", fip);
+fputs("#include <math.h> \n", fip);
+
+fputs("/* ------ Compare bits on double --------- */ \n", fip);
+fputs("typedef long long int_8;\n", fip);
+fputs("int_8 BitCmp64(double v,int_8 flg)\n", fip);
+fputs("{return ((int_8)((v<0.) ? v-0.1 : v+0.1))&flg;}\n", fip);
+fputs("/* ------ Some random number generators --------- */ \n", fip);
+fputs("#if defined(__ppc__) && defined(__MACH__) \n",fip);
+fputs("#include <limits.h> \n", fip);
+fputs("#define drand48() ((double)(random())/LONG_MAX) \n",fip);
+fputs("#endif \n",fip);
+fputs("#define frand01() ( (float) drand48() ) \n", fip);
+fputs("#define drand01() drand48()  \n", fip);
+fputs("#define rand01()  drand48()  \n", fip);
+fputs("#define frandpm1() ( 2. * frand01() - 1.) \n", fip);
+fputs("#define drandpm1() ( 2. * drand01() - 1.) \n", fip);
+fputs("#define randpm1() ( 2. * drand01() - 1.) \n", fip);
+fputs("double NorRand(void) \n", fip);
+fputs(" { \n double x,A,B; \n LAB10: \n A = drand01(); \n", fip);
+fputs(" if ( A == 0. ) goto LAB10; \n B = drand01(); \n", fip);
+fputs(" x = sqrt(-2.*log(A))*cos(2.*M_PI*B); \n", fip);
+fputs(" return(x); \n } \n", fip);
+fputs("#define GauRand() NorRand() \n", fip);
+fputs("#define gaurand() NorRand() \n\n", fip);
+
+fputs("int expf_pia_dl_func(double* _zz6qi_, double* _rx_6q_, double* _ry_6q_, double* _rz_6q_, double* _rt_6q_) \n{\n", fip);
+fprintf(fip,"%s \n", vardec.c_str());
+fprintf(fip, "if (!(%s)) { *_rx_6q_ = *_ry_6q_ = *_rz_6q_ = *_rt_6q_ = 0.;  return(0); } \n", cut.c_str());
+fprintf(fip, "*_rx_6q_ = %s ; \n", expx.c_str());
+fprintf(fip, "*_ry_6q_ = %s ; \n", expy.c_str());
+fprintf(fip, "*_rz_6q_ = %s ; \n", expz.c_str());
+fprintf(fip, "*_rt_6q_ = %s ; \n", expt.c_str());
+fputs("return(1); \n} \n", fip);
+fclose(fip);
+string func = "expf_pia_dl_func";
+return((PlotExprFunc)LinkFunctionFromFile(fname, func));
+}
+
+
+/* --Methode-- */
+DlFunction Services2NObjMgr::LinkFunctionFromFile(string const & fname, string const & funcname)
+{
+//  Le link dynamique
+CloseDLL();
+dynlink = PDynLinkMgr::BuildFromCFile(fname);
+if (dynlink == NULL) { 
+  cerr << "Services2NObjMgr/LinkFunctionFromFile_Erreur: Erreur creation/Ouverture SO " << endl; 
+  return(NULL); 
+  }
+
+DlFunction retfunc = dynlink->GetFunction(funcname);
+if (retfunc == NULL) { 
+  string sn = funcname; 
+  cerr << "Services2NObjMgr/LinkExprFunc_Erreur: Erreur linking " << sn << endl; 
+  CloseDLL();
+  return(NULL); 
+  }
+else return(retfunc);
+}
+
+/* --Methode-- */
+void Services2NObjMgr::CloseDLL()
+{
+if (dynlink) delete dynlink;   dynlink = NULL;
+}
+
+/* --Methode-- */
+int Services2NObjMgr::ExecuteCommand(string line)
+{
+  if (mImgapp == NULL) return(99);
+  return(mImgapp->CmdInterpreter()->Interpret(line));
+}
+
+// Fonction static
+/* --Methode-- */
+void Services2NObjMgr::DecodeLoopParameters(string& loop, int& i1, int& i2, int& di)
+{
+// Decode des paramatres de boucle for(int i=i1; i<i2; i+=di) specifies 
+// sous forme i1[:i2[:di]]
+// cout << "LoopParam() " << loop << " I1=" << i1 << " I2=" << i2 << " DI=" << di; 
+size_t l = loop.length();
+if (l < 1) return;
+size_t p = loop.find(':');
+if (p >= l) { i1 = atoi(loop.c_str()); return; }
+i1 = atoi(loop.substr(0, p).c_str());
+string aa = loop.substr(p+1);
+p = aa.find(':');
+if (p < aa.length() ) { 
+  i2 = atoi(aa.substr(0,p).c_str());
+  di = atoi(aa.substr(p+1).c_str());
+  }
+else i2 = atoi(aa.c_str());
+// cout << "-> I1= " << i1 << " I2= " << i2 << " DI= " << di << endl; 
+return;
+}
+
+/* --Methode-- */
+string Services2NObjMgr::FileName2Name(string const & fn)
+{
+
+char fsep[2] = {FILESEP, '\0'};
+char tsep[2] = {'.', '\0'};
+size_t p = fn.find_last_of(fsep);
+size_t l = fn.length();
+if (p >= l)  p = 0;
+else p++;
+size_t q = fn.find_first_of(tsep,p);
+if (q < p) q = l;
+return(fn.substr(p,q-p));
+}
+
+
+
+
+// SANS_EVOLPLANCK     Attention !
+#ifdef SANS_EVOLPLANCK
+#include "pclassids.h"
+
+/* --Methode-- */
+char* Services2NObjMgr::PClassIdToClassName(int cid)
+{
+switch (cid) {
+  case ClassId_Poly1 : 
+    return("Poly1");
+  case ClassId_Poly2 : 
+    return("Poly2");
+  case ClassId_Matrix : 
+    return("Matrix");
+  case ClassId_Vector : 
+    return("Vector");
+
+  case ClassId_DVList : 
+    return("DVList");
+
+  case ClassId_Histo1D : 
+    return("Histo1D");
+  case ClassId_Histo2D : 
+    return("Histo2D");
+  case ClassId_HProf : 
+    return("HProf");
+  case ClassId_NTuple : 
+    return("NTuple");
+  case ClassId_XNTuple : 
+    return("XNTuple");
+  case ClassId_GeneralFitData : 
+    return("GeneralFitData");
+
+  case ClassId_Image : 
+    return("RzImage");
+  case ClassId_Image + kuint_1 : 
+    return("ImageU1");
+  case ClassId_Image + kint_1 : 
+    return("ImageI1");
+  case ClassId_Image + kuint_2 : 
+    return("ImageU2");
+  case ClassId_Image + kint_2 : 
+    return("ImageI2");
+  case ClassId_Image + kuint_4 : 
+    return("ImageU4");
+  case ClassId_Image + kint_4 : 
+    return("ImageI4");
+  case ClassId_Image + kr_4 : 
+    return("ImageR4");
+  case ClassId_Image + kr_8 : 
+    return("ImageR8");
+  case ClassId_ZFidu : 
+    return("ZFidu");
+
+  case ClassId_StarList : 
+    return("StarList");
+  case ClassId_Transfo : 
+    return("Transfo");
+  case ClassId_PSF : 
+    return("PSF");
+
+
+// - Ajout objet PPF
+  default:
+    return("AnyDataObj");
+  }
+}  
+
+#else
+char* Services2NObjMgr::PClassIdToClassName(int cid)
+{
+    return("AnyDataObj");
+}
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/servnobjm.h
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/servnobjm.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/servnobjm.h	(revision 2309)
@@ -0,0 +1,140 @@
+// This may look like C code, but it is really -*- C++ -*-
+// Classe de services destinee a NamedObjMgr pour piapp
+// Reza                             Aout 98
+// CEA-DAPNIA      LAL-IN2P3/CNRS
+
+#ifndef SERVNOBJM_H_SEEN
+#define SERVNOBJM_H_SEEN
+
+#include "machdefs.h"
+#include <string>
+#include <list>
+#include <map>
+#include <functional>
+
+#include "pdlmgr.h"
+#include "dlftypes.h"
+#include "anydataobj.h"
+
+#ifdef SANS_EVOLPLANCK
+class NTuple;
+class Histo;
+class Histo2D;
+class HProf;
+#else
+namespace SOPHYA { 
+class NTuple;
+class Histo;
+class Histo2D;
+class HProf;
+}
+#endif
+
+class NamedObjMgr;
+class PIStdImgApp;
+class NObjMgrAdapter;
+
+class Services2NObjMgr {
+public:
+         	Services2NObjMgr(NamedObjMgr* omg, string& tmpdir);
+  virtual	~Services2NObjMgr();
+
+// Pour enregistrer les objets de donnees et leurs adaptateurs
+  void			RegisterClass(AnyDataObj* o, NObjMgrAdapter* oa);
+// Pour recuperer l'adaptateur pour un objet o 
+  NObjMgrAdapter*	GetAdapter(AnyDataObj* o);
+
+  inline void   SetImgApp(PIStdImgApp* app) {mImgapp = app; }
+  void          SetTmpDir(string const & tmpdir);
+
+// Trace de fonctions 1-D , 2-D
+  virtual void  PlotFunc(string const & expfunc, string & nom, double xmin, double xmax, 
+                         int np=100, string dopt="");
+  virtual void  PlotFunc2D(string const & expfunc, string & nom, double xmin, double xmax, 
+                           double ymin, double ymax, int npx=50, int npy=50, string dopt="");
+  virtual void  PlotFuncFrCFile(string const & fname, string const & func, string & nom, 
+                                double xmin, double xmax, int np=100, string dopt="");
+  virtual void  PlotFunc2DFrCFile(string const & fname, string const & func, string & nom, 
+                                  double xmin, double xmax, double ymin, double ymax, 
+                                  int npx=50, int npy=50, string dopt="");
+  virtual void  PlotFunc(DlFunctionOfX f, string & nom, double xmin, double xmax, 
+                         int np=100, string dopt="");
+  virtual void  PlotFunc2D(DlFunctionOfXY f, string & nom, double xmin, double xmax, 
+                           double ymin, double ymax, int npx=50, int npy=50, string dopt="");
+
+// Calcul d'expression arithmetique
+  virtual void ExpVal(string expval,string resultvarname="");
+
+//  Trace d'expression de NTuple, et d'autres objets
+  virtual void          DisplayPoints2D(string & nom, string& expx, string& expy,
+                                        string& experrx, string& experry, 
+                                        string& expcut, string dopt="", string loop="");
+  virtual void          DisplayPoints3D(string & nom, string& expx, string& expy, string& expz, 
+                                        string& expcut, string dopt="", string loop="");
+  virtual void          DisplayPoints2DW(string & nom, string& expx, string& expy, 
+                                         string& expwt, string& expcut, string dopt="", string loop="");
+//  Projection d'expressions dans histogramme, vecteur/matrices (et trace) 
+  virtual void          ProjectH1(string & nom, string& expx, string& expwt, string& expcut, 
+                                  string& nomh1, string dopt="", string loop="");
+  virtual void          ProjectH2(string & nom, string& expx, string& expy, string& expwt, 
+                                  string& expcut, string& nomh2, string dopt="", string loop="");
+  virtual void          ProjectHProf(string & nom, string& expx, string& expy, string& expwt, 
+                                  string& expcut, string& nomprof, string dopt="", string loop="");
+
+//  Remplissage de vecteurs, ntuples, GFD 
+  virtual void          FillVect(string & nom, string& expx, string& expv, string& expcut, 
+                                  string& nomvec, string dopt="", string loop="");
+  virtual void          FillMatx(string & nom, string& expx, string& expy, string& expv, 
+                                  string& expcut, string& nommtx, string dopt="", string loop="");
+
+  virtual void          ExpressionToVector(string & nom, string& expx, string& expcut, 
+                                           string& nomvec, string dopt="", string loop="");
+  virtual void          NtFromASCIIFile(string& nom,string& filename,double def_val=0.);
+  virtual void          FillNT(string & nom, string& expx, string& expy, string& expz,
+                               string& expt, string& expcut, string& nomnt, string loop=""); 
+  virtual void          FillGFD(string & nom, string& expx, string& expy, string& expz,
+                               string& experr, string& expcut, string& nomgfd, string loop="");
+  virtual void          FillGFDfrVec(string nomgfd,string namx,string namy,string namz,string name);
+  virtual void          FillNTFrCFile(string & nom, string const & fname, 
+                                      string const & funcname, string & nomnt, string loop="");
+  virtual void		PrepareNTExpressionCFile(string & nomobj, string const & fname, 
+                                                 string const & funcname);
+
+// Calcul d'expressions d'interface NTuple pour les objets
+  void 		ComputeExpressions(NObjMgrAdapter* obja, string& expx, string& expy, 
+                                   string& expz, string& expt, string& expcut, string& loop,
+                                   NTuple* nt=NULL, Histo* h1=NULL,
+                                   Histo2D* h2=NULL, HProf* hp=NULL);
+  PlotExprFunc  LinkExprFunc(string& vardec, string& expx, string& expy, 
+                             string& expz, string& expt, string& cut);
+  DlFunction    LinkFunctionFromFile(string const & fname, string const & funcname);
+  void 		CloseDLL();  
+
+// Execution de chaine de commande par l'interpreteur
+  int	        ExecuteCommand(string line);
+
+// Utilitaires divers 
+  static void   DecodeLoopParameters(string& loop, int& i1, int& i2, int& di);
+  string 	FileName2Name(string const & fn);
+  char* 	PClassIdToClassName(int cid);
+
+protected:
+
+// Pour enregister les objets et leurs adaptateurs pour NamedObjMgr
+  struct dataobj_adapter {
+    AnyDataObj* obj;  NObjMgrAdapter* obja;
+  };
+  typedef list<dataobj_adapter> ObjAdaptList;
+  ObjAdaptList objadaplist;
+
+
+  PDynLinkMgr * dynlink;  // shared-lib lib.so
+  string TmpDir;          // Pour fichiers temporaires
+
+  PIStdImgApp* mImgapp;
+  NamedObjMgr* mOmg;
+  
+};
+
+
+#endif
Index: /tags/V_Dec2002/SophyaPI/PIext/userfitfunex.c
===================================================================
--- /tags/V_Dec2002/SophyaPI/PIext/userfitfunex.c	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/PIext/userfitfunex.c	(revision 2309)
@@ -0,0 +1,72 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+/********************************************************************/
+/* fonction de fit "f(x;h,x0,sig,c) = h*exp(-0.5*((x-x0)/sig)^2)+c" */
+/* avec nvar=1 npar=4                                               */
+/*      x = x[0]                                                    */
+/*      p[0]=h, p[1]=x0, p[2]=sig, p[3]=c                           */
+/********************************************************************/
+double gauss1(double const* x,double const* p)
+{
+double xc;
+xc = (x[0]-p[1])/p[2]; xc *= -xc/2.;
+return((xc>=-80.) ? p[0]*exp(xc)+p[3] : p[3]);
+}
+
+/* la definition de cette fonction n'est pas obligatoire */
+/* dp[0] = df(x;h,x0,sig,c)/dh, dp[1] = etc...           */
+double gauss1_der(double const* x,double const* p,double* dp)
+{
+double xc,xc2,e,f;
+xc = (x[0]-p[1])/p[2];
+xc2 = xc*xc;
+e = -xc2/2.;
+if(e>=-80.) e = exp(e); else e = 0.;
+f = p[0]*e;
+dp[0] = e;
+dp[1] = xc  / p[2] *f;
+dp[2] = xc2 / p[2] *f;
+dp[3] = 1.;
+return(f+p[3]);
+}
+
+/********************************************************/
+/* fonction de fit gaussienne 2D avec correlation       */
+/* f(x,y;h,x0,y0,sx,sy,rho,c) =                         */
+/*   h * exp{ -0.5*[ (x-x0)^2/sx^2 + (y-y0)^2/s^2       */
+/*                   -2*rho*(x-x0)*(y-y0)/(sx*sy) ]}    */
+/* avec nvar=2 npar=7                                   */
+/*      x = x[0] et y=x[2]                              */
+/*      p[0]=h, p[1]=x0, p[2]=y0                        */
+/*      p[3]=sx, p[4]=sy, p[5]=rho, p[6]=fond           */
+/********************************************************/
+double gauss2(double const* x,double const* p)
+{
+double ax,ay,a;
+ax = (x[0]-p[1])/p[3];
+ay = (x[1]-p[2])/p[4];
+a  = -(ax*ax+ay*ay-2.*p[5]*ax*ay)/2.;
+return((a>=-80.) ? p[0]*exp(a)+p[6] : p[6]);
+}
+
+/* la definition de cette fonction n'est pas obligatoire */
+/* dp[0] = f(x,y;h,x0,y0,sx,sy,rho,c)/dh, dp[1] = etc... */
+double gauss2_der(double const* x,double const* p,double* dp)
+{
+double ax,ay,a,p0ea;
+ax   = (x[0]-p[1])/p[3];
+ay   = (x[1]-p[2])/p[4];
+a    = -(ax*ax+ay*ay-2.*p[5]*ax*ay)/2.;
+p0ea = (a>=-80.) ? exp(a) : 0.;
+dp[0] = p0ea;
+  p0ea *= p[0];
+dp[1] = (ax-p[5]*ay)/p[3] *p0ea;
+dp[2] = (ay-p[5]*ax)/p[4] *p0ea;
+dp[3] = ax*dp[1];
+dp[4] = ay*dp[2];
+dp[5] = ax*ay *p0ea;
+dp[6] = 1.;
+return(p0ea+p[6]);
+}
Index: /tags/V_Dec2002/SophyaPI/ProgPI/Makefile
===================================================================
--- /tags/V_Dec2002/SophyaPI/ProgPI/Makefile	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/ProgPI/Makefile	(revision 2309)
@@ -0,0 +1,534 @@
+MODULECXXREPNAME :=  ProgPI
+MODULEDECCXXFLAGS := -msg_quiet
+include ../Mgr/Makefile.h
+ 
+ifdef NOSHLIB
+LIBF =  $(LIB)libTArray.a $(LIB)libSysTools.a $(LIB)libNTools.a $(LIB)libSkyMap.a $(LIB)libSamba.a $(LIB)libSkyT.a $(LIB)libFitsIOServer.a $(LIB)libPI.a $(LIB)libPIext.a
+LIBS = -L$(LIB) -lTArray -lSysTools -lNTools -lSkyMap -lSamba -lSkyT -lFitsIOServer -lPI -lPIext  -lm
+ifeq ($(CXX),cxx)
+# librairie des instances de templates cxx
+LIBS := $(LIBS) -lertcxx
+endif
+else
+LIBF =  $(SLB)libPI.so $(SLB)libsophya.so $(SLB)libextsophya.so
+
+ifeq ($(MACHEROS),Darwin)
+LIBS = -L$(SLB) -lPI -lsophya -lextsophya 
+else
+ifeq ($(MACHEROS),Linux)
+LIBS = -L$(SLB) -lPI -lsophya -lextsophya  -L/usr/X11R6/lib -lXm -lXp -lXt -lX11 -lm
+else
+LIBS = -L$(SLB) -lPI -lsophya -lextsophya  -lXm -lXp -lXt -lX11 -lm
+endif
+endif
+
+endif
+LIBSORA := $(LIBS)
+LDLIBS := $(LIBS) $(LDLIBS)
+PROGS = $(EXE)spiapp
+
+all: $(PROGS)
+
+clean:
+	rm -f $(PROGS)
+	rm -f $(OBJ)piapp.o $(OBJ)sopiamodule.o $(OBJ)fitsbtadapter.o $(OBJ)w2ps.o $(OBJ)skymapmodule.o
+	if [ -d $(OBJ)cxxrep_ProgPI ] ; then cd $(OBJ)cxxrep_ProgPI ; rm -f *.o ; fi
+
+spiapp: $(EXE)spiapp
+	echo echo $@ " done"	
+$(EXE)spiapp: $(OBJ)piapp.o $(OBJ)sopiamodule.o $(OBJ)fitsbtadapter.o $(OBJ)w2ps.o $(OBJ)skymapmodule.o
+	$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@ 
+
+$(OBJ)fitsbtadapter.o: fitsbtadapter.cc \
+ $(INC)machdefs.h \
+ $(INC)nobjmgr.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)mutyv.h \
+ $(INC)dlftypes.h \
+ $(INC)servnobjm.h \
+ $(INC)pdlmgr.h \
+ $(INC)nomgadapter.h \
+ $(INC)pidrawer.h \
+ $(INC)pibwdggen.h \
+ $(INC)pisysdep.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picolist.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)ntupintf.h \
+ $(INC)generalfit.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)generaldata.h \
+ $(INC)poly.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)fmath.h \
+ $(INC)pistdimgapp.h \
+ $(INC)piapplx.h \
+ $(INC)piapplgen.h \
+ $(INC)picontainerx.h \
+ $(INC)picontainergen.h \
+ $(INC)pimenubarx.h \
+ $(INC)pimenubargen.h \
+ $(INC)pimenux.h \
+ $(INC)pimenugen.h \
+ $(INC)picons.h \
+ $(INC)pistdwdgx.h \
+ $(INC)pistdwdggen.h \
+ $(INC)pibwdgx.h \
+ $(INC)pigraphps.h \
+ $(INC)piwindowx.h \
+ $(INC)piwindowgen.h \
+ $(INC)pioptmenux.h \
+ $(INC)pioptmenugen.h \
+ $(INC)pifilechox.h \
+ $(INC)pifilechogen.h \
+ $(INC)piimage.h \
+ $(INC)pipixmapx.h \
+ $(INC)pipixmapgen.h \
+ $(INC)picmapview.h \
+ $(INC)pi3ddrw.h \
+ $(INC)pigraph3d.h \
+ $(INC)piacmd.h \
+ $(INC)pisiadw.h \
+ $(INC)pilistx.h \
+ $(INC)pilistgen.h \
+ $(INC)pistzwin.h \
+ $(INC)piperiodx.h \
+ $(INC)periodic.h \
+ $(INC)fbtntintf.h 
+$(OBJ)piapp.o: piapp.cc $(INC)pistdimgapp.h \
+ $(INC)pisysdep.h \
+ $(INC)machdefs.h \
+ $(INC)piapplx.h \
+ $(INC)piapplgen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picontainerx.h \
+ $(INC)picontainergen.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)picolist.h \
+ $(INC)pimenubarx.h \
+ $(INC)pimenubargen.h \
+ $(INC)pimenux.h \
+ $(INC)pimenugen.h \
+ $(INC)picons.h \
+ $(INC)pistdwdgx.h \
+ $(INC)pistdwdggen.h \
+ $(INC)pibwdgx.h \
+ $(INC)pibwdggen.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigraphps.h \
+ $(INC)piwindowx.h \
+ $(INC)piwindowgen.h \
+ $(INC)pioptmenux.h \
+ $(INC)pioptmenugen.h \
+ $(INC)pifilechox.h \
+ $(INC)pifilechogen.h \
+ $(INC)piimage.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)pidrawer.h \
+ $(INC)pipixmapx.h \
+ $(INC)pipixmapgen.h \
+ $(INC)picmapview.h \
+ $(INC)pi3ddrw.h \
+ $(INC)pigraph3d.h \
+ $(INC)nobjmgr.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)mutyv.h \
+ $(INC)dlftypes.h \
+ $(INC)piacmd.h \
+ $(INC)pdlmgr.h \
+ $(INC)pisiadw.h \
+ $(INC)pilistx.h \
+ $(INC)pilistgen.h \
+ $(INC)pistzwin.h \
+ $(INC)piperiodx.h \
+ $(INC)periodic.h \
+ $(INC)piversion.h \
+ $(INC)piaversion.h \
+ $(INC)timing.h \
+ $(INC)skyinit.h \
+ $(INC)ntoolsinit.h \
+ $(INC)tarrinit.h \
+ $(INC)sophyainit.h \
+ $(INC)xntuple.h \
+ $(INC)ntupintf.h
+$(OBJ)rznoisemodule.o: rznoisemodule.cc \
+ $(INC)machdefs.h \
+ $(INC)piacmd.h \
+ $(INC)dlftypes.h \
+ $(INC)pdlmgr.h \
+ $(INC)nobjmgr.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)mutyv.h \
+ $(INC)pistdimgapp.h \
+ $(INC)pisysdep.h \
+ $(INC)piapplx.h \
+ $(INC)piapplgen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picontainerx.h \
+ $(INC)picontainergen.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)picolist.h \
+ $(INC)pimenubarx.h \
+ $(INC)pimenubargen.h \
+ $(INC)pimenux.h \
+ $(INC)pimenugen.h \
+ $(INC)picons.h \
+ $(INC)pistdwdgx.h \
+ $(INC)pistdwdggen.h \
+ $(INC)pibwdgx.h \
+ $(INC)pibwdggen.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigraphps.h \
+ $(INC)piwindowx.h \
+ $(INC)piwindowgen.h \
+ $(INC)pioptmenux.h \
+ $(INC)pioptmenugen.h \
+ $(INC)pifilechox.h \
+ $(INC)pifilechogen.h \
+ $(INC)piimage.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)pidrawer.h \
+ $(INC)pipixmapx.h \
+ $(INC)pipixmapgen.h \
+ $(INC)picmapview.h \
+ $(INC)pi3ddrw.h \
+ $(INC)pigraph3d.h \
+ $(INC)pisiadw.h \
+ $(INC)pilistx.h \
+ $(INC)pilistgen.h \
+ $(INC)pistzwin.h \
+ $(INC)piperiodx.h \
+ $(INC)periodic.h \
+ $(INC)servnobjm.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)pitvmaad.h \
+ $(INC)fftpserver.h \
+ $(INC)fftservintf.h \
+ $(INC)bruit.h \
+ $(INC)piscdrawwdg.h \
+ $(INC)ctimer.h
+$(OBJ)sopiamodule.o: sopiamodule.cc \
+ $(INC)machdefs.h \
+ $(INC)piacmd.h \
+ $(INC)dlftypes.h \
+ $(INC)pdlmgr.h \
+ $(INC)nobjmgr.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)mutyv.h \
+ $(INC)pistdimgapp.h \
+ $(INC)pisysdep.h \
+ $(INC)piapplx.h \
+ $(INC)piapplgen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picontainerx.h \
+ $(INC)picontainergen.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)picolist.h \
+ $(INC)pimenubarx.h \
+ $(INC)pimenubargen.h \
+ $(INC)pimenux.h \
+ $(INC)pimenugen.h \
+ $(INC)picons.h \
+ $(INC)pistdwdgx.h \
+ $(INC)pistdwdggen.h \
+ $(INC)pibwdgx.h \
+ $(INC)pibwdggen.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigraphps.h \
+ $(INC)piwindowx.h \
+ $(INC)piwindowgen.h \
+ $(INC)pioptmenux.h \
+ $(INC)pioptmenugen.h \
+ $(INC)pifilechox.h \
+ $(INC)pifilechogen.h \
+ $(INC)piimage.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)pidrawer.h \
+ $(INC)pipixmapx.h \
+ $(INC)pipixmapgen.h \
+ $(INC)picmapview.h \
+ $(INC)pi3ddrw.h \
+ $(INC)pigraph3d.h \
+ $(INC)pisiadw.h \
+ $(INC)pilistx.h \
+ $(INC)pilistgen.h \
+ $(INC)pistzwin.h \
+ $(INC)piperiodx.h \
+ $(INC)periodic.h \
+ $(INC)servnobjm.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)pitvmaad.h \
+ $(INC)fftpserver.h \
+ $(INC)fftservintf.h \
+ $(INC)bruit.h \
+ $(INC)piscdrawwdg.h \
+ $(INC)ctimer.h \
+ $(INC)nomgadapter.h \
+ $(INC)ntupintf.h \
+ $(INC)generalfit.h \
+ $(INC)generaldata.h \
+ $(INC)poly.h \
+ $(INC)peida.h \
+ $(INC)utils.h \
+ $(INC)perrors.h \
+ $(INC)fmath.h
+$(OBJ)w2ps.o: w2ps.cc $(INC)machdefs.h \
+ $(INC)piacmd.h \
+ $(INC)dlftypes.h \
+ $(INC)pdlmgr.h \
+ $(INC)nobjmgr.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)mutyv.h \
+ $(INC)pistdimgapp.h \
+ $(INC)pisysdep.h \
+ $(INC)piapplx.h \
+ $(INC)piapplgen.h \
+ $(INC)pimsghandler.h \
+ $(INC)picontainerx.h \
+ $(INC)picontainergen.h \
+ $(INC)piwdgx.h \
+ $(INC)piwdggen.h \
+ $(INC)picolist.h \
+ $(INC)pimenubarx.h \
+ $(INC)pimenubargen.h \
+ $(INC)pimenux.h \
+ $(INC)pimenugen.h \
+ $(INC)picons.h \
+ $(INC)pistdwdgx.h \
+ $(INC)pistdwdggen.h \
+ $(INC)pibwdgx.h \
+ $(INC)pibwdggen.h \
+ $(INC)picmap.h \
+ $(INC)picmapx.h \
+ $(INC)picmapgen.h \
+ $(INC)pigraphx.h \
+ $(INC)pigraphgen.h \
+ $(INC)pifontx.h \
+ $(INC)pifontgen.h \
+ $(INC)pigraphuc.h \
+ $(INC)pievthandler.h \
+ $(INC)psfile.h \
+ $(INC)pigraphps.h \
+ $(INC)piwindowx.h \
+ $(INC)piwindowgen.h \
+ $(INC)pioptmenux.h \
+ $(INC)pioptmenugen.h \
+ $(INC)pifilechox.h \
+ $(INC)pifilechogen.h \
+ $(INC)piimage.h \
+ $(INC)parradapter.h \
+ $(INC)lut.h \
+ $(INC)pidrawer.h \
+ $(INC)pipixmapx.h \
+ $(INC)pipixmapgen.h \
+ $(INC)picmapview.h \
+ $(INC)pi3ddrw.h \
+ $(INC)pigraph3d.h \
+ $(INC)pisiadw.h \
+ $(INC)pilistx.h \
+ $(INC)pilistgen.h \
+ $(INC)pistzwin.h \
+ $(INC)piperiodx.h \
+ $(INC)periodic.h
+skymapmodule.o: skymapmodule.cc \
+  $(INC)machdefs.h \
+  $(INC)piacmd.h \
+  $(INC)dlftypes.h \
+  $(INC)pdlmgr.h \
+  $(INC)ctimer.h \
+  $(INC)nobjmgr.h \
+  $(INC)anydataobj.h \
+  $(INC)ppersist.h \
+  $(INC)pexceptions.h \
+  $(INC)gnumd5.h \
+  $(INC)dvlist.h \
+  $(INC)objfio.h \
+  $(INC)mutyv.h \
+  $(INC)pistdimgapp.h \
+  $(INC)pisysdep.h \
+  $(INC)piapplx.h \
+  $(INC)piapplgen.h \
+  $(INC)pimsghandler.h \
+  $(INC)picontainerx.h \
+  $(INC)picontainergen.h \
+  $(INC)piwdgx.h \
+  $(INC)piwdggen.h \
+  $(INC)picolist.h \
+  $(INC)pimenubarx.h \
+  $(INC)pimenubargen.h \
+  $(INC)pimenux.h \
+  $(INC)pimenugen.h \
+  $(INC)picons.h \
+  $(INC)pistdwdgx.h \
+  $(INC)pistdwdggen.h \
+  $(INC)pibwdgx.h \
+  $(INC)pibwdggen.h \
+  $(INC)picmap.h \
+  $(INC)picmapx.h \
+  $(INC)picmapgen.h \
+  $(INC)pigraphx.h \
+  $(INC)pigraphgen.h \
+  $(INC)pifontx.h \
+  $(INC)pifontgen.h \
+  $(INC)pigrcoord.h \
+  $(INC)pilineatt.h \
+  $(INC)pigraphuc.h \
+  $(INC)pievthandler.h \
+  $(INC)psfile.h \
+  $(INC)pigraphps.h \
+  $(INC)piwindowx.h \
+  $(INC)piwindowgen.h \
+  $(INC)pioptmenux.h \
+  $(INC)pioptmenugen.h \
+  $(INC)pifilechox.h \
+  $(INC)pifilechogen.h \
+  $(INC)piperiodx.h \
+  $(INC)periodic.h \
+  $(INC)piimage.h \
+  $(INC)parradapter.h \
+  $(INC)lut.h \
+  $(INC)pieldrw.h \
+  $(INC)pidrawer.h \
+  $(INC)pigratt.h \
+  $(INC)piaxes.h \
+  $(INC)pipixmapx.h \
+  $(INC)pipixmapgen.h \
+  $(INC)picmapview.h \
+  $(INC)pi3dwdg.h \
+  $(INC)pi3ddrw.h \
+  $(INC)pigraph3d.h \
+  $(INC)pisiadw.h \
+  $(INC)pilistx.h \
+  $(INC)pilistgen.h \
+  $(INC)pistzwin.h \
+  $(INC)pitherm.h \
+  $(INC)resusage.h \
+  $(INC)servnobjm.h \
+  $(INC)tvector.h \
+  $(INC)tmatrix.h \
+  $(INC)tarray.h \
+  $(INC)basarr.h \
+  $(INC)ndatablock.h \
+  $(INC)utilarr.h \
+  $(INC)nomgadapter.h \
+  $(INC)ntupintf.h \
+  $(INC)generalfit.h \
+  $(INC)generaldata.h \
+  $(INC)poly.h \
+  $(INC)peida.h \
+  $(INC)utils.h \
+  $(INC)perrors.h \
+  $(INC)fmath.h \
+  $(INC)skymap.h \
+  $(INC)spherethetaphi.h \
+  $(INC)sphericalmap.h \
+  $(INC)smathconst.h \
+  $(INC)pixelmap.h \
+  $(INC)spherepos.h \
+  $(INC)unitvector.h \
+  $(INC)vector3d.h \
+  $(INC)longlat.h \
+  $(INC)utilgeom.h \
+  $(INC)spherehealpix.h \
+  $(INC)HEALPixUtils.h \
+  $(INC)localmap.h \
+  $(INC)fiospherethetaphi.h \
+  $(INC)fiospherehealpix.h \
+  $(INC)fiolocalmap.h \
+  $(INC)sphericaltransformserver.h \
+  $(INC)fftservintf.h \
+  $(INC)fftpserver.h \
+  $(INC)alm.h \
+  $(INC)nbrandom.h \
+  $(INC)srandgen.h \
+  $(INC)nbmath.h \
+  $(INC)triangmtx.h \
+  $(INC)lambdaBuilder.h
Index: /tags/V_Dec2002/SophyaPI/ProgPI/fitsbtadapter.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/ProgPI/fitsbtadapter.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/ProgPI/fitsbtadapter.cc	(revision 2309)
@@ -0,0 +1,154 @@
+/* Interface Fits BINARY/ASCII Table     cmv 21/05/2001 */
+#include "machdefs.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <typeinfo>
+#include <iostream.h>
+#include <string.h>
+#include <string>
+
+#include "nobjmgr.h"
+#include "servnobjm.h"
+#include "nomgadapter.h"
+#include "pistdimgapp.h"
+#include "fbtntintf.h"
+
+////////////////////////////////////////////////////////////
+class NOMAdapter_FitsBT : public NObjMgrAdapter {
+public:
+  NOMAdapter_FitsBT(FitsBTNtuIntf* o = NULL);
+  virtual ~NOMAdapter_FitsBT();
+
+  virtual NObjMgrAdapter* Clone(AnyDataObj* o);
+  virtual string GetDataObjType();
+  virtual AnyDataObj* CloneDataObj(bool share=false);
+  virtual void SavePPF(POutPersist& s, string const & nom);
+  virtual void Print(ostream& os);
+  virtual NTupleInterface* GetNTupleInterface(bool& adel);
+
+protected:
+  FitsBTNtuIntf* mFBT;
+};
+
+////////////////////////////////////////////////////////////
+NOMAdapter_FitsBT::NOMAdapter_FitsBT(FitsBTNtuIntf* o)
+ : NObjMgrAdapter(o)
+{
+mFBT = o;
+}
+
+NOMAdapter_FitsBT::~NOMAdapter_FitsBT()
+{
+}
+
+NObjMgrAdapter* NOMAdapter_FitsBT::Clone(AnyDataObj* o)
+{
+FitsBTNtuIntf* g = dynamic_cast<FitsBTNtuIntf *>(o);
+if(g) return ( new NOMAdapter_FitsBT(g) );
+return ( new NObjMgrAdapter(o) );
+}
+
+string NOMAdapter_FitsBT::GetDataObjType()
+{
+return( "FitsBTNtuIntf " );
+}
+
+AnyDataObj* NOMAdapter_FitsBT::CloneDataObj(bool /*share*/)
+{
+return( new FitsBTNtuIntf(*mFBT) );
+}
+
+void NOMAdapter_FitsBT::SavePPF(POutPersist& pos, string const & nom)
+{
+cout<<"NOMAdapter_FitsBT::SavePPF: not implemented"<<endl;
+}
+
+void NOMAdapter_FitsBT::Print(ostream& os)
+{
+mFBT->Print(os,99);
+}
+
+NTupleInterface* NOMAdapter_FitsBT::GetNTupleInterface(bool& adel)
+{
+adel = false;
+return(mFBT);
+}
+
+////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+extern "C" {
+void fitsbtadapter_init();
+void fitsbtadapter_end();
+}
+
+class fitsbtadapterExecutor : public CmdExecutor {
+public:
+  fitsbtadapterExecutor();
+  virtual ~fitsbtadapterExecutor();
+  virtual int Execute(string& keyw, vector<string>& args, string& toks);
+};
+
+///////////////////////////////////////////////////////////
+fitsbtadapterExecutor::fitsbtadapterExecutor()
+{
+NamedObjMgr omg;
+PIACmd * mpiac = omg.GetImgApp()->CmdInterpreter();
+
+// On enregistre l'adaptateur
+Services2NObjMgr* serv = omg.GetServiceObj();
+serv->RegisterClass(new FitsBTNtuIntf, new NOMAdapter_FitsBT);
+
+// On enregistre la commande 
+string hgrp = "FileIO";
+string kw = "fitsadapt";
+string usage = "fitsadapt: NTuple adaptor for Binary and ASCII Fits table\n" ;
+usage += "Usage: fitsadapt fitsfile [nomobj hdu buflen[,bufsens,lp]]";
+usage += "\n fitsfile : Fits file name";
+usage += "\n nomobj : Object name (needed if file name misleading as C++ variable)";
+usage += "\n hdu : Fits HDU (if <=0 take first binary/ascii table)";
+usage += "\n buflen[,bufsens,lp] : buffer length (sens) for fits reading (default is 100,1,0)";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+}
+
+fitsbtadapterExecutor::~fitsbtadapterExecutor()
+{
+}
+
+int fitsbtadapterExecutor::Execute(string& kw, vector<string>& tokens, string&)
+{
+NamedObjMgr omg;
+if(kw == "fitsadapt") {
+  if(tokens.size()<1)
+    {cout<<"Usage: fitsadapt fitsfile [nomobj hdu buflen[,bufsens]]"<<endl;
+     return(0);}
+    int ihdu=0;
+    int_4 buflen=100, bufsens=1, lp=0;
+    string fname = tokens[0];
+    string nom_obj ="";
+    if(tokens.size()>1) nom_obj = tokens[1];
+    if(tokens.size()>2) sscanf(tokens[2].c_str(),"%d",&ihdu);
+    if(tokens.size()>3) sscanf(tokens[3].c_str(),"%d,%d,%d",&buflen,&bufsens,&lp);
+    FitsBTNtuIntf* fbt = new FitsBTNtuIntf(fname,ihdu,buflen,bufsens,lp);
+
+    if(nom_obj=="" || nom_obj=="!") nom_obj = omg.GetServiceObj()->FileName2Name(fname);
+    omg.AddObj(fbt,nom_obj);
+ }
+ return(0);
+}
+
+///////////////////////////////////////////////////////////
+static fitsbtadapterExecutor * piafbtex = NULL;
+
+void fitsbtadapter_init()
+{
+if(piafbtex) delete piafbtex;
+piafbtex = new fitsbtadapterExecutor;
+}
+
+void fitsbtadapter_end()
+{
+if(piafbtex) delete piafbtex;
+piafbtex = NULL;
+}
Index: /tags/V_Dec2002/SophyaPI/ProgPI/piapp.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/ProgPI/piapp.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/ProgPI/piapp.cc	(revision 2309)
@@ -0,0 +1,297 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <iostream.h>
+
+#include "pistdimgapp.h"
+#include "piacmd.h"
+#include "piversion.h"
+#include "piaversion.h"
+
+#include "timing.h"
+#include "skyinit.h"
+
+#include "xntuple.h" // Pour faire le SetTmpDir()
+
+
+// ---- Pour charger automatiquement le module sopiamodule 
+extern "C" {
+void sopiamodule_init();
+void sopiamodule_end();
+void skymapmodule_init();
+void skymapmodule_end();
+void fitsbtadapter_init();
+void fitsbtadapter_end();
+void W2PSModule_init();
+void W2PSModule_end();
+}
+
+/*!
+  \defgroup ProgPI ProgPI module
+  This module contains programs for interactive data analysis and
+  visualisation, based on SOPHYA class libray and PI (GUI framework)
+  and PIext (Interactive data analysis framework).
+*/
+
+/*!
+  \ingroup ProgPI
+  \file piapp.cc
+  \brief \b (s)piapp: Starts the piapp interactive data analysis program.
+
+  The current version of the program has a single execution thread. This
+  creates few limitations (GUI can not be used when computing is being
+  done, ...). Also the command file executed during start-up (-exec)
+  cannot contain display (graphic) commands.
+
+  \verbatim
+  csh> spiapp -h
+  SOPHYA Version  1.3 Revision 70 (V_Jun2002) -- Jul 16 2002 15:45:53 cxx
+
+   piapp: Interactive data analysis and visualisation program
+   Usage: piapp [-nored] [-nosig] [-nosigfpe] [-nosigsegv] [-hidezswin]
+                [-tmpdir TmpDirectory] [-help2tex] [-exec file [args]]
+    -nored : NoRedirect StdOut/StdErr
+    -nosig : Don't catch SigFPE, SigSEGV
+    -nosigfpe -nosigsegv: Don t catch SigFPE / SigSEGV
+    -hidezswin : Hide Zoom/Stat/ColMap window
+    -tmpdir TmpDirectory: defines TMDIR for temporary files
+    -help2tex: Create a LaTeX help file (piahelp.tex)
+    -exec file [args] : Execute command file
+  
+  \endverbatim
+ 
+*/
+
+void Usage(bool fgerr)
+{
+  if (fgerr) { 
+    cout << " piapp : Argument Error ! piapp -h for Usage" << endl; 
+    exit(1);
+  }
+  else {
+    cout << "\n piapp: Interactive data analysis and visualisation program \n"
+	 << " Usage: piapp [-nored] [-nosig] [-nosigfpe] [-nosigsegv] [-hidezswin] \n"
+	 << "              [-tmpdir TmpDirectory] [-help2tex] [-exec file [args]] \n"
+	 << "  -nored : NoRedirect StdOut/StdErr \n"
+	 << "  -nosig : Don't catch SigFPE, SigSEGV \n"
+         << "  -nosigfpe -nosigsegv: Don t catch SigFPE / SigSEGV \n"
+	 << "  -hidezswin : Hide Zoom/Stat/ColMap window \n"
+	 << "  -tmpdir TmpDirectory: defines TMDIR for temporary files \n"
+	 << "  -help2tex: Create a LaTeX help file (piahelp.tex)\n"
+	 << "  -exec file [args] : Execute command file \n"
+	 << endl;
+    exit(0);
+  }
+}
+
+/*  ================================ MAIN() =================================  */
+
+int main(int narg, char *arg[])
+{
+int ofa;
+bool fgfpe, fgsegv, fgred, fghidezsw, fgexec;
+
+SkyTInitiator skyinit;
+   
+InitTim();
+
+
+if ( (narg > 1) && (strcmp(arg[1],"-h") == 0) ) Usage(false);
+
+ofa = 1;
+fgred = fgfpe = fgsegv = true;
+fghidezsw = false;
+fgexec = false;
+bool fgtmp = false;
+string tmpdir;
+string exfc;
+// Pour fabriquer le help
+bool fgtexh = false;
+int ka;
+for(ka=1; ka<narg; ka++) {
+  if (strcmp(arg[ka],"-nored") == 0)   fgred=false; 
+  else if (strcmp(arg[ka],"-nosig") == 0)   fgfpe=fgsegv=false; 
+  else if (strcmp(arg[ka],"-nosigfpe") == 0)   fgfpe=false; 
+  else if (strcmp(arg[ka],"-nosigsegv") == 0)   fgsegv=false; 
+  else if (strcmp(arg[ka],"-hidezswin") == 0)   fghidezsw=true; 
+  else if (strcmp(arg[ka],"-help2tex") == 0) { fgtexh=true; fgred=false; }
+  else if (strcmp(arg[ka],"-tmpdir") == 0) {
+    if (ka == narg-1) Usage(true);
+    fgtmp = true;  ka++;
+    tmpdir = arg[ka];    
+  }
+  else if (strcmp(arg[ka],"-exec") == 0) {
+    if (ka < narg-1) {
+      fgexec = true;
+      exfc = "exec";
+      for(int kaa=ka+1; kaa<narg; kaa++)  { exfc += ' ';  exfc +=  arg[kaa]; }
+      }
+    break;
+    }
+  }
+
+ 
+if (fgexec) printf(">>>>> Starting piapp , Executing %s \n", exfc.c_str()); 
+else printf(">>>>> Starting piapp <<<<< \n");
+printf("Version: piapp=%g  PI=%g  SOPHYA=%g \n", (double)PIAPP_VERSIONNUMBER, 
+              (double)PI_VERSIONNUMBER, (double)skyinit.Version());
+
+char* vcmds=NULL;
+string vcmd;
+if (fgtmp) {
+  if (tmpdir[tmpdir.length()-1] != '/') tmpdir += '/';  // Necessaire pour SetSwapPath
+  vcmd = "TMPDIR=" + tmpdir;
+  vcmds = new char[vcmd.length()+1];
+  strcpy(vcmds, vcmd.c_str());
+  putenv(vcmds);
+}
+
+char* tmpde = getenv("TMPDIR");
+char  tmpdname[32];
+if (tmpde == NULL) tmpde = "./";
+if (tmpde[strlen(tmpde)-1] != '/')
+  strcpy(tmpdname, "/PIATmp_XXXXXX"); 
+else 
+  strcpy(tmpdname, "PIATmp_XXXXXX"); 
+mktemp(tmpdname);
+tmpdir = tmpde;
+tmpdir += tmpdname;
+tmpdir += '/';
+vcmd = "mkdir ";
+vcmd += tmpde;
+vcmd += tmpdname;
+cout << " --piapp: Creating Tmp Directory: " << tmpdir << endl;
+int rcc = system(vcmd.c_str());
+if (rcc != 0) {
+  cout << " --piapp: Error creating TmpDir " << vcmd << " ---> exit !" << endl;
+  return(9);
+}
+
+// On cree un repertoire temporaire 
+// cout << " DBG-TMPDIR= " << getenv("TMPDIR") << endl;
+
+PIStdImgApp * app = new PIStdImgApp(narg, arg);
+// cout << " DBG-2 " <<  app->ObjMgr()->GetTmpDir() << endl;
+cout << "  NamedObjMgr::SetTmpDir()+XNTuple::SetSwapPath() " << tmpdir << endl;
+app->ObjMgr()->SetTmpDir(tmpdir);
+XNTuple::SetSwapPath(const_cast<char *>(tmpdir.c_str()));
+
+
+
+// Gestion de redirection stdout/err et Signaux
+if (fgred) app->RedirectStdOutErr(true);
+else app->RedirectStdOutErr(false);
+app->CatchSignals(fgfpe, fgsegv);
+
+// if Hide Zoom/Stat Win
+if (fghidezsw)  app->StatZoomWindowSetVisible(false);
+
+// S'il y a un fichier de commande a executer
+// if (fgexec) app->CmdInterpreter()->Interpret(exfc);
+if (fgexec) app->SubmitCommand(exfc);
+
+// On charge le module sopiamodule
+sopiamodule_init();
+// On charge le module skymapmodule
+skymapmodule_init();
+// On charge le module de lecture ligne a ligne des Fits BINARY/ASCII tables
+fitsbtadapter_init();
+// On charge le module des commandes de creation de fichier postscript
+W2PSModule_init();
+
+// S'il y a besoin de faire le fichier Help
+if (fgtexh) { 
+  string thf = "piahelp.tex";
+  app->CmdInterpreter()->HelptoLaTeX(thf);
+  printf("piapp : Help file piahelp.tex created --> exit(0) \n"); 
+  delete app;
+  exit(0);
+}
+
+int rc = 0;
+bool cont = true;
+char rep; // ans[32]
+int excnt = 0;
+while(cont) {
+  rc = 0;   cont = false;
+  app->SetReady();
+  if (fgred) app->RedirectStdOutErr(true);
+  try {
+    app->Run();
+  }
+  catch(PThrowable exc) {  // Catching SOPHYA exceptions 
+    app->Stop();
+    app->RedirectStdOutErr(false);  
+    //BUG ? fait planter OSF-cxx     fflush(stdout); 
+    cout << endl;      cerr << endl;
+    cout << "\n piapp/main() PThrowable catched ! " << exc.Msg() << endl;
+    cout << ++excnt << "- continue <CR>, Close Windows, "
+         << " continue C<CR> Stop program S<CR> ? " << endl; 
+    rep = getchar();  // was: gets(ans);
+    rep = toupper(rep);  
+    if (rep == 'S')  { 
+      cout << " !!!! Stopping piapp !!!! " << endl;
+      rc = 78;
+      cont = false;
+    }
+    else { 
+      if (rep == 'C') {
+	cout << "piapp/main() Closing all windows ... " << endl;
+	app->CloseAllWindows();
+      }
+      cout << " *** piapp - Continuing event loop *** " << endl;
+      cont = true;
+    }
+  }
+  catch(...) { // Catching all other exceptions 
+    app->Stop();
+    app->RedirectStdOutErr(false);  
+    cout << endl;      cerr << endl;
+    cout << "\n piapp/main() exception catched ! " << endl;
+    cout << ++excnt << "- continue <CR>, Close Windows, "
+         << " continue C<CR> Stop program S<CR> ? " << endl; 
+    rep = getchar(); // gets(ans);
+    rep = toupper(rep);  
+    if (rep == 'S')  { 
+      cout << " !!!! Stopping piapp !!!! " << endl;
+      rc = 78;
+      cont = false;
+    }
+    else { 
+      if (rep == 'C') {
+	cout << "piapp/main() Closing all windows ... " << endl;
+	app->CloseAllWindows();
+      }
+      cout << " *** piapp - Continuing event loop *** " << endl;
+      cont = true;
+    }
+  }
+}
+cout << "\n ------------------------------------------------ \n"
+     << " piapp: Cleaning up ... " << endl;
+
+app->RedirectStdOutErr(false);  
+// On de-charge le module sopiamodule et fitsbtadapter
+sopiamodule_end();
+skymapmodule_end();
+fitsbtadapter_end();
+W2PSModule_end();
+
+delete app;
+if (fgtmp) delete[] vcmds;
+
+vcmd = "rm -rf ";
+vcmd += tmpdir;
+cout << " --piapp: Removing Tmp Directory: " << tmpdir << endl;
+rcc = system(vcmd.c_str());
+if (rcc != 0) {
+  cout << " --piapp: Error deleting TmpDir " << vcmd << endl;
+  return(9);
+}
+
+cout << "------------------------------------------------ \n"
+     << "-------- piapp : Exiting .... Rc= " << rc << " -----------\n"
+     << "------------------------------------------------ " << endl; 
+return(rc);
+}
+
Index: /tags/V_Dec2002/SophyaPI/ProgPI/programs
===================================================================
--- /tags/V_Dec2002/SophyaPI/ProgPI/programs	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/ProgPI/programs	(revision 2309)
@@ -0,0 +1,1 @@
+spiapp piapp.o sopiamodule.o fitsbtadapter.o w2ps.o
Index: /tags/V_Dec2002/SophyaPI/ProgPI/skymapmodule.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/ProgPI/skymapmodule.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/ProgPI/skymapmodule.cc	(revision 2309)
@@ -0,0 +1,1457 @@
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream.h>
+#include <math.h>
+
+#include <typeinfo>
+#include <vector>
+#include <string>
+
+#include "piacmd.h"
+#include "nobjmgr.h"
+#include "pistdimgapp.h"
+#include "servnobjm.h"
+#include "pidrawer.h"
+#include "nomgadapter.h"
+
+#include "tvector.h"
+#include "ntuple.h"
+#include "slinparbuff.h"
+#include "localmap.h"
+#include "spherehealpix.h"
+#include "spherethetaphi.h"
+#include "sphericaltransformserver.h"
+
+extern "C" {
+  void skymapmodule_init();
+  void skymapmodule_end();
+}
+
+class skymapmoduleExecutor : public CmdExecutor {
+public:
+  enum {UnKnown=(uint_2) 0,
+        TypeR8=(uint_2) 16, TypeR4=(uint_2) 32,
+        Spherical=(uint_2) 1, HealPix=(uint_2) 2, ThetaPhi=(uint_2) 4,
+        Spherical8=(uint_2) Spherical|TypeR8,
+        Spherical4=(uint_2) Spherical|TypeR4,
+        HealPix8  =(uint_2) Spherical|HealPix|TypeR8,
+        HealPix4  =(uint_2) Spherical|HealPix|TypeR4,
+        ThetaPhi8 =(uint_2) Spherical|ThetaPhi|TypeR8,
+        ThetaPhi4 =(uint_2) Spherical|ThetaPhi|TypeR4};
+
+                skymapmoduleExecutor();
+  virtual       ~skymapmoduleExecutor();
+  virtual int   Execute(string& keyw, vector<string>& args, string& toks);
+
+  void TypeMap(vector<string>& tokens);
+  void Map2Double(vector<string>& tokens);
+  void Map2Float(vector<string>& tokens);
+  void Map2Map(vector<string>& tokens);
+  void MapMult(vector<string>& tokens);
+  void MapCover(vector<string>& tokens);
+  void Map2Cl(vector<string>& tokens);
+  void Cl2Map(vector<string>& tokens);
+  void Map2Alm(vector<string>& tokens);
+  void Alm2Map(vector<string>& tokens);
+  void CrMapMask(vector<string>& tokens);
+  void CrMaskFrMap(vector<string>& tokens);
+  void MaskMap(vector<string>& tokens);
+  void MapProj(vector<string>& tokens);
+  void Map2Local(vector<string>& tokens);
+  void MapOper(vector<string>& tokens);
+  void MapStat(vector<string>& tokens);
+  void Alm2Cl(vector<string>& tokens);
+  void Cl2llCl(vector<string>& tokens);
+  void ClMean(vector<string>& tokens);
+  void ClMult(vector<string>& tokens);
+  void ClOper(vector<string>& tokens);
+  void ClRebin(vector<string>& tokens);
+protected:
+  void SetTypeMap(vector<string>& tokens);
+  bool IsNSideGood(int_4 nside);
+  void GetNSideGood(int_4 &nside);
+  uint_2 typemap(AnyDataObj* obj);
+
+  uint_2 DefTypMap;
+};
+
+/* --Methode-- */
+skymapmoduleExecutor::skymapmoduleExecutor()
+{
+PIACmd * mpiac;
+NamedObjMgr omg;
+mpiac = omg.GetImgApp()->CmdInterpreter();
+
+string hgrp = "SkyMapCmd";
+string kw,usage;
+
+kw = "settypemap";
+usage = "Set le type de map(double) par default";
+usage += "\n Usage: settypemap type";
+usage += "\n   type= H for Healpix (default)";
+usage += "\n         T for ThetaPhi";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "typemap";
+usage = "Imprime le type de map";
+usage += "\n Usage: typemap map";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "map2double";
+usage = "Convert a float map to a double map";
+usage += "\n Usage: map2double map(float)";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "map2float";
+usage = "Convert a double map to a float map";
+usage += "\n Usage: map2float map(double)";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "map2map";
+usage = "Convert a map(double) into an other map type";
+usage += "\n Usage: map2map map(double) type [nside]";
+usage += "\n   type= H for Healpix";
+usage += "\n         T for ThetaPhi";
+usage += "\n   if nside <=1 use nside from map";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "mapmult";
+usage = "Multiply a map(double) by a constant";
+usage += "\n Usage: mapmult map(double) cste";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "mapcover";
+usage = "Print the covering of a map(double)";
+usage += "\n Usage: mapcover map(double) v1,v2 [varname]";
+usage += "\n    v1,v2: good pixels have v1<=val<=v2 (def=0.99,1.01)";
+usage += "\n          (use default (0.99,1.01): \"!\")";
+usage += "\n    $varname: percent of sky covering";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "map2cl";
+usage = "SkyMap map(double) to Cl";
+usage += "\n Usage: map2cl map(double) clvec [lmax] [niter]";
+usage += "\n   lmax: if <=0 or \"!\" use default (3*nside-1)";
+usage += "\n   niter: number of iterations (<=0 or def=3)";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "cl2map";
+usage = "Generate SkyMap map(double) from Cl";
+usage += "\n Usage: cl2map clvec map(double) nside [fwhm]";
+usage += "\n    (see command settypemap)";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "map2alm";
+usage = "SkyMap map(double) to Alm";
+usage += "\n Usage: map2alm map(double) almmat [lmax] [niter]";
+usage += "\n   lmax: if <=0 or \"!\" use default (3*nside-1)";
+usage += "\n   niter: number of iterations (<=0 or def=3)";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "alm2map";
+usage = "Generate SkyMap map(double) from Alm";
+usage += "\n Usage: alm2map almmat map(double) nside";
+usage += "\n    (see command settypemap)";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "crmapmask";
+usage = "Create a map mask(double) (nside) between latitudes lat1,lat2 longitudes lon1,lon2";
+usage += "\n Usage: crmapmask mapmsk(double) nside lat1,lat2 lon1,lon2 [valmsk,valnomsk]";
+usage += "\n    mask pixels between [lat1,lat2] ([-90,90] in degrees)";
+usage += "\n                and    [lon1,lon2] ([0,360[ in degrees)";
+usage += "\n                (for no mask \"!\")";
+usage += "\n    valmsk=value to be written into masked pixels (def=0)";
+usage += "\n    valnomsk=value to be written into unmasked pixels (def=1)";
+usage += "\n          (see command settypemap)";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "crmaskfrmap";
+usage = "Create a map mask(double) (nside) relative to an other map(double) pixels values";
+usage += "\n Usage: crmaskfrmap mapmsk(double) nside map(double) v1,v2 [valmsk,valnomsk]";
+usage += "\n    mask if v1<mapmsk(i)<v2";
+usage += "\n    valmsk=value to be written into masked pixels (def=0)";
+usage += "\n    valnomsk=value to be written into unmasked pixels (def=1)";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "maskmap";
+usage = "Mask a map(double) with a mask map(double)";
+usage += "\n Usage: maskmap map msk";
+usage += "\n    operation is map(i) *= msk(theta,phi)";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "maproj";
+usage = "Project a map(double) into an other one";
+usage += "\n Usage: maproj map(double) mapproj(double) [nside]";
+usage += "\n   Create mapproj(nside) and project map into mapproj";
+usage += "\n   (use \"maproj map mapproj\" to make a copy)";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "map2local";
+usage = "Project a map(double) into a local map(double)";
+usage += "\n Usage: map2local map(double) localmap(double) nx,ny angleX,angleY phi0,theta0 [x0,y0] [angle]";
+usage += "\n   nx,ny: number of pixels in x(col),y(row) direction";
+usage += "\n          X-axis==phi, Y-axis==theta";
+usage += "\n   angleX,angleY: total angle aperture in x,y direction (degrees)";
+usage += "\n   phi0,theta0: define origin in phi,theta (degrees)";
+usage += "\n   x0,y0: map phi0,theta0 to pixel x0,y0 (\"!\" or def=middle of the localmap)";
+usage += "\n   angle: angle (degrees) of rotation between x-axis of  map-coordinate system";
+usage += "\n           and the tangent to parallel on the sphere (def: 0.)";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "mapop";
+usage = "operation on a map(double)";
+usage += "\n Usage: mapop map(double) op1 map1(double) [op2 map2(double)] [op2 map3(double)] [...]";
+usage += "\n   Do \"map op1= map1\", \"map op2=map2\", ...";
+usage += "\n      where op = +,-,*,/";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "mapstat";
+usage = "Statistics from a map(double)";
+usage += "\n Usage: mapstat map(double) [msk(double)] [meanvarname] [sigmavarname]";
+usage += "\n   msk = mask sphere used as weight";
+usage += "\n     if msk(i)<=0 do not use that pixel";
+usage += "\n     if msk(i)>0  use that pixel with weight msk(i)";
+usage += "\n   msk = \"!\" means no mask sphere";
+usage += "\n   meanvarname  = variable name to store mean";
+usage += "\n   sigmavarname = variable name to store sigma";
+usage += "\n   (\"!\" means do not store)";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "alm2cl";
+usage = "Project alm to cl";
+usage += "\n Usage: alm2cl alm cl";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "cl2llcl";
+usage = "Project cl to l*(l+1)*cl";
+usage += "\n Usage: cl2llcl cl llcl";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "clmean";
+usage = "Compute mean for a cl vector";
+usage += "\n Usage: clmean cl imin,imax [meanvarname]";
+usage += "\n   imin,imax  = compute between these indices";
+usage += "\n   meanvarname  = variable name to store mean";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "clmult";
+usage = "Multiply a cl by a constant";
+usage += "\n Usage: clmult cl val";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "clop";
+usage = "operation on a cl";
+usage += "\n Usage: clop cl(double) op1 cl1(double) [op2 cl2(double)] [op2 cl3(double)] [...]";
+usage += "\n   Do \"cl op1= cl1\", \"cl op2=cl2\", ...";
+usage += "\n      where op = +,-,*,/";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+kw = "clrebin";
+usage = "rebin a cl into an ntuple";
+usage += "\n Usage: clrebin cl ntuple nbin,bin0";
+usage += "\n   nbin: rebin by nbin";
+usage += "\n   bin0: begin rebinning at bin bin0 (def=0)";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+DefTypMap = HealPix;
+}
+
+/* --Methode-- */
+skymapmoduleExecutor::~skymapmoduleExecutor()
+{
+}
+
+/* --Methode-- */
+int skymapmoduleExecutor::Execute(string& kw, vector<string>& tokens, string& toks)
+{
+
+if(kw == "settypemap") {
+  SetTypeMap(tokens);
+} else if(kw == "typemap") {
+  if(tokens.size()<1) {
+    cout<<"Usage: typemap map"<<endl;
+    return(0);
+  }
+  TypeMap(tokens);
+} else if(kw == "map2double") {
+  if(tokens.size()<1) {
+    cout<<"Usage: map2double map"<<endl;
+    return(0);
+  }
+  Map2Double(tokens);
+} else if(kw == "map2float") {
+  if(tokens.size()<1) {
+    cout<<"Usage: map2float map"<<endl;
+    return(0);
+  }
+  Map2Float(tokens);
+} else if(kw == "map2map") {
+  if(tokens.size()<2) {
+    cout<<"Usage: map2map map type [nside]"<<endl;
+    return(0);
+  }
+  Map2Map(tokens);
+} else if(kw == "mapmult") {
+  if(tokens.size()<2) {
+    cout<<"Usage: mapmult map cste"<<endl;
+    return(0);
+  }
+  MapMult(tokens);
+} else if(kw == "mapcover") {
+  if(tokens.size()<1) {
+    cout<<"Usage: mapcover map v1,v2 [varname]"<<endl;
+    return(0);
+  }
+  MapCover(tokens);
+} else if(kw == "map2cl") {
+  if(tokens.size()<2) {
+    cout<<"Usage: map2cl map clvec [lmax] [niter]"<<endl;
+    return(0);
+  }
+  Map2Cl(tokens);
+} else if(kw == "cl2map") {
+  if(tokens.size()<2) {
+    cout<<"Usage: cl2map clvec map nside [fwhm]"<<endl;
+    return(0);
+  }
+  Cl2Map(tokens);
+} else if(kw == "map2alm") {
+  if(tokens.size()<2) {
+    cout<<"Usage: map2alm map(double) almmat [lmax] [niter]"<<endl;
+    return(0);
+  }
+  Map2Alm(tokens);
+} else if(kw == "alm2map") {
+  if(tokens.size()<3) {
+    cout<<"Usage: alm2map almmat map nside"<<endl;
+    return(0);
+  }
+  Alm2Map(tokens);
+} else if(kw == "crmapmask") {
+  if(tokens.size()<2) {
+    cout<<"Usage: crmapmask mapmsk nside lat1,lat2 lon1,lon2 [valmsk,valnomsk]"<<endl;
+    return(0);
+  }
+  CrMapMask(tokens);
+} else if(kw == "crmaskfrmap") {
+  if(tokens.size()<3) {
+    cout<<"Usage: crmaskfrmap mapmsk nside map(double) v1,v2 [valmsk,valnomsk]"<<endl;
+    return(0);
+  }
+  CrMaskFrMap(tokens);
+} else if(kw == "maskmap") {
+  if(tokens.size()<2) {
+    cout<<"Usage: maskmap map msk"<<endl;
+    return(0);
+  }
+  MaskMap(tokens);
+} else if(kw == "maproj") {
+  if(tokens.size()<2) {
+    cout<<"Usage: maproj map mapproj [nside]"<<endl;
+    return(0);
+  }
+  MapProj(tokens);
+} else if(kw == "map2local") {
+  if(tokens.size()<5) {
+    cout<<"Usage: map2local map localmap nx,ny angleX,angleY phi0,theta0 [x0,y0] [angle]"<<endl;
+    return(0);
+  }
+  Map2Local(tokens);
+} else if(kw == "mapop") {
+  if(tokens.size()<3) {
+    cout<<"Usage: mapop map op map1 [op map2] [op map3] [...]"<<endl;
+    return(0);
+  }
+  MapOper(tokens);
+} else if(kw == "mapstat") {
+  if(tokens.size()<1) {
+    cout<<"Usage: Usage: mapstat map [msk] [meanvarname] [sigmavarname]"<<endl;
+    return(0);
+  }
+  MapStat(tokens);
+} else if(kw == "alm2cl") {
+  if(tokens.size()<2) {
+    cout<<"Usage: alm2cl alm cl"<<endl;
+    return(0);
+  }
+  Alm2Cl(tokens);
+} else if(kw == "cl2llcl") {
+  if(tokens.size()<2) {
+    cout<<"Usage: cl2llcl cl llcl"<<endl;
+    return(0);
+  }
+  Cl2llCl(tokens);
+} else if(kw == "clmean") {
+  if(tokens.size()<1) {
+    cout<<"Usage: clmean cl imin,imax [meanvarname]"<<endl;
+    return(0);
+  }
+  ClMean(tokens);
+} else if(kw == "clmult") {
+  if(tokens.size()<1) {
+    cout<<"Usage: clmult cl val"<<endl;
+    return(0);
+  }
+  ClMult(tokens);
+} else if(kw == "clop") {
+  if(tokens.size()<3) {
+    cout<<"Usage: clop cl op1 cl1 [op2 cl2] [op2 cl3] [...]"<<endl;
+    return(0);
+  }
+  ClOper(tokens);
+} else if(kw == "clrebin") {
+  if(tokens.size()<2) {
+    cout<<"Usage: clrebin cl ntuple nbin,bin0"<<endl;
+    return(0);
+  }
+  ClRebin(tokens);
+}
+
+return(0);
+}
+
+/* --Methode-- */
+void skymapmoduleExecutor::TypeMap(vector<string>& tokens)
+{
+ NamedObjMgr omg;
+ AnyDataObj* obj=omg.GetObj(tokens[0]);
+ uint_2 t = typemap(obj);
+ if(t==UnKnown)  {cout<<"TypeMap: UnKnown"<<endl; return;}
+
+ int nside = 0;
+ if(t&TypeR8) {
+   SphericalMap<r_8>* map = dynamic_cast<SphericalMap<r_8>*>(obj);
+   nside = map->SizeIndex();
+ } else if(t&TypeR4) {
+   SphericalMap<r_4>* map = dynamic_cast<SphericalMap<r_4>*>(obj);
+   nside = map->SizeIndex();
+ }
+
+ string dum = "";
+ if(t==HealPix8)        dum = "SphereHEALPix<r_8>";
+ else if(t==HealPix4)   dum = "SphereHEALPix<r_4>";
+ else if(t==ThetaPhi8)  dum = "SphereThetaPhi<r_8>";
+ else if(t==ThetaPhi4)  dum = "SphereThetaPhi<r_4>";
+ else if(t==Spherical8) dum = "SphericalMap<r_8>";
+ else if(t==Spherical4) dum = "SphericalMap<r_4>";
+
+ cout<<"TypeMap: "<<dum<<" nside="<<nside<<endl;
+}
+
+/* --Methode-- */
+void skymapmoduleExecutor::Map2Double(vector<string>& tokens)
+{
+ NamedObjMgr omg;
+ AnyDataObj* obj=omg.GetObj(tokens[0]);
+ if(obj==NULL) {
+   cout<<"Error: Pas d'objet de nom "<<tokens[0]<<endl;
+   return;
+ }
+ SphericalMap<r_4>* map = dynamic_cast<SphericalMap<r_4>*>(obj);
+ if(map==NULL) {
+   cout<<"Error: "<<tokens[0]<<" is not a SphericalMap<r_4>"<<endl;
+   return;
+ }
+ uint_2 t = typemap(obj);
+ int_4 nside = map->SizeIndex();
+
+ SphericalMap<r_8>* map8 = NULL;
+ if(t&HealPix)       map8 = new SphereHEALPix<r_8>(nside);
+ else if(t&ThetaPhi) map8 = new SphereThetaPhi<r_8>(nside);
+ else return;
+
+ cout<<"Map2Double: converting to double "<<tokens[0]<<" nside="<<nside<<endl;
+ for(int_4 i=0;i<map8->NbPixels();i++) (*map8)(i) = (r_8) (*map)(i);
+
+ omg.AddObj(map8,tokens[0]);
+}
+
+/* --Methode-- */
+void skymapmoduleExecutor::Map2Float(vector<string>& tokens)
+{
+ NamedObjMgr omg;
+ AnyDataObj* obj=omg.GetObj(tokens[0]);
+ if(obj==NULL) {
+   cout<<"Error: Pas d'objet de nom "<<tokens[0]<<endl;
+   return;
+ }
+ SphericalMap<r_8>* map = dynamic_cast<SphericalMap<r_8>*>(obj);
+ if(map==NULL) {
+   cout<<"Error: "<<tokens[0]<<" is not a SphericalMap<r_8>"<<endl;
+   return;
+ }
+ uint_2 t = typemap(obj);
+ int_4 nside = map->SizeIndex();
+
+ SphericalMap<r_4>* map4 = NULL;
+ if(t&HealPix)       map4 = new SphereHEALPix<r_4>(nside);
+ else if(t&ThetaPhi) map4 = new SphereThetaPhi<r_4>(nside);
+ else return;
+
+ cout<<"Map2Float: converting to float "<<tokens[0]<<" nside="<<nside<<endl;
+ for(int_4 i=0;i<map4->NbPixels();i++) (*map4)(i) = (r_4) (*map)(i);
+
+ omg.AddObj(map4,tokens[0]);
+}
+
+/* --Methode-- */
+void skymapmoduleExecutor::Map2Map(vector<string>& tokens)
+{
+ NamedObjMgr omg;
+ AnyDataObj* obj=omg.GetObj(tokens[0]);
+ if(obj==NULL) {
+   cout<<"Error: Pas d'objet de nom "<<tokens[0]<<endl;
+   return;
+ }
+ SphericalMap<r_8>* map = dynamic_cast<SphericalMap<r_8>*>(obj);
+ if(map==NULL) {
+   cout<<"Error: "<<tokens[0]<<" is not a SphericalMap<r_8>"<<endl;
+   return;
+ }
+ uint_2 t = typemap(obj);
+ int_4 nside = map->SizeIndex();
+
+ uint_2 tomap = UnKnown;
+ if(toupper(tokens[1][0])=='H')      tomap = HealPix;
+ else if(toupper(tokens[1][0])=='T') tomap = ThetaPhi;
+ else {cout<<"unkown map type "<<(char)toupper(tokens[1][0])<<" (H or T)!"<<endl; return;}
+ if(t&tomap) {cout<<"map of same type, no conversion done"<<endl; return;}
+
+ int_4 tonside = nside;
+ if(tokens.size()>2) tonside = atoi(tokens[2].c_str());
+ else {
+   if(tomap&HealPix) {tonside=int(nside/1.5); GetNSideGood(tonside);}
+   else tonside=int(map->NbThetaSlices()/2.5);
+ }
+ if(tomap&HealPix && !IsNSideGood(tonside))
+   {cout<<"Bad nside for Healpix "<<tonside<<endl; return;}
+
+ SphericalMap<r_8>* map8 = NULL;
+ if(tomap&HealPix)       map8 = new SphereHEALPix<r_8>(tonside);
+ else if(tomap&ThetaPhi) map8 = new SphereThetaPhi<r_8>(tonside);
+ else return;
+
+ cout<<"Map2Map: convert "<<tokens[0]<<" nside="<<nside
+     <<" to type "<<tokens[1]<<" tonside="<<tonside
+     <<"   ntheta="<<map->NbThetaSlices()<<" -> "<<map8->NbThetaSlices()<<endl;
+
+ for(int_4 i=0;i<map8->NbPixels();i++) {
+   double theta,phi; map8->PixThetaPhi(i,theta,phi);
+   int_4 ip = map->PixIndexSph(theta,phi);
+   if(ip<0 || ip>=map->NbPixels()) continue;
+   (*map8)(i)=(*map)(ip);
+ }
+
+ omg.AddObj(map8,tokens[0]);
+}
+
+/* --Methode-- */
+void skymapmoduleExecutor::MapMult(vector<string>& tokens)
+{
+ NamedObjMgr omg;
+ AnyDataObj* obj=omg.GetObj(tokens[0]);
+ if(obj==NULL) {
+   cout<<"Error: Pas d'objet de nom "<<tokens[0]<<endl;
+   return;
+ }
+ SphericalMap<r_8>* map = dynamic_cast<SphericalMap<r_8>*>(obj);
+ if(map==NULL) {
+   cout<<"Error: "<<tokens[0]<<" is not a SphericalMap<r_8>"<<endl;
+   return;
+ }
+ double v = atof(tokens[1].c_str());
+ cout<<"MapMult: Multiply "<<tokens[0]<<" by "<<v<<endl;
+ for(int_4 i=0;i<map->NbPixels();i++) (*map)(i) *= v;
+}
+
+/* --Methode-- */
+void skymapmoduleExecutor::MapCover(vector<string>& tokens)
+{
+ NamedObjMgr omg;
+ AnyDataObj* obj=omg.GetObj(tokens[0]);
+ if(obj==NULL) {
+   cout<<"Error: Pas d'objet de nom "<<tokens[0]<<endl;
+   return;
+ }
+ SphericalMap<r_8>* map = dynamic_cast<SphericalMap<r_8>*>(obj);
+ if(map==NULL) {
+   cout<<"Error: "<<tokens[0]<<" is not a SphericalMap<r_8>"<<endl;
+   return;
+ }
+
+ double v1=0.99, v2=1.01;
+ if(tokens.size()>1) if(tokens[1][0]!='!')
+   sscanf(tokens[1].c_str(),"%lf,%lf",&v1,&v2);
+
+ cout<<"MapCover: "<<tokens[0]<<" good px=["<<v1<<","<<v2<<"]"<<endl;
+
+ int_4 ngood=0;
+ for(int_4 i=0;i<map->NbPixels();i++)
+   if(v1<=(*map)(i) && (*map)(i)<=v2) ngood++;
+ double per = (double)ngood/(double)map->NbPixels();
+ cout<<"NGood="<<ngood<<" NTot="<<map->NbPixels()
+     <<" -> "<<100.*per<<" %";
+ if(tokens.size()>2) {
+   if(omg.HasVar(tokens[2])) omg.DeleteVar(tokens[2]);
+   char str[512]; sprintf(str,"%g",per);
+   omg.SetVar(tokens[2],(string)str);
+   cout<<" stored into $"<<tokens[2];
+ }
+ cout<<endl;
+}
+
+/* --Methode-- */
+void skymapmoduleExecutor::Map2Cl(vector<string>& tokens)
+{
+ NamedObjMgr omg;
+
+ int_4 lmax=0, niter=3;
+ if(tokens.size()>2) if(tokens[2][0]!='!')
+   lmax = atoi(tokens[2].c_str());
+ if(tokens.size()>3) niter = atoi(tokens[3].c_str());
+ if(niter<=0) niter = 3;
+
+ AnyDataObj* obj=omg.GetObj(tokens[0]);
+ if(obj==NULL) {
+   cout<<"Error: Pas d'objet de nom "<<tokens[0]<<endl;
+   return;
+ }
+ SphericalMap<r_8>* map = dynamic_cast<SphericalMap<r_8>*>(obj);
+ if(map==NULL) {
+   cout<<"Error: "<<tokens[0]<<" is not a SphericalMap<r_8>"<<endl;
+   return;
+ }
+ uint_2 t = typemap(obj);
+
+ SphericalTransformServer<r_8> ylmserver;
+
+ int_4 nside = map->SizeIndex();
+ if(lmax<=0) lmax = 3*nside-1;
+
+ SphericalMap<r_8>* tmpmap = NULL;
+ if(t&HealPix)       tmpmap = new SphereHEALPix<r_8>(*((SphereHEALPix<r_8>*)map),false);
+ else if(t&ThetaPhi) tmpmap = new SphereThetaPhi<r_8>(*((SphereThetaPhi<r_8>*)map),false);
+ else return;
+
+ cout<<"Map2Cl: "<<tokens[0]<<"(nside="<<nside
+     <<") lmax="<<lmax<<" niter="<<niter<<" -> "<<tokens[1];
+
+ TVector<r_8> cltmp = ylmserver.DecomposeToCl(*tmpmap,lmax,0.,niter);
+ cout<<"("<<cltmp.Size()<<")"<<endl;
+ delete tmpmap;
+
+ omg.AddObj(cltmp,tokens[1]);
+}
+
+/* --Methode-- */
+void skymapmoduleExecutor::Cl2Map(vector<string>& tokens)
+{
+ NamedObjMgr omg;
+
+ AnyDataObj* obj=omg.GetObj(tokens[0]);
+ if(obj==NULL) {
+   cout<<"Error: Pas d'objet de nom "<<tokens[0]<<endl;
+   return;
+ }
+ TVector<r_8>* cl = dynamic_cast<TVector<r_8>*>(obj);
+ if(cl==NULL) {
+   cout<<"Error: "<<tokens[0]<<" is not a TVector<r_8>"<<endl;
+   return;
+ }
+
+ int nside = 128;
+ if(tokens.size()>2) nside = atoi(tokens[2].c_str());
+ if(DefTypMap&HealPix && !IsNSideGood(nside))
+   {cout<<"Cl2Map: Bad nside for HealPix "<<nside<<endl; return;}
+
+ double fwhm = 0.;
+ if(tokens.size()>3) fwhm = atof(tokens[3].c_str());
+
+ SphericalMap<r_8>* map = NULL;
+ if(DefTypMap&HealPix)       map = new SphereHEALPix<r_8>;
+ else if(DefTypMap&ThetaPhi) map = new SphereThetaPhi<r_8>;
+ else return;
+
+ SphericalTransformServer<r_8> ylmserver;
+ cout<<"Cl2Map: Generate map "<<tokens[1]<<" with nside="<<nside
+     <<" from cl "<<tokens[0]<<"("<<cl->Size()<<")"
+     <<" with fwhm="<<fwhm<<endl;
+ ylmserver.GenerateFromCl(*map,nside,*cl,fwhm);
+
+ omg.AddObj(map,tokens[1]);
+}
+
+/* --Methode-- */
+void skymapmoduleExecutor::Map2Alm(vector<string>& tokens)
+{
+ NamedObjMgr omg;
+
+ int_4 lmax=0, niter=3;
+ if(tokens.size()>2) if(tokens[2][0]!='!')
+   lmax = atoi(tokens[2].c_str());
+ if(tokens.size()>3) niter = atoi(tokens[3].c_str());
+ if(niter<=0) niter = 3;
+
+ AnyDataObj* obj=omg.GetObj(tokens[0]);
+ if(obj==NULL) {
+   cout<<"Error: Pas d'objet de nom "<<tokens[0]<<endl;
+   return;
+ }
+ SphericalMap<r_8>* map = dynamic_cast<SphericalMap<r_8>*>(obj);
+ if(map==NULL) {
+   cout<<"Error: "<<tokens[0]<<" is not a SphericalMap<r_8>"<<endl;
+   return;
+ }
+ uint_2 t = typemap(obj);
+
+ SphericalTransformServer<r_8> ylmserver;
+
+ int_4 nside = map->SizeIndex();
+ if(lmax<=0) lmax = 3*nside-1;
+
+ SphericalMap<r_8>* tmpmap = NULL;
+ if(t&HealPix)       tmpmap = new SphereHEALPix<r_8>(*((SphereHEALPix<r_8>*)map),false);
+ else if(t&ThetaPhi) tmpmap = new SphereThetaPhi<r_8>(*((SphereThetaPhi<r_8>*)map),false);
+ else return;
+
+ cout<<"Map2Alm: "<<tokens[0]<<"(nside="<<nside
+     <<") lmax="<<lmax<<" niter="<<niter<<" -> "<<tokens[1];
+
+ Alm<r_8> almtmp;
+ ylmserver.DecomposeToAlm(*tmpmap,almtmp,lmax,0.,niter);
+ cout<<"("<<almtmp.rowNumber()<<")"<<endl;
+ delete tmpmap;
+
+ int n = almtmp.rowNumber();
+ TMatrix< complex<r_8> >* alm = new TMatrix< complex<r_8> >(n,n);
+ *alm = (complex<r_8>)0.;
+ for(int i=0;i<n;i++) for(int j=0;j<=i;j++) (*alm)(i,j)=almtmp(i,j);
+ omg.AddObj(alm,tokens[1]);
+}
+
+/* --Methode-- */
+void skymapmoduleExecutor::Alm2Map(vector<string>& tokens)
+{
+ NamedObjMgr omg;
+
+ AnyDataObj* obj=omg.GetObj(tokens[0]);
+ if(obj==NULL) {
+   cout<<"Error: Pas d'objet de nom "<<tokens[0]<<endl;
+   return;
+ }
+ TMatrix< complex<r_8> >* almmat = dynamic_cast<TMatrix< complex<r_8> >*>(obj);
+ if(almmat==NULL) {
+   cout<<"Error: "<<tokens[0]<<" is not a TMatrix< complex<r_8> >"<<endl;
+   return;
+ }
+
+ int lmax = almmat->NRows()-1;
+ Alm<r_8> alm(lmax);
+ alm = (complex<r_8>)0.;
+ for(int i=0;i<lmax+1;i++) for(int j=0;j<=i;j++) alm(i,j)=(*almmat)(i,j);
+
+ int nside = 128;
+ if(tokens.size()>2) nside = atoi(tokens[2].c_str());
+ if(DefTypMap&HealPix && !IsNSideGood(nside))
+   {cout<<"Alm2Map: Bad nside for HealPix "<<nside<<endl; return;}
+
+ SphericalMap<r_8>* map = NULL;
+ if(DefTypMap&HealPix)       map = new SphereHEALPix<r_8>;
+ else if(DefTypMap&ThetaPhi) map = new SphereThetaPhi<r_8>;
+ else return;
+
+ SphericalTransformServer<r_8> ylmserver;
+ cout<<"Alm2Map: Generate map "<<tokens[1]<<" with nside="<<nside
+     <<" from alm "<<tokens[0]<<"("<<alm.rowNumber()<<")"<<endl;
+ ylmserver.GenerateFromAlm(*map,nside,alm);
+
+ omg.AddObj(map,tokens[1]);
+}
+
+/* --Methode-- */
+void skymapmoduleExecutor::CrMapMask(vector<string>& tokens)
+{
+ NamedObjMgr omg;
+
+ int_4 nside = atoi(tokens[1].c_str());
+ if(DefTypMap&HealPix && !IsNSideGood(nside))
+   {cout<<"CrMapMask: Bad nside "<<nside<<endl; return;}
+
+ SphericalMap<r_8>* map = NULL;
+ if(DefTypMap&HealPix)       map = new SphereHEALPix<r_8>(nside);
+ else if(DefTypMap&ThetaPhi) map = new SphereThetaPhi<r_8>(nside);
+ else return;
+
+ bool lat=false, lon=false;
+ double lat1=-99., lat2=99., lon1=-999., lon2=999.;
+ if(tokens.size()>2) if(tokens[2][0]!='!')
+   {lat=true; sscanf(tokens[2].c_str(),"%lf,%lf",&lat1,&lat2);}
+ if(tokens.size()>3) if(tokens[3][0]!='!')
+   {lon=true; sscanf(tokens[3].c_str(),"%lf,%lf",&lon1,&lon2);}
+
+ double valmsk=0., unvalmsk=1.;
+ if(tokens.size()>4) sscanf(tokens[4].c_str(),"%lf,%lf",&valmsk,&unvalmsk);
+
+ cout<<"CrMapMask "<<tokens[0]<<" nside="<<nside;
+ if(lat) cout<<" for latitude in ["<<lat1<<","<<lat2<<"]";
+ if(lon) cout<<" for longitude in ["<<lon1<<","<<lon2<<"]";
+ cout<<" valmsk="<<valmsk<<" unvalmsk="<<unvalmsk<<endl;
+
+ //Attention: conversion en co-latitude ==> inversion: [lat2,lat1]
+ lat1 = (90.-lat1)*M_PI/180.; lat2 = (90.-lat2)*M_PI/180.;
+ lon1 *= M_PI/180.; lon2 *= M_PI/180.;
+ for(int_4 i=0;i<map->NbPixels();i++) {
+   (*map)(i)=unvalmsk;
+   if(!lat && !lon) continue;
+   double theta,phi; map->PixThetaPhi(i,theta,phi);
+   if(lat && (theta<lat2 || lat1<theta)) continue;
+   if(lon && (  phi<lon1 || lon2<phi  )) continue;
+   (*map)(i)=valmsk;
+ }
+
+ omg.AddObj(map,tokens[0]);
+}
+
+/* --Methode-- */
+void skymapmoduleExecutor::CrMaskFrMap(vector<string>& tokens)
+{
+ NamedObjMgr omg;
+
+ AnyDataObj* obj=omg.GetObj(tokens[2]);
+ if(obj==NULL) {
+   cout<<"Error: Pas d'objet de nom "<<tokens[2]<<endl;
+   return;
+ }
+ SphericalMap<r_8>* map = dynamic_cast<SphericalMap<r_8>*>(obj);
+ if(map==NULL) {
+   cout<<"Error: "<<tokens[2]<<" is not a SphericalMap<r_8>"<<endl;
+   return;
+ }
+ uint_2 t = typemap(obj);
+
+ int_4 nside = atoi(tokens[1].c_str());
+ if(nside<=1) return;
+ if(t&HealPix && !IsNSideGood(nside))
+   {cout<<"CrMapMask: Bad nside for HealPix "<<nside<<endl; return;}
+
+ SphericalMap<r_8>* msk = NULL;
+ if(t&HealPix)       msk = new SphereHEALPix<r_8>(nside);
+ else if(t&ThetaPhi) msk = new SphereThetaPhi<r_8>(nside);
+ else return;
+
+ double v1=-1.e100, v2=1.e100;
+ if(tokens.size()>3) if(tokens[3][0]!='!')
+   sscanf(tokens[3].c_str(),"%lf,%lf",&v1,&v2);
+
+ double valmsk=0., unvalmsk=1.;
+ if(tokens.size()>4) sscanf(tokens[4].c_str(),"%lf,%lf",&valmsk,&unvalmsk);
+
+ cout<<"CrMaskFrMap "<<tokens[0]<<" nside="<<nside<<" with "<<tokens[2]<<endl
+     <<"   for value in ["<<v1<<","<<v2<<"]"
+     <<" valmsk="<<valmsk<<" unvalmsk="<<unvalmsk<<endl;
+
+ for(int_4 i=0;i<msk->NbPixels();i++) {
+   double theta,phi; msk->PixThetaPhi(i,theta,phi);
+   int_4 ip = map->PixIndexSph(theta,phi);
+   if(ip<0 || ip>=map->NbPixels()) continue;
+   double v = (*map)(ip);
+   if(v>v1 && v<v2) (*msk)(i)=valmsk;
+     else           (*msk)(i)=unvalmsk;
+ }
+
+ omg.AddObj(msk,tokens[0]);
+}
+
+/* --Methode-- */
+void skymapmoduleExecutor::MaskMap(vector<string>& tokens)
+{
+ NamedObjMgr omg;
+
+ AnyDataObj* obj=omg.GetObj(tokens[0]);
+ if(obj==NULL) {
+   cout<<"Error: Pas d'objet de nom "<<tokens[0]<<endl;
+   return;
+ }
+ SphericalMap<r_8>* map = dynamic_cast<SphericalMap<r_8>*>(obj);
+ if(map==NULL) {
+   cout<<"Error: "<<tokens[0]<<" is not a SphericalMap<r_8>"<<endl;
+   return;
+ }
+
+ AnyDataObj* objm=omg.GetObj(tokens[1]);
+ if(obj==NULL) {
+   cout<<"Error: Pas d'objet de nom "<<tokens[1]<<endl;
+   return;
+ }
+ SphericalMap<r_8>* msk = dynamic_cast<SphericalMap<r_8>*>(objm);
+ if(msk==NULL) {
+   cout<<"Error: "<<tokens[1]<<" is not a SphericalMap<r_8>"<<endl;
+   return;
+ }
+
+ cout<<"MskMap: "<<tokens[0]<<" with mask "<<tokens[1]<<endl;
+
+ for(int_4 i=0;i<map->NbPixels();i++) {
+   double theta,phi; map->PixThetaPhi(i,theta,phi);
+   int_4 ip = msk->PixIndexSph(theta,phi);
+   if(ip<0 || ip>=msk->NbPixels()) continue;
+   (*map)(i) *= (*msk)(ip);
+ }
+
+}
+
+/* --Methode-- */
+void skymapmoduleExecutor::MapProj(vector<string>& tokens)
+{
+ NamedObjMgr omg;
+
+ AnyDataObj* obj=omg.GetObj(tokens[0]);
+ if(obj==NULL) {
+   cout<<"Error: Pas d'objet de nom "<<tokens[0]<<endl;
+   return;
+ }
+ SphericalMap<r_8>* map = dynamic_cast<SphericalMap<r_8>*>(obj);
+ if(map==NULL) {
+   cout<<"Error: "<<tokens[0]<<" is not a SphericalMap<r_8>"<<endl;
+   return;
+ }
+ int_4 nsidemap = map->SizeIndex();
+ uint_2 t = typemap(obj);
+
+ int_4 nside = nsidemap;
+ if(tokens.size()>2) nside = atoi(tokens[2].c_str());
+ if(t&HealPix && !IsNSideGood(nside))
+   {cout<<"MapProj: Bad nside for Healpix "<<nside<<endl; return;}
+
+ SphericalMap<r_8>* mapproj = NULL;
+ if(t&HealPix)       mapproj = new SphereHEALPix<r_8>(nside);
+ else if(t&ThetaPhi) mapproj = new SphereThetaPhi<r_8>(nside);
+ else return;
+
+ cout<<"MapProj: project "<<tokens[0]<<" n="<<nsidemap
+     <<" to "<<tokens[1]<<" n="<<nside<<endl;
+
+ if(nsidemap==nside) {  // tailles egales
+   for(int_4 i=0;i<mapproj->NbPixels();i++)
+      (*mapproj)(i) = (*map)(i);
+  } else if(nsidemap<nside) {  // mapproj>map
+   for(int_4 i=0;i<mapproj->NbPixels();i++) {
+     double theta,phi; mapproj->PixThetaPhi(i,theta,phi);
+     int_4 ip = map->PixIndexSph(theta,phi);
+     if(ip<0 || ip>=map->NbPixels()) continue;
+     (*mapproj)(i) = (*map)(ip);
+   }
+ } else {  // mapproj<map
+   SphericalMap<int_4>*  nproj= NULL;
+   if(t&HealPix)       nproj= new SphereHEALPix<int_4>(nside);
+   else if(t&ThetaPhi) nproj= new SphereThetaPhi<int_4>(nside);
+   int_4 i;
+   for(i=0;i<nproj->NbPixels();i++) {(*nproj)(i)=0;(*mapproj)(i)=0.;}
+   for(i=0;i<map->NbPixels();i++) {
+     double theta,phi; map->PixThetaPhi(i,theta,phi);
+     int_4 ip = mapproj->PixIndexSph(theta,phi);
+     if(ip<0 || ip>=mapproj->NbPixels()) continue;
+     (*mapproj)(ip) += (*map)(i);
+     (*nproj)(ip)++;
+   }
+   for(i=0;i<mapproj->NbPixels();i++)
+      (*mapproj)(i) /= (r_8) (*nproj)(i);
+   delete nproj;
+ }
+ 
+ omg.AddObj(mapproj,tokens[1]);
+}
+
+/* --Methode-- */
+void skymapmoduleExecutor::Map2Local(vector<string>& tokens)
+{
+ NamedObjMgr omg;
+
+ AnyDataObj* obj=omg.GetObj(tokens[0]);
+ if(obj==NULL) {
+   cout<<"Error: Pas d'objet de nom "<<tokens[0]<<endl;
+   return;
+ }
+ SphericalMap<r_8>* map = dynamic_cast<SphericalMap<r_8>*>(obj);
+ if(map==NULL) {
+   cout<<"Error: "<<tokens[0]<<" is not a SphericalMap<r_8>"<<endl;
+   return;
+ }
+
+ int_4 nx=10,ny=10;
+ if(tokens.size()>2) sscanf(tokens[2].c_str(),"%d,%d",&nx,&ny);
+ if(nx<=0)
+   {cout<<"Error: nx="<<nx<<" value >0"<<endl; return;}
+ if(ny<=0)
+   {cout<<"Error: ny="<<ny<<" value >0"<<endl; return;}
+
+ double angleX=1., angleY=1.;
+ if(tokens.size()>3) sscanf(tokens[3].c_str(),"%lf,%lf",&angleX,&angleY);
+ if(angleX<=0. || angleX>180.)
+   {cout<<"Error: bad angleX="<<angleX<<" value #]0,180]"<<endl; return;}
+ if(angleY<=0. || angleY>180.)
+   {cout<<"Error: bad angleY="<<angleY<<" value #]0,180]"<<endl; return;}
+
+ double phi0=0., theta0=0.;
+ if(tokens.size()>4) sscanf(tokens[4].c_str(),"%lf,%lf",&phi0,&theta0);
+ if(phi0<0. || phi0>=360.)
+   {cout<<"Error: bad phi0="<<phi0<<" value #[0,360["<<endl; return;}
+ if(theta0<-90. || theta0>90.)
+   {cout<<"Error: bad theta0="<<theta0<<" value #[-90,90]"<<endl; return;}
+
+ int_4 x0=nx/2, y0=ny/2;
+ if(tokens.size()>5) if(tokens[5][0]!='!')
+   sscanf(tokens[5].c_str(),"%d,%d",&x0,&y0);
+
+ double angle=0.;
+ if(tokens.size()>6) sscanf(tokens[6].c_str(),"%lf",&angle);
+
+ cout<<"Map2Local: proj "<<tokens[0]<<" to local "<<tokens[1]<<endl
+     <<" nx="<<nx<<" ny="<<ny<<" angleX="<<angleX<<" angleY="<<angleY
+     <<" phi0="<<phi0<<" theta0="<<theta0<<" x0="<<x0<<" y0="<<y0
+     <<" angle="<<angle<<endl;
+ if(angle<-90. || angle>90.)
+   {cout<<"Error: bad angle="<<angle<<" value #[-90,90]"<<endl; return;}
+
+ theta0 = (90.-theta0);
+ LocalMap<r_8>* lmap = new LocalMap<r_8>(nx,ny,angleX,angleY,theta0,phi0,x0,y0,angle);
+ *lmap = 0.;  //lmap->print(cout);
+
+ int_4 nbad=0;
+ double tmax=-9999., pmax=-9999., tmin=9999., pmin=9999.;
+ for(int_4 i=0;i<lmap->NbPixels();i++) {
+   double theta,phi;
+   lmap->PixThetaPhi(i,theta,phi);
+   int_4 ip = map->PixIndexSph(theta,phi);
+   if(ip<0 || ip>=map->NbPixels()) {nbad++; continue;}
+   if(theta<tmin) tmin=theta; if(theta>tmax) tmax=theta; 
+   if(phi<pmin) pmin=phi; if(phi>pmax) pmax=phi; 
+   (*lmap)(i) = (*map)(ip);
+ }
+ if(nbad) cout<<"Warning: "<<nbad<<" bad pixels numbers"<<endl;
+ cout<<" phi=["<<pmin/M_PI*180.<<","<<pmax/M_PI*180.<<"]="
+               <<(pmax-pmin)/M_PI*180.
+     <<" theta=["<<tmin/M_PI*180.<<","<<tmax/M_PI*180.<<"]="
+               <<(tmax-tmin)/M_PI*180.<<endl;
+
+ omg.AddObj(lmap,tokens[1]); 
+}
+
+/* --Methode-- */
+void skymapmoduleExecutor::MapOper(vector<string>& tokens)
+{
+ NamedObjMgr omg;
+
+ AnyDataObj* obj=omg.GetObj(tokens[0]);
+ if(obj==NULL) {
+   cout<<"Error: Pas d'objet de nom "<<tokens[0]<<endl;
+   return;
+ }
+ SphericalMap<r_8>* map = dynamic_cast<SphericalMap<r_8>*>(obj);
+ if(map==NULL) {
+   cout<<"Error: "<<tokens[0]<<" is not a SphericalMap<r_8>"<<endl;
+   return;
+ }
+
+ cout<<"MapOper: "<<tokens[0];
+ for(unsigned short iop=1;iop<tokens.size()-1;iop+=2) {
+   string op = tokens[iop];
+   if(op!="+" && op!="-" && op!="*" && op!="/") continue;
+   AnyDataObj* obj1=omg.GetObj(tokens[iop+1]);
+   if(obj1==NULL)
+     {cout<<"Error: Pas d'objet de nom "<<tokens[iop+1]<<endl;
+      continue;}
+   SphericalMap<r_8>* map1 = dynamic_cast<SphericalMap<r_8>*>(obj1);
+   if(map1==NULL)
+     {cout<<"Error: "<<tokens[iop+1]<<" is not a SphericalMap<r_8>"<<endl;
+      continue;}
+   cout<<" "<<op<<"= "<<tokens[iop+1];
+   for(int_4 i=0;i<map->NbPixels();i++) {
+     double theta,phi; map->PixThetaPhi(i,theta,phi);
+     int_4 ip = map1->PixIndexSph(theta,phi);
+     if(ip<0 || ip>=map1->NbPixels()) continue;
+     if(op=="+")      (*map)(i) += (*map1)(ip);
+     else if(op=="-") (*map)(i) -= (*map1)(ip);
+     else if(op=="*") (*map)(i) *= (*map1)(ip);
+     else if(op=="/")
+       {if((*map1)(ip)!=0.) (*map)(i)/=(*map1)(ip); else (*map)(i)=0.;}
+   }
+ }
+ cout<<endl;
+}
+
+/* --Methode-- */
+void skymapmoduleExecutor::MapStat(vector<string>& tokens)
+{
+ NamedObjMgr omg;
+
+ AnyDataObj* obj=omg.GetObj(tokens[0]);
+ if(obj==NULL) {
+   cout<<"Error: Pas d'objet de nom "<<tokens[1]<<endl;
+   return;
+ }
+ SphericalMap<r_8>* map = dynamic_cast<SphericalMap<r_8>*>(obj);
+ if(map==NULL) {
+   cout<<"Error: "<<tokens[0]<<" is not a SphericalMap<r_8>"<<endl;
+   return;
+ }
+
+ SphericalMap<r_8>* msk = NULL;
+ if(tokens.size()>1) {
+   if(tokens[1][0]!='!') {
+     AnyDataObj* objm=omg.GetObj(tokens[1]);
+     if(objm==NULL) {
+       cout<<"Error: Pas d'objet de nom "<<tokens[1]<<endl;
+       return;
+     }
+     msk = dynamic_cast<SphericalMap<r_8>*>(objm);
+     if(msk==NULL) {
+       cout<<"Error: "<<tokens[1]<<" is not a SphericalMap<r_8>"<<endl;
+       return;
+     }
+   }
+ }
+
+ cout<<"MapStat for map "<<tokens[0];
+ if(msk) cout<<" using mask "<<tokens[1];
+ cout<<endl;
+
+ double sum=0., sum2=0., sumw=0.;
+ int npix = map->NbPixels(), npixgood=0;
+ for(int_4 i=0;i<npix;i++) {
+   double w = 1.;
+   if(msk) {
+     double theta,phi; map->PixThetaPhi(i,theta,phi);
+     int_4 ip = msk->PixIndexSph(theta,phi);
+     if(ip<0 || ip>=msk->NbPixels()) w=0.;
+       else                          w=(*msk)(ip);
+   }
+   if(w<=0.) continue;
+   npixgood++; sumw += w;
+   sum += (*map)(i)*w;
+   sum2 += (*map)(i)*(*map)(i)*w*w;
+ }
+ if(sumw<=0. || npixgood==0) {
+   sum = sum2 = sumw=0.;
+ } else {
+   sum /= sumw;
+   sum2 = sum2/sumw - sum*sum;
+   if(sum2<=0.) sum2=0.; else sum2=sqrt(sum2);
+ }
+ cout<<"Number of good px="<<npixgood<<" / "<<npix
+     <<" ("<<100.*npixgood/npix<<" %)"<<endl;
+ cout<<" mean="<<sum<<" sigma="<<sum2<<endl;
+
+ if(tokens.size()>2) if(tokens[2][0]!='!') {
+   if(omg.HasVar(tokens[2])) omg.DeleteVar(tokens[2]);
+   char str[512]; sprintf(str,"%.8f",sum);
+   omg.SetVar(tokens[2],(string)str);
+   cout<<" mean stored into $"<<tokens[2];
+ }
+ if(tokens.size()>3) if(tokens[3][0]!='!') {
+   if(omg.HasVar(tokens[3])) omg.DeleteVar(tokens[3]);
+   char str[512]; sprintf(str,"%.8f",sum2);
+   omg.SetVar(tokens[3],(string)str);
+   cout<<" sigma stored into $"<<tokens[3];
+ }
+ if(tokens.size()>2) cout<<endl;
+
+}
+
+/* --Methode-- */
+void skymapmoduleExecutor::Alm2Cl(vector<string>& tokens)
+{
+ NamedObjMgr omg;
+
+ AnyDataObj* obj=omg.GetObj(tokens[0]);
+ if(obj==NULL) {
+   cout<<"Error: Pas d'objet de nom "<<tokens[0]<<endl;
+   return;
+ }
+ TMatrix< complex<r_8> >* almmat = dynamic_cast<TMatrix< complex<r_8> >*>(obj);
+ if(almmat==NULL) {
+   cout<<"Error: "<<tokens[0]<<" is not a TMatrix< complex<r_8> >"<<endl;
+   return;
+ }
+
+ int lmax = almmat->NRows()-1;
+ Alm<r_8> alm(lmax);
+ alm = (complex<r_8>)0.;
+ for(int i=0;i<lmax+1;i++) for(int j=0;j<=i;j++) alm(i,j)=(*almmat)(i,j);
+
+ TVector<r_8> cl(almmat->NRows());
+ cl = 0.;
+
+ cout<<"Alm2Cl: project alm "<<tokens[0]<<"("<<alm.rowNumber()
+     <<") to cl "<<tokens[1]<<"("<<cl.Size()<<")"<<endl;
+
+ for(int_4 l=0;l<alm.rowNumber();l++) {
+   cl(l) = alm(l,0).real()*alm(l,0).real()+alm(l,0).imag()*alm(l,0).imag();
+   if(l>0) for(int_4 m=1;m<=l;m++)
+     cl(l) += 2.*(alm(l,m).real()*alm(l,m).real()+alm(l,m).imag()*alm(l,m).imag());
+   cl(l) /= 2.*l+1;
+ }
+
+ omg.AddObj(cl,tokens[1]);
+}
+
+/* --Methode-- */
+void skymapmoduleExecutor::Cl2llCl(vector<string>& tokens)
+{
+ NamedObjMgr omg;
+
+ AnyDataObj* obj=omg.GetObj(tokens[0]);
+ if(obj==NULL) {
+   cout<<"Error: Pas d'objet de nom "<<tokens[0]<<endl;
+   return;
+ }
+ TVector<r_8>* cl = dynamic_cast<TVector<r_8>*>(obj);
+ if(cl==NULL) {
+   cout<<"Error: "<<tokens[0]<<" is not a TVector<r_8>"<<endl;
+   return;
+ }
+
+ TVector<r_8> llcl(*cl,false);
+
+ cout<<"Cl2llCl: project "<<tokens[0]<<"("<<cl->Size()
+     <<") to l*(l+1)*cl "<<tokens[1]<<"("<<llcl.Size()<<")"<<endl;
+
+ for(int_4 l=0;l<llcl.Size();l++) llcl(l) *= (double)l*(l+1.);
+
+ omg.AddObj(llcl,tokens[1]);
+}
+
+/* --Methode-- */
+void skymapmoduleExecutor::ClMean(vector<string>& tokens)
+{
+ NamedObjMgr omg;
+
+ AnyDataObj* obj=omg.GetObj(tokens[0]);
+ if(obj==NULL) {
+   cout<<"Error: Pas d'objet de nom "<<tokens[0]<<endl;
+   return;
+ }
+ TVector<r_8>* cl = dynamic_cast<TVector<r_8>*>(obj);
+ if(cl==NULL) {
+   cout<<"Error: "<<tokens[0]<<" is not a TVector<r_8>"<<endl;
+   return;
+ }
+
+ int lmin=0, lmax=-1;
+ if(tokens.size()>1) if(tokens[1][0]!='!')
+   sscanf(tokens[1].c_str(),"%d,%d",&lmin,&lmax);
+ if(lmin<0) lmin=0; if(lmax>=cl->Size()) lmax=cl->Size()-1;
+ if(lmin>lmax) {lmin=0; lmax=cl->Size()-1;}
+
+ cout<<"ClMean: compute mean "<<tokens[0]<<"("<<cl->Size()
+     <<") between ["<<lmin<<","<<lmax<<"]";
+
+ double mean = 0.;
+ for(int_4 l=lmin;l<=lmax;l++) mean += (*cl)(l);
+ mean /= lmax-lmin+1;
+
+ cout<<" mean="<<mean;
+
+ if(tokens.size()>2) {
+   if(omg.HasVar(tokens[2])) omg.DeleteVar(tokens[2]);
+   char str[512]; sprintf(str,"%.8f",mean);
+   omg.SetVar(tokens[2],(string)str);
+   cout<<" stored into $"<<tokens[2];
+ }
+ cout<<endl;
+
+}
+
+/* --Methode-- */
+void skymapmoduleExecutor::ClMult(vector<string>& tokens)
+{
+ NamedObjMgr omg;
+
+ AnyDataObj* obj=omg.GetObj(tokens[0]);
+ if(obj==NULL) {
+   cout<<"Error: Pas d'objet de nom "<<tokens[0]<<endl;
+   return;
+ }
+ TVector<r_8>* cl = dynamic_cast<TVector<r_8>*>(obj);
+ if(cl==NULL) {
+   cout<<"Error: "<<tokens[0]<<" is not a TVector<r_8>"<<endl;
+   return;
+ }
+
+ double val = 1.;
+ if(tokens.size()>1) val=atof(tokens[1].c_str());
+
+ cout<<"ClMult: multiply "<<tokens[0]<<"("<<cl->Size()<<") by "<<val<<endl;
+
+ *cl *= val;
+
+}
+
+/* --Methode-- */
+void skymapmoduleExecutor::ClOper(vector<string>& tokens)
+{
+ NamedObjMgr omg;
+
+ AnyDataObj* obj=omg.GetObj(tokens[0]);
+ if(obj==NULL) {
+   cout<<"Error: Pas d'objet de nom "<<tokens[0]<<endl;
+   return;
+ }
+ TVector<r_8>* cl = dynamic_cast<TVector<r_8>*>(obj);
+ if(cl==NULL) {
+   cout<<"Error: "<<tokens[0]<<" is not a TVector<r_8>"<<endl;
+   return;
+ }
+
+ cout<<"ClOper: "<<tokens[0]<<"("<<cl->Size()<<")";
+ for(unsigned short iop=1;iop<tokens.size()-1;iop+=2) {
+   string op = tokens[iop];
+   if(op!="+" && op!="-" && op!="*" && op!="/") continue;
+   AnyDataObj* obj1=omg.GetObj(tokens[iop+1]);
+   if(obj1==NULL)
+     {cout<<"Error: Pas d'objet de nom "<<tokens[iop+1]<<endl;
+      continue;}
+   TVector<r_8>* cl1 = dynamic_cast<TVector<r_8>*>(obj1);
+   if(cl1==NULL)
+     {cout<<"Error: "<<tokens[iop+1]<<" is not a TVector<r_8>"<<endl;
+      continue;}
+   cout<<" "<<op<<"= "<<tokens[iop+1]<<"("<<cl1->Size()<<")";
+   int_4 n=cl->Size(); if(n>cl1->Size()) n=cl1->Size();
+   for(int_4 i=0;i<n;i++) {
+     if(op=="+")      (*cl)(i) += (*cl1)(i);
+     else if(op=="-") (*cl)(i) -= (*cl1)(i);
+     else if(op=="*") (*cl)(i) *= (*cl1)(i);
+     else if(op=="/")
+       {if((*cl1)(i)!=0.) (*cl)(i)/=(*cl1)(i); else (*cl)(i)=0.;}
+   }
+ }
+ cout<<endl;
+}
+/* --Methode-- */
+void skymapmoduleExecutor::ClRebin(vector<string>& tokens)
+{
+ NamedObjMgr omg;
+
+ AnyDataObj* obj=omg.GetObj(tokens[0]);
+ if(obj==NULL) {
+   cout<<"Error: Pas d'objet de nom "<<tokens[0]<<endl;
+   return;
+ }
+ TVector<r_8>* cl = dynamic_cast<TVector<r_8>*>(obj);
+ if(cl==NULL) {
+   cout<<"Error: "<<tokens[0]<<" is not a TVector<r_8>"<<endl;
+   return;
+ }
+ int_4 nn = cl->Size();
+ if(nn<=0) return;
+
+ int_4 nrebin=1, ibin0=0;
+ if(tokens.size()>2) sscanf(tokens[2].c_str(),"%d,%d",&nrebin,&ibin0);
+ if(ibin0<0 || ibin0>=nn) ibin0=0;
+
+ cout<<"ClRebin: rebin "<<tokens[0]<<"("<<nn<<") by nbin="<<nrebin
+     <<" begin at "<<ibin0<<" -> "<<tokens[1]<<endl;
+ 
+ const int ndim = 8;
+ char *nament[ndim] =
+   {"l","n","clmean","cllin","clpar","sclmean","scllin","sclpar"};
+ NTuple clbin(ndim,nament);
+ r_4 xnt[ndim];
+
+ SLinParBuff slp(nrebin+2);
+
+ for(int_4 i=ibin0;i<nn;i+=nrebin) {
+   r_8 ll=0.;
+   slp.Reset();
+   int_4 j;
+   for(j=0;j<ndim;j++) xnt[j]=0.;
+   for(j=i;j<nn;j++) {
+     ll += (r_8) j;
+     slp.Push((r_8)j,(*cl)(j));
+     if((int_4)slp.NPoints()>=nrebin) break;
+   }
+   if(slp.NPoints()<=0) continue;
+   ll /=  (r_8) slp.NPoints();
+   xnt[0] = ll;
+   xnt[1] = slp.NPoints();
+   r_8 s,a0,a1,a2;
+   s = slp.Compute(a0);
+   if(s>0.) {xnt[2]=a0; xnt[5]=s;}
+   s = slp.Compute(a0,a1);
+   if(s>0.) {xnt[3]=a0+a1*ll; xnt[6]=s;}
+   s = slp.Compute(a0,a1,a2);
+   if(s>0.) {xnt[4]=a0+a1*ll+a2*ll*ll; xnt[7]=s;}
+   clbin.Fill(xnt);
+ }
+
+ omg.AddObj(clbin,tokens[1]);
+}
+
+////////////////////////////////////////////////////////////
+
+/* --Methode-- */
+void skymapmoduleExecutor::SetTypeMap(vector<string>& tokens)
+{
+ if(tokens.size()<1) {
+   cout<<"SetTypeMap: Usage: settypemap type"<<endl;
+ } else {
+   if(toupper(tokens[0][0])=='H')      DefTypMap = HealPix;
+   else if(toupper(tokens[0][0])=='T') DefTypMap = ThetaPhi;
+   else cout<<"unkown map type, should be (H or T)!"<<endl;
+ }
+ string dum;
+ if(DefTypMap&HealPix)       dum="HealPix";
+ else if(DefTypMap&ThetaPhi) dum="ThetaPhi";
+ cout<<"SetTypeMap: type map is "<<dum<<" ("<<DefTypMap<<")"<<endl;
+}
+
+/* --Methode-- */
+bool skymapmoduleExecutor::IsNSideGood(int_4 nside)
+{
+ if(nside<=1) return false;
+ while(nside>1) {if(nside%2!=0) return false; else nside/=2;}
+ return true;
+}
+
+/* --Methode-- */
+void skymapmoduleExecutor::GetNSideGood(int_4 &nside)
+// get the nearest good nside for HealPix
+{
+ double n=1.e50; int_4 ns=nside;
+ for(int_4 i=1;i<66000;i*=2) {
+   double v = fabs((double)(nside-i));
+   if(v>n) continue;
+   n=v; ns=i;
+ }
+ nside = ns;
+}
+
+/* --Methode-- */
+uint_2 skymapmoduleExecutor::typemap(AnyDataObj* obj)
+{
+  if(obj==NULL) return UnKnown;
+  if(dynamic_cast<SphereHEALPix<r_4> *>(obj)) return HealPix4;
+  if(dynamic_cast<SphereHEALPix<r_8> *>(obj)) return HealPix8;
+  if(dynamic_cast<SphereThetaPhi<r_4>*>(obj)) return ThetaPhi4;
+  if(dynamic_cast<SphereThetaPhi<r_8>*>(obj)) return ThetaPhi8;
+  if(dynamic_cast<SphericalMap<r_4>  *>(obj)) return Spherical4;
+  if(dynamic_cast<SphericalMap<r_8>  *>(obj)) return Spherical8;
+  return UnKnown;
+}
+
+////////////////////////////////////////////////////////////
+static skymapmoduleExecutor * piaskmex = NULL;
+
+void skymapmodule_init()
+{
+if (piaskmex) delete piaskmex;
+piaskmex = new skymapmoduleExecutor;
+}
+
+void skymapmodule_end()
+{
+// Desactivation du module
+if (piaskmex) delete piaskmex;
+piaskmex = NULL;
+}
Index: /tags/V_Dec2002/SophyaPI/ProgPI/skymapmodule.pic
===================================================================
--- /tags/V_Dec2002/SophyaPI/ProgPI/skymapmodule.pic	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/ProgPI/skymapmodule.pic	(revision 2309)
@@ -0,0 +1,455 @@
+#---------------------- Create Maps and Save
+shell rm -f h4*.fits t4*.ppf h8*.fits t8*.ppf clh*.ppf clt*.ppf almh*.ppf almt*.ppf
+delobjs *
+c++import SkyMap
+c++exec \
+  double theta,phi; \
+  SphereHEALPix<r_4>  h4(256); \
+  for(int_4 i=0;i<h4.NbPixels();i++) { \
+    h4.PixThetaPhi(i,theta,phi); \
+    h4(i) = 0.; \
+    double v = (M_PI_2-theta)*(M_PI_2-theta)/(0.50*0.50); \
+    v += (phi-M_PI)*(phi-M_PI)/(M_PI*M_PI/2.); \
+    v = 100.*exp(-v/2.); \
+    v += 10.*NorRand(); \
+    if(phi<20.*M_PI/180.||phi>340.*M_PI/180.) continue; \
+    if(phi<190.*M_PI/180.&&phi>170.*M_PI/180.) continue; \
+    h4(i) = v; \
+  } \
+  KeepObj(h4); \
+  SphereThetaPhi<r_4> t4(400); \
+  for(int_4 i=0;i<t4.NbPixels();i++) { \
+    t4.PixThetaPhi(i,theta,phi); \
+    t4(i) = 0.; \
+    double v = (M_PI_2-theta)*(M_PI_2-theta)/(0.50*0.50); \
+    v += (phi-M_PI)*(phi-M_PI)/(M_PI*M_PI/2.); \
+    v = 100.*exp(-v/2.); \
+    v += 10.*NorRand(); \
+    if(phi<20.*M_PI/180.||phi>340.*M_PI/180.) continue; \
+    if(phi<190.*M_PI/180.&&phi>170.*M_PI/180.) continue; \
+    t4(i) = v; \
+  } \
+  KeepObj(t4); \
+  cout<<"End of Job"<<endl;
+
+savefits h4 !h4.fits
+saveppf t4 t4.ppf
+
+zone 1 2
+disp h4 zoom/4
+disp t4 zoom/4
+
+#---------------------- test Map2Double
+delobjs *
+zone
+openfits h4.fits
+
+map2double h4
+rename h4 h8
+savefits h8 !h8.fits
+
+delobjs *
+zone
+openppf t4.ppf
+map2double t4
+rename t4 t8
+saveppf t8 t8.ppf
+
+#---------------------- test Map2Float
+delobjs *
+zone
+openfits h8.fits
+openppf t8.ppf
+
+map2float h8
+map2float t8
+typemap h8
+typemap t8
+
+#---------------------- test TypeMap
+delobjs *
+zone
+openfits h4.fits
+openfits h8.fits
+openppf t4.ppf
+openppf t8.ppf
+typemap h4
+typemap h8
+typemap t4
+typemap t8
+
+#---------------------- test Map2Map
+delobjs *
+zone
+openfits h8.fits
+openppf t8.ppf
+map2map h8 t
+map2map t8 h
+
+#---------------------- test MapMult
+delobjs *
+zone
+openfits h8.fits
+openppf t8.ppf
+mapmult h8 1000
+mapmult t8 1000
+
+#---------------------- test MapProj
+delobjs *
+zone
+openfits h8.fits
+maproj h8 h8p
+mapop h8p - h8
+disp h8p zoom/4
+
+maproj h8 h8p64 64
+disp h8p64 zoom/4
+savefits h8p64 !h8p64.fits
+
+delobjs *
+zone
+openppf t8.ppf
+maproj t8 t8p
+mapop t8p - t8
+disp t8p zoom/4
+
+maproj t8 t8p100 100
+disp t8p100 zoom/4
+saveppf t8p100 t8p100.ppf
+
+#---------------------- test Map2Cl
+delobjs *
+zone
+openfits h8p64.fits
+map2cl h8p64 clh64
+saveppf clh64 clh64.ppf
+n/plot clh64.n*(n+1)*val%n ! ! crossmarker5
+
+map2cl h8p64 clh64 50
+n/plot clh64.n*(n+1)*val%n ! ! crossmarker5
+
+delobjs *
+zone
+openppf t8p100.ppf
+map2cl t8p100 clt100 191
+saveppf clt100 clt100.ppf
+n/plot clt100.n*(n+1)*val%n ! ! crossmarker5
+
+#---------------------- test Map2Alm
+delobjs *
+zone
+openfits h8p64.fits
+map2alm h8p64 almh64
+saveppf almh64 almh64.ppf
+disp almh64
+
+delobjs *
+zone
+openppf t8p100.ppf
+map2alm t8p100 almt100 191
+saveppf almt100 almt100.ppf
+disp almt100
+
+#---------------------- test Alm2Cl
+delobjs *
+zone
+openppf clh64.ppf
+openppf almh64.ppf
+alm2cl almh64 clh64fralm
+n/plot clh64.n*(n+1)*val%n ! ! crossmarker5
+n/plot clh64fralm.n*(n+1)*val%n ! ! "red same circlemarker5"
+c++exec clh64fralm -= clh64;
+n/plot clh64fralm.n*(n+1)*val%n ! ! crossmarker5
+
+delobjs *
+zone
+openppf clt100.ppf
+openppf almt100.ppf
+alm2cl almt100 clt100fralm
+n/plot clt100.n*(n+1)*val%n ! ! crossmarker5
+n/plot clt100fralm.n*(n+1)*val%n ! ! "red same circlemarker5"
+c++exec clt100fralm -= clt100;
+n/plot clt100fralm.n*(n+1)*val%n ! ! crossmarker5
+
+#---------------------- test Cl2Map et SetTypeMap
+delobjs *
+zone
+openppf clh64.ppf
+settypemap h
+cl2map clh64 h8p64frcl 64
+savefits h8p64frcl !h8p64frcl.fits
+disp h8p64frcl
+
+delobjs *
+zone
+openppf clt100.ppf
+settypemap t
+cl2map clt100 t8p100frcl 100
+saveppf t8p100frcl t8p100frcl.ppf
+disp t8p100frcl
+
+#---------------------- test Alm2Map et SetTypeMap
+delobjs *
+zone
+openppf almh64.ppf
+settypemap h
+alm2map almh64 h8p64fralm 64
+savefits h8p64fralm !h8p64fralm.fits
+disp h8p64fralm
+
+delobjs *
+zone
+openppf almt100.ppf
+settypemap t
+alm2map almt100 t8p100fralm 100
+saveppf t8p100fralm t8p100fralm.ppf
+disp t8p100fralm
+
+#---------------------- test Cl2llCl
+delobjs *
+zone
+openppf clh64.ppf
+cl2llcl clh64 llclh64
+n/plot clh64.n*(n+1)*val%n ! ! crossmarker5
+n/plot llclh64.val%n ! ! "red same circlemarker5"
+
+delobjs *
+zone
+openppf clt100.ppf
+cl2llcl clt100 llclt100
+n/plot clt100.n*(n+1)*val%n ! ! crossmarker5
+n/plot llclt100.val%n ! ! "red same circlemarker5"
+
+#---------------------- test ClMean
+delobjs *
+zone
+openppf clh64.ppf
+cl2llcl clh64 llclh64
+n/plot llclh64.val%n ! ! circlemarker5
+clmean llclh64
+clmean llclh64 !
+clmean llclh64 100,9999 mean
+echo $mean
+
+delobjs *
+zone
+openppf clt100.ppf
+cl2llcl clt100 llclt100
+n/plot llclt100.val%n ! ! circlemarker5
+clmean llclt100
+clmean llclt100 !
+clmean llclt100 100,9999 mean
+echo $mean
+
+#---------------------- test ClMult
+delobjs *
+openppf clh64.ppf
+zone 1 2
+n/plot clh64.val%n ! ! circlemarker5
+clmult clh64 1000.
+n/plot clh64.val%n ! ! circlemarker5
+
+delobjs *
+openppf clt100.ppf
+zone 1 2
+n/plot clt100.val%n ! ! circlemarker5
+clmult clt100 1000.
+n/plot clt100.val%n ! ! circlemarker5
+
+#---------------------- test ClOper
+delobjs *
+zone
+openppf clh64.ppf
+cp clh64 dum
+clop dum + clh64 - clh64 * clh64 / clh64
+n/plot clh64.val%n ! ! crossmarker5
+n/plot dum.val%n ! ! "same red circlemarker5"
+
+delobjs *
+zone
+openppf clt100.ppf
+cp clt100 dum
+clop dum + clt100 - clt100 * clt100 / clt100
+n/plot clt100.val%n ! ! crossmarker5
+n/plot dum.val%n ! ! "same red circlemarker5"
+
+delobjs *
+zone
+openppf clh64.ppf
+openppf clt100.ppf
+clop clh64 - clt100
+n/plot clh64.val%n ! ! crossmarker5
+
+#---------------------- test ClRebin
+delobjs *
+zone
+openppf clh64.ppf
+cl2llcl clh64 llclh64
+clrebin llclh64 clntu 10,0
+
+n/plot clntu.n%l ! ! crossmarker5
+
+n/plot llclh64.val%n  ! ! "crossmarker3"
+n/plot clntu.clmean%l ! ! "same circlemarker5 red"
+n/plot clntu.cllin%l  ! ! "same boxmarker5 blue"
+n/plot clntu.clpar%l  ! ! "same trianglemarker5 darkviolet"
+
+n/plot llclh64.val%n  ! ! "crossmarker3"
+nt2d clntu l clmean 0 sclmean 1 " " "same circlemarker5 red thinline"
+
+n/plot llclh64.val%n  ! ! "crossmarker3"
+nt2d clntu l cllin 0 scllin 1 " " "same boxmarker5 blue thinline"
+
+n/plot llclh64.val%n  ! ! "crossmarker3"
+nt2d clntu l clpar 0 sclpar 1 " " "same trianglemarker5 darkviolet thinline"
+
+#---------------------- test CrMaskMap et SetTypeMap
+delobjs *
+zone
+settypemap h
+crmapmask h8m 256 -20,20 100,130 0,1
+savefits h8m !h8m.fits
+disp h8m zoom/4
+
+delobjs *
+zone
+settypemap t
+crmapmask t8m 400 -20,20 100,130 0,1
+saveppf t8m t8m.ppf
+disp t8m zoom/4
+
+#---------------------- test CrMaskFrMap
+delobjs *
+zone
+openfits h8.fits
+crmaskfrmap h8fm 256 h8 -1.e-30,1.e-30 0,1
+savefits h8fm !h8fm.fits
+disp h8fm zoom/4
+
+delobjs *
+zone
+openppf t8.ppf
+crmaskfrmap t8fm 400 t8 -1.e-30,1.e-30 0,1
+saveppf t8fm t8fm.ppf
+disp t8fm zoom/4
+
+#---------------------- test MaskMap
+delobjs *
+zone
+openfits h8.fits
+openfits h8m.fits
+maskmap h8 h8m
+disp h8 zoom/4
+
+delobjs *
+zone
+openppf t8.ppf
+openppf t8m.ppf
+maskmap t8 t8m
+disp t8 zoom/4
+
+delobjs *
+zone
+openfits h8.fits
+openppf t8m.ppf
+maskmap h8 t8m
+disp h8 zoom/4
+
+delobjs *
+zone
+openppf t8.ppf
+openfits h8m.fits
+maskmap t8 h8m
+disp t8 zoom/4
+
+#---------------------- test MapCover
+delobjs *
+zone
+openfits h8m.fits
+mapcover h8m 0.9,1 couvh8m
+echo $couvh8m
+
+delobjs *
+zone
+openppf t8m.ppf
+mapcover t8m 0.9,1 couvt8m
+echo $couvt8m
+
+#---------------------- test Map2Local
+delobjs *
+zone
+openfits h8.fits
+map2local h8 h8loc 200,300 20,30 0,90 !
+disp h8loc
+map2local h8 h8loc 200,300 20,30 0,90 ! 45
+disp h8loc
+
+delobjs *
+zone
+openppf t8.ppf
+map2local t8 t8loc 200,300 20,30 0,90 !
+disp t8loc
+map2local t8 t8loc 200,300 20,30 0,90 ! 45
+disp t8loc
+
+#---------------------- test MapOper
+delobjs *
+zone
+openfits h8.fits
+cp h8 h8save
+mapop h8save + h8 - h8 * h8 / h8
+disp h8save zoom/4
+mapop h8save - h8
+disp h8save zoom/4
+
+delobjs *
+zone
+openppf t8.ppf
+cp t8 t8save
+mapop t8save + t8 - t8 * t8 / t8
+disp t8save zoom/4
+mapop t8save - t8
+disp t8save zoom/4
+
+delobjs *
+zone
+openfits h8.fits
+openppf t8.ppf
+mapop h8 - t8
+disp h8 zoom/4
+
+#---------------------- test MapStat
+delobjs *
+zone
+openfits h8.fits
+openfits h8fm.fits
+mapstat h8 !    mean sig
+echo mean=$mean sig=$sig
+mapstat h8 h8fm mean sig
+echo mean=$mean sig=$sig
+
+openppf t8.ppf
+openppf t8fm.ppf
+mapstat t8 !    mean sig
+echo mean=$mean sig=$sig
+mapstat t8 t8fm mean sig
+echo mean=$mean sig=$sig
+
+#---------------------- test ExpVal
+set x 1
+set y 2
+set z 3
+eval ! x +y +z
+eval ! $x +$y +$z
+eval r x +y +z
+ echo result is $r
+
+eval r 1e150
+ echo result is $r
+eval r 1e10
+ echo result is $r
+eval r 0
+ echo result is $r
+
+eval r sqrt(-1.)
+ echo $r
Index: /tags/V_Dec2002/SophyaPI/ProgPI/sopiamodule.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/ProgPI/sopiamodule.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/ProgPI/sopiamodule.cc	(revision 2309)
@@ -0,0 +1,331 @@
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream.h>
+#include <math.h>
+
+#include <typeinfo>
+
+#include <vector>
+#include <string>
+
+#include "piacmd.h"
+#include "nobjmgr.h"
+#include "pistdimgapp.h"
+#include "servnobjm.h"
+#include "tvector.h"
+#include "pitvmaad.h"
+#include "fftpserver.h"
+#include "bruit.h"
+#include "piscdrawwdg.h"
+#include "ctimer.h"
+
+#include "pidrawer.h"
+#include "nomgadapter.h"
+
+extern "C" {
+void sopiamodule_init();
+void sopiamodule_end();
+}
+
+void SophyaFFT(string& nom, string& nomout, string dopt);
+
+class sopiamoduleExecutor : public CmdExecutor {
+public:
+                sopiamoduleExecutor();
+  virtual       ~sopiamoduleExecutor();
+  virtual int   Execute(string& keyw, vector<string>& args, string& toks);
+};
+
+//  Classe pour trace de grille en projection spherique Mollweide 
+class MollweideGridDrawer : public PIDrawer {
+public:
+                    MollweideGridDrawer(int np, int nm, int nx, int ny);
+                    MollweideGridDrawer(int np, int nm, double x_larg=0., double x_0=0., 
+					double y_larg=0., double y_0=0.);
+  virtual           ~MollweideGridDrawer();
+  virtual void      Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax);
+  virtual void      UpdateLimits();
+
+protected:
+  double xlarg, x0;
+  double ylarg, y0;
+  int nbparall, nbmerid;
+  int nbpt;
+  bool fgrevtheta;
+};
+
+/* --Methode-- */
+MollweideGridDrawer::MollweideGridDrawer(int np, int nm, int nx, int ny)
+{
+  x0 = (double)nx/2.; 
+  y0 = (double)ny/2.;
+  xlarg = nx;  
+  ylarg = ny;
+  nbparall = np;
+  nbmerid = nm;
+  nbpt = ny/5;
+  if ((nbpt % 20) == 0) nbpt++;  
+  fgrevtheta = true;
+}
+
+/* --Methode-- */
+MollweideGridDrawer::MollweideGridDrawer(int np, int nm, double x_larg, double x_0, 
+					 double y_larg, double y_0)
+{
+  if (x_larg > 0.) {
+    xlarg = x_larg; x0 = x_0;
+  }
+  else {
+    xlarg = M_PI*2.;  x0 = M_PI;
+  }
+  if (y_larg > 0.) {
+    ylarg = y_larg; y0 = y_0;
+  }
+  else {
+    ylarg = M_PI;  y0 = 0.;
+  }
+  nbparall = np;
+  nbmerid = nm;
+  nbpt = 101;
+  fgrevtheta = false;
+}
+
+/* --Methode-- */
+MollweideGridDrawer::~MollweideGridDrawer()
+{
+}
+
+/* --Methode-- */
+void MollweideGridDrawer::Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax)
+{
+  PIGrCoord * xxl = new PIGrCoord[nbpt];
+  PIGrCoord * xxr = new PIGrCoord[nbpt];
+  PIGrCoord * yy = new PIGrCoord[nbpt];
+
+  char buff[64];
+
+  // Trace des paralleles
+  g->DrawLine(xmin, y0, xmax, y0);
+  g->DrawString(x0+xlarg/100, y0+ylarg/100, "0");
+
+  //  PIGrCoord asc, PIGrCoord desc;
+  int i,k;
+
+  int nkp = (nbparall-1)/2;
+  if (nkp > 0) {
+    double dy = 0.5*ylarg/(double)(nkp+1);
+    double dtd = 90./(double)(nkp+1);
+    for(k=1; k<=nkp; k++) {
+      double fx = sin(acos(2.*(double)k*dy/ylarg))*0.5;
+      double yc = k*dy+y0;
+      g->DrawLine(x0-fx*xlarg, yc, x0+fx*xlarg, yc); 
+      double ctd = (fgrevtheta) ? -dtd*k : dtd*k;
+      sprintf(buff, "%5.1f", ctd);
+      g->DrawString(x0, yc, buff);
+      g->DrawString(x0-0.3*xlarg, yc, buff);
+      g->DrawString(x0+0.25*xlarg, yc, buff);
+      yc = -k*dy+y0;
+      g->DrawLine(x0-fx*xlarg, yc, x0+fx*xlarg, yc); 
+      sprintf(buff, "%5.1f", -ctd);
+      g->DrawString(x0, yc, buff);
+      g->DrawString(x0-0.3*xlarg, yc, buff);
+      g->DrawString(x0+0.25*xlarg, yc, buff);
+    }
+  }
+
+  // Trace des meridiennes
+  g->DrawLine(x0, ymin, x0, ymax);
+
+  int nkm = (nbmerid-1)/2;
+  if (nkm < 1)  nkm = 1;
+  double dphi = M_PI/nkm;
+  double dpd = 180./(double)(nkm);
+  double dy = ylarg/(nbpt-1);
+  for(k=0; k<nkm; k++) {
+    double phi0 = k*dphi;
+    double dphimil = fabs(phi0-M_PI);
+    if (dphimil < 1.e-6)  continue;
+    for(i=0; i<nbpt; i++) {
+      double yc = (double)i*dy+y0-0.5*ylarg;
+      double fx = (2.*fabs(yc-y0)/ylarg <= 1.) ? 
+	sin(acos(2.*fabs(yc-y0)/ylarg)) * dphimil/M_PI * 0.5 : 0.;
+      yy[i] = yc;
+      xxl[i] = x0-fx*xlarg;
+      xxr[i] = x0+fx*xlarg;
+    }
+
+    g->DrawPolygon(xxl, yy, nbpt, false);
+    g->DrawPolygon(xxr, yy, nbpt, false);
+
+    if (k == 0)  continue;
+    for(i=-1; i<=1; i++) {
+      double yc = 0.20*i*ylarg+y0;
+      double fx = sin(acos(2.*fabs(yc-y0)/ylarg)) * dphimil/M_PI * 0.5;
+      double xc = x0-fx*xlarg;
+      sprintf(buff, "%4.1f", dpd*k);
+      g->DrawString(xc, yc, buff);
+      xc = x0+fx*xlarg;
+      sprintf(buff, "%4.1f", 360.-dpd*k);
+      g->DrawString(xc, yc, buff);
+    }
+  }
+
+  delete [] xxl;
+  delete [] xxr;
+  delete [] yy;
+}
+
+/* --Methode-- */
+void MollweideGridDrawer::UpdateLimits()
+{
+  SetLimits(x0-xlarg/2., x0+xlarg/2., y0-ylarg/2., y0+ylarg/2.);
+}
+
+/* --Methode-- */
+sopiamoduleExecutor::sopiamoduleExecutor()
+{
+
+PIACmd * mpiac;
+NamedObjMgr omg;
+mpiac = omg.GetImgApp()->CmdInterpreter();
+
+string hgrp = "SophyaCmd";
+string kw = "powerspec";
+string usage = "FFT on a vector -> Plots power spectrum ";
+usage += "\n Usage: fftp vecName vecFFT [graphic_att] ";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+kw = "mollgridsph";
+usage = "Creates a spherical coordinate grid in Molleweide projection ";
+usage += "\n Usage: mollgridsph NameSphericalMap [Nb_Parallel Nb_Meridien graphic_att] ";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+kw = "mollgrid";
+usage = "Creates a spherical coordinate grid in Molleweide projection ";
+usage += "\n Usage: mollgrid [Nb_Parallel Nb_Meridien graphic_att] ";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+
+}
+
+/* --Methode-- */
+sopiamoduleExecutor::~sopiamoduleExecutor()
+{
+}
+
+/* --Methode-- */
+int sopiamoduleExecutor::Execute(string& kw, vector<string>& tokens, string& toks)
+{
+
+if (kw == "powerspec") {
+  if (tokens.size() < 2) {
+    cout << "Usage: powerspec nameVec vecFFT [graphic_att]" << endl;
+    return(0);
+    }
+  if (tokens.size() < 3)  tokens.push_back((string)"n");
+  SophyaFFT(tokens[0], tokens[1], tokens[2]);
+  }
+ else if ( (kw == "mollgridsph") || (kw == "mollgrid") ) {
+   NamedObjMgr omg;
+   MollweideGridDrawer * mollgrid = NULL;
+   string dopt="";
+   if (kw == "mollgridsph") {
+     if (tokens.size() < 1) {
+       cout << "Usage: mollgridsph NameSphericalMap [Nb_Parallel Nb_Meridien graphic_att]"
+	    << endl;
+       return(0);
+     }
+     int np = 5;
+     int nm = 5;
+     dopt = "same,thinline";
+     if (tokens.size() > 1)  np = atoi(tokens[1].c_str());
+     if (tokens.size() > 2)  nm = atoi(tokens[2].c_str());
+     if (tokens.size() > 3)  dopt = tokens[3];
+     NObjMgrAdapter* obja = omg.GetObjAdapter(tokens[0]);
+     if (obja == NULL) {
+       cout << "mollgridsph Error , No object with name " << tokens[0] << endl; 
+       return(0);
+     }
+     P2DArrayAdapter* arr = obja->Get2DArray(dopt);
+     if (arr == NULL) {
+       cout << "mollgridsph Error , object has non 2DArrayAdapter - Not a spherical map "
+	    << endl;
+       return(0);       
+     }
+     int nx = arr->XSize();
+     int ny = arr->YSize();
+     delete arr;
+     mollgrid = new MollweideGridDrawer(np, nm, nx, ny);
+     cout << " mollgridsph: Creating MollweideGridDrawer() for object" << tokens[0] << endl;
+   }
+   else if (kw == "mollgrid") {
+     int np = 5;
+     int nm = 5;
+     if (tokens.size() > 0)  np = atoi(tokens[0].c_str());
+     if (tokens.size() > 1)  nm = atoi(tokens[1].c_str());
+     if (tokens.size() > 2)  dopt = tokens[2];
+     mollgrid = new MollweideGridDrawer(np, nm);
+     cout << " mollgrid: Creating MollweideGridDrawer(" << np << "," << nm << ")" << endl;
+   }
+
+   if (mollgrid == NULL) {
+     cout << "mollgridsph Error/BUG !!! mollgrid = NULL "  << endl; 
+     return(0);
+   }
+
+   int wrsid = 0;
+   //bool fgsr = true;
+   
+   string name = "mollgrid";
+   wrsid = omg.GetImgApp()->DispScDrawer(mollgrid, name, dopt); 
+ }
+
+return(0);
+
+}
+
+static sopiamoduleExecutor * piaerex = NULL;
+/* Nouvelle-Fonction */
+void sopiamodule_init()
+{
+// Fonction d'initialisation du module
+// Appele par le gestionnaire de modules de piapp (PIACmd::LoadModule())
+if (piaerex) delete piaerex;
+piaerex = new sopiamoduleExecutor;
+}
+
+/* Nouvelle-Fonction */
+void sopiamodule_end()
+{
+// Desactivation du module
+if (piaerex) delete piaerex;
+piaerex = NULL;
+}
+
+
+/* --Methode-- */
+void SophyaFFT(string& nom, string& nomout, string dopt)
+{
+Timer tm("powerspec");
+NamedObjMgr omg;
+AnyDataObj* obj=omg.GetObj(nom);
+if (obj == NULL) {
+  cout << "SophyaFFT() Error , Pas d'objet de nom " << nom << endl;
+  return;
+}
+
+Vector* vin = dynamic_cast<Vector *>(obj);
+if (vin == NULL) {
+  cout << "SophyaFFT() Error , Objet n'est pas un vecteur " <<  endl;
+  return;
+  }
+TVector< complex<double> > * vout = new TVector< complex<double> >  ;
+FFTPackServer ffts;
+cout << "SophyaFFT() - Computing FFT of vector size " << vin->NElts() << endl;
+ffts.FFTForward(*vin, *vout);
+// cout << " SophyaFFT - FFT done " << endl;
+ // tm.Split(" FFT done ");
+
+omg.AddObj(vout, nomout);
+omg.DisplayObj(nomout, dopt);
+return;
+
+}
Index: /tags/V_Dec2002/SophyaPI/ProgPI/usedlibs
===================================================================
--- /tags/V_Dec2002/SophyaPI/ProgPI/usedlibs	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/ProgPI/usedlibs	(revision 2309)
@@ -0,0 +1,9 @@
+TArray
+SysTools
+NTools
+SkyMap
+Samba
+SkyT
+FitsIOServer
+PI
+PIext
Index: /tags/V_Dec2002/SophyaPI/ProgPI/usedslibs
===================================================================
--- /tags/V_Dec2002/SophyaPI/ProgPI/usedslibs	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/ProgPI/usedslibs	(revision 2309)
@@ -0,0 +1,3 @@
+PI
+sophya
+extsophya
Index: /tags/V_Dec2002/SophyaPI/ProgPI/w2ps.cc
===================================================================
--- /tags/V_Dec2002/SophyaPI/ProgPI/w2ps.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaPI/ProgPI/w2ps.cc	(revision 2309)
@@ -0,0 +1,209 @@
+#include "machdefs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream.h>
+#include <math.h>
+
+#include <typeinfo>
+
+#include <vector>
+#include <string>
+
+#include "piacmd.h"
+#include "nobjmgr.h"
+#include "pistdimgapp.h"
+
+
+//  Module chargeable ds piapp - Commande de gestion de sortie PS
+
+//  Declaration de la fonction d'activation et de desactivation du module
+extern "C" {
+void W2PSModule_init();
+void W2PSModule_end();
+}
+
+
+//  Une classe commande-executor, permettant d'enregistrer de 
+//  nouvelles commandes a piapp
+class W2PSModuleExecutor : public CmdExecutor {
+public:
+                W2PSModuleExecutor();
+  virtual       ~W2PSModuleExecutor();
+  // Execute s'occupe de l'execution effective des commandes
+  virtual int   Execute(string& keyw, vector<string>& args, string& toks);
+protected:
+  string psfilename;
+  PSFile * mpsfile;
+};
+
+/* --Methode-- */
+W2PSModuleExecutor::W2PSModuleExecutor()
+{
+
+psfilename = "w2ps.ps";
+mpsfile = NULL;
+
+PIACmd * mpiac;
+NamedObjMgr omg;
+mpiac = omg.GetImgApp()->CmdInterpreter();
+
+// On enregistre deux nouvelles commandes 
+string hgrp = "Graphics";
+// commande w2pssetfilename
+string kw = "pssetfilename";
+string usage = "pssetfilename: Sets current PostScript file name\n" ;
+usage += "Usage: pssetfilename FileName ";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+// commande w2psgetfilename
+kw = "psgetfilename";
+usage = "psgetfilename: Prints current PostScript file name \n" ;
+usage += "Usage: psgetfilename ";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+// commande w2psclosefile
+kw = "psclosefile";
+usage = "psclosefile: close current postscript file \n" ;
+usage += "Usage: w2psclosefile ";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+// commande w2ps
+kw = "w2ps";
+usage = "w2ps: Current Window To PostScript \n" ;
+usage += "Usage: w2ps ";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+// commande w2eps
+kw = "w2eps";
+usage = "w2eps: Current Window To EncapsulatedPostScript \n" ;
+usage += "Usage: w2eps EPSFileName";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+// commande imagcmap2eps
+kw = "imagcmap2ps";
+usage = "w2ps: Current Image+ColorMap To PostScript \n" ;
+usage += "Usage: imagcmap2ps ";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+// commande imagcmap2eps
+kw = "imagcmap2eps";
+usage = "imagcmap2eps: Current Image+ColorMap To EncapsulatedPostScript \n" ;
+usage += "Usage: imagcmap2eps EPSFileName";
+mpiac->RegisterCommand(kw, usage, this, hgrp);
+}
+
+/* --Methode-- */
+W2PSModuleExecutor::~W2PSModuleExecutor()
+{
+  if(mpsfile) delete mpsfile;
+}
+
+/* --Methode-- */
+int W2PSModuleExecutor::Execute(string& kw, vector<string>& tokens, string&)
+{
+
+NamedObjMgr omg;
+if (kw == "pssetfilename") {
+  if (tokens.size() < 1) {
+    cout << "Usage: pssetfilename PSFileName" << endl;
+    return(0);
+    }
+  if (mpsfile) delete mpsfile;
+  mpsfile = NULL;
+  psfilename = tokens[0];
+}
+else if (kw == "psgetfilename") {
+  cout << " W2PS: PSFileName= " << psfilename << endl;
+}
+else if (kw == "psclosefile") {
+  if (mpsfile) { 
+    cout << "psclosefile: Closing file " << psfilename << endl; 
+    delete mpsfile;
+    mpsfile = NULL;
+    psfilename = "w2ps.ps";
+  }
+}
+else if ( (kw == "w2ps") || (kw == "w2eps") ) {
+  PIStdImgApp*  sapp = omg.GetImgApp();
+  if (sapp == NULL) {
+    cout << " W2PSModuleExecutor::Execute() No PIStdImgApp !" << endl;
+    return(0);
+  }
+  if (sapp->CurrentWindow() == NULL) {
+    cout << " W2PSModuleExecutor::Execute() No current window !" << endl;
+    return(0);
+  }
+  if (kw == "w2ps") {
+    if (mpsfile == NULL) 
+      mpsfile = new PSFile(psfilename.c_str(), PI_Portrait, PI_A4, 2., 2.);
+    sapp->CurrentWindow()->PSPrint(mpsfile,0,0);
+    cout << " w2ps: Current window to PS file " << psfilename << endl;
+  }
+  else if (kw == "w2eps") {
+    if (tokens.size() < 1) {
+      cout << "Usage: w2eps EPSFileName" << endl;
+      return(0);
+    }
+    PSFile epsfile(tokens[0].c_str());
+    sapp->CurrentWindow()->PSPrint(&epsfile,0,0);
+    cout << " w2eps: Current window to EPS file " << tokens[0] << endl;
+  }
+}
+else if ( (kw == "imagcmap2ps") || (kw == "imagcmap2eps") ) {
+  PIStdImgApp*  sapp = omg.GetImgApp();
+  if (sapp == NULL) {
+    cout << " W2PSModuleExecutor::Execute() No PIStdImgApp !" << endl;
+    return(0);
+  }
+  PIImage* curpimg = NULL;
+  if (sapp->CurrentBaseWdg()) 
+    curpimg = dynamic_cast<PIImage *>(sapp->CurrentBaseWdg());
+  if (curpimg == NULL) {
+    cout << " W2PSModuleExecutor::Execute() No current PIImage !" << endl;
+    return(0);
+  }
+  PSFile * cpsf = NULL;
+  PSFile * cepsf = NULL;
+  if (kw == "imagcmap2ps") {
+    if (mpsfile == NULL) 
+      mpsfile = new PSFile(psfilename.c_str(), PI_Portrait, PI_A4, 2., 2.);
+    cpsf = mpsfile;
+    cout << " imagcmap2ps: Current image+colormap to PS file " << psfilename << endl;
+  }
+  else if (kw == "imagcmap2eps") {
+    if (tokens.size() < 1) {
+      cout << "Usage: imagcmap2eps EPSFileName" << endl;
+      return(0);
+    }
+    cepsf = new PSFile(tokens[0].c_str());
+    cpsf = cepsf;
+    cout << " imagcmap2eps: Current image+colormap to EPS file " << tokens[0] << endl;
+  }
+  double sx, sy;
+  sx = curpimg->XSize();
+  sy = curpimg->YSize() + sapp->CMapVW()->YSize() + 10;
+  cpsf->NewPage(sx, sy, PI_Auto);
+  curpimg->PSPrint(cpsf, -curpimg->XPos(), -curpimg->YPos());
+  sapp->CMapVW()->PSPrint(cpsf, -(sapp->CMapVW()->XPos()), 			
+			  -(sapp->CMapVW()->YPos())+curpimg->YSize()+10,
+			  sx/(double)sapp->CMapVW()->XSize(), 1.);
+
+  if (cepsf) delete cepsf;
+}
+
+return(0);
+
+}
+
+static W2PSModuleExecutor * piaw2psex = NULL;
+/* Nouvelle-Fonction */
+void W2PSModule_init()
+{
+// Fonction d'initialisation du module
+// Appele par le gestionnaire de modules de piapp (PIACmd::LoadModule())
+if (piaw2psex) delete piaw2psex;
+piaw2psex = new W2PSModuleExecutor;
+}
+
+/* Nouvelle-Fonction */
+void W2PSModule_end()
+{
+// Desactivation du module
+if (piaw2psex) delete piaw2psex;
+piaw2psex = NULL;
+}
+
Index: /tags/V_Dec2002/SophyaProg/Examples/Makefile
===================================================================
--- /tags/V_Dec2002/SophyaProg/Examples/Makefile	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Examples/Makefile	(revision 2309)
@@ -0,0 +1,59 @@
+MODULECXXREPNAME := Tests
+MODULEDECCXXFLAGS := -msg_quiet
+include $(DPCDEVREP)/Include/Makefile.h
+
+
+ifdef NOSHLIB
+
+LIBF =  $(LIB)libSysTools.a $(LIB)libNTools.a $(LIB)libBlitz.a $(LIB)libFitsIOServer.a $(LIB)libPI.a $(LIB)libPIext.a 
+LIBS = -L$(LIB) -lPIext -lPI -lSysTools -lNTools -lBlitz  -lm
+#LIBS =  -L$(LIB) -lSysTools -lm
+ifeq ($(CXX),cxx)
+# librairie des instances de templates cxx
+LIBS := $(LIBS) -lrt
+endif
+
+else
+
+LIBF =  $(SLB)libsophya.so 
+LIBS = -L$(SLB) -lPI -lextsophya -lsophya -lm 
+ifeq ($(MACHEROS),OSF1)
+LIBS := $(LIBS) -lfor
+endif
+ifeq ($(MACHEROS),Linux)
+LIBS := $(LIBS) -ldl -lf2c
+endif
+
+endif
+
+LDLIBS := $(LIBS) $(LDLIBS) 
+
+%:%.cc
+%:%.o
+%.o:%.cc
+%.o:%.c
+%:%.c
+
+.PRECIOUS: $(EXE)% $(OBJ)%.o
+
+%:$(EXE)%
+	echo $@ " done"
+
+$(EXE)%:$(OBJ)%.o
+	$(LINK.cc)  -o $@ $< $(LIBS)
+
+$(OBJ)%.o:%.cc
+	$(COMPILE.cc)   $(USERFLAGS) -o $@ $<
+
+$(EXE)%:$(OBJ)%.cc
+	$(LINK.cc) $(USERFLAGS)  -o $@ $< $(LIBS) 
+
+$(EXE)%:$(OBJ)%.c
+	$(LINK.c)  $(USERFLAGS) -o $@ $< $(LIBS) 
+
+$(OBJ)%.o:%.c
+	$(COMPILE.c) -c $(CFLAGS) $(USERFLAGS) -o $@ $< 
+
+dump :
+	echo $(LIBS)
+
Index: /tags/V_Dec2002/SophyaProg/Examples/README
===================================================================
--- /tags/V_Dec2002/SophyaProg/Examples/README	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Examples/README	(revision 2309)
@@ -0,0 +1,49 @@
+#   Programmes exemple pour l'utilisation de Sophya
+
+On suppose que $DPCBASREP/`uname`-$EROSCXX/Exec est ds le path et 
+  .:$DPCBASREP/`uname`-$EROSCXX/ShLibs ds LD_LIBRARY_PATH 
+
+1) ex1.cc 
+   Un programme simple utilisant SOPHYA
+   
+
+2) arr1.icc 
+   Un bout de code C++ utilisant SOPHYA, pouvant etre execute
+   par runcxx :
+   csh> runcxx -f arr1.icc 
+   OU 
+   csh> runcxx -tmpdir /tmp arr1.icc
+
+3) fft.icc et myf_fft.icc
+   Exemple de code C++ utilisant les transforme de Fourier de SOPHYA,
+   pouvant etre execute ds spiapp.
+
+4) sphylm.icc sphylm.h
+   Exemple d'utilisation des cartes 4Pi (SphericalMaps) et des 
+   transforme en harmonique spherique pouvant etre execute ds spiapp.
+
+
+5) apc.icc apcxx.icc apcxx_cstyle.icc
+   Matrix and vector manipulation and Fourier filtering 
+   apc.icc : written as a C program
+   apcxx.icc : C++ code with SOPHYA arrays
+   apcxx_cstyle.icc : similar to apcxx.icc but with 
+        C_style programming (explicit loops) 
+
+   csh> spiapp   
+   (on peut definir la variable d'environnement TMPDIR avant l'appel
+    a spiapp )
+
+   Commandes a taper dans la fenetre de commande de (s)piapp :
+
+      Cmd> delobjs *
+      Cmd> c++execfrf fft.icc myf_fft.h
+      Cmd> delobjs *
+      Cmd> c++execfrf sphylm.icc sphylm.h
+
+6) arrwrt.icc , arrrd.icc
+   Creation/ecriture, lecture de tableaux ds fichiers PPF 
+   #  Pour ecrire le fichier arrt.ppf
+   csh> runcxx -f arrwrt.icc
+   #  Lecture du fichier arrt.ppf   
+   csh> runcxx -f arrrd.icc
Index: /tags/V_Dec2002/SophyaProg/Examples/apc.icc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Examples/apc.icc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Examples/apc.icc	(revision 2309)
@@ -0,0 +1,91 @@
+/*  ------------------ apc.icc -------------------
+
+   Example illustrating C programming for performing 
+   operations comparable to those performed in apcxx.icc
+
+                                   R. Ansari  08/2001
+ 
+   ---- Computation steps :
+    > Allocate an array representing a matrix (NL x NC )  (mtx)
+    > fill it with a gaussian distributed random values
+    > make a copy of the matrix   (mtxs)
+    > allocate and fill 1D filter in Fourier space 
+    > Loop over matrix rows k
+     >> Extract row k (fline)
+     >> compute 1D Fourier transform FFTForward (fline) 
+     >> apply filter in Fourier space
+     >> compute backward 1D FFT 
+     >> Replace matrix row with the filtered values
+   
+    > free the allocated memory
+   
+   this example code can be 
+     - included in a main program
+     - executed using runcxx 
+       csh> runcxx -tmpdir /tmp -f apc.icc
+     - executed within spiapp 
+       Cmd> c++execfrf apc.icc
+*/
+
+// Select computation on float or double (r_4 r_8)
+#define FTYP r_4
+
+// Number of matrix lines and colums
+int NL = 1024;
+int NC = 4096;
+int i,k;
+cout << " apc : NL= " << NL << " NC= " << NC << endl;
+PrtTim("apc_Start");
+
+// Creation of the initial matrix
+FTYP * mtx = new FTYP [NL*NC];
+// Filling matrix with gaussian random values
+for(i=0; i<NL*NC; i++) 
+  mtx[i] = 15.+NorRand()*3.;
+
+// Allocation of the copy matrix (mtxs)
+FTYP * mtxs = new FTYP [NL*NC];
+// copying mtxs to mtx 
+for(i=0; i<NL*NC; i++) 
+  mtxs[i] = mtx[i];
+
+// Creation and initialization of the Fourier filter filt(nu)
+FTYP * filt = new FTYP [NC];
+for(i=0; i<NC; i++) { 
+  filt[i] =  1.-i/(double)NC;
+  filt[i] *= filt[i]; 
+}
+
+
+// Creation of the FFTPackServer
+// We use this class to avoid to do the initialization steps needed to use fftpack.
+FFTPackServer ffts;
+ffts.setNormalize(true);
+
+PrtTim("apc_AfterInit");
+
+// Allocation of the matrix row memory  
+FTYP * fline = new FTYP [NC];
+
+//  Loop over matrix rows
+for(k=0; k<NL; k++) {
+  // Matrix row extraction 
+  for(i=0; i<NC; i++) fline[i] = mtx[k*NC+i];
+  // Compute 1D forward FFT
+  ffts.fftf(NC, fline);
+  // Applying filter in Fourier space f(nu) =  f(nu)*filter(nu)
+  for(i=0; i<NC; i++) fline[i] *= filt[i];
+  // backward FFT
+  ffts.fftb(NC, fline);
+  // replace matrix row with filtered values
+  for(i=0; i<NC; i++) mtx[k*NC+i] = fline[i];
+}
+
+PrtTim("apc_AfterFFTLoop");
+
+
+delete[] mtx;
+delete[] mtxs;
+delete[] fline;
+delete[] filt;
+
Index: /tags/V_Dec2002/SophyaProg/Examples/apcxx.icc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Examples/apcxx.icc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Examples/apcxx.icc	(revision 2309)
@@ -0,0 +1,80 @@
+/*  ----------------- apcxx.icc -------------------
+
+   Example illustrating C++ scientific programming 
+   using SOPHYA library arrays and FFT computation 
+   through FFTServerInterface.                         
+                                   R. Ansari  08/2001 
+   ---- Computation steps :
+    > Create a matrix (NL x NC )  (mtx)
+    > fill it with a gaussian distributed random values
+    > make a copy of the matrix   (mtxs)
+    > create a 1D filter in Fourier space 
+    > Loop over matrix rows k
+     >> Extract row k (fline)
+     >> compute 1D Fourier transform FFTForward (fline) 
+     >> apply filter in Fourier space
+     >> compute backward 1D FFT 
+     >> Replace matrix row with the filtered values
+   
+
+   this example code can be 
+     - included in a main program
+     - executed using runcxx 
+       csh> runcxx -tmpdir /tmp -f apcxx.icc
+     - executed within spiapp 
+       Cmd> c++execfrf apcxx.icc
+*/
+
+// Select computation on float or double (r_4 r_8)
+#define FTYP r_4
+
+// Number of matrix lines and colums
+int NL = 1024;
+int NC = 4096;
+cout << " apc_xx : NL= " << NL << " NC= " << NC << endl;
+PrtTim("apcxx_Start");
+
+// BaseArray::SetDefaultMemoryMapping(BaseArray::CMemoryMapping);
+// BaseArray::SetMaxPrint(10, 3);
+
+// Creation of the initial matrix
+TMatrix< FTYP > mtx(NL, NC), mtxs;
+// Filling matrix with gaussian random values
+mtx = RandomSequence(RandomSequence::Gaussian, 15., 3.);
+// Making a copy of the original matrix
+mtxs = mtx;
+
+// Creation and initialization of the Fourier filter filt(nu) = 1/(1+0.3*nu)
+int LFFT = NC/2+1;
+TVector< complex< FTYP > > filt(LFFT, BaseArray::RowVector);
+filt(0) = 1.;
+for(int i=1; i<filt.Size(); i++) 
+  filt(i) = 1./(1+0.3*(double)i);
+
+
+// Creation of the FFTServer
+FFTPackServer ffts;
+ffts.setNormalize(true);
+
+PrtTim("apcxx_AfterInit");
+
+// Vectors for FFT operations 
+TVector< FTYP > fline(NC, BaseArray::RowVector);
+TVector< complex< FTYP > > vfft;
+
+//  Loop over matrix rows
+for(int k=0; k<NL; k++) {
+  fline = mtx.Row(k);      // Matrix row extraction 
+  ffts.FFTForward(fline, vfft);    // Compute 1D forward FFT
+  // Applying filter in Fourier space f(nu) =  f(nu)*filter(nu)
+  vfft.MulElt(filt);             
+  ffts.FFTBackward(vfft, fline);   // backward FFT
+  mtx.Row(k) = fline;      // replace matrix row with filtered values
+ }
+
+PrtTim("apcxx_AfterFFTLoop");
+
+// Macro KeepObj can be used with runcxx or within (s)piapp 
+// KeepObj(mtx);
+// KeepObj(mtxs);
+
Index: /tags/V_Dec2002/SophyaProg/Examples/apcxx_cstyle.icc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Examples/apcxx_cstyle.icc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Examples/apcxx_cstyle.icc	(revision 2309)
@@ -0,0 +1,96 @@
+/*  --------------- apcxx_cstyle.icc -----------------
+
+   Example illustrating C++ scientific programming 
+   using SOPHYA library arrays and FFT computation 
+   through FFTServerInterface.   
+   This example, performs the same operations as in
+   apcxx.icc, through C-style programming with 
+   explicit loops. This C_style should be avoided when 
+   programming in C++.
+                      
+                                   R. Ansari  08/2001
+ 
+   ---- Computation steps :
+    > Create a matrix (NL x NC )  (mtx)
+    > fill it with a gaussian distributed random values
+    > make a copy of the matrix   (mtxs)
+    > create a 1D filter in Fourier space 
+    > Loop over matrix rows k
+     >> Extract row k (fline)
+     >> compute 1D Fourier transform FFTForward (fline) 
+     >> apply filter in Fourier space
+     >> compute backward 1D FFT 
+     >> Replace matrix row with the filtered values
+   
+
+   this example code can be 
+     - included in a main program
+     - executed using runcxx 
+       csh> runcxx -tmpdir /tmp -f apcxx_cstyle.icc
+     - executed within spiapp 
+       Cmd> c++execfrf apcxx_cstyle.icc
+*/
+
+// Select computation on float or double (r_4 r_8)
+#define FTYP r_4
+
+// Number of matrix lines and colums
+int NL = 1024;
+int NC = 4096;
+int i, j;
+cout << " apc_cstyle : NL= " << NL << " NC= " << NC << endl;
+PrtTim("apc_cstyle_Start");
+
+//BaseArray::SetDefaultMemoryMapping(BaseArray::CMemoryMapping);
+//BaseArray::SetMaxPrint(10, 3);
+
+
+// Creation of the initial matrix
+TMatrix< FTYP > mtx(NL, NC);
+// Filling matrix with gaussian random values
+// mtx = RandomSequence(RandomSequence::Gaussian, 15., 3.);
+for(i=0; i<NL; i++) 
+  for(j=0; j<NC; j++) mtx(i, j) = 15.+NorRand()*3.;
+
+// Making a copy of the original matrix
+//mtxs = mtx;
+TMatrix< FTYP > mtxs(NL, NC);
+for(i=0; i<NL; i++) 
+  for(j=0; j<NC; j++) mtxs(i, j) = mtx(i, j);
+
+
+// Creation and initialization of the Fourier filter filt(nu) = 1/(1+0.3*nu)
+int LFFT = NC/2+1;
+TVector< complex< FTYP > > filt(LFFT, BaseArray::RowVector);
+filt(0) = 1.;
+for(int i=1; i<filt.Size(); i++) 
+  filt(i) = 1./(1+0.3*(double)i);
+
+// Creation of the FFTServer
+FFTPackServer ffts;
+ffts.setNormalize(true);
+
+PrtTim("apc_cstyle_AfterInit");
+
+// Vectors for FFT operations 
+TVector< FTYP > fline(NC, BaseArray::RowVector);
+TVector< complex< FTYP > > vfft;
+
+for(int k=0; k<NL; k++) {
+  //  fline = mtx.Row(k);   Matrix row extraction 
+  for(j=0; j<NC; j++) fline(j) = mtx(k, j);
+  ffts.FFTForward(fline, vfft);   // Compute 1D forward FFT
+  // Applying filter in Fourier space f(nu) =  f(nu)*filter(nu)
+  //  vfft.MulElt(filt); 
+  for(j=0; j<LFFT; j++) vfft(j) *= filt(j);
+  ffts.FFTBackward(vfft, fline);  // backward FFT
+  //  mtx.Row(k) = fline;  // replace matrix row with filtered values
+  for(j=0; j<NC; j++) mtx(k, j) = fline(j);
+}
+
+PrtTim("apc_cstyle_AfterFFTLoop");
+
+// Macro KeepObj can be used with runcxx or within (s)piapp 
+// KeepObj(mtx);
+// KeepObj(mtxs);
+
Index: /tags/V_Dec2002/SophyaProg/Examples/arr1.icc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Examples/arr1.icc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Examples/arr1.icc	(revision 2309)
@@ -0,0 +1,28 @@
+// Fichier arr1.icc
+// Exemple d'utilisation de tableaux  
+// Appel: runcxx -f arr1.icc
+// Creation , remplissage d'une matrice
+  TMatrix<r_4> ma(7,9);
+  ma = RegularSequence(0.1, 0.05);   
+  cout << "\n arr1.icc: ma = " << ma << endl;
+  float min, max;
+// Utilisation des sous-tableaux
+  ma(Range(2,4), Range(4,7)) = M_PI;
+  cout << "\n Apres ma(Range(2,4), Range(4,7)) = " << ma << endl;
+// Appel de methodes
+  ma.MinMax(min, max);
+  cout << " MinMax(ma) : min= " << min << " max= " << max << endl;
+  TMatrix<r_4> sma = Sin(ma);
+  cout << "\n test pour runcxx - sma = Sin(ma)= " << sma << endl;
+  sma.MinMax(min, max);
+  cout << " MinMax(sma) : min= " << min << " max= " << max << endl;
+
+// Vector , matrix multiplication
+  Vector v1(5);
+  v1 = 12.;
+  Vector v2(5);
+  v2 = 14;
+  Matrix m = v2*v1.Transpose();
+  cout << " m= v2*v1.Transpose() : " << m;
+// Computing the scalar product   
+  cout << " v1.v2 = " << (v1.Transpose()*v2).toScalar() << endl;
Index: /tags/V_Dec2002/SophyaProg/Examples/arrrd.icc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Examples/arrrd.icc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Examples/arrrd.icc	(revision 2309)
@@ -0,0 +1,12 @@
+  cout << " >>>>>>> Reading from  arrt.ppf  <<<<< " << endl;
+  PInPersist pis("arrt.ppf");
+  TArray<int_4> iaa, ibb, icc;
+  // We read the three arrays from the stream
+  pis >> iaa >> ibb >> icc;
+  cout << " ----- Array IAA = \n " << iaa << endl;
+  cout << " ----- Array IBB = \n " << ibb << endl;
+  cout << " ----- Array ICC = \n " << icc << endl;
+  icc = 12;
+  cout << " ----- Array ICC (=12) = \n " << icc << endl;
+  cout << " ----- Array IAA (ICC=12) = \n " << iaa << endl;
+
Index: /tags/V_Dec2002/SophyaProg/Examples/arrwrt.icc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Examples/arrwrt.icc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Examples/arrwrt.icc	(revision 2309)
@@ -0,0 +1,21 @@
+  // We create a integer array SizeX=7, SizeY=5
+  TArray<int_4> ia(7,5);
+  // We fill it with a sequence of numbers starting at 10., with step = 2.
+  ia = RegularSequence(10., 2.);
+  cout << " ----- Array IA = \n " << ia << endl;
+  TArray<int_4> ib = ia(Range(0,3), Range(3,4), Range(0));
+  cout << " ----- Array IB IA(Range(0,3), Range(3,2)) = \n" << ib << endl;
+  // sub array extraction, Range(2,4) : starting position=2 , End=4
+  TArray<int_4> ic = ia(Range(2,3),Range(1,3),Range(0));
+  cout << " ----- Array IC IA(Range(2,3),Range(1,3)) = \n " << ic << endl;
+  // we set the sub-array to zero, this should reflect in the original array
+  // sub-arrays share their data with parent array
+  ic = 0;
+  cout << " ----- Array IC Apres (=0) = \n " << ic << endl;
+  cout << " ----- Array IB Apres IC=0 = \n " << ib << endl;
+  cout << " ----- Array IA Apres IC=0 = \n " << ia << endl;
+  cout << " >>>>>> Writing in  arrt.ppf <<<<<<< " << endl;
+  POutPersist pos("arrt.ppf");
+  // We write  the three arrays in the stream
+  pos << ia << ib << ic;
+
Index: /tags/V_Dec2002/SophyaProg/Examples/auto_makefile
===================================================================
--- /tags/V_Dec2002/SophyaProg/Examples/auto_makefile	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Examples/auto_makefile	(revision 2309)
@@ -0,0 +1,53 @@
+#  ------------------ SOPHYA -------------------------
+#    Makefile fot compiling and linking a simple C++ 
+#         program with SOPHYA class library 
+#  ---------------------------------------------------
+#  GNU make program should be used with this makefile
+#  ---------------------------------------------------
+#  Usage: make prog_name
+#     - compiles prog_name.cc -> prog_name.o 
+#     - links prog_name.o -> prog_name 
+
+#   SOPHYA compilation rules - OPTFLAG and DBGFLAG 
+# can be used to define Debug and optimization flags
+# Additional options can be specified using USERFLAGS
+# USERFLAGS := -I/.../myincludes 
+
+include $(DPCBASEREP)/Include/MakefileUser.h
+
+
+# ----- List of SOPHYA libraries 
+ifdef NOSHLIB
+LIBF =  $(LIB)libLinAlg.a $(LIB)libIFFTW.a $(LIB)libFitsIOServer.a $(LIB)libSamba.a $(LIB)libSkyMap.a $(LIB)libSkyT.a $(LIB)libNTools.a $(LIB)libHiStats.a $(LIB)libTArray.a $(LIB)libSysTools.a
+LIBS = -L$(LIB) -lLinAlg -lIFFTW -lFitsIOServer -lSamba -lSkyMap -lSkyT -lNTools -lHiStats -lTArray -lSysTools -lm
+ifeq ($(CXX),cxx)
+# librairie des instances de templates cxx
+LIBS := $(LIBS) -lsotcxx
+endif
+else
+LIBF =  $(SLB)libsophya.so $(SLB)libextsophya.so
+LIBS = -L$(SLB) -lextsophya -lsophya  -lm
+endif
+
+LDLIBS := $(LIBS) $(LDLIBS) 
+
+%:%.cc
+%:%.o
+%.o:%.cc
+%.o:%.c
+%:%.c
+
+.PRECIOUS: % %.o
+
+
+#  --- Compilation and linking rules
+%:%.o
+	$(LINK.cc)  -o $@ $< $(LIBS)
+
+%.o:%.cc
+	$(COMPILE.cc)   $(USERFLAGS) -o $@ $<
+
+%:%.c
+	$(LINK.c)  $(USERFLAGS) -o $@ $< $(LIBS) 
+
+
Index: /tags/V_Dec2002/SophyaProg/Examples/ex1.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Examples/ex1.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Examples/ex1.cc	(revision 2309)
@@ -0,0 +1,77 @@
+#include "dvlist.h"
+#include "ndatablock.h"
+#include "fiondblock.h"
+#include "sophyainit.h"
+
+
+int main(int narg, char* arg[])
+{
+
+  // We handle exception at the high level
+  try {
+  // This macro initialize the library
+  // static objects handle this - However, not all loader call
+  // the constructor for static objects
+  SophyaInit();
+
+  // using a DVList object
+  cout << " Creating and using DVList and NDataBlock<T> " << endl;
+  DVList dvl;
+  dvl["A"] = 12;
+  dvl["bs"] = "hello";
+
+  // Using a datablock object with 66 integers
+  NDataBlock<int_4> idb(66);
+  // We initialize all values with the value 15
+  idb = 15;
+
+  // Using a datablock object with 40 float
+  NDataBlock<r_4> rdb(40);
+  // We initialize all values with the value 3.14
+  rdb = 3.14;
+
+  // Writing (serialiazing) objects into POutPersist streams
+  cout << " Writing objects in POutPersist streams " << endl;
+      {  
+      POutPersist so1("t11.ppf");
+      so1 << dvl;
+      POutPersist so2("t12.ppf");
+      string nom = "idb";
+      so2.PutObject(idb, nom);
+      nom = "rdb";
+      so2.PutObject(rdb, nom);
+      }
+
+  // Reading objects from PInPersist streams
+  cout << " reading objects from PInPersist streams " << endl;
+      {
+      PInPersist si1("t11.ppf");
+      DVList dvlr;
+      si1 >> dvlr;
+      cout << dvlr;     // Print on the standard output
+      PInPersist si2("t12.ppf");
+      string nom = "rdb";
+      NDataBlock<r_4> rrdb;
+      si2.GetObject(rrdb, nom);
+      cout << rrdb;     // Print on the standard output
+      NDataBlock<int_4> ridb;
+      nom = "idb";
+      si2.GetObject(ridb, nom);
+      cout << ridb;     // Print on the standard output
+      si2.GetObject(ridb, nom);      
+      }
+
+  // Opening an non existing file for reading generates an exception
+  cout << " Generating an exception ... " << endl;
+  PInPersist si("zz.zz");
+
+  }
+  catch (PThrowable & exc) {
+    cerr << " Catched Exception " << (string)typeid(exc).name() 
+	 << " - Msg= " << exc.Msg() << endl;
+  }
+  catch (...) {
+    cerr << " some other exception was caught ! " << endl;
+  }
+}
+
Index: /tags/V_Dec2002/SophyaProg/Examples/ex_makefile
===================================================================
--- /tags/V_Dec2002/SophyaProg/Examples/ex_makefile	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Examples/ex_makefile	(revision 2309)
@@ -0,0 +1,63 @@
+#  ------------------ SOPHYA -------------------------
+#    Makefile fot compiling and linking a simple C++ 
+#         program with SOPHYA class library 
+#  ---------------------------------------------------
+#  GNU make program should be used with this makefile
+#  ---------------------------------------------------
+#  Usage: make 
+#     - compiles ex1.cc -> Objs/ex1.o 
+#     - links Objs/ex1.o -> Objs/ex1 
+#         make depend
+#         to create the Objs/ directory
+
+#   SOPHYA compilation rules - OPTFLAG and DBGFLAG 
+# can be used to define Debug and optimization flags
+# Additional options can be specified using USERFLAGS
+# USERFLAGS := -I/.../myincludes 
+
+include $(DPCBASEREP)/Include/MakefileUser.h
+
+
+# ----- List of SOPHYA libraries 
+ifdef NOSHLIB
+LIBF =  $(LIB)libLinAlg.a $(LIB)libIFFTW.a $(LIB)libFitsIOServer.a $(LIB)libSamba.a $(LIB)libSkyMap.a $(LIB)libSkyT.a $(LIB)libNTools.a $(LIB)libHiStats.a $(LIB)libTArray.a $(LIB)libSysTools.a
+LIBS = -L$(LIB) -lLinAlg -lIFFTW -lFitsIOServer -lSamba -lSkyMap -lSkyT -lNTools -lHiStats -lTArray -lSysTools -lm
+ifeq ($(CXX),cxx)
+# librairie des instances de templates cxx
+LIBS := $(LIBS) -lsotcxx
+endif
+else
+LIBF =  $(SLB)libsophya.so $(SLB)libextsophya.so
+LIBS = -L$(SLB) -lextsophya -lsophya  -lm
+endif
+
+LDLIBS := $(LIBS) $(LDLIBS) 
+
+#  Object and executable files will be put in 
+MYOBJS := Objs/
+
+#  --- Compilation and linking rules
+$(MYOBJS)%.o:%.cc
+	$(COMPILE.cc)   $(USERFLAGS) -o $@ $<
+
+$(MYOBJS)%:%.c
+	$(COMPILE.c)  $(USERFLAGS) -o $@ $< 
+
+
+#  list of default build target
+all : depend $(MYOBJS)ex1
+
+#  Clean procedure
+clean : 
+	rm -f $(MYOBJS)ex1 $(MYOBJS)ex1.o
+#  Directory buid procedure
+depend :
+	if (test ! -d $(MYOBJS) ) then mkdir $(MYOBJS) ; fi
+
+#  build rules for ex1
+$(MYOBJS)ex1 : $(MYOBJS)ex1.o
+	$(LINK.cc) $^ $(LIBS) -o $@
+$(MYOBJS)ex1.o : ex1.cc
+
+
+
Index: /tags/V_Dec2002/SophyaProg/Examples/fft.icc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Examples/fft.icc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Examples/fft.icc	(revision 2309)
@@ -0,0 +1,20 @@
+TVector<r_8> in(4048);
+TVector<r_8> noise(4048);
+TVector< complex<r_8> > out;
+in = RegularSequence(0., 0.05);
+noise = RandomSequence(RandomSequence::Gaussian, 0., 4.);
+MathArray<r_8> ma;
+ma.ApplyFunctionInPlace(in, myf);
+in += noise;
+FFTPackServer FFTServ;
+cout << " Calling FFT " << endl;
+FFTServ.FFTForward(in, out); 
+ExecuteCommand("zone 1 2");
+KeepObj(in);
+DisplayObj(in, "");
+// KeepObj(out);
+DisplayObj(out, "red");
+
+
+
+
Index: /tags/V_Dec2002/SophyaProg/Examples/myf_fft.h
===================================================================
--- /tags/V_Dec2002/SophyaProg/Examples/myf_fft.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Examples/myf_fft.h	(revision 2309)
@@ -0,0 +1,7 @@
+inline double myf(double x)
+{
+return(3*sin(0.2*x)+4*cos(x)+5*sin(4*x+0.25) +3.5*cos(9*x+0.45) + 0.05*x);
+}
+
+
+
Index: /tags/V_Dec2002/SophyaProg/Examples/sphylm.h
===================================================================
--- /tags/V_Dec2002/SophyaProg/Examples/sphylm.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Examples/sphylm.h	(revision 2309)
@@ -0,0 +1,2 @@
+#include "skymap.h"
+#include "samba.h"
Index: /tags/V_Dec2002/SophyaProg/Examples/sphylm.icc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Examples/sphylm.icc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Examples/sphylm.icc	(revision 2309)
@@ -0,0 +1,46 @@
+// Generate input spectra  a + b* l + c * gaussienne(l, 50, 20)
+int lmax = 92;
+Vector clin(lmax);
+for(int l=0; l<lmax; l++) {
+  double xx = (l-50.)/10.;
+  clin(l) = 1.e-2 -1.e-4*l + 0.1*exp(-xx*xx);
+}
+
+// Compute map from spectra
+SphericalTransformServer<r_8> ylmserver;
+int m = 128;  // HealPix pixelisation parameter
+SphereHEALPix<r_8> map(m);
+ylmserver.GenerateFromCl(map, m,  clin, 0.);
+// Compute power spectrum from map
+Vector clout = ylmserver.DecomposeToCl(map, lmax,  0.);
+
+// Copy the synthetised map
+SphereHEALPix<r_8> mapdip;
+mapdip = map;
+
+// Define the dipole direction
+double thetadipole = 1.2;
+double phidipole = 0.3;
+UnitVector vd(thetadipole, phidipole);
+UnitVector vc(thetadipole, phidipole);
+
+// Add a dipole component to the map
+for(int i=0; i<mapdip.NbPixels(); i++) {  // Boucle sur les pixels
+  double Thetar,Phir;
+  mapdip.PixThetaPhi(i,Thetar,Phir);  // direction du pixel      
+  vc.SetThetaPhi(Thetar,  Phir);      
+  mapdip(i) += 5.*vd.Psc(vc);  // Produit scalaire 
+}
+
+// Compute the new map power spectrum 
+Vector cldip = ylmserver.DecomposeToCl(mapdip, lmax,  0.);
+
+// Display objects (kept automatically through Display)
+ExecuteCommand("zone 1 2");
+DisplayObj(map, " ");
+DisplayObj(mapdip, " ");
+DisplayObj(clin, "win");
+DisplayObj(clout, "same,red,fcirclemarker5,defline");
+KeepObj(cldip);
+
+
Index: /tags/V_Dec2002/SophyaProg/Examples/tvm.icc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Examples/tvm.icc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Examples/tvm.icc	(revision 2309)
@@ -0,0 +1,7 @@
+Vector v1(5);
+v1 = 12.;
+Vector v2(5);
+v2 = 14;
+Matrix m = v2*v1.Transpose();
+cout << m;
+KeepObj(m);
Index: /tags/V_Dec2002/SophyaProg/PMixer/HowToUse
===================================================================
--- /tags/V_Dec2002/SophyaProg/PMixer/HowToUse	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PMixer/HowToUse	(revision 2309)
@@ -0,0 +1,53 @@
+#!/bin/csh
+if ($#argv < 2)  then
+  echo 'Usage: HowToUse NSide_HealPix OutFITSfile'
+  exit 1
+endif
+
+
+echo '    *************************************************************';
+echo '		creating spectral response powerlaw';
+echo '    *************************************************************';
+echo '  ' 
+set cmd = "tgrsr $1 .2,120,50,-0.7,100,600 200 pl.fits"
+echo ' ' 
+echo 'Executing' $cmd
+time $cmd
+
+echo '	*************************************************************';
+echo '		creating gaussian radiation spectra sky';
+echo '	*************************************************************';
+set cmd = "tgsky $1 0 140,30 gauss.fits"
+echo ' ' 
+echo 'Executing' $cmd
+time $cmd
+
+echo '	*************************************************************';
+echo '		creating cosine/sine radiation spectra  sky';
+echo '	*************************************************************';
+set cmd = "tgsky $1 2 12,7,9,10 cossin.fits"
+echo ' ' 
+echo 'Executing' $cmd
+time $cmd
+
+echo '	*************************************************************';
+echo '		creating noise radiation spectra sky';
+echo '	*************************************************************';
+set cmd = "tgsky $1 1 160,44 noise.fits"
+echo ' ' 
+echo 'Executing' $cmd
+time $cmd
+
+echo '	*************************************************************'
+echo '		calling skymixer'
+echo '	*************************************************************'
+set xx = "@SKYMIX  3  $1"
+echo $xx > test.d
+cat howto.d >> test.d
+
+set cmd = "skymixer test.d $2"
+echo ' ' 
+echo 'Executing' $cmd
+time $cmd
+
+
Index: /tags/V_Dec2002/SophyaProg/PMixer/Makefile
===================================================================
--- /tags/V_Dec2002/SophyaProg/PMixer/Makefile	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PMixer/Makefile	(revision 2309)
@@ -0,0 +1,348 @@
+MODULECXXREPNAME :=  PMixer
+include ../Mgr/Makefile.h
+ 
+ifdef NOSHLIB
+LIBF =  $(LIB)libFitsIOServer.a $(LIB)libSamba.a $(LIB)libSkyMap.a $(LIB)libSkyT.a $(LIB)libNTools.a $(LIB)libHiStats.a $(LIB)libTArray.a $(LIB)libSysTools.a 
+LIBS = -L$(LIB) -lFitsIOServer -lSamba -lSkyMap -lSkyT -lNTools -lHiStats -lTArray -lSysTools -lm
+ifeq ($(CXX),cxx)
+# librairie des instances de templates cxx
+LIBS := $(LIBS) -lertcxx
+endif
+else
+LIBF =  $(SLB)libsophya.so $(SLB)libextsophya.so
+LIBS = -L$(SLB) -lsophya -lextsophya  -lm
+endif
+LIBSORA := $(LIBS)
+ifdef ORACLE_HOME
+LIBSORA := -L$(LIB) -lDb++ $(LIBS) -lErosDb -L$(ORACLE_HOME)/lib -lclntsh
+endif
+LDLIBS := $(LIBS) $(LDLIBS)
+PROGS = $(EXE)skymixer $(EXE)extractRS $(EXE)tgrsr $(EXE)tgsky $(EXE)easyTest $(EXE)Sph2Sph
+ 
+all: $(PROGS)
+
+clean:
+	rm -f $(PROGS)
+	if [ -d $(OBJ)cxxrep_PMixer ] ; then cd $(OBJ)cxxrep_PMixer ; rm -f *.o ; fi
+
+skymixer: $(EXE)skymixer
+	
+$(EXE)skymixer: $(OBJ)skymixer.o
+	$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@ 
+  
+extractRS: $(EXE)extractRS
+	
+$(EXE)extractRS: $(OBJ)extractRS.o
+	$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@ 
+  
+tgrsr: $(EXE)tgrsr
+	
+$(EXE)tgrsr: $(OBJ)tgrsr.o
+	$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@ 
+  
+tgsky: $(EXE)tgsky
+	
+$(EXE)tgsky: $(OBJ)tgsky.o
+	$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@ 
+  
+easyTest: $(EXE)easyTest
+	
+$(EXE)easyTest: $(OBJ)easyTest.o
+	$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@ 
+  
+Sph2Sph: $(EXE)Sph2Sph
+	
+$(EXE)Sph2Sph: $(OBJ)Sph2Sph.o
+	$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@ 
+  
+$(OBJ)Sph2Sph.o: Sph2Sph.cc pmixer.h \
+ $(INC)machdefs.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)tvector.h \
+ $(INC)fioarr.h \
+ $(INC)vector3d.h \
+ $(INC)longlat.h \
+ $(INC)utilgeom.h \
+ $(INC)srandgen.h \
+ $(INC)timing.h \
+ $(INC)sambainit.h \
+ $(INC)skymapinit.h \
+ $(INC)sophyainit.h \
+ $(INC)ntoolsinit.h \
+ $(INC)tarrinit.h \
+ $(INC)datacards.h \
+ $(INC)ntuple.h \
+ $(INC)ntupintf.h \
+ $(INC)fiospherehealpix.h \
+ $(INC)sphericalmap.h \
+ $(INC)smathconst.h \
+ $(INC)pixelmap.h \
+ $(INC)spherepos.h \
+ $(INC)unitvector.h \
+ $(INC)spherehealpix.h \
+ $(INC)HEALPixUtils.h \
+ $(INC)fitsspherehealpix.h \
+ $(INC)fitsfile.h \
+ $(INC)fitstarray.h \
+ $(INC)cimage.h \
+ $(INC)radspecvector.h \
+ $(INC)radspec.h \
+ $(INC)specresp.h \
+ $(INC)blackbody.h \
+ $(INC)convtools.h \
+ $(INC)derivblackbody.h \
+ $(INC)nupower.h \
+ $(INC)squarefilt.h \
+ $(INC)trianglefilt.h \
+ $(INC)specrespvector.h \
+ $(INC)gaussfilt.h \
+ $(INC)bruit.h \
+ $(INC)mapoperation.h
+$(OBJ)easyTest.o: easyTest.cc $(INC)blackbody.h \
+ $(INC)radspec.h \
+ $(INC)machdefs.h \
+ $(INC)specresp.h \
+ $(INC)anydataobj.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)convtools.h \
+ $(INC)radspecvector.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)specrespvector.h \
+ $(INC)squarefilt.h \
+ $(INC)gaussfilt.h \
+ $(INC)trianglefilt.h
+$(OBJ)extractRS.o: extractRS.cc pmixer.h \
+ $(INC)machdefs.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)tvector.h \
+ $(INC)fioarr.h \
+ $(INC)vector3d.h \
+ $(INC)longlat.h \
+ $(INC)utilgeom.h \
+ $(INC)srandgen.h \
+ $(INC)timing.h \
+ $(INC)sambainit.h \
+ $(INC)skymapinit.h \
+ $(INC)sophyainit.h \
+ $(INC)ntoolsinit.h \
+ $(INC)tarrinit.h \
+ $(INC)datacards.h \
+ $(INC)ntuple.h \
+ $(INC)ntupintf.h \
+ $(INC)fiospherehealpix.h \
+ $(INC)sphericalmap.h \
+ $(INC)smathconst.h \
+ $(INC)pixelmap.h \
+ $(INC)spherepos.h \
+ $(INC)unitvector.h \
+ $(INC)spherehealpix.h \
+ $(INC)HEALPixUtils.h \
+ $(INC)fitsspherehealpix.h \
+ $(INC)fitsfile.h \
+ $(INC)fitstarray.h \
+ $(INC)cimage.h \
+ $(INC)radspecvector.h \
+ $(INC)radspec.h \
+ $(INC)specresp.h \
+ $(INC)blackbody.h \
+ $(INC)convtools.h \
+ $(INC)derivblackbody.h \
+ $(INC)nupower.h \
+ $(INC)squarefilt.h \
+ $(INC)trianglefilt.h \
+ $(INC)specrespvector.h \
+ $(INC)gaussfilt.h \
+ $(INC)bruit.h \
+ $(INC)mapoperation.h
+$(OBJ)skymixer.o: skymixer.cc pmixer.h \
+ $(INC)machdefs.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)tvector.h \
+ $(INC)fioarr.h \
+ $(INC)vector3d.h \
+ $(INC)longlat.h \
+ $(INC)utilgeom.h \
+ $(INC)srandgen.h \
+ $(INC)timing.h \
+ $(INC)sambainit.h \
+ $(INC)skymapinit.h \
+ $(INC)sophyainit.h \
+ $(INC)ntoolsinit.h \
+ $(INC)tarrinit.h \
+ $(INC)datacards.h \
+ $(INC)ntuple.h \
+ $(INC)ntupintf.h \
+ $(INC)fiospherehealpix.h \
+ $(INC)sphericalmap.h \
+ $(INC)smathconst.h \
+ $(INC)pixelmap.h \
+ $(INC)spherepos.h \
+ $(INC)unitvector.h \
+ $(INC)spherehealpix.h \
+ $(INC)HEALPixUtils.h \
+ $(INC)fitsspherehealpix.h \
+ $(INC)fitsfile.h \
+ $(INC)fitstarray.h \
+ $(INC)cimage.h \
+ $(INC)radspecvector.h \
+ $(INC)radspec.h \
+ $(INC)specresp.h \
+ $(INC)blackbody.h \
+ $(INC)convtools.h \
+ $(INC)derivblackbody.h \
+ $(INC)nupower.h \
+ $(INC)squarefilt.h \
+ $(INC)trianglefilt.h \
+ $(INC)specrespvector.h \
+ $(INC)gaussfilt.h \
+ $(INC)bruit.h \
+ $(INC)mapoperation.h
+$(OBJ)tgrsr.o: tgrsr.cc pmixer.h $(INC)machdefs.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)tvector.h \
+ $(INC)fioarr.h \
+ $(INC)vector3d.h \
+ $(INC)longlat.h \
+ $(INC)utilgeom.h \
+ $(INC)srandgen.h \
+ $(INC)timing.h \
+ $(INC)sambainit.h \
+ $(INC)skymapinit.h \
+ $(INC)sophyainit.h \
+ $(INC)ntoolsinit.h \
+ $(INC)tarrinit.h \
+ $(INC)datacards.h \
+ $(INC)ntuple.h \
+ $(INC)ntupintf.h \
+ $(INC)fiospherehealpix.h \
+ $(INC)sphericalmap.h \
+ $(INC)smathconst.h \
+ $(INC)pixelmap.h \
+ $(INC)spherepos.h \
+ $(INC)unitvector.h \
+ $(INC)spherehealpix.h \
+ $(INC)HEALPixUtils.h \
+ $(INC)fitsspherehealpix.h \
+ $(INC)fitsfile.h \
+ $(INC)fitstarray.h \
+ $(INC)cimage.h \
+ $(INC)radspecvector.h \
+ $(INC)radspec.h \
+ $(INC)specresp.h \
+ $(INC)blackbody.h \
+ $(INC)convtools.h \
+ $(INC)derivblackbody.h \
+ $(INC)nupower.h \
+ $(INC)squarefilt.h \
+ $(INC)trianglefilt.h \
+ $(INC)specrespvector.h \
+ $(INC)gaussfilt.h \
+ $(INC)bruit.h \
+ $(INC)mapoperation.h
+$(OBJ)tgsky.o: tgsky.cc pmixer.h $(INC)machdefs.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)tvector.h \
+ $(INC)fioarr.h \
+ $(INC)vector3d.h \
+ $(INC)longlat.h \
+ $(INC)utilgeom.h \
+ $(INC)srandgen.h \
+ $(INC)timing.h \
+ $(INC)sambainit.h \
+ $(INC)skymapinit.h \
+ $(INC)sophyainit.h \
+ $(INC)ntoolsinit.h \
+ $(INC)tarrinit.h \
+ $(INC)datacards.h \
+ $(INC)ntuple.h \
+ $(INC)ntupintf.h \
+ $(INC)fiospherehealpix.h \
+ $(INC)sphericalmap.h \
+ $(INC)smathconst.h \
+ $(INC)pixelmap.h \
+ $(INC)spherepos.h \
+ $(INC)unitvector.h \
+ $(INC)spherehealpix.h \
+ $(INC)HEALPixUtils.h \
+ $(INC)fitsspherehealpix.h \
+ $(INC)fitsfile.h \
+ $(INC)fitstarray.h \
+ $(INC)cimage.h \
+ $(INC)radspecvector.h \
+ $(INC)radspec.h \
+ $(INC)specresp.h \
+ $(INC)blackbody.h \
+ $(INC)convtools.h \
+ $(INC)derivblackbody.h \
+ $(INC)nupower.h \
+ $(INC)squarefilt.h \
+ $(INC)trianglefilt.h \
+ $(INC)specrespvector.h \
+ $(INC)gaussfilt.h \
+ $(INC)bruit.h \
+ $(INC)mapoperation.h
Index: /tags/V_Dec2002/SophyaProg/PMixer/RSextract.d
===================================================================
--- /tags/V_Dec2002/SophyaProg/PMixer/RSextract.d	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PMixer/RSextract.d	(revision 2309)
@@ -0,0 +1,88 @@
+#  EXT_RS  NbComponents  NSide_HealPix
+@EXT_RS  31 1024
+
+#  RD_EXT_PATH  PathForFITS   
+#  path for input Sky Component FITS files , from which the RadSpec
+#  will be extracted
+@RS_EXT_PATH /tmp_mnt/exp/planck/CartesRT/supertango/templates/
+
+#  ----    Sky map for different frequencies        ---------
+#  ----    From which will be extracted the radspectra   ----
+#  RADSPECMAPi FITSfilename freq(MHz)
+@RADSPECMAP1 	eran102_441_00015000mhz.fits
+@RADSPECMAP2 	eran102_441_00018884mhz.fits 
+@RADSPECMAP3 	eran102_441_00023773mhz.fits 
+@RADSPECMAP4	eran102_441_00029929mhz.fits 
+@RADSPECMAP5 	eran102_441_00037678mhz.fits 
+@RADSPECMAP6 	eran102_441_00047434mhz.fits 
+@RADSPECMAP7 	eran102_441_00059716mhz.fits 
+@RADSPECMAP8  	eran102_441_00075178mhz.fits 
+@RADSPECMAP9 	eran102_441_00094644mhz.fits 
+@RADSPECMAP10 	eran102_441_00119149mhz.fits 
+@RADSPECMAP11 	eran102_441_00150000mhz.fits
+@RADSPECMAP12 	eran102_441_00188839mhz.fits	
+@RADSPECMAP13 	eran102_441_00237734mhz.fits
+@RADSPECMAP14 	eran102_441_00299289mhz.fits 
+@RADSPECMAP15 	eran102_441_00376783mhz.fits
+@RADSPECMAP16 	eran102_441_00474342mhz.fits
+@RADSPECMAP17 	eran102_441_00597161mhz.fits
+@RADSPECMAP18 	eran102_441_00751781mhz.fits
+@RADSPECMAP19 	eran102_441_00946436mhz.fits
+@RADSPECMAP20 	eran102_441_01191492mhz.fits
+@RADSPECMAP21 	eran102_441_01500000mhz.fits	
+@RADSPECMAP22 	eran102_441_01888388mhz.fits	
+@RADSPECMAP23 	eran102_441_02377340mhz.fits
+@RADSPECMAP24 	eran102_441_02992893mhz.fits	
+@RADSPECMAP25 	eran102_441_03767830mhz.fits	
+@RADSPECMAP26 	eran102_441_04743416mhz.fits
+@RADSPECMAP27 	eran102_441_05971608mhz.fits	
+@RADSPECMAP28 	eran102_441_07517809mhz.fits	
+@RADSPECMAP29 	eran102_441_09464360mhz.fits
+@RADSPECMAP30 	eran102_441_11914924mhz.fits		
+@RADSPECMAP31 	eran102_441_15000000mhz.fits
+
+
+#  ----   Source point map for different frequencies        ---------
+#  ----    From which will be extracted the radspectra   ----
+#  SOURCEPTMAPi FITSfilename freq(MHz)
+@SOURCEPTMAP1 	eran102_441_00015000mhz.s_rare
+@SOURCEPTMAP2 	eran102_441_00018884mhz.s_rare
+@SOURCEPTMAP3 	eran102_441_00023773mhz.s_rare
+@SOURCEPTMAP4	eran102_441_00029929mhz.s_rare
+@SOURCEPTMAP5 	eran102_441_00037678mhz.s_rare
+@SOURCEPTMAP6 	eran102_441_00047434mhz.s_rare 
+@SOURCEPTMAP7 	eran102_441_00059716mhz.s_rare 	
+@SOURCEPTMAP8  	eran102_441_00075178mhz.s_rare 
+@SOURCEPTMAP9 	eran102_441_00094644mhz.s_rare 
+@SOURCEPTMAP10 	eran102_441_00119149mhz.s_rare
+@SOURCEPTMAP11 	eran102_441_00150000mhz.s_rare
+@SOURCEPTMAP12 	eran102_441_00188839mhz.s_rare	
+@SOURCEPTMAP13 	eran102_441_00237734mhz.s_rare
+@SOURCEPTMAP14 	eran102_441_00299289mhz.s_rare 
+@SOURCEPTMAP15 	eran102_441_00376783mhz.s_rare	
+@SOURCEPTMAP16 	eran102_441_00474342mhz.s_rare	
+@SOURCEPTMAP17 	eran102_441_00597161mhz.s_rare	
+@SOURCEPTMAP18 	eran102_441_00751781mhz.s_rare
+@SOURCEPTMAP19 	eran102_441_00946436mhz.s_rare
+@SOURCEPTMAP20 	eran102_441_01191492mhz.s_rare
+@SOURCEPTMAP21 	eran102_441_01500000mhz.s_rare
+@SOURCEPTMAP22 	eran102_441_01888388mhz.s_rare
+@SOURCEPTMAP23 	eran102_441_02377340mhz.s_rare
+@SOURCEPTMAP24 	eran102_441_02992893mhz.s_rare
+@SOURCEPTMAP25 	eran102_441_03767830mhz.s_rare
+@SOURCEPTMAP26 	eran102_441_04743416mhz.s_rare	
+@SOURCEPTMAP27 	eran102_441_05971608mhz.s_rare
+@SOURCEPTMAP28 	eran102_441_07517809mhz.s_rare
+@SOURCEPTMAP29 	eran102_441_09464360mhz.s_rare
+@SOURCEPTMAP30 	eran102_441_11914924mhz.s_rare		
+@SOURCEPTMAP31 	eran102_441_15000000mhz.s_rare
+
+
+# Filter definition now !!
+# define the detector (only one)
+@GAUSSFILTER 143 16 0.84 50. 300.
+
+#  ---- wanna print a lot of stuff..---------
+#  ----  let's try PRINTLEVEL 5          ----
+@PRINTLEVEL  5
+
Index: /tags/V_Dec2002/SophyaProg/PMixer/Sph2Sph.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/PMixer/Sph2Sph.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PMixer/Sph2Sph.cc	(revision 2309)
@@ -0,0 +1,60 @@
+#include "pmixer.h"
+
+/*!
+ * \ingroup PMixer
+ * \file Sph2Sph.cc
+ *\brief   \b PROGRAM    \b Sph2Sphr  <BR>
+ * From a map with a given Nside to another map with
+ * another Nside -> this program performs the translation
+ * from one to the other (and reverse)
+ */
+
+// -----------------------------------------------------------------
+static POutPersist * so = NULL;  // Debug PPFOut file
+
+// -------------------------------------------------------------------------
+//                             main program 
+// -------------------------------------------------------------------------
+int main(int narg, char * arg[])
+{
+  if ((narg < 4) || ((narg > 1) && (strcmp(arg[1], "-h") == 0) )) {
+    cout << "  Usage: Sph2Sph FITS_sphIn nside_out FITS_sphOut [PPF_sphOut]" << endl;
+    exit(0);
+  }
+  InitTim();
+  
+  so = NULL;
+  double moy,sig;
+  int hp_nside = 16;
+  SphereHEALPix<float> InSph(hp_nside);
+  FITS_SphereHEALPix<float> fios(&InSph);
+  fios.Read(arg[1],2);
+  
+  MeanSig(InSph.DataBlock(), moy, sig );
+  cout << "Number of Pixels (input)  ->" <<  InSph.NbPixels() << endl;
+  cout << "MeanSig of Input Map      ->" << moy << " " << sig << endl;
+
+  string nSide = arg[2];
+  int nsideOut = atof(nSide.c_str());
+  SphereHEALPix<float> outgs(nsideOut);
+  Sph2Sph(InSph,outgs);
+  // Saving the output map in FITS format 
+  FITS_SphereHEALPix<float> fios2(&outgs);
+  fios2.Write(arg[3]);
+
+  MeanSig(outgs.DataBlock(), moy, sig );
+  cout << "Number of Pixels (output) ->" <<  outgs.NbPixels() << endl;
+  cout << "MeanSig of Output Map     ->" << moy << " " << sig << endl;
+  
+  PrtTim("End of WriteFITS ");
+  // Saving the output map in PPF format 
+  if (narg > 4) {
+    POutPersist s(arg[4]); 
+    FIO_SphereHEALPix<float> fiog(&outgs) ;
+    fiog.Write(s);
+    cout << "Output Map (SphereHEALPix<float>) written to POutPersist file "  
+	 << (string)(arg[3]) << endl;
+    PrtTim("End of WritePPF ");
+  }
+  if (so) delete so;  //  Closing the debug ppf file 
+}
Index: /tags/V_Dec2002/SophyaProg/PMixer/easyTest.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/PMixer/easyTest.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PMixer/easyTest.cc	(revision 2309)
@@ -0,0 +1,189 @@
+#include <iostream.h>
+#include "blackbody.h"
+#include "radspecvector.h"
+#include "specrespvector.h"
+#include "tvector.h"
+#include "squarefilt.h"
+#include "gaussfilt.h"
+#include "trianglefilt.h"
+
+
+int
+main() 
+{ 
+//   PInPersist in("out");
+//   SR_ReadSelf(in);
+//   cout << " " << endl;
+
+  cout << "BlackBody!" << endl;
+  BlackBody myBB(2.73);
+  double freqmin =  230.;
+  double freqmax = 500;
+  double logIF = myBB.logIntegratedFlux(freqmin,freqmax);
+  double IF    = myBB.integratedFlux(freqmin,freqmax);
+  cout << "log   " << logIF << endl;
+  cout << "nolog " << IF    << endl;
+  cout << "min et max " << myBB.minFreq() << " :: " << myBB.maxFreq() << endl;
+  cout << "full integration no log  " << myBB.integratedFlux(freqmin,freqmax) << endl;
+  cout << "full integration log     " << myBB.logIntegratedFlux(freqmin,freqmax) << endl;
+  cout << "full integration no log nolimit " << myBB.integratedFlux() << endl;
+  cout << "full integration log  nolimit  " << myBB.logIntegratedFlux() << endl;
+
+  cout << "squareFilter " << endl;
+  SquareFilter mySF(200,600);
+  double logSF = mySF.logIntegratedSpect(freqmin,freqmax);
+  double SF    = mySF.IntegratedSpect(freqmin,freqmax);
+  cout << "log   " << logSF << endl;
+  cout << "nolog " << SF    << endl;
+  cout << "min et max " << mySF.minFreq() << " :: " << mySF.maxFreq() << endl;
+  cout << "full integration no log  " << mySF.IntegratedSpect(200,700) << endl;
+  cout << "full integration log     " << mySF.logIntegratedSpect(200,700) << endl;
+  cout << "full integration no log nolimit  " << mySF.IntegratedSpect() << endl;
+  cout << "full integration log  nolimit   " << mySF.logIntegratedSpect() << endl;
+
+
+  cout << "triangleFilter" << endl;
+  TriangleFilter myTF(200,500,120,40);
+  double logTF = myTF.logIntegratedSpect(10.,freqmax);
+  double TF    = myTF.IntegratedSpect(10.,freqmax);
+  cout << "log   " << logTF << endl;
+  cout << "nolog " << TF    << endl;
+  cout << "min et max " << myTF.minFreq() << " :: " << myTF.maxFreq() << endl;
+  cout << "full integration no log  " << myTF.IntegratedSpect() << endl;
+  cout << "full integration log     " << myTF.logIntegratedSpect() << endl;
+  
+  cout << "....Testing RadSpectraVec..." << endl;
+  int maxVal = 10;
+  Vector vecOfNu(maxVal);
+  Vector vecOfFDeNu(maxVal);
+  int i;
+  for (i=0; i<maxVal; i++)
+    {
+      vecOfNu(i) = (double)i+230.;
+      vecOfFDeNu(i) = 1.; //*(double)i+1;
+      cout << "entry values  " <<  vecOfNu(i) << " " << vecOfFDeNu(i) << endl;
+    }
+  freqmin = 200.;
+  freqmax = 259.;
+  RadSpectraVec myRSV(vecOfNu, vecOfFDeNu);
+  double RSV    = myRSV.integratedFlux(freqmin,freqmax);
+ 
+  double logRSV = myRSV.logIntegratedFlux(freqmin,freqmax);
+  cout << "nolog int " << RSV    << endl; 
+  cout << "log int   " << logRSV << endl;
+  cout << "min et max " << myRSV.minFreq() << " :: " << myRSV.maxFreq() << endl;
+  cout << "full integration no log  " << myRSV.integratedFlux() << endl;
+  cout << "full integration log     " << myRSV.logIntegratedFlux() << endl;
+
+  cout << "....Testing SpecRespVec..." << endl;
+  int SRVmaxVal = 100;
+  Vector vecOfNuRSV(SRVmaxVal);
+  Vector vecOfFDeNuRSV(SRVmaxVal);
+  for (i=0; i<SRVmaxVal; i++)
+    {
+      vecOfNuRSV(i) = (double)i+130.;
+      vecOfFDeNuRSV(i) = 10*(double)i+1;
+      //      cout << "entry values  " <<  vecOfNuRSV(i) << " " << vecOfFDeNuRSV(i) << endl;
+    }
+  freqmin = vecOfNuRSV(0);
+  freqmax = vecOfNuRSV(SRVmaxVal-1);
+  SpecRespVec mySRV(vecOfNuRSV, vecOfFDeNuRSV);
+
+// Test ecriture en PPF 
+  {
+  cout << " Writing mySRV (RadSpecVec to PPF " << endl;
+  POutPersist s("srvec.ppf");
+  s << mySRV;
+  }
+  {
+  cout << " Reading  mySRV from PPF " << endl;
+  PInPersist s("srvec.ppf");
+  SpecRespVec srv;
+  s >> srv;
+  cout << srv;
+  }
+
+  double SRV    = mySRV.IntegratedSpect(freqmin,freqmax);
+  double logSRV = mySRV.logIntegratedSpect(freqmin,freqmax);
+  cout << "nolog " << SRV    << endl; 
+  cout << "log   " << logSRV << endl;
+  cout << "min et max " << mySRV.minFreq() << " :: " << mySRV.maxFreq() << endl;
+  cout << "full integration no log " << mySRV.IntegratedSpect() << endl;
+  cout << "full integration log    " << mySRV.logIntegratedSpect() << endl;
+  
+  cout << "----------------------------------------------------" << endl;
+  cout << "...Testing filter and integrate !" << endl;
+
+  cout << " BBSF nolog " << myBB.filteredIntegratedFlux(mySF,200.,400.) << endl;
+  cout << " BBSF   log " << myBB.filteredLogIntFlux(mySF,200.,400.) << endl;
+  cout << "full integration no log  " << myBB.integratedFlux(200.,400.) << endl;
+  cout << "full integration log     " << myBB.logIntegratedFlux(200.,400.) << endl;
+  cout << "SF" << endl;
+  cout << "full integration no log  " << mySF.IntegratedSpect(200.,400.) << endl;
+  cout << "full integration log     " << mySF.logIntegratedSpect(200.,400.) << endl;
+
+  cout << " BBTF nolog " << myBB.filteredIntegratedFlux(myTF,200.,400.) << endl;
+  cout << " BBTF   log " << myBB.filteredLogIntFlux(myTF,200.,400.) << endl;
+  cout << "TF" << endl;
+  cout << "full integration no log  " << myTF.IntegratedSpect(200.,400.) << endl;
+  cout << "full integration log     " << myTF.logIntegratedSpect(200.,400.) << endl;
+
+  /*
+  cout << " SZSF nolog " << mySZ.filteredIntegratedFlux(mySF,30.,100.) << endl;
+  cout << " SZSF  log " << mySZ.filteredLogIntFlux(mySF,30.,100.) << endl;
+  cout << "full integration no log  " << mySZ.integratedFlux(30.,100.) << endl;
+  cout << "full integration log     " << mySZ.logIntegratedFlux(30.,100.) << endl;
+
+  cout << " SZTF nolog " << mySZ.filteredIntegratedFlux(myTF,30.,100.) << endl;
+  cout << " SZTF   log " << mySZ.filteredLogIntFlux(myTF,30.,100.) << endl;
+			   */
+  cout << "********" << endl;
+  double min, max;
+  min=232;
+  max=235;
+
+  cout << " RSVSF nolog " << myRSV.filteredIntegratedFlux(mySF,min,max) << endl;
+  cout << " RSVSF   log " << myRSV.filteredLogIntFlux(mySF,min,max) << endl;
+  cout << "full integration no log  " << myRSV.integratedFlux(230.,500.) << endl;
+  cout << "full integration log     " << myRSV.logIntegratedFlux(230.,500.) << endl;
+  cout << "full integration no log min max " << myRSV.integratedFlux(min,max) << endl;
+  cout << "full integration log  min max   " << myRSV.logIntegratedFlux(min,max) << endl;
+
+  cout << " RSVTF nolog " << myRSV.filteredIntegratedFlux(myTF,230.,500.) << endl;
+  cout << " RSVTF   log " << myRSV.filteredLogIntFlux(myTF,230.,500.) << endl;
+  
+//   cout << "New TESTS USING IOBJS!" << endl;
+//   POutPersist out("out");
+//   TriangleFilter* myTF2 = new TriangleFilter(10,200,20,40);
+//   SR_WriteSelf(myTF2,out);
+
+//   POutPersist outV("outV");
+//   cout << "check before anything" << vecOfNu.NElts()<< endl;
+//   SpecRespVec* mySRV2 = new SpecRespVec(vecOfNu, vecOfFDeNu);
+//   SR_WriteSelf(mySRV2,outV);
+  
+//   Vector myVec(10);
+//   myVec.ReSize(10);
+//   cout << myVec.NElts();
+//   return 1;
+
+  cout << "read and write things in file...ppersist!" << endl;
+  TriangleFilter myTF2(10,200,20,40);
+//   PInPersist inTF("outTF");
+//   myTF2.ReadSelf(inTF);
+
+  {  // Test IO PPF GaussianFilter
+  cout << " Writing  GaussianFilter gf(276., 39.6, 0.794, 27., 690.) to PPF " << endl;
+  GaussianFilter gf(276., 39.6, 0.794, 27., 690.);
+  POutPersist s("fgauss.ppf");
+  s << gf ;
+  }
+  {
+  cout << " Reading  GaussianFilter from PPF " << endl;
+  PInPersist s("fgauss.ppf");
+  GaussianFilter gf2;
+  s >> gf2;
+  cout << gf2 << endl;
+  }
+
+} 
Index: /tags/V_Dec2002/SophyaProg/PMixer/extractRS.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/PMixer/extractRS.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PMixer/extractRS.cc	(revision 2309)
@@ -0,0 +1,454 @@
+#include "pmixer.h"
+
+/*! \ingroup PMixer
+ *  \file extractRS.cc 
+ * \brief  \b PROGRAM \b extractRS  <BR>
+ * Program to create a map (SphereHEALPix) with point source
+ * from small map (matrix) and convolving their radiation spectrum
+ * RadSpectra
+ * with a given filter response SpectralResponse
+ */
+
+// -----------------------------------------------------------------
+// ------------- Function declaration ------------------------------
+int CheckCards(DataCards & dc, string & msg);
+char * BuildFITSFileName(string const & fname);
+SpectralResponse * getSpectralResponse(DataCards & dc);
+float ComputeFrequency(DataCards &,string&);
+
+// -----------------------------------------------------------------
+
+//  ----- Global (static) variables ------------
+static bool rdmap = false;    // true -> Read map first 
+static char mapPath[256];     // Path for input maps
+static int  hp_nside = 32;    // HealPix NSide
+static int  nskycomp = 0;     // Number of sky components
+static int  debuglev = 0;     // Debug Level
+static int  printlev = 0;     // Print Level
+static POutPersist * so = NULL;  // Debug PPFOut file
+
+// -------------------------------------------------------------------------
+//                             main program 
+// -------------------------------------------------------------------------
+int main(int narg, char * arg[])
+{
+  if ((narg < 3) || ((narg > 1) && (strcmp(arg[1], "-h") == 0) )) {
+    cout << "  Usage: extractRS parameterFile outputfitsnameformaps  [outppfname]" << endl;
+    exit(0);
+  }
+  
+  InitTim();
+  
+  string msg;
+  int rc = 0;
+  RadSpectra * es = NULL;
+  SpectralResponse * sr = NULL;
+  double moy, sig;
+  
+  DataCards dc;
+  so = NULL;
+  
+  try {
+    string dcard = arg[1];
+    cout << " Decoding parameters from file " << dcard << endl;
+    dc.ReadFile(dcard);
+    
+    rc = CheckCards(dc, msg);
+    if (rc) { 
+      cerr << " Error condition -> Rc= " << rc << endl;
+      cerr << " Msg= " << msg << endl;
+      return(rc);
+    }
+  }
+  catch (PException exc) {
+    msg = exc.Msg();
+    cerr << " !!!! extractRS/ Readcard - Catched exception - Msg= " << exc.Msg() << endl;
+    return(90);
+  }   
+  
+  
+  cout << " extractRS/Info : NComp = " <<  nskycomp << " SphereHEALPix_NSide= " << hp_nside << endl;
+  cout << "  ... MapPath = " << (string)mapPath << "  DebugLev= " << debuglev 
+       << "  PrintLev= " << printlev << endl;
+  
+
+  // We create an output persist file for writing debug objects
+  if (debuglev > 0) so = new POutPersist("extrRSdbg.ppf");
+  SphereHEALPix<float> SourceMap(hp_nside);
+  SphereHEALPix<float> OutputMap(hp_nside);
+  bool okout = true;
+  
+  try {
+    
+    //    FitsIoServer fios; // Our FITS IO Server
+    char * flnm, buff[90];
+    string key;
+    string key2;
+   
+    double K = 1.;
+    
+    // Loop over sky frequencies components
+    int maxOfSkyComp = nskycomp;
+    int nbOfPix;
+    int sk;
+    Vector freq(maxOfSkyComp);
+    TMatrix<float> spectrum;
+    TMatrix<float> fdenu; //par freq et par pixel
+    int nb_source;
+    TMatrix<float> rareSource; //par freq et par numero de source
+    
+    for(sk = 0; sk<maxOfSkyComp; sk++) 
+      {
+	TMatrix<float> ings;	
+	// Opening the file containing the map
+	cout << "-------------------" << endl;
+	cout << " Processing map's frequency component No " << sk+1 << endl;
+	sprintf(buff, "%d", sk+1);
+	key = (string)"RADSPECMAP" + buff;
+	
+	flnm = BuildFITSFileName(dc.SParam(key,0));
+	cout << " Reading Input FITS map " << (string)flnm << endl;
+	FITS_TArray<float> read_input(flnm); 
+	ings = (TArray<float>)read_input;
+
+	if (printlev > 2) 
+	  {
+	    double min = 9.e99;
+	    double max = -9.e99;
+	    for(int x=0;x<ings.NRows(); x++)
+	      {
+		for(int y=0;y<ings.NCols(); y++)
+		  {
+		    if(min>ings(x,y)) min = ings(x,y);
+		    if(max<ings(x,y)) max = ings(x,y);
+		  }
+	      }
+	    cout << "min and max values for input map" << min << " " << max << endl;
+	  }
+	// Computing the frequency according to the name of the file
+	freq(sk) =  ComputeFrequency(dc,key);
+	if (printlev > 2)  cout << "filling spectrum for freq = " << freq(sk) << endl;
+	
+	// Opening the file containing the point source
+	sprintf(buff, "%d", sk+1);
+	key2 = (string)"SOURCEPTMAP" + buff;
+	flnm = BuildFITSFileName(dc.SParam(key2,0));
+	const char* nameOfFile = flnm ;
+	if (printlev > 2) cout << " Reading Input FITS map " << nameOfFile << endl;
+	ifstream from(nameOfFile);
+	char ch;
+	string dum;
+	from >> nb_source >> dum;
+	if(sk==0) rareSource.ReSize(maxOfSkyComp,nb_source);
+	for (int ii=0; ii< nb_source; ii++)
+	  {
+	    double value = 0;
+	    from >> value;
+	    rareSource(sk,ii) = value*1.e-26; //for Jansky->W
+	  }
+	from.close();
+
+	nbOfPix = ings.NRows()*ings.NCols();
+	spectrum.ReSize(ings.NRows(),ings.NCols());
+	if(sk==0) fdenu.ReSize(maxOfSkyComp,nbOfPix);
+	int xy=0;
+	for(int x=0;x<ings.NRows(); x++)
+	  {
+	    for(int y=0;y<ings.NCols(); y++)
+	      {
+		spectrum(x,y) = ings(x,y)*1.e-26; //for Jansky->W
+		fdenu(sk,xy) = spectrum(x,y);  
+		xy += 1;
+	      }
+	  }
+	if (printlev > 2) 
+	  {
+	    MeanSig(spectrum.DataBlock(), moy, sig );
+	    cout << " MeanSig for spectrum  map - Mean= " << moy << " Sigma= " << sig << endl;
+	  }
+	
+	
+	K = dc.DParam(key, 1, 1.);
+	if (debuglev > 4) {  // Writing the input map to the outppf
+	  FIO_TArray<float> fiog;
+	  fiog.Write(*so, key);
+	}
+	
+	if(printlev>2) 
+	  {	
+	    sprintf(buff, "End of Proc. Comp. %d ", sk+1);
+	    cout << " --------------------------------------- \n" << endl;    
+	    PrtTim(buff);
+	  }
+      }   // End of sky component loop 
+    
+    // ---------------------------------------------------------------------
+    //      Integration in the detector band of the maps
+    // ---------------------------------------------------------------------
+    SpectralResponse* sr = NULL;
+    sr = getSpectralResponse(dc);
+  
+    if (printlev > 2)  cout  << "SpectralResponse!" << *sr << endl;
+    TVector<float> outCoeff(nbOfPix);
+
+    for(int pix=0;pix<nbOfPix;pix++)
+      {
+	Vector smallFDeNu(maxOfSkyComp);
+	for(sk = 0; sk<maxOfSkyComp; sk++) 
+	  {
+	    smallFDeNu(sk) =  fdenu(sk,pix);
+	  }
+	
+	RadSpectraVec radSV(freq,smallFDeNu);
+	if (printlev > 10)  cout << "RadiationSpectra" << radSV << endl;
+
+	outCoeff(pix) = radSV.filteredIntegratedFlux(*sr);
+      }
+    int i;    
+    for(i=0;i<OutputMap.NbPixels();i++)
+      {
+	float rndval = frand01();
+	if(rndval == 1) rndval = frand01();
+	int rndvalPix = rndval*OutputMap.NbPixels();
+	int outpix = rndval*nbOfPix; 
+	OutputMap(i) = outCoeff(outpix);
+      }
+
+    
+    // ---------------------------------------------------------------------
+    //      Integration in the detector band of the sources
+    // ---------------------------------------------------------------------
+    TVector<float> sourceCoeff(nb_source);
+    for(int nsource=0;nsource<nb_source;nsource++)
+      {
+	Vector SourceFDeNu(maxOfSkyComp);
+	for(sk = 0; sk<maxOfSkyComp; sk++) 
+	  {
+	    SourceFDeNu(sk) =  rareSource(sk,nsource);
+	  }
+	RadSpectraVec radSV_Source(freq,SourceFDeNu);
+	sourceCoeff(nsource) = radSV_Source.filteredIntegratedFlux(*sr);
+      }
+
+    for(i=0;i<nb_source;i++)
+      {
+	float rndval = frand01();
+	int outPix = rndval*OutputMap.NbPixels(); 
+	SourceMap(outPix) = sourceCoeff(i); 
+	OutputMap(outPix) = OutputMap(i)+ SourceMap(outPix);
+      }
+  }  
+  catch (PException exc) {
+    msg = exc.Msg();
+    cerr << " !!!! extractRS - Catched PException  - Msg= " << exc.Msg() << endl;
+    rc = 50;
+  }   
+  catch (PThrowable exc) {
+    msg = exc.Msg();
+    cerr << " !!!! extractRS - Catched PThrowable  - Msg= " << exc.Msg() << endl;
+    rc = 50;
+  }   
+  catch (...) {
+    cerr << " Une exception de type inconnue !!! " << endl;
+    exit(99);
+  }
+  
+  // Saving the output map in FITS format 
+  if (okout) 
+    {
+      //       {
+      // 	FitsIoServer fios;
+      // 	fios.save(SourceMap, arg[3]);
+      // 	double moy,sig;
+      // 	MeanSig(SourceMap.DataBlock(),moy,sig);
+      // 	cout << " MeanSig for Source Map - Mean= " << moy << " Sigma= " << sig << endl;
+      // 	cout << "Source Map (SphereHEALPix<float>) written to FITS file " 
+      // 	     << (string)(arg[3]) << endl;
+      //       }
+      {
+	 FITS_SphereHEALPix<float> fios2(OutputMap);
+	 fios2.Write(arg[2]);
+	 double moy,sig;
+	 MeanSig(OutputMap.DataBlock(),moy,sig);
+	 cout << " MeanSig for Output Map - Mean= " << moy << " Sigma= " << sig << endl;
+	 cout << "Output Map (SphereHEALPix<float>) written to FITS file " 
+	      << (string)(arg[2]) << endl;
+      }
+      if(printlev>2) PrtTim("End of WriteFITS ");
+      // Saving the output map in PPF format 
+      if (narg > 2) {
+	POutPersist s(arg[3]); 
+	FIO_SphereHEALPix<float> fiog(OutputMap);
+	fiog.Write(s);
+	cout << "Output Map (SphereHEALPix<float>) written to POutPersist file "  
+	     << (string)(arg[3]) << endl;
+	if(printlev>2) PrtTim("End of WritePPF ");
+      }
+    }
+  if (so) delete so;  //  Closing the debug ppf file 
+  return(rc);
+}
+
+
+
+/* Nouvelle-Fonction */
+int CheckCards(DataCards & dc, string & msg)
+  //   Function to check datacards
+{
+  rdmap = false;
+  mapPath[0] = '\0';
+  nskycomp = 0;
+  debuglev  = 0;
+  printlev = 0;
+  
+  int rc = 0;
+  string key, key2;
+  
+  //  Checking datacards
+  if (dc.NbParam("EXT_RS") < 2)   {
+     rc = 71; 
+     msg = "Invalid parameters  - Check @EXT_RS card ";
+     return(rc);
+  }
+  int kc;
+  char buff[256];
+  bool pb = false;
+  string key3;
+  int ncomp = 0;
+  ncomp = dc.IParam("EXT_RS", 0);
+  int nside = 32;
+  nside = dc.IParam("EXT_RS", 1);
+  
+  for(kc=0; kc<ncomp; kc++) 
+    {
+      key = "RS_EXT_PATH";
+      if (dc.NbParam(key) < 3)  strncpy(mapPath, dc.SParam(key, 0).c_str(), 255);
+      mapPath[255] = '\0';
+      sprintf(buff, "RADSPECMAP%d", kc+1);
+      key = buff;
+      
+      if (dc.NbParam(key) < 1) {   
+	msg = "Missing or invalid card : " + key;
+	pb = true;  break;
+      }
+    }
+  
+  //  Checking detection filter specification 
+
+  key = "GAUSSFILTER";
+  key2 = "FILTERFITSFILE";
+  if ( (dc.NbParam(key) < 5) && (dc.NbParam(key2) < 3)) { 
+    msg = "Missing card or parameters : Check @GAUSSFILTER or @FILTERFITSFILE";
+    rc = 73;  return(rc); 
+  }
+  
+  if (pb)  {
+    rc = 75;
+    return(75);
+  }
+  
+  
+  // Initialiazing parameters
+  rc = 0;
+  msg = "OK";
+  nskycomp = ncomp;
+  hp_nside = nside;
+  // Checking for PATH definition card
+  key = "RS_EXT_PATH";
+  if (dc.NbParam(key) < 3)  strncpy(mapPath, dc.SParam(key, 0).c_str(), 255);
+  mapPath[255] = '\0';
+  key = "DEBUGLEVEL";
+  debuglev =  dc.IParam(key, 0, 0);
+  key = "PRINTLEVEL";
+  printlev =  dc.IParam(key, 0, 0);
+  return(rc);
+}
+
+static char buff_flnm[1024];   // Mal protege !
+/* Nouvelle-Fonction */
+char* BuildFITSFileName(string const & fname)
+{
+if (mapPath[0] != '\0') sprintf(buff_flnm, "%s/%s", mapPath, fname.c_str());
+else sprintf(buff_flnm, "%s", fname.c_str());
+return(buff_flnm);
+}
+
+
+
+/* Nouvelle-Fonction */
+SpectralResponse * getSpectralResponse(DataCards & dc)
+{
+  SpectralResponse * filt = NULL;
+
+  string key = "FILTERFITSFILE";
+  string key2 = "GAUSSFILTER";
+  string ppfname = "filter";
+
+  if (dc.HasKey(key) ) {      // Reading FITS filter file
+    char ifnm[256];
+    strncpy(ifnm, dc.SParam(key, 1).c_str(), 255);
+    ifnm[255] = '\0';
+    TMatrix<float> mtx(2,10);
+    FITS_TArray<float> read_input(ifnm); 
+    mtx = (TMatrix<float>)read_input;
+
+    double numin = dc.DParam(key, 2, 1.);
+    double numax = dc.DParam(key, 3, 9999.);
+    Vector nu(mtx.NCols());
+    Vector fnu(mtx.NCols());
+    for(int k=0; k<mtx.NCols(); k++) {
+      nu(k) = mtx(0, k);
+      fnu(k) = mtx(1, k);
+    }
+  filt = new SpecRespVec(nu, fnu, numin, numax);
+  ppfname = key;
+  }
+  else if (dc.HasKey(key2) ) {   // creating GaussianFilter 
+    double nu0 = dc.DParam(key2, 0, 10.);
+    double s = dc.DParam(key2, 1, 1.);
+    double a = dc.DParam(key2, 2, 1.);
+    double numin = dc.DParam(key2, 3, 0.1);
+    double numax = dc.DParam(key2, 4, 9999);
+    filt = new GaussianFilter(nu0, s, a, numin, numax);
+    ppfname = key2;
+    }
+  if (filt == NULL) throw ParmError("datacard error ! No detection filter");
+  cout << " Filter decoded - Created " << endl;
+  cout << *filt << endl;
+
+// for debug
+  //  if (debuglev > 1)  SpectralResponse2Nt(*filt, *so, ppfname);
+  return(filt);
+}
+
+
+float ComputeFrequency(DataCards & dc,string& key)
+{
+  ofstream filename("temp_filename");
+  filename << dc.SParam(key,0) << '\n';
+  filename.close();
+  
+  ifstream fromtempfile("temp_filename");
+  char chtemp;
+  string temp_str;
+  int count = 0;
+  do { 
+    fromtempfile.get(chtemp);    
+    if(count> 12 && count < 20)
+      {
+	temp_str+= chtemp; 
+      }
+    count+=1;
+  } while(chtemp!='\n'); 
+  fromtempfile.close();
+  
+  ofstream filename2("temp_filename");
+  filename2 << temp_str << '\n';
+  filename2.close();
+  
+  int frequency;
+  ifstream fromtempfile2("temp_filename");
+  fromtempfile2 >> frequency;
+  fromtempfile2.close();
+  return ((float)frequency/1000.);
+}
Index: /tags/V_Dec2002/SophyaProg/PMixer/howto.d
===================================================================
--- /tags/V_Dec2002/SophyaProg/PMixer/howto.d	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PMixer/howto.d	(revision 2309)
@@ -0,0 +1,51 @@
+#  SKYMIX  NbComponents  NSide_HealPix
+SKYMIX  3  128
+
+# PDMTYPE should be checked if PDMTYPE==1, OTHERWISE 
+# NO CHECK IS PERFORMED
+# PDMTYPECHECK 1
+
+#  READMAP  FitsName
+#  To Read the already prepared (mixed) Output MAP from FITS file
+#  FitsName should be the complete path to the FITS file
+READMAP xxx.fits
+
+#  Defining the Detection filter pass - band
+#  GAUSSFILTER or FILTERFITSFILE  card
+#  GAUSSFILTER -> Gaussian filter
+#  FILTERFITSFILE -> Filter (nu, T(nu)) from FITS file
+#  GAUSSFILTER  Nu0 Sigma_Nu Tmax NuMin NuMax
+#  FILTERFITSFILE FileName NuMin NuMax
+#       FileName should be a complete path
+@GAUSSFILTER 143 12 0.84 50. 300.
+
+#  MAPPATH  PathForFITS   
+#  path for input Sky Component FITS files , and EmissionSpectra files 
+MAPPATH /data/opus/Rz/SOPHYA/
+
+
+#  ----        Sky components  ---------
+#      ----     HealPix maps   ----
+#  MAPFITSFILEi FITSfilename Normalisation
+@MAPFITSFILE1  gauss.fits  1.0 
+
+#      ---   Emission Spectra definition -----
+#   SPECTRAFITSFILEi  FITSfilename  Fmin Fmax 
+@SPECTRAFITSFILE1  pl.fits 100 600  
+
+#   Other possible definition of emission spectra
+#   BLACKBODYi  temperature
+#  The blackbody object returns flux in units of watt/m2/sr/hz
+#   We thus scale the map (x 1.e17) 
+@MAPFITSFILE2  cossin.fits  1.e17 
+@BLACKBODY2 2.726
+
+#   For power-law spectra  f = a ((nu-nu0)/dnu)^b)
+#   POWERLAWSPECTRAi  a nu0 dnu b Fmin Fmax
+@MAPFITSFILE3  noise.fits    0.1 
+@POWERLAWSPECTRA3 1. 150. 50. -0.5 100. 500.
+
+#  Define the Debug level
+@DEBUGLEVEL  0
+#  Define the Print level
+@PRINTLEVEL  5
Index: /tags/V_Dec2002/SophyaProg/PMixer/makefile_sunmpa
===================================================================
--- /tags/V_Dec2002/SophyaProg/PMixer/makefile_sunmpa	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PMixer/makefile_sunmpa	(revision 2309)
@@ -0,0 +1,316 @@
+MODULECXXREPNAME :=  PMixer
+include ../Mgr/Makefile.h
+ 
+LIBF =  $(LIB)libSysTools.a $(LIB)libNTools.a $(LIB)libSamba.a $(LIB)libSkyMap.a $(LIB)libSkyT.a $(LIB)libFitsIOServer.a
+LIBS = -L$(LIB) -lFitsIOServer -lSamba -lSkyMap -lSkyT -lNTools -lHiStats -lTArray -lSysTools  -L$(EXTLIBPATH) -lcfitsio -lxnet -lm
+LDLIBS := $(LIBS)
+
+PROGS = $(EXE)skymixer $(EXE)extractRS $(EXE)tgrsr $(EXE)tgsky $(EXE)easyTest
+ 
+all: $(PROGS)
+
+clean:
+	rm -f $(PROGS)
+	if [ -d $(OBJ)cxxrep_PMixer ] ; then cd $(OBJ)cxxrep_PMixer ; rm -f *.o ; fi
+
+skymixer: $(EXE)skymixer
+	
+$(EXE)skymixer: $(OBJ)skymixer.o
+	$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@ 
+  
+extractRS: $(EXE)extractRS
+	
+$(EXE)extractRS: $(OBJ)extractRS.o
+	$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@ 
+  
+tgrsr: $(EXE)tgrsr
+	
+$(EXE)tgrsr: $(OBJ)tgrsr.o
+	$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@ 
+  
+tgsky: $(EXE)tgsky
+	
+$(EXE)tgsky: $(OBJ)tgsky.o
+	$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@ 
+  
+easyTest: $(EXE)easyTest
+	
+$(EXE)easyTest: $(OBJ)easyTest.o
+	$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@ 
+  
+$(OBJ)easyTest.o: easyTest.cc $(INC)blackbody.h \
+ $(INC)radspec.h \
+ $(INC)machdefs.h \
+ $(INC)specresp.h \
+ $(INC)anydataobj.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)convtools.h \
+ $(INC)radspecvector.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)dvlist.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)specrespvector.h \
+ $(INC)squarefilt.h \
+ $(INC)gaussfilt.h \
+ $(INC)trianglefilt.h
+$(OBJ)extractRS.o: extractRS.cc pmixer.h \
+ $(INC)machdefs.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)tvector.h \
+ $(INC)fioarr.h \
+ $(INC)vector3d.h \
+ $(INC)longlat.h \
+ $(INC)utilgeom.h \
+ $(INC)srandgen.h \
+ $(INC)timing.h \
+ $(INC)sambainit.h \
+ $(INC)skymapinit.h \
+ $(INC)sophyainit.h \
+ $(INC)ntoolsinit.h \
+ $(INC)tarrinit.h \
+ $(INC)datacards.h \
+ $(INC)fitsioserver.h \
+ $(INC)skymap.h \
+ $(INC)spherethetaphi.h \
+ $(INC)sphericalmap.h \
+ $(INC)smathconst.h \
+ $(INC)pixelmap.h \
+ $(INC)spherepos.h \
+ $(INC)unitvector.h \
+ $(INC)spherehealpix.h \
+ $(INC)localmap.h \
+ $(INC)fiospherethetaphi.h \
+ $(INC)fiospherehealpix.h \
+ $(INC)fiolocalmap.h \
+ $(INC)ntuple.h \
+ $(INC)ntupintf.h \
+ $(INC)cimage.h \
+ $(INC)rzimage.h \
+ $(INC)rzvect.h \
+ $(INC)perrors.h \
+ $(INC)datatypes.h \
+ $(EXTINCPATH)FitsIO/fitsio.h \
+ $(EXTINCPATH)FitsIO/longnam.h \
+ $(INC)fitsspherehealpix.h \
+ $(INC)fitsfile.h \
+ $(INC)fitstarray.h \
+ $(INC)radspecvector.h \
+ $(INC)radspec.h \
+ $(INC)specresp.h \
+ $(INC)blackbody.h \
+ $(INC)convtools.h \
+ $(INC)derivblackbody.h \
+ $(INC)nupower.h \
+ $(INC)squarefilt.h \
+ $(INC)trianglefilt.h \
+ $(INC)specrespvector.h \
+ $(INC)gaussfilt.h \
+ $(INC)bruit.h \
+ $(INC)mapoperation.h
+$(OBJ)skymixer.o: skymixer.cc pmixer.h \
+ $(INC)machdefs.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)tvector.h \
+ $(INC)fioarr.h \
+ $(INC)vector3d.h \
+ $(INC)longlat.h \
+ $(INC)utilgeom.h \
+ $(INC)srandgen.h \
+ $(INC)timing.h \
+ $(INC)sambainit.h \
+ $(INC)skymapinit.h \
+ $(INC)sophyainit.h \
+ $(INC)ntoolsinit.h \
+ $(INC)tarrinit.h \
+ $(INC)datacards.h \
+ $(INC)fitsioserver.h \
+ $(INC)skymap.h \
+ $(INC)spherethetaphi.h \
+ $(INC)sphericalmap.h \
+ $(INC)smathconst.h \
+ $(INC)pixelmap.h \
+ $(INC)spherepos.h \
+ $(INC)unitvector.h \
+ $(INC)spherehealpix.h \
+ $(INC)localmap.h \
+ $(INC)fiospherethetaphi.h \
+ $(INC)fiospherehealpix.h \
+ $(INC)fiolocalmap.h \
+ $(INC)ntuple.h \
+ $(INC)ntupintf.h \
+ $(INC)cimage.h \
+ $(INC)rzimage.h \
+ $(INC)rzvect.h \
+ $(INC)perrors.h \
+ $(INC)datatypes.h \
+ $(EXTINCPATH)FitsIO/fitsio.h \
+ $(EXTINCPATH)FitsIO/longnam.h \
+ $(INC)fitsspherehealpix.h \
+ $(INC)fitsfile.h \
+ $(INC)fitstarray.h \
+ $(INC)radspecvector.h \
+ $(INC)radspec.h \
+ $(INC)specresp.h \
+ $(INC)blackbody.h \
+ $(INC)convtools.h \
+ $(INC)derivblackbody.h \
+ $(INC)nupower.h \
+ $(INC)squarefilt.h \
+ $(INC)trianglefilt.h \
+ $(INC)specrespvector.h \
+ $(INC)gaussfilt.h \
+ $(INC)bruit.h \
+ $(INC)mapoperation.h
+$(OBJ)tgrsr.o: tgrsr.cc pmixer.h $(INC)machdefs.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)tvector.h \
+ $(INC)fioarr.h \
+ $(INC)vector3d.h \
+ $(INC)longlat.h \
+ $(INC)utilgeom.h \
+ $(INC)srandgen.h \
+ $(INC)timing.h \
+ $(INC)sambainit.h \
+ $(INC)skymapinit.h \
+ $(INC)sophyainit.h \
+ $(INC)ntoolsinit.h \
+ $(INC)tarrinit.h \
+ $(INC)datacards.h \
+ $(INC)fitsioserver.h \
+ $(INC)skymap.h \
+ $(INC)spherethetaphi.h \
+ $(INC)sphericalmap.h \
+ $(INC)smathconst.h \
+ $(INC)pixelmap.h \
+ $(INC)spherepos.h \
+ $(INC)unitvector.h \
+ $(INC)spherehealpix.h \
+ $(INC)localmap.h \
+ $(INC)fiospherethetaphi.h \
+ $(INC)fiospherehealpix.h \
+ $(INC)fiolocalmap.h \
+ $(INC)ntuple.h \
+ $(INC)ntupintf.h \
+ $(INC)cimage.h \
+ $(INC)rzimage.h \
+ $(INC)rzvect.h \
+ $(INC)perrors.h \
+ $(INC)datatypes.h \
+ $(EXTINCPATH)FitsIO/fitsio.h \
+ $(EXTINCPATH)FitsIO/longnam.h \
+ $(INC)fitsspherehealpix.h \
+ $(INC)fitsfile.h \
+ $(INC)fitstarray.h \
+ $(INC)radspecvector.h \
+ $(INC)radspec.h \
+ $(INC)specresp.h \
+ $(INC)blackbody.h \
+ $(INC)convtools.h \
+ $(INC)derivblackbody.h \
+ $(INC)nupower.h \
+ $(INC)squarefilt.h \
+ $(INC)trianglefilt.h \
+ $(INC)specrespvector.h \
+ $(INC)gaussfilt.h \
+ $(INC)bruit.h \
+ $(INC)mapoperation.h
+$(OBJ)tgsky.o: tgsky.cc pmixer.h $(INC)machdefs.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)tvector.h \
+ $(INC)fioarr.h \
+ $(INC)vector3d.h \
+ $(INC)longlat.h \
+ $(INC)utilgeom.h \
+ $(INC)srandgen.h \
+ $(INC)timing.h \
+ $(INC)sambainit.h \
+ $(INC)skymapinit.h \
+ $(INC)sophyainit.h \
+ $(INC)ntoolsinit.h \
+ $(INC)tarrinit.h \
+ $(INC)datacards.h \
+ $(INC)fitsioserver.h \
+ $(INC)skymap.h \
+ $(INC)spherethetaphi.h \
+ $(INC)sphericalmap.h \
+ $(INC)smathconst.h \
+ $(INC)pixelmap.h \
+ $(INC)spherepos.h \
+ $(INC)unitvector.h \
+ $(INC)spherehealpix.h \
+ $(INC)localmap.h \
+ $(INC)fiospherethetaphi.h \
+ $(INC)fiospherehealpix.h \
+ $(INC)fiolocalmap.h \
+ $(INC)ntuple.h \
+ $(INC)ntupintf.h \
+ $(INC)cimage.h \
+ $(INC)rzimage.h \
+ $(INC)rzvect.h \
+ $(INC)perrors.h \
+ $(INC)datatypes.h \
+ $(EXTINCPATH)FitsIO/fitsio.h \
+ $(EXTINCPATH)FitsIO/longnam.h \
+ $(INC)fitsspherehealpix.h \
+ $(INC)fitsfile.h \
+ $(INC)fitstarray.h \
+ $(INC)radspecvector.h \
+ $(INC)radspec.h \
+ $(INC)specresp.h \
+ $(INC)blackbody.h \
+ $(INC)convtools.h \
+ $(INC)derivblackbody.h \
+ $(INC)nupower.h \
+ $(INC)squarefilt.h \
+ $(INC)trianglefilt.h \
+ $(INC)specrespvector.h \
+ $(INC)gaussfilt.h \
+ $(INC)bruit.h \
+ $(INC)mapoperation.h
Index: /tags/V_Dec2002/SophyaProg/PMixer/makeprog
===================================================================
--- /tags/V_Dec2002/SophyaProg/PMixer/makeprog	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PMixer/makeprog	(revision 2309)
@@ -0,0 +1,49 @@
+MODULECXXREPNAME := SkyT
+# MODULEDECCXXFLAGS := -msg_quiet
+include $(DPCDEVREP)/Include/Makefile.h
+
+ifdef NOSHLIB
+LIBF =  $(LIB)libFitsIOServer.a $(LIB)libSkyT.a $(LIB)libSamba.a $(LIB)libNTools.a $(LIB)libSysTools.a 
+LIBS = -L$(LIB) -lSkyT -lSamba -lNTools -lSysTools -lm
+ifeq ($(CXX),cxx)
+# librairie des instances de templates cxx
+LIBS := $(LIBS) -lertcxx
+endif
+else
+LIBF =  $(SLB)/libtools.so 
+LIBS = -L$(SLB) -ltools -lm 
+ifeq ($(MACHEROS),Linux)
+LIBS := $(LIBS) -ldl
+endif
+endif
+
+
+myexe = $(EXE)easyTest $(EXE)skymixer $(EXE)extractRS $(EXE)tgsky $(EXE)tgrsr 
+
+all : $(myexe)
+
+
+$(EXE)easyTest :  $(OBJ)easyTest.o 
+	$(LINK.cc)  $^ $(LIBS) -o $@
+
+$(EXE)skymixer :  $(OBJ)skymixer.o 
+	$(LINK.cc)  $^ $(LIBS) -o $@
+
+$(EXE)extractRS :  $(OBJ)extractRS.o 
+	$(LINK.cc)  $^ $(LIBS) -o $@
+
+$(EXE)tgsky :  $(OBJ)tgsky.o 
+	$(LINK.cc)  $^ $(LIBS) -o $@
+
+$(EXE)tgrsr :  $(OBJ)tgrsr.o 
+	$(LINK.cc)  $^ $(LIBS) -o $@
+
+$(OBJ)easyTest.o : easyTest.cc
+
+$(OBJ)tgsky.o : tgsky.cc
+
+$(OBJ)tgrsr.o : tgrsr.cc
+
+$(OBJ)skymixer.o : skymixer.cc
+
+$(OBJ)extractRS.o : extractRS.cc
Index: /tags/V_Dec2002/SophyaProg/PMixer/pmixer.h
===================================================================
--- /tags/V_Dec2002/SophyaProg/PMixer/pmixer.h	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PMixer/pmixer.h	(revision 2309)
@@ -0,0 +1,37 @@
+#include "machdefs.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <fstream.h>
+#include <iostream.h>
+#include <math.h>
+
+#include <string>
+#include <vector>
+
+#include "tmatrix.h"
+#include "tvector.h"
+#include "fioarr.h"
+#include "vector3d.h"
+#include "srandgen.h"
+#include "timing.h"
+#include "sambainit.h"
+#include "pexceptions.h"
+#include "datacards.h"
+#include "ntuple.h"
+#include "fiospherehealpix.h"
+#include "fitsspherehealpix.h"
+#include "fitstarray.h"
+#include "cimage.h"
+
+#include "radspecvector.h"
+#include "blackbody.h"
+#include "derivblackbody.h"
+#include "nupower.h"
+
+#include "squarefilt.h"
+#include "trianglefilt.h"
+#include "specrespvector.h"
+#include "gaussfilt.h"
+
+#include "bruit.h"
+#include "mapoperation.h"
Index: /tags/V_Dec2002/SophyaProg/PMixer/programs
===================================================================
--- /tags/V_Dec2002/SophyaProg/PMixer/programs	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PMixer/programs	(revision 2309)
@@ -0,0 +1,6 @@
+skymixer skymixer.o
+extractRS extractRS.o
+tgrsr tgrsr.o
+tgsky tgsky.o
+easyTest easyTest.o
+Sph2Sph Sph2Sph.o
Index: /tags/V_Dec2002/SophyaProg/PMixer/skm.d
===================================================================
--- /tags/V_Dec2002/SophyaProg/PMixer/skm.d	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PMixer/skm.d	(revision 2309)
@@ -0,0 +1,66 @@
+#  SKYMIX  NbComponents  NSide_HealPix
+@SKYMIX  1 16
+
+#  READMAP  FitsName
+#  To Read the already prepared (mixed) Output MAP from FITS file
+#  FitsName should be the complete path to the FITS file
+READMAP xxx.fits
+
+#  Defining the Detection filter pass - band
+#  GAUSSFILTER or FILTERFITSFILE  card
+#  GAUSSFILTER -> Gaussian filter
+#  FILTERFITSFILE -> Filter (nu, T(nu)) from FITS file
+#  GAUSSFILTER  Nu0 Sigma_Nu Tmax NuMin NuMax
+#  FILTERFITSFILE FileName NuMin NuMax
+#       FileName should be a complete path
+@GAUSSFILTER 143 12 0.84 50. 300.
+
+#  MAPPATH  PathForFITS   
+#  path for input Sky Component FITS files , and EmissionSpectra files 
+MAPPATH /data/opus/Rz/SOPHYA/
+
+#  ----        Sky components  ---------
+#      ----     HealPix maps   ----
+#  MAPFITSFILEi FITSfilename Normalisation
+@MAPFITSFILE4  gauss.fits  1.0 
+
+#      ---   Emission Spectra definition -----
+#   SPECTRAFITSFILEi  FITSfilename  Fmin Fmax 
+@SPECTRAFITSFILE4  pl.fits 100 600  
+
+#   Other possible definition of emission spectra
+#   BLACKBODYi  temperature
+#  The blackbody object returns flux in units of watt/m2/sr/hz
+#   We thus scale the map (x 1.e17) 
+@MAPFITSFILE1  cossin.fits  1.e17 
+
+#   For power-law spectra  f = a ((nu-nu0)/dnu)^b)
+#   POWERLAWSPECTRAi  a nu0 dnu b Fmin Fmax
+@MAPFITSFILE2  noise.fits    0.1 
+@POWERLAWSPECTRA2 1. 150. 50. -0.5 100. 500.
+
+#  For an emission spectrum which depends on the position 
+#  in the map -> synchrotron for instance nu^(-beta(theta,phi))
+#  MAPFITSFILE will still correspond to the brightness temperature
+@MAPFITSFILE3 /exp/planck/Sync/Template408MHz.fits 0.2
+#@MAPFITSFILE1 gauss.fits 0.2
+# and the BETAFITSFILE will correspond to a map with the spectral
+# index beta(theta,phi) 
+# 408 is the normalisation frequency of the map
+# 32 is the nside of the map on which the integration over the
+#	spectralResponse of the detector will be performed
+#	for the full resolution, write the nside of the map
+#	or a negative value.
+@BETAFITSFILE3 /exp/planck/Sync/SpectralIndex.fits  408e-3 16
+#@BETAFITSFILE1 gauss.fits  408e-3 32
+
+#  For adding a dipole component
+# @DIPOLEx Theta Phi Amplitude [Temperature=Tcmb=2.726]
+# CMB dipole parameters , theta, phi 3.358mK
+# @DIPOLE4 0.73 -1.67 3.358e-3
+@DIPOLE4 2.726
+
+#  Define the Debug level
+@DEBUGLEVEL  0
+#  Define the Print level
+@PRINTLEVEL  5
Index: /tags/V_Dec2002/SophyaProg/PMixer/skymixer.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/PMixer/skymixer.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PMixer/skymixer.cc	(revision 2309)
@@ -0,0 +1,1069 @@
+#include "pmixer.h"
+
+/*!
+ * \defgroup PMixer PMixer module
+ * This module contains programs which:
+ * <UL>
+ * <LI> add several sky components, taking into account their
+ * radiation spectra and convoluting them with a given filter
+ * response : skymixer
+ * <LI> create a map with point source : extractRS
+ * <LI> generate sky components, radiation spectra and spectral 
+ * response (small generator of maps) : tgsky and tgrsr
+ * </UL> 
+ * A detailed description may be found at:
+ */
+/*!
+ * \ingroup PMixer
+ * \file skymixer.cc
+ *\brief   \b PROGRAM    \b skyMixer  <BR>
+ *   add several sky components, taking into account their
+ *radiation spectra and convoluting them with a given filter
+ *response
+ */
+
+// -----------------------------------------------------------------
+// ------------- Function declaration ------------------------------
+int CheckCards(DataCards & dc, string & msg, FitsOutFile& fios);
+char * BuildFITSFileName(string const & fname);
+SpectralResponse * getSpectralResponse(DataCards & dc, FitsOutFile& fios);
+RadSpectra * getEmissionSpectra(DataCards & dc, int nc, FitsOutFile& fios);
+void SKM_MergeFITSKeywords(char * flnm);
+void SKM_MergeFITSKeywords2(DVList & dvl);
+void RadSpec2Nt(RadSpectra & rs, POutPersist & so, string name);
+void SpectralResponse2Nt(SpectralResponse& sr, POutPersist & so, string name);
+ 
+// to add different sky components and corresponding tools
+//----------------------------------------------------------
+template <class T> 
+void addComponent(SpectralResponse&  sr, 
+				     PixelMap<T>& finalMap, 
+				     PixelMap<T>& mapToAdd, 
+				     RadSpectra& rs, double K=1.);
+//
+template <class T>
+void addComponentBeta(SphereHEALPix<T>& finalMap, 
+		      SphereHEALPix<T>& mapToAdd,SpectralResponse& sr, 
+		      SphereHEALPix<T>& betaMap, double normFreq, double K);
+//
+template <class T>
+void integratedMap(SpectralResponse&  sr,   
+		   SphereHEALPix<T>& betaMap, double normFreq, SphereHEALPix<T>& intBetaMap);
+
+//
+template <class T>
+void addComponentBeta(SphereHEALPix<T>& finalMap, 
+		      SphereHEALPix<T>& mapToAdd,
+		      SphereHEALPix<T>& intBetaMap, double K);
+//
+template <class T> 
+void addDipole(SpectralResponse&  sr,  PixelMap<T>& finalMap, 
+	       double theta,double phi,double amp,double temp);
+//
+// -----------------------------------------------------------------
+
+//  ----- Global (static) variables ------------
+static bool rdmap = false;    // true -> Read map first 
+static char mapPath[256];     // Path for input maps
+static int  hp_nside = 32;    // HealPix NSide
+static int  nskycomp = 0;     // Number of sky components
+static int  debuglev = 0;     // Debug Level
+static int  printlev = 0;     // Print Level
+static POutPersist * so = NULL;    // Debug PPFOut file
+static DVList * dvl_fitskw = NULL; // Global DVList for all FITS Keywords 
+bool checkpdmtype=false;
+bool dvliston= false;
+// --------- SkyMixer Version --------------
+static double skm_version = 1.5;
+
+// -------------------------------------------------------------------------
+//                             main program 
+// -------------------------------------------------------------------------
+int main(int narg, char * arg[])
+{
+  if ((narg < 3) || ((narg > 1) && (strcmp(arg[1], "-h") == 0) )) {
+    cout << "  Usage: skymixer parameterFile outputfitsname [outppfname]" << endl;
+    exit(0);
+  }
+  
+  InitTim();
+  FitsOutFile fios(arg[2]);
+     
+  cout << " skymixer Version= " << skm_version << " SophyaVersion= " 
+       << SophyaVersion() << endl;
+  
+  string msg;
+  int rc = 0;
+  RadSpectra * es = NULL;
+  SpectralResponse * sr = NULL;
+  double moy, sig;
+  
+  DataCards dc;
+  so = NULL;
+  // DVList for merging all FITS keywords and datacards
+  dvl_fitskw = new DVList;
+  
+  try {
+    string dcard = arg[1];
+    if(printlev > 1) cout << " Decoding parameters from file " << dcard << endl;
+    dc.ReadFile(dcard);
+    
+    rc = CheckCards(dc, msg,fios);
+    if (rc) { 
+      cerr << " Error condition -> Rc= " << rc << endl;
+      cerr << " Msg= " << msg << endl;
+      return(rc);
+    }
+  }
+  catch (PException exc) {
+    msg = exc.Msg();
+    cerr << " !!!! skymixer/ Readcard - Catched exception - Msg= " << exc.Msg() << endl;
+    return(90);
+  }   
+  
+  
+  cout << " skymix/Info : NComp = " <<  nskycomp << " SphereHEALPix_NSide= " << hp_nside << endl;
+  cout << "  ... MapPath = " << (string)mapPath << "  DebugLev= " << debuglev 
+       << "  PrintLev= " << printlev << endl;
+  
+  // We create an output persist file for writing debug objects
+  if (debuglev > 0) so = new POutPersist("skymixdbg.ppf");
+  int countHead = 2;
+  SphereHEALPix<float> outgs(hp_nside);
+  try{
+    if (rdmap) {  // Reading map from FITS file
+      char ifnm[256];
+      strncpy(ifnm, dc.SParam("READMAP", 0).c_str(), 255);
+      ifnm[255] = '\0';
+      cout << " Reading output HealPix map from FITS file " << (string)ifnm << endl;
+      {
+	FitsInFile fitsin(ifnm);
+	fitsin >> outgs;
+	//  Getting FITS keywords in primary header
+	//	SKM_MergeFITSKeywords(ifnm); 
+	//  Getting FITS keywords in data object header
+	if(checkpdmtype)
+	  {
+	    int status = 1;
+	    string whatsup=fitsin.getStringKeyword(2,"PDMTYPE",status);
+	    if(!(status==0&&whatsup=="COMPMAP")) 
+	      {
+		cerr << " !!!! skymixer - file" << ifnm << " is not a COMPMAP " << endl;
+		throw ParmError("Error");
+	      }
+	    else cout << "read the comment COMPMAP from " << ifnm << endl;
+	  }
+	if(dvliston) SKM_MergeFITSKeywords2(outgs.Info());
+	else 
+	  {
+	    fios.appendInputHeader(fitsin, countHead);
+	  }
+      }
+      if(printlev>0)
+	cout << " Output HealPIx Map read - NbPixels= " << 
+	  outgs.NbPixels() << endl;
+      if (printlev > 0) {
+	MeanSig(outgs.DataBlock(), moy, sig );
+	cout << " MeanSig for outpout map - Mean= " << 
+	  moy << " Sigma= " << sig << endl;
+      }
+    }
+    else {
+      if(printlev>0)
+	cout << " Output HealPix Map  created - NbPixels= " << 
+	  outgs.NbPixels() << endl;
+      outgs.SetPixels(0.);
+    }
+    
+    // Decoding detection pass-band filter 
+    sr = getSpectralResponse(dc,fios);
+    PrtTim(" After FilterCreation ");
+    
+    char * flnm, buff[90];
+    string key;
+    
+    double K = 1.;
+    double freqOfMap = 1.;
+    // Loop over sky component 
+    int sk;
+    for(sk = 0; sk<nskycomp; sk++) {
+      cout << "------------------------------------" << endl;
+      cout << " Processing sky component No " << sk+1 << endl;
+      
+
+      sprintf(buff, "%d", sk+1);
+      key = (string)"DIPOLE" + buff;
+      // check for an eventual dipole
+      if(dc.HasKey(key)) 
+	{
+	  if (es) { delete es; es = NULL; }
+	  double temp = -10.;
+	  double theta=  dc.DParam(key,1,1.);
+	  double phi  =  dc.DParam(key,2,1.);
+	  double amp  =  dc.DParam(key,3,1.);
+	  if(dc.NbParam(key)>3) 
+	    {
+	      temp =  dc.DParam(key,4,1.);
+	    }
+	  cout << " creating dipole " << temp << " " << amp << " " << phi << " " << theta << " " << endl;
+	  addDipole(*sr, outgs,theta,phi,amp,temp);
+	}
+      else
+	{
+	  sprintf(buff, "%d", sk+1);
+	  key = (string)"MAPFITSFILE" + buff;
+	  flnm = BuildFITSFileName(dc.SParam(key, 0));
+	  
+	  K = dc.DParam(key, 1, 1.);
+	  
+	  cout << " Reading Input FITS map " << (string)flnm << endl;
+	  SphereHEALPix<float> ings(hp_nside);
+	  {
+	    FitsInFile fiosIn(flnm);
+	    fiosIn >> ings;
+	    //  Getting FITS keywords in primary header
+	    //  SKM_MergeFITSKeywords(flnm); 
+	    //  Getting FITS keywords in data object header
+	    //if(fiosIn.hasKeyword(string("PDMTYPE"), 1)) cout << "read the comment COMPMAP from " << flnm << endl;
+	    if(checkpdmtype)
+	      {
+		int status = 1;
+		string ch = "PDMTYPE";
+		string whatsup=fiosIn.getStringKeyword(2,ch,status);
+		if(!(status==0&&whatsup=="COMPMAP")) 
+		  {
+		    cerr << " !!!! skymixer - file" << flnm << " is not a COMPMAP " << endl;
+		    throw ParmError("Error");
+		  }
+		else cout << "read the comment COMPMAP from " << flnm << endl;
+	      }
+	    if(dvliston) SKM_MergeFITSKeywords2(ings.Info());
+	    else 
+	      {
+		fios.appendInputHeader(fiosIn, countHead);
+	      }
+	  }
+	  if (debuglev > 4) {  // Writing the input map to the outppf
+	    FIO_SphereHEALPix<float> fiog(ings);
+	    fiog.Write(*so, key);
+	  }
+	  if (printlev > 2) {
+	    MeanSig(ings.DataBlock(), moy, sig );
+	    cout << " MeanSig for input map - Mean= " << moy << " Sigma= " << sig << endl;
+	  }
+	  bool mapDependentOfFreq = false;
+	  key = (string)"BETAFITSFILE"+ buff;
+	  if(dc.HasKey(key)) 
+	    {
+	      mapDependentOfFreq = true;
+	    }
+	  
+	  // getting Emission spectra  
+	  if(!mapDependentOfFreq)
+	    {
+	      if (es) { delete es; es = NULL; }
+	      es = getEmissionSpectra(dc, sk,fios);
+	      addComponent(*sr, outgs, ings, *es, K);
+	    }
+	  else
+	    {
+	      key = (string)"BETAFITSFILE"+ buff;
+	      //SphereHEALPix<float> betaMap;
+	      flnm = BuildFITSFileName(dc.SParam(key, 0));
+	      double normFreq = dc.DParam(key, 1, 1.);
+	      if (printlev > 4) cout << "....BetaFits... normalization Freq = " << normFreq << endl;
+	      int nSideForInt = dc.DParam(key, 2, 1.);
+	      if (printlev > 4) cout << "....BetaFits... NSide for Integration map = " << nSideForInt << endl;
+	      cout << "....BetaFits...  Reading Beta FITS map " << (string)flnm << endl;
+	      SphereHEALPix<float> betaMap(hp_nside);
+	      {
+		FitsInFile fiosBM(flnm);
+		fiosBM >> betaMap;
+		//  Getting FITS keywords in primary header
+		// SKM_MergeFITSKeywords(flnm); 
+		//  Getting FITS keywords in data object header
+		//if(fiosBM.hasKeyword(string("COMPMAP"), 1)) cout << "read the comment COMPMAP from " << flnm << endl;
+		if(checkpdmtype)
+		  {
+		    int status = 1;
+		    string whatsup=fiosBM.getStringKeyword(2,"PDMTYPE",status);
+		    if(!(status==0&&whatsup=="INDEXMAP")) 
+		      {
+			cerr << " !!!! skymixer - file" << flnm << " is not an INDEXMAP " << endl;
+			throw ParmError("Error");
+		      }
+		    else cout << "read the comment INDEXMAP from " << flnm << endl;
+		  }
+		if(dvliston) SKM_MergeFITSKeywords2(betaMap.Info()); 
+		else 
+		  {
+		    fios.appendInputHeader(fiosBM, countHead);
+		  }
+	      }
+	      if (printlev > 2) {
+		MeanSig(betaMap.DataBlock(), moy, sig );
+		cout << " MeanSig for Beta map - Mean= " << moy << " Sigma= " << sig << endl;
+	      }
+	      if (debuglev > 4) {  // Writing the input map to the outppf
+		FIO_SphereHEALPix<float> fiogs(betaMap);
+		fiogs.Write(*so, key);
+	      }
+	      
+	      if(nSideForInt<0) nSideForInt = sqrt((double)betaMap.NbPixels()/12);
+	      bool bydefault = true;
+	      if(!bydefault)
+		addComponentBeta(outgs,ings,*sr,betaMap,normFreq, K);
+	      else
+		{
+		  // integrate the betamap over the SpectralResponse
+		  SphereHEALPix<float> intBetaMap(nSideForInt);
+		  integratedMap(*sr, betaMap, normFreq, intBetaMap);
+		  if (debuglev > 4) {  // Writing the input map to the outppf
+		    FIO_SphereHEALPix<float> fiogs2(intBetaMap);
+		    fiogs2.Write(*so, "INTBETAMAP");
+		  }
+		  
+		  betaMap.Resize(8);
+		  if (printlev > 4)
+		    {
+		      MeanSig(intBetaMap.DataBlock(), moy, sig );
+		      cout << "....BetaFits... MeanSig for intBetaMap - Mean= " 
+			   << moy << " Sigma= " << sig << endl;
+		    }
+		  // add the integrated beta map 
+		  addComponentBeta(outgs,ings,intBetaMap, K);
+		}
+	    }
+	  
+	  MeanSig(outgs.DataBlock(), moy, sig );
+	  cout << " MeanSig for Sum map - Mean= " << moy << " Sigma= " << sig << endl;
+	  cout << "-------------------------------------------------" << endl;
+	  
+	  sprintf(buff, "End of Processing Component %d ", sk+1);
+	  PrtTim(buff);
+	} 
+    }
+  }
+  catch(PException exc) 
+    {
+      cout << "catched PException" << endl;
+      msg = exc.Msg();
+      cerr << " !!!! skymixer - Catched exception - Msg= " << exc.Msg() << endl;
+      rc = 50;
+      return(50);
+    } 
+  
+ try {
+ // Saving the output map in FITS format 
+   cout << "Output Map (SphereHEALPix<float>) written to FITS file " 
+	<< (string)(arg[2]) << endl;
+   {
+     //     FitsOutFile fios(arg[2]);
+     fios.firstImageOnPrimaryHeader(false); // Use secondary header 
+     DVList& dvl = (*dvl_fitskw);
+     dvl["PDMTYPE"] = "COMPMAP";
+     dvl.SetComment("PDMTYPE", "Planck Data Model Type"); 
+     dvl["SOPHYVER"] =  SophyaVersion();
+     dvl.SetComment("SOPHYVER", "Sophya Version number"); 
+     dvl["SKYMVER"] =  skm_version;
+     dvl.SetComment("SKYMVER", "skymixer Version number"); 
+     //     fios.DVListIntoPrimaryHeader(dvl);  
+     dvl["CREATOR"] = "SkyMixer";
+     outgs.Info() = dvl;
+     fios << outgs ;
+   }
+   PrtTim("End of WriteFITS ");
+   // Saving the output map in PPF format 
+   if (narg > 3) {
+     POutPersist s(arg[3]); 
+     FIO_SphereHEALPix<float> fiog(&outgs) ;
+     fiog.Write(s);
+     cout << "Output Map (SphereHEALPix<float>) written to POutPersist file "  
+	  << (string)(arg[3]) << endl;
+     PrtTim("End of WritePPF ");
+   }
+ }
+ catch(PException exc) 
+   {
+     cout << "catched PException (2)" << endl;
+     msg = exc.Msg();
+     cerr << " !!!! skymixer(2) - Catched exception - Msg= " << exc.Msg() << endl;
+     rc = 55;
+     return(55);
+   } 
+
+ if (so) delete so;  //  Closing the debug ppf file 
+ return(rc);
+}
+
+/* Nouvelle-Fonction */
+int CheckCards(DataCards & dc, string & msg, FitsOutFile& fios)
+//   Function to check datacards
+{
+rdmap = false;
+mapPath[0] = '\0';
+hp_nside = 32;
+nskycomp = 0;
+debuglev  = 0;
+printlev = 0;
+
+int rc = 0;
+string key, key2,key3;
+
+ DVList & dvl = *dvl_fitskw; 
+  //  Cheking datacards
+  if (dc.NbParam("SKYMIX") < 2)   {
+     rc = 71; 
+     msg = "Invalid parameters  - Check @SKYMIX card ";
+     return(rc);
+  }
+  if(dvliston)
+    dvl.SetS("SKYMIX", dc.GetParams("SKYMIX"));
+  else
+    {
+      fios.insertCommentLineOnHeader("--------------------");
+      fios.insertCommentLineOnHeader("SkyMixer DataCard");
+      fios.insertCommentLineOnHeader("--------------------");
+ 
+       string key = "SKYMIX"+ (string)dc.GetParams("SKYMIX");
+       fios.insertCommentLineOnHeader(key);
+    }
+
+  key = "CHECKPDMTYPE";
+  if (dc.HasKey(key)) {
+    checkpdmtype=true;
+  }
+
+  
+  key = "READMAP";
+  if (dc.HasKey(key)) {
+    if (dc.NbParam(key) < 1) {
+     rc = 72; 
+     msg = "Invalid parameters  - Check @READMAP card ";
+     return(rc);
+    }
+    else rdmap = true;
+    
+    if(dvliston) dvl.SetS(key, dc.GetParams(key));
+    else 
+      {
+	string keynew = key + (string)dc.GetParams(key);
+	fios.insertCommentLineOnHeader(keynew);
+      }
+  }
+
+//  Checking detection filter specification 
+  key = "GAUSSFILTER";
+  key2 = "FILTERFITSFILE";
+  key3 = "DIPOLE";
+  if ( (dc.NbParam(key) < 5) && (dc.NbParam(key2) < 3) && (dc.NbParam(key3) < 3)) { 
+    msg = "Missing card or parameters : Check @GAUSSFILTER or @FILTERFITSFILE or @DIPOLE";
+    rc = 73;  return(rc); 
+    }
+
+  if (dc.HasKey(key))   
+    { 
+      if(dvliston) dvl.SetS("GAUSFILT", dc.GetParams(key));
+      else 
+	{
+	  string keynew = key + (string)dc.GetParams(key);
+	  fios.insertCommentLineOnHeader(keynew);
+	}
+    }
+  if (dc.HasKey(key2))
+    {
+      if(dvliston) dvl.SetS("FILTFILE", dc.GetParams(key2));
+      else
+	{
+	  string keynew = key2 + (string)dc.GetParams(key2);
+	  fios.insertCommentLineOnHeader(keynew);
+	}
+    }
+  if (dc.HasKey(key3))  
+    {
+      if(dvliston) dvl.SetS("DIPOLE", dc.GetParams(key3));
+      else
+	{
+	  string keynew = key3 + (string)dc.GetParams(key3);
+	  fios.insertCommentLineOnHeader(keynew);
+	}
+    }
+  // Decoding number of component and pixelisation parameter
+  int mg = 32;
+  int ncomp = 0;
+  ncomp = dc.IParam("SKYMIX", 0, 0);
+  mg = dc.IParam("SKYMIX", 1, 32);
+  if (ncomp < 1)  {
+    msg = "Invalid parameters  - Check datacards @SKYMIX ";
+    rc = 74;
+    return(rc);
+  }
+
+  // Checking detection filter specification
+  //  Checking input FITS file specifications 
+  int kc;
+  char buff[256];
+  bool pb = false;
+  string key4;
+  string key5;
+  string key6;
+  for(kc=0; kc<ncomp; kc++) {
+    sprintf(buff, "MAPFITSFILE%d", kc+1);
+    key = buff;
+    sprintf(buff, "DIPOLE%d", kc+1);
+    key3 = buff;
+    if (dc.NbParam(key) < 1 && (dc.NbParam(key3)<1)) 
+      {   
+	msg = "Invalid card or Missing card" + key + " or " + key3 ;
+	pb = true;  break;
+      }
+	
+    sprintf(buff, "MAPFIL%d", kc+1);
+    if (dc.HasKey(key))  
+      {
+	if(dvliston) dvl.SetS(buff, dc.GetParams(key));
+	else 
+	  {
+	    string keynew = buff + (string)dc.GetParams(key);
+	    fios.insertCommentLineOnHeader(keynew);
+	  }
+      }	
+    sprintf(buff, "DIPOLE%d", kc+1);
+    if (dc.HasKey(key3))  
+      {
+	if(dvliston) dvl.SetS(buff, dc.GetParams(key3));
+	else
+	  {
+	    string keynew = buff + (string)dc.GetParams(key3);
+	    fios.insertCommentLineOnHeader(keynew);
+	  }
+      }
+    sprintf(buff, "SPECTRAFITSFILE%d", kc+1);
+    key = buff;
+    sprintf(buff, "BLACKBODY%d", kc+1);
+    key2 = buff;
+    sprintf(buff, "POWERLAWSPECTRA%d", kc+1);
+    key3 = buff;
+    sprintf(buff, "BETAFITSFILE%d", kc+1);
+    key4 = buff;
+    sprintf(buff, "DIPOLE%d", kc+1);
+    key5 = buff;
+    sprintf(buff, "DERIVBB%d", kc+1);
+    key6 = buff;
+    if ( (dc.NbParam(key) < 3) && (dc.NbParam(key2) < 1) && (dc.NbParam(key3) < 6) && (dc.NbParam(key4)<2)
+	 &&  (dc.NbParam(key6)<1) &&  (dc.NbParam(key5)<1))  {   
+      msg = "Missing card or invalid parameters : " + key + " " + key2 + " " + key3 + " " + key4+ " " + key5;
+      pb = true;  break;
+    }
+
+    sprintf(buff, "SPECTF%d", kc+1);
+    if (dc.HasKey(key)) {   
+      if(dvliston) dvl.SetS(buff, dc.GetParams(key));
+      else { 
+	string keynew = buff + (string)dc.GetParams(key);
+	fios.insertCommentLineOnHeader(keynew);}
+    }
+    sprintf(buff, "BLACKB%d", kc+1);
+    if (dc.HasKey(key2)) {
+      if(dvliston) dvl.SetS(buff, dc.GetParams(key2));
+      else { 
+	string keynew = buff + (string)dc.GetParams(key2);
+	fios.insertCommentLineOnHeader(keynew);}
+    }
+
+    sprintf(buff, "PLAWSP%d", kc+1);
+    if (dc.HasKey(key3)) {
+      if(dvliston) dvl.SetS(buff, dc.GetParams(key3));
+      else { 
+	string keynew = buff + (string)dc.GetParams(key3);
+	fios.insertCommentLineOnHeader(keynew);}
+    }
+
+    sprintf(buff, "BETAFI%d", kc+1);
+    if (dc.HasKey(key4))  {
+      if(dvliston) dvl.SetS(buff, dc.GetParams(key4));
+      else { 
+	string keynew = buff + (string)dc.GetParams(key4);
+	fios.insertCommentLineOnHeader(keynew);}
+    }
+
+    sprintf(buff, "DIPOLE%d", kc+1);
+    if (dc.HasKey(key5))  {
+      if(dvliston) dvl.SetS(buff, dc.GetParams(key5));
+      else { 
+	string keynew = buff + (string)dc.GetParams(key5);
+	fios.insertCommentLineOnHeader(keynew);}
+    }
+
+    sprintf(buff, "DERIBB%d", kc+1);
+    if (dc.HasKey(key6))  {
+      if(dvliston) dvl.SetS(buff, dc.GetParams(key6));
+      else { 
+	string keynew = buff + (string)dc.GetParams(key6);
+	fios.insertCommentLineOnHeader(keynew);}
+    }
+    
+  }
+
+  if (pb)  {
+    rc = 75;
+    return(75);
+  }
+
+
+// Initialiazing parameters
+  rc = 0;
+  msg = "OK";
+  nskycomp = ncomp;
+  hp_nside = mg;  
+
+
+// Checking for PATH definition card
+  key = "MAPPATH";
+  if (dc.NbParam(key) < 3)  strncpy(mapPath, dc.SParam(key, 0).c_str(), 255);
+  mapPath[255] = '\0';
+  key = "DEBUGLEVEL";
+  debuglev =  dc.IParam(key, 0, 0);
+  key = "PRINTLEVEL";
+  printlev =  dc.IParam(key, 0, 0);
+  return(rc);
+}
+
+static char buff_flnm[1024];   // Mal protege !
+/* Nouvelle-Fonction */
+char* BuildFITSFileName(string const & fname)
+{
+if (mapPath[0] != '\0') sprintf(buff_flnm, "%s/%s", mapPath, fname.c_str());
+else sprintf(buff_flnm, "%s", fname.c_str());
+return(buff_flnm);
+}
+
+/* Nouvelle-Fonction */
+SpectralResponse * getSpectralResponse(DataCards & dc, FitsOutFile& fios)
+{
+  SpectralResponse * filt = NULL;
+
+  string key = "FILTERFITSFILE";
+  string key2 = "GAUSSFILTER";
+  string ppfname = "filter";
+
+  if (dc.HasKey(key) ) {      // Reading FITS filter file
+    char ifnm[256];
+    strncpy(ifnm, dc.SParam(key, 1).c_str(), 255);
+    ifnm[255] = '\0';
+    Matrix mtx;
+    FitsInFile fiis(ifnm);
+    fiis.firstImageOnPrimaryHeader(false); // Use secondary header HDU=2
+    fiis >> mtx ; 
+    //  Getting FITS keywords in primary header
+    //    SKM_MergeFITSKeywords(ifnm); 
+    //  Getting FITS keywords in data object header
+    if(checkpdmtype)
+      {
+	int status = 1;
+	string whatsup=fiis.getStringKeyword(2,"PDMTYPE",status);
+	if(!(status==0&&whatsup=="COMPMAP")) 
+	  {
+	    cerr << " !!!! skymixer - file" << ifnm << " is not a COMPMAP " << endl;
+	    throw ParmError("Error");
+	  }
+	else cout << "read the comment COMPMAP from " << ifnm << endl;
+      }
+    if(dvliston) SKM_MergeFITSKeywords2(mtx.Info()); 
+    else 
+      {
+	fios.appendInputHeader(fiis, 2);
+      }
+    double numin = dc.DParam(key, 2, 1.);
+    double numax = dc.DParam(key, 3, 9999.);
+    Vector nu(mtx.NCols());
+    Vector fnu(mtx.NCols());
+    for(int k=0; k<mtx.NCols(); k++) {
+      nu(k) = mtx(0, k);
+      fnu(k) = mtx(1, k);
+    }
+  filt = new SpecRespVec(nu, fnu, numin, numax);
+  ppfname = key;
+  }
+  else if (dc.HasKey(key2) ) {   // creating GaussianFilter 
+    double nu0 = dc.DParam(key2, 0, 10.);
+    double s = dc.DParam(key2, 1, 1.);
+    double a = dc.DParam(key2, 2, 1.);
+    double numin = dc.DParam(key2, 3, 0.1);
+    double numax = dc.DParam(key2, 4, 9999);
+    filt = new GaussianFilter(nu0, s, a, numin, numax);
+    ppfname = key2;
+    }
+  if (filt == NULL) throw ParmError("datacard error ! No detection filter");
+  if(printlev>0)
+    {
+      cout << endl;
+      cout << " Filter decoded - Created " << endl;
+      cout << *filt << endl;
+    }
+  // for debug
+  if (debuglev > 1)  SpectralResponse2Nt(*filt, *so, ppfname);
+  return(filt);
+}
+
+/* Nouvelle-Fonction */
+RadSpectra * getEmissionSpectra(DataCards & dc, int nc, FitsOutFile& fios)
+{
+  char numb[16];
+  sprintf(numb, "%d", nc+1);
+
+  string key = (string)"SPECTRAFITSFILE" + numb;
+  string key2 = (string)"BLACKBODY" + numb;
+  string key5 = (string)"DERIVBB" + numb;
+  string key3 = (string)"POWERLAWSPECTRA" + numb;
+  string ppfname = "espectra";
+
+  RadSpectra * rs = NULL;
+  if (dc.HasKey(key) ) {    // Reading emission spectra from file
+    char * ifnm = BuildFITSFileName(dc.SParam(key, 0));
+    cout << " Reading Input FITS spectra file " << (string)ifnm << endl;
+    Matrix mtx;
+    FitsInFile fiis(ifnm);
+    fiis.firstImageOnPrimaryHeader(false); // Use secondary header HDU=2
+    fiis >> mtx ; 
+    //  Getting FITS keywords in primary header
+    //    SKM_MergeFITSKeywords(ifnm); 
+    //  Getting FITS keywords in data object header
+    //if(fiis.hasKeyword(string("PDMTYPE"), 1)) cout << "read the comment COMPMAP from " << ifnm << endl;
+    if(checkpdmtype)
+      {
+	int status = 1;
+	string whatsup=fiis.getStringKeyword(2,"PDMTYPE",status);
+	if(!(status==0&&whatsup=="FGRSPEC")) 
+	  {
+	    cerr << " !!!! skymixer - file" << ifnm << " is not a  FGRSPEC" << endl;
+	    throw ParmError("Error");
+	  }
+	else cout << "read the comment FGRSPEC from " << ifnm << endl;
+      }
+    if(dvliston) SKM_MergeFITSKeywords2(mtx.Info()); 
+    else 
+      {
+	fios.appendInputHeader(fiis, 2);
+      }
+    double numin = dc.DParam(key, 2, 1.);
+    double numax = dc.DParam(key, 3, 9999.);
+    Vector nu(mtx.NCols());
+    Vector tnu(mtx.NCols());
+    for(int k=0; k<mtx.NCols(); k++) {
+      nu(k) = mtx(0, k);
+      tnu(k) = mtx(1, k);
+    }
+  rs = new RadSpectraVec(nu, tnu, numin, numax);
+  ppfname = key;
+  }
+  else if (dc.HasKey(key2) ) { // Creating BlackBody emission spectra
+    rs = new BlackBody(dc.DParam(key2, 0, 2.726));
+    ppfname = key2;
+  }
+  else if (dc.HasKey(key5) ) { // Creating Dipole
+    rs = new DerivBlackBody(dc.DParam(key5, 0, 3.E-3));
+    ppfname = key5;
+  }
+  else if (dc.HasKey(key3) ) { // Creating PowerLaw emission spectra
+    double a = dc.DParam(key3, 0, 1.);
+    double nu0 = dc.DParam(key3, 1, 100.);
+    double dnu = dc.DParam(key3, 2, 10.);
+    double b = dc.DParam(key3, 3, 0.);
+    double numin = dc.DParam(key3, 4, 0.1);
+    double numax = dc.DParam(key3, 5, 9999);
+    rs = new PowerLawSpectra(a, b, nu0, dnu, numin, numax);
+    ppfname = key3;
+  }
+  if (rs == NULL) throw ParmError("datacard error ! missing Emission spectra");
+  cout << " Emission spectra decoded - Created (" << ppfname << ")" << endl;
+  cout << *rs << endl;
+// for debug
+  if (debuglev > 2)  RadSpec2Nt(*rs, *so, ppfname);
+  return(rs);
+}
+
+
+
+
+template <class T> 
+void addDipole(SpectralResponse&  sr,  PixelMap<T>& finalMap, 
+	       double theta,double phi,double amp,double temp)
+{
+  DerivBlackBody dbb;
+  if(temp>0) dbb.setTemperature(temp);
+  double coeff = dbb.filteredIntegratedFlux(sr) * amp;
+  UnitVector vd(theta,phi);
+  UnitVector vc(theta,phi);
+  
+  for(int i=0; i<finalMap.NbPixels(); i++)
+    {
+      double thetar,phir;
+      finalMap.PixThetaPhi(i,thetar,phir);      
+      vc.SetThetaPhi(thetar,  phir);
+      finalMap(i) += vd.Psc(vc)*coeff;
+    }
+  if (debuglev > 4) {  // Writing the input map to the outppf
+    SphereHEALPix<float> ings(sqrt((double)finalMap.NbPixels()/12));
+    for(int i=0; i<finalMap.NbPixels(); i++)
+      {
+	double thetar,phir;
+	finalMap.PixThetaPhi(i,thetar,phir);      
+	vc.SetThetaPhi(thetar,  phir);
+	ings(i) = vd.Psc(vc);
+      }
+    FIO_SphereHEALPix<float> fiog(ings);
+    fiog.Write(*so, "dipole");
+    cout << "Debug the dipole map....saved in debug file !" << endl;
+  }
+}
+/* Nouvelle-Fonction */
+template <class T> 
+void addComponent(SpectralResponse&  sr, PixelMap<T>& finalMap, 
+                  PixelMap<T>& mapToAdd, RadSpectra& rs, double K)
+{
+  // finalMap = finalMap + coeff* mapToAdd
+  // coeff    =  convolution of sr and rs 
+  // compute the coefficient corresponding to mapToAdd
+  if (finalMap.NbPixels() != mapToAdd.NbPixels())   
+    throw SzMismatchError("addComponent()/Error: Unequal number of Input/Output map pixels");
+  double coeff = rs.filteredIntegratedFlux(sr) * K;
+  if (printlev > 1) 
+    cout << " addComponent - Coeff= " << coeff << " (K= " << K << ")" << endl; 
+  for(int i=0; i<finalMap.NbPixels(); i++)
+    {
+      finalMap(i) += coeff * mapToAdd(i);
+    }
+}
+/* Nouvelle-Fonction */
+template <class T> 
+void addComponentBeta(SphereHEALPix<T>& finalMap, 
+		      SphereHEALPix<T>& mapToAdd,SpectralResponse& sr, 
+		      SphereHEALPix<T>& betaMap, double normFreq, double K)
+{
+  // finalMap = finalMap + coeff* mapToAdd
+  // coeff    =  convolution of sr and rs 
+  // compute the coefficient corresponding to mapToAdd
+  // betaMap is the map of (beta(theta,phi)) 
+
+  int nbpix = finalMap.NbPixels();
+  if (nbpix != mapToAdd.NbPixels())   
+    throw SzMismatchError("addComponentBeta()/Error: Unequal number of Input/Output map pixels");
+  if (printlev > 1) 
+    {
+      cout << "addComponentBeta - Coeff= "  << K  << endl; 
+      cout << "nb pixels: " << finalMap.NbPixels() << endl;
+    }
+  SphereHEALPix<T> bigBetaMap(sqrt((double)nbpix/12));
+  if(nbpix != betaMap.NbPixels())
+    {
+       Sph2Sph(betaMap,bigBetaMap);
+     }
+  for(int i=0; i<finalMap.NbPixels(); i++)
+    {
+      // coeff = integration of (nu/normFreq)^(-beta(theta,phi)) in each pixels
+      RadSpectra* rs =  new PowerLawSpectra
+	(1.,-bigBetaMap(i), 0., normFreq, 0.01, 800.);
+      double coeff = rs->filteredIntegratedFlux(sr);
+      finalMap(i) += coeff*K*mapToAdd(i);
+    }
+}
+
+template <class T>
+void integratedMap(SpectralResponse&  sr,   
+		   SphereHEALPix<T>& betaMap, 
+		   double normFreq, 
+		   SphereHEALPix<T>& intBetaMap)
+{
+  PowerLawSpectra rs(1.,-2., 0., normFreq);
+  
+  if(betaMap.NbPixels()!=intBetaMap.NbPixels()) 
+    {
+      Sph2Sph(betaMap,intBetaMap);
+      for(int i=0; i<intBetaMap.NbPixels(); i++)
+	{
+	  rs.setExp(-intBetaMap(i));
+	  double coeff = rs.filteredIntegratedFlux(sr);
+	  intBetaMap(i) = coeff;
+	}
+    }
+  else
+    {      
+      for(int i=0; i<intBetaMap.NbPixels(); i++)
+	{
+	  rs.setExp(-betaMap(i));
+	  double coeff = rs.filteredIntegratedFlux(sr);
+	  intBetaMap(i) = coeff;
+	}
+    }
+}
+
+template <class T>
+void addComponentBeta(SphereHEALPix<T>& finalMap, 
+		      SphereHEALPix<T>& mapToAdd,SphereHEALPix<T>& intBetaMap, double K)
+{
+  // finalMap = finalMap + coeff* mapToAdd
+  // coeff    =  convolution of sr and rs 
+  // compute the coefficient corresponding to mapToAdd
+  // integBetaMap is the map of the integration (nu/normFreq)^(-beta(theta,phi)) over
+  // the spectralResponse
+  // different from addComponentBeta(PixelMap<T>& finalMap, 
+  //    PixelMap<T>& mapToAdd,SpectralResponse& sr, PixelMap<T>& betaMap, double normFreq, double K)
+  //   since it permits to use a intBetaMap with a different number of pixels than
+  //   the other maps
+
+  int nbpix = finalMap.NbPixels();
+  if (nbpix != mapToAdd.NbPixels())   
+    throw SzMismatchError("addComponentBeta(PixelMap<T>&,PixelMap<T>&,PixelMap<T>&,double)/Error: Unequal number of Input/Output map pixels");
+  double coeff = K;
+
+  if(nbpix != intBetaMap.NbPixels())
+    {
+      for(int i=0; i<finalMap.NbPixels();i++)
+ 	{
+	  double teta,phi,val;
+	  finalMap.PixThetaPhi(i, teta, phi);
+	  int pixel = intBetaMap.PixIndexSph(teta,phi);
+	  val = intBetaMap.PixVal(pixel);
+	  finalMap(i) += coeff*mapToAdd(i)*val;
+ 	}
+    }
+  else
+    {
+      for(int i=0; i<finalMap.NbPixels();i++)
+ 	{
+ 	  finalMap(i) += coeff*mapToAdd(i)*intBetaMap(i);
+ 	}
+    }
+  if (printlev > 1) 
+    {
+      cout << "addComponentBeta(SG<T>,SG<T>,SG<T>,double) - Coeff= "  << K  << endl;     
+    }
+}
+
+
+
+
+
+/* Nouvelle-Fonction */
+void SKM_MergeFITSKeywords(char * flnm)
+{
+  DVList dvl;
+  FitsFile::FitsExtensionType typeOfExtension;
+  int naxis;
+  vector<int> naxisn;
+  FitsFile::FitsDataType dataType;
+  FitsInFile::GetBlockType(flnm, 1, typeOfExtension, naxis, naxisn, dataType, dvl);
+  // Cleaning the keywords 
+#define SZexlst 21
+  char *exlst[SZexlst]=
+  {"SIMPLE","BITPIX" ,"NAXIS" ,"NAXIS#" ,"PCOUNT","GCOUNT",
+     "EXTEND","ORIGIN" ,"DATE*" ,"TFIELDS","TTYPE#","TFORM#",
+     "TUNIT#","EXTNAME","CTYPE#","CRVAL#" ,"CRPIX#","CDELT#",
+     "XTENSION","INSTRUME","TELESCOP"};
+  char  kwex[32];
+  int i,l;
+  for (i=0; i<SZexlst; i++) {
+    strncpy(kwex, exlst[i], 32);
+    l = strlen(kwex)-1;
+    if ((kwex[l] != '*') && (kwex[l] != '#')) {
+      dvl.DeleteKey(kwex);
+    } 
+    else {
+      bool fgd = (kwex[l] == '#') ? true : false;
+      list<string> lstsup;
+      kwex[l] = '\0';
+      DVList::ValList::const_iterator it;
+      for (it = dvl.Begin(); it != dvl.End(); it++) {
+	if ((*it).first.substr(0,l) != kwex) continue;
+	if (fgd && !isdigit((*it).first[l])) continue;
+	lstsup.push_back((*it).first);
+      }
+      list<string>::iterator it2;
+      for (it2 = lstsup.begin(); it2 != lstsup.end(); it2++)
+	dvl.DeleteKey(*it2);
+    }
+  }
+  dvl_fitskw->Merge(dvl);
+}
+
+/* Nouvelle-Fonction */
+void SKM_MergeFITSKeywords2(DVList & dvl)
+{
+  // Cleaning the keywords 
+#define SZexlst 21
+  char *exlst[SZexlst]=
+  {"SIMPLE","BITPIX" ,"NAXIS" ,"NAXIS#" ,"PCOUNT","GCOUNT",
+     "EXTEND","ORIGIN" ,"DATE*" ,"TFIELDS","TTYPE#","TFORM#",
+     "TUNIT#","EXTNAME","CTYPE#","CRVAL#" ,"CRPIX#","CDELT#",
+     "XTENSION","INSTRUME","TELESCOP"};
+  char  kwex[32];
+  int i,l;
+  for (i=0; i<SZexlst; i++) {
+    strncpy(kwex, exlst[i], 32);
+    l = strlen(kwex)-1;
+    if ((kwex[l] != '*') && (kwex[l] != '#')) {
+      dvl.DeleteKey(kwex);
+    } 
+    else {
+      bool fgd = (kwex[l] == '#') ? true : false;
+      list<string> lstsup;
+      kwex[l] = '\0';
+      DVList::ValList::const_iterator it;
+      for (it = dvl.Begin(); it != dvl.End(); it++) {
+	if ((*it).first.substr(0,l) != kwex) continue;
+	if (fgd && !isdigit((*it).first[l])) continue;
+	lstsup.push_back((*it).first);
+      }
+      list<string>::iterator it2;
+      for (it2 = lstsup.begin(); it2 != lstsup.end(); it2++)
+	dvl.DeleteKey(*it2);
+    }
+  }
+  dvl_fitskw->Merge(dvl);
+}
+
+/* Nouvelle-Fonction */
+void RadSpec2Nt(RadSpectra & rs, POutPersist & so, string name)
+{
+  char *ntn[2] = {"nu","fnu"};
+  NTuple nt(2,ntn);  // Creation NTuple (AVEC new )
+  float xnt[2];
+  double nu;
+  double numin = rs.minFreq();
+  double numax = rs.maxFreq();
+  int nmax = 500;
+  double dnu = (numax-numin)/nmax;
+  for(int k=0; k<nmax; k++) {
+    nu = numin+k*dnu;
+    xnt[0] = nu;
+    xnt[1] = rs.flux(nu);
+    nt.Fill(xnt);
+  }
+  ObjFileIO<NTuple> oiont(nt);
+  oiont.Write(so, name);
+  return;
+}
+
+/* Nouvelle-Fonction */
+void SpectralResponse2Nt(SpectralResponse& sr, POutPersist & so, string name)
+{
+  char *ntn[2] = {"nu","tnu"};
+  NTuple nt(2,ntn);  // Creation NTuple (AVEC new )
+  float xnt[2];
+  double nu;
+  double numin = sr.minFreq();
+  double numax = sr.maxFreq();
+  int nmax = 500;
+  double dnu = (numax-numin)/nmax;
+  for(int k=0; k<nmax; k++) {
+    nu = numin+k*dnu;
+    xnt[0] = nu;
+    xnt[1] = sr.transmission(nu);
+    nt.Fill(xnt);
+  }
+  ObjFileIO<NTuple> oiont(nt);
+  oiont.Write(so, name);
+  return;
+}
+
Index: /tags/V_Dec2002/SophyaProg/PMixer/tgrsr.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/PMixer/tgrsr.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PMixer/tgrsr.cc	(revision 2309)
@@ -0,0 +1,168 @@
+#include <typeinfo>
+#include "pmixer.h"
+
+/*!\ingroup PMixer
+ * \file tgrsr.cc
+ * \brief \b PROGRAM \b tgrsr  <BR>
+ * Program to generate different type of RadSpectra
+ * and SpectralResponse in the form of RadSpectraVec and SpecRespVec
+ * in FITS format
+ */
+
+
+// ------------- Main program --------------
+int main(int narg, char* arg[]) 
+{
+#if !defined(SunOS) || !defined(__GNUG__)
+  // ca se plante sur Sun !
+  SophyaInit();
+#endif
+
+  InitTim();   // Initializing the CPU timer 
+
+  if ((narg < 5) || ((narg>1) && (strcmp(arg[1],"-h") == 0)) )  {
+    cout << " tgrsr : Generation of RadSpectraVec and SpecRespVec in FITS  " << endl;
+    cout << " Usage: tgrsr 0/1 Params NPoints FitsFileName [ImageR4FITSName] [ppfname] " << endl;
+    cout << " 0 -> GaussianFilter  T = A exp(((nu-nu0)/dnu)^2" << endl;
+    cout << " Params : A,Nu0,DNu,MinFreq,MaxFreq " << endl;
+    cout << " 1 -> PowerLawSpectra f = a ((nu-nu0)/dnu)^b " << endl;
+    cout << " Params : A,Nu0,dnu,b,MinFreq,MaxFreq " << endl;
+    exit(0);
+    }
+
+try {
+  int typ = 0; 
+  typ = atoi(arg[1]);
+  int k, npt = 100;
+  npt = atoi(arg[3]);
+  if (npt < 5) npt = 5;
+  cout << " ---- tgrsr/Info: Type= " << typ << " NPoints= " << npt << endl;
+  Matrix mtx(2, npt);
+  ImageR4 img(npt, 2);
+
+  char buff[256];
+  if (typ == 0) {  // Generation de SpecRespVec from GaussianFilter
+    double a,nu0,dnu,fmin,fmax;
+    a = 1.0;
+    nu0 = 143.;
+    dnu = 10.;
+    fmin = 10.;
+    fmax = 1000.;
+    sscanf(arg[2],"%lg,%lg,%lg,%lg,%lg",&a,&nu0,&dnu,&fmin,&fmax);
+    cout << " GaussianFilter  T = A exp(((nu-nu0)/dnu)^2" << endl;
+    sprintf(buff,"A=%g Nu0=%g DNu=%g FMin=%g FMax=%g",
+            a,nu0,dnu,fmin,fmax);
+    cout << "Decoded params: " << (string)buff << endl;
+    GaussianFilter sr(nu0, dnu, a, fmin, fmax);
+    cout << sr << endl;
+    cout << " Creating SpecRespVec() ... " << endl;
+    Vector v1(10);
+    Vector v2(10);
+    SpecRespVec srv(v1, v2, fmin, fmax);
+    Vector & nu = srv.getNuVec();
+    Vector & tnu = srv.getTNuVec();
+    nu.ReSize(npt);
+    tnu.ReSize(npt);
+    double freq;
+    double dfreq = (fmax-fmin)/(npt-3);
+    for(k=0; k<npt; k++) {
+      freq = fmin+(k-1)*dfreq;
+      nu(k) = freq;
+      tnu(k) = sr.transmission(freq);
+      //      if ((k>10) && (k<25))  cout << " DBG - K = " << k <<
+      //        " Nu= " << nu(k) << " Tnu= " << tnu(k) << endl; 
+      mtx(0,k) = nu(k);
+      mtx(1,k) = tnu(k);
+      img(k,0) = nu(k);
+      img(k,1) = tnu(k);
+    }
+    if ((typ == 0) && (narg > 6)) { // Writing to ppf  file
+      cout << "writing SpecRespVec(" << npt << ") to PPF file: " 
+           << (string)(arg[6]) << endl;
+      cout << sr ; 
+      cout << srv ; 
+      {
+        POutPersist pos(arg[6]);
+        pos << srv;
+      }
+      PrtTim("End of ImageR4->PPF ");
+    }
+
+  }
+  else { // Generation de RadSpectraVec from PowerLawSpectra
+    double a,nu0,dnu,b,fmin,fmax;
+    a = 1.0;
+    nu0 = 143.;
+    b = 0.;
+    dnu = 10.;
+    fmin = 10.;
+    fmax = 1000.;
+    sscanf(arg[2],"%lg,%lg,%lg,%lg,%lg,%lg",&a,&nu0,&dnu,&b,&fmin,&fmax);
+    cout << " PowerLawSpectra f = a ((nu-nu0)/dnu)^b " << endl;
+    sprintf(buff,"A=%g Nu0=%g DNu=%g B=%g FMin=%g FMax=%g",
+            a,nu0,dnu,b,fmin,fmax);
+    cout << "Decoded params: " << (string)buff << endl;
+    PowerLawSpectra rs(a,b, nu0, dnu, fmin, fmax);
+    cout << rs << endl;
+    cout << " Creating RadSpectraVec() ... " << endl;
+    Vector v1(10);
+    Vector v2(10);
+    RadSpectraVec rsv(v1, v2, fmin, fmax);
+    Vector & nu = rsv.getNuVec();
+    Vector & fnu = rsv.getFNuVec();
+    nu.ReSize(npt);
+    fnu.ReSize(npt);
+    double freq;
+    double dfreq = (fmax-fmin)/(npt-3);
+    for(k=0; k<npt; k++) {
+      freq = fmin+(k-1)*dfreq;
+      nu(k) = freq;
+      fnu(k) = rs.flux(freq);
+      //      if ((k>10) && (k<25))  cout << " DBG2 - K = " << k <<
+      //        " Nu= " << nu(k) << " Fnu= " << fnu(k) << endl; 
+      mtx(0,k) = nu(k);
+      mtx(1,k) = fnu(k);
+      img(k,0) = nu(k);
+      img(k,1) = fnu(k);
+    }
+  }
+
+  PrtTim("End of filling ");
+
+  {
+  cout << "\n Writing Matrix NRows= " << mtx.NRows() << "  NCols= " 
+       << mtx.NCols() << " to FITS file: " << (string)(arg[4]) << endl;
+  FitsOutFile fios(arg[4]);
+  fios.firstImageOnPrimaryHeader(false);  // use secondary header
+  DVList dvl;
+  if (typ == 0) 
+    dvl["PDMTYPE"] = "FGRSPEC";
+  dvl.SetComment("PDMTYPE", "Planck Data Model Type"); 
+  dvl["SOPHYVER"] =  SophyaVersion();
+  dvl.SetComment("SOPHYVER", "Sophya Version"); 
+  dvl["TGRSRKW"] =  "Test Keyword from tgrsr.cc";
+  fios.DVListIntoPrimaryHeader(dvl);  
+  fios << mtx ; 
+  PrtTim("End of Matrix->FITS ");
+  }
+
+  if (narg > 5) { // Writing ImageR4 fo FITS file
+    cout << "writing ImageR4(" << npt << ", 2) to FITS file: " 
+         << (string)(arg[5]) << endl;
+    FitsOutFile fios(arg[5]);
+    fios.firstImageOnPrimaryHeader(true);  // use primary  header
+    fios << img ; 
+    PrtTim("End of ImageR4->FITS ");
+  }
+}
+catch (PThrowable & exc) {
+  cerr << "tgrsr/Error Catched Exception " << (string)typeid(exc).name() 
+       << " - Msg= " << exc.Msg() << endl;
+}
+catch (...) {
+  cerr << "tgrsr/Error some other exception was caught ! " << endl;
+}
+
+  cout <<  " ============ End of tgrsr program ======== " << endl;
+  return 0;
+}
Index: /tags/V_Dec2002/SophyaProg/PMixer/tgsky.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/PMixer/tgsky.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PMixer/tgsky.cc	(revision 2309)
@@ -0,0 +1,136 @@
+#include "pmixer.h"
+#include "mapoperation.h"
+
+/*! \ingroup PMixer
+ * \file tgsky.cc
+ * \brief \b PROGRAM \b tgsky  <BR>
+ * \l Program which generates different types of random skies
+ */
+// ------------- Main program --------------
+
+int main(int narg, char* arg[]) 
+{
+
+  if ((narg < 5) || ((narg>1) && (strcmp(arg[1],"-h") == 0)) )  {
+    cout << " tgsky : Generation of random skies  " << endl;
+    cout << " Usage: tgsky NSide TypSky Params FitsFileName [PPFName] " << endl;
+    cout << "   - TypSky = 0  Params= m,sig  , Gaussian(m,sig) " << endl;
+    cout << "   - TypSky = 1  Params= m,sig  , OOFNoise(sig) + m" << endl;
+    cout << "   - TypSky = 2  Params= K,a,b,m  K*cos(a*teta)*sin(b*phi)+m" << endl;   
+    cout << "   - TypSky = 3  Params= theta,phi DIPOLE" << endl;   
+    exit(0);
+    }
+
+  try {
+  double teta,phi;
+  double gmoy=0., gsig=0.;
+#if !defined(SunOS) || !defined(__GNUG__)
+  // ca se plante sur Sun !
+  SophyaInit();
+#endif
+  InitTim();   // Initializing the CPU timer 
+  int  ns = atoi(arg[1]);
+  SphereHEALPix<float> sph(ns);
+
+  cout << "Filling SphereHEALPix<float> NSide= " << ns 
+       << "  NPixels= " << sph.NbPixels() << endl;
+
+  int typ = atoi(arg[2]);
+  double m,s,a,b,K;
+  double Theta,Phi;
+  Theta = 0.;
+  Phi   = 0.;
+  m = 0.;
+  s = 1.;
+  a = b = 1.;
+  K = 1.;
+  if ((typ < 0) || (typ > 3)) typ = 0;
+  if (typ < 2)  { 
+    sscanf(arg[3],"%lg,%lg",&m,&s);
+    cout << "  TypSky= " << typ << " m= " << m << " sig= " << s << endl;
+    if (typ == 1) cout << "  ---> OOFNoise() " << endl;
+    else cout << "  ---> NoiseGenerator() " << endl;
+  }
+  else if(typ==2) { 
+    sscanf(arg[3],"%lg,%lg,%lg,%lg",&K,&a,&b,&m);
+    cout << "  TypSky= " << typ << " K= " << m << " a= " << a << " b=" 
+         << b << " m= " << m << endl;
+    cout << "    ---> K * cos(a*teta) * sin(b*teta) + m" << endl;
+    }
+  else if(typ==3) { 
+    sscanf(arg[3],"%lg,%lg",&Theta,&Phi);
+    cout << "  TypSky= " << typ << " Theta= " << Theta << " phi= " << Phi ;
+    cout << "    ---> DIPOLE " << endl;
+    }
+
+  PrtTim("End of Init ");
+
+  if (typ == 2) {
+    for (int j=0;j<sph.NbPixels();j++)   {
+      sph.PixThetaPhi(j,teta,phi);
+      sph(j)= K * cos(a*teta)*sin(b*phi) + m;
+    }
+  }
+  else if(typ==3)
+    {
+      UnitVector vd(Theta,Phi);
+      UnitVector vc(Theta,Phi);
+      for(int i=0; i<sph.NbPixels(); i++)
+	{
+	  double Thetar,Phir;
+	  sph.PixThetaPhi(i,Thetar,Phir);      
+	  vc.SetThetaPhi(Thetar,  Phir);
+	  sph(i) += vd.Psc(vc);
+	}
+    }
+  else{
+    NoiseGenerator * ng;
+    if (typ == 0) ng = new NoiseGenerator(s);
+    else ng = new OOFNoise(s);    
+    for (int j=0;j<sph.NbPixels();j++)   sph(j) = ng->Noise()+m;
+    delete ng;
+  }
+  PrtTim("End of Fill ");
+
+  // Computing mean and sigma on the sphere 
+  MeanSig(sph.DataBlock(), gmoy, gsig);
+  cout << "SphereHEALPix<float> Mean= " << gmoy << "  Sigma = " << gsig << endl;
+  PrtTim("End of Mean-Sig ");
+
+  if (narg > 5) {
+   POutPersist s(arg[5]); 
+   FIO_SphereHEALPix<float> fiog(&sph) ;
+   fiog.Write(s);
+   cout << "SphereHEALPix<float> written to POutPersist file"  
+        << (string)(arg[5]) << endl;
+   PrtTim("End of WritePPF ");
+   }
+
+
+  { 
+  FitsOutFile fios(arg[4]);
+  fios.firstImageOnPrimaryHeader(false); // Use secondary header 
+  DVList dvl;
+  dvl["PDMTYPE"] = "COMPMAP";
+  dvl.SetComment("PDMTYPE", "Planck Data Model Type"); 
+  dvl["SOPHYVER"] =  SophyaVersion();
+  dvl.SetComment("SOPHYVER", "Sophya Version"); 
+  dvl["TGSKYKW"] =  "Test Keyword from tgsky.cc";
+  fios.DVListIntoPrimaryHeader(dvl);  
+  sph.Info() = dvl;
+  fios << sph; 
+  cout << "SphereHEALPix<float> written to FITS file " << (string)(arg[4]) << endl;
+  PrtTim("End of WriteFITS ");
+  }
+  }
+  catch (PThrowable & exc) {
+    cerr << " tgsky: Catched Exception - Msg= " << exc.Msg() 
+	 << " Type=" << (string)typeid(exc).name() << endl;
+  }
+  catch (...) {
+    cerr << " tgsky: Catched unknown exception (...) " << endl;
+  }
+  cout <<  " ============ End of tgsky program ======== " << endl;
+  return 0;
+}
+
Index: /tags/V_Dec2002/SophyaProg/PMixer/usedlibs
===================================================================
--- /tags/V_Dec2002/SophyaProg/PMixer/usedlibs	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PMixer/usedlibs	(revision 2309)
@@ -0,0 +1,6 @@
+SysTools
+NTools
+Samba
+SkyMap
+SkyT
+FitsIOServer
Index: /tags/V_Dec2002/SophyaProg/PMixer/usedslibs
===================================================================
--- /tags/V_Dec2002/SophyaProg/PMixer/usedslibs	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PMixer/usedslibs	(revision 2309)
@@ -0,0 +1,2 @@
+sophya
+extsophya
Index: /tags/V_Dec2002/SophyaProg/PrgMap/Makefile
===================================================================
--- /tags/V_Dec2002/SophyaProg/PrgMap/Makefile	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PrgMap/Makefile	(revision 2309)
@@ -0,0 +1,388 @@
+MODULECXXREPNAME :=  PrgMap
+include ../Mgr/Makefile.h
+ 
+ifdef NOSHLIB
+LIBF =  $(LIB)libFitsIOServer.a $(LIB)libSamba.a $(LIB)libSkyMap.a $(LIB)libSkyT.a $(LIB)libNTools.a $(LIB)libHiStats.a $(LIB)libTArray.a $(LIB)libSysTools.a 
+LIBS = -L$(LIB) -lFitsIOServer -lSamba -lSkyMap -lSkyT -lNTools -lHiStats -lTArray -lSysTools -lm
+ifeq ($(CXX),cxx)
+# librairie des instances de templates cxx
+LIBS := $(LIBS) -lertcxx
+endif
+else
+LIBF =  $(SLB)libsophya.so $(SLB)libextsophya.so
+LIBS = -L$(SLB) -lsophya -lextsophya  -lm
+endif
+LIBSORA := $(LIBS)
+LDLIBS := $(LIBS) $(LDLIBS)
+PROGS = $(EXE)cl2map $(EXE)map2cl $(EXE)prjsmap $(EXE)cremskfrsph \
+         $(EXE)msksphere $(EXE)extrapsph $(EXE)extrap2sph
+
+PROBJS = $(OBJ)cl2map.o $(OBJ)map2cl.o $(OBJ)prjsmap.o \
+         $(OBJ)cremskfrsph.o $(OBJ)msksphere.o \
+         $(OBJ)extrapsph.o $(OBJ)extrap2sph.o
+
+all: $(PROGS)
+
+clean:
+	rm -f $(PROGS)
+	rm -f $(PROBJS)
+	if [ -d $(OBJ)cxxrep_PrgMap ] ; then cd $(OBJ)cxxrep_PrgMap ; rm -f *.o ; fi
+
+cl2map: $(EXE)cl2map
+	@ echo cl2map done
+$(EXE)cl2map: $(OBJ)cl2map.o
+	$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@ 
+
+map2cl: $(EXE)map2cl
+	@ echo map2cl done
+$(EXE)map2cl: $(OBJ)map2cl.o
+	$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@ 
+
+prjsmap: $(EXE)prjsmap
+	@ echo prjsmap done
+$(EXE)prjsmap: $(OBJ)prjsmap.o
+	$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@ 
+
+cremskfrsph: $(EXE)cremskfrsph
+	@ echo cremskfrsph done
+$(EXE)cremskfrsph: $(OBJ)cremskfrsph.o
+	$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@ 
+
+msksphere: $(EXE)msksphere
+	@ echo msksphere done
+$(EXE)msksphere: $(OBJ)msksphere.o
+	$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@ 
+
+extrapsph: $(EXE)extrapsph
+	@ echo extrapsph done
+$(EXE)extrapsph: $(OBJ)extrapsph.o
+	$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@ 
+
+extrap2sph: $(EXE)extrap2sph
+	@ echo extrap2sph done
+$(EXE)extrap2sph: $(OBJ)extrap2sph.o
+	$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@ 
+  
+$(OBJ)cl2map.o: cl2map.cc $(INC)machdefs.h \
+ $(INC)nbmath.h \
+ $(INC)smathconst.h \
+ $(INC)timing.h \
+ $(INC)array.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)tmatrix.h \
+ $(INC)tvector.h \
+ $(INC)matharr.h \
+ $(INC)fioarr.h \
+ $(INC)sopemtx.h \
+ $(INC)skymap.h \
+ $(INC)spherethetaphi.h \
+ $(INC)sphericalmap.h \
+ $(INC)pixelmap.h \
+ $(INC)spherepos.h \
+ $(INC)unitvector.h \
+ $(INC)vector3d.h \
+ $(INC)longlat.h \
+ $(INC)utilgeom.h \
+ $(INC)spherehealpix.h \
+ $(INC)HEALPixUtils.h \
+ $(INC)localmap.h \
+ $(INC)fiospherethetaphi.h \
+ $(INC)fiospherehealpix.h \
+ $(INC)fiolocalmap.h \
+ $(INC)samba.h \
+ $(INC)alm.h \
+ $(INC)nbrandom.h \
+ $(INC)srandgen.h \
+ $(INC)triangmtx.h \
+ $(INC)bruit.h \
+ $(INC)circle.h \
+ $(INC)geometry.h \
+ $(INC)lambdaBuilder.h \
+ $(INC)misstime.h \
+ $(INC)mlobe.h \
+ $(INC)prefcount.h \
+ $(INC)scan.h \
+ $(INC)sphericaltransformserver.h \
+ $(INC)fftservintf.h \
+ $(INC)fftpserver.h \
+ $(INC)tod.h \
+ $(INC)sambainit.h \
+ $(INC)skymapinit.h \
+ $(INC)sophyainit.h \
+ $(INC)ntoolsinit.h \
+ $(INC)tarrinit.h \
+ $(INC)fitsspherehealpix.h \
+ $(INC)fitsfile.h \
+ $(INC)fitstarray.h
+$(OBJ)map2cl.o: map2cl.cc $(INC)machdefs.h \
+ $(INC)nbmath.h \
+ $(INC)smathconst.h \
+ $(INC)timing.h \
+ $(INC)array.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)tmatrix.h \
+ $(INC)tvector.h \
+ $(INC)matharr.h \
+ $(INC)fioarr.h \
+ $(INC)sopemtx.h \
+ $(INC)skymap.h \
+ $(INC)spherethetaphi.h \
+ $(INC)sphericalmap.h \
+ $(INC)pixelmap.h \
+ $(INC)spherepos.h \
+ $(INC)unitvector.h \
+ $(INC)vector3d.h \
+ $(INC)longlat.h \
+ $(INC)utilgeom.h \
+ $(INC)spherehealpix.h \
+ $(INC)HEALPixUtils.h \
+ $(INC)localmap.h \
+ $(INC)fiospherethetaphi.h \
+ $(INC)fiospherehealpix.h \
+ $(INC)fiolocalmap.h \
+ $(INC)samba.h \
+ $(INC)alm.h \
+ $(INC)nbrandom.h \
+ $(INC)srandgen.h \
+ $(INC)triangmtx.h \
+ $(INC)bruit.h \
+ $(INC)circle.h \
+ $(INC)geometry.h \
+ $(INC)lambdaBuilder.h \
+ $(INC)misstime.h \
+ $(INC)mlobe.h \
+ $(INC)prefcount.h \
+ $(INC)scan.h \
+ $(INC)sphericaltransformserver.h \
+ $(INC)fftservintf.h \
+ $(INC)fftpserver.h \
+ $(INC)tod.h \
+ $(INC)sambainit.h \
+ $(INC)skymapinit.h \
+ $(INC)sophyainit.h \
+ $(INC)ntoolsinit.h \
+ $(INC)tarrinit.h \
+ $(INC)fitsspherehealpix.h \
+ $(INC)fitsfile.h \
+ $(INC)fitstarray.h
+$(OBJ)prjsmap.o: prjsmap.cc $(INC)machdefs.h \
+ $(INC)nbmath.h \
+ $(INC)smathconst.h \
+ $(INC)timing.h \
+ $(INC)array.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)tmatrix.h \
+ $(INC)tvector.h \
+ $(INC)matharr.h \
+ $(INC)fioarr.h \
+ $(INC)sopemtx.h \
+ $(INC)skymap.h \
+ $(INC)spherethetaphi.h \
+ $(INC)sphericalmap.h \
+ $(INC)pixelmap.h \
+ $(INC)spherepos.h \
+ $(INC)unitvector.h \
+ $(INC)vector3d.h \
+ $(INC)longlat.h \
+ $(INC)utilgeom.h \
+ $(INC)spherehealpix.h \
+ $(INC)HEALPixUtils.h \
+ $(INC)localmap.h \
+ $(INC)fiospherethetaphi.h \
+ $(INC)fiospherehealpix.h \
+ $(INC)fiolocalmap.h \
+ $(INC)samba.h \
+ $(INC)alm.h \
+ $(INC)nbrandom.h \
+ $(INC)srandgen.h \
+ $(INC)triangmtx.h \
+ $(INC)bruit.h \
+ $(INC)circle.h \
+ $(INC)geometry.h \
+ $(INC)lambdaBuilder.h \
+ $(INC)misstime.h \
+ $(INC)mlobe.h \
+ $(INC)prefcount.h \
+ $(INC)scan.h \
+ $(INC)sphericaltransformserver.h \
+ $(INC)fftservintf.h \
+ $(INC)fftpserver.h \
+ $(INC)tod.h \
+ $(INC)sambainit.h \
+ $(INC)skymapinit.h \
+ $(INC)sophyainit.h \
+ $(INC)ntoolsinit.h \
+ $(INC)tarrinit.h \
+ $(INC)fitsspherehealpix.h \
+ $(INC)fitsfile.h \
+ $(INC)fitstarray.h
+$(OBJ)cremskfrsph.o: cremskfrsph.cc \
+ $(INC)machdefs.h \
+ $(INC)skymapinit.h \
+ $(INC)sophyainit.h \
+ $(INC)skymap.h \
+ $(INC)spherethetaphi.h \
+ $(INC)sphericalmap.h \
+ $(INC)smathconst.h \
+ $(INC)pixelmap.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)spherepos.h \
+ $(INC)unitvector.h \
+ $(INC)vector3d.h \
+ $(INC)longlat.h \
+ $(INC)utilgeom.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)spherehealpix.h \
+ $(INC)HEALPixUtils.h \
+ $(INC)localmap.h \
+ $(INC)fiospherethetaphi.h \
+ $(INC)fiospherehealpix.h \
+ $(INC)fiolocalmap.h \
+ $(INC)fitsspherehealpix.h \
+ $(INC)fitsfile.h
+$(OBJ)extrapsph.o: extrapsph.cc \
+ $(INC)machdefs.h \
+ $(INC)skymapinit.h \
+ $(INC)sophyainit.h \
+ $(INC)skymap.h \
+ $(INC)spherethetaphi.h \
+ $(INC)sphericalmap.h \
+ $(INC)smathconst.h \
+ $(INC)pixelmap.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)spherepos.h \
+ $(INC)unitvector.h \
+ $(INC)vector3d.h \
+ $(INC)longlat.h \
+ $(INC)utilgeom.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)spherehealpix.h \
+ $(INC)HEALPixUtils.h \
+ $(INC)localmap.h \
+ $(INC)fiospherethetaphi.h \
+ $(INC)fiospherehealpix.h \
+ $(INC)fiolocalmap.h \
+ $(INC)fitsspherehealpix.h \
+ $(INC)fitsfile.h
+$(OBJ)extrap2sph.o: extrap2sph.cc \
+ $(INC)machdefs.h \
+ $(INC)skymapinit.h \
+ $(INC)sophyainit.h \
+ $(INC)skymap.h \
+ $(INC)spherethetaphi.h \
+ $(INC)sphericalmap.h \
+ $(INC)smathconst.h \
+ $(INC)pixelmap.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)spherepos.h \
+ $(INC)unitvector.h \
+ $(INC)vector3d.h \
+ $(INC)longlat.h \
+ $(INC)utilgeom.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)spherehealpix.h \
+ $(INC)HEALPixUtils.h \
+ $(INC)localmap.h \
+ $(INC)fiospherethetaphi.h \
+ $(INC)fiospherehealpix.h \
+ $(INC)fiolocalmap.h \
+ $(INC)fitsspherehealpix.h \
+ $(INC)fitsfile.h
+$(OBJ)msksphere.o: msksphere.cc \
+ $(INC)machdefs.h \
+ $(INC)skymapinit.h \
+ $(INC)sophyainit.h \
+ $(INC)skymap.h \
+ $(INC)spherethetaphi.h \
+ $(INC)sphericalmap.h \
+ $(INC)smathconst.h \
+ $(INC)pixelmap.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)mutyv.h \
+ $(INC)spherepos.h \
+ $(INC)unitvector.h \
+ $(INC)vector3d.h \
+ $(INC)longlat.h \
+ $(INC)utilgeom.h \
+ $(INC)tvector.h \
+ $(INC)tmatrix.h \
+ $(INC)tarray.h \
+ $(INC)basarr.h \
+ $(INC)ndatablock.h \
+ $(INC)utilarr.h \
+ $(INC)spherehealpix.h \
+ $(INC)HEALPixUtils.h \
+ $(INC)localmap.h \
+ $(INC)fiospherethetaphi.h \
+ $(INC)fiospherehealpix.h \
+ $(INC)fiolocalmap.h \
+ $(INC)fitsspherehealpix.h \
+ $(INC)fitsfile.h
Index: /tags/V_Dec2002/SophyaProg/PrgMap/cl2map.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/PrgMap/cl2map.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PrgMap/cl2map.cc	(revision 2309)
@@ -0,0 +1,208 @@
+#include "machdefs.h"    // Definitions specifiques SOPHYA
+
+#include <math.h>
+#include <iostream.h>
+
+#include "nbmath.h"
+#include "timing.h"
+
+#include "array.h"
+#include "skymap.h"
+#include "samba.h"
+#include "sambainit.h"
+#include "fitsspherehealpix.h"
+#include "fitstarray.h"
+
+/*!
+  \defgroup PrgMap PrgMap module
+  This module contains simple programs to perform various tasks
+  on spherical maps.
+*/
+
+/*!
+  \ingroup PrgMap
+  \file cl2map.cc
+  \brief \b cl2map: generates spherical maps from power spectra (C(l))
+
+  \verbatim
+
+  csh> cl2map -h
+  SOPHYA Version  1.1 Revision 0 (V_Fev2001) -- Mar  9 2001 15:45:31 cxx
+
+  cl2map : Spherical harmonics synthesis - Power spectrum C_l -> HEALPix map
+  Usage: cl2map [-float/-r4] [-msph pixp] [-beam fwhm]
+         [-fitsin] [-fitsout] [-autoinirand] InFileName OutFileName
+   -float (-r4): single precision C_l and map (default = double)
+   -msph pix: Spherical map pixelization parameter
+              nside=2^n for HEALPix - default=128
+                lmax = 2^n  default=128
+   -beam fwhm : Beam moothing (in l-space) FWHM in arcmin, default=0
+   -fitsout: Select the FITS format for the output map (default PPF format)
+   -fitsin : Select the FITS format for the input vector (default PPF format)
+   -autoinirand : Automtatic random number generator initialization
+   InFileName : Input file name containing the C_l vector
+   OutFileName : Output file name (HEALPix map)
+
+  \endverbatim
+*/
+
+
+/* Nouvelle-Fonction */
+void Usage(bool fgerr)
+{
+  cout << endl;
+  if (fgerr) {
+    cout << " cl2map : Argument Error ! cl2map -h for usage " << endl; 
+    exit(1);
+  }
+  else {
+    cout << " cl2map : Spherical harmonics synthesis - Power spectrum C_l -> HEALPix map \n" 
+	 << " Usage: cl2map [-float/-r4] [-msph pixp] [-beam fwhm] \n" 
+	 << "        [-fitsin] [-fitsout] [-autoinirand] InFileName OutFileName \n" 
+	 << "   -float (-r4): single precision C_l and map (default = double) \n"
+	 << "   -msph pix: Spherical map pixelization parameter \n" 
+	 << "              nside=2^n for HEALPix - default=128 \n"
+	 << "                lmax = 2^n  default=128 \n"
+	 << "   -beam fwhm : Beam moothing (in l-space) FWHM in arcmin, default=0 \n"
+	 << "   -fitsout: Select the FITS format for the output map (default PPF format) \n"
+	 << "   -fitsin : Select the FITS format for the input vector (default PPF format) \n"
+	 << "   -autoinirand : Automtatic random number generator initialization \n" 
+	 << "   InFileName : Input file name containing the C_l vector \n" 
+	 << "   OutFileName : Output file name (HEALPix map) \n" << endl;
+    exit(0);
+  }  
+}
+
+/* Nouvelle-Classe */
+template <class T> 
+class _Cl2Map {
+public :
+static void BuildMap(string & infile, string & outfile, int msph, double beam, 
+		     bool fgfitsin, bool fgfitsout)
+{
+  double deg2rad =  M_PI/180.;
+  double minute2rad =  M_PI/(180.*60.);
+
+  TArray<T> cla;
+  SphereHEALPix<T> sph;
+  if (fgfitsin) {
+    cout << "--- Reading Input FITS file " << infile << endl; 
+    FitsInFile fii(infile);
+    fii >> cla;
+  }
+  else {
+    cout << "--- Reading Input PPF file " << infile << endl; 
+    PInPersist ppi(infile);
+    ppi >> cla;
+  }
+  TVector<T> clvec(cla);
+  cout << " Input vector : " ; 
+  clvec.Show(); 
+  T min, max;
+  double mean, sigma;
+  clvec.MinMax(min, max);
+  MeanSigma(clvec, mean, sigma);
+  cout << " C_l.Min= " << min << " C_l.Max= " << max 
+       << " C_l.Mean= " << mean << " C_l.Sigma= " << sigma << endl;
+
+  cout << "--- Calling  GenerateFromCl() (beam= " << beam 
+       << "' msph= " << msph << ") beam=" << beam*minute2rad << " rad" << endl;
+  // on cree la carte 
+  SphericalTransformServer<T> sphtr;
+  sphtr.GenerateFromCl(sph, msph, clvec, beam*minute2rad);
+
+  cout << " Output map : NbPixels= " <<  sph.NbPixels() << " NSide= " 
+       << sph.SizeIndex() << " Resolution= "
+       << sqrt(sph.PixSolAngle(0))/minute2rad << " Arcminutes " << endl;
+
+  if (fgfitsout) {
+    cout << "--- Writing map to Output FITS file " << outfile << endl;
+    string dum = "rm -f "; dum += outfile; system(dum.c_str()); 
+    FitsOutFile fio(outfile, FitsFile::clear);
+    fio << sph;
+  }
+  else {
+    cout << "--- Writing map to Output PPF file " << outfile << endl; 
+    POutPersist ppo(outfile);
+    ppo << sph;
+  }
+}
+
+};
+
+/* Main-Program */
+int main(int narg, char *arg[])
+{
+  if ((narg > 1) && (strcmp(arg[1],"-h") == 0) ) Usage(false);
+  
+  int msph = 128;
+  double beam = 0.;
+  string infile;
+  string outfile;
+  bool fgfitsin = false;
+  bool fgfitsout = false;
+  bool fginirand = false;
+  bool fgr4 = false;
+  cout << " cl2map : Decoding command line options ... " << endl;
+
+  int ko=1;
+  for (int k=1; k<narg; k++)   {
+    if (strcmp(arg[k], "-msph") == 0)  {
+	if (k == narg-1) Usage(true);  // -msph est suivi d'un argument 
+      msph = atoi(arg[k+1]);  k++;       // k++ pour sauter au suivant
+    }
+    else if (strcmp(arg[k], "-beam") == 0)  {
+	if (k == narg-1) Usage(true);  // -beam est suivi d'un argument 
+      beam = atof(arg[k+1]);  k++;       // k++ pour sauter au suivant
+    }
+    else if (strcmp(arg[k], "-fitsin") == 0) {
+      fgfitsin = true;  
+    }
+    else if (strcmp(arg[k], "-fitsout") == 0) {
+      fgfitsout = true;  
+    }
+    else if (strcmp(arg[k], "-autoinirand") == 0) {
+      fginirand = true;  
+    }
+    else if ((strcmp(arg[k], "-float") == 0) || (strcmp(arg[k], "-r4") == 0) ) {
+      fgr4 = true;  
+    }
+   
+    else { ko = k; break; }  // Debut des noms
+  }
+
+  if ((narg-ko) < 2)  Usage(true); 
+  infile = arg[ko];
+  outfile = arg[ko+1];
+  
+  // Bloc try de gestion des exception 
+  try {
+    InitTim();
+    SophyaInit();
+    if (fginirand) {
+      cout << " Setting random number generator seed (using time) " << endl; 
+      Auto_Ini_Ranf(1);
+    }
+    if (fgr4) {
+      cout << " Power spectrum C_l (r_4) --> SphereHEALPix<r_4> (float) " << endl;
+      _Cl2Map<r_4>::BuildMap(infile, outfile, msph, beam, fgfitsin, fgfitsout);
+    }
+    else {
+      cout << " Power spectrum C_l (r_8) --> SphereHEALPix<r_8> (double) " << endl;
+      _Cl2Map<r_8>::BuildMap(infile, outfile, msph, beam, fgfitsin, fgfitsout);
+    }
+  }
+  catch (PThrowable & exc) {   // Exceptions de SOPHYA
+    cerr << " cl2map: Catched Exception " << (string)typeid(exc).name()
+         << " - Msg= " << exc.Msg() << endl;
+  }
+  catch (...) {    // Autres Exceptions
+    cerr << " cl2map: some other exception was caught ! " << endl;
+  }
+  
+  PrtTim("End of cl2map ");
+  return(0);
+}
+
+
+  
Index: /tags/V_Dec2002/SophyaProg/PrgMap/cremskfrsph.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/PrgMap/cremskfrsph.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PrgMap/cremskfrsph.cc	(revision 2309)
@@ -0,0 +1,146 @@
+// Creation d'une sphere de masque a partir d'une sphere de valeurs
+//         cmv 13/6/01
+// cremskfrsph -m 0.1 -v 1.,0. sph143k05_e.fits sphmskw.fits
+// cremskfrsph -n -m -1.e-30. -M 1.e-30. -v 1.,0. sph143k05.fits sphmsk.fits
+#include "machdefs.h"
+#include <unistd.h>
+#include <stdexcept>
+#include <iostream.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "skymapinit.h"
+#include "skymap.h"
+#include "fitsspherehealpix.h" 
+
+/*!
+  \ingroup PrgMap
+  \file cremskfrsph.cc
+  \brief \b cremskfrsph: Create a masked sphere from a sphere of datas
+  \verbatim
+csh> cremskfrsph -h
+cremskfrsph [-n -m min -M max -v valmsk,inimsk] sphval.fits sphmask.fits
+ -m min : min value
+ -M max : max value
+    condition for filling masque is: min<=sphere_value<=max
+          (fill mask with valmsk)     (bounds are included)
+ -n : negate the condition
+      (switch to: sphere_value<min || max<sphere_value)
+ -b bmin,bmax : on coupe en latitude entre [bmin,bmax] degres (def=no+cut)
+ -v valmsk,inimsk:
+    valmsk: value to be put into mask if ok (def=1.)
+    inimsk: initialisation value for the mask (def=0.)
+  \endverbatim
+*/
+
+void usage();
+void usage()
+{
+cout<<"cremskfrsph [-n -m min -M max -v valmsk,inimsk] sphval.fits sphmask.fits"<<endl
+    <<" -m min : min value"<<endl
+    <<" -M max : max value"<<endl
+    <<"    condition for filling masque is: min<=sphere_value<=max"<<endl
+    <<"          (fill mask with valmsk)     (bounds are included)"<<endl
+    <<" -n : negate the condition"<<endl
+    <<"      (switch to: sphere_value<min || max<sphere_value)"<<endl
+    <<" -b bmin,bmax : on coupe en latitude entre [bmin,bmax] degres (def=no+cut)"<<endl
+    <<" -v valmsk,inimsk:"<<endl
+    <<"    valmsk: value to be put into mask if ok (def=1.)"<<endl
+    <<"    inimsk: initialisation value for the mask (def=0.)"<<endl;
+}
+
+
+int main(int narg, char* arg[])
+{
+double vmin=-1.e30,vmax=1.e30,vmask=1.,vmaskini=0., bmin=1.,bmax=-1.;
+bool tstmin=false,tstmax=false,negate=false;
+string dum;
+int c;
+while((c = getopt(narg,arg,"hnm:M:v:b:")) != -1) {
+  switch (c) {
+  case 'n' :
+    negate = true;
+    break;
+  case 'm' :
+    sscanf(optarg,"%lf",&vmin);
+    tstmin = true;
+    break;
+  case 'M' :
+    sscanf(optarg,"%lf",&vmax);
+    tstmax = true;
+    break;
+  case 'v' :
+    sscanf(optarg,"%lf,%lf",&vmask,&vmaskini);
+    break;
+  case 'b' :
+    sscanf(optarg,"%lf,%lf",&bmin,&bmax);
+    break;
+  case 'h' :
+  default:
+    usage(); exit(1);
+  }
+}
+
+if(optind+1>=narg) {usage(); exit(1);}
+char * sphval = arg[optind];
+char * sphmsk = arg[optind+1];
+
+if(negate) dum = ".NOT."; else dum = "";
+cout<<"Sphere values : "<<sphval<<endl
+    <<"Sphere mask   : "<<sphmsk<<endl
+    <<"  ...min("<<tstmin<<") "<<vmin<<endl
+    <<"     max("<<tstmax<<") "<<vmax<<endl
+    <<"  ...negate "<<negate<<endl
+    <<"  ...mask set value "<<vmask<<endl
+    <<"     mask init value "<<vmaskini<<endl
+    <<"Cut latitude between "<<bmin<<" and "<<bmax<<" deg"<<endl
+    <<"Condition on data to set the mask: "
+    <<dum<<"( "<<vmin<<" <= V <= "<<vmax<<" )"<<endl;
+
+// Lecture de la sphere Healpix des valeurs
+SphereHEALPix<r_8> sph;
+FitsInFile sfits(sphval);
+sfits >> sph;
+cout<<"Opening Sphere HEALPix for testing values :"<<endl
+    <<"          Type of map : "<<sph.TypeOfMap()<<endl
+    <<"     Number of pixels : "<<sph.NbPixels()<<endl
+    <<"                 Nlat : "<<sph.SizeIndex()<<endl;
+
+// Ouverture de la sphere Healpix pour le masque
+cout<<"Creating Mask Sphere"<<endl;
+SphereHEALPix<r_8> sphm(sph,false);
+
+// Filling Mask Sphere with cut on values
+cout<<"Filling Mask"<<endl;
+double thetamin = (90.-bmax) * M_PI/180.;
+double thetamax = (90.-bmin) * M_PI/180.;
+uint_4 nmask = 0;
+for(int_4 i=0;i<sph.NbPixels();i++) {
+  sphm(i) = vmaskini;
+
+  bool skp = (tstmin || tstmax) ? negate : false;
+  if((tstmin && sph(i)<vmin) || (tstmax && sph(i)>vmax)) skp = !negate;
+  if(skp) continue;   // Do nothing
+
+  if(bmin<bmax) {
+    double theta,phi;
+    sphm.PixThetaPhi(i,theta,phi);
+    if(theta>=thetamin && theta<=thetamax) continue;
+  }
+
+  sphm(i) = vmask;
+  nmask++;
+}
+cout<<"    .... Number of values set in mask   : "<<nmask<<endl;
+cout<<"    .... Fraction of values set in mask : "
+    <<(r_8)nmask/sph.NbPixels()*100.<<" %"<<endl;
+
+// Ecriture de la sphere Healpix sur fits
+{
+dum = "rm -f "; dum += sphmsk; system(dum.c_str());
+FitsOutFile swfits(sphmsk,FitsFile::clear);
+cout<<"Writing Mask Sphere Fits file"<<endl;
+swfits<<sphm;
+}
+
+return 0;
+}
Index: /tags/V_Dec2002/SophyaProg/PrgMap/extrap2sph.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/PrgMap/extrap2sph.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PrgMap/extrap2sph.cc	(revision 2309)
@@ -0,0 +1,195 @@
+// Pour boucher les trous d'une sphere HEALPIX en utilisant
+// une autre sphere HEALPIX
+//             cmv 13/6/01
+// extrap2sph -w sph143k05_e.fits sph143k05.fits sphred.fits sphout_2.fits
+// extrap2sph -m -1.e-30 -M +1.e-30 sph143k05.fits sphred.fits sphout_22.fits
+#include "machdefs.h"
+#include <unistd.h>
+#include <stdexcept>
+#include <iostream.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "skymapinit.h"
+#include "skymap.h"
+#include "fitsspherehealpix.h" 
+
+/*!
+  \ingroup PrgMap
+  \file extrap2sph.cc
+  \brief \b extrap2sph: Fill holes in a sphere of datas by using
+  an other sphere of datas.
+  A mask to define the place to be tested in the sphere might be given.
+  \verbatim
+csh> extrap2sph -h
+extrap2sph [-m valmin -M valmax -r rvalmin -R rvalmax]
+           [-w sphinw.fits] sphin.fits sphred.fits sphout.fits
+ -w sphinw.fits : input sphere  weight, if sphinw_value<=0. (def=NULL)
+                  if sphinw_value<=0. pixel has not to be filled
+ -m minval : min value to identify EMPTY pixel of sphin (def=no_test)
+ -M maxval : max value to identify EMPTY pixel of sphin (def=no_test)
+    condition for EMPTY pixel is (minval<=val<=maxval)
+ -n : negate the previous condition, condition for EMPTY pixel
+      becomes: (val<minval || maxval<val)
+ -r rminval : min value to identify GOOD pixel of sphred (def=no_test)
+ -R rmaxval : max value to identify GOOD pixel of sphred (def=no_test)
+    condition for GOOD pixel is (minval<=val<=maxval)
+ -n : negate the previous condition, condition for GOOD pixel
+      becomes: (val<minval || maxval<val)
+ sphin.fits   : input sphere
+ sphred.fits  : input reducted sphere
+ sphout.fits  : output sphere
+  \endverbatim
+*/
+
+void usage();
+void usage()
+{
+cout<<"extrap2sph [-m valmin -M valmax -r rvalmin -R rvalmax]"<<endl
+    <<"           [-w sphinw.fits] sphin.fits sphred.fits sphout.fits"<<endl
+    <<" -w sphinw.fits : input sphere  weight, if sphinw_value<=0. (def=NULL)"<<endl
+    <<"                  if sphinw_value<=0. pixel has not to be filled"<<endl
+    <<" -m minval : min value to identify EMPTY pixel of sphin (def=no_test)"<<endl
+    <<" -M maxval : max value to identify EMPTY pixel of sphin (def=no_test)"<<endl
+    <<"    condition for EMPTY pixel is (minval<=val<=maxval)"<<endl
+    <<" -n : negate the previous condition, condition for EMPTY pixel"<<endl
+    <<"      becomes: (val<minval || maxval<val)"<<endl
+    <<" -r rminval : min value to identify GOOD pixel of sphred (def=no_test)"<<endl
+    <<" -R rmaxval : max value to identify GOOD pixel of sphred (def=no_test)"<<endl
+    <<"    condition for GOOD pixel is (minval<=val<=maxval)"<<endl
+    <<" -n : negate the previous condition, condition for GOOD pixel"<<endl
+    <<"      becomes: (val<minval || maxval<val)"<<endl
+    <<" sphin.fits   : input sphere"<<endl
+    <<" sphred.fits  : input reducted sphere"<<endl
+    <<" sphout.fits  : output sphere"<<endl;
+}
+
+int main(int narg, char* arg[])
+{
+bool tstmin=false,  tstmax=false,  neg=false;
+bool rtstmin=false, rtstmax=false, rneg=false;
+double valmin=0., valmax=0., rvalmin=0., rvalmax=0.;
+char * fsphinw = NULL;
+string dum;
+int c;
+while((c = getopt(narg,arg,"hnNm:M:r:R:w:")) != -1) {
+  switch (c) {
+  case 'n' :
+    neg = true;
+    break;
+  case 'N' :
+    rneg = true;
+    break;
+  case 'm' :
+    sscanf(optarg,"%lf",&valmin);
+    tstmin=true;
+    break;
+  case 'M' :
+    sscanf(optarg,"%lf",&valmax);
+    tstmax=true;
+    break;
+  case 'r' :
+    sscanf(optarg,"%lf",&rvalmin);
+    rtstmin=true;
+    break;
+  case 'R' :
+    sscanf(optarg,"%lf",&rvalmax);
+    rtstmax=true;
+    break;
+  case 'w' :
+    fsphinw = optarg;
+    break;
+  case 'h' :
+  default:
+    usage(); exit(1);
+  }
+}
+
+if(optind+2>=narg) {usage(); exit(1);}
+char * fsphin  = arg[optind];
+char * fsphred = arg[optind+1];
+char * fsphout = arg[optind+2];
+
+cout<<"Input Sphere          : "<<fsphin<<endl
+    <<"Input Weight Sphere   : "<<fsphinw<<endl
+    <<"Input Reducted Sphere : "<<fsphred<<endl
+    <<"Output Sphere         : "<<fsphout<<endl;
+if(neg) dum = ".NOT."; else dum="";
+cout<<"- Sphere - test min("<<tstmin<<") : "<<valmin<<endl
+    <<"           test max("<<tstmax<<") : "<<valmax<<endl
+    <<"           negate("<<neg<<")"<<endl
+    <<"  - Condition for EMPTY pixel in Sphere is :"<<endl
+    <<"    "<<dum<<"( "<<valmin<<" <= V <= "<<valmax<<" )"<<endl;
+if(rneg) dum = ".NOT."; else dum="";
+cout<<"- Reducted Sphere - test min("<<rtstmin<<") : "<<rvalmin<<endl
+    <<"                    test max("<<rtstmax<<") : "<<rvalmax<<endl
+    <<"                    negate("<<rneg<<")"<<endl
+    <<"  - Condition for GOOD pixel in Reducted Sphere is :"<<endl
+    <<"    "<<dum<<"( "<<rvalmin<<" <= V <= "<<rvalmax<<" )"<<endl;
+
+// Lecture des spheres
+SphereHEALPix<r_8> sphin;
+{FitsInFile sfits(fsphin); sfits >> sphin;}
+int nlat = sphin.SizeIndex();
+cout<<"Opening Input Sphere :"<<endl
+    <<"          Type of map : "<<sphin.TypeOfMap()<<endl
+    <<"     Number of pixels : "<<sphin.NbPixels()<<endl
+    <<"                 Nlat : "<<sphin.SizeIndex()<<endl;
+
+SphereHEALPix<r_8> sphinw;
+if(fsphinw) {
+  FitsInFile sfits(fsphinw);
+  sfits >> sphinw;
+  cout<<"Opening Input Weight Sphere :"<<endl
+      <<"          Type of map : "<<sphinw.TypeOfMap()<<endl
+      <<"     Number of pixels : "<<sphinw.NbPixels()<<endl
+      <<"                 Nlat : "<<sphinw.SizeIndex()<<endl;
+  if(sphinw.SizeIndex()!=nlat) {
+    cout<<"Incompatible sphin sphinw"<<endl;
+    exit(2);
+  }
+}
+
+SphereHEALPix<r_8> sphred;
+{FitsInFile sfits(fsphred); sfits >> sphred;}
+cout<<"Opening Input Reducted Sphere :"<<endl
+    <<"          Type of map : "<<sphred.TypeOfMap()<<endl
+    <<"     Number of pixels : "<<sphred.NbPixels()<<endl
+    <<"                 Nlat : "<<sphred.SizeIndex()<<endl;
+
+// Filling hole for Output Sphere
+cout<<"...Filling hole for Output Sphere"<<endl;
+uint_4 n=0, n0=0;
+for(int_4 i=0;i<sphin.NbPixels();i++) {
+  bool skp;
+  if(fsphinw) if(sphinw(i)<=0.) continue; // Pixel out of acceptance!
+
+  // Test if pixel of Sphere has to be extrapolated
+  skp = (tstmin || tstmax) ? neg : false;
+  if((tstmin && sphin(i)<valmin) || (tstmax && sphin(i)>valmax)) skp = !neg;
+  if(skp) continue;   // Do nothing
+
+  double theta,phi;
+  sphin.PixThetaPhi(i,theta,phi);
+  int_4 ir = sphred.PixIndexSph(theta,phi);
+
+  // Test if pixel of Reducted Sphere is good
+  skp = (rtstmin || rtstmax) ? rneg : false;
+  if((rtstmin && sphred(i)<rvalmin) || (rtstmax && sphred(i)>rvalmax)) skp = !rneg;
+  if(skp) continue;   // Do nothing
+
+  sphin(i) = sphred(ir);
+  n++; if(sphred(ir)!=0.) n0++;
+}
+cout<<"      Number of pixels filled "
+    <<n<<" (not null values "<<n0<<")"<<endl;
+
+// Ecriture de la sphere
+{
+dum = "rm -f "; dum += fsphout; system(dum.c_str());
+FitsOutFile sfits(fsphout, FitsFile::clear);
+cout<<"Writing Output Sphere Fits file"<<endl;
+sfits<<sphin;
+}
+
+exit(0);
+}
Index: /tags/V_Dec2002/SophyaProg/PrgMap/extrapsph.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/PrgMap/extrapsph.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PrgMap/extrapsph.cc	(revision 2309)
@@ -0,0 +1,178 @@
+// Pour boucher les trous d'une sphere HEALPIX en la clusterisant
+// dans une sphere plus petite puis en la re-extrapolant.
+//                    cmv 13/6/01
+// extrapsph -r 2 sph143k05.fits sph143k05_e.fits
+//                sphout.fits sphoutw.fits sphred.fits sphredw.fits
+#include "machdefs.h"
+#include <unistd.h>
+#include <stdexcept>
+#include <iostream.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "skymapinit.h"
+#include "skymap.h"
+#include "fitsspherehealpix.h" 
+
+/*!
+  \ingroup PrgMap
+  \file extrapsph.cc
+  \brief \b extrapsph: Fill holes in a sphere of datas by reducing
+  it size and re-extrapolating.
+  \verbatim
+csh> extrapsph -h
+extrapsph [-r reduc_factor] sphin.fits sphinw.fits
+          sphout.fits [sphout_w.fits sphred.fits sphred_w.fits]
+ -r reduc : reduction factor for clustering (must be 2^n, def=2)
+ sphin.fits    : input sphere
+ sphin_w.fits  : input sphere filling weight
+ sphout.fits   : output sphere
+ sphout_w.fits : output sphere filling weight
+ sphred.fits   : output reducted sphere
+ sphred_w.fits : output reducted sphere filling weight
+  \endverbatim
+*/
+
+void usage();
+void usage()
+{
+cout<<"extrapsph [-r reduc_factor] sphin.fits sphinw.fits"<<endl
+    <<"          sphout.fits [sphout_w.fits"
+    <<" sphred.fits sphred_w.fits]"<<endl
+    <<" -r reduc : reduction factor for clustering (must be 2^n, def=2)"<<endl
+    <<" sphin.fits    : input sphere"<<endl
+    <<" sphin_w.fits  : input sphere filling weight"<<endl
+    <<" sphout.fits   : output sphere"<<endl
+    <<" sphout_w.fits : output sphere filling weight"<<endl
+    <<" sphred.fits   : output reducted sphere"<<endl
+    <<" sphred_w.fits : output reducted sphere filling weight"<<endl;
+}
+
+int main(int narg, char* arg[])
+{
+int red=2;
+string dum;
+int c;
+while((c = getopt(narg,arg,"hr:")) != -1) {
+  switch (c) {
+  case 'r' :
+    sscanf(optarg,"%d",&red);
+    break;
+  case 'h' :
+  default:
+    usage(); exit(1);
+  }
+}
+
+if(optind+2>=narg) {usage(); exit(1);}
+char * fsphin   = arg[optind];
+char * fsphinw  = arg[optind+1];
+char * fsphout  = arg[optind+2];
+char * fsphoutw = NULL;
+char * fsphred = NULL;
+char * fsphredw = NULL;
+if(optind+3<narg) fsphoutw = arg[optind+3];
+if(optind+4<narg) fsphred = arg[optind+4];
+if(optind+5<narg) fsphredw = arg[optind+5];
+
+cout<<"Input Sphere : "<<fsphin<<endl
+    <<"Input Weight Sphere : "<<fsphinw<<endl
+    <<"Output Sphere : "<<fsphout<<endl
+    <<"Output Weight Sphere : "<<fsphoutw<<endl
+    <<"Output Reducted Sphere : "<<fsphred<<endl
+    <<"Output Reducted Weight Sphere : "<<fsphredw<<endl
+    <<"Reduction : "<<red<<endl;
+
+// Lecture des spheres
+SphereHEALPix<r_8> sphin;
+{FitsInFile sfits(fsphin); sfits >> sphin;}
+int nlat = sphin.SizeIndex();
+int nlatr = nlat/red;
+cout<<"Opening Input Sphere :"<<endl
+    <<"          Type of map : "<<sphin.TypeOfMap()<<endl
+    <<"     Number of pixels : "<<sphin.NbPixels()<<endl
+    <<"                 Nlat : "<<sphin.SizeIndex()<<endl;
+
+SphereHEALPix<r_8> sphinw;
+{FitsInFile sfits(fsphinw); sfits >> sphinw;}
+cout<<"Opening Input Weight Sphere :"<<endl
+    <<"          Type of map : "<<sphinw.TypeOfMap()<<endl
+    <<"     Number of pixels : "<<sphinw.NbPixels()<<endl
+    <<"                 Nlat : "<<sphinw.SizeIndex()<<endl;
+if(sphinw.SizeIndex()!=nlat) {
+  cout<<"Incompatible sphin sphinw"<<endl;
+  exit(2);
+}
+
+// Creation des spheres reduites
+cout<<"Creating Reducted Spheres : nlatr = "<<nlatr<<endl;
+SphereHEALPix<r_8> sphred(nlatr);
+  sphred.SetPixels(0.);
+SphereHEALPix<r_8> sphredw(nlatr);
+  sphredw.SetPixels(0.);
+cout<<"     Number of pixels : "<<sphred.NbPixels()<<endl
+    <<"                 Nlat : "<<sphred.SizeIndex()<<endl;
+
+// Filling reducted spheres
+cout<<"...Filling Reducted Spheres"<<endl;
+uint_4 n=0;
+int_4 i, ir;
+for(i=0;i<sphin.NbPixels();i++) {
+  if(sphinw(i)<=0.) continue;
+  double theta,phi;
+  sphin.PixThetaPhi(i,theta,phi);
+  ir = sphred.PixIndexSph(theta,phi);
+  sphred(ir)  += sphin(i)*sphinw(i);
+  sphredw(ir) += sphinw(i);
+  n++;
+}
+cout<<"      Input Sphere: Number of filled pixels "<<n<<endl;
+cout<<"...Computing Reducted Spheres"<<endl;
+n=0;
+for(ir=0;ir<sphred.NbPixels();ir++)
+  if(sphredw(ir) > 0.) {sphred(ir) /= sphredw(ir); n++;}
+cout<<"      Reducted Sphere: Number of pixels filled "<<n<<endl;
+
+// Filling hole for Output Spheres
+cout<<"...Filling hole for Output Spheres"<<endl;
+n=0;
+for(i=0;i<sphin.NbPixels();i++) {
+  if(sphinw(i)>0.) continue;
+  double theta,phi;
+  sphin.PixThetaPhi(i,theta,phi);
+  int_4 ir = sphred.PixIndexSph(theta,phi);
+  if(sphredw(ir)<=0.) continue;
+  sphin(i)  = sphred(ir);
+  // On passe en negatif les pixels qui ont ete extrapoles
+  sphinw(i) = -sphredw(ir);
+  n++;
+}
+cout<<"      Output Sphere: Number of pixels filled "<<n<<endl;
+
+// Ecriture des spheres
+{
+dum = "rm -f "; dum += fsphout; system(dum.c_str());
+FitsOutFile sfits(fsphout, FitsFile::clear);
+cout<<"Writing Output Sphere Fits file"<<endl;
+sfits<<sphin;
+}
+if(fsphoutw) {
+dum = "rm -f "; dum += fsphoutw; system(dum.c_str());
+FitsOutFile sfits(fsphoutw, FitsFile::clear);
+cout<<"Writing Output Sphere Weight Fits file"<<endl;
+sfits<<sphinw;
+}
+if(fsphred) {
+dum = "rm -f "; dum += fsphred; system(dum.c_str());
+FitsOutFile sfits(fsphred, FitsFile::clear);
+cout<<"Writing Reducted Sphere Fits file"<<endl;
+sfits<<sphred;
+}
+if(fsphredw) {
+dum = "rm -f "; dum += fsphredw; system(dum.c_str());
+FitsOutFile sfits(fsphredw, FitsFile::clear);
+cout<<"Writing Reducted Sphere Weight Fits file"<<endl;
+sfits<<sphredw;
+}
+
+exit(0);
+}
Index: /tags/V_Dec2002/SophyaProg/PrgMap/map2cl.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/PrgMap/map2cl.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PrgMap/map2cl.cc	(revision 2309)
@@ -0,0 +1,225 @@
+#include "machdefs.h"    // Definitions specifiques SOPHYA
+
+#include <math.h>
+#include <iostream.h>
+
+#include "nbmath.h"
+#include "timing.h"
+
+#include "array.h"
+#include "skymap.h"
+#include "samba.h"
+#include "sambainit.h"
+#include "fitsspherehealpix.h"
+#include "fitstarray.h"
+
+
+/*!
+  \ingroup PrgMap
+  \file map2cl.cc
+  \brief \b map2cl: Computes power spectra (C(l)) on spherical maps.
+
+  \verbatim
+
+  csh> map2cl -h
+  SOPHYA Version  1.1 Revision 0 (V_Fev2001) -- Mar  9 2001 15:45:31 cxx
+
+  map2cl : Spherical harmonics analysis - HEALPix map -> Power spectrum C_l
+  Usage: map2cl [-float/-r4] [-lmax lval] [-thetacut dtdeg]
+         [-fitsin] [-fitsout] InFileName OutFileName
+   -float (-r4): single precision C_l and map (default = double)
+   -lmax lval: Maximum value for l index (default=255)
+   -thetacut dtdeg : Symmetric delta-theta cut (in degree) along equator
+                    (default=0 -> no cut)
+   -iter_order lval : 1,2,3,4... order of an iterative analysis,
+              3rd order is usually optimal (default=0 -> standard analysis)
+   -keepalm : Save Alm's as a 2-D array (Matrix) 
+   -fitsout: Select the FITS format for the output vector/alm's (default PPF format)
+   -fitsin : Select the FITS format for the input map (default PPF format)
+   InFileName : Input file name (HEALPix map)
+   OutFileName : Output file name (the C_l vector / and Alm's)
+
+  \endverbatim
+*/
+
+/* Nouvelle-Fonction */
+void Usage(bool fgerr)
+{
+  cout << endl;
+  if (fgerr) {
+    cout << " map2cl : Argument Error ! map2cl -h for usage " << endl; 
+    exit(1);
+  }
+  else {
+    cout << " map2cl : Spherical harmonics analysis - HEALPix map -> Power spectrum C_l \n" 
+	 << " Usage: map2cl [-float/-r4] [-lmax lval] [-thetacut dtdeg] [-iter_order lval]\n" 
+	 << "        [-keepalm AlmFileName] [-fitsin] [-fitsout] InFileName OutFileName \n" 
+	 << "   -float (-r4): single precision C_l and map (default = double) \n"
+	 << "   -lmax lval: Maximum value for l index (default=255)\n" 
+	 << "   -thetacut dtdeg : Symmetric delta-theta cut (in degree) along equator \n" 
+	 << "                    (default=0 -> no cut)\n"
+         << "   -iter_order lval : 1,2,3,4... order of an iterative analysis\n" 
+	 << "       3rd order is usually optimal (default=0 -> standard analysis)\n"
+	 << "   -keepalm : Save Alm's as a 2-D complex array (Matrix<complex>) - only with PPF format  \n"
+	 << "   -fitsout: Select the FITS format for the output files (Map/Alm) (default PPF format) \n"
+	 << "   -fitsin : Select the FITS format for the input map (default PPF format) \n"
+	 << "   InFileName : Input file name (HEALPix map) \n" 
+	 << "   OutFileName : Output file name (the C_l vector) \n" << endl; 
+    exit(0);
+  }  
+}
+
+/* Nouvelle-Fonction */
+template <class T> 
+class _Map2Cl {
+public :
+static void ComputeCl(string & infile, string & outfile, int lmax, double tcut, 
+		      int iterationOrder, bool fgfitsin, bool fgfitsout, bool keepalm)
+{
+  double deg2rad =  M_PI/180.;
+  double minute2rad =  M_PI/(180.*60.);
+ 
+  SphereHEALPix<T> sph;
+  if (fgfitsin) {
+    cout << "--- Reading Input FITS file " << infile << endl; 
+    FitsInFile fii(infile);
+    fii >> sph;
+  }
+  else {
+    cout << "--- Reading Input PPF file " << infile << endl; 
+    PInPersist ppi(infile);
+    ppi >> sph;
+  } 
+
+  cout << " Input map : NbPixels= " <<  sph.NbPixels() << " NSide= " 
+       << sph.SizeIndex() << " Resolution= "
+       << sqrt(sph.PixSolAngle(0))/minute2rad << " Arcminutes " << endl;
+  
+  double ctcut = (tcut < 1.e-19) ? 0. : cos((90.-tcut)*deg2rad);
+  cout << "--- Calling  DecomposeToCl() (lmax= " << lmax 
+       << " cos_theta_cut= " << ctcut << " iter_order= " << iterationOrder << ") theta_cut=" << tcut << " deg"  << endl;
+  // Decomposition de la carte en C_l
+  SphericalTransformServer<T> sphtr;
+  TVector<T> clvec;
+  TMatrix< complex<T> > almmtx;
+  if (keepalm) {
+    Alm<T> alm(lmax);
+    sphtr.DecomposeToAlm(sph, alm, lmax, ctcut, iterationOrder);
+    almmtx.SetSize(alm.Lmax()+1, alm.Lmax()+1);
+    for(int il=0; il<alm.Lmax()+1; il++)
+      for(int im=0; im<il; im++)
+	almmtx(il, im) = alm(il, im);
+    clvec = alm.powerSpectrum();
+  }
+  else {
+    clvec = sphtr.DecomposeToCl(sph, lmax, ctcut, iterationOrder);
+  }
+  T min, max;
+  double mean, sigma;
+  clvec.MinMax(min, max);
+  MeanSigma(clvec, mean, sigma);
+  cout << "--- Statistics on the computed C_l vector: Size=" << clvec.Size() << endl; 
+  cout << " C_l.Min= " << min << " C_l.Max= " << max 
+       << " C_l.Mean= " << mean << " C_l.Sigma= " << sigma << endl;
+  
+  if (fgfitsout) {
+    FitsOutFile fio(outfile, FitsFile::clear);
+    cout << "--- Writing C_l vector to Output FITS file " << outfile << endl; 
+    fio << clvec;
+  }
+  else {
+    POutPersist ppo(outfile);
+    if (keepalm) {
+      cout << "--- Writing C_l vector to Output PPF file " << outfile << endl; 
+      ppo.PutObject(clvec, "Cl");
+      cout << "--- Writing Alm Matrix to Output PPF file " << outfile << endl; 
+      ppo.PutObject(almmtx, "Alm");      
+    }
+    else {
+      cout << "--- Writing C_l vector to Output PPF file " << outfile << endl; 
+      ppo << clvec;
+    }
+  }
+}
+
+};
+
+/* Main-Program */
+int main(int narg, char *arg[])
+{
+  if ((narg > 1) && (strcmp(arg[1],"-h") == 0) ) Usage(false);
+  
+  int lmax = 255;
+  int iterationOrder = 0;
+  double tcut = 0.;
+  string infile;
+  string outfile;
+  bool fgfitsin = false;
+  bool fgfitsout = false;
+  bool fgr4 = false;
+  bool fgkeepalm = false;
+  cout << " map2cl : Decoding command line options ... " << endl;
+
+  int ko=1;
+  for (int k=1; k<narg; k++)   {
+    if (strcmp(arg[k], "-lmax") == 0)  {
+      if (k == narg-1) Usage(true);  // -lmax est suivi d'un argument 
+      lmax = atoi(arg[k+1]);  k++;       // k++ pour sauter au suivant
+    }
+    else if (strcmp(arg[k], "-thetacut") == 0)  {
+      if (k == narg-1) Usage(true);  // -thetacut est suivi d'un argument 
+      tcut = atof(arg[k+1]);  k++;       // k++ pour sauter au suivant
+    }
+    else if (strcmp(arg[k], "-iter_order") == 0)  {
+      if (k == narg-1) Usage(true);  // -iter_order est suivi d'un argument 
+      iterationOrder = atof(arg[k+1]);  k++;   // k++ pour sauter au suivant
+    }
+    else if (strcmp(arg[k], "-fitsin") == 0) {
+      fgfitsin = true;  
+    }
+    else if (strcmp(arg[k], "-fitsout") == 0) {
+      fgfitsout = true;  
+    }
+    else if (strcmp(arg[k], "-keepalm") == 0) {
+      fgkeepalm = true;  
+    }
+    else if ((strcmp(arg[k], "-float") == 0) || (strcmp(arg[k], "-r4") == 0) ) {
+      fgr4 = true;  
+    }
+   
+    else { ko = k; break; }  // Debut des noms
+  }
+
+  if ((narg-ko) < 2)  Usage(true); 
+  infile = arg[ko];
+  outfile = arg[ko+1];
+  
+  // Bloc try de gestion des exception 
+  try {
+    InitTim();
+    SophyaInit();
+    if (fgr4) {
+      cout << " SphereHEALPix<r_4>  --> Power spectrum C_l<r_4> (float)" << endl;
+      _Map2Cl<r_4>::ComputeCl(infile, outfile, lmax, tcut, iterationOrder, 
+			      fgfitsin, fgfitsout, fgkeepalm);
+    }
+    else {
+      cout << " SphereHEALPix<r_8>  --> Power spectrum C_l<r_8> (double)" << endl;
+      _Map2Cl<r_8>::ComputeCl(infile, outfile, lmax, tcut, iterationOrder,
+			      fgfitsin, fgfitsout, fgkeepalm);
+    }
+  }
+  catch (PThrowable & exc) {   // Exceptions de SOPHYA
+    cerr << " map2cl: Catched Exception " << (string)typeid(exc).name()
+         << " - Msg= " << exc.Msg() << endl;
+  }
+  catch (...) {    // Autres Exceptions
+    cerr << " map2cl: some other exception was caught ! " << endl;
+  }
+  
+  PrtTim("End of map2cl ");
+  return(0);
+}
+
+
+  
Index: /tags/V_Dec2002/SophyaProg/PrgMap/msksphere.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/PrgMap/msksphere.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PrgMap/msksphere.cc	(revision 2309)
@@ -0,0 +1,140 @@
+// Creation d'une sphere de masquee a partir d'une sphere de masques
+//         cmv 15/6/01
+#include "machdefs.h"
+#include <unistd.h>
+#include <stdexcept>
+#include <iostream.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "skymapinit.h"
+#include "skymap.h"
+#include "fitsspherehealpix.h" 
+
+/*!
+  \ingroup PrgMap
+  \file msksphere.cc
+  \brief \b msksphere: mask a sphere of datas with a mask sphere.
+  \verbatim
+csh> msksphere -h
+msksphere [-m min -M max -v valmsk] sphval.fits sphmask.fits sphout.fits
+ sphval.fits : inpout sphere of datas where the pixels have to be masked
+ sphmask.fits : inpout masked sphere used to mask pixels
+ sphout.fits : output masked sphere of datas
+ -m min : min mask_sphere_value for MASKING the sphere pixel
+ -M max : max mask_sphere_value for MASKING the sphere pixel
+    condition for MASKING sphere pixel is (min<=mask_sphere_value<=max)
+ -n : negate the previous condition, condition for MASKING sphere pixel
+      becomes: (mask_sphere_value<minval || maxval<mask_sphere_value)
+ Default (no -m and -M): mask pixel if mask_sphere_value<0.
+ -v valmsk : set sphere value for masked pixels (def=0.)
+  \endverbatim
+*/
+
+void usage();
+void usage()
+{
+cout<<"msksphere [-m min -M max -v valmsk]"
+    <<" sphval.fits sphmask.fits sphout.fits"<<endl
+    <<" sphval.fits : inpout sphere of datas where the pixels have to be masked"<<endl
+    <<" sphmask.fits : inpout masked sphere used to mask pixels"<<endl
+    <<" sphout.fits : output masked sphere of datas"<<endl
+    <<" -m min : min mask_sphere_value for MASKING the sphere pixel"<<endl
+    <<" -M max : max mask_sphere_value for MASKING the sphere pixel"<<endl
+    <<"    condition for MASKING sphere pixel is (min<=mask_sphere_value<=max)"<<endl
+    <<" -n : negate the previous condition, condition for MASKING sphere pixel"<<endl
+    <<"      becomes: (mask_sphere_value<minval || maxval<mask_sphere_value)"<<endl
+    <<" Default (no -m and -M): mask pixel if mask_sphere_value<0."<<endl
+    <<" -v valmsk : set sphere value for masked pixels (def=0.)"<<endl;
+}
+
+int main(int narg, char* arg[])
+{
+double vmask=0.,vmin=-1.e30,vmax=1.e30;
+bool tstmin=false,tstmax=false,negate=false;
+string dum;
+int c;
+while((c = getopt(narg,arg,"hnm:M:v:")) != -1) {
+  switch (c) {
+  case 'n' :
+    negate = true;
+    break;
+  case 'm' :
+    sscanf(optarg,"%lf",&vmin);
+    tstmin = true;
+    break;
+  case 'M' :
+    sscanf(optarg,"%lf",&vmax);
+    tstmax = true;
+    break;
+  case 'v' :
+    sscanf(optarg,"%lf",&vmask);
+    break;
+  case 'h' :
+  default:
+    usage(); exit(1);
+  }
+}
+
+if(optind+2>=narg) {usage(); exit(1);}
+char * sphval = arg[optind];
+char * sphmsk = arg[optind+1];
+char * sphout = arg[optind+2];
+
+if(!tstmin && !tstmax) {tstmin=true; vmin=0.; negate=true;}
+
+if(negate) dum = ".NOT."; else dum="";
+cout<<"Sphere values : "<<sphval<<endl
+    <<"Sphere mask   : "<<sphmsk<<endl
+    <<"Sphere out    : "<<sphout<<endl
+    <<"  ...min("<<tstmin<<") "<<vmin<<endl
+    <<"     max("<<tstmax<<") "<<vmax<<endl
+    <<"  ...mask set value "<<vmask<<endl
+    <<"  Condition for masking pixel is :"<<endl
+    <<"    "<<dum<<"( "<<vmin<<" <= V <= "<<vmax<<" )"<<endl;
+
+// Lecture de la sphere Healpix des valeurs
+SphereHEALPix<r_8> sph;        
+{FitsInFile sfits(sphval); sfits >> sph;}
+cout<<"Opening Sphere HEALPix for testing values :"<<endl
+    <<"          Type of map : "<<sph.TypeOfMap()<<endl
+    <<"     Number of pixels : "<<sph.NbPixels()<<endl
+    <<"                 Nlat : "<<sph.SizeIndex()<<endl;
+
+// Lecture de la sphere Healpix des masques
+SphereHEALPix<r_8> msph;        
+{FitsInFile sfits(sphmsk); sfits >> msph;}
+cout<<"Opening Sphere HEALPix for mask :"<<endl
+    <<"          Type of map : "<<msph.TypeOfMap()<<endl
+    <<"     Number of pixels : "<<msph.NbPixels()<<endl
+    <<"                 Nlat : "<<msph.SizeIndex()<<endl;
+if(msph.SizeIndex()!=sph.SizeIndex()) {
+  cout<<"Sphere of values and sphere of mask must have same NLat"<<endl;
+  exit(1);
+}
+
+// Filling Mask Sphere
+cout<<"Testing For Masked Pixels"<<endl;
+uint_4 nmask = 0;
+for(int_4 i=0;i<sph.NbPixels();i++) {
+
+  bool skp = (tstmin || tstmax) ? negate : false;
+  if((tstmin && msph(i)<vmin) || (tstmax && msph(i)>vmax)) skp = !negate;
+  if(skp) continue;   // Do nothing
+
+  sph(i) = vmask;
+  nmask++;
+}
+cout<<"    .... Number of values masked   : "<<nmask<<endl;
+cout<<"    .... Fraction of values masked : "
+    <<(r_8)nmask/sph.NbPixels()*100.<<" %"<<endl;
+
+// Ecriture de la sphere Healpix sur fits
+{
+dum = "rm -f "; dum += sphout; system(dum.c_str());
+FitsOutFile sfits(sphout, FitsFile::clear);
+cout<<"Writing Output Masked Sphere Fits file"<<endl;
+sfits<<sph;
+}
+
+exit(0);
+}
Index: /tags/V_Dec2002/SophyaProg/PrgMap/prjsmap.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/PrgMap/prjsmap.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PrgMap/prjsmap.cc	(revision 2309)
@@ -0,0 +1,340 @@
+#include "machdefs.h"    // Definitions specifiques SOPHYA
+
+#include <math.h>
+#include <iostream.h>
+
+#include "nbmath.h"
+#include "timing.h"
+
+#include "array.h"
+#include "skymap.h"
+#include "samba.h"
+#include "sambainit.h"
+#include "fitsspherehealpix.h"
+#include "fitstarray.h"
+
+/*!
+  \ingroup PrgMap
+  \file prjsmap.cc
+  \brief \b prjsmap: Molleweide and sinus projection of sky maps
+
+  \verbatim 
+
+  csh> prjsmap -h
+  SOPHYA Version  1.1 Revision 0 (V_Fev2001) -- Mar  9 2001 15:45:31 cxx
+
+  prjsmap : Molleweide and Sinus projection for sky maps
+  Usage: prjsmap [-float/-r4] [-sinus] [-sx sizeX] [-sy sizeY] [-scale fact]
+         [-off val][-ump val] [-invy] [-fitsin] [-fitsout] InFileName OutFileName
+   -float (-r4): single precision sky map and projection (default = double)
+   -sinus: Selects Sinus projection (default Molleweide projection)
+   -sx sizeX: Projected map size in X
+   -sy sizeY: Projected map size in Y
+       default: sizeX = 2*sizeY ; sizeX*sizeY ~ map.NbPixels()/2
+   -scale fact: scale factor applied to skymap pixels (def=1.)
+   -off val: offset value for projected map (def=0.)
+             prj(ix, jy) = offset + scale*skymap(theta, phi)
+   -ump val: Unmapped pixel value in projected map (def=0.)
+   -invy: reverses the projection direction along Y (Theta)
+   -fitsout: Select the FITS format for the output map (default PPF format)
+   -fitsin : Select the FITS format for the input vector (default PPF format)
+   InFileName : Input file name (HEALPix map)
+   OutFileName : Output file name (the C_l vector)
+
+  \endverbatim
+*/
+
+
+/* Nouvelle-Fonction */
+void Usage(bool fgerr)
+{
+  cout << endl;
+  if (fgerr) {
+    cout << " prjsmap : Argument Error ! prjsmap -h for usage " << endl; 
+    exit(1);
+  }
+  else {
+    cout << " prjsmap : Molleweide and Sinus projection for sky maps \n" 
+	 << " Usage: prjsmap [-float/-r4] [-sinus] [-sx sizeX] [-sy sizeY] [-scale fact] \n" 
+	 << "        [-off val][-ump val] [-invy] [-fitsin] [-fitsout] InFileName OutFileName\n" 
+	 << "   -float (-r4): single precision sky map and projection (default = double) \n"
+	 << "   -sinus: Selects Sinus projection (default Molleweide projection) \n"
+	 << "   -sx sizeX: Projected map size in X \n"
+	 << "   -sy sizeY: Projected map size in Y \n"
+	 << "       default: sizeX = 2*sizeY ; sizeX*sizeY ~ map.NbPixels()/2 \n"
+	 << "   -scale fact: scale factor applied to skymap pixels (def=1.) \n"
+	 << "   -off val: offset value for projected map (def=0.) \n"
+	 << "             prj(ix, jy) = offset + scale*skymap(theta, phi) \n"
+	 << "   -ump val: Unmapped pixel value in projected map (def=0.) \n" 
+	 << "   -invy: reverses the projection direction along Y (Theta) \n"
+	 << "   -fitsout: Select the FITS format for the output map (default PPF format) \n"
+	 << "   -fitsin : Select the FITS format for the input vector (default PPF format) \n"
+	 << "   InFileName : Input file name (HEALPix map) \n" 
+	 << "   OutFileName : Output file name (the C_l vector) \n" << endl; 
+    exit(0);
+  }  
+}
+
+/* Nouvelle-Fonction */
+template <class T> 
+class _PrjMap {
+public :
+/* Methode */
+static void PM_MeanSigma(PixelMap<T> const & map, double& gmoy, double& gsig, T& min, T& max)
+{
+  min = max = map(0);
+  gmoy=0.;
+  gsig = 0.; 
+  double valok;
+  for(int k=0; k<map.NbPixels(); k++) {
+    valok = map(k);
+    gmoy += valok;  gsig += valok*valok; 
+    if (map(k)<min)  min = map(k);
+    else if (map(k)>max)  max = map(k);      
+  }
+  gmoy /= (double)map.NbPixels();
+  gsig = gsig/(double)map.NbPixels() - gmoy*gmoy;
+  if (gsig >= 0.) gsig = sqrt(gsig);
+  return;
+}
+
+/* Methode */
+static TArray<T> Project_Molleweide(SphericalMap<T> const & map, int sx=0, int sy=0, T ump=0, 
+				    T offset=0, T scale=1, bool invy=false)
+{
+  if ( (sx <= 0) && (sy <= 0) ) {
+    sy = sqrt((double)(map.NbPixels()/2));
+    sx = sy*2;    
+  }
+  else {
+    if (sx <= 0) sx = 2*sy;
+    else sy = sx/2;
+  }
+  TArray<T> prj(sx, sy);
+  prj = ump;   // On met tout a ump
+  
+  cout << " Molleweide projection (sizeX= " << sx << " sizeY= " << sy << " )" 
+       << " Scale=" << scale << " Offset=" << offset << endl;
+  r_8 xa, yd, teta,phi, facteur;
+  int_4 ix, jy, k;
+  for(jy=0; jy<sy; jy++) {
+    yd = (r_8)(jy+0.5)/(r_8)sy-0.5;
+    if (invy) teta = (0.5-yd)*M_PI;
+    else teta = (yd+0.5)*M_PI;
+    facteur=2.*M_PI/sin(acos((double)yd*2));
+    for(ix=0; ix<sx; ix++)  {
+      xa = (r_8)(ix+0.5)/(r_8)sx-0.5;
+      phi = xa*facteur+M_PI;
+      if ( (phi <= 2*M_PI) && (phi >= 0.) ) {
+        k = map.PixIndexSph(teta, phi);
+        prj(ix,jy,0) = offset + scale*map(k);
+      }
+    }
+  }
+
+  return prj;   
+}
+
+/* Methode */
+static TArray<T> Project_Sinus(SphericalMap<T> const & map, int sx=0, int sy=0, T ump=0, 
+			       T offset=0, T scale=1, bool invy=false)
+{
+  if ( (sx <= 0) && (sy <= 0) ) {
+    sy = sqrt((double)(map.NbPixels()/2));
+    sx = sy*2;    
+  }
+  else {
+    if (sx <= 0) sx = 2*sy;
+    else sy = sx/2;
+  }
+  TArray<T> prj(sx, sy);
+  prj = ump;   // On met tout a ump
+
+  cout << " Sinus projection (sizeX= " << sx << " sizeY= " << sy << " )"
+       << " Scale=" << scale << " Offset=" << offset << endl;
+  r_8 xa, yd, teta,phi, facteur;
+  int_4 ix, jy, k;
+  for(jy=0; jy<sy; jy++) {
+    yd = (r_8)(jy+0.5)/(r_8)sy-0.5;
+    if (invy) teta = (0.5-yd)*M_PI;
+    else teta = (yd+0.5)*M_PI;
+    facteur=1./sin(teta);
+    for(ix=0; ix<sx; ix++)  {
+      xa = (r_8)(ix+0.5)/(r_8)sx-0.5;
+      phi = 2*M_PI*xa*facteur+M_PI;
+      if ( (phi <= 2*M_PI) && (phi >= 0.) ) {
+        k = map.PixIndexSph(teta, phi);
+        prj(ix,jy,0) = offset + scale*map(k);
+      }
+    }
+  }
+  return prj;   
+}
+
+/* Methode */
+static void Project(string & infile, string & outfile, int sx, int sy, T ump, T offset, 
+                    T scale, bool fgsin, bool invy, bool fgfitsin, bool fgfitsout) 
+{
+
+  double deg2rad =  M_PI/180.;
+  double minute2rad =  M_PI/(180.*60.);
+
+  SphericalMap<T> * sphp = NULL;
+  SphereHEALPix<T> sphh;
+
+  PPersist * pp = NULL;
+
+  if (fgfitsin) {
+    cout << "--- Reading Input FITS file " << infile << endl; 
+    FitsInFile fii(infile);
+    fii >> sphh;
+    sphp = &sphh;
+  }
+  else {
+    cout << "--- Reading Input PPF file " << infile << endl; 
+    PInPersist ppi(infile);
+    pp = ppi.ReadObject();
+    if (pp) 
+      sphp = dynamic_cast< SphericalMap<T> * > (pp->DataObj());
+    else sphp = NULL;
+    if (sphp == NULL) {
+      cout << " Object in PPF file is not a SphericalMap<T> or wrong data type ! " << endl;
+      throw TypeMismatchExc("_PrjMap::Project(...) Error reading input PPF file !");
+    }
+  }
+
+  SphericalMap<T> & sph = *sphp;
+  T min, max;
+  double mean, sigma;
+  PM_MeanSigma(sph, mean, sigma, min, max);
+  
+  cout << " Input map type= " << sph.TypeOfMap() << " PixParm (=NSide for HEALPix)= " 
+       << sph.SizeIndex() << endl;
+  cout << " Input map : NbPixels= " << sph.NbPixels() << " Resolution= "
+       << sqrt(sph.PixSolAngle(0))/minute2rad << " Arcminutes " << endl;
+  cout << " map.Min= " << min << " map.Max= " << max 
+       << " map.Mean= " << mean << " map.Sigma= " << sigma << endl;
+  
+  cout << "--- Sky map projection " << endl;
+  TArray<T> prj;
+
+  if (fgsin) prj = Project_Sinus(sph, sx, sy, ump, offset, scale, invy); 
+  else prj = Project_Molleweide(sph, sx, sy, ump, offset, scale, invy); 
+
+  cout << "--- Statistics on the projected map :" ; 
+  prj.Show();
+  prj.MinMax(min, max);
+  MeanSigma(prj, mean, sigma);  
+  cout << " prj.Min= " << min << " prj.Max= " << max 
+       << " prj.Mean= " << mean << " prj.Sigma= " << sigma << endl;
+  
+  if (fgfitsout) {
+    cout << "--- Writing projection to Output FITS file " << outfile << endl; 
+    FitsOutFile fio(outfile, FitsFile::clear);
+    fio << prj;
+  }
+  else {
+    cout << "--- Writing projection to Output PPF file " << outfile << endl; 
+    POutPersist ppo(outfile);
+    ppo << prj;
+  }
+
+  if (pp) delete pp;
+}
+
+};
+
+/* Main-Program */
+int main(int narg, char *arg[])
+{
+  if ((narg > 1) && (strcmp(arg[1],"-h") == 0) ) Usage(false);
+  
+  double ump = 0.;
+  double off = 0.;
+  double scale = 1.;
+  int sx = 0;
+  int sy = 0;
+  string infile;
+  string outfile;
+  bool fgfitsin = false;
+  bool fgfitsout = false;
+  bool fgr4 = false;
+  bool fgsinus = false;
+  bool fginvy = false;
+
+  cout << " prjsmap : Decoding command line options ... " << endl;
+
+  int ko=1;
+  for (int k=1; k<narg; k++)   {
+    if (strcmp(arg[k], "-sx") == 0)  {
+      if (k == narg-1) Usage(true);  // -sx est suivi d'un argument 
+      sx = atoi(arg[k+1]);  k++;       // k++ pour sauter au suivant
+    }
+    else if (strcmp(arg[k], "-sy") == 0)  {
+      if (k == narg-1) Usage(true);  // -sy est suivi d'un argument 
+      sy = atoi(arg[k+1]);  k++;       // k++ pour sauter au suivant
+    }
+    else if (strcmp(arg[k], "-scale") == 0)  {
+      if (k == narg-1) Usage(true);  
+      scale = atof(arg[k+1]);  k++;   
+    }
+    else if (strcmp(arg[k], "-off") == 0)  {
+      if (k == narg-1) Usage(true);  
+      off = atof(arg[k+1]);  k++;   
+    }
+    else if (strcmp(arg[k], "-ump") == 0)  {
+      if (k == narg-1) Usage(true);  
+      ump = atof(arg[k+1]);  k++;   
+    }
+    else if (strcmp(arg[k], "-sinus") == 0) {
+      fgsinus = true;  
+    }
+    else if (strcmp(arg[k], "-invy") == 0) {
+      fginvy = true;  
+    }
+    else if (strcmp(arg[k], "-fitsin") == 0) {
+      fgfitsin = true;  
+    }
+    else if (strcmp(arg[k], "-fitsout") == 0) {
+      fgfitsout = true;  
+    }
+    else if ((strcmp(arg[k], "-float") == 0) || (strcmp(arg[k], "-r4") == 0) ) {
+      fgr4 = true;  
+    }
+   
+    else { ko = k; break; }  // Debut des noms
+  }
+
+  if ((narg-ko) < 2)  Usage(true); 
+  infile = arg[ko];
+  outfile = arg[ko+1];
+  
+  // Bloc try de gestion des exception 
+  try {
+    InitTim();
+    SophyaInit();
+    if (fgr4) {
+      cout << " Projecting SphericalMap<r_4>  -->  Array<r_4> (float)" << endl;
+      _PrjMap<r_4>::Project(infile, outfile, sx, sy, ump, off, scale, 
+			    fgsinus, fginvy, fgfitsin, fgfitsout);
+    }
+    else {
+      cout << " Projecting SphericalMap<r_8>  -->  Array<r_8> (double)" << endl;
+      _PrjMap<r_8>::Project(infile, outfile, sx, sy, ump, off, scale, 
+			    fgsinus, fginvy, fgfitsin, fgfitsout);
+    }
+  }
+  catch (PThrowable & exc) {   // Exceptions de SOPHYA
+    cerr << " prjsmap: Catched Exception " << (string)typeid(exc).name()
+         << " - Msg= " << exc.Msg() << endl;
+  }
+  catch (...) {    // Autres Exceptions
+    cerr << " prjsmap: some other exception was caught ! " << endl;
+  }
+  
+  PrtTim("End of prjsmap ");
+  return(0);
+}
+
+
+  
Index: /tags/V_Dec2002/SophyaProg/PrgMap/programs
===================================================================
--- /tags/V_Dec2002/SophyaProg/PrgMap/programs	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PrgMap/programs	(revision 2309)
@@ -0,0 +1,6 @@
+cl2map cl2map.o
+map2cl map2cl.o
+prjsmap prjsmap.o
+cremskfrsph cremskfrsph.o
+extrapsph extrapsph.o
+extrap2sph extrap2sph.o
Index: /tags/V_Dec2002/SophyaProg/PrgMap/usedlibs
===================================================================
--- /tags/V_Dec2002/SophyaProg/PrgMap/usedlibs	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PrgMap/usedlibs	(revision 2309)
@@ -0,0 +1,8 @@
+TArray
+SysTools
+NTools
+SkyMap
+Samba
+SkyT
+
+
Index: /tags/V_Dec2002/SophyaProg/PrgMap/usedslibs
===================================================================
--- /tags/V_Dec2002/SophyaProg/PrgMap/usedslibs	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PrgMap/usedslibs	(revision 2309)
@@ -0,0 +1,2 @@
+sophya
+extsophya
Index: /tags/V_Dec2002/SophyaProg/PrgUtil/Makefile
===================================================================
--- /tags/V_Dec2002/SophyaProg/PrgUtil/Makefile	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PrgUtil/Makefile	(revision 2309)
@@ -0,0 +1,81 @@
+MODULECXXREPNAME :=  PrgUtil
+include ../Mgr/Makefile.h
+ 
+ifdef NOSHLIB
+LIBF =  $(LIB)libFitsIOServer.a $(LIB)libSamba.a $(LIB)libSkyMap.a $(LIB)libSkyT.a $(LIB)libNTools.a $(LIB)libHiStats.a $(LIB)libTArray.a $(LIB)libSysTools.a 
+LIBS = -L$(LIB) -lFitsIOServer -lSamba -lSkyMap -lSkyT -lNTools -lHiStats -lTArray -lSysTools -lm
+ifeq ($(CXX),cxx)
+# librairie des instances de templates cxx
+LIBS := $(LIBS) -lertcxx
+endif
+else
+LIBF =  $(SLB)libsophya.so $(SLB)libextsophya.so
+LIBS = -L$(SLB) -lsophya -lextsophya  -lm
+endif
+LIBSORA := $(LIBS)
+LDLIBS := $(LIBS) $(LDLIBS)
+PROGS = $(EXE)runcxx $(EXE)scanppf $(EXE)scanfits 
+PROBJS = $(OBJ)runcxx.o $(OBJ)scanppf.o $(OBJ)scanfits.o 
+
+all: $(PROGS)
+
+clean:
+	rm -f $(PROGS)
+	rm -f $(PROBJS)
+	if [ -d $(OBJ)cxxrep_PrgUtil ] ; then cd $(OBJ)cxxrep_PrgUtil ; rm -f *.o ; fi
+
+runcxx: $(EXE)runcxx
+	@ echo runcxx done
+$(EXE)runcxx: $(OBJ)runcxx.o
+	$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@ 
+
+scanppf: $(EXE)scanppf
+	@ echo scanppf done
+$(EXE)scanppf: $(OBJ)scanppf.o
+	$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@ 
+
+scanfits: $(EXE)scanfits
+	@ echo scanfits done
+$(EXE)scanfits: $(OBJ)scanfits.o
+	$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@ 
+
+$(OBJ)runcxx.o: runcxx.cc $(INC)sambainit.h \
+ $(INC)skymapinit.h \
+ $(INC)sophyainit.h \
+ $(INC)machdefs.h \
+ $(INC)ntoolsinit.h \
+ $(INC)tarrinit.h \
+ $(INC)skyinit.h \
+ $(INC)pexceptions.h \
+ $(INC)cxxcmplnk.h \
+ $(INC)pdlmgr.h \
+ $(INC)timing.h
+$(OBJ)scanfits.o: scanfits.cc $(INC)histinit.h \
+ $(INC)ntoolsinit.h \
+ $(INC)tarrinit.h \
+ $(INC)sophyainit.h \
+ $(INC)machdefs.h \
+ $(INC)dvlist.h \
+ $(INC)objfio.h \
+ $(INC)anydataobj.h \
+ $(INC)ppersist.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)mutyv.h \
+ $(INC)ntuple.h \
+ $(INC)ntupintf.h \
+ $(INC)xntuple.h \
+ $(INC)fitsxntuple.h \
+ $(INC)fitsfile.h \
+ $(INC)ndatablock.h \
+ $(INC)fitsntuple.h
+$(OBJ)scanppf.o: scanppf.cc $(INC)ppersist.h \
+ $(INC)machdefs.h \
+ $(INC)pexceptions.h \
+ $(INC)gnumd5.h \
+ $(INC)anydataobj.h \
+ $(INC)sambainit.h \
+ $(INC)skymapinit.h \
+ $(INC)sophyainit.h \
+ $(INC)ntoolsinit.h \
+ $(INC)tarrinit.h
Index: /tags/V_Dec2002/SophyaProg/PrgUtil/programs
===================================================================
--- /tags/V_Dec2002/SophyaProg/PrgUtil/programs	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PrgUtil/programs	(revision 2309)
@@ -0,0 +1,3 @@
+runcxx runcxx.o
+scanppf scanppf.o
+scanfits scanfits.o
Index: /tags/V_Dec2002/SophyaProg/PrgUtil/runcxx.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/PrgUtil/runcxx.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PrgUtil/runcxx.cc	(revision 2309)
@@ -0,0 +1,315 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <iostream.h>
+#include <fstream.h>
+
+#include <string>
+#include <vector>
+
+#include <typeinfo>
+
+#include "sambainit.h"
+#include "skyinit.h"
+#include "tarrinit.h"
+
+#include "pexceptions.h"
+#include "cxxcmplnk.h"
+#include "pdlmgr.h"
+#include "timing.h"
+
+/*!
+  \ingroup PrgUtil
+  \file runcxx.cc
+  \brief \b runcxx: Compile and run simple C++ code using SOPHYA 
+
+  \verbatim
+  csh> runcxx -h
+  SOPHYA Version  1.1 Revision 0 (V_Fev2001) -- Mar  9 2001 15:45:31 cxx
+  runcxx : compiling and running of a piece of C++ code
+    Usage: runcxx [-compopt CompileOptions] [-linkopt LinkOptions]
+                  [-tmpdir TmpDirectory] [-f C++CodeFileName]
+                  [-inc includefile] [-inc includefile ...]
+                  [-import modulename] [-import modulename ...]
+                  [-uarg UserArg1 UserArg2 ...]
+   if no file name is specified, read from standard input
+   modulenames: SkyMap, Samba, SkyT, FitsIOServer, LinAlg, IFFTW
+  \endverbatim
+*/
+
+typedef void (* DlFunctionOfVecStr) (vector<string> & args, int & rc);
+
+static void Usage(bool fgerr);
+static int  GetInput(string & codeflnm);
+static int  FillCxxFile(string & codeflnm, string & cxxfile, 
+			vector<string> & inc1, vector<string> & inc2);
+
+/* --Fonction-- */
+void Usage(bool fgerr)
+{
+  if (fgerr) 
+    cout << " runcxx : Argument Error ! " << endl; 
+  else
+    cout << " runcxx : compiling and running of a piece of C++ code " << endl;
+ 
+  cout << "   Usage: runcxx [-compopt CompileOptions] [-linkopt LinkOptions] \n"
+       << "                 [-tmpdir TmpDirectory] [-f C++CodeFileName] \n"
+       << "                 [-inc includefile] [-inc includefile ...] \n"
+       << "                 [-import modulename] [-import modulename ...] \n"
+       << "                 [-uarg UserArg1 UserArg2 ...] \n"
+       << "   if no file name is specified, read from standard input \n" 
+       << "   modulenames: SkyMap, Samba, SkyT, FitsIOServer, LinAlg, IFFTW \n"
+       << endl;
+
+  exit(0);
+}
+
+
+
+/* --Main-- */
+int main(int narg, char *arg[])
+{
+  if ((narg > 1) && (strcmp(arg[1],"-h") == 0) ) Usage(false);
+
+  // Decoding options   
+  string codefile;
+  string compoption;
+  string linkoption;
+  string tmpdir;
+
+  bool fgco = false;
+  bool fglo = false;
+  bool fgcofn = false;
+  bool fgtmp = false;
+
+  vector<string> uarg;
+  vector<string> inc1;
+  vector<string> inc2;
+  
+  cout << " runcxx: Decoding command line options ... " << endl;
+  for (int k=1; k<narg; k++)   {
+    if (strcmp(arg[k], "-compopt") == 0)  {
+      if (k == narg-1) Usage(true);
+      fgco = true;  k++;
+      compoption = arg[k];
+    }
+    else if (strcmp(arg[k], "-linkopt") == 0) {
+      if (k == narg-1) Usage(true);
+      fglo = true;  k++;
+      linkoption = arg[k];
+    }
+    else if (strcmp(arg[k], "-tmpdir") == 0) {
+      if (k == narg-1) Usage(true);
+      fgtmp = true;  k++;
+      tmpdir = arg[k];
+    }
+    else if (strcmp(arg[k], "-f") == 0) {
+      if (k == narg-1) Usage(true);
+      fgcofn = true;  k++;
+      codefile = arg[k];
+    }
+    else if (strcmp(arg[k], "-inc") == 0) {
+      if (k == narg-1) Usage(true);
+      k++; inc2.push_back(arg[k]);
+    }
+    else if (strcmp(arg[k], "-import") == 0) {
+      if (k == narg-1) Usage(true);
+      k++; 
+      if (strcmp(arg[k], "SkyMap"))  inc1.push_back("skymap.h");
+      else if (strcmp(arg[k], "Samba"))  inc1.push_back("samba.h");
+      else if (strcmp(arg[k], "SkyT"))  inc1.push_back("skyt.h");
+      else if (strcmp(arg[k], "FitsIOServer"))  inc1.push_back("fitsautoreader.h");
+      else if (strcmp(arg[k], "LinAlg"))  inc1.push_back("intflapack.h");
+      else if (strcmp(arg[k], "IFFTW"))  inc1.push_back("fftwserver.h");
+    }
+
+    else if (strcmp(arg[k], "-uarg") == 0) {
+      if (k == narg-1) Usage(true);
+      for(int kk=k+1; kk<narg; kk++)
+	uarg.push_back(arg[kk]);
+      break;
+    }
+    else Usage(true);
+  }
+
+  // Checking TMPDIR
+  if (!fgtmp) {  // TMPDIR pas defini par option de ligne de commande
+    char* varenv;
+    if ( (varenv=getenv("TMPDIR")) != NULL )  { 
+      tmpdir = varenv;
+      fgtmp = true;
+    }
+  }
+  if (tmpdir.length() > 0)
+    if (tmpdir[tmpdir.length()-1] != '/') tmpdir += '/';
+  
+  int rc = 0;
+
+  try {
+    SophyaInit();
+    InitTim();
+
+    if (!fgcofn) {  // Pas de fichier specifie - Lecture de fichier sur stdin
+      codefile = tmpdir + "aucode.icc";
+      rc = GetInput(codefile);
+    }
+    string flnm;
+    if (rc == 0) {
+      flnm = tmpdir + "acxxrun.cc";
+      rc = FillCxxFile(codefile, flnm, inc1, inc2);
+    }
+
+    PrtTim(" End of FillCxxFile ");
+
+    string oname, soname;
+    if (rc == 0) {
+      CxxCompilerLinker cxx;
+      if (fgtmp) cxx.SetTmpDir(tmpdir);
+      if (fgco) cxx.AddCompileOptions(compoption);
+      if (fglo) cxx.AddLinkOptions(linkoption);
+      cxx.SetVerbose(true);
+
+      rc = cxx.Compile(flnm, oname);
+      cout << " RC from cxx.Compile() = " << rc << " oname= " << oname << endl;
+      if (rc == 0) {
+	rc = cxx.BuildSO(oname, soname);
+	cout << " RC from cxx.BuildSO() = " << rc << " soname= " << soname << endl;
+      }
+      PrtTim(" End of Compile-Link ");
+    }
+    if (rc == 0) {
+      string funcname = "runcxx_usercode";
+      if (fgtmp) PDynLinkMgr::SetTmpDir(tmpdir);
+      PDynLinkMgr dyl(soname);
+      DlFunction f = dyl.GetFunction(funcname);  
+      if (f != NULL) {
+	cout << "DlFunctionOfVecStr  f linked OK - calling f(uarg) ... \n" << endl;
+	DlFunctionOfVecStr fvs = (DlFunctionOfVecStr)f;
+	int rcu = 0;
+	fvs(uarg, rcu);
+	cout << "\n RC from UserCode() = " << rcu << endl;
+	rc = rcu;
+      } 
+      else {
+	cout << " ERROR linking DlFunction f !!! " << endl;
+      }
+    }
+  } 
+ 
+  catch (PThrowable & exc) {
+    cerr << " Catched Exception " << (string)typeid(exc).name()
+         << " - Msg= " << exc.Msg() << endl;
+  }
+  catch (...) {
+    cerr << " some other exception was caught ! " << endl;
+  }
+
+  PrtTim(" End of runcxx ");
+  return(rc);
+}
+
+/* --Fonction-- */
+int  GetInput(string & codeflnm)
+{
+  cout << " runcxx/GetInput() : Type in your C++ code, \n" 
+       << "     end with a blanck line OR <Cntl>D " << endl;
+  int line = 0;
+  ofstream os(codeflnm.c_str(),ios::out); 
+  os << "\n" ; 
+  bool fg = true;
+  char buff[512];
+  char * ret;
+  while (fg) {
+    printf("L%d ? ", line+1);
+    fflush(stdout);
+    buff[0] = '\0';
+    ret = fgets(buff, 512, stdin);
+    buff[511] = '\0';
+    if (ret && ( (buff[0] != '\0') && (buff[0] != '\n') && (buff[0] != '\r')) ) { 
+      os << buff << endl;  line++;
+    }
+    else fg = false;
+  }
+  os << "\n" ; 
+  cout << " \n Total " << line << " lines copied to file " <<  codeflnm << endl;
+  if (line > 0) return(0);
+  else return(1);
+}
+
+/* --Fonction-- */
+int  FillCxxFile(string & code, string & cxxfile, 
+		 vector<string>& inc1, vector<string>& inc2)
+{
+  ofstream os(cxxfile.c_str(),ios::out); 
+  
+  os<<"#include \"machdefs.h\" \n"<<endl;
+
+  os<<"//---- System et stdc++ include files \n"
+    <<"#include <stdio.h> \n"
+    <<"#include <stdlib.h> \n"
+    <<"#include <math.h> \n"
+    <<"#include <ctype.h> \n"
+    <<"#include <string.h> \n"
+    <<"#include <iostream.h> \n"
+    <<"#include <fstream.h> \n"
+    <<"#include <complex> \n"
+    <<endl
+
+    <<"#include <typeinfo> \n"
+    <<"#include <string> \n"
+    <<"#include <vector> \n"
+    <<"#include <map> \n"
+    <<"#include <functional> \n"
+    <<"#include <list> \n"
+    <<endl
+    
+    <<"//---- Sophya include files \n"
+    <<"#include \"basetools.h\" \n"
+    <<"#include \"systools.h\" \n"
+    <<"#include \"sutils.h\" \n"
+    <<"#include \"ntools.h\" \n"
+    <<"#include \"array.h\" \n"
+    <<"#include \"histats.h\" \n"
+    <<endl;
+  
+  int ki;
+  for(ki=0; ki<inc1.size(); ki++)
+    os << "#include \"" << inc1[ki] << "\" \n" ;
+  os << endl;
+  for(ki=0; ki<inc2.size(); ki++)
+    os << "#include \"" << inc2[ki] << "\" \n" ;
+  os << endl;
+
+  os<<"//---- function for Adding and displaying Objects  " << endl;
+  os<<"//---- compatibility with piapp cxxexecutor  " << endl;
+  os<<"void Keep_Object(AnyDataObj & obj, string const & nom) \n{ \n" 
+    <<"  POutPersist pos(nom); \n"
+    <<"  pos.PutObject(obj); \n"
+    <<"} \n" << endl;
+
+  os<<"//---- Objects and variables saving"<<endl
+    <<"#define KeepObj(obj) Keep_Object(obj, #obj);"<<endl
+    <<endl;
+
+  os<<"//---- Displaying objects and command execution"<<endl;
+  os<<"#define DisplayObj(obj, att) " 
+    <<" cout << \"DisplayObj() available only in piapp \" << endl; " << endl;
+  os<<"#define ExecuteCommand(cmd) "
+    <<" cout << \"ExecuteCommand() available only in piapp \" << endl; " << endl;
+
+
+  os << "extern \"C\" { \n" 
+     << " void runcxx_usercode(vector<string>& arg, int & rc); \n" 
+    //     << " void runcxx_usercode(); \n"
+     << " } \n " << endl;
+  
+  os << "// ---- User Code function ----- \n" 
+     << " void runcxx_usercode(vector<string>& arg, int & rc) \n" 
+    //     << " void runcxx_usercode() \n" 
+     << "{ \n"
+     << "#include \"" << code << "\" \n"
+     << "} \n" << endl;
+
+  return(0);
+}
+
Index: /tags/V_Dec2002/SophyaProg/PrgUtil/scanfits.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/PrgUtil/scanfits.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PrgUtil/scanfits.cc	(revision 2309)
@@ -0,0 +1,107 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <iostream.h>
+
+#include "histinit.h"
+#include "dvlist.h"
+#include "ntuple.h"
+#include "xntuple.h"
+#include "fitsxntuple.h"
+#include "fitsntuple.h"
+
+/*!
+  \ingroup PrgUtil
+  \file scanfits.cc
+  \brief \b scanfits: Check and scan FITS files 
+
+  Scan FITS files and prints information on each FITS bloc in file.
+  Uses the FitsIOServer module. 
+
+  \verbatim
+  Usage: scanfits FITSFilename
+  \endverbatim
+ */
+
+string FITSExtType2String(FitsFile::FitsExtensionType exttype)
+{
+  if (exttype == FitsFile::FitsExtensionType_IMAGE) return("IMAGE");
+  else if (exttype == FitsFile::FitsExtensionType_ASCII_TBL) return("ASCII_TBL");
+  else if (exttype == FitsFile::FitsExtensionType_BINARY_TBL) return("BINARY_TBL");
+  else if (exttype == FitsFile::FitsExtensionType_EOF) return("EOF");
+  else if (exttype == FitsFile::FitsExtensionType_ERROR) return("ERROR");
+  else return("Unknown?");
+}
+
+string FITSDataType2String(FitsFile::FitsDataType datatype)
+{
+  if (datatype == FitsFile::FitsDataType_double) return("double");
+  else if (datatype == FitsFile::FitsDataType_float) return("float");
+  else if (datatype == FitsFile::FitsDataType_int) return("int");
+  else if (datatype == FitsFile::FitsDataType_long) return("long");
+  else if (datatype == FitsFile::FitsDataType_byte) return("byte");
+  else if (datatype == FitsFile::FitsDataType_char) return("char");
+  else if (datatype == FitsFile::FitsDataType_ASCII) return("ASCII");
+  else if (datatype == FitsFile::FitsDataType_NULL) return("NULL");
+  else return("Unknown?");
+}
+
+int main(int narg, char *arg[])
+{
+  if (narg < 2) {
+    cerr << "scanfits/Erreur arg - Usage scanfits nomfits \n" << endl;
+    exit(0);
+  }
+  try {
+    SophyaInit();
+    string flnm = arg[1];
+    int nbblk = FitsInFile::NbBlocks(arg[1]);
+    cout << " :::::::: File " << flnm << " has " << nbblk << " blocks " 
+	 << " :::::::: " << endl;
+
+    //    cout << " FitsFile::FitsExtensionType : FitsExtensionType_IMAGE= " <<
+    //      (int)FitsFile::FitsExtensionType_IMAGE << 
+    //      "  FitsExtensionType_ASCII_TBL= " << (int)FitsFile::FitsExtensionType_ASCII_TBL <<
+    //      "  FitsExtensionType_BINARY_TBL= " << (int)FitsFile::FitsExtensionType_BINARY_TBL << endl;
+    //    cout << " FitsFile::FitsDataType: FitsDataType_double= " <<
+    //      (int)FitsFile::FitsDataType_double << 
+    //      " FitsDataType_float= " << (int)FitsFile::FitsDataType_float <<
+    //      " FitsDataType_int= " << (int)FitsFile::FitsDataType_int <<
+    //      " FitsDataType_char= " << (int)FitsFile::FitsDataType_char <<
+    //      " FitsDataType_ASCII= " << (int)FitsFile::FitsDataType_ASCII << endl << endl;
+
+    for(int i=1; i<=nbblk; i++) {
+      int naxis;
+      vector<int> axis;
+      DVList header;
+      FitsFile::FitsExtensionType exttype;
+      FitsFile::FitsDataType datatype;
+
+      FitsInFile::GetBlockType(arg[1], i, exttype, naxis, axis, datatype, header);
+      cout << "\n--------- Header Num " << i << " Type " << FITSExtType2String(exttype) 
+	   << "  --- NAxis= " << naxis 
+	   << " DataType= " << FITSDataType2String(datatype) << endl;
+      if (axis.size() > 0) { 
+	cout << " >> Axis Sizes: " ;
+	for(int j=0; j<axis.size(); j++) { 
+	  if (j > 0) cout << " x " ;
+	  cout  << axis[j] ;
+	}
+	cout << endl;
+      }
+      cout << " >>> Header info : " ;
+      cout << header << endl;
+      cout << "----------------------------------------------------------------------" 
+	   << endl;
+    } 
+ 
+  }
+  catch (PThrowable & exc) {
+    cerr << "sanfits: Catched Exception " << (string)typeid(exc).name()
+         << "\n .... Msg= " << exc.Msg() << endl;
+  }
+  catch (...) {
+    cerr << " some other exception was caught ! " << endl;
+  }
+
+}
Index: /tags/V_Dec2002/SophyaProg/PrgUtil/scanppf.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/PrgUtil/scanppf.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PrgUtil/scanppf.cc	(revision 2309)
@@ -0,0 +1,112 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <typeinfo>
+#include <iostream.h>
+#include <string>
+
+#include "ppersist.h"
+#include "anydataobj.h"
+#include "sambainit.h"
+
+#ifdef __MWERKS__
+#include <console.h>
+#endif
+
+
+/*!
+  \defgroup PrgUtil PrgUtil module
+  This module contains simple programs to perform various utility tasks:
+  <UL>
+  <LI> scanppf : Check and scan PPF files (scanppf.cc)
+  <LI> scanfits : Check and scan FITS files (scanfits.cc)
+  <LI> runcxx : Compile and run simple C++ code using SOPHYA (runcxx.cc)
+  <LI> prjsmap : Molleweide and sinus projection of sky maps (prjsmap.cc)
+  <LI> map2cl : Computes power spectra (C(l)) on spherical maps (map2cl.cc)
+  <LI> cl2map : generates spherical maps from power spectra (C(l)) (cl2map.cc)
+  </UL>
+*/
+
+/*!
+  \ingroup PrgUtil
+  \file scanppf.cc
+  \brief \b scanppf: Check and scan PPF files
+
+  \verbatim
+
+  csh> scanppf -h
+  SOPHYA Version  1.1 Revision 0 (V_Fev2001) -- Mar  9 2001 15:45:31 cxx
+  Usage: scanppf filename [s/n/a0/a1/a2/a3]
+     s[=default} : Sequential reading of objects
+     n : Object reading at NameTags
+     a0...a3 : Tag List with PInPersist.AnalyseTags(0...3)
+
+  \endverbatim
+*/
+
+int main(int narg, char* arg[])
+{
+
+#ifdef __MWERKS__
+narg = ccommand(&arg);
+#endif
+
+SambaInitiator smbinit;
+
+if ((narg < 2) || (strcmp(arg[1],"-h") == 0) ) {
+  cerr << " Usage: scanppf filename [s/n/a0/a1/a2/a3] \n" 
+       << "   s[=default} : Sequential reading of objects \n" 
+       << "   n : Object reading at NameTags \n"
+       << "   a0...a3 : Tag List with PInPersist.AnalyseTags(0...3) \n" << endl;
+  exit(0);
+  }
+
+try {
+  string flnm = arg[1];
+  bool seq=true;
+  bool ana=false;
+  int analev = 0;
+  string opt = "s";
+  if (narg > 2) opt = arg[2];
+  
+  if (opt == "n")  seq = false;
+  else if (opt[0] == 'a') {  ana = true;  analev = opt[1]-'0'; }
+
+  if (ana)   cout << " Analyse PInPersist( " << flnm << ")  Level=" << analev << endl;
+  else { 
+    if (!seq) cout << "PInPersist( " << flnm << ") Object Reading at NameTags " << endl;
+    else  cout << "PInPersist( " << flnm << ") Sequential Object Reading " << endl;
+  }
+   
+  PPersist* op = NULL;
+  cout << " Opening PPF file " << flnm << endl; 
+  PInPersist s(flnm);
+
+  if (ana) s.AnalyseTags(analev);   // Analysing all tags in file 
+
+  else {
+    cout << " Version= " << s.Version() << " CreationDate= " << s.CreationDateStr() << endl;
+    int nt = s.NbTags();
+    cout << " Number of tags in file = " << nt << endl;
+    if ( seq || (nt < 1) ) {
+      while (1) {
+	op = s.ReadObject();
+	cout << " Object Type " << typeid(*op).name() << endl;
+	if (op) delete op;
+      }
+    }
+    for(int i=0; i<nt; i++) {
+      cout << ">>> TagNum= " << i << " TagName= " << s.GetTagName(i) << endl;
+      s.GotoTagNum(i);
+      op = s.ReadObject();
+      cout << " Object Type " << typeid(*op).name() << endl;
+      if (op) delete op;
+    }
+  }
+}
+catch (PThrowable & pex) {
+  cerr << " scanppf/Error - Exception catched " << (string)typeid(pex).name()
+       << " - Msg= " << pex.Msg() << endl;
+}
+
+cout << " ----------- End of scanppf ------------- " << endl;
+}
Index: /tags/V_Dec2002/SophyaProg/PrgUtil/tst.icc
===================================================================
--- /tags/V_Dec2002/SophyaProg/PrgUtil/tst.icc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PrgUtil/tst.icc	(revision 2309)
@@ -0,0 +1,13 @@
+// Code test pour runcxx.cc 
+// Appel: runcxx -f tst.icc
+  TMatrix<r_4> ma(4,7);
+  ma = RegularSequence(10., 2.);   
+  cout << "\n test pour runcxx - ma = " << ma << endl;
+  float min, max;
+  ma.MinMax(min, max);
+  cout << " MinMax(ma) : min= " << min << " max= " << max << endl;
+  TMatrix<r_4> sma = Sin(ma);
+  cout << "\n test pour runcxx - sma = Sin(ma)= " << sma << endl;
+  sma.MinMax(min, max);
+  cout << " MinMax(sma) : min= " << min << " max= " << max << endl;
+
Index: /tags/V_Dec2002/SophyaProg/PrgUtil/usedlibs
===================================================================
--- /tags/V_Dec2002/SophyaProg/PrgUtil/usedlibs	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PrgUtil/usedlibs	(revision 2309)
@@ -0,0 +1,8 @@
+TArray
+SysTools
+NTools
+SkyMap
+Samba
+SkyT
+
+
Index: /tags/V_Dec2002/SophyaProg/PrgUtil/usedslibs
===================================================================
--- /tags/V_Dec2002/SophyaProg/PrgUtil/usedslibs	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/PrgUtil/usedslibs	(revision 2309)
@@ -0,0 +1,2 @@
+sophya
+extsophya
Index: /tags/V_Dec2002/SophyaProg/Tests/JTCMakefile
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/JTCMakefile	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/JTCMakefile	(revision 2309)
@@ -0,0 +1,65 @@
+MODULECXXREPNAME := Tests
+MODULEDECCXXFLAGS := -msg_quiet -pthread 
+include $(DPCDEVREP)/Include/Makefile.h
+
+# Makefile pour linket avec libJThreadsC++
+#               Reza 
+
+ifdef NOSHLIB
+
+LIBF =  $(LIB)libSysTools.a $(LIB)libNTools.a  $(LIB)libFitsIOServer.a $(LIB)libPI.a $(LIB)libPIext.a 
+LIBS = -L$(LIB) -lPIext -lPI -lSysTools -lNTools -lBlitz  -lm
+#LIBS =  -L$(LIB) -lSysTools -lm
+ifeq ($(CXX),cxx)
+# librairie des instances de templates cxx
+LIBS := $(LIBS) -lrt
+endif
+
+else
+
+LIBF =  $(SLB)libsophya.so 
+LIBS = -L$(SLB) -lPI -lextsophya -lsophya -L$(EXTSLBPATH) -lJTC  
+ifeq ($(MACHEROS),OSF1)
+LIBS := $(LIBS) -lfor
+endif
+ifeq ($(MACHEROS),Linux)
+LIBS := $(LIBS) -ldl -lf2c -L/usr/X11R6/lib 
+endif
+LIBS := $(LIBS) -lXm -lXt -lX11 -lm
+
+endif
+
+LDLIBS := $(LIBS) $(LDLIBS) 
+ifeq ($(MACHEROS),OSF1)
+LDLIBS := $(LDLIBS) -lexc
+endif
+
+%:%.cc
+%:%.o
+%.o:%.cc
+%.o:%.c
+%:%.c
+
+.PRECIOUS: $(EXE)% $(OBJ)%.o
+
+%:$(EXE)%
+	echo $@ " done"
+
+$(EXE)%:$(OBJ)%.o
+	$(LINK.cc)  -o $@ $< $(LIBS)
+
+$(OBJ)%.o:%.cc
+	$(COMPILE.cc)   $(USERFLAGS) -o $@ $<
+
+$(EXE)%:$(OBJ)%.cc
+	$(LINK.cc) $(USERFLAGS)  -o $@ $< $(LIBS) 
+
+$(EXE)%:$(OBJ)%.c
+	$(LINK.c)  $(USERFLAGS) -o $@ $< $(LIBS) 
+
+$(OBJ)%.o:%.c
+	$(COMPILE.c) -c $(CFLAGS) $(USERFLAGS) -o $@ $< 
+
+dump :
+	echo $(LIBS)
+
Index: /tags/V_Dec2002/SophyaProg/Tests/Makefile
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/Makefile	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/Makefile	(revision 2309)
@@ -0,0 +1,72 @@
+MODULECXXREPNAME := Tests
+MODULEDECCXXFLAGS := -msg_quiet
+include $(DPCDEVREP)/Include/Makefile.h
+
+
+ifdef NOSHLIB
+
+LIBF =  $(LIB)libFitsIOServer.a $(LIB)libSamba.a $(LIB)libSkyMap.a $(LIB)libSkyT
+.a $(LIB)libNTools.a $(LIB)libHiStats.a $(LIB)libTArray.a $(LIB)libSysTools.a
+LIBS = -L$(LIB) -lFitsIOServer -lSamba -lSkyMap -lSkyT -lNTools -lHiStats -lTArr
+ay -lSysTools -lm
+
+ifeq ($(CXX),cxx)
+# librairie des instances de templates cxx
+LIBS := $(LIBS) -lrt
+endif
+
+else
+
+LIBF =  $(SLB)libsophya.so 
+LIBS = -L$(SLB) -lextsophya -lsophya -lpthread -lm 
+ifeq ($(MACHEROS),OSF1)
+LIBS := $(LIBS) -lfor
+endif
+ifeq ($(MACHEROS),Linux)
+LIBS := $(LIBS) -ldl 
+endif
+
+endif
+
+#  Sur MacOSX, LinAlg+lapack ne peuvent pas etre mis ds un
+#  shared lib (pb symbols globaux)
+ifeq ($(MACHEROS),Darwin)
+LIBS := -L$(LIB) -lLinAlg $(LIBS) -L$(EXTLIBPATH) -llapack -lblas -lg2c
+endif
+
+LDLIBS := $(LIBS) $(LDLIBS) 
+
+%:%.cc
+%:%.o
+%.o:%.cc
+%.o:%.c
+%:%.c
+
+.PRECIOUS: $(EXE)% $(OBJ)%.o
+
+%:$(EXE)%
+	echo $@ " done"
+
+$(EXE)%:$(OBJ)%.o
+	$(LINK.cc)  -o $@ $< $(LIBS)
+
+$(OBJ)%.o:%.cc
+	$(COMPILE.cc)   $(USERFLAGS) -o $@ $<
+
+$(EXE)%:$(OBJ)%.cc
+	$(LINK.cc) $(USERFLAGS)  -o $@ $< $(LIBS) 
+
+$(EXE)%:$(OBJ)%.c
+	$(LINK.c)  $(USERFLAGS) -o $@ $< $(LIBS) 
+
+$(OBJ)%.o:%.c
+	$(COMPILE.c) -c $(CFLAGS) $(USERFLAGS) -o $@ $< 
+
+dump :
+	echo $(LIBS)
+
+clean : 
+	../Mgr/cleantstprg.csh
+
+basetests : lpk arrt carrt tfft tobjio tspm zthr 
+        
Index: /tags/V_Dec2002/SophyaProg/Tests/arrt.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/arrt.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/arrt.cc	(revision 2309)
@@ -0,0 +1,366 @@
+#include "machdefs.h"
+
+#include <math.h>
+#include <iostream.h>
+#include <fstream.h>
+
+#include "tarrinit.h"
+#include "array.h"
+#include "timing.h"
+
+static void tstarr(bool tio);
+static void tstasciiio();
+static void tstioarr(TArray<int_4> & ia, TArray<int_4> & ib, TArray<int_4> & ic);
+static void tstmtx(int n);
+void _ZZ_TestTMatrixRC_YY_(TMatrix<r_8> & m);
+
+int main(int narg, char* arg[])
+{
+
+  SophyaInit();
+  InitTim();   // Initializing the CPU timer
+
+
+  if (narg < 2) {
+    cout << " arrt - TArray<T> Test - Usage arrt a/w/m/z [size=5] [prtlev=1] [nprt=50]\n" 
+	 << " a: Simple Array Test  w: a+ PPersist Test (FIO_TArray<T>) \n" 
+	 << " m: Matrix and Vector Test \n" 
+	 << " ascio: Test of ascii I/O \n" 
+	 << " z: Appel_ZZ_TestTMatrixRC_YY_ " << endl;
+    exit(0);
+  }
+
+  string opt = arg[1];
+  int n = 5;
+  if (narg > 2) n = atoi(arg[2]);
+  uint_4 prtlev = 1;
+  uint_4 nprt = 50;
+  if (narg > 3) prtlev = atoi(arg[3]);
+  if (narg > 4) nprt = atoi(arg[4]);
+
+  BaseArray::SetMaxPrint(nprt, prtlev);
+
+  try {
+    if (opt == "w")  tstarr(true);
+    else if (opt == "a") tstarr(false);
+    else if (opt == "z") {
+      if (n<5) n = 5;
+      TMatrix<r_8> tza(n,n+3);
+      tza = RegularSequence(2.,1.5);
+      _ZZ_TestTMatrixRC_YY_(tza);
+      TMatrix<r_8> tza2 = tza(Range(1,3), Range(2,5));
+      _ZZ_TestTMatrixRC_YY_(tza2);
+    }
+    else if (opt == "m") tstmtx(n);
+    else if (opt == "ascio") tstasciiio();
+    else {
+      cout << " arrt/Error : unknown option ! " << endl;
+    }
+  }
+  catch (PThrowable exc) {
+    cerr << " catched Exception " << exc.Msg() << endl;
+  }  
+  catch (...) {
+    cerr << " catched unknown (...) exception " << endl; 
+  }  
+  PrtTim("--- End of arrt ---");
+  cout << " ---------------  END of ArrayTest programme -------------- " << endl;
+}
+
+
+void tstmtx(int n)
+{
+  TMatrix<r_4> ma(4,7);
+  ma = RegularSequence(10., 2.);
+  cout << "\n ::::::  Testing TMatrix - TVector ::::::  " << endl;  
+  TMatrix<r_4> sma1 = ma(Range(1,2), Range(2,4));
+  cout << " ----- Matrix ma = \n " << ma << endl;
+  sma1 = 3.14;
+  cout << " ----- Matrix ma (Avec sma1=ma(Range(1,2), Range(2,3))=3.14) = \n " << ma << endl;
+  TMatrix<r_4> mb(2,3);
+  mb = 50.;
+  TMatrix<r_4> mc = mb+sma1;
+  cout << " ----- Matrix mc = mb(=50.)+sma1(=3.14) = " << mc << endl;
+  TMatrix<r_4> md = (float)100+mc;
+  cout << " ----- Matrix md=100.+mc = " << md << endl;
+  cout << " ----- Matrix md-50 = " << md-(float)50. << endl;
+
+  TMatrix<int_4> ima(3,10);
+  ima = RegularSequence(0.01,1.);
+  cout << " ----- Matrix ima(3,10) = RegularSequence(0.01,1.) = " << ima << endl;
+  cout << " ----- Matrix  ima.Column(3) = \n" << ima.Column(3) << endl;
+  TVector<int_4> vcol = ima.Column(7);
+  cout << " ----- Vector  vcol=ima.Column(7) = \n" << vcol << endl;
+  cout << " ----- Matrix  ima.Row(0) = \n" << ima.Row(0) << endl;
+  TVector<int_4> vlig;
+  vlig = ima.Row(1);
+  cout << " ----- Vector  vlig=ima.Row(1) = \n" << vlig << endl;
+
+  TMatrix<int_4> imb(3,10);
+  imb = RegularSequence(100.01,10.);
+  cout << " ----- Matrix imb(3,10) = RegularSequence(100.01,10.) = " << imb << endl;
+  TMatrix<int_4> imc = ima+imb;
+  cout << " ----- Matrix imc=ima+imb = " << imc << endl;
+  TMatrix<int_4> imd(3,10);
+  TMatrix<int_4> imd2(3,10);
+  imd += 25;
+  imd *= 2;
+  imd2 = 2;
+  imd.MulElt(imd2);
+  cout << " ----- Matrix imd (? = 100) " << imd << endl;
+  imb -= imd;
+  imc -= imd;
+  cout << " ----- Matrix ((imc-=imd)-(imb-=imd))-ima (== 0 ?) " 
+       << (imc-imb)-ima << endl;
+  TVector<r_4> va(16, BaseArray::RowVector);
+  va = RegularSequence(0.,1.);
+  cout << " ----- Vector va = RegularSequence(0.,1.) = " << va << endl;
+  va(Range(2,0,6,2)) *= 10.;
+  cout << " ----- Vector va apres va(Range(2,0,6,2)) *= 10. " << va << endl;
+  va(Range(0,5)) += 100.;
+  cout << " ----- Vector va apres va(Range(0,6)) += 100. " << va << endl;
+
+  TMatrix<r_4> esm(3,5);
+  EnumeratedSequence ess;
+              ess ,
+         11 , 12 , 13, 14, 15,  
+         21 , 22 , 23, 24, 25,
+         31 , 32 , 33, 34, 35  ;  
+  esm = ess;
+  cout << "\n TMatrix<r_4> esm(3,5) = EnumeratedSequence(), 11 , 12 , 13, 14, 15 ... " 
+       << esm << endl;
+  r_4 emin,emax,esum,eprod,esumx2;
+  esm.MinMax(emin, emax);  
+  esum = esm.Sum();
+  eprod = esm.Product();
+  esumx2 = esm.SumX2();
+
+  cout << " Min= " << emin << "  Max= " << emax 
+       << " Sum= " << esum << " Prod=" << eprod << " SumX2=" << esumx2 << endl;
+
+  cout << "\n :::::: Testing Matrix operations :::::: " << endl;
+  TMatrix<r_4> ra(2,2), ira(2,2);
+  /*  ra(0,0) = 2.;   ra(0,1) = 1.;
+  ra(1,0) = 4.;   ra(1,1) = 3.;
+  */
+  ira(0,0) = 1.5;   ira(0,1) = -0.5;
+  ira(1,0) = -2.;    ira(1,1) = 1.;
+  EnumeratedSequence es;
+  es, 2 , 1 , 4 , 3 ;
+  ra = es ;
+  
+  cout << " ----- Matrix ra = \n " << ra << endl; 
+  cout << " ----- Matrix ira = \n " << ira << endl; 
+  cout << " ----- Matrix ira*ra = (= Identity ?) " << ira*ra << endl; 
+
+
+  cout << "\n ::::::: Testing Matrix Inversion ::::::: " << endl;
+  SimpleMatrixOperation<r_4> smr;
+  TMatrix<r_4> cira = smr.Inverse(ra);
+  cout << " ----- Matrix Inverse(ra) =  " << cira << endl;
+  cout << " ----- ira-Inverse(ra) = " << ira-cira << endl;
+
+  Matrix a(n,n);
+
+    
+  //  for(int i=0; i<n; i++)
+  //    for(int j=0; j<n; j++)  a(j,i) = GauRnd(0., 1.);
+  a = RandomSequence(RandomSequence::Gaussian, 0., 2.5);
+  cout << " ----- Matrix a=RandomSequence(RandomSequence::Gaussian, 0., 2.5) = \n " << a << endl;
+  Vector x(n);
+  x = RegularSequence(1.,3.);
+  Vector b = a*x;
+  cout << " ----- Vector x = \n " << x << endl;
+  cout << " ----- Vector b = a*x = \n " << b << endl;
+  SimpleMatrixOperation<r_8> smo;
+  Matrix inva = smo.Inverse(a);
+  cout << " ----- Matrix Inverse(a) = \n " << inva << endl;
+  cout << " ----- Matrix a*Inverse(a) = \n " << inva*a << endl;
+  cout << " ----- Matrix Inverse(a)*b (=Inv(a)*a*x) = \n " << inva*b << endl;
+  cout << " ----- Matrix x-Inverse(a)*b = (=0 ?)\n " << x-inva*b << endl;
+}
+
+void tstarr(bool tio)
+{
+  cout << "\n -----> Testing TArray <---- " << endl;  
+  // We create a integer array SizeX=7, SizeY=5
+  TArray<int_4> ia(7,5); 
+  // We fill it with a sequence of numbers starting at 10., with step = 2.
+  ia = RegularSequence(10., 2.);
+  cout << " ----- Array IA = \n " << ia << endl;
+  // sub array extraction, Range(2,4) : starting position=2 , End=4
+  TArray<int_4> ic = ia(Range(2,3),Range(1,3),Range(0));
+  cout << " ----- Array IC IA(Range(2,3),Range(1,3)) = \n " << ic << endl;
+  // we set the sub-array to zero, this should reflect in the original array
+  // sub-arrays share their data with parent array
+  ic = 0;
+  cout << " ----- Array IC Apres (=0) = \n " << ic << endl;
+  cout << " ----- Array IA Apres IC=0 = \n " << ia << endl;
+
+  cout << "  :::: 3 Dim arrays ::::: " << endl;
+  TArray<int_4>::SetMaxPrint(1000);
+  // Creating 3-dim array (X=8 x Y=7 x Z=2) , filling it with 5
+  TArray<int_4> ib(8,7,2);
+  ib = 5;
+  cout << " ----- Array IB = \n " << ib << endl;
+  // Sub array extraction  X from 1 , size 4 - Y from 2 , size 3 , in Z default, from 0, size 1
+  // we multiply this sub-array elements by 3
+  ib(Range(1,4),Range(2,4), Range(0)) *= 3;
+  cout << " -- Array IB , Apres ib(Range(1,4),Range(2,4))*=3 : " << endl;
+  cout << ib;
+  cout << " -- Array ib(Range(1,4),Range(2,4)) =  : " 
+       << ib(Range(1,4),Range(2,4), Range(0)) << endl;
+
+  // Creating a double array X=5 x Y=2
+  TArray<r_4> fa(5,2);
+  // fill it up with a sequence of 0. to 1.
+  fa = RegularSequence(0.,1./(5*2));
+  cout << " ------ TArray<r_4> fa(5,2) = \n" << fa << endl;
+  // Create a new array from the original array , multiplying it by 2*Pi
+  TArray<r_4> fa2 = fa*(float)(2.*M_PI); 
+  cout << " ------ TArray<r_4> fa2=fa*2*Pi = \n" << fa2 << endl;
+  // Compute sin(fa2) cos(fa2)
+  cout << " ------ sin(fa2=fa*2*Pi) = \n" << Sin(fa2) << endl;
+  cout << " ------ cos(fa2=fa*2*Pi) = \n" << Cos(fa2) << endl;
+
+  //  Test des fonctions sur complexes 
+  TVector<r_4> p_real(10, BaseArray::RowVector), p_imag(10, BaseArray::RowVector);
+  p_real = RegularSequence(0., 0.5);
+  p_imag = RegularSequence(0., 0.25);
+  TVector< complex<r_4> > zvec = ComplexArray(p_real, p_imag);
+  cout << " ------ zvec = ComplexArray(p_real, p_imag) -------- "  << endl;
+  cout << " :: p_real= " << p_real; 
+  cout << " :: p_imag= " << p_imag;
+  cout << " :: zvec= " << zvec;
+  cout << " :: real(zvec) = " << real(zvec) ;
+  cout << " :::: imag(zvec) = " << imag(zvec) ;
+  cout << " :::: module2(zvec) = " << module2(zvec) ;
+  cout << " :::: module(zvec) = " << module(zvec) ;
+  cout << " :::: phase(zvec) = " << phase(zvec) ;
+  cout << " ----------------------------------------------------- " << endl;
+
+  if (tio) tstioarr(ia, ib, ic);
+}
+
+void tstioarr(TArray<int_4> & ia, TArray<int_4> & ib, TArray<int_4> & ic)
+{
+  cout << " ------ tstioarr(TArray<int_4> & ia, TArray<int_4> & ib, TArray<int_4> & ic) ---- " << endl;
+  {
+  cout << " >>>>>> Writing in  arrt.ppf <<<<<<< " << endl;
+  POutPersist pos("arrt.ppf");
+  // We write  the three arrays in the stream 
+  pos << ia << ib << ic;
+  cout << " >>>>>> Writing in  arrtn.ppf with names <<<<<<<" << endl;
+  POutPersist posn("arrtn.ppf");
+  string tag = "ArrIA";
+  posn.PutObject(ia, tag);
+  tag = "ArrIB";
+  posn.PutObject(ib, tag);
+  tag = "ArrIC";
+  posn.PutObject(ic, tag);
+  }
+
+  {
+  cout << " >>>>>>> Reading from  arrt.ppf  <<<<< " << endl;
+  PInPersist pis("arrt.ppf");
+  TArray<int_4> iaa, ibb, icc; 
+  // We read the three arrays from the stream 
+  pis >> iaa >> ibb >> icc;
+  cout << " ----- Array IAA = \n " << iaa << endl;
+  cout << " ----- Array IBB = \n " << ibb << endl;
+  cout << " ----- Array ICC = \n " << icc << endl;
+  icc = 12;
+  cout << " ----- Array ICC (=12) = \n " << icc << endl;
+  cout << " ----- Array IAA (ICC=12) = \n " << iaa << endl;
+  }
+
+  {
+  cout << " >>>>>>> Reading from  arrtn.ppf  <<<<< " << endl;
+  PInPersist pis("arrtn.ppf");
+  TArray<int_4> iaa, ibb, icc; 
+  // We read the three arrays from the stream 
+  string tag = "ArrIC";
+  pis.GetObject(icc, tag);
+  tag = "ArrIB";
+  pis.GetObject(ibb, tag);
+  tag = "ArrIA";
+  pis.GetObject(iaa, tag);
+
+  cout << " ----- Array IAAA = \n " << iaa << endl;
+  cout << " ----- Array IBBB = \n " << ibb << endl;
+  cout << " ----- Array ICCC = \n " << icc << endl;
+  icc = 68;
+  cout << " ----- Array ICCC (=12) = \n " << icc << endl;
+  cout << " ----- Array IAAA (ICC=12) = \n " << iaa << endl;
+  }
+
+}
+
+
+void tstasciiio()
+{
+
+cout << "\n -----> Testing EnumeratedSequence/TArray ASCII I/O <---- " << endl; 
+
+EnumeratedSequence ess;
+int nbad;
+ess.Append("56.5 (1.,-1.) 4 8 16", nbad);
+cout << " --- ess.Append(\"56.5 (1.,-1.) 4 8 16\", nbad) :  ess=" << endl;
+cout << ess;
+
+EnumeratedSequence ess2;
+ess2.Append("56.5 (-3.14, 12) 'Hello' 4. 8.565432 12 32 3.1415e-6", nbad);
+cout << " --- ess2.Append(...) ess2=" << endl; 
+cout << ess2;
+cout << " --- ess2.Append(...) (2) ess2=" << endl; 
+ess2.Append("(2.7, -8) Bonjour ByeBye 'Comment ca va ?' 64 64.7 128 1.28 25.6e3", 
+	    nbad);
+cout << ess2;
+
+Matrix A(4,6);
+A = RegularSequence(0.5, 0.2);
+cout << " Matrix A(4,6); A=RegularSequence(0.5, 0.2) : " << endl;
+cout << A ;
+
+char * flnm = "arr_ascii.txt";
+{
+cout << " Writing A to file " << flnm << endl;
+ofstream ofs(flnm);
+A.WriteASCII(ofs);
+}
+
+Matrix B;
+sa_size_t nr, nc;
+{
+ifstream ifs(flnm);
+B.ReadASCII(ifs,nr,nc);
+}
+
+cout << " Matrix B; B.ReadASCII() from file " << flnm << endl;
+cout << B ;
+
+Vector C;
+{
+ifstream ifs(flnm);
+ifs >> C;
+}
+cout << " Vector C; ifstream( " << flnm << ") >> C " << endl;
+cout << " C.Transpose()= " << C.Transpose() ;
+
+TVector<int_4> IC;
+{
+ifstream ifs(flnm);
+IC.ReadASCII(ifs,nr,nc);
+}
+cout << " TVector<int_4> IC; IC.ReadASCII() from file " << flnm << endl;
+cout << " IC.Transpose()= " << IC.Transpose() ;
+
+TArray<r_4> D(4,6,2);
+{
+ifstream ifs(flnm);
+D.ReadASCII(ifs,nr,nc);
+}
+cout << " TArray<r_4> D(4,6,2); D.ReadASCII() from file " << flnm << endl;
+cout << D ;
+
+}
Index: /tags/V_Dec2002/SophyaProg/Tests/carrt.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/carrt.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/carrt.cc	(revision 2309)
@@ -0,0 +1,208 @@
+#include "machdefs.h"
+
+#include <math.h>
+#include <iostream.h>
+
+#include "tarrinit.h"
+#include "array.h"
+#include "timing.h"
+
+static int test_ac();
+static int test_oso(int r, int c);
+static int test_odo(int r, int c);
+
+static int prtlev = 0;
+static int nprt = 100;
+
+template <class T>
+void getMinMax(TArray<T>& a, T& min, T& max)
+{
+  min = a[0];
+  max = a[0];
+  for(uint_8 k=1; k<a.Size(); k++) {
+    if (a[k]<min)  min = a[k];
+    else if (a[k]>max)  max = a[k];
+  }
+}
+
+int main(int narg, char* arg[])
+{
+
+  SophyaInit();
+  InitTim();   // Initializing the CPU timer
+
+  if (narg < 2) {
+    cout << " carrt ac/oso/odo [NRow=5] [NCols=10] [prtlev=0] [nprtmax=100] \n"
+	 << "   ac : array conversion test   \n" 
+	 << "   oso : operation same memory organisation \n" 
+	 << "   odo : operation different memory organisation \n" << endl;
+    exit(0);
+  }
+
+  string opt = arg[1];
+  int nr = 5;
+  int nc = 10;
+  if (narg > 2) nr = atoi(arg[2]);
+  if (narg > 3) nc = atoi(arg[3]);
+  if (narg > 4) prtlev = atoi(arg[4]);
+  if (narg > 5) nprt = atoi(arg[5]);
+
+  BaseArray::SetMaxPrint(nprt, prtlev);
+  
+  PrtTim(" Start of Test ");
+  try {
+    if (opt == "ac") test_ac();
+    else if (opt == "oso") test_oso(nr, nc);
+    else if (opt == "odo") test_odo(nr, nc);
+  }
+  catch (PThrowable & exc) {
+    cerr << " catched Exception " << exc.Msg() << endl;
+  }  
+  catch (...) {
+    cerr << " catched unknown (...) exception " << endl; 
+  }  
+
+  PrtTim(" End of Test ");
+
+}
+
+
+int test_ac()
+{
+    cout << "\n -----> Testing TArray Conversion <---- " << endl;
+     TArray<int_4> ia(7,5);   
+     ia = RegularSequence(10., 2.);
+     TArray<r_4> ra(7,5);   
+     ra = ia;
+     cout << " ra = ia(= RegularSequence(10., 2.)) = \n " << ra << endl;
+     TArray<r_4> rb(5,3);
+     rb =  RegularSequence(20., .5);  
+     TMatrix<int_4> mx(3,5);
+     cout << " TArray<r_4> rb(5,3); rb =  RegularSequence(20., .5); rb : " << endl;
+     cout << rb << endl;
+     mx = rb;
+     cout << " TMatrix<int_4> mx(3,5);       mx = rb;  mx: " << endl;
+     cout << mx << endl;
+     TArray<r_4> rc(10);
+     rc = 3.1415;
+     TMatrix<r_8> mx2(rc);
+     cout << "   TArray<r_4> rc(10) = 3.1415 , TMatrix<r_8> mx2(rc) rc : " << endl;
+     cout << mx2 << endl;
+     TMatrix<int_4> mx3(3,5);
+     cout << " Trying      TMatrix<int_4> mx3(3,5);  mx3 = rc; ?? " << endl;
+     mx3 = rc;
+     return(0);
+}
+
+int test_oso(int nr, int nc)
+{
+  cout << "\n -----> Testing TArray operation TArray<int_4>(nx=" << nr << ",ny=" 
+       << nc << " )" << endl;
+
+  int rc = 0;
+  int min,max;
+
+  TArray<int_4> a(nr,nc);
+  a = 20;
+  TArray<int_4> b(nr,nc);
+  b = 9;
+  TArray<int_4> c = a-2*b;
+
+  if (prtlev > 0) {
+    cout << " A = \n " << a << endl;
+    cout << " B = \n " << b << endl;
+    cout << " C = A-2*B= \n " << c << endl;
+  }
+
+  getMinMax(c, min, max);
+  if ((min != 2) || (max != 2)) {
+    cout << "!!! ERROR Test C=A+2*B  Min=" << min << " Max=" << max << endl;
+    rc += 1;
+  }
+  else cout << " OK   Test C=A+2*B  OK " << endl; 
+
+  c = (a*4+1).DivElt(b);
+  if (prtlev > 0) cout << " C = (A*4+1)/B = \n" << c << endl;
+  getMinMax(c, min, max);
+  if ((min != 9) || (max != 9)) {
+    cout << "!!! ERROR Test C = (A*4+1)/B  Min=" << min << " Max=" << max << endl;
+    rc += 2;
+  }
+  else cout << " OK   Test C = (A*4+1)/B  OK " << endl; 
+  
+  a = RegularSequence(1, 1);
+  b = RegularSequence(nr*nc, -1);
+  c = (a*2)+(b*2);
+  if (prtlev > 0) {
+    cout << " A = \n " << a << endl;
+    cout << " B = \n " << b << endl;
+    cout << " C = 2A-2*B= \n " << c << endl;
+  }
+  c /= (nr*nc+1);
+  getMinMax(c, min, max);
+  if ((min != 2) || (max != 2)) {
+    cout << "!!! ERROR Test3 C=2A+2*B  Min=" << min << " Max=" << max << endl;
+    rc += 1;
+  }
+  else cout << " OK   Test3 C=2A+2*B  OK " << endl; 
+  
+  return(rc);
+}
+
+int test_odo(int nr, int nc)
+{
+  cout << "\n -----> Testing TMatrix operation TMatrix<r_4>(nr=" << nr << ",nc=" 
+       << nc << " )" << endl;
+  cout << "   A CMemoryMapping  - B FortranMemoryMapping " << endl;
+
+  int rc = 0;
+  r_4 min,max;
+
+  TMatrix<r_4> a(nr,nc,BaseArray::CMemoryMapping);
+  a = 20;
+  TMatrix<r_4> b(nr,nc,BaseArray::FortranMemoryMapping);
+  b = 9;
+  TMatrix<r_4> c(nr,nc,BaseArray::CMemoryMapping);
+
+  if (prtlev > 0) {
+    cout << " A = \n " << a << endl;
+    cout << " B = \n " << b << endl;
+  }
+  c = a-(b*2.0f);
+  if (prtlev > 0) cout << " C = A-2*B= \n " << c << endl;
+
+  getMinMax(c, min, max);
+  if ((fabs(min-2.) > 0.0001) || (fabs(max-2.) > 0.0001)) {
+    cout << "!!! ERROR Test C=A+2*B  Min=" << min << " Max=" << max << endl;
+    rc += 1;
+  }
+  else cout << " OK   Test C=A+2*B  OK " << endl; 
+
+  c = (a*4.0f+5.5f).DivElt(b);
+  if (prtlev > 0) cout << " C = (A*4+12)/B = \n" << c << endl;
+  getMinMax(c, min, max);
+  if ((fabs(min-9.5) > 0.0001) || (fabs(max-9.5) > 0.0001)) {
+    cout << "!!! ERROR Test C = (A*4+12)/B  Min=" << min << " Max=" << max << endl;
+    rc += 2;
+  }
+  else cout << " OK   Test C = (A*4+12)/B  OK " << endl; 
+
+  a = RegularSequence(1, 1);
+  b = RegularSequence(nr*nc, -1);
+  c = (a*2.f)+(b*2.f);
+  if (prtlev > 0) {
+    cout << " A = \n " << a << endl;
+    cout << " B = \n " << b << endl;
+    cout << " C = 2A-2*B= \n " << c << endl;
+  }
+  c /= (nr*nc+1);
+  getMinMax(c, min, max);
+  if ((fabs(min-2.) > 0.0001) || (fabs(max-2.) > 0.0001)) {
+    cout << "!!! ERROR Test3 C=2A+2*B  Min=" << min << " Max=" << max << endl;
+    rc += 1;
+  }
+  else cout << " OK   Test3 C=2A+2*B  OK " << endl; 
+
+  return(rc);
+
+}
Index: /tags/V_Dec2002/SophyaProg/Tests/exacmplnk.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/exacmplnk.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/exacmplnk.cc	(revision 2309)
@@ -0,0 +1,15 @@
+#include "array.h"
+
+extern "C" {
+  void exacmplnk();
+}
+
+void exacmplnk()
+{
+  TMatrix<r_4> ma(4,7);
+  ma = RegularSequence(10., 2.);   
+  cout << "\n exacmplnk() - ma = " << ma << endl;
+  TMatrix<r_4> sma = Sin(ma);
+  cout << "\n exacmplnk() - sma = Sin(ma)= " << sma << endl;
+
+}
Index: /tags/V_Dec2002/SophyaProg/Tests/fitsServTest.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/fitsServTest.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/fitsServTest.cc	(revision 2309)
@@ -0,0 +1,146 @@
+//++
+// Verbatim	
+//
+
+#include <iostream.h>
+#include "fitsioserver.h" 
+#include "tvector.h"
+//#include "spheregorski.h"
+#include "spherethetaphi.h"
+#include "localmap.h"
+#include "skymapinit.h"
+
+
+int main() 
+{
+  // ----- ATTENTION -------
+  // Initialisation de Sophya
+  // A faire au debut de main()
+  SophyaInit();
+
+   FitsIoServer fserv;
+  int nsmax=32;
+   // test pour les vecteurs 
+   /* 
+  double tab[12]={1,2,3,4,5,6,7,8,9,10,11,12};
+  TVector<double> V(12,tab);
+  delete [] tab;
+  cout << " impression du vecteur V" << endl;
+  cout << V << endl;
+  fserv.save(V, "vecteur.fits");
+  TVector<double> W(5);
+  fserv.load(W,"vecteur.fits");
+  cout << " impression du vecteur W" << endl;
+  cout << W << endl;
+  */
+   // test pour les matrices
+   /*
+   double tab[12]={1,2,3,4,5,6,7,8,9,10,11,12};
+   //TMatrix<double> m(3,4,tab);
+   TVector<double> m(12,tab);
+   cout << " impression de la matrice m" << endl;
+   cout << m << endl;
+   fserv.save(m, "matrice.fits");
+   TMatrix<double> mm(2,3);
+   //TVector<double> mm(12);
+   fserv.load(mm,  "matrice.fits"); 
+   cout << " impression de la matrice mm" << endl;
+   cout << mm << endl;
+   */
+   // test pour spheres
+   /*
+  // nsmax est parameter chez Gorski (anafast)
+  int bid=0;
+  
+  //int npixtot=12*32*32;
+  //float map[12*32*32];
+   // test pour les spheres
+  // Définition de la sphère 
+   int  m=nsmax;
+  double teta,phi;
+  SphereGorski<float> sph1(nsmax);
+  //SphereThetaPhi sph1(nsmax);
+  for (int j=0;j<sph1.NbPixels();j++) 
+    {
+      sph1.PixThetaPhi(j,teta,phi);
+      int bid= sph1.PixIndexSphNest(teta,phi);
+      int bid2= sph1. NestToRing(bid);
+      sph1(bid2)= 200* cos(3.*teta)*sin(8*phi);
+    }
+   // test projection sur une image fits
+   cout << " je  projette  la sphere 1 " <<endl;
+   char fileimg[]="img1.fits";
+   fserv.sinus_picture_projection(sph1,fileimg);
+
+   */
+
+
+   /*
+   // test ecriture sur une image
+   char fileout[]="out.fits";
+   cout << " ecriture dans " << fileout << endl;
+   fserv.save(sph1,fileout);   
+   cout << "relecture du fichier " << fileout << " qu'on verse dans une autre sphere" << endl;
+   m=8;
+   //SphereThetaPhi sph2(m);   
+   SphereGorski<float> sph2(m);   
+   fserv.load(sph2,fileout); 
+  
+  for (int j=0;j<10;j++) 
+    {
+      sph2.PixThetaPhi(j,teta,phi);
+      int bid= sph2.PixIndexSphNest(teta,phi);
+      int bid2= sph2.NestToRing(bid);
+      cout << " ring= " << j << " nest= " << bid << " ring= " << bid2 << endl;
+    }
+
+   // reprojection sur image
+   cout << " je  projette  la sphere 2 " <<endl;
+   char fileimg2[]="img2.fits";
+   fserv.sinus_picture_projection(sph2,fileimg2);
+
+   */
+   // test pour localmap
+  int  m=nsmax;
+  //SphereGorski<double> sph1(nsmax);
+  SphereThetaPhi<double> sph1(nsmax);
+  for (int j=0;j<sph1.NbPixels();j++) 
+    {
+      double teta,phi;
+      sph1.PixThetaPhi(j,teta,phi);
+      //int bid= sph1.PixIndexSphNest(teta,phi);
+      //int bid2= sph1. NestToRing(bid);
+      sph1(j)= 200* cos(3.*teta)*sin(8*phi);
+    }
+  LocalMap<double> lcl(600,300);
+  lcl.SetOrigin(90.,180.);
+  lcl.SetSize(60.,60.);
+  for (int k=0; k< lcl.NbPixels(); k++)
+    {
+      double theta, phi;
+      lcl.PixThetaPhi(k, theta, phi);
+      lcl(k)=sph1(sph1.PixIndexSph( theta, phi));
+    }
+  cout << " dessin sur img5" << endl;
+  fserv.picture(lcl,"img5.fits");
+  cout << " sauvegarde sur out5" << endl;
+  fserv.save(lcl,"out5.fits");
+  /*		
+  SphereGorski<double> sph3(nsmax);
+  lcl.Project(sph3);
+  cout << " je  projette  la sphere 3 " <<endl;
+  char fileimg3[]="img3.fits";
+  fserv.sinus_picture_projection(sph3,fileimg3);
+  char fileout3[]="out3.fits";
+  fserv.save(lcl,fileout3);
+  LocalMap<double> lcl2(3,4);
+  fserv.load(lcl2,fileout3);
+  SphereGorski<double> sph4(nsmax);
+  lcl2.Project(sph4);
+  cout << " je  projette  la sphere 4 " <<endl;
+  char fileimg4[]="img4.fits";
+  fserv.sinus_picture_projection(sph4,fileimg4);
+  */
+   cout <<  " ===== Fin de testfits ======== " << endl;
+   exit( 0 );
+}
Index: /tags/V_Dec2002/SophyaProg/Tests/fitsioGorski.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/fitsioGorski.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/fitsioGorski.cc	(revision 2309)
@@ -0,0 +1,28 @@
+// Utilisation des flots d'entree-sortie C++
+#include <iostream.h>
+// Utilisation de la classe LocalMap<T>
+#include "ntoolsinit.h"
+#include "spheregorski.h"
+#include "ntuple.h"
+
+// Utilisation des generateurs aleatoires
+#include "nbrandom.h"
+#include "fitsioserver.h" 
+#include "skymapinit.h"
+
+int main()
+{
+
+  // ----- ATTENTION -------
+  // Initialisation de Sophya
+  // A faire au debut de main()
+  SophyaInit();
+
+  int m=4;
+  SphereGorski<float> sph(m);
+  cout << " nombre de pixels: " << sph.NbPixels() << endl;
+  FitsIoServer fserv;
+  fserv.load(sph, "map_essai.fits",2);
+  //sph.print(cout);
+   fserv.Mollweide_picture_projection(sph, "dessin.fits");
+}
Index: /tags/V_Dec2002/SophyaProg/Tests/fitsioImage.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/fitsioImage.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/fitsioImage.cc	(revision 2309)
@@ -0,0 +1,40 @@
+// Utilisation des flots d'entree-sortie C++
+#include <iostream.h>
+// Utilisation de la classe Image<T>
+#include "ntoolsinit.h"
+#include "cimage.h"
+// Utilisation des generateurs aleatoires
+#include "nbrandom.h"
+#include "fitsioserver.h" 
+#include "skymapinit.h"
+
+
+int main()
+{
+
+  // ----- ATTENTION -------
+  // Initialisation de Sophya
+  // A faire au debut de main()
+  SophyaInit();
+
+  ImageR4  img(20, 10);
+  r_4 compt=0;
+  for(int i=0; i<20; i++)
+    {
+      for(int j=0; j<10; j++)
+	{
+	  compt+=1.;
+	  img(i,j) =compt+0.6;
+    }
+    }
+  img.CheckDyn();
+  img.Print();
+  img.PrintImage();
+  FitsIoServer fserv;
+  fserv.save(img,"image.fits");
+  ImageI4  img2(20, 10);
+  fserv.load(img2,"image.fits");
+  img2.Print();
+  img2.PrintImage();
+ 
+}
Index: /tags/V_Dec2002/SophyaProg/Tests/fitsioLocMap.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/fitsioLocMap.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/fitsioLocMap.cc	(revision 2309)
@@ -0,0 +1,37 @@
+// Utilisation des flots d'entree-sortie C++
+#include <iostream.h>
+// Utilisation de la classe LocalMap<T>
+#include "ntoolsinit.h"
+#include "localmap.h"
+
+// Utilisation des generateurs aleatoires
+#include "nbrandom.h"
+#include "fitsioserver.h" 
+#include "skymapinit.h"
+
+
+int main()
+{
+
+  // ----- ATTENTION -------
+  // Initialisation de Sophya
+  // A faire au debut de main()
+  SophyaInit();
+
+  int nx=10;
+  int ny=5;
+  LocalMap cart(nx,ny);
+
+  float tt=1.57;
+  float ff=3.14;
+  cart.SetOrigin(tt*1.5,tt,45.);
+  cart.SetSize(60.,30.);
+  for(int j=0; j<cart.NbPixels(); j++ ) {
+    float theta,phi;
+    cart.PixThetaPhi(j, theta,phi);
+    int jsph=sph.PixIndexSph(theta, phi);
+    cart(j)= (double)j;
+  }
+ 
+ 
+}
Index: /tags/V_Dec2002/SophyaProg/Tests/fitsioSphere.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/fitsioSphere.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/fitsioSphere.cc	(revision 2309)
@@ -0,0 +1,32 @@
+// Utilisation des flots d'entree-sortie C++
+#include <iostream.h>
+// Utilisation de la classe LocalMap<T>
+#include "ntoolsinit.h"
+#include "spheregorski.h"
+
+// Utilisation des generateurs aleatoires
+#include "nbrandom.h"
+#include "fitsioserver.h" 
+#include "skymapinit.h"
+
+int main()
+{
+
+  // ----- ATTENTION -------
+  // Initialisation de Sophya
+  // A faire au debut de main()
+  SophyaInit();
+
+  int m=4;
+  SphereGorski<float> sph(m);
+  cout << " nombre de pixels: " << sph.NbPixels() << endl;
+  for(int j=0; j<sph.NbPixels(); j++ ) {
+    sph(j)= (float)j;
+  }
+  sph.print(cout);
+  FitsIoServer fserv;
+  fserv.save(sph, "sph.fits");
+  SphereGorski<double> sph2(m);
+  fserv.load(sph2, "sph.fits");
+  sph2.print(cout);
+}
Index: /tags/V_Dec2002/SophyaProg/Tests/jtcpitarr.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/jtcpitarr.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/jtcpitarr.cc	(revision 2309)
@@ -0,0 +1,397 @@
+#include "machdefs.h"
+#include "JTC/JTC.h"
+
+#include <math.h>
+#include <iostream.h>
+#include <stdexcept>
+
+//  Include file pour PI 
+#include "pisysdep.h"
+
+#include PIAPP_H
+#include PIMENU_H 
+#include PISTDWDG_H 
+#include PIWIN_H
+#include PIPERIODIC_H
+#include "picons.h"
+
+//  Include file Sophya (TArray) 
+#include "tarrinit.h"
+#include "array.h"
+#include "timing.h"
+
+using namespace std;
+
+// ..........................................................
+// Programme interactive de test des threads JThreadsC++ 
+// avec les arrays de Sophya et PI 
+//     R. Ansari  LAL-IN2P3/CNRS   05/2000
+// ..........................................................
+
+// ................... MtxComputer ...................
+// A thread class for doing matrix computation 
+class PIJTApp;
+class MtxComputer : public JTCThread   // <JThreadC++> 
+{
+public:
+  MtxComputer(PIJTApp * japp, PIScale * sc, int id, int sz, int nloop);
+  virtual void run();
+protected:
+  int id_;
+  int sz_;
+  int nloop_;
+  PIJTApp * japp_;
+  PIScale * sc_;
+};
+
+// ................... CPUTimer ...................
+// Periodic class for CPU and elapsed time counting 
+class CPUTimer : public PIPeriodic {
+public:
+  CPUTimer(PIJTApp * app);
+  virtual void DoPeriodic();
+protected:
+  PIJTApp * japp; 
+  int dt;
+};
+
+// ................... PIJTApp ...................
+// La classe application   <JThreadC++> 
+class PIJTApp : public PIApplication , public JTCThread {
+// class PIJTApp : public PIApplication  {   // Pas oblige d'en faire un Thread
+public:
+  PIJTApp(int narg, char* arg[]);
+  ~PIJTApp();
+  virtual void   Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+  virtual void   UpdateCPUTime();
+  virtual void   run();    //  <JThreadC++> 
+  // virtual void Run();    Si pas thread
+  JTCMonitor &   getMonitor();  // <JThreadC++>  for synchronization 
+protected:
+  PIMenu * m[3];
+  PIScale *sc[2];
+  PILabel *tlab[2];
+  PILabel *cputlab;
+  PIConsole* cons;
+  // CPU and elapsed time
+  CPUTimer tm;
+  clock_t cput0;
+  time_t t0;
+  // The computing threads 
+  JTCThreadHandle thr[2];    //  <JThreadC++> 
+  // for synchronization with other threads
+  JTCMonitor amon;   //  <JThreadC++> 
+  int syn_cntrl;
+};
+
+
+// .........................................................
+// .............   PIJTApp  implementation .................
+// .........................................................
+
+PIJTApp::PIJTApp(int narg, char* arg[])
+  : PIApplication(600, 400, narg, arg) , tm(this)  // 200 ms timer
+{
+if (narg < 3) throw ParmError("PIJTApp::PIJTApp() narg<3 !");
+
+m[0] = new PIMenu(Menubar(),"Fichier");
+m[0]->AppendItem("Start", 10101);
+m[0]->AppendItem("Exit", 10110);
+AppendMenu(m[0]);
+m[1] = new PIMenu(Menubar(),"Thread-1");
+m[1]->AppendItem("Suspend", 10201);
+m[1]->AppendItem("Resume", 10202);
+m[1]->AppendItem("Stop", 10203);
+AppendMenu(m[1]);
+m[2] = new PIMenu(Menubar(),"Thread-2");
+m[2]->AppendItem("Suspend", 10301);
+m[2]->AppendItem("Resume", 10302);
+m[2]->AppendItem("Stop", 10303);
+AppendMenu(m[2]);
+
+cputlab = new PILabel(MainWin(), "CPUTime", 590, 30, 5, 5);
+cputlab->SetBorderWidth(1);
+
+tlab[0] = new PILabel(MainWin(), "Thr-1", 50, 30, 10, 40);
+sc[0] = new PIScale(MainWin(), "Sc-Thr-1", 510, kSDirLtoR, 220, 40, 70, 40);
+sc[0]->SetValue(0);
+tlab[1] = new PILabel(MainWin(), "Thr-2", 50, 30, 300, 40);
+sc[1] = new PIScale(MainWin(), "Sc-Thr-2", 520, kSDirLtoR, 220, 40, 360, 40);
+sc[1]->SetValue(0);
+
+// Creating the console and redirecting output
+cons = new PIConsole(MainWin(), "PIConsole", 700, 500, 80, 600, 315, 0, 85, true );
+cons->SetBinding(PIBK_fixed, PIBK_fixed, PIBK_fixed, PIBK_fixed);
+RedirectOutStream(cons);
+//RedirectErrStream(cons);
+
+// Creating matrix Computing thread 
+int nloop = atoi(arg[1]);
+int size = atoi(arg[2]);
+thr[0] = new MtxComputer(this, sc[0], 0, size, nloop);
+thr[1] = new MtxComputer(this, sc[1], 1, size, nloop);
+
+cput0 = clock();  t0 = time(NULL);
+tm.Start();  // We start our cpu timer
+syn_cntrl = 0;  // Normal event loop 
+}
+
+PIJTApp::~PIJTApp()
+{
+int k;
+for(k=0; k<3; k++) delete m;
+for(k=0; k<2; k++) { delete tlab[k];  delete sc[k]; }
+delete cputlab;
+
+delete cons;
+}
+
+void PIJTApp::UpdateCPUTime()
+{
+clock_t cput;
+time_t elt;
+time_t tm;  struct tm * stm;
+elt = time(&tm);  stm = localtime(&tm);
+cput = clock();
+float tcal = ( (float)(cput) - (float)(cput0) ) / (float)(CLOCKS_PER_SEC);
+float  etm = elt - t0;
+float percen = (elt > t0) ?  (tcal*100.)/etm : 0.;
+char buff[192];
+sprintf(buff, "%02d:%02d:%02d CPUTime= %g sec Elapsed= %g sec (%g %%)", 
+	stm->tm_hour, stm->tm_min, stm->tm_sec,
+	tcal, etm, percen);
+
+string s = buff;
+cputlab->SetLabel(s);
+}
+
+JTCMonitor &  PIJTApp::getMonitor()
+{
+syn_cntrl++;
+return amon;
+}
+
+void PIJTApp::run()
+  // void PIJTApp::Run()  Si pas thread
+{
+
+XEvent evt;
+int szx, szy, szf;
+XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
+// Pour appeler FinishCreate() des objets dans la fenetre principale 
+if (mStop) { // C'est la premiere fois
+  topwdg->SetSize(MBCont()->XSize(), MBCont()->YSize());
+  MBCont()->FinishCreate();   
+  }
+else mStop = true;   // On rerentre apres un stop 
+
+cout << "DBG-PIJTApp::run/Run Starting event loop " << endl;
+try {
+  JTCSynchronized sync(amon);  //  <JThreadC++>   synchronized block 
+
+  while (mStop) {
+    while (syn_cntrl > 0) {
+      amon.wait();  //  <JThreadC++>  
+      syn_cntrl = 0;
+    }
+    XtAppNextEvent(*appctx, &evt);
+    XtDispatchEvent(&evt);
+  }
+}
+catch (JTCException const & e) {  // <JThreadC++>
+  cerr << "PIJTApp::run() Catched JTCException  Msg= " << e.getMessage() << endl;
+}
+catch (JTCThreadDeath const & e) {  // <JThreadC++>
+  cerr << "PIJTApp::run() Catched JTCThreadDeath exception ! " << endl;
+}
+catch (...) {
+  cerr << "PIJTApp::run() Catched ... exception " << endl;
+}
+
+
+}
+
+void PIJTApp::Process(PIMessage msg, PIMsgHandler* sender, void* data)
+{
+  int num;
+try {
+  switch(UserMsg(msg)) {
+  case 10101 : // starting computing threads 
+    thr[0]->start();  //  <JThreadC++> 
+    thr[1]->start();  //  <JThreadC++> 
+    break;
+  case 10110 : // starting computing threads 
+    RedirectOutStream(NULL);
+    RedirectErrStream(NULL);
+    cout << " PIJTApp::Process() Waiting for threads to terminate ... " << endl;
+    thr[0]->join();  //  <JThreadC++> 
+    thr[1]->join();  //  <JThreadC++> 
+    Stop();
+    break;
+  case 10201 :
+  case 10301 :
+    num = (UserMsg(msg)-10201)/100;
+    thr[num]->suspend();  //  <JThreadC++> 
+    break;
+  case 10202 :
+  case 10302 :
+    num = (UserMsg(msg)-10202)/100;
+    thr[num]->resume();  //  <JThreadC++> 
+    break;
+  case 10203 :
+  case 10303 :
+    num = (UserMsg(msg)-10203)/100;
+    thr[num]->stop();  //  <JThreadC++> 
+    break;
+  }
+}
+catch (JTCException const & e) {  // <JThreadC++>
+  cerr << "PIJTApp::Process() Catched JTCException  Msg= " << e.getMessage() << endl;
+}
+catch (...) {
+  cerr << "PIJTApp::Process() Catched ... exception " << endl;
+}
+
+}
+
+// .........................................................
+// .............   CPUTimer implementation .................
+// .........................................................
+
+CPUTimer::CPUTimer(PIJTApp * app)
+: PIPeriodic(1)
+{
+japp = app;
+dt = -1;
+SetIntervalms(200);  // 200 ms interval timer
+}
+
+void
+CPUTimer::DoPeriodic()
+{
+dt++;
+if ((dt == 0) || (dt >= 5)) { japp->UpdateCPUTime();  dt = 0; }
+}
+
+
+// .........................................................
+// .............  MtxComputer implementation ...............
+// .........................................................
+
+// A global monitor for print synchronisation 
+JTCMonitor prtmon;  // <JThreadC++> 
+
+MtxComputer::MtxComputer(PIJTApp * japp, PIScale * sc, int id, int sz, int nloop)
+{
+  id_ = id;  sz_ = sz;  nloop_ = nloop;  japp_ = japp;  sc_ = sc; 
+}
+
+void MtxComputer::run()
+{
+  int n = sz_;
+  double seuil = 1.e-6;
+  Matrix id;
+  id = IdentityMatrix(1.,n);
+  double gmax = -1.e99;
+  double gmin = 1.e99;
+  int npb = 0;
+  // Loop creating a random matrix, inverting it
+  // and checking the result 
+  for(int k=0; k<nloop_; k++) {
+    try {
+      Matrix a(n,n);
+      a = RandomSequence(RandomSequence::Gaussian, 0., 2.5);
+      Matrix inva = Inverse(a);
+      Matrix diff = id-a*inva;
+      double max = -1.e99;
+      double min = 1.e99;
+      double x;
+      int nerr = 0;
+      for(int i=0; i<n; i++) 
+	for(int j=0; j<n; j++) {
+	  x = diff(i,j);
+	  if (x < min)  min = diff(i,j); 
+	  if (x > max)  max = diff(i,j); 
+	  if (fabs(x) > seuil)  nerr++;
+	}
+      if (min < gmin) gmin = min;
+      if (max > gmax) gmax = max;
+      if (nerr > 0) npb++;
+      {  // Synchronized writing to cout stream  
+	JTCSynchronized sync(prtmon);  // <JThreadC++> 
+	cout << " ------- Thread[" << id_ << "] K= " 
+	     << k << "  NErr = " << nerr << endl;
+	cout << "  Min(Diff) = " << min << " Max(Diff) = " << max << endl;
+	if (k == nloop_-1) {
+	  double frac = (double)npb*100./(double)nloop_;
+	  cout << " ...... Thread[" << id_ << "] End NPb= " << npb 
+	       << " / NTot= " << nloop_ << " ( = " << frac << " %) " << endl;
+	  cout << "  GMin(Diff) = " << gmin << " GMax(Diff) = " << gmax << endl;
+	  cout << " ..................................................... " << endl;
+	}
+      }
+      {  // Synchronized updating of Scale Widget 
+	JTCMonitor & amon = japp_->getMonitor();
+	JTCSynchronized sync(amon);  // <JThreadC++> 
+	// The event loop should be stopped until the end of the block
+	int percentage = 100*(k+1)/nloop_;
+	sc_->SetValue(percentage);
+	amon.notify();   // <JThreadC++> 
+      }
+ 
+    }
+    catch (PException const & e) {
+	cerr << "MtxComputer Catched PException in  Thread(" << (string)getName() 
+	     << ") Msg= " << e.Msg() << endl;
+    }
+    catch (JTCException const & e) {  // <JThreadC++>
+	cerr << "MtxComputer Catched JTCException in  Thread(" << (string)getName() 
+	     << ") Msg= " << e.getMessage() << endl;
+    }
+  }
+}
+
+
+// .........................................................
+// ................... The main program ....................
+// .........................................................
+
+int main(int narg, char* arg[])
+{
+
+  if (narg < 3) {
+    cout << " jtcpitarr - JThreadsC++/PI+Sophya::TArray<T> Test \n " 
+	 << " ... Usage jtcpitarr NLoop MtxSize [-JTCss ... \n" 
+	 << "     NLoop=10...10^4  MtxSize=10...10^3 \n"
+	 << endl;
+    exit(0);
+  }
+
+  InitTim();   // Initializing the CPU timer
+
+  int nloop = atoi(arg[1]);
+  int size = atoi(arg[2]);
+  cout << " ::::: jtcpitarr - JThreadsC++/PI+Sophya::TArray<T> Test ::::: \n"
+       << " NLoop= " << nloop << " MtxSize= " << size << endl;   
+
+  try {
+    SophyaInit();  // Sophya Initialization
+    JTCInitialize iniJTC(narg, arg);  // <JThreadC++>  Initialize library
+    JTCThreadHandle t = new PIJTApp(narg, arg);  // <JThreadC++>  
+    t->start();   // <JThreadC++>  -   starting event loop 
+    t->join();    // <JThreadC++>  Waiting for thread to end
+    //  PIJTApp * t = new  PIJTApp(narg, arg); Si pas thread
+    //  t->Run();      Si pas thread
+  }
+  catch (PThrowable const & e) {
+    cerr << " Catched PThrowable in main Msg= " << e.Msg() << endl;
+  }
+  catch (JTCException const & e) {  // <JThreadC++>
+    cerr << " Catched JTCException in main Msg= " << e.getMessage() << endl;
+  }
+  catch(...) {
+    cerr << " Catched ... exception in main " << endl;
+  }
+
+  PrtTim("End of jtcpitarr");
+}
Index: /tags/V_Dec2002/SophyaProg/Tests/jtctarr.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/jtctarr.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/jtctarr.cc	(revision 2309)
@@ -0,0 +1,137 @@
+#include "machdefs.h"
+#include "JTC/JTC.h"
+
+#include <math.h>
+#include <iostream.h>
+
+#include "tarrinit.h"
+#include "array.h"
+#include "timing.h"
+
+// Programme de test des threads JThreadsC++ 
+// avec les arrays de Sophya
+
+// A global monitor for print synchronisation 
+JTCMonitor prtmon;  // <JThreadC++> 
+
+// A thread class for doing matrix computation 
+class MtxComputer : public JTCThread   // <JThreadC++> 
+{
+public:
+  MtxComputer(int id, int sz, int nloop);
+  virtual void run();
+protected:
+  int id_;
+  int sz_;
+  int nloop_;
+};
+
+MtxComputer::MtxComputer(int id, int sz, int nloop)
+{
+  id_ = id;  sz_ = sz;  nloop_ = nloop;  
+}
+
+void MtxComputer::run()
+{
+  int n = sz_;
+  double seuil = 1.e-6;
+  Matrix id;
+  id = IdentityMatrix(1.,n);
+  double gmax = -1.e99;
+  double gmin = 1.e99;
+  int npb = 0;
+  // Loop creating a random matrix, inverting it
+  // and checking the result 
+  for(int k=0; k<nloop_; k++) {
+    try {
+      Matrix a(n,n);
+      a = Sequence(RandomSequence(RandomSequence::Gaussian, 0., 2.5));
+      Matrix inva = Inverse(a);
+      Matrix diff = id-a*inva;
+      double max = -1.e99;
+      double min = 1.e99;
+      double x;
+      int nerr = 0;
+      for(int i=0; i<n; i++) 
+	for(int j=0; j<n; j++) {
+	  x = diff(i,j);
+	  if (x < min)  min = diff(i,j); 
+	  if (x > max)  max = diff(i,j); 
+	  if (fabs(x) > seuil)  nerr++;
+	}
+      if (min < gmin) gmin = min;
+      if (max > gmax) gmax = max;
+      if (nerr > 0) npb++;
+      {  // Synchronized writing to cout stream  
+	JTCSynchronized sync(prtmon);  // <JThreadC++> 
+	cout << " ------- Thread[" << id_ << "] K= " 
+	     << k << "  NErr = " << nerr << endl;
+	cout << "  Min(Diff) = " << min << " Max(Diff) = " << max << endl;
+	if (k == nloop_-1) {
+	  double frac = (double)npb*100./(double)nloop_;
+	  cout << " ...... Thread[" << id_ << "] End NPb= " << npb 
+	       << " / NTot= " << nloop_ << " ( = " << frac << " %) " << endl;
+	cout << "  GMin(Diff) = " << gmin << " GMax(Diff) = " << gmax << endl;
+	cout << " ..................................................... " << endl;
+	}
+      } 
+    }
+    catch (PException const & e) {
+	cerr << " Catched PException in  Thread(" << (string)getName() 
+	     << ") Msg= " << e.Msg() << endl;
+    }
+    catch (JTCException const & e) {  // <JThreadC++>
+	cerr << " Catched JTCException in  Thread(" << (string)getName() 
+	     << ") Msg= " << e.getMessage() << endl;
+    }
+  }
+}
+
+
+// ------- The main program ---------
+int main(int narg, char* arg[])
+{
+
+#define MAXNTHR 10    
+  if (narg < 4) {
+    cout << " jtctarr - JThreadsC++/Sophya::TArray<T> Test \n " 
+	 << " ... Usage jtctarr NThreads NLoop MtxSize [-JTCss ... \n" 
+	 << " NThreads=1...4  NLoop=10...10^4  MtxSize=10...10^3 \n"
+	 << endl;
+    exit(0);
+  }
+
+  InitTim();   // Initializing the CPU timer
+
+  int nthr = atoi(arg[1]);
+  if (nthr > MAXNTHR) nthr = MAXNTHR;
+  int nloop = atoi(arg[2]);
+  int size = atoi(arg[3]);
+  cout << " ::::: jtctarr - JThreadsC++/Sophya::TArray<T> Test ::::: \n"
+       << " NThreads= " << nthr << " NLoop= " << nloop << " MtxSize= " 
+       << size << endl;   
+
+  try {
+    SophyaInit();  // Sophya Initialization
+    JTCInitialize iniJTC(narg, arg);  // <JThreadC++>  Initialize library
+
+    JTCThreadHandle t[MAXNTHR];  // <JThreadC++>  
+    int k;
+    for(k=0; k<nthr; k++)  t[k] = new MtxComputer(k, size, nloop);
+    cout << " Starting threads ... " << endl;
+    for(k=0; k<nthr; k++) t[k]->start();  // <JThreadC++> 
+    // Waiting for threads to end
+    for(k=0; k<nthr; k++) t[k]->join();   // <JThreadC++>
+  }
+  catch (PThrowable const & e) {
+    cerr << " Catched PThrowable in main Msg= " << e.Msg() << endl;
+  }
+  catch (JTCException const & e) {  // <JThreadC++>
+    cerr << " Catched JTCException in main Msg= " << e.getMessage() << endl;
+  }
+  catch(...) {
+    cerr << " Catched ... exception in main " << endl;
+  }
+
+  PrtTim("End of jtctarr");
+}
Index: /tags/V_Dec2002/SophyaProg/Tests/lpk.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/lpk.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/lpk.cc	(revision 2309)
@@ -0,0 +1,241 @@
+#include "machdefs.h"
+
+#include <math.h>
+#include <iostream.h>
+
+#include "srandgen.h"
+#include "tarrinit.h"
+#include "array.h"
+#include "timing.h"
+#include "intflapack.h"
+
+
+int lpk_rzt_arr(int n);
+int lpk_linsolve_mtx(int n);
+int lpk_svd_mtx(int l, int c, int wsf, bool covu=true);
+int lpk_leastsquare_mtx(int l, int c);
+
+static double TOLERANCE = 1.e-6;
+
+int main(int narg, char* arg[])
+{
+
+  SophyaInit();
+  InitTim();   // Initializing the CPU timer
+
+
+
+  if (narg < 2) {
+    cout << " lpk - LinAlg/LapackServer test \n" 
+	 << " Usage: lpk linsolve/svd/rzt [sizeL,C=5,5] [prtlev=0] \n" 
+	 << "             [nprtmax=100] [WorkSpaceSizeFactor=2] \n" 
+	 << "   linsolve:  lpk_linsolve_mtx() LapackServer::LinSolve with TMatrix<r_8> \n" 
+	 << "   svd:  lpk_svd_mtx() LapackServer::SVD(a,s,u,vt) with TMatrix<r_8> \n" 
+	 << "   svds:  lpk_svd_mtx() LapackServer::SVD(a,s); with TMatrix<r_8> \n"
+	 << "   lss:  lpk_leastsquare_mtx() LapackServer::LeastSquareSolve() r_8 \n"
+	 << "   rzt:  lpk_rzt_tarr() rztest_lapack with TArray<r_4> \n" << endl;
+    exit(0);
+  }
+  int l,c;
+  l = c = 5;
+  int wsf = 2;
+  string opt = arg[1];
+  if (narg > 2) sscanf(arg[2], "%d,%d", &l, &c); 
+  int nprt = 100;
+  int prtlev = 1;
+  if (narg > 3) prtlev = atoi(arg[3]);
+  if (narg > 4) nprt = atoi(arg[4]);
+  if (narg > 5) wsf = atoi(arg[5]);
+
+  int rc = 0;
+  BaseArray::SetMaxPrint(nprt, prtlev);
+  try {
+    if (opt == "linsolve") rc = lpk_linsolve_mtx(l);
+    else if (opt == "svd") rc = lpk_svd_mtx(l,c,wsf,true);
+    else if (opt == "svds") rc = lpk_svd_mtx(l,c,wsf,false);
+    else if (opt == "lss") rc = lpk_leastsquare_mtx(l,c);
+    else if (opt == "rzt") rc = lpk_rzt_arr(l);
+    else { cout << " Unknown option " << opt << " ! " << endl; rc = 66; }
+  }
+  catch (PThrowable exc) {
+    cerr << " catched Exception (lpk.cc) " << exc.Msg() << endl;
+    rc = 77;
+  }  
+  catch (...) {
+    cerr << " catched unknown (...) exception (lpk.cc) " << endl; 
+    rc = 78; 
+  } 
+  
+  PrtTim(" End of lpk LinAlg/Lapack test ");
+  cout << " ---------------  END of Programme -------- (Rc= " 
+       << rc << ") --- " << endl;
+  return(rc);
+}
+
+// -----------------------------------------------------------------------
+/* Nouvelle-Fonction */
+int lpk_linsolve_mtx(int n)
+{
+  int i,j;
+  BaseArray::SetDefaultMemoryMapping(BaseArray::FortranMemoryMapping);
+  cout << " lpk_linsolve_mtx() - Test of LapackServer::LinSolve()  " << endl;
+  Matrix a(n,n);
+  for(i=0; i<n; i++)
+    for(j=0; j<n; j++)  a(j,i) = GauRnd(0., 1.);
+  
+  Vector x(n), b;
+  //  Matrix  x(n,1), b;
+  cout << " ------------ Vector X = \n " << x << "\n" << endl; 
+  for(i=0; i<n; i++) x(i) = GauRnd(2., 1.5);
+  b = a*x;
+
+  cout << " ---- lpk_tmtx() LapackServer::LinSolve Test Using TMatrix<r_8> ----- " << endl; 
+  cout << " ------------ Matrix A = \n " << a << "\n" << endl; 
+  cout << " ------------ Matrix X = \n " << x << "\n" << endl; 
+  cout << " ------------ Matrix B = \n " << b << "\n" << endl; 
+
+  cout << "\n   Calling LapackLinSolve(a,b) .... " << endl;
+  PrtTim(" Calling LapackLinSolve(a,b) ");
+  LapackLinSolve(a,b);
+  PrtTim(" End LapackLinSolve(a,b) ");
+
+  cout << " ------------ Result B(=X ?) = \n " << b << "\n" << endl; 
+  Vector diff = b-x;
+  PrtTim(" End of Compute(diff)");
+  cout << " ------------ Vector diff B-X = \n " << diff << "\n" << endl; 
+  double min,max;
+  diff.MinMax(min, max);
+  cout << " Min/Max difference Vector (?=0) , Min= " << min 
+       << " Max= " << max << endl;
+  if ((fabs(min) > TOLERANCE) || (fabs(max) > TOLERANCE)) {
+    cout << " !!! Difference exceeding tolerance (=" << TOLERANCE << ") !!!" 
+	 << endl;
+    return(99);
+  } 
+  return(0);
+
+}
+
+// -----------------------------------------------------------------------
+/* Nouvelle-Fonction */
+int lpk_svd_mtx(int m, int n, int wsf, bool covu)
+{
+  BaseArray::SetDefaultMemoryMapping(BaseArray::FortranMemoryMapping);
+  cout << " lpk_svd_mtx() - Test of LapackServer::SVD " << endl;
+  
+  Matrix a(m , n), aa;
+  a = RandomSequence(RandomSequence::Gaussian, 0., 4.);
+  aa = a;
+  Vector s;
+  Matrix u, vt;
+  cout << " ---- lpk_svd_tmtx() LapackServer::SVD Test Using TMatrix<r_8> ---- " << endl; 
+  cout << " ------------ Matrix A = \n " << a << "\n" << endl; 
+
+  cout << "\n   Calling LapackSVD(a,s,u,vt) .... " << endl;
+  PrtTim(" Calling LapackSVD() ");
+  LapackServer<r_8> lpks;
+  lpks.SetWorkSpaceSizeFactor(wsf);
+  if (covu) lpks.SVD(aa, s, u, vt);
+  else lpks.SVD(aa, s);
+  PrtTim(" End LapackSVD() ");
+
+  cout << " ------------ Result S  = \n " << s << "\n" << endl; 
+  if (!covu) return(0);
+  cout << " ------------ Result U  = \n " << u << "\n" << endl; 
+  cout << " ------------ Result VT = \n " << vt << "\n" << endl; 
+  Matrix sm(m,n);
+  int minmn = (m<n) ? m : n ;
+  for(int k=0; k< minmn ; k++) sm(k,k) = s(k);
+  Matrix diff = u*(sm*vt) - a;
+  PrtTim(" End of Compute(diff)");
+  cout << " ------------ Matrix diff U*S*Vt - A = \n " << diff << "\n" << endl; 
+  double min,max;
+  diff.MinMax(min, max);
+  cout << " Min/Max difference Matrix (?=0) , Min= " << min 
+       << " Max= " << max << endl;
+  if ((fabs(min) > TOLERANCE) || (fabs(max) > TOLERANCE)) {
+    cout << " !!! Difference exceeding tolerance (=" << TOLERANCE << ") !!!" 
+	 << endl;
+    return(99);
+  } 
+  return(0);
+
+}
+
+// -----------------------------------------------------------------------
+/* Nouvelle-Fonction */
+int lpk_leastsquare_mtx(int m, int n)
+{
+  BaseArray::SetDefaultMemoryMapping(BaseArray::FortranMemoryMapping);
+  cout << " lpk_leastsquare_mtx() - Test of LapackLeastSquareSolve " << endl;
+  
+  Matrix a(m , n), aa;
+  a = RandomSequence(RandomSequence::Gaussian, 0., 4.);
+  aa = a;
+  Vector x(n),noise(m),b,bx;
+  x = RandomSequence(RandomSequence::Gaussian, 2., 1.);
+  double signoise = 0.1;
+  noise = RandomSequence(RandomSequence::Gaussian, 0., 0.1);
+  b = a*x;
+  bx = b+noise;
+ 
+  cout << " ---- lpk_leastsquare_tmtx() LapackLeastSquareSolve<r_8> ---- " << endl; 
+  cout << " ------------ Matrix A = \n " << a << "\n" << endl; 
+  cout << " ------------ Vector B = \n " << bx << "\n" << endl; 
+  cout << " ------------ Vector X = \n " << x << "\n" << endl; 
+
+  cout << "\n   Calling  LapackLeastSquareSolve(a,bx) .... " << endl;
+  PrtTim(" Calling LapackLeastSquareSolve() ");
+  LapackLeastSquareSolve(aa, bx);
+  PrtTim(" End LapackLeastSquareSolve() ");
+  bx.Share(bx(Range(0,0,n)));
+  cout << " ------------ Result X  = \n " << bx << "\n" << endl; 
+  cout << " ------------ X-X_Real  = \n " << bx-x << "\n" << endl; 
+  Vector diff = b-a*bx;
+  PrtTim(" End of Compute(diff)");
+  cout << " ------------ Matrix diff b-a*x = \n " << diff << "\n" << endl; 
+  double mean,sigma;
+  MeanSigma(diff, mean, sigma);
+  cout << " MeanSigma(diff) , Mean= " << mean << " Sigma=" << sigma
+       << " SigNoise= " << signoise << endl;
+  if ((fabs(mean) > signoise) || (fabs(sigma-signoise) > signoise)) {
+    cout << " !!! Difference exceeding tolerance (=" << TOLERANCE << ") !!!" 
+	 << endl;
+    return(99);
+  } 
+  return(0);
+
+}
+
+
+void rztest_lapack(TArray<r_4>& aa, TArray<r_4>& bb);
+
+int  lpk_rzt_arr(int n)
+{
+  int i,j;
+  TArray<r_4> a(n,n);
+  for(i=0; i<n; i++)
+    for(j=0; j<n; j++)  a(i,j,0) = GauRnd(0., 1.);
+  
+  TArray<r_4> x(n,1), b(n,1);
+  r_4 sum ;
+  for(i=0; i<n; i++) x(i,0,0) = GauRnd(2., 1.5);
+  for(i=0; i<n; i++) {
+    sum = 0.;
+    for(j=0; j<n; j++) sum +=  a(i,j,0)*x(j,0,0);
+    b(i,0,0) = sum;
+  }
+
+  //  cout << ":::::::: rztest_lapack - Size=" << n << "  ::::::::: " << endl;
+  cout << " ------- lpk_tarr() LapaackTest Using TArray<r_4> -------- " << endl; 
+  cout << " ------------ Array A = \n " << a << "\n" << endl; 
+  cout << " ------------ Array X = \n " << x << "\n" << endl; 
+  cout << " ------------ Array B = \n " << b << "\n" << endl; 
+
+  cout << "\n     Calling rztest_lapack ... " << endl;
+
+  rztest_lapack(a, b);
+
+  cout << " ------------ Result B(=X ?) = \n " << b << "\n" << endl; 
+  return(0);
+}
Index: /tags/V_Dec2002/SophyaProg/Tests/makepi
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/makepi	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/makepi	(revision 2309)
@@ -0,0 +1,59 @@
+MODULECXXREPNAME := Tests
+MODULEDECCXXFLAGS := -msg_quiet
+include $(DPCDEVREP)/Include/Makefile.h
+
+
+ifdef NOSHLIB
+
+LIBF =  $(LIB)libSysTools.a $(LIB)libNTools.a $(LIB)libBlitz.a $(LIB)libFitsIOServer.a $(LIB)libPI.a $(LIB)libPIext.a 
+LIBS = -L$(LIB) -lPIext -lPI -lSysTools -lNTools -lBlitz  -lm
+#LIBS =  -L$(LIB) -lSysTools -lm
+ifeq ($(CXX),cxx)
+# librairie des instances de templates cxx
+LIBS := $(LIBS) -lrt
+endif
+
+else
+
+LIBF =  $(SLB)libsophya.so 
+LIBS = -L$(SLB) -lPI -lextsophya -lsophya -lpthread -lXm -lXt -lX11 -lm 
+ifeq ($(MACHEROS),OSF1)
+LIBS := $(LIBS) -lfor
+endif
+ifeq ($(MACHEROS),Linux)
+LIBS := $(LIBS) -ldl -lf2c
+endif
+
+endif
+
+LDLIBS := $(LIBS) $(LDLIBS) 
+
+%:%.cc
+%:%.o
+%.o:%.cc
+%.o:%.c
+%:%.c
+
+.PRECIOUS: $(EXE)% $(OBJ)%.o
+
+%:$(EXE)%
+	echo $@ " done"
+
+$(EXE)%:$(OBJ)%.o
+	$(LINK.cc)  -o $@ $< $(LIBS)
+
+$(OBJ)%.o:%.cc
+	$(COMPILE.cc)   $(USERFLAGS) -o $@ $<
+
+$(EXE)%:$(OBJ)%.cc
+	$(LINK.cc) $(USERFLAGS)  -o $@ $< $(LIBS) 
+
+$(EXE)%:$(OBJ)%.c
+	$(LINK.c)  $(USERFLAGS) -o $@ $< $(LIBS) 
+
+$(OBJ)%.o:%.c
+	$(COMPILE.c) -c $(CFLAGS) $(USERFLAGS) -o $@ $< 
+
+dump :
+	echo $(LIBS)
+
Index: /tags/V_Dec2002/SophyaProg/Tests/obj_fits.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/obj_fits.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/obj_fits.cc	(revision 2309)
@@ -0,0 +1,89 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <iostream.h>
+
+#include "histinit.h"
+#include "dvlist.h"
+#include "ntuple.h"
+#include "xntuple.h"
+#include "fitsxntuple.h"
+#include "fitsntuple.h"
+#include "fitstarray.h"
+#include "array.h"
+
+int main(int narg, char *arg[])
+{
+  if (narg < 3) {
+    cout << "obj_fits/Erreur arg - Usage obj_fits r/r2/w/w2 fitsfilename " << endl;
+    cout << "  w : Create a FITS file with a matrix and an NTuple " << endl;
+    cout << "  r : Read a matrix and an NTuple from a Fits File " << endl;
+    cout << "  2 : Image on secondary header " << endl;  
+    exit(1);
+  }
+  try {
+    SophyaInit();
+    string flnm = arg[2];
+    bool imgonph = true;
+    if (*(arg[1]+1) == '2')  imgonph = false;
+    if (*arg[1] == 'r') {
+      cout << " obj_fits/Info: Opening input FitsFile " << endl;
+      FitsInFile fiis(flnm);
+      fiis.firstImageOnPrimaryHeader(imgonph);
+
+      cout << " Reading Matrix m from FITS " << endl;
+      Matrix m;
+      fiis >> m;
+      cout << m << endl;
+
+      cout << " Reading NTuple from FITS " << endl;
+      NTuple nt;
+      fiis >> nt ;
+      nt.Show();
+    }
+    else {
+      cout << " obj_fits/Info: Opening output FitsFile " << endl;
+      FitsOutFile fios(flnm);
+      fios.firstImageOnPrimaryHeader(imgonph);
+
+      cout << " Creating Matrix m " << endl;
+      Matrix m(50,70);
+      m = RegularSequence(35., 0.2);
+      m.Info()["SVERSION"] = SophyaVersion();
+      m.Info().SetComment("SVERSIO", "Sophya Version");
+      m.Info()["OBJ_FITS"] = "Test Matrix" ;
+      cout << m << endl;
+      
+      cout << " Writing Matrix m to FITS " << endl;
+      fios << m ;
+      
+      cout << " Creating NTuple " << endl;
+      char * names[3] = {"XPos", "YPos", "Val"};
+      int i,j, k;
+      float xnt[3];
+      
+      NTuple  nt1(3, names, 20);
+      
+      k = 0;
+      for(j=0; j<8; j++)
+	for(i=0; i<12; i++)
+	  { xnt[0] = i+0.5;  xnt[1] = j+0.5;  xnt[2] = k;
+	  nt1.Fill(xnt); k++; }
+      
+      nt1.Info().Comment() = "NTuple de Test - Cree par obj_fits.cc";
+      nt1.Info()["Version"] = SophyaVersion();
+      nt1.Show();
+      
+      cout << " Writing NTuple to FITS " << endl;
+      fios << nt1 ;
+    }
+  }
+  catch (PThrowable & exc) {
+    cerr << " Catched Exception " << (string)typeid(exc).name()
+         << " - Msg= " << exc.Msg() << endl;
+  }
+  catch (...) {
+    cerr << " some other exception was caught ! " << endl;
+  }
+
+}
Index: /tags/V_Dec2002/SophyaProg/Tests/ovharr.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/ovharr.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/ovharr.cc	(revision 2309)
@@ -0,0 +1,640 @@
+#include "machdefs.h"
+
+#include <math.h>
+#include <iostream.h>
+#include <fstream.h>
+
+#include "tarrinit.h"
+#include "array.h"
+#include "ctimer.h"
+#include "timing.h"
+
+
+// --------------------------------------------------------
+//  Programme de mesure d'overhead, lie a l'utilisation des
+//  classes, de NDataBlock et TArray en particulier  
+//    Attention, l'operateur * declare ds les classes 
+//  ci-dessous denote l'operation multiplication element 
+//  par element - Ceci n'est pas le cas pour les Tmatrix<T>
+// --------------------------------------------------------
+
+// --------
+
+// ---------------------------------------------------
+// Classe simple de matrice, utilisant les NDataBlock
+// ---------------------------------------------------
+
+template <class T>
+class SimpleMatrix : public AnyDataObj {
+public:
+		SimpleMatrix(sa_size_t nr, sa_size_t nc);
+		SimpleMatrix(const SimpleMatrix<T> & m);
+		SimpleMatrix(const SimpleMatrix<T> & m, bool share);
+  virtual       ~SimpleMatrix();
+
+  virtual SimpleMatrix<T>& Set(const SimpleMatrix<T> & a);
+  inline SimpleMatrix<T>& operator = (const SimpleMatrix<T> & a)
+  { return Set(a); }
+
+  inline T operator()(int r, int c) const 
+                { return data_(r*ncol_+c); }
+  inline T& operator()(int r, int c) 
+                { return data_(r*ncol_+c); }
+
+  inline sa_size_t NRows() const {return nrow_; }
+  inline sa_size_t NCols() const {return ncol_; }
+
+  SimpleMatrix<T>& AddElt(const SimpleMatrix<T> & b);
+  SimpleMatrix<T>& MulElt(const SimpleMatrix<T> & b);
+
+protected:
+  sa_size_t ncol_ , nrow_;
+  NDataBlock<T> data_;
+};
+
+template <class T>
+inline SimpleMatrix<T> operator + (const SimpleMatrix<T>& a, 
+				   const SimpleMatrix<T>& b)
+{
+  SimpleMatrix<T> ret(a, false); 
+  return(ret.AddElt(b));
+}
+
+template <class T>
+inline SimpleMatrix<T> operator * (const SimpleMatrix<T>& a, 
+				   const SimpleMatrix<T>& b)
+{
+  SimpleMatrix<T> ret(a, false); 
+  return(ret.MulElt(b));
+}
+
+template <class T>
+SimpleMatrix<T>::SimpleMatrix(sa_size_t nr, sa_size_t nc)
+  : nrow_(nr), ncol_(nc), data_(nr*nc) 
+{
+}
+
+template <class T>
+SimpleMatrix<T>::SimpleMatrix(const SimpleMatrix & m)
+  : nrow_(m.nrow_), ncol_(m.ncol_), data_(m.data_)
+{
+}
+
+template <class T>
+SimpleMatrix<T>::SimpleMatrix(const SimpleMatrix & m, bool share)
+  : nrow_(m.nrow_), ncol_(m.ncol_), data_(m.data_, share)
+{
+}
+
+template <class T>
+SimpleMatrix<T>::~SimpleMatrix()
+{
+}
+
+template <class T>
+SimpleMatrix<T>& SimpleMatrix<T>::Set(const SimpleMatrix & b)
+{
+  if ((nrow_ != b.nrow_) || (ncol_ != b.ncol_))
+    throw(SzMismatchError("SimpleMatrix::Set() Size(a) != Size(b)"));
+  data_ = b.data_;
+  return(*this);
+}
+
+template <class T>
+SimpleMatrix<T>& SimpleMatrix<T>::AddElt(const SimpleMatrix & b)
+{
+  if ((nrow_ != b.nrow_) || (ncol_ != b.ncol_))
+    throw(SzMismatchError("SimpleMatrix::AddElt() Size(a) != Size(b)"));
+  data_ += b.data_;
+  return(*this);
+}
+
+template <class T>
+SimpleMatrix<T>& SimpleMatrix<T>::MulElt(const SimpleMatrix & b)
+{
+  if ((nrow_ != b.nrow_) || (ncol_ != b.ncol_))
+    throw(SzMismatchError("SimpleMatrix::MulElt() Size(a) != Size(b)"));
+  data_ *= b.data_;
+  return(*this);
+}
+
+
+
+// -------------------------------------------------
+// Classe simple de matrice nxm , avec new double
+// -------------------------------------------------
+
+class VerySimpleMatrix {
+public:
+		VerySimpleMatrix(int nr, int nc, bool zero=true);
+		VerySimpleMatrix(const VerySimpleMatrix & m);
+  virtual       ~VerySimpleMatrix();
+
+  virtual VerySimpleMatrix& Set(const VerySimpleMatrix & a);
+  inline VerySimpleMatrix& operator = (const VerySimpleMatrix & a)
+  { return Set(a); }
+
+
+  inline double operator()(int r, int c) const 
+                { return a_[r*ncol_+c]; }
+  inline double& operator()(int r, int c) 
+                { return a_[r*ncol_+c]; }
+
+  inline int NRows() const {return nrow_; }
+  inline int NCols() const {return ncol_; }
+
+  VerySimpleMatrix& AddElt(const VerySimpleMatrix & b);
+  VerySimpleMatrix& MulElt(const VerySimpleMatrix & b);
+
+protected:
+  int ncol_ , nrow_;
+  double* a_;
+};
+
+inline
+VerySimpleMatrix operator + (const VerySimpleMatrix& a, const VerySimpleMatrix& b)
+{  
+  VerySimpleMatrix ret(a);
+  return(ret.AddElt(b));
+}
+
+inline
+VerySimpleMatrix operator * (const VerySimpleMatrix& a, const VerySimpleMatrix& b)
+{  
+  VerySimpleMatrix ret(a);
+  return(ret.MulElt(b));
+}
+
+
+VerySimpleMatrix::VerySimpleMatrix(int nr, int nc, bool zero)
+{
+  nrow_ = nr; ncol_ = nc;
+  int l = nrow_ * ncol_;
+  a_ = new double[l];
+  if (zero) 
+    for(int i=0; i<l; i++) a_[i] = 0.;
+}
+
+VerySimpleMatrix::VerySimpleMatrix(const VerySimpleMatrix & m)
+{
+  nrow_ = m.nrow_; ncol_ = m.ncol_;
+  a_ = new double[nrow_ * ncol_];
+  for(int i=0; i<nrow_ * ncol_; i++)
+    a_[i] = m.a_[i];
+}
+
+VerySimpleMatrix::~VerySimpleMatrix()
+{
+  delete[] a_;
+}
+
+
+VerySimpleMatrix& VerySimpleMatrix::Set(const VerySimpleMatrix & b)
+{
+  if ((nrow_ != b.nrow_) || (ncol_ != b.ncol_))
+    throw(SzMismatchError("VerySimpleMatrix::Set Size(a) != Size(b)"));
+  for(int i=0; i<nrow_ * ncol_; i++)
+    a_[i] = b.a_[i];
+  return(*this);
+}
+
+VerySimpleMatrix& VerySimpleMatrix::AddElt(const VerySimpleMatrix & b)
+{
+  if ((nrow_ != b.nrow_) || (ncol_ != b.ncol_))
+    throw(SzMismatchError("VerySimpleMatrix::AddElt() Size(a) != Size(b)"));
+  for(int i=0; i<nrow_ * ncol_; i++)
+    a_[i] += b.a_[i];
+  return(*this);
+}
+
+VerySimpleMatrix& VerySimpleMatrix::MulElt(const VerySimpleMatrix & b)
+{
+  if ((nrow_ != b.nrow_) || (ncol_ != b.ncol_))
+    throw(SzMismatchError("VerySimpleMatrix::MulElt() Size(a) != Size(b)"));
+  for(int i=0; i<nrow_ * ncol_; i++)
+    a_[i] += b.a_[i];
+  return(*this);
+}
+
+
+//--------------------------------------------------------
+// classe template de matrice NxM 
+//--------------------------------------------------------
+
+template <class T, int L, int C> 
+class SmallMatrix {
+public:
+                SmallMatrix() { } 
+        	SmallMatrix(const SmallMatrix<T,L,C> & m)
+                   { for(int i=0; i<L*C; i++)  data_[i] = m.data_[i]; }
+
+  virtual       ~SmallMatrix() { }
+
+  inline SmallMatrix<T,L,C>& Set(const SmallMatrix<T,L,C> & m)
+                   { for(int i=0; i<L*C; i++) data_[i] = m.data_[i]; return (*this); }
+  inline SmallMatrix<T,L,C>& operator = (const SmallMatrix<T,L,C>& a)
+                 { return Set(a); } 
+ 
+
+
+  inline T operator()(int r, int c) const 
+                { return data_[r*C+c]; }
+  inline T& operator()(int r, int c) 
+                { return data_[r*C+c]; }
+
+  inline int NRows() const {return L; }
+  inline int NCols() const {return C; }
+
+  inline SmallMatrix<T,L,C> & AddElt(const SmallMatrix<T,L,C> & m)
+                   { for(int i=0; i<L*C; i++) data_[i] += m.data_[i]; return (*this); }
+
+  inline SmallMatrix<T,L,C> & MulElt(const SmallMatrix<T,L,C> & m)
+                   { for(int i=0; i<L*C; i++) data_[i] *= m.data_[i]; return (*this); }
+
+protected:
+  T data_[L*C];
+};
+
+template <class T, int L, int C> 
+inline SmallMatrix<T,L,C> 
+       operator + (const SmallMatrix<T,L,C>& a, const SmallMatrix<T,L,C>& b)
+   {  SmallMatrix<T,L,C> ret(a);  return(ret.AddElt(b)); }
+
+template <class T, int L, int C> 
+inline SmallMatrix<T,L,C> 
+       operator * (const SmallMatrix<T,L,C>& a, const SmallMatrix<T,L,C>& b)
+   {  SmallMatrix<T,L,C> ret(a);  return(ret.MulElt(b)); }
+
+ 
+// -------------------------------------------------------
+// Classe simple de matrice 2x2 - sans allocation memoire
+// -------------------------------------------------------
+
+class VerySimpleMatrix2x2 {
+public:
+  inline        VerySimpleMatrix2x2() { } 
+  inline	VerySimpleMatrix2x2(const VerySimpleMatrix2x2 & m)
+                   { for(int i=0; i<4; i++)  a_[i] = m.a_[i]; }
+
+  inline        ~VerySimpleMatrix2x2() { }
+
+  inline VerySimpleMatrix2x2& Set(const VerySimpleMatrix2x2 & m)
+                   { for(int i=0; i<4; i++) a_[i] = m.a_[i]; return (*this); }
+  inline VerySimpleMatrix2x2& operator = (const VerySimpleMatrix2x2 & a)
+                   { return Set(a); }
+
+  inline double operator()(int r, int c) const 
+                { return a_[r*2+c]; }
+  inline double& operator()(int r, int c) 
+                { return a_[r*2+c]; }
+
+  inline int NRows() const {return 2; }
+  inline int NCols() const {return 2; }
+
+  inline VerySimpleMatrix2x2& AddElt(const VerySimpleMatrix2x2 & m)
+                   { for(int i=0; i<4; i++) a_[i] += m.a_[i]; return (*this); }
+  inline VerySimpleMatrix2x2& MulElt(const VerySimpleMatrix2x2 & m)
+                   { for(int i=0; i<4; i++) a_[i] *= m.a_[i]; return (*this); }
+
+protected:
+  double a_[4];
+};
+
+inline VerySimpleMatrix2x2 operator + (const VerySimpleMatrix2x2& a, const VerySimpleMatrix2x2& b)
+   {  VerySimpleMatrix2x2 ret(a);  return(ret.AddElt(b)); }
+
+inline VerySimpleMatrix2x2 operator * (const VerySimpleMatrix2x2& a, const VerySimpleMatrix2x2& b)
+   {  VerySimpleMatrix2x2 ret(a);  return(ret.MulElt(b)); }
+
+// ------------------------------------------------------------
+//   programme de test 
+//   Appel: ovharr NLoop [NRow NCol]
+//   NRow = 0 ou NCol = 0 --> test 2x2 only  
+// ------------------------------------------------------------ 
+
+void add_double_n(int n, double* x1, double* x2, double* x3);
+void mul_double_n(int n, double* x1, double* x2, double* x3);
+
+int main(int narg, char* arg[])
+{
+
+  SophyaInit();
+  InitTim();   // Initializing the CPU timer
+
+  if (narg < 2) {
+    cout << " Missing argument/ Usage: ovharr NLoop [NRow NCol] \n " 
+	 << " NRow==0 OR NCol==0   ---> Test 2x2 only \n " << endl;
+    exit(1);
+  }
+  int i,j,k;
+  char buff[128];
+  int N = atoi(arg[1]);
+  int nrow = 2; 
+  int ncol = 2;
+
+  if (narg > 2)  nrow = atoi(arg[2]);
+  if (narg > 3)  ncol = atoi(arg[3]);
+
+  bool fgall = true;
+  if ((nrow == 0) || (ncol == 0))    fgall = false;
+
+  cout << " ovharr/ Testing TArray overhead - NLoop = " << N 
+       << "  NRow=" << nrow << " NCol= " << ncol << endl;
+  try {
+
+    if (fgall) {
+      cout << "1) ------ Overhead using TMatrix<T> ------" << endl;
+      Timer tm("Overhead:TMatrix<T>");
+      for(k=0; k<N; k++) {
+	Matrix * m1 = new Matrix(nrow, ncol);
+	Matrix * m2 = new Matrix(nrow, ncol);
+	Matrix * m3 = new Matrix(nrow, ncol);
+	for(i=0; i<nrow; i++)
+	  for(j=0; j<ncol; j++) {
+	    (*m1)(i,j) = k*300+10.*i+j;	
+	    (*m2)(i,j) = k*550+20.*i+2.*j;	
+	  }
+	*m3 = *m1 + *m2;
+	// m4 = m1*m2 est une multiplication de matrice avec les TMatrix<T>
+	Matrix * m4 = new Matrix(*m1);
+	m4->MulElt(*m2);  
+
+	delete m1; 
+	delete m2; 
+	delete m3;
+	delete m4;
+      //  if (k%(N/10) == 0) {
+      //    sprintf(buff, "ovharr: Iteration k= %d ",k);
+      //    PrtTim(buff);
+      //  }
+      }
+    }
+
+    if (fgall) {
+      cout << "2) ------ Overhead using TMatrix<T> No new ------" << endl;
+      Timer tm("Overhead:TMatrix<T> No new");
+      for(k=0; k<N; k++) {
+	Matrix m1(nrow, ncol);
+	Matrix m2(nrow, ncol);
+	for(i=0; i<nrow; i++)
+	  for(j=0; j<ncol; j++) {
+	    m1(i,j) = k*300+10.*i+j;	
+	    m2(i,j) = k*550+20.*i+2.*j;	
+	  }
+	Matrix m3 = m1 + m2;
+	Matrix m4(m1);
+	m4.MulElt(m2); 
+      }
+    }
+
+    if (fgall) {
+      cout << "3) ------ Overhead using SimpleMatrix<r_8> ------" << endl;
+      Timer tm("Overhead:SimpleMatrix<r_8>");
+      for(k=0; k<N; k++) {
+	SimpleMatrix<r_8> * m1 = new SimpleMatrix<r_8>(nrow, ncol);
+	SimpleMatrix<r_8> * m2 = new SimpleMatrix<r_8>(nrow, ncol);
+	SimpleMatrix<r_8> * m3 = new SimpleMatrix<r_8>(nrow, ncol);
+	SimpleMatrix<r_8> * m4 = new SimpleMatrix<r_8>(nrow, ncol);
+	for(i=0; i<nrow; i++)
+	  for(j=0; j<ncol; j++) {
+	    (*m1)(i,j) = k*300+10.*i+j;	
+	    (*m2)(i,j) = k*550+20.*i+2.*j;	
+	  }
+	*m3 = *m1 + *m2;
+	*m4 = *m1 * *m2;
+	delete m1; 
+	delete m2; 
+	delete m3;
+	delete m4;
+      }
+    }
+
+    if (fgall) {
+      cout << "4) ---- Overhead using SimpleMatrix<r_8> NO new ----" << endl;
+      Timer tm("Overhead:SimpleMatrix<r_8> NO new");
+      for(k=0; k<N; k++) {
+	SimpleMatrix<r_8> m1(nrow, ncol);
+	SimpleMatrix<r_8> m2(nrow, ncol);
+	for(i=0; i<nrow; i++)
+	  for(j=0; j<ncol; j++) {
+	    m1(i,j) = k*300+10.*i+j;	
+	    m2(i,j) = k*550+20.*i+2.*j;	
+	  }
+	SimpleMatrix<r_8> m3 = m1 + m2;
+	SimpleMatrix<r_8> m4 = m1 * m2;
+      }
+    }
+
+    if (fgall) {
+      cout << "5) ---- Overhead using VerySimpleMatrix( , , zero=true) ----" << endl;
+      Timer tm("Overhead:VerySimpleMatrix( , , zero=true)");
+      for(k=0; k<N; k++) {
+	VerySimpleMatrix * m1 = new VerySimpleMatrix(nrow, ncol, true);
+	VerySimpleMatrix * m2 = new VerySimpleMatrix(nrow, ncol, true);
+	VerySimpleMatrix * m3 = new VerySimpleMatrix(nrow, ncol, true);
+	VerySimpleMatrix * m4 = new VerySimpleMatrix(nrow, ncol, true);
+	for(i=0; i<nrow; i++)
+	  for(j=0; j<ncol; j++) {
+	    (*m1)(i,j) = k*300+10.*i+j;	
+	    (*m2)(i,j) = k*550+20.*i+2.*j;	
+	  }
+	*m3 = *m1 + *m2;
+	*m4 = *m1 * *m2;
+	delete m1; 
+	delete m2; 
+	delete m3;
+	delete m4;
+      }
+    }
+
+    if (fgall) {
+      cout << "6) ---- Overhead using VerySimpleMatrix( , , zero=false) ----" << endl;
+      Timer tm("Overhead:VerySimpleMatrix( , , zero=true)");
+      for(k=0; k<N; k++) {
+	VerySimpleMatrix * m1 = new VerySimpleMatrix(nrow, ncol, false);
+	VerySimpleMatrix * m2 = new VerySimpleMatrix(nrow, ncol, false);
+	VerySimpleMatrix * m3 = new VerySimpleMatrix(nrow, ncol, false);
+	VerySimpleMatrix * m4 = new VerySimpleMatrix(nrow, ncol, false);
+	for(i=0; i<nrow; i++)
+	  for(j=0; j<ncol; j++) {
+	    (*m1)(i,j) = k*300+10.*i+j;	
+	    (*m2)(i,j) = k*550+20.*i+2.*j;	
+	  }
+	*m3 = *m1 + *m2;
+	*m4 = *m1 * *m2;
+	delete m1; 
+	delete m2; 
+	delete m3;
+	delete m4;
+      }
+    }
+
+    if (fgall) {
+      cout << "7) ---- Overhead using VerySimpleMatrix( , , zero=false) NO new ----" << endl;
+      Timer tm("Overhead:VerySimpleMatrix( , , zero=true) NO new");
+      for(k=0; k<N; k++) {
+	VerySimpleMatrix m1(nrow, ncol, false);
+	VerySimpleMatrix m2(nrow, ncol, false);
+	for(i=0; i<nrow; i++)
+	  for(j=0; j<ncol; j++) {
+	    m1(i,j) = k*300+10.*i+j;	
+	    m2(i,j) = k*550+20.*i+2.*j;	
+	  }
+	VerySimpleMatrix m3 = m1 + m2;
+	VerySimpleMatrix m4 = m1 * m2;
+      }
+    }
+
+    if (fgall) {
+      cout << "8) ---- Overhead using new double[nrow*ncol] ----" << endl;
+      Timer tm("Overhead:new double[nrow*ncol]");
+      for(k=0; k<N; k++) {
+	int l = nrow*ncol;
+	double* m1 = new double[l];
+	double* m2 = new double[l];
+	double* m3 = new double[l];
+	double* m4 = new double[l];
+	for(i=0; i<nrow; i++)
+	  for(j=0; j<ncol; j++) {
+	    m1[i*ncol+j] = k*300+10.*i+j;	
+	    m2[i*ncol+j] = k*550+20.*i+2.*j;	
+	  }
+	for(i=0; i<l; i++) m3[i] = m1[i] + m2[i];
+	for(i=0; i<l; i++) m3[i] = m4[i] * m2[i];
+	delete[] m1; 
+	delete[] m2; 
+	delete[] m3;
+	delete[] m4;
+      }
+    }
+
+
+    {
+      cout << "9) ---- Overhead using SmallMatrix<r_8,4,5> No new ----" << endl;
+      Timer tm("Overhead:SmallMatrix<r_8,4,5> No new ");
+      for(k=0; k<N; k++) {
+	SmallMatrix<r_8,4,5> m1,m2;
+	for(i=0; i<4; i++)
+	  for(j=0; j<5; j++) {
+	    m1(i,j) = k*300+10.*i+j;	
+	    m2(i,j) = k*550+20.*i+2.*j;	
+	  }
+	SmallMatrix<r_8,4,5> m3 = m1 + m2;
+	SmallMatrix<r_8,4,5> m4 = m1 * m2;
+      }
+    }
+
+    {
+      cout << "10) ---- Overhead using SmallMatrix<r_8,2,2> No new ----" << endl;
+      Timer tm("Overhead:SmallMatrix<r_8,2,2> No new");
+      for(k=0; k<N; k++) {
+	SmallMatrix<r_8,2,2> m1,m2;
+	for(i=0; i<2; i++)
+	  for(j=0; j<2; j++) {
+	    m1(i,j) = k*300+10.*i+j;	
+	    m2(i,j) = k*550+20.*i+2.*j;	
+	  }
+	SmallMatrix<r_8,2,2>m3 = m1 + m2;
+ 	SmallMatrix<r_8,2,2>m4 = m1 * m2;
+     }
+    }
+
+
+    {
+      cout << "11) ---- Overhead using VerySimpleMatrix2x2 ----" << endl;
+      Timer tm("Overhead:VerySimpleMatrix2x2");
+      for(k=0; k<N; k++) {
+	VerySimpleMatrix2x2 * m1 = new VerySimpleMatrix2x2();
+	VerySimpleMatrix2x2 * m2 = new VerySimpleMatrix2x2();
+	VerySimpleMatrix2x2 * m3 = new VerySimpleMatrix2x2();
+	VerySimpleMatrix2x2 * m4 = new VerySimpleMatrix2x2();
+	for(i=0; i<2; i++)
+	  for(j=0; j<2; j++) {
+	    (*m1)(i,j) = k*300+10.*i+j;	
+	    (*m2)(i,j) = k*550+20.*i+2.*j;	
+	  }
+	*m3 = *m1 + *m2;
+	*m4 = *m1 * *m2;
+	delete m1; 
+	delete m2; 
+	delete m3;
+	delete m4;
+      }
+    }
+
+    {
+      cout << "12) ---- Overhead using VerySimpleMatrix2x2 NO new ----" << endl;
+      Timer tm("Overhead:VerySimpleMatrix2x2 NO new");
+      for(k=0; k<N; k++) {
+	VerySimpleMatrix2x2 m1,m2;
+	for(i=0; i<2; i++)
+	  for(j=0; j<2; j++) {
+	    m1(i,j) = k*300+10.*i+j;	
+	    m2(i,j) = k*550+20.*i+2.*j;	
+	  }
+	VerySimpleMatrix2x2 m3 = m1+m2;
+	VerySimpleMatrix2x2 m4 = m1*m2;
+      }
+    }
+
+
+    {
+      cout << "13) ---- Overhead using double a[4] + function call ----" << endl;
+      Timer tm("Overhead:double a[4]");
+      for(k=0; k<N; k++) {
+	double m1[4], m2[4], m3[4], m4[4];
+	for(i=0; i<2; i++)
+	  for(j=0; j<2; j++) {
+	    m1[i*2+j] = k*300+10.*i+j;	
+	    m2[i*2+j] = k*550+20.*i+2.*j;	
+	  }
+	add_double_n(4, m1, m2, m3);
+	mul_double_n(4, m1, m2, m4);
+      }
+    }
+
+    {
+      cout << "14) ---- Overhead a3[4] = a1[4]+a2[4] ----" << endl;
+      Timer tm("Overhead:double a[4]");
+      for(k=0; k<N; k++) {
+	double m1[4], m2[4], m3[4], m4[4];
+	for(i=0; i<2; i++)
+	  for(j=0; j<2; j++) {
+	    m1[i*2+j] = k*300+10.*i+j;	
+	    m2[i*2+j] = k*550+20.*i+2.*j;	
+	  }
+	for(i=0; i<4; i++) m3[i] = m1[i] + m2[i];
+	for(i=0; i<4; i++) m4[i] = m1[i] * m2[i];
+      }
+    }
+
+
+  }
+  catch (PThrowable exc) {
+    cerr << " catched Exception " << exc.Msg() << endl;
+  }  
+  catch (...) {
+    cerr << " catched unknown (...) exception " << endl; 
+  }  
+
+  cout << "\n --------------------------------------------------------" << endl;
+  PrtTim("--- End of ovharr ---");
+  cout << " ---------------  END of ovharr programme -------------- " << endl;
+}
+
+/* Fonction pour ajouter deux tableaux */
+void add_double_n(int n, double* x1, double* x2, double* x3)
+{
+  if (n < 1) 
+    throw(SzMismatchError("add_double_n : n<1 !"));
+  for(int i=0; i<n; i++) x3[i] = x1[i] + x2[i];
+  return;
+}
+/* Fonction pour multiplier deux tableaux */
+void mul_double_n(int n, double* x1, double* x2, double* x3)
+{
+  if (n < 1) 
+    throw(SzMismatchError("mul_double_n : n<1 !"));
+  for(int i=0; i<n; i++) x3[i] = x1[i] * x2[i];
+  return;
+}
Index: /tags/V_Dec2002/SophyaProg/Tests/pizthr.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/pizthr.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/pizthr.cc	(revision 2309)
@@ -0,0 +1,409 @@
+#include "machdefs.h"
+#include "zthread.h"
+
+#include <math.h>
+#include <unistd.h>
+#include <iostream.h>
+#include <stdexcept>
+
+//  Include file pour PI 
+#include "pisysdep.h"
+
+#include PIAPP_H
+#include PIMENU_H 
+#include PISTDWDG_H 
+#include PIWIN_H
+#include PIPERIODIC_H
+#include "picons.h"
+
+//  Include file Sophya (TArray) 
+#include "tarrinit.h"
+#include "array.h"
+#include "timing.h"
+
+using namespace std;
+
+// ..........................................................
+// Programme interactive de test des threads ZThread
+// avec les arrays de Sophya et PI 
+//     R. Ansari  LAL-IN2P3/CNRS   02/2001
+// ..........................................................
+
+// ................... MtxComputer ...................
+// A thread class for doing matrix computation 
+class PIZTApp;
+class MtxComputer : public ZThread   // <JThreadC++> 
+{
+public:
+  MtxComputer(PIZTApp * app, PIScale * sc, int id, int sz, int nloop);
+  virtual ~MtxComputer();
+  virtual void run();
+protected:
+  int id_;
+  int sz_;
+  int nloop_;
+  PIZTApp * zapp_;
+  PIScale * sc_;
+};
+
+// ................... CPUTimer ...................
+// Periodic class for CPU and elapsed time counting 
+class CPUTimer : public PIPeriodic {
+public:
+  CPUTimer(PIZTApp * app);
+  virtual void DoPeriodic();
+protected:
+  PIZTApp * zapp; 
+  int dt;
+};
+
+// ................... PIZTApp ...................
+// La classe application   <JThreadC++> 
+// class PIZTApp : public PIApplication , public ZThread {
+class PIZTApp : public PIApplication  {   // Pas oblige d'en faire un Thread
+public:
+  PIZTApp(int narg, char* arg[]);
+  ~PIZTApp();
+  virtual void   Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
+  virtual void   UpdateCPUTime();
+  virtual void   run();    //  <ZTread> 
+  // virtual void Run();    Si pas thread
+  ZMutex &   getMutex();  // <ZThread>  for synchronization 
+protected:
+  PIMenu * m[3];
+  PIScale *sc[2];
+  PILabel *tlab[2];
+  PILabel *cputlab;
+  PIConsole* cons;
+  // CPU and elapsed time
+  CPUTimer tm;
+  clock_t cput0;
+  time_t t0;
+  // The computing threads 
+  ZThread * thr[2];    //  <JThreadC++> 
+  // for synchronization with other threads
+  ZMutex amon;   //  <JThreadC++> 
+  int syn_cntrl;
+};
+
+
+// .........................................................
+// .............   PIZTApp  implementation .................
+// .........................................................
+
+PIZTApp::PIZTApp(int narg, char* arg[])
+  : PIApplication(600, 400, narg, arg) , tm(this)  // 200 ms timer
+{
+if (narg < 3) throw ParmError("PIZTApp::PIZTApp() narg<3 !");
+
+m[0] = new PIMenu(Menubar(),"Fichier");
+m[0]->AppendItem("Start", 10101);
+m[0]->AppendItem("Exit", 10110);
+AppendMenu(m[0]);
+m[1] = new PIMenu(Menubar(),"Thread-1");
+m[1]->AppendItem("Stop", 10203);
+AppendMenu(m[1]);
+m[2] = new PIMenu(Menubar(),"Thread-2");
+m[2]->AppendItem("Stop", 10303);
+AppendMenu(m[2]);
+
+cputlab = new PILabel(MainWin(), "CPUTime", 590, 30, 5, 5);
+cputlab->SetBorderWidth(1);
+
+tlab[0] = new PILabel(MainWin(), "Thr-1", 50, 30, 10, 40);
+sc[0] = new PIScale(MainWin(), "Sc-Thr-1", 510, kSDirLtoR, 220, 40, 70, 40);
+sc[0]->SetValue(0);
+tlab[1] = new PILabel(MainWin(), "Thr-2", 50, 30, 300, 40);
+sc[1] = new PIScale(MainWin(), "Sc-Thr-2", 520, kSDirLtoR, 220, 40, 360, 40);
+sc[1]->SetValue(0);
+
+// Creating the console and redirecting output
+cons = new PIConsole(MainWin(), "PIConsole", 700, 500, 80, 600, 315, 0, 85, true );
+cons->SetBinding(PIBK_fixed, PIBK_fixed, PIBK_fixed, PIBK_fixed);
+RedirectOutStream(cons);
+//RedirectErrStream(cons);
+
+// Creating matrix Computing thread 
+int nloop = atoi(arg[1]);
+int size = atoi(arg[2]);
+thr[0] = new MtxComputer(this, sc[0], 0, size, nloop);
+thr[1] = new MtxComputer(this, sc[1], 1, size, nloop);
+
+cput0 = clock();  t0 = time(NULL);
+tm.Start();  // We start our cpu timer
+syn_cntrl = 0;  // Normal event loop 
+}
+
+PIZTApp::~PIZTApp()
+{
+cout << " Getting in PIZTApp::~PIZTApp() - " << endl;
+int k;
+ cout << " PIZTApp::~PIZTApp() - deleting m[0..2] ... " << endl;
+for(k=0; k<3; k++) delete m;
+ cout << " PIZTApp::~PIZTApp() - deleting tlab/sc[0..1] ... " << endl;
+for(k=0; k<2; k++) { delete tlab[k];  delete sc[k]; }
+ cout << " PIZTApp::~PIZTApp() - deleting cputlab ... " << endl;
+delete cputlab;
+ cout << " PIZTApp::~PIZTApp() - deleting thr[0..1] ... " << endl;
+delete thr[0];
+delete thr[1];
+ cout << " PIZTApp::~PIZTApp() - deleting cons ... " << endl;
+delete cons;
+}
+
+void PIZTApp::UpdateCPUTime()
+{
+clock_t cput;
+time_t elt;
+time_t tm;  struct tm * stm;
+elt = time(&tm);  stm = localtime(&tm);
+cput = clock();
+float tcal = ( (float)(cput) - (float)(cput0) ) / (float)(CLOCKS_PER_SEC);
+float  etm = elt - t0;
+float percen = (elt > t0) ?  (tcal*100.)/etm : 0.;
+char buff[192];
+sprintf(buff, "%02d:%02d:%02d CPUTime= %g sec Elapsed= %g sec (%g %%)", 
+	stm->tm_hour, stm->tm_min, stm->tm_sec,
+	tcal, etm, percen);
+
+string s = buff;
+cputlab->SetLabel(s);
+}
+
+ZMutex &  PIZTApp::getMutex()
+{
+syn_cntrl++;
+return amon;
+}
+
+void PIZTApp::run()
+  // void PIZTApp::Run()  Si pas thread
+{
+
+XEvent evt;
+int szx, szy, szf;
+XtAppContext * appctx = PIXtAppCtx(szx, szy, szf);
+// Pour appeler FinishCreate() des objets dans la fenetre principale 
+if (mStop) { // C'est la premiere fois
+  topcont->SetSize(topcont->XSize(), topcont->YSize());
+  MBCont()->FinishCreate();   
+  }
+else mStop = true;   // On rerentre apres un stop 
+
+cout << "DBG-PIZTApp::run/Run Starting event loop " << endl;
+try {
+
+  while (mStop) {
+    //    while (syn_cntrl > 0) {
+    //      amon.wait();  //  <JThreadC++>  
+    //      syn_cntrl = 0;
+    //    }
+    amon.lock(); //  <ZThread> 
+    while (XtAppPending(*appctx) != 0) {
+      XtAppNextEvent(*appctx, &evt);
+      XtDispatchEvent(&evt);
+    }
+    amon.unlock(); // <ZThread>
+    usleep(1000);
+  }
+}
+catch (PThrowable  & e) {  
+  cerr << "PIZTApp::Run() Catched Exception  Msg= " << e.Msg() << endl;
+}
+catch (...) {
+  cerr << "PIZTApp::run() Catched ... exception " << endl;
+}
+
+
+}
+
+void PIZTApp::Process(PIMessage msg, PIMsgHandler* sender, void* data)
+{
+  int num;
+try {
+  switch(UserMsg(msg)) {
+  case 10101 : // starting computing threads 
+    thr[0]->start();  //  <ZThread> 
+    thr[1]->start();  //  <ZThread> 
+    break;
+  case 10110 : // stoping computing threads 
+    RedirectOutStream(NULL);
+    RedirectErrStream(NULL);
+    cout << " PIZTApp::Process() Waiting for threads to terminate ... " << endl;
+    thr[0]->join();  //  <ZThread> 
+    thr[1]->join();  //  <ZThread> 
+    Stop();
+    break;
+  case 10203 :
+  case 10303 :
+    num = (UserMsg(msg)-10203)/100;
+    thr[num]->stop();  //  <ZThread> 
+    break;
+  }
+}
+catch (ZThreadExc  & e) {  // <ZThread>
+  cerr << "PIZTApp::Process() Catched ZThreadExc  Msg= " << e.Msg() << endl;
+}
+catch (...) {
+  cerr << "PIZTApp::Process() Catched ... exception " << endl;
+}
+
+}
+
+// .........................................................
+// .............   CPUTimer implementation .................
+// .........................................................
+
+CPUTimer::CPUTimer(PIZTApp * app)
+: PIPeriodic(1)
+{
+zapp = app;
+dt = -1;
+SetIntervalms(200);  // 200 ms interval timer
+}
+
+void
+CPUTimer::DoPeriodic()
+{
+dt++;
+if ((dt == 0) || (dt >= 5)) { zapp->UpdateCPUTime();  dt = 0; }
+}
+
+
+// .........................................................
+// .............  MtxComputer implementation ...............
+// .........................................................
+
+// A global monitor for print synchronisation 
+ZMutex prtmon;  // <ZThread> 
+
+MtxComputer::MtxComputer(PIZTApp * app, PIScale * sc, int id, int sz, int nloop)
+{
+  id_ = id;  sz_ = sz;  nloop_ = nloop;  zapp_ = app;  sc_ = sc; 
+}
+
+MtxComputer::~MtxComputer()
+{
+}
+
+void MtxComputer::run()
+{
+  int n = sz_;
+  double seuil = 1.e-6;
+  Matrix id;
+  id = IdentityMatrix(1.,n);
+  double gmax = -1.e99;
+  double gmin = 1.e99;
+  int npb = 0;
+  // Loop creating a random matrix, inverting it
+  // and checking the result 
+  for(int k=0; k<nloop_; k++) {
+    try {
+      Matrix a(n,n);
+      a = RandomSequence(RandomSequence::Gaussian, 0., 2.5);
+      Matrix inva = Inverse(a);
+      Matrix diff = id-a*inva;
+      double max = -1.e99;
+      double min = 1.e99;
+      double x;
+      int nerr = 0;
+      for(int i=0; i<n; i++) 
+	for(int j=0; j<n; j++) {
+	  x = diff(i,j);
+	  if (x < min)  min = diff(i,j); 
+	  if (x > max)  max = diff(i,j); 
+	  if (fabs(x) > seuil)  nerr++;
+	}
+      if (min < gmin) gmin = min;
+      if (max > gmax) gmax = max;
+      if (nerr > 0) npb++;
+      {  // Synchronized writing to cout stream  
+	ZSync sync(prtmon);  // <ZThread> 
+	cout << " ------- Thread[" << id_ << "] K= " 
+	     << k << "  NErr = " << nerr << endl;
+	cout << "  Min(Diff) = " << min << " Max(Diff) = " << max << endl;
+	if (k == nloop_-1) {
+	  double frac = (double)npb*100./(double)nloop_;
+	  cout << " ...... Thread[" << id_ << "] End NPb= " << npb 
+	       << " / NTot= " << nloop_ << " ( = " << frac << " %) " << endl;
+	  cout << "  GMin(Diff) = " << gmin << " GMax(Diff) = " << gmax << endl;
+	  cout << " ..................................................... " << endl;
+	}
+      }
+      {  // Synchronized updating of Scale Widget 
+	ZSync sync(zapp_->getMutex());  // <ZThread> 
+	// The event loop should be stopped until the end of the block
+	int percentage = 100*(k+1)/nloop_;
+	sc_->SetValue(percentage);
+      }
+ 
+    }
+    catch (ZThreadExc const & e) {  // <ZThread>
+      cerr << "MtxComputer Catched ZThreadExc in  Thread(" // << (string)getName() 
+	     << ") Msg= " << e.Msg() << endl;
+    }
+    catch (PException const & e) {
+      cerr << "MtxComputer Catched PException in  Thread(" // << (string)getName() 
+	     << ") Msg= " << e.Msg() << endl;
+    }
+  }
+}
+
+
+static void run_piapp(void * x)
+{
+    PIZTApp * t = (PIZTApp *)x;
+    t->run();
+    return;
+}
+
+// .........................................................
+// ................... The main program ....................
+// .........................................................
+
+int main(int narg, char* arg[])
+{
+
+  if (narg < 3) {
+    cout << " pizthr - ZThread/PI/Sophya::TArray<T> Test \n " 
+	 << " ... Usage pizthr NLoop MtxSize [-JTCss ... \n" 
+	 << "     NLoop=10...10^4  MtxSize=10...10^3 \n"
+	 << endl;
+    exit(0);
+  }
+
+  InitTim();   // Initializing the CPU timer
+
+  int nloop = atoi(arg[1]);
+  int size = atoi(arg[2]);
+  cout << " ::::: pizthr - ZThread/PI/Sophya::TArray<T> Test ::::: \n"
+       << " NLoop= " << nloop << " MtxSize= " << size << endl;   
+
+  try {
+    SophyaInit();  // Sophya Initialization
+    PIZTApp * t = new PIZTApp(narg, arg);  // <ZThread>  
+    //    t->Run();
+    ZThread * zt = new ZThread(50000);
+    zt->setAction(run_piapp, t);
+    zt->start();   // <ZThread>  -   starting event loop 
+    cout << " Waiting for PIZTApp thread to end ... " << endl;
+    zt->join();    // <ZThread>  Waiting for thread to end
+    //  PIZTApp * t = new  PIZTApp(narg, arg); Si pas thread
+    //  t->Run();      Si pas thread
+    cout << " PIZTApp thread ended - deleting PIZTApplication ... " << endl;
+    delete zt;
+    delete t;
+  }
+  catch (PThrowable const & e) {
+    cerr << " Catched PThrowable in main Msg= " << e.Msg() << endl;
+  }
+  catch(...) {
+    cerr << " Catched ... exception in main " << endl;
+  }
+
+  PrtTim("End of pizthr");
+}
+
+
+
+
Index: /tags/V_Dec2002/SophyaProg/Tests/sph2lm.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/sph2lm.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/sph2lm.cc	(revision 2309)
@@ -0,0 +1,560 @@
+#include "tarray.h"
+#include "cimage.h"
+#include "skymap.h"
+#include "mapoperation.h"
+#include "sambainit.h"
+#include "fftwserver.h"
+
+#include <typeinfo>
+
+
+//--------------------------------------------------------------------------
+//  Classe pour projeter localement (dans un tableau indexe i,j) 
+//  des coordonnees spheriques
+
+class MtxLM {
+public:
+  MtxLM(double latdeg, double longdeg, 
+	double deltheta_min, double delphi_min,
+	int_4 npixtheta, int_4 npixphi);
+  MtxLM(TMatrix<r_8> & mtx, bool uselat=true);
+
+  virtual ~MtxLM();
+
+  void Init(double latdeg, double longdeg,
+	double deltheta_min, double delphi_min,
+	int_4 npixtheta, int_4 npixphi);
+
+  // Conversion d'index de pixel (ip,jt) (ip: Phi/X/Column, jt: Theta/Y/Row )
+  // en Theta,Phi
+  void ip_jt2tp(int_4 ip, int_4 jt, double& theta, double& phi);
+  // Conversion de (Theta,Phi) en index de pixel (ip,jt) 
+  // (ip: Phi/X/Column, jt: Theta/Y/Row )
+  void tp2ipjt(double theta, double phi, int_4& ip, int_4& jt);
+
+  double _latdeg, _longdeg;
+  double _deltheta_min, _delphi_min;
+  int_4 _npixtheta, _npixphi;
+  double _theta0, _phi0;
+  double _thetaC, _phiC;
+  double _deltatheta, _deltaphi;
+  static double _deuxpi;
+};
+
+double MtxLM::_deuxpi = 2.*M_PI;
+
+MtxLM::MtxLM(double latdeg, double longdeg, 
+	     double deltheta_min, double delphi_min,
+	     int_4 npixtheta, int_4 npixphi)
+{
+  Init(latdeg, longdeg, deltheta_min, delphi_min, npixtheta,  npixphi );
+}
+
+//--------------------------------------------------------------------------
+
+MtxLM::MtxLM(TMatrix<r_8> & mtx, bool uselat)
+{
+  double latdeg = (uselat) ? (double)mtx.Info()["Latitude_C"] : 0.;
+  double longdeg = mtx.Info()["Longitude_C"];
+  double deltheta_min = mtx.Info()["LatPixSize"];
+  double delphi_min = mtx.Info()["LongPixSize"];
+  int_4 npixtheta =  mtx.NRows();
+  int_4 npixphi = mtx.NCols();
+  Init(latdeg, longdeg, deltheta_min, delphi_min, npixtheta, npixphi);
+}
+
+MtxLM::~MtxLM() 
+{
+}
+
+void MtxLM::Init(double latdeg, double longdeg,
+	    double deltheta_min, double delphi_min,
+	    int_4 npixtheta, int_4 npixphi)
+{
+  _latdeg = latdeg;
+  _longdeg = longdeg;
+  _deltheta_min = deltheta_min;
+  _delphi_min = delphi_min;
+  _npixtheta = npixtheta;
+  _npixphi = npixphi;  
+  _thetaC = (90.-latdeg)*M_PI/180.;
+  _phiC = longdeg*M_PI/180.;
+  _deltatheta = deltheta_min*M_PI/(180.*60.);
+  _deltaphi = delphi_min*M_PI/(180.*60.)/sin(_thetaC);
+  _theta0 = _thetaC-0.5*(double)_npixtheta*_deltatheta;
+  if ((_thetaC + 0.5*(double)_npixtheta*_deltatheta) > M_PI-1.e-6) 
+    throw RangeCheckError("MtxLM::Init() ThetaMax out of range (> M_PI-1.e-6)");
+  if ((_thetaC - 0.5*(double)_npixtheta*_deltatheta) < 1.e-6) 
+    throw RangeCheckError("MtxLM::Init() ThetaMin out of range (< 1.e-6)");
+  
+  double deltaphitot = delphi_min*M_PI/(180.*60.)/sin(_thetaC + 0.5*(double)_npixtheta*_deltatheta);
+  if (deltaphitot*_npixphi > _deuxpi) 
+    throw RangeCheckError("MtxLM::Init() Wrapping will occur for Phi at ThetaMax ! ");
+  deltaphitot = delphi_min*M_PI/(180.*60.)/sin(_thetaC - 0.5*(double)_npixtheta*_deltatheta);
+  if (deltaphitot*_npixphi > _deuxpi) 
+    throw RangeCheckError("MtxLM::Init() Wrapping will occur for Phi at ThetaMin ! ");
+  
+  _phi0 = _phiC-0.5*(double)_npixphi*_deltaphi;
+  return;
+}
+
+void MtxLM::ip_jt2tp(int_4 ip, int_4 jt, double& theta, double& phi)
+{
+  theta = jt*_deltatheta+_theta0;
+  if ( (theta<0.) || (theta > M_PI) )
+    throw RangeCheckError(" MtxLM::ip_jt2tp - Theta out of range !");
+  double delphi = _delphi_min*M_PI/(180.*60.)/sin(theta);
+  double phi0 = _phiC-0.5*(double)_npixphi*delphi;
+  //  phi = ip*_deltaphi+_phi0;
+  phi = ip*delphi+phi0;
+
+  while (phi < 0.)  phi += _deuxpi;
+  while (phi >=_deuxpi )  phi -= _deuxpi;
+
+  if ( (phi<0.) || (phi > _deuxpi) ) 
+    throw RangeCheckError(" MtxLM::ip_jt2tp - Phi out of range !");
+  return;
+}
+
+void MtxLM::tp2ipjt(double theta, double phi, int_4& ip, int_4& jt)
+{
+  if ( (theta<0.) || (theta > M_PI) )
+    throw RangeCheckError(" MtxLM::tp2ipjt - Theta out of range !");
+  if ( (phi<0.) || (phi > _deuxpi) ) 
+    throw RangeCheckError(" MtxLM::tp2ipjt - Phi out of range !");
+
+  jt = (theta-_theta0)/_deltatheta;
+  double delphi = _delphi_min*M_PI/(180.*60.)/sin(theta);
+  double phi0 = _phiC-0.5*(double)_npixphi*delphi;
+  if (phi0 < 0.) phi0 += 2*M_PI;
+  //  ip = (phi-_phi0)/_deltaphi;
+  ip = (phi-phi0)/delphi;
+  if ((ip < 0) || (ip >= _npixphi) )
+    throw RangeCheckError(" MtxLM::ip_jt2tp - ip out of range !");
+  if ((jt < 0) || (jt >= _npixtheta) )
+    throw RangeCheckError(" MtxLM::ip_jt2tp - jt out of range !");
+  return;
+}
+
+//--------------------------------------------------------------------------
+//     Fonction de filtrage de carte de type Matrix
+//-------------------------------------------------------------------------- 
+template <class T>
+void FilterMtxMap(TMatrix<T> & mtx, TMatrix<T> & mxout, int filw=1)
+{
+  if (filw < 1) return;
+  mxout = mtx;
+  sa_size_t r,c;
+  sa_size_t fw = 2*filw+1;
+  // Filtering 
+  // Filling holes in Matrix
+  for(r=filw; r<mtx.NRows()-filw; r++) 
+    for(c=filw; c<mtx.NCols()-filw; c++) 
+      mxout(r,c) = mtx(Range(r-filw, 0, fw), Range(c-filw, 0, fw)).Sum()/fw*fw;
+    
+  return;
+}
+
+//--------------------------------------------------------------------------
+// Projection depuis une carte spherique dans un local map
+//-------------------------------------------------------------------------- 
+
+template <class T>
+void Sph2LocalMap(SphericalMap<T> & in, LocalMap<T> & out)
+{
+  out.SetPixels(0);
+  int kout;
+  double teta,phi;
+
+  // Projecting to localMap
+  for(kout=0; kout<out.NbPixels(); kout++) {
+    out.PixThetaPhi(kout, teta, phi);
+    int pixel = in.PixIndexSph(teta,phi);
+    out(kout) = in.PixVal(pixel);
+  }
+
+  return;
+}
+
+//-------------------------------------------------------------------------- 
+// Projection depuis une matrice ds carte spherique 
+//-------------------------------------------------------------------------- 
+template <class T>
+void ProjectMatrix2Sph(TMatrix<T> & mtx, SphericalMap<T> & out, bool userot=false)
+{
+  if (userot) {
+    double phi =  (double)mtx.Info()["Longitude_C"]+90.;
+    double psi = -((double)mtx.Info()["Latitude_C"])*M_PI/180.;
+    while (phi >= 360.) phi -= 360.;
+    phi *= (M_PI/180.);
+    Vector3d omega(M_PI/2., phi);
+    ProjMatrix2RotateSph(mtx, out, omega, psi, false);
+  }
+  else ProjMatrix2Sph(mtx, out); 
+  return;
+}
+
+//-------------------------------------------------------------------------- 
+// Projection depuis une matrice ds carte spherique sans rotation explicite
+//-------------------------------------------------------------------------- 
+template <class T>
+void ProjMatrix2Sph(TMatrix<T> & mtx, SphericalMap<T> & out)
+{
+  int kout;
+  double teta,phi;
+
+  // Projecting to Matrix
+  sa_size_t i,j,r,c;
+  MtxLM mtxlm(mtx);
+  for(r=0; r<mtx.NRows(); r++) 
+    for(c=0; c<mtx.NCols(); c++) {
+      mtxlm.ip_jt2tp(c, r, teta, phi);
+      out(teta, phi) = mtx(r,c); 
+    }
+  return;
+}
+
+//-------------------------------------------------------------------------- 
+// Projection depuis une matrice ds carte spherique avec rotation explicite
+//-------------------------------------------------------------------------- 
+template <class T>
+void ProjMatrix2RotateSph(TMatrix<T> & mtx, SphericalMap<T> & out, 
+			  Vector3d& omega, double phirot, bool uselat=true)
+{
+  double teta,phi;
+
+  // Projecting to Matrix
+  sa_size_t r,c;
+  MtxLM mtxlm(mtx, uselat);
+  for(r=0; r<mtx.NRows(); r++) 
+    for(c=0; c<mtx.NCols(); c++) {
+      mtxlm.ip_jt2tp(c, r, teta, phi);
+      Vector3d vv1(teta, phi);
+      Vector3d vv2 = vv1.Rotate(omega, phirot);
+      out(vv2.Theta(), vv2.Phi()) = mtx(r,c); 
+    }
+  return;
+}
+//-------------------------------------------------------------------------- 
+// Projection depuis carte spherique ds une matrice 
+//-------------------------------------------------------------------------- 
+template <class T>
+void Sphere2Matrix(SphericalMap<T> & in, TMatrix<T> & mtx, bool userot=false)
+{
+  if (userot) {
+    double phi =  (double)mtx.Info()["Longitude_C"]+90.;
+    double psi = -((double)mtx.Info()["Latitude_C"])*M_PI/180.;
+    while (phi >= 360.) phi -= 360.;
+    phi *= (M_PI/180.);
+    Vector3d omega(M_PI/2., phi);
+    RotateSph2Matrix(in, mtx, omega, psi, false);
+  }
+  else Sph2Matrix(in, mtx); 
+  return;
+
+}
+
+//-------------------------------------------------------------------------- 
+// Projection depuis carte spherique ds une matrice sans rotation explicite
+//-------------------------------------------------------------------------- 
+template <class T>
+void Sph2Matrix(SphericalMap<T> & in, TMatrix<T> & mtx)
+{
+  int kout;
+  double teta,phi;
+
+  // Projecting to Matrix
+  sa_size_t i,j,r,c;
+  MtxLM mtxlm(mtx);
+  for(r=0; r<mtx.NRows(); r++) 
+    for(c=0; c<mtx.NCols(); c++) {
+      mtxlm.ip_jt2tp(c, r, teta, phi);
+      mtx(r, c) = in.PixVal(in.PixIndexSph(teta,phi));
+    }
+
+  // Filling holes in Matrix
+  int_4 nholes = 0;
+  for(r=2; r<mtx.NRows()-2; r++) 
+    for(c=2; c<mtx.NCols()-2; c++) {
+      if (fabs(mtx(r,c)) < 1.e-31) {
+	nholes++;
+	mtx(r,c) = mtx(Range(r-2, 0, 5), Range(c-2, 0, 5)).Sum()/24.;
+      }
+    }
+  cout << " Sph2Matrix()/Info: NbHoles= " << nholes << " filled " << endl;
+  return;
+}
+
+//-------------------------------------------------------------------------- 
+// Projection depuis carte spherique ds une matrice, avec une rotation 
+// d'angle phi autour du vecteur omega 
+//-------------------------------------------------------------------------- 
+template <class T>
+void RotateSph2Matrix(SphericalMap<T> & in, TMatrix<T> & mtx, 
+		      Vector3d& omega,double phirot, bool uselat=true)
+{
+  double teta,phi;
+
+  // Projecting to Matrix
+  sa_size_t r,c;
+  MtxLM mtxlm(mtx,uselat);
+  for(r=0; r<mtx.NRows(); r++) 
+    for(c=0; c<mtx.NCols(); c++) {
+      mtxlm.ip_jt2tp(c, r, teta, phi);
+      Vector3d vv1(teta, phi);
+      Vector3d vv2 = vv1.Rotate(omega, phirot);
+      mtx(r, c) = in.PixVal(in.PixIndexSph(vv2.Theta(), vv2.Phi()));
+    }
+
+  // Filling holes in Matrix
+  int_4 nholes = 0;
+  for(r=2; r<mtx.NRows()-2; r++) 
+    for(c=2; c<mtx.NCols()-2; c++) {
+      if (fabs(mtx(r,c)) < 1.e-31) {
+	nholes++;
+	mtx(r,c) = mtx(Range(r-2, 0, 5), Range(c-2, 0, 5)).Sum()/24.;
+      }
+    }
+  cout << " RotateSph2Matrix()/Info: NbHoles= " << nholes << " filled " << endl;
+  return;
+}
+
+
+//-------------------------------------------------------------------------- 
+//-------------------------------------------------------------------------- 
+
+template <class T>
+void CheckRotatedProjection(SphericalMap<T> & in);
+
+//-------------------------------------------------------------------------- 
+//               ************** Le main *****************
+//-------------------------------------------------------------------------- 
+
+int main(int narg, char* arg[])
+{
+  #define NLM 9
+  // Tableau des theta,phi des cartes partielles
+  // latitude_map : Latitude en degre
+  // longitude_map : longitude en degre
+  // nx_map : Nb de pixels selon la longitude (Phi)
+  // ny_map : Nb de pixels selon la latitude (Theta)
+  // resolx_map : Resolution cartes selon la longitude (phi)
+  // resoly_map : Resolution cartes selon la latitue (theta)
+  //  double latitude_map[NLM] = {0., -15., -15., 65., 65., 65., 65.};
+  double latitude_map[NLM] = {0., -15., -15., -28., 50., 60., 50., 75., 75.};
+  //  double thetadeg_map[NLM] = {90., 105., 105., 25., 25., 25., 25.};
+  //  double thetadeg_map[NLM] = {90., 105., 105., 115., 40., 30., 40., 15., 15.};
+  double thetadeg_map[NLM]; // = 90.-latitude_map[lnm]
+  double longitude_map[NLM] = {95., 100., 120., 130., 82., 90., 200., 140., 200.};
+  int nx_map[NLM] = {512, 512, 512, 512, 512, 512, 512, 512, 512};
+  int ny_map[NLM] = {512, 512, 512, 512, 512, 512, 512, 512, 512};
+  double resolx_map[NLM] = {2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5}; 
+  double resoly_map[NLM] = {2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5};
+
+
+  if ( (narg > 1) && (strcmp(arg[1], "-h") == 0) ) {
+    cout << " Usage: sph2lm InHealPixPPFName OutPPFName [-userot/-tstrot] [Filter1/2W = 0] "
+	 << endl;
+    exit(0);
+  }
+  if (narg < 3) {
+    cout << " sph2lm/Erreur argument - sph2lm -h for usage" << endl; 
+    exit(0);
+  }
+
+  bool userot = false;
+  bool tstrot = false;
+  if (narg > 3) {
+    if (strcmp(arg[3],"-userot") == 0) {
+      userot = true;
+      cout << " sph2lm: Explicit rotation will be used -> userot=true " << endl;
+    }
+    if (strcmp(arg[3],"-tstrot") == 0) {
+      userot = true;
+      cout << " sph2lm: Test rotated projection  -> tstrot=true / CheckRotatedProjection() " << endl;
+    }
+  }
+  int filw = 0;
+  if (narg > 4) filw = atoi(arg[4]);
+
+  cout << "\n >>>> Starting sph2lm: arg[1]= " << arg[1] 
+  << " arg[2]= " << arg[2] << " FW=" << filw << endl;
+
+  // We handle exception at the high level
+  try {
+  // This macro initialize the library
+  // static objects handle this - However, not all loader call
+  // the constructor for static objects
+  SophyaInit();
+
+  cout << " --- Reading input SphericalMap from file " << arg[1] << endl;
+  PInPersist inppf(arg[1]);
+  PPersist * pps = inppf.ReadObject();
+  AnyDataObj * obj = pps->DataObj();
+  cout << " Object type read from input PPF file : " 
+       << typeid(*obj).name() << endl;
+  SphereHEALPix<r_8> * ps8 = dynamic_cast< SphereHEALPix<r_8>* > (obj);
+  SphereHEALPix<r_8> sphin;
+  if (ps8 != NULL)  sphin.Share(*ps8);
+  else {
+    SphereHEALPix<r_4> * ps4 = dynamic_cast< SphereHEALPix<r_4>* > (obj);
+    if (ps4 != NULL) {
+      cout << " -- Converting SphereHEALPix<r_4> to SphereHEALPix<r_8> " << endl;
+      sphin.Resize(ps4->SizeIndex());
+      for(int kp=0; kp<sphin.NbPixels(); kp++) sphin(kp) = (*ps4)(kp);
+    }
+    else {
+      cout << " sph2lm/Error : Unsupported input object ! " << endl;
+      throw  TypeMismatchExc("sph2lm/Error wrong input object type ");
+    }
+  }
+
+  //   inppf.GetObject(sphin);
+  cout << " Sphere read: SizeIndex()= " << sphin.SizeIndex() 
+       << " NbPixels()= " << sphin.NbPixels() << endl;
+
+  if (tstrot) {
+    CheckRotatedProjection(sphin);
+    cout << " sph2lm: CheckRotatedProjection() done --> exit() " << endl;
+    return(0);
+  }
+  cout << " --- Opening output PPF file " << arg[1] << endl;
+  POutPersist outppf(arg[2]);
+
+  FFTWServer FFTServ;
+  SphereHEALPix<r_8> sphck(128);
+  SphereHEALPix<r_8> sphckmtx(128);
+
+  int nlm;
+  for(nlm=0; nlm<NLM; nlm++) {
+    thetadeg_map[nlm] = 90.-latitude_map[nlm];
+    cout << "\n ------ LocalMap No " << nlm+1 << " Latitude=" << latitude_map[nlm] 
+	 << " Longitude= " << longitude_map[nlm] << endl;
+
+    LocalMap<r_8> lm(nx_map[nlm], ny_map[nlm],
+		     nx_map[nlm]*resolx_map[nlm]/60.,
+		     ny_map[nlm]*resoly_map[nlm]/60.,
+		     thetadeg_map[nlm], longitude_map[nlm],
+		     nx_map[nlm]/2, ny_map[nlm]/2);
+    TMatrix<r_8> mtx(nx_map[nlm], ny_map[nlm]);
+
+    //    lm.SetOrigin(thetadeg_map[nlm], longitude_map[nlm]);
+    //    lm.SetSize(nx_map[nlm]*resolx_map[nlm]/60.,
+    //       ny_map[nlm]*resoly_map[nlm]/60.);
+  
+    lm.SetPixels((nlm+1)*100.);
+    mtx.Info()["Latitude_C"] = latitude_map[nlm];
+    mtx.Info()["Longitude_C"] = longitude_map[nlm];
+    mtx.Info()["LatPixSize"] = resoly_map[nlm];
+    mtx.Info()["LongPixSize"] = resolx_map[nlm];
+    mtx = (nlm+1)*100.;
+    
+    cout << " Doing lm.Project(sphck) ... " << endl;
+    lm.ProjectionToSphere(sphck);
+    cout << " Doing mtx.Project(sphck) ... " << endl;
+    ProjectMatrix2Sph(mtx, sphckmtx, userot);
+
+    cout << " Doing Sph2LocalMap(sphin, lm) ... " << endl;
+    Sph2LocalMap(sphin, lm);
+    cout << " Doing Sphere2Matrix(sphin, lm) ... " << endl;
+    Sphere2Matrix(sphin, mtx, userot);
+    MuTyV num = nlm+1;
+    string name = "lm" + (string)num;
+    cout << " Writing local map and mtx  to OutPPF " << endl;
+    outppf.PutObject(lm, name);
+    name = "mtx" + (string)num;
+    outppf.PutObject(mtx, name);
+
+    cout << " Calling FFTServ.FFTForward(mtx, fftmtx) " << endl;
+    TMatrix< complex<r_8> > fftmtx;
+    FFTServ.FFTForward(mtx, fftmtx); 
+
+    name = "fftmtx" + (string)num;
+    cout << " Writing fftmtx  to OutPPF " << endl;
+    outppf.PutObject(fftmtx, name);
+
+    if (filw < 1) continue;
+    TMatrix<r_8> fmtx;
+    cout << " Filtering mtx  FilterW= " << filw << endl;
+    FilterMtxMap(mtx, fmtx, filw);
+    cout << " Calling FFTServ.FFTForward(fmtx, fftfmtx) " << endl;
+    TMatrix< complex<r_8> > fftfmtx;
+    FFTServ.FFTForward(fmtx, fftfmtx); 
+
+    cout << " Writing fmtx and fftfmtx  to OutPPF " << endl;
+    name = "fmtx" + (string)num;
+    outppf.PutObject(fmtx, name);
+    name = "fftfmtx" + (string)num;
+    outppf.PutObject(fftfmtx, name);    
+  }
+
+  //  cout << " Doing Sph2Sph(sphin, lm) ... " << endl;
+  //  Sph2Sph(sphin, lm);
+  cout << "\n --- Writing sphck  and sphckmtxsphericalmap  to OutPPF " << endl;
+  outppf.PutObject(sphck, "sphck");
+  outppf.PutObject(sphckmtx, "sphckmtx");
+
+  }
+  catch (PThrowable & exc) {
+    cerr << " Catched Exception " << (string)typeid(exc).name() 
+	 << " - Msg= " << exc.Msg() << endl;
+  }
+  catch (...) {
+    cerr << " some other exception was caught ! " << endl;
+  }
+
+  cout << " >>>> End of sph2lm  <<<< " << endl; 
+}
+
+//-------------------------------------------------------------------------- 
+//    Fonction pour la verification des projection avec rotation 
+//-------------------------------------------------------------------------- 
+
+template <class T>
+void CheckRotatedProjection(SphericalMap<T> & in)
+{
+
+  cout << " >>> CheckRotatedProjection() : Testing rotated projection with matrices " << endl;
+  SphereHEALPix<r_8> sphckrot(128);
+  double latdeg = 0.;
+  double longdeg = 90.;
+  int nr = 512;
+  int nc = 512;
+  double resol = 2.5; 
+ 
+  TMatrix<r_8> mtx(nr, nc);
+  TMatrix<r_8> mtxA, mtxB, mtxC; 
+  
+  mtx.Info()["Latitude_C"] = latdeg;
+  mtx.Info()["Longitude_C"] = longdeg;
+  mtx.Info()["LatPixSize"] = resol;
+  mtx.Info()["LongPixSize"] = resol;
+  
+  mtx = 100.;
+  ProjMatrix2Sph(mtx, sphckrot);
+  Sph2Matrix(in, mtx);
+  mtxA = mtx;
+  Vector3d omega(M_PI/2., M_PI);
+  mtx = 200.;
+  ProjMatrix2RotateSph(mtx, sphckrot, omega, -M_PI/2.);
+  RotateSph2Matrix(in, mtx, omega, -M_PI/2.);
+  mtxB = mtx;
+  mtx = 300.;
+  ProjMatrix2RotateSph(mtx, sphckrot, omega, -M_PI/4.);
+  RotateSph2Matrix(in, mtx, omega, -M_PI/4.);
+  mtxC = mtx;
+
+  string ppfname = "rotproj.ppf";
+  cout << " -- Writing mtxA,B,C & sphckrot to OutPPF " << ppfname << endl;
+  POutPersist outppf(ppfname);
+  
+  outppf.PutObject(mtxA, "mtxA");
+  outppf.PutObject(mtxB, "mtxB");
+  outppf.PutObject(mtxC, "mtxC");
+
+  outppf.PutObject(sphckrot, "sphckrot");
+  
+  cout << " >>> End of CheckRotatedProjection() " << endl;
+  
+  return;
+}
Index: /tags/V_Dec2002/SophyaProg/Tests/sphg0.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/sphg0.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/sphg0.cc	(revision 2309)
@@ -0,0 +1,23 @@
+#include <iostream.h>
+#include "sambainit.h"
+#include "tod.h"
+#include "spherehealpix.h"
+
+
+int main() 
+{
+  double teta,phi;
+  SophyaInit();
+
+  int  m=32;
+  SphereHEALPix<double> sph(m);
+  for (int j=0;j<sph.NbPixels();j++) 
+    {
+      sph.PixThetaPhi(j,teta,phi);
+      sph(j)= 0.2* cos(3.*teta)*sin(8*phi);
+    }
+  // Projection  dans une image
+
+  cout <<  " ===== Fin de sphg0 ======== " << endl;
+  return 0;
+}
Index: /tags/V_Dec2002/SophyaProg/Tests/t_scan.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/t_scan.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/t_scan.cc	(revision 2309)
@@ -0,0 +1,70 @@
+// Utilisation des flots d'entree-sortie C++
+#include <iostream.h>
+
+#include <math.h>
+#include "nbmath.h"
+// Utilisation de la classe Scan
+#include "sambainit.h"
+#include "scan.h"
+#include "ppersist.h"
+int main()  
+{
+  // ----- ATTENTION -------
+  // Initialisation de Sophya
+  // A faire au debut de main()
+  SophyaInit();
+
+  int nbpix;
+  float teta,phi;
+  float Ouv,d_tet,Omega[3],fech,T,T0,phi0;
+
+  // provisoire : recupere (teta,phi) position du satellite (en degres)
+  teta= 0.;
+  phi = 0.;
+  
+  // Ouverture
+  Ouv= 90.*(float)Pi/180.;
+  // Direction de l'axe de rotation du satellite
+  Omega[0]= teta*(float)Pi/180.;
+  Omega[1]= phi*(float)Pi/180.;
+  // Vitesse de rotation
+  Omega[2]= (float)Pi;
+  // Frequence
+  fech= 30.;
+  // Temps max
+  T= 2.;
+  // Temps initial
+  T0= 0.;
+  // Offset
+  phi0= 0.;
+  int npas=15;
+  d_tet= (float)Pi*0.5/npas;
+  Scan equ(Ouv,Omega,fech,T,T0,phi0);
+  nbpix= equ.NbPoints();
+  cout << " nb pixels " << nbpix << endl;
+  for( int j=0; j<nbpix; j++ ) {
+    equ(j)=  100.*(j+1)/npas;
+  }
+  DVList dvl;
+  
+  equ.Info()["Temp"]=33.;
+  equ.Info()["Texte"]="bla bla bla";
+  cout << " scan initial " << endl;
+  for( int j=0; j<10; j++ ) {
+    cout << " pix no " << j << " val= " << equ(j) << endl;;
+  }
+  string sfile("scan.out");
+  Scan equ2;
+    {
+    FIO_Scan fsc(equ); 
+    fsc.Write(sfile);
+    FIO_Scan gsc(sfile);
+    equ2=(Scan)gsc;
+      } 
+  cout << " scan relu " << endl;
+  for( int j=0; j<10; j++ ) 
+    {
+          cout << " pix no " << j << " val= " << equ2(j) << endl;
+    }
+  cout << " fin test persistance scan" << endl;
+}
Index: /tags/V_Dec2002/SophyaProg/Tests/tblitz.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/tblitz.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/tblitz.cc	(revision 2309)
@@ -0,0 +1,73 @@
+#include <stdio.h>
+#include <iostream.h>
+#include "nbrandom.h"
+#include "timing.h"
+#include "cimage.h"
+#include "ntoolsinit.h"
+// Test des NDataBlock
+#include "ndatablock.h"
+
+#include "blitz/array.h"
+using namespace blitz ;
+
+main(int narg, char *arg[])
+{
+SophyaInit();
+InitTim();
+
+char strg[128];
+int N1,N2, k, kk, i, j;
+N1 = 1;
+N2 = 10;
+if (narg > 1)  N1 = atoi(arg[1]);
+if (narg > 2)  N2 = atoi(arg[2]);
+
+cout << N1 << " Tests avec " << N2 << " multiplications" << endl; 
+
+int sx = 300;
+int sy = 200;
+
+ImageR4  img(sx, sy), i2(sx, sy), ir(sx, sy);
+for(kk=0; kk<N1; kk++) {
+  cout << kk << " - Remplissage image (" << sx << "x" << sy << ") , " << N2 << " mult. " << endl;
+  for(i=0; i<sx; i++)
+    for(j=0; j<sy; j++) img(i,j) = frand01()*10.*j+20.*i;
+  for(i=0; i<sx; i++)
+    for(j=0; j<sy; j++) i2(i,j) =  frand01()*10.*j+20.*i;
+
+  for(k=0; k<N2; k++) ir = img * i2;
+  sprintf(strg, "Img T[%d] ", kk);
+  PrtTim(strg);
+}
+
+
+ cout << "\n ====  Test avec Blitz++ " << endl;
+
+Array<float,2> a1(sy, sx), a2(sy, sx), a3(sy, sx);
+firstIndex ii;
+secondIndex jj;
+
+for(kk=0; kk<N1; kk++) {
+  cout << kk << " BlitzArray (" << sx << "x" << sy << ") , " << N2 << " mult. " << endl;
+  a1 = frand01()*10.*jj+20.*ii;
+  a2 = frand01()*10.*jj+20.*ii;
+  for(k=0; k<N2; k++) a3 = a1*a2;
+  sprintf(strg, "Blitz-Array T[%d] ", kk);
+  PrtTim(strg);
+}
+
+ cout << "\n ====  Test avec NDataBlock<float> " << endl;
+NDataBlock<r_4> b1(sx*sy), b2(sx*sy), b3(sx*sy);
+for(kk=0; kk<N1; kk++) {
+  cout << kk << " NDataBlock<float> (" << sx*sy <<  ") , " << N2 << " mult. " << endl;
+  for(k=0; k<sx*sy; k++) {
+    b1(k) = frand01()*10.*k;
+    b2(k) = frand01()*10.*k;
+    }
+  for(k=0; k<N2; k++) b3 = b1*b2;
+  sprintf(strg, "NDataBlock<float> T[%d] ", kk);
+  PrtTim(strg);
+}
+
+exit(0);
+}
Index: /tags/V_Dec2002/SophyaProg/Tests/tcxxcmpldynl.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/tcxxcmpldynl.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/tcxxcmpldynl.cc	(revision 2309)
@@ -0,0 +1,57 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <iostream.h>
+
+#include "histinit.h"
+#include "array.h"
+#include "cxxcmplnk.h"
+#include "pdlmgr.h"
+#include "timing.h"
+
+int main(int narg, char *arg[])
+{
+  if (narg < 3) {
+    cout << " tcxxcmpldynl : test of  CxxCompilerLinker and PDynLinkMgr classes \n " 
+	 << " Usage tcxxcmpldynl nomCC nomFunc \n" 
+	 << "       For test, tcxxcmpldynl exacmplnk.cc exacmplnk \n" << endl;
+    exit(0);
+  }
+  try {
+    SophyaInit();
+    InitTim();
+
+    string flnm = arg[1];
+    string oname, soname;
+    int rc;
+
+    CxxCompilerLinker cxx(true, false, false);
+    cxx.SetVerbose(true);
+    rc = cxx.Compile(flnm, oname);
+    cout << " RC from cxx.Compile() = " << rc << " oname= " << oname << endl;
+    rc = cxx.BuildSO(oname, soname);
+    cout << " RC from cxx.BuildSO() = " << rc << " soname= " << soname << endl;
+    PrtTim(" End of Compile-Link ");
+
+    string funcname = arg[2];
+    PDynLinkMgr dyl(soname, false);
+    DlFunction f = dyl.GetFunction(funcname);  
+    if (f != NULL) {
+      cout << " DlFunction f linked OK - calling f() ... " << endl;
+      f();
+    } 
+    else {
+      cout << " ERROR linking DlFunction f !!! " << endl;
+    }
+  } 
+ 
+  catch (PThrowable & exc) {
+    cerr << " Catched Exception " << (string)typeid(exc).name()
+         << " - Msg= " << exc.Msg() << endl;
+  }
+  catch (...) {
+    cerr << " some other exception was caught ! " << endl;
+  }
+
+  PrtTim(" End of tcxxcmpldynl ");
+}
Index: /tags/V_Dec2002/SophyaProg/Tests/tdcr.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/tdcr.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/tdcr.cc	(revision 2309)
@@ -0,0 +1,52 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "math.h"
+#include <iostream.h>
+#include <string>
+
+// Pour le test 
+#include "histinit.h"
+#include "histos.h"
+#include "histos2.h"
+#include "psighand.h"
+
+
+#include "fmath.h"
+#include "nbrandom.h"
+
+void tdcr(AnyDataObj * obj)
+{
+Histo & h = *(dynamic_cast<Histo *>(obj));
+h.Print();
+}
+
+int main(int narg, char* arg[])
+{
+
+  SophyaInit();
+  SophyaConfigureSignalhandling(true,true,true);
+  try { 
+  Histo *h;
+  float x;
+
+
+  h = new Histo(0., 200., 100);  // Creation histo (AVEC new )
+  for(int i=0; i<100; i++)  // Remplissage d'histo
+    { x = (2*i+1.);  h->Add(x, x*(200.-x)); }
+  cout << " Appel tdcr(histo) " << endl;
+  tdcr(h);
+  cout << " Appel tdcr(histo2D) " << endl;
+  Histo2D * h2 = new Histo2D(0., 1., 10, 0., 1., 10);
+  tdcr(h2);
+  //  cout << " Appel tdcr(NULL) " << endl;
+  //  tdcr(NULL);
+  cout << " End --- exit .... " << endl;
+}
+  catch (PThrowable & exc) {
+    cerr << " catched Exception " << exc.Msg() << endl;
+  }  
+  catch (...) {
+    cerr << " catched unknown (...) exception " << endl; 
+  }  
+}
+
Index: /tags/V_Dec2002/SophyaProg/Tests/testfitsio.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/testfitsio.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/testfitsio.cc	(revision 2309)
@@ -0,0 +1,143 @@
+//++
+// Verbatim	
+//
+
+#include <iostream.h>
+#include "fitsioserver.h" 
+#include "tvector.h"
+//#include "spheregorski.h"
+#include "spherethetaphi.h"
+#include "localmap.h"
+#include "skymapinit.h"
+
+int main() 
+{
+
+  SophyaInit();
+
+   FitsIoServer fserv;
+  int nsmax=32;
+   // test pour les vecteurs 
+   /* 
+  double tab[12]={1,2,3,4,5,6,7,8,9,10,11,12};
+  TVector<double> V(12,tab);
+  delete [] tab;
+  cout << " impression du vecteur V" << endl;
+  cout << V << endl;
+  fserv.save(V, "vecteur.fits");
+  TVector<double> W(5);
+  fserv.load(W,"vecteur.fits");
+  cout << " impression du vecteur W" << endl;
+  cout << W << endl;
+  */
+   // test pour les matrices
+   /*
+   double tab[12]={1,2,3,4,5,6,7,8,9,10,11,12};
+   //TMatrix<double> m(3,4,tab);
+   TVector<double> m(12,tab);
+   cout << " impression de la matrice m" << endl;
+   cout << m << endl;
+   fserv.save(m, "matrice.fits");
+   TMatrix<double> mm(2,3);
+   //TVector<double> mm(12);
+   fserv.load(mm,  "matrice.fits"); 
+   cout << " impression de la matrice mm" << endl;
+   cout << mm << endl;
+   */
+   // test pour spheres
+   /*
+  // nsmax est parameter chez Gorski (anafast)
+  int bid=0;
+  
+  //int npixtot=12*32*32;
+  //float map[12*32*32];
+   // test pour les spheres
+  // Définition de la sphère 
+   int  m=nsmax;
+  double teta,phi;
+  SphereGorski<float> sph1(nsmax);
+  //SphereThetaPhi sph1(nsmax);
+  for (int j=0;j<sph1.NbPixels();j++) 
+    {
+      sph1.PixThetaPhi(j,teta,phi);
+      int bid= sph1.PixIndexSphNest(teta,phi);
+      int bid2= sph1. NestToRing(bid);
+      sph1(bid2)= 200* cos(3.*teta)*sin(8*phi);
+    }
+   // test projection sur une image fits
+   cout << " je  projette  la sphere 1 " <<endl;
+   char fileimg[]="img1.fits";
+   fserv.sinus_picture_projection(sph1,fileimg);
+
+   */
+
+
+   /*
+   // test ecriture sur une image
+   char fileout[]="out.fits";
+   cout << " ecriture dans " << fileout << endl;
+   fserv.save(sph1,fileout);   
+   cout << "relecture du fichier " << fileout << " qu'on verse dans une autre sphere" << endl;
+   m=8;
+   //SphereThetaPhi sph2(m);   
+   SphereGorski<float> sph2(m);   
+   fserv.load(sph2,fileout); 
+  
+  for (int j=0;j<10;j++) 
+    {
+      sph2.PixThetaPhi(j,teta,phi);
+      int bid= sph2.PixIndexSphNest(teta,phi);
+      int bid2= sph2.NestToRing(bid);
+      cout << " ring= " << j << " nest= " << bid << " ring= " << bid2 << endl;
+    }
+
+   // reprojection sur image
+   cout << " je  projette  la sphere 2 " <<endl;
+   char fileimg2[]="img2.fits";
+   fserv.sinus_picture_projection(sph2,fileimg2);
+
+   */
+   // test pour localmap
+  int  m=nsmax;
+  //SphereGorski<double> sph1(nsmax);
+  SphereThetaPhi<double> sph1(nsmax);
+  for (int j=0;j<sph1.NbPixels();j++) 
+    {
+      double teta,phi;
+      sph1.PixThetaPhi(j,teta,phi);
+      //int bid= sph1.PixIndexSphNest(teta,phi);
+      //int bid2= sph1. NestToRing(bid);
+      sph1(j)= 200* cos(3.*teta)*sin(8*phi);
+    }
+  LocalMap<double> lcl(600,300);
+  lcl.SetOrigin(90.,180.);
+  lcl.SetSize(60.,60.);
+  for (int k=0; k< lcl.NbPixels(); k++)
+    {
+      double theta, phi;
+      lcl.PixThetaPhi(k, theta, phi);
+      lcl(k)=sph1(sph1.PixIndexSph( theta, phi));
+    }
+  cout << " dessin sur img5" << endl;
+  fserv.picture(lcl,"img5.fits");
+  cout << " sauvegarde sur out5" << endl;
+  fserv.save(lcl,"out5.fits");
+  /*		
+  SphereGorski<double> sph3(nsmax);
+  lcl.Project(sph3);
+  cout << " je  projette  la sphere 3 " <<endl;
+  char fileimg3[]="img3.fits";
+  fserv.sinus_picture_projection(sph3,fileimg3);
+  char fileout3[]="out3.fits";
+  fserv.save(lcl,fileout3);
+  LocalMap<double> lcl2(3,4);
+  fserv.load(lcl2,fileout3);
+  SphereGorski<double> sph4(nsmax);
+  lcl2.Project(sph4);
+  cout << " je  projette  la sphere 4 " <<endl;
+  char fileimg4[]="img4.fits";
+  fserv.sinus_picture_projection(sph4,fileimg4);
+  */
+   cout <<  " ===== Fin de testfits ======== " << endl;
+   exit( 0 );
+}
Index: /tags/V_Dec2002/SophyaProg/Tests/tfft.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/tfft.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/tfft.cc	(revision 2309)
@@ -0,0 +1,225 @@
+#include "machdefs.h"
+
+#include <math.h>
+#include <iostream.h>
+
+#include "nbrandom.h"
+#include "matharr.h"
+#include "fftpserver.h"
+#include "fftmserver.h"
+#include "fftwserver.h"
+#include "ntoolsinit.h"
+
+#include "timing.h"
+
+
+static bool inp_typ_random = false ;  // true -> random input
+
+template <class T>
+inline T module(complex<T> c) 
+{
+  return (sqrt(c.real()*c.real()+c.imag()*c.imag()));
+}
+
+// Max Matrix print elts
+static int nprt = 2;
+static int nprtfc = 8;
+
+template <class T>
+void TestFFTPack(T seuil, int num)
+{
+  int i;
+  T fact = 1./num;
+
+  TVector< complex<T> > inc(num), bkc(num), difc(num);
+  TVector< T > in(num), ino(num), bk(num),dif(num);
+  TVector< complex<T> > outc(num);
+
+  cout << " DBG/1 outc " << outc.NElts()  << endl; 
+  outc.ReSize(32);
+  cout << " DBG/2 outc " << outc.NElts()  << endl; 
+  outc.ReSize(10);
+  cout << " DBG/3 outc " << outc.NElts()  << endl; 
+  outc.ReSize(48);
+  cout << " DBG/4 outc " << outc.NElts()  << endl; 
+
+  if (inp_typ_random) 
+    for (i=0; i<num ; i++){
+      ino[i] = in[i] = GauRnd(0., 1.);
+      inc[i] = complex<T> (in[i], 0.);
+    }
+  else for (i=0; i<num ; i++){
+    ino[i] = in[i] = 0.5 + cos(2*M_PI*(double)i/(double)num) 
+                         + 2*sin(4*M_PI*(double)i/(double)num);
+    inc[i] = complex<T> (in[i], 0.);
+  }
+  
+
+  cout << "Input / L = " << num << in; 
+  cout << endl;
+
+  cout << " >>>> Testing FFTPackServer "  << endl;
+  FFTPackServer fftp;
+  cout << " Testing FFTPackServer "  << endl;
+  fftp.fftf(in.NElts(), in.Data());
+  //  in /= (num/2.);
+  cout << " fftp.fftf(in.NElts(), in.Data()) FORWARD: " << in << endl; 
+  cout << endl;
+  fftp.fftb(in.NElts(), in.Data());
+  cout << " fftp.fftb(in.NElts(), in.Data()) BACKWARD: " << in <<endl; 
+  cout << endl;
+  dif = ino-in;
+  cout << " dif , NElts= " << dif.NElts() << dif << endl;
+
+  int ndiff = 0;
+  T maxdif=0., vdif;
+  for(i=0; i<num; i++) {
+    vdif = fabs(dif(i));
+    if (vdif > seuil)  ndiff++;
+    if (vdif > maxdif) maxdif = vdif;
+  }
+  cout << " Difference, Seuil= " << seuil << " NDiff= " << ndiff 
+       << " MaxDiff= " << maxdif << endl;
+
+}
+
+template <class T>
+void TestFFTS(T seuil, FFTServerInterface & ffts, int num)
+{
+
+  cout <<" ===>  TestFFTS " << ffts.getInfo() << " ArrSz= " << num << endl;  
+  int i;
+
+  T fact = 1.;
+
+  TVector< complex<T> > inc(num), bkc(num), difc(num);
+  TVector< T > in(num), ino(num), bk(num),dif(num);
+  TVector< complex<T> > outc(num);
+
+  for (i=0; i<num ; i++){
+    ino[i] = in[i] = 0.5 + cos(2*M_PI*(double)i/(double)num) 
+                         + 2*sin(4*M_PI*(double)i/(double)num);
+    inc[i] = complex<T> (in[i], 0.);
+  }
+  
+
+  cout << " Testing FFTServer " << ffts.getInfo() << endl;
+
+  cout << "Input / L = " << num << in << endl; 
+  cout << endl;
+
+  int ndiff = 0;
+
+  cout << "\n ----  Testing FFT(T, complex<T>) ---- " << endl;
+  ffts.FFTForward(in, outc);
+  cout << " FourierCoefs , NElts= " << outc.NElts() << outc << endl;
+
+  ffts.FFTBackward(outc, bk);
+  cout << " Backward , NElts= " << bk.NElts() << bk << endl;
+ 
+  dif = bk*fact - in;
+  cout << " Difference , NElts= " << dif.NElts() << dif << endl;
+
+  ndiff = 0;
+  T maxdif=0., vdif;
+  for(i=0; i<num; i++) {
+    vdif = fabs(dif(i));
+    if (vdif > seuil)  ndiff++;
+    if (vdif > maxdif) maxdif = vdif;
+  }
+  cout << " Difference, Seuil= " << seuil << " NDiff= " << ndiff 
+       << " MaxDiff= " << maxdif << endl;
+ 
+  cout << "\n ----  Testing FFT(complex<T>, complex<T>) ---- " << endl;
+  ffts.FFTForward(inc, outc);
+  cout << " FourierCoef , NElts= " << outc.NElts() << outc << endl;
+
+  ffts.FFTBackward(outc, bkc);
+  cout << " Backward , NElts= " << bkc.NElts() << bkc << endl;
+ 
+  difc = bkc*complex<T>(fact,0.) - inc;
+  cout << " Difference , NElts= " << difc.NElts() << difc << endl;
+
+  ndiff = 0;
+  maxdif=0., vdif;
+  for(i=0; i<num; i++) {
+    vdif = fabs(module(difc(i)));
+    if (vdif > seuil)  ndiff++;
+    if (vdif > maxdif) maxdif = vdif;
+  }
+  cout << " Difference, Seuil= " << seuil << " NDiff= " << ndiff 
+       << " MaxDiff= " << maxdif << endl;
+}
+
+
+
+
+
+int main(int narg, char* arg[])
+{
+
+  SophyaInit();
+  InitTim();   // Initializing the CPU timer
+
+  if (narg < 4) {
+    cout << "tfft/ args error - \n  Usage tfft size px/Px/Mx/Wx f/d [NPrt=50 PrtLev=0] \n" 
+	 << " p=FFTPackTest  P=FFTPack, M=FFTMayer, W= FFTWServer" 
+         << " x=0 -> Random input - f=float, d=double " << endl;
+    exit(0);
+  }
+
+  FFTPackServer fftp;
+  FFTMayerServer fftm;
+
+  FFTWServer fftw;
+
+  inp_typ_random = false;
+  if (arg[2][1] == '0')  inp_typ_random = true;
+
+  int sz = atoi(arg[1]);
+  int nprt = 50;
+  int prtlev = 0;
+  if (narg > 4) nprt = atoi(arg[4]);
+  if (narg > 5) prtlev = atoi(arg[5]);
+  BaseArray::SetMaxPrint(nprt, prtlev);
+
+  if (sz < 2) sz = 2;
+  FFTServerInterface * ffts;
+  if (*arg[2] == 'M')  ffts = fftm.Clone();
+  else if (*arg[2] == 'W')  ffts = fftw.Clone();
+  else ffts = fftp.Clone();
+
+  float fs = 1.e-4;
+  double ds = 1.e-6;
+
+  try {
+    if (*arg[3] == 'd') {
+      cout << "\n ========================================== \n"
+	   << "    ------ Testing FFTServer for double ----- \n"
+	   << " ============================================ " << endl;
+      if (*arg[2] == 'p') TestFFTPack(ds, sz);
+      else TestFFTS(ds, *ffts, sz);
+    }
+    else {
+      cout << "\n ========================================= \n"
+	   << "    ------ Testing FFTServer for float ----- \n"
+	   << " =========================================== " << endl;
+      if (*arg[2] == 'p') TestFFTPack(fs, sz);
+      else TestFFTS(fs, *ffts, sz);
+    }
+  }
+  catch(PThrowable exc ) {
+    cerr << "TestFFT-main() , Catched exception: \n" << exc.Msg() << endl;
+  }
+  catch(std::exception ex) {
+    cerr << "TestFFT-main() , Catched exception ! " << (string)(ex.what()) << endl;
+  }
+
+  /*
+  catch(...) {
+    cerr << "TestFFT-main() , Catched ... exception ! " << endl;
+  }
+  */
+  PrtTim("End of tfft ");
+  delete ffts;
+}
Index: /tags/V_Dec2002/SophyaProg/Tests/thash.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/thash.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/thash.cc	(revision 2309)
@@ -0,0 +1,21 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <iostream.h>
+
+#include "ppersist.h"
+int main(int narg, char *arg[])
+{
+  char * sid[3] = { "Hello","Reza","ERIC" } ;
+  uint_8 code[3];
+  int k;
+  printf(" ------- Testing SOPHYA Hash coding --------- \n");
+  printf(" Size of uint_4 = %d \n ", sizeof(uint_4)); 
+  printf(" Size of uint_8 = %d \n ", sizeof(uint_8)); 
+  printf(" Size of unsigned long = %d \n ", sizeof(unsigned long)); 
+  for(k=0; k<3; k++) {
+    code[k] = PPersistRegistrar<double>::Hash(sid[k]);
+    printf(" Resultat de Hash sur %s = %lx  (%ld) \n", sid[k], code[k], code[k]);
+    cout << " Result--- " << code[k] << endl;
+  }
+}
Index: /tags/V_Dec2002/SophyaProg/Tests/timg.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/timg.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/timg.cc	(revision 2309)
@@ -0,0 +1,140 @@
+// Utilisation des flots d'entree-sortie C++
+#include <iostream.h>
+// Utilisation de la classe Image<T>
+#include "ntoolsinit.h"
+#include "array.h"
+#include "cimage.h"
+// Utilisation des generateurs aleatoires
+#include "nbrandom.h"
+
+// Test des NDataBlock
+#include "ndatablock.h"
+#include "fiondblock.h"
+#include <complex>
+
+
+// -------- Le programme principal ---------
+
+main(int narg, char *arg[])
+{
+int i,j;
+double mean,sig;
+
+try {
+// ----- ATTENTION -------
+// Initialisation de Sophya
+// A faire au debut de main()
+SophyaInit();
+
+cout << " ........ Debut de timg.cc ....... " << endl;
+// declaration et creation d'une image de type flottant 300x200
+ImageR4  img(300, 200);
+ImageR4  imgo(300, 200);
+// Remplissage de l'image Tirage aleatoire plat entre 1000-2000
+for(i=0; i<300; i++)
+  for(j=0; j<200; j++) img(i,j) = imgo(i,j) =  frand01()*1000.+1000.;
+// Verification de la dynamique de l'image
+MeanSigma(img, mean, sig);
+cout << " img: Mean= " << mean << " Sigma= " << sig << endl;
+cout << img ; 
+
+// On sauve l'image ds img.ppf (fichier  format PPersist)
+{
+POutPersist po("img.ppf");
+po << img;
+}
+
+// On rajoute du bruit a l'image (Gaussienne de sigma=3)
+for(i=0; i<300; i++)
+  for(j=0; j<200; j++) img(i,j) += NorRand()*3. ;
+
+// Verification de la dynamique de l'image
+MeanSigma(img, mean, sig);
+cout << "ApresNoise img: Mean= " << mean << " Sigma= " << sig << endl;
+
+// On verifie la date de creation du fichier .ppf
+  {
+  string ppfname = "img.ppf";
+  PInPersist pin(ppfname, false);
+  cout << "Fichier PPF: " << ppfname << " Version= " << pin.Version() 
+       << " Created: " << pin.CreationDate() << endl;
+  }
+
+// On cree une nouvelle image 
+ImageR4  img2;
+// On lit le contenu du fichier imgin.ppf
+{
+PInPersist pi("img.ppf");
+pi >> img2;
+}
+
+// On calcule la difference entre les images img et img2
+//    Avant ajout de bruit
+cout << "\n imgo(sansbruit) - img2 (fromfile) == 0 ? " << endl;
+imgo -= img2;
+// Verification de la dynamique de l'image soustraite
+r_4 min,max;
+imgo.MinMax(min, max);
+cout << " Min(imgo) = " << min << " Max(imgo) = " << max << endl;
+
+//    Apres  ajout de bruit
+cout << " img(avecbruit) - img2 (fromfile) == Noise, sigma=3 ? " << endl;
+img -= img2;
+// Verification de la dynamique de l'image soustraite
+imgo.MinMax(min, max);
+cout << " Min(img) = " << min << " Max(img) = " << max << endl;
+MeanSigma(img, mean, sig);
+cout << "Apres img -= img2 img: Mean= " << mean << " Sigma= " << sig << endl;
+
+// ---- Test des NDataBlock 
+cout << "\n ----------> Test des NDataBlock <r_8>" << endl;
+NDataBlock<r_8> db(20);
+for(i=0; i<20; i++) db(i) = i*5.;
+cout << " DataBlock<r_8> i*5 : (db)" << endl;
+cout << db << endl;
+NDataBlock<r_8> db2(db,false);
+cout << " DataBlock<r_8> (db2=db) - db" << endl;
+cout << db2-db << endl;
+
+FIO_NDataBlock<r_8> fdb(db);
+fdb.Write("db_r8.ppf");
+cout << " DataBlock<r_8> db -> File db_r8.ppf" << endl;
+FIO_NDataBlock<r_8> fdb2("db_r8.ppf");
+cout << " DataBlock<r_8> Frome file(db_r8.ppf) - db" << endl;
+cout << (NDataBlock<r_8>)fdb2-db << endl;
+
+cout << "\n\n ----------> Test des NDataBlock <complex<double>>" << endl;
+NDataBlock< complex<double> > zb(20);
+for(i=0; i<20; i++) {complex<double> z(i*10., 0.1*i); zb(i) = z; }
+cout << " DataBlock<complex<double>>  (zb) = " << endl;
+cout << zb << endl;
+FIO_NDataBlock< complex<double> > fzb(zb);
+fzb.Write("zb_z8.ppf");
+FIO_NDataBlock< complex<double> > fzb2("zb_z8.ppf");
+cout << " DataBlock<complex<double>> Frome file(zb_z8.ppf) - db" << endl;
+cout << (NDataBlock< complex<double> >)(fzb2) ;
+
+cout << "\n -------> Test de typeinfo : " << endl;
+string st;
+ImageR4 ir;
+ImageU2* irp;
+
+st = typeid(NDataBlock<r_8>).name();
+cout << "typeid(NDataBlock<r_8>).name() = " << st << endl;
+st = typeid(ir).name();
+cout << "typeid(ir).name() - " << st << endl;
+st = typeid(irp).name();
+cout << "typeid(irp).name() - " << st << endl;
+}
+
+catch (PThrowable & exc) {
+  cerr << "timg/Error Catched Exception " << (string)typeid(exc).name() 
+       << " - Msg= " << exc.Msg() << endl;
+}
+catch (...) {
+  cerr << "timg/Error some other exception was caught ! " << endl;
+}
+
+cout << "\n ========= Fin de timg.cc ======== " << endl;
+exit(0);
+}
Index: /tags/V_Dec2002/SophyaProg/Tests/tnt.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/tnt.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/tnt.cc	(revision 2309)
@@ -0,0 +1,274 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <iostream.h>
+
+#include "histinit.h"
+#include "dvlist.h"
+#include "ntuple.h"
+#include "xntuple.h"
+
+void test_dvl();
+void test_ntuple();
+void test_xntuple() ; 
+void test_Xntuple() ; 
+
+int main(int narg, char *arg[])
+{
+  SophyaInit();
+  if (narg < 2) {
+    cout << " tnt/Erreur arg - Usage: tnt d/n/x/X \n" 
+	 << " d:DVList n:NTuple x/X:XNTuple test \n" << endl;
+    exit(0);
+  }
+
+  try {
+    if (*arg[1] == 'd')  test_dvl();
+    else if (*arg[1] == 'n')  test_ntuple();
+    else if (*arg[1] == 'x')  test_xntuple();
+    else if (*arg[1] == 'X')  test_Xntuple();
+  }
+  catch(PThrowable exc ) {
+    cerr << "tnt-main() , Catched exception: \n" << exc.Msg() << endl;
+  }
+  catch(std::exception ex) {
+    cerr << "tnt-main() , Catched exception ! " << (string)(ex.what()) << endl;
+  }
+  catch(...) {
+    cerr << "tnt-main() , Catched ... ! " << endl;
+  }
+}
+
+/*  ***** Test de NTuple simple ***** */
+void test_ntuple()
+{
+  char * names[3] = {"XPos", "YPos", "Val"};
+  int i,j, k;
+  float xnt[3];
+
+  cout << "======= test_ntuple:  Testing NTuple ======= " << endl;
+
+ cout << "Creation Ntuple avec X,Y,Val ... " << endl;
+ NTuple  nt1(3, names, 20);
+
+ k = 0;
+ for(j=0; j<8; j++)
+   for(i=0; i<12; i++)
+     { xnt[0] = i+0.5;  xnt[1] = j+0.5;  xnt[2] = k;
+     nt1.Fill(xnt); k++; }
+
+ nt1.Info().Comment() = "NTuple de Test - Cree par tnt.cc";
+ nt1.Info()["Version"] = SophyaVersion();
+ nt1.Show(cout);
+ nt1.Print(0, 5);
+ nt1.Print(18, 5);
+ nt1.Print(94, 5);
+
+ string fn = "nt.ppf";
+ {
+  cout << "Ecriture NTuple ds nt.ppf ... \n" << endl;
+  ObjFileIO<NTuple> fio(&nt1);
+  fio.Write(fn);
+ }
+
+ {
+   cout << "Lecture NTuple (nt2) ds nt.ppf ... \n" << endl;
+
+   ObjFileIO<NTuple> fio(fn);
+   NTuple* nt2 = (NTuple*)fio.DataObj();
+   nt2->Show(cout);
+   nt2->Print(0, 5);
+   nt2->Print(18, 5);
+   nt2->Print(94, 5);
+ }
+
+
+}
+
+/*  ***** Test de dvlist ***** */
+void test_dvl()
+{
+DVList dvl;
+
+cout << "\n ======= test_dvl:  Testing MuTyV ======= " << endl;
+MuTyV zvs = " ( 1.41 -2.71) ";
+MuTyV dvs = "434.898";
+MuTyV fvu = 314.1596;
+MuTyV ivu = 7654321;
+cout << " float->string: fvu= " << fvu << " (string)fvu=" << (string)fvu << endl;
+cout << " int->string: ivu= " << ivu << " (string)ivu=" << (string)ivu << endl;
+ complex<double> zzd = zvs;
+cout << "String->complex<double>: zvs = " << zvs 
+     << " (complex<double>)zvs= " << zzd << endl;
+cout << "String->double: dvs = " << dvs 
+     << " (double)zvs= " << (double)dvs << endl;
+
+
+cout << "\n\n ======= test_dvl:  Testing DVList ======= " << endl;
+dvl.SetI("Var XXX", 12345);
+dvl.SetI("IV1-80", 80);
+dvl.SetI("IV2-330", 330);
+
+dvl.SetD("DV1-0.2", 0.2);
+dvl.SetD("DV2-4.5", 4.5);
+dvl.SetZ("ZV", complex<r_8>(2.0,-1.44));
+
+dvl.SetI("IVV3-783", 783);
+dvl("IVV3-783-O") =  7783;
+// dvl["Avec[]"] =  "operateur [] !";
+dvl.SetD("DVV3", 3.141592652141592652);
+dvl.SetComment("DVV3", "Comment for DVV3, r_8 type variable");
+dvl("DVV3avec()") =  44.555e-8; 
+
+dvl.SetS("Blanc_White", "123.456Ma premiere chaine");
+dvl.SetI("IntegerValue", 55777);
+dvl.SetComment("IntegerValue", "This variable has a comment");
+dvl.Comment() = "This is a test DVL produced by the program tdvl.cc \n Using SOPHYA , Feb 2000";
+
+dvl["Sinf"] = "inf 0985";
+dvl.Print();
+
+
+double d = dvl("DV2-4.5");
+float f = dvl("DVV3");
+int i = dvl("IVV3-783");
+complex<r_8> z = dvl("ZV");
+
+printf("\n \n Essai1 (IVV3 DVV3 DV2= ) %d  %.20g  %g \n", i, f, (float)d);
+printf("\n \n Essai ZV= (%.2g  %g I) \n", z.real(), z.imag());
+cout << "Test Comment/IntegerValue: " << dvl.GetComment("IntegerValue") << endl;
+cout << "Test Comment/DVV3: " << dvl.GetComment("DVV3") << endl;
+
+cout << "Test string recup  " << (string)(dvl["Blanc_White"]) << endl;
+cout << "Test string recup(int=80)  " << (string)(dvl["IV1-80"]) << endl;
+dvl("DVV3") = (double)3.141592652141592652;
+cout << "Test string recup(double=Pi..i)  " << (string)(dvl["DVV3"]) << endl;
+
+ {
+   cout << " Writing DVList in file PPF dvl.ppf " << endl;
+   POutPersist os("dvl.ppf");
+   os << dvl ;
+ }
+
+ cout << "-------------------------- \n\n" 
+      << " reading DVList from file dvl.ppf ... \n" << endl;
+
+ DVList dvlr("dvl.ppf");
+ double df1 = (double)( dvlr["DVV3"] );
+ double df2 = (double)3.141592652141592652 - df1;
+ cout << " Test Precision : Pi-Pi= " << df2  << "DVV3= " << df1 << endl;
+
+ cout << dvlr;
+
+}
+
+void test_Xntuple() 
+{
+    char* names[] = {"str1", "str2", "str3", "str4", "str5"} ; 
+    XNTuple nt(0, 0, 0, 5, names) ; 
+    char** ce = new char*[5] ; 
+    int i;
+    for(i = 0 ; i < 5 ; i++)
+	ce[i] = new char[20] ; 
+
+  cout << "======= test_Xtuple:  simple XNTuple test ======= " << endl;
+
+    strncpy(ce[1], "toto a une auto", 20) ; 
+    strncpy(ce[2], "titi a une iti", 20) ; 
+    strncpy(ce[3], "tutu a une utu", 20) ; 
+    strncpy(ce[4], "tata a une ata", 20) ; 
+    for(i = 0 ; i < 100000 ; i++) {
+	sprintf(ce[0], "%d", i) ; 
+	nt.Fill(NULL, NULL, NULL, ce) ; 
+    }
+    
+    nt.Show() ; 
+    cout << nt.LineHeaderToString() ; 
+    cout << nt.LineToString(5027) << endl ; 
+    
+    char* names2[] = {"d0", "d1", "f0", "f1", "f2", "i0", "str0", "str1"} ; 
+    XNTuple nt2(2, 3, 1, 2, names2) ; 
+    double de[2] ; float fe[3] ; int ie ; 
+    char** ce2 = new char*[2] ; 
+    for(i = 0 ; i < 2 ; i++) ce2[i] = new char[20] ; 
+    strncpy(ce2[1], "glop glop", 20) ; 
+    
+    for(i = 0 ; i < 100000 ; i++) {
+	de[0] = i ; 
+	de[1] = sin((double)i) ; 
+	fe[0] = i ; 
+	fe[1] = i * cos((double)i) ; 
+	fe[2] = 2*i ; 
+	ie    = -i; 
+	sprintf(ce[0], "%d", i) ; 
+	nt2.Fill(de, fe, &ie, ce) ; 
+    }
+    nt2.Show() ; 
+    nt2.LineHeaderToString() ; 
+    //    nt2.LineToString(20) ; 
+}
+
+
+void test_xntuple() 
+{
+    char* names[] = {"dblval", "floval", "intval", "strval"} ; 
+    XNTuple nt(1, 1, 1, 1, names) ; 
+    double de ; 
+    float  fe ; 
+    int    ie ; 
+    char*  ce = new char[22] ; 
+    
+    
+  cout << "======= test_Xtuple:  XNTuple test ======= " << endl;
+  int i;
+    for(i = 0 ; i < nt.NVar() ; i++)
+	printf(" +++ %s <--> %d \n", 
+	       nt.NomIndex(i).c_str(), nt.IndexNom(nt.NomIndex(i).c_str())) ; 
+
+    for(i = 0 ; i < 100000 ; i++) {
+	de = fe = ie = i ; 
+	sprintf(ce, "%d", i) ; 
+	nt.Fill(&de, &fe, &ie, &ce) ; 
+    }
+    nt.Show() ; 
+    cout << nt.VarList_C("toto") ; 
+    cout << nt.LineHeaderToString() ; 
+    cout << nt.LineToString(20) << endl << endl ; 
+    
+    
+    XNTuple nt2 ; 
+    nt2.SwapPath() = "/tmp/sop/" ; 
+    nt2.Copy(nt) ; 
+    nt2.Show() ; 
+    for(i = 0 ; i < 100000 ; i++) {
+	de = fe = ie = i ; 
+	sprintf(ce, "%d", i) ; 
+	nt2.Fill(&de, &fe, &ie, &ce) ; 
+    }
+    nt2.Show() ; 
+    
+    {
+      POutPersist os("xnt.ppf");
+      os << nt2 ;
+    }
+
+    XNTuple::SetSwapPath("/tmp/sop/") ; 
+    XNTuple nt3("xnt.ppf") ; 
+    nt3.Show() ; 
+    
+    for(i = 0 ; i < nt3.NEntry() ; i+= 1000)
+	printf("%f %f %d %s\n", 
+	       nt3.GetDVal(i,0), 
+	       nt3.GetFVal(i,1), 
+	       nt3.GetIVal(i,2), 
+	       nt3.GetSVal(i,3).c_str()) ; 
+    
+    double min, max ; 
+    for(i = 0 ; i < nt3.NVar() ; i++) {
+	nt3.GetMinMax(i, min, max) ; 
+	printf("GetMinMax(%s) : %f/%f\n", 
+	       nt3.NomIndex(i).c_str(), min, max) ; 
+    }
+    //    nt3.Show() ; 
+}
+
Index: /tags/V_Dec2002/SophyaProg/Tests/tobjio.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/tobjio.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/tobjio.cc	(revision 2309)
@@ -0,0 +1,173 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "math.h"
+#include <iostream.h>
+#include <string>
+
+// Pour le test 
+#include "histinit.h"
+#include "histos.h"
+#include "histos2.h"
+#include "ntuple.h"
+
+
+#include "fmath.h"
+#include "nbrandom.h"
+#include "fioarr.h"
+
+
+int main(int narg, char* arg[])
+{
+
+  SophyaInit();
+
+  cout << "Hash check, OMatrix : " << hex << PIOPersist::Hash("OMatrix") << dec << endl;
+
+  cout << "Test Creation / PPersist Save NTuple, Histo, ..." << endl;
+
+  POutPersist so("tobjio.ppf");
+
+  NTuple *nt;
+  float xnt[4];
+  char *ntn[4] = {"x","y","ex","ey"};
+  int nent,i;
+  nent = 1000;
+  nt = new NTuple(2,ntn);  // Creation NTuple (AVEC new )
+  for(i=0; i<nent; i++) {
+    xnt[0] = i*50./nent; xnt[1] = 0.2*xnt[0]*xnt[0]+(NorRand()*xnt[0]/3.);
+    nt->Fill(xnt);
+  }
+
+  string nom = "nt21";
+  ObjFileIO<NTuple> oiont(*nt);
+  oiont.Write(so, nom);
+  cout << "Writing " << nom << endl;
+
+  string nx, ny, nz;
+  string ex,ey,ez;
+  nx = "x";  ny = "y";
+  nent = 20;
+  nt = new NTuple(4,ntn);  // Creation NTuple (AVEC new )
+  for(i=0; i<nent; i++) {
+    xnt[0] = i*50./nent; xnt[1] = 0.2*xnt[0]*xnt[0]+(NorRand()*xnt[0]/3.);
+    xnt[2] = sqrt((double) xnt[0]); xnt[3] = xnt[0]*2;
+    nt->Fill(xnt);
+  }
+  nom = "nt22";
+  ObjFileIO<NTuple> oiont2(*nt);
+  oiont2.Write(so, nom);
+  cout << "Writing " << nom << endl;
+
+  {  //  Objet Histo-2D
+  r_8 x,y,w;
+  int i,j;
+  Histo2D* h = new Histo2D(-10.,10.,25,-10.,10.,25);
+  for(i=0; i<25; i++) for(j=0; j<25; j++) {
+    h->BinCenter(i,j,x,y);
+    w = 100.*exp(-0.5*(x*x/9. + y*y/9.));
+    h->Add(x,y,w);
+    w = 50.*exp(-0.5*((x+10.)*(x+10.)/9. + (y+10.)*(y+10.)/9.));
+    h->Add(x,y,w);
+    }
+  nom = "h2d";
+  ObjFileIO<Histo2D> oioh(*h);
+  oioh.Write(so, nom);
+  cout << "Writing " << nom << endl;
+  }
+
+  {
+  Histo *h;
+  float x;
+
+
+  h = new Histo(0., 200., 100);  // Creation histo (AVEC new )
+  for(i=0; i<100; i++)  // Remplissage d'histo
+    { x = (2*i+1.);  h->Add(x, x*(200.-x)); }
+  nom = "h1d";
+  ObjFileIO<Histo> oioh(*h);
+  oioh.Write(so, nom);
+  cout << "Writing " << nom << endl;
+  
+  }
+
+  {   // Vecteurs 
+  Vector* vpx, *vpy;
+  vpx = new Vector(20);  vpy = new Vector(20);
+  int i;   double x;
+  for(i=0; i<20; i++) { x = 8.*i/20;  (*vpx)(i) = x;  (*vpy)(i) = 3*cos(x)+2*sin(x); }
+  nom = "vx1";
+  FIO_TArray<double>  oiov1(vpx);
+  oiov1.Write(so, nom);
+  cout << "Writing " << nom << endl;
+  nom = "vy1";
+  FIO_TArray<double>  oiov2(vpy);
+  oiov2.Write(so, nom);
+  cout << "Writing " << nom << endl;
+  vpx = new Vector(30);  
+  for(i=0; i<30; i++) { x = 8.*i/30+0.1;  (*vpx)(i) = sin(2.*x)/(2.*x); }
+  nom = "vx2";
+  FIO_TArray<double>  oiov3(vpx);
+  oiov3.Write(so, nom);
+  cout << "Writing " << nom << endl;
+  }
+
+      
+  {       // NTuple 3D
+  float xnt[6];
+  double ang;
+  char *ntn[6] = {"x","y","z","ex","ey","ez"};
+  int nent,i;
+      
+  NTuple* nt = new NTuple(6,ntn);  // Creation NTuple (AVEC new )
+  nent = 3000;
+  for(i=0; i<nent; i++) {
+  ang = 5.*6.28*(double)i/(double)nent;
+  xnt[0] = cos(ang)*1.5+NorRand()*0.1; xnt[1] = sin(ang)*1.5+NorRand()*0.1;
+  xnt[2] = ang/8.+NorRand()*0.05;   xnt[3] = xnt[4] = xnt[5] = 0.;
+  nt->Fill(xnt);
+  }
+
+  nom = "nt31";
+  ObjFileIO<NTuple> oiont(*nt);
+  oiont.Write(so, nom);
+  cout << "Writing " << nom << endl;
+  
+  nt = new NTuple(6,ntn);  // Creation NTuple (AVEC new )
+  nent = 100;
+  for(i=0; i<nent; i++) {
+    ang = 5.*6.28*(double)i/(double)nent;
+    xnt[0] = cos(-ang)*1+NorRand()*0.0; xnt[1] = sin(-ang)*1.+NorRand()*0.0;
+    xnt[2] = ang/8.+NorRand()*0.0;   xnt[3] = 0.1; xnt[4] = 0.15;  xnt[5] = 0.07;
+    nt->Fill(xnt);
+    }
+  nom = "nt32";
+  ObjFileIO<NTuple> oiont2(*nt);
+  oiont2.Write(so, nom);
+  cout << "Writing " << nom << endl;
+  }
+
+  {    // Matrices 
+  Matrix* mtx = new Matrix(50, 50);
+  int i,j;
+  double xp,yp,rp;
+  for(i=0; i<50; i++)
+     for(j=0; j<50; j++) { 
+     xp = i-15;   yp = j-25;
+     rp = (xp*xp)/16.+(yp*yp)/16.;
+     (*mtx)(j,i) = 11.*exp(-rp);
+     xp = i-35;   yp = j-15;
+     rp = (xp*xp)/9.+(yp*yp)/9.;
+     (*mtx)(j,i) += 3.*exp(-rp);
+     xp = i-45;   yp = j-40;
+     rp = (xp*xp)/10.+(yp*yp)/20.;
+     (*mtx)(j,i) += 6.*exp(-rp);
+     }
+  nom = "mtx1";
+  FIO_TArray<double> oiom(mtx);
+  oiom.Write(so, nom);
+  cout << "Writing " << nom << endl;
+  }
+
+  cout << " End --- exit .... " << endl;
+}
+
Index: /tags/V_Dec2002/SophyaProg/Tests/tobjio2.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/tobjio2.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/tobjio2.cc	(revision 2309)
@@ -0,0 +1,104 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <iostream.h>
+#include <string>
+
+// Pour le test 
+#include "histinit.h"
+#include "histos.h"
+#include "histos2.h"
+#include "ntuple.h"
+#include "tarray.h"
+
+
+#include "fmath.h"
+#include "nbrandom.h"
+
+
+int main(int narg, char* arg[])
+{
+
+  SophyaInit();
+
+  cout << "Hash check, OMatrix : " << hex << PIOPersist::Hash("OMatrix") << dec << endl;
+
+  cout << "Test Creation / PPersist Save NTuple, Histo, ..." << endl;
+
+  try {
+  POutPersist so("tobjio2.ppf");
+
+  NTuple *nt;
+  float xnt[4];
+  char *ntn[4] = {"x","y","ex","ey"};
+  int nent,i;
+  nent = 1000;
+  nt = new NTuple(2,ntn);  // Creation NTuple (AVEC new )
+  for(i=0; i<nent; i++) {
+    xnt[0] = i*50./nent; xnt[1] = 0.2*xnt[0]*xnt[0]+(NorRand()*xnt[0]/3.);
+    nt->Fill(xnt);
+  }
+
+  string nom = "nt21";
+  cout << "Writing " << nom << endl;
+  so.PutObject(*nt, nom);
+
+  string nx, ny, nz;
+  string ex,ey,ez;
+  nx = "x";  ny = "y";
+  nent = 20;
+  nt = new NTuple(4,ntn);  // Creation NTuple (AVEC new )
+  for(i=0; i<nent; i++) {
+    xnt[0] = i*50./nent; xnt[1] = 0.2*xnt[0]*xnt[0]+(NorRand()*xnt[0]/3.);
+    xnt[2] = sqrt((double) xnt[0]); xnt[3] = xnt[0]*2;
+    nt->Fill(xnt);
+  }
+  nom = "nt22";
+  cout << "Writing " << nom << endl;
+  so.PutObject(*nt, nom);
+
+  {  //  Objet Histo-2D
+  r_8 x,y,w;
+  int i,j;
+  Histo2D* h = new Histo2D(-10.,10.,25,-10.,10.,25);
+  for(i=0; i<25; i++) for(j=0; j<25; j++) {
+    h->BinCenter(i,j,x,y);
+    w = 100.*exp(-0.5*(x*x/9. + y*y/9.));
+    h->Add(x,y,w);
+    w = 50.*exp(-0.5*((x+10.)*(x+10.)/9. + (y+10.)*(y+10.)/9.));
+    h->Add(x,y,w);
+    }
+  nom = "h2d";
+  cout << "Writing " << nom << endl;
+  so.PutObject(*h, nom);
+  }
+
+
+  {    // Matrices 
+  TArray<double> * mtx = new TArray<double>(50, 50);
+  int i,j;
+  double xp,yp,rp;
+  for(i=0; i<50; i++)
+     for(j=0; j<50; j++) { 
+     xp = i-15;   yp = j-25;
+     rp = (xp*xp)/16.+(yp*yp)/16.;
+     (*mtx)(j,i,0) = 11.*exp(-rp);
+     xp = i-35;   yp = j-15;
+     rp = (xp*xp)/9.+(yp*yp)/9.;
+     (*mtx)(j,i,0) += 3.*exp(-rp);
+     xp = i-45;   yp = j-40;
+     rp = (xp*xp)/10.+(yp*yp)/20.;
+     (*mtx)(j,i,0) += 6.*exp(-rp);
+     }
+  nom = "mtx1";
+  cout << "Writing " << nom << endl;
+  so.PutObject(*mtx, nom);
+
+  }
+  }
+  catch (PThrowable exc) {
+    cerr << " Catched Exception PThrowable - Msg= " << exc.Msg() << endl;
+  }
+  cout << " End --- exit .... " << endl;
+}
+
Index: /tags/V_Dec2002/SophyaProg/Tests/tspm.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/tspm.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/tspm.cc	(revision 2309)
@@ -0,0 +1,137 @@
+#include <iostream.h>
+#include "skymapinit.h"
+#include "skymap.h"
+
+#include "tod.h"
+#include "timing.h"
+
+template <class T>
+void  MeanSig(PixelMap<T> const & map, double& gmoy, double& gsig)
+{
+  gmoy=0.;
+  gsig = 0.;
+  double valok;
+  for(int k=0; k<map.NbPixels(); k++) {
+    valok = map(k);
+    gmoy += valok;  gsig += valok*valok;
+  }
+  gmoy /= (double)map.NbPixels();
+  gsig = gsig/(double)map.NbPixels() - gmoy*gmoy;
+  if (gsig >= 0.) gsig = sqrt(gsig);
+}
+
+int main(int narg, char* arg[]) 
+{
+  double teta,phi;
+  double gmoy, gsig;
+
+  SophyaInit();
+  InitTim();   // Initializing the CPU timer 
+  if ((narg > 1) && (strcmp(arg[1],"-h") == 0) )  {
+    cout << " tspm [HEALPix_M=32] [M_TetaPhi=64] : Spherical Map Test " << endl;
+    exit(0);
+    }
+
+  int  m=32;
+  if (narg >1)  m = atoi(arg[1]);
+  cout <<  " ===== HEALPix Spherical Map Test M= " << m << endl;
+
+  SphereHEALPix<double> sph(m);
+
+  cout << "Filling spherical map NPixels= " << sph.NbPixels() << endl;
+  int j;
+  for (j=0;j<sph.NbPixels();j++) 
+    {
+      sph.PixThetaPhi(j,teta,phi);
+      sph(j)= 0.2* cos(3.*teta)*sin(8*phi);
+    }
+  PrtTim("End of Fill ");
+
+  // Computing mean and sigma on the sphere 
+  MeanSig(sph, gmoy, gsig);
+  cout << "SphereHEALPix<double> Mean= " << gmoy << "  Sigma = " << gsig << endl;
+  PrtTim("End of Mean-Sig ");
+
+//  Writing to a PPF file
+  {
+  POutPersist s("sphg.ppf"); 
+  FIO_SphereHEALPix<double> fiog(&sph) ;
+  fiog.Write(s);
+  cout << "SphereHEALPix<double>  written to sphg.ppf "  << endl;
+  }
+
+  // Reading from the file
+  {
+  FIO_SphereHEALPix<double> fiog("sphg.ppf");
+  SphereHEALPix<double>  sph2 = fiog;
+  PrtTim("End of Write/Read ");
+
+  cout << " Spherical map from file sphg.ppf NPixels= " << sph2.NbPixels() << endl;
+
+  int ndiff = 0;
+  for(int k=0; k<sph2.NbPixels(); k++) {
+//    if ((sph2(k)-sph(k)) > 1.e-49)  { 
+    if ( sph2(k) != sph(k) )   { 
+      ndiff++;
+      if (ndiff < 20)  cout << "!!!Diff: K= " << k << " SPH2= " << sph2(k) << " SPH= " << sph(k) << endl;
+    }
+  }
+  MeanSig(sph, gmoy, gsig);
+  cout << "SphMapFromFile Mean= " << gmoy << "  Sigma = " << gsig << endl;
+  cout << " NDiff = " << ndiff << " (should be zero = 0) " << endl;
+  PrtTim("End of Mean-Sig ");
+  }
+
+
+  int  mt=64;
+  if (narg > 2)  mt = atoi(arg[2]);
+  cout <<  "\n ===== ThetaPhi Spherical Map Test MT= " << mt << endl;
+
+  SphereThetaPhi<float> spht(m);
+
+  cout << "Filling spherical map NPixels= " << spht.NbPixels() << endl;
+  for (j=0;j<spht.NbPixels();j++) 
+    {
+      spht.PixThetaPhi(j,teta,phi);
+      spht(j)= 0.5* cos(5.*teta)*sin(10.*phi);
+    }
+  PrtTim("End of Fill ");
+
+  // Computing mean and sigma on the sphere 
+  MeanSig(spht, gmoy, gsig);
+  cout << "SphereThetaPhi<float> Mean= " << gmoy << "  Sigma = " << gsig << endl;
+  PrtTim("End of Mean-Sig ");
+
+//  Writing to a PPF file
+  {
+  POutPersist s("spht.ppf"); 
+  FIO_SphereThetaPhi<float> fiog(spht) ;
+  fiog.Write(s);
+  cout << "SphereThetaPhi<float> written to spht.ppf "  << endl;
+  }
+
+  // Reading from the file
+  {
+  FIO_SphereThetaPhi<float> fiog("spht.ppf");
+  SphereThetaPhi<float>  sph2 = fiog;
+  PrtTim("End of Write/Read ");
+
+  cout << " Spherical map from file sph.ppf NPixels= " << sph2.NbPixels() << endl;
+
+  int ndiff = 0;
+  for(int k=0; k<sph2.NbPixels(); k++) {
+//    if ((sph2(k)-sph(k)) > 1.e-49)  { 
+    if ( sph2(k) != spht(k) )   { 
+      ndiff++;
+      if (ndiff < 20)  cout << "!!!Diff: K= " << k << " SPH2= " << sph2(k) << " SPH= " << sph(k) << endl;
+    }
+  }
+  MeanSig(sph, gmoy, gsig);
+  cout << "SphMapFromFile Mean= " << gmoy << "  Sigma = " << gsig << endl;
+  cout << " NDiff = " << ndiff << " (should be zero = 0) " << endl;
+  PrtTim("End of Mean-Sig ");
+  }
+
+  cout <<  " ===== Fin de TSPM_Test ======== " << endl;
+  return 0;
+}
Index: /tags/V_Dec2002/SophyaProg/Tests/tspm2.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/tspm2.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/tspm2.cc	(revision 2309)
@@ -0,0 +1,208 @@
+#include <iostream.h>
+#include <math.h>
+#include "sambainit.h"
+#include "skymap.h"
+
+#include "tod.h"
+#include "fitstarray.h"
+#include "fitsspherehealpix.h"
+#include "nbrandom.h"
+
+#include "timing.h"
+
+template <class T>
+void  MeanSig(PixelMap<T> const & map, double& gmoy, double& gsig)
+{
+  gmoy=0.;
+  gsig = 0.; 
+  double valok;
+  for(int k=0; k<map.NbPixels(); k++) {
+    valok = map(k);
+    gmoy += valok;  gsig += valok*valok; 
+  }
+  gmoy /= (double)map.NbPixels();
+  gsig = gsig/(double)map.NbPixels() - gmoy*gmoy;
+  if (gsig >= 0.) gsig = sqrt(gsig);
+}
+
+template <class T>
+void  Project_Mol(PixelMap<T> const & map, TMatrix<T> & mtx, T defval=-999.)
+{
+  r_8 xa, yd, teta,phi, facteur;
+  int_4 l,c,k;
+  int_4 nl = mtx.NRows();
+  int_4 nc = mtx.NCols();
+  mtx = defval;   // On met tout a defval
+  cout << " NRows= " << nl << "  NCols= " << nc  << endl;
+  for(l=0; l<nl; l++) {
+    yd = (r_8)(l+0.5)/(r_8)nl-0.5;
+    facteur=2.*M_PI/sin(acos((double)yd*2));
+    teta = (yd+0.5)*Pi;
+    //    teta = (0.5-yd)*M_PI;
+    for(c=0; c<nc; c++)  {
+      xa = (r_8)(c+0.5)/(r_8)nc-0.5;
+      phi = xa*facteur+M_PI;
+      if ( (phi <= 2*M_PI) && (phi >= 0.) ) {
+        k = map.PixIndexSph(teta, phi);
+        mtx(l,c) = map(k);
+      }
+    }
+  }
+
+}
+
+int main(int narg, char* arg[]) 
+{
+  double teta,phi;
+  double gmoy=0., gsig=0.;
+
+  SophyaInit();
+  InitTim();   // Initializing the CPU timer 
+  if ((narg > 1) && (strcmp(arg[1],"-h") == 0) )  {
+    cout << " tspm [HEALPix_M=32] : HEALPix Spherical Map Test " << endl;
+    exit(0);
+    }
+
+  int  m=32;
+  if (narg >1)  m = atoi(arg[1]);
+  cout <<  " ===== HEALPix Spherical Map Test M= " << m << endl;
+
+  try {
+
+  POutPersist s("spheres.ppf"); 
+  string nomobj;
+
+  {
+  SphereHEALPix<double> sph(m);
+
+  cout << "Filling spherical map NPixels= " << sph.NbPixels() << endl;
+  for (int j=0;j<sph.NbPixels();j++) 
+    {
+      sph.PixThetaPhi(j,teta,phi);
+      sph(j)= 0.2* cos(3.*teta)*sin(8*phi);
+    }
+  PrtTim("End of Fill ");
+
+   {
+   FIO_SphereHEALPix<double> fiog(&sph) ;
+   nomobj = "sphg1";
+   fiog.Write(s, nomobj);
+   cout << "SphMap SphereHEALPix<double> written to POutPersist with name "  << nomobj << endl;
+   }
+
+
+  TMatrix<double> mtx(3*m, 6*m);
+  cout << " Project_Mol(sph, mtx) " << endl;
+  Project_Mol(sph, mtx);
+  {
+  cout << " Writing to FITS prjmol1.fits " << endl;  
+  FITS_TArray<double> fios(mtx);
+  fios.Write("prjmol1.fits");
+  }
+
+  // Computing mean and sigma on the sphere 
+  MeanSig(sph, gmoy, gsig);
+  cout << "SphMap Mean= " << gmoy << "  Sigma = " << gsig << endl;
+  PrtTim("End of Mean-Sig ");
+  }
+
+  {
+  SphereHEALPix<float> sph(m);
+
+  cout << "Filling spherical map2 NPixels= " << sph.NbPixels() << endl;
+  for (int j=0;j<sph.NbPixels();j++) 
+    {
+      sph.PixThetaPhi(j,teta,phi);
+      if (teta < 0.3)  sph(j) = 30.;
+      else if ((teta>1.4) && (teta<1.6) ) sph(j) = 20.;
+      else {
+        if (phi < 2.)    sph(j) = 2.;
+        else if (phi > 3.) sph(j) = 5.;
+        else sph(j) = 0.;
+      }
+    }
+  PrtTim("End of Fill2 ");
+
+   {
+   FIO_SphereHEALPix<float> fiog(&sph) ;
+   nomobj = "sphg2";
+   fiog.Write(s, nomobj);
+   cout << "SphMap SphereHEALPix<float> written to POutPersist with name "  << nomobj << endl;
+   }
+
+
+  // On projete dans un fichier FITS
+   {
+   cout << "Test of Write/Read SphereHEALPix<float> to FITS (sphg_r4.fits) " << endl;
+   FITS_SphereHEALPix<r_4> fiosw(sph);
+   fiosw.Write("sphg_r4.fits");
+   }
+
+   
+   SphereHEALPix<float> sphr;
+   {
+   FITS_SphereHEALPix<r_4> fiosr("sphg_r4.fits");
+   sphr = fiosr;
+   cout << " Read from file - SphereHEALPix<float> NPixels= " << sphr.NbPixels() << endl;
+   int ndiff = 0;
+   for(int k=0; k<sphr.NbPixels(); k++) {
+    if ( sphr(k) != sph(k) )   { 
+      ndiff++;
+      if (ndiff < 20)  cout << "!!!Diff: K= " << k << " SPHR= " << sphr(k) << " SPH= " << sph(k) << endl;
+      }
+    }
+   cout << " ReadFrom FITS NDiff = " << ndiff << " (should be zero = 0) " << endl;
+   
+   }
+
+
+  TMatrix<float> mtx(3*m, 6*m);
+  Project_Mol(sph, mtx);
+  {
+  cout << " Writing to FITS prjmol2.fits " << endl;  
+  FITS_TArray<double> fios(mtx);
+  fios.Write("prjmol2.fits");
+  }
+
+  // Computing mean and sigma on the sphere 
+  MeanSig(sph, gmoy, gsig);
+  cout << "SphMap2 Mean= " << gmoy << "  Sigma = " << gsig << endl;
+  PrtTim("End of Mean-Sig2 ");
+  }
+
+  {
+  SphereThetaPhi< complex<float> > sphc(m*10);
+
+  cout << "Filling spherical map3 SphereThetaPhi(complex) NPixels= " << sphc.NbPixels() << endl;
+  for (int j=0;j<sphc.NbPixels();j++) 
+    {
+      sphc.PixThetaPhi(j,teta,phi);
+      if (teta < 0.3)   sphc(j) = (30., drandpm1()*3.); 
+      else if ((teta>1.4) && (teta<1.6) ) sphc(j) = (20., NorRand()); 
+      else {
+        if (phi < 2.)     sphc(j) = 2.; 
+        else if (phi > 3.) sphc(j) = 5.;
+        else sphc(j) = 0.;
+      }
+    }
+  PrtTim("End of Fill2 ");
+
+   {
+   FIO_SphereThetaPhi< complex<float> > fio(&sphc) ;
+   nomobj = "sphtp";
+   fio.Write(s, nomobj);
+   cout << "SphMap written to POutPersist with name "  << nomobj << endl;
+   }
+  }
+  }
+  catch (PThrowable & exc) {
+    cerr << "tspm2: Catched Exception " << (string)typeid(exc).name()
+         << " - Msg= " << exc.Msg() << endl;
+  }
+  catch (...) {
+    cerr << "tspm2:  some other exception was caught ! " << endl;
+  }
+
+  cout <<  " ===== Fin de TSPM2_Test ======== " << endl;
+  return 0;
+}
Index: /tags/V_Dec2002/SophyaProg/Tests/tstboloread.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/tstboloread.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/tstboloread.cc	(revision 2309)
@@ -0,0 +1,200 @@
+// Test des classes FitsBoloRead
+/*
+set DIR = $PLANCK/Kiruna_2001_01_29/TOI/Full_sampling
+ln -sf $DIR/PointingABv8/gLatLonAB_143k05_104000000_108465000.fits pointing.fits
+ln -sf $DIR/Bolo_etc/b143k05_104000000_108465000.fits bolo.fits
+cmvboloread -L 1000,1 -m 100000 \
+           -a gLonBolo_27 -d gLatBolo_27 -b boloMuV_27  -s sampleNum \
+           -A pointing.fits -1 0 -B bolo.fits -3 0
+*/
+#include "machdefs.h"
+#include <typeinfo>
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream.h>
+#include <values.h>
+#include <string.h>
+#include <string>
+#include <unistd.h>
+#include "sophyainit.h"
+#include "pexceptions.h"
+#include "fboloread.h"
+#include "fabtwriter.h"
+
+//#define NO_VECTOR
+#define USE_EXCEPT
+
+int main(int narg,char *arg[])
+{
+ SophyaInit();
+ char *label_alpha = "", *label_delta = "",
+      *label_bolo  = "", *label_flag  = "",
+      *label_snum  = "";
+ char *fits_alpha  = "", *fits_delta  = "",
+      *fits_bolo   = "", *fits_flag   = "",
+      *fits_snum   = "";
+ int hdu_alpha=0, hdu_delta=0, hdu_bolo=0, hdu_flag=0, hdu_snum=0;
+ long blen = 100, bsens = 1, lpmod=1;
+ char c;
+ while((c = getopt(narg,arg,"ha:d:s:b:f:A:D:S:B:F:1:2:3:4:5:L:m:")) != -1) {
+   switch (c) {
+   case 'a' :
+     label_alpha = optarg;
+     break;
+   case 'd' :
+     label_delta = optarg;
+     break;
+   case 'b' :
+     label_bolo = optarg;
+     break;
+   case 'f' :
+     label_flag = optarg;
+     break;
+   case 's' :
+     label_snum = optarg;
+     break;
+   case 'A' :
+     fits_alpha = optarg;
+     break;
+   case 'D' :
+     fits_delta = optarg;
+     break;
+   case 'B' :
+     fits_bolo = optarg;
+     break;
+   case 'F' :
+     fits_flag = optarg;
+     break;
+   case 'S' :
+     fits_snum = optarg;
+     break;
+   case '1' :
+     sscanf(optarg,"%d",&hdu_alpha);
+     break;
+   case '2' :
+     sscanf(optarg,"%d",&hdu_delta);
+     break;
+   case '3' :
+     sscanf(optarg,"%d",&hdu_bolo);
+     break;
+   case '4' :
+     sscanf(optarg,"%d",&hdu_flag);
+     break;
+   case '5' :
+     sscanf(optarg,"%d",&hdu_snum);
+     break;
+   case 'L' :
+     sscanf(optarg,"%ld,%ld",&blen,&bsens);
+     break;
+   case 'm' :
+     sscanf(optarg,"%ld",&lpmod);
+     if(lpmod<=0) lpmod = 1;
+     break;
+   case 'h' :
+   default :
+     cout<<"cmvcolread -L buflen,sens -m print_modulo"
+         <<"\n           -a label_alpha -d label_delta"
+         <<"\n           -b label_bolo  -f label_flag"
+         <<"\n           -s label_snum"
+         <<"\n           -A fits_alpha  -D fits_delta"
+         <<"\n           -B fits_bolo   -F fits_flag"
+         <<"\n           -S fits_snum"
+         <<"\n           -1 hdu_alpha  -2 hdu_delta"
+         <<"\n           -3 hdu_bolo   -4 hdu_flag"
+         <<"\n           -5 hdu_snum"
+         <<endl;
+     return -1;
+   }
+ }
+
+ cout<<"alpha: "<<label_alpha<<" ("<<fits_alpha<<") hdu="<<hdu_alpha<<endl;
+ cout<<"delta: "<<label_delta<<" ("<<fits_delta<<") hdu="<<hdu_delta<<endl;
+ cout<<"bolo : "<<label_bolo <<" ("<<fits_bolo<<") hdu="<<hdu_bolo<<endl;
+ cout<<"flag : "<<label_flag <<" ("<<fits_flag<<") hdu="<<hdu_flag<<endl;
+ cout<<"snum : "<<label_snum <<" ("<<fits_snum<<") hdu="<<hdu_snum<<endl;
+
+#ifdef USE_EXCEPT
+try {
+#endif
+
+  FitsBoloRead fbr(blen,bsens);
+  fbr.SetDebug(3);
+  fbr.Print(3);
+
+  if(strlen(label_bolo)>0)
+    fbr.SetBolo(label_bolo,fits_bolo,hdu_bolo);
+  if(strlen(label_flag)>0)
+    fbr.SetFlag(label_flag,fits_flag,hdu_flag);
+  if(strlen(label_snum)>0)
+    fbr.SetSNum(label_snum,fits_snum,hdu_snum);
+  if(strlen(label_alpha)>0)
+    fbr.SetAlpha(label_alpha,fits_alpha,hdu_alpha);
+  if(strlen(label_delta)>0)
+    fbr.SetDelta(label_delta,fits_delta,hdu_delta);
+  int col1=-1;
+  if(strlen(label_snum)>0 && strlen(fits_alpha)>0)
+    col1 = fbr.AddCol(label_snum,fits_alpha,hdu_alpha);
+
+  fbr.Print(3);
+  cout<<"NRows= "<<fbr.GetNbLine()<<endl;
+  if(fbr.IsSNum()) fbr.SetNbLine(FitsBoloRead::ColSNum);
+  cout<<"fbr.SetNbLine(ColSNum): NRows= "<<fbr.GetNbLine()<<endl;
+  fbr.SetNbLine(-1);
+  cout<<"fbr.SetNbLine(): NRows= "<<fbr.GetNbLine()<<endl;
+
+#ifdef NO_VECTOR
+  cout<<"Reading element by elements"<<endl;
+  for(long i=0; i<fbr.GetNbLine(); i++) {
+    double a=-1.,d=-1.,b=-1.,f=-1.,s=-1.,c1=-1.;
+    if(fbr.IsAlpha())   a  = fbr.GetAlpha(i);
+    if(fbr.IsDelta())   d  = fbr.GetDelta(i);
+    if(fbr.IsBolo())    b  = fbr.GetBolo(i);
+    if(fbr.IsSNum())    s  = fbr.GetSNum(i);
+    if(fbr.IsFlag())    f  = fbr.GetFlag(i);
+    if(col1>=0) if(fbr.IsCol(col1)) c1 = fbr.GetCol(col1,i);
+    if(i%lpmod==0)
+      cout<<i<<" s="<<(long long)s
+          <<" b="<<b<<" f="<<f
+          <<" a="<<a<<" d="<<d<<" c1="<<(long long)c1<<endl;
+  }
+#else
+  cout<<"Reading with vectors"<<endl;
+  long istep = lpmod;
+  TVector<double> s,a,d,b,f,c1;
+  TVector<int_4> si4,fi4;
+  for(long i=0; i<fbr.GetNbLine(); i+=istep) {
+    long i2=i+istep-1; if(i2>=fbr.GetNbLine()) i2=fbr.GetNbLine()-1;
+    if(fbr.IsSNum())   {fbr.GetSNum(i,i2,s); fbr.GetSNum(i,i2,si4);}
+    if(fbr.IsBolo())    fbr.GetBolo(i,i2,b);
+    if(fbr.IsFlag())   {fbr.GetFlag(i,i2,f); fbr.GetFlag(i,i2,fi4);}
+    if(fbr.IsAlpha())   fbr.GetAlpha(i,i2,a);
+    if(fbr.IsDelta())   fbr.GetDelta(i,i2,d);
+    if(col1>=0) if(fbr.IsCol(col1)) fbr.GetCol(col1,i,i2,c1);
+    for(int j=0; j<2; j++) {
+      int ii = 0; if(j==1) ii=i2-i;
+      cout<<i<<"("<<ii<<") ";
+      if(fbr.IsSNum())    cout<<" s=("<<s(ii)<<","<<si4(ii)<<")";
+      if(fbr.IsBolo())    cout<<" b="<<b(ii);
+      if(fbr.IsFlag())    cout<<" f=("<<f(ii)<<","<<fi4(ii)<<")";
+      if(fbr.IsAlpha())   cout<<" a="<<a(ii);
+      if(fbr.IsDelta())   cout<<" d="<<d(ii);
+      if(col1>=0) if(fbr.IsCol(col1)) cout<<" c1="<<c1(ii);
+      cout<<endl;
+    }
+  }
+#endif
+
+#ifdef USE_EXCEPT
+} catch (PThrowable & exc) {
+  cout<<"Exception : "<<(string)typeid(exc).name()
+      <<" - Msg= "<<exc.Msg()<<endl;
+  return -2;
+
+} catch (...) {
+  cout<<" some other exception was caught !"<<endl;
+  return -2;
+}
+#endif
+
+ return 0;
+}
Index: /tags/V_Dec2002/SophyaProg/Tests/tstcolread.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/tstcolread.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/tstcolread.cc	(revision 2309)
@@ -0,0 +1,177 @@
+// Test des classes FitsBTColRead
+#include "machdefs.h"
+#include <typeinfo>
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream.h>
+#include <values.h>
+#include <string.h>
+#include <string>
+#include <unistd.h>
+#include "sophyainit.h"
+#include "pexceptions.h"
+#include "fabtcolread.h"
+#include "fabtwriter.h"
+
+#define NO_VECTOR
+#define USE_EXCEPT
+
+int main(int narg,char *arg[])
+{
+ SophyaInit();
+ char *colname = "";
+ int colnum = -1;
+ int ihdu = 0;
+ long blen = 100;
+ long bsens = 1;
+ long lpmod=1;
+ double vs1,vs2; bool vsearch=false;
+ char c;
+ while((c = getopt(narg,arg,"hb:s:H:i:c:m:v:")) != -1) {
+   switch (c) {
+   case 'b' :
+     sscanf(optarg,"%ld",&blen);
+     break;
+   case 's' :
+     sscanf(optarg,"%ld",&bsens);
+     break;
+   case 'H' :
+     sscanf(optarg,"%d",&ihdu);
+     break;
+   case 'i' :
+     sscanf(optarg,"%d",&colnum);
+     break;
+   case 'c' :
+     colname = optarg;
+     break;
+   case 'm' :
+     sscanf(optarg,"%ld",&lpmod);
+     if(lpmod<=0) lpmod = 1;
+     break;
+   case 'v' :
+     sscanf(optarg,"%lf,%lf",&vs1,&vs2);
+     vsearch=true;
+     break;
+   case 'h' :
+   default :
+     cout<<"cmvcolread -b buflen -s sens -H hdu -m print_modulo"
+         <<" -i colnum -c colname -v vsearch1,vsearch2"
+         <<" fitsread fitswrite"<<endl;
+     return -1;
+   }
+ }
+ if(optind>=narg) {
+   cout<<"Donnez un nom de fichier fits"<<endl;
+   return -1;
+ }
+ char * fitsname = arg[optind];
+ char * fitswrit = NULL;
+ if(optind+1<narg) fitswrit = arg[optind+1];
+
+ FitsABTColRead* fbt=NULL;
+ FitsABTWriter*  fbtw=NULL;
+ if(fitswrit)
+   fbtw = new FitsABTWriter(fitswrit,BINARY_TBL,3);
+
+#ifdef USE_EXCEPT
+try {
+#endif
+
+  if(strlen(colname)>0)
+    fbt = new FitsABTColRead(fitsname,colname,ihdu,blen,bsens,3);
+  else
+    fbt = new FitsABTColRead(fitsname,colnum,ihdu,blen,bsens,3);
+  fbt->SetDebug(3);
+  fbt->Print(3);
+  cout<<"ReadFirstRow : "<<fbt->ReadFirstRow()<<endl;
+  cout<<"ReadLastRow  : "<<fbt->ReadLastRow()<<endl;
+
+  if(fbtw) {
+    fbtw->SetExtName("MON_EXTENSION");
+    fbtw->AddCol("xshort",NULL,"unitS",TSHORT);
+    fbtw->AddCol("xlong",NULL,"unitL",TLONG);
+    fbtw->AddCol("xfloat",NULL,"unitF",TFLOAT);
+    fbtw->AddCol("xdouble",NULL,"unitD",TDOUBLE);
+    fbtw->AddCol("xshort2",NULL,"unitS",TSHORT);
+    fbtw->SetDebug(3);
+  }
+
+  if(vsearch) {
+    long mid = fbt->GetNbLine()/2;
+    cout<<"Search vs1="<<vs1<<" vs2="<<vs2<<endl;
+    cout<<"FirstRow: "<<fbt->FirstRow(vs1,vs2,-1)<<endl;
+    cout<<"LastRow : "<<fbt->LastRow(vs1,vs2,-1)<<endl;
+    cout<<"FirstRow from middle: "<<fbt->FirstRow(vs1,vs2,mid)<<endl;
+    cout<<"LastRow  from middle: "<<fbt->LastRow(vs1,vs2,mid)<<endl;
+  }
+
+#ifdef NO_VECTOR
+  cout<<"Writting element by elements"<<endl;
+  for(long i=0;i<fbt->GetNbLine();i++) {
+    double x = fbt->Read(i);
+    if(i%lpmod==0) cout<<i<<": "<<x<<endl;
+    if(fbtw) {
+      fbtw->Write(0,i,x); // Si overflow la conversion est faite par cfitsio
+      fbtw->Write(1,i,x);
+      fbtw->Write(2,i,x);
+      fbtw->Write(3,i,x);
+      fbtw->Write(4,i,(short)x); // Si overflow la conversion est faite par le system
+    }
+  }
+#else
+  cout<<"Writting with vectors"<<endl;
+  TVector<double> data;
+  TVector<float> dataf;
+  TVector<int_4> datal;
+  long istep = fbt->GetNbLine()/10; if(istep>1000) istep=1000;
+  for(long i=0;i<fbt->GetNbLine();i+=istep) {
+    long i2=i+istep-1; if(i2>=fbt->GetNbLine()) i2=fbt->GetNbLine()-1;
+    long n = fbt->Read(i,i2,data);
+    fbt->Read(i,i2,dataf);
+    fbt->Read(i,i2,datal);
+    cout<<i<<" n="<<n<<" ("<<data.Size()<<")"
+        <<" d="<<data(0)<<","<<data(n-1)
+        <<" f="<<dataf(0)<<","<<dataf(n-1)
+        <<" l="<<datal(0)<<","<<datal(n-1)
+        <<endl;
+    if(fbtw) {
+      fbtw->Write(1,i,datal);
+      fbtw->Write(2,i,dataf);
+      fbtw->Write(3,i,data);
+    }
+  }
+#endif
+
+  fbt->Print(3);
+
+  //FitsABTColRead fbt2(*fbt);
+  //fbt2.SetDebug(3);
+  //fbt2.Print(3);
+  //cout<<"Read(0):   "<<fbt2.Read(0)<<endl;
+  //cout<<"Read(n-1): "<<fbt2.Read(fbt2.GetNbLine()-1)<<endl;
+  //fbt2.Print(3);
+
+  if(fbt) delete fbt;
+  if(fbtw) {
+    cout<<"Number of Overflows when writing: "<<fbtw->GetNOverFlow()<<endl;
+    delete fbtw;
+  }
+
+#ifdef USE_EXCEPT
+} catch (PThrowable & exc) {
+  cout<<"Exception : "<<(string)typeid(exc).name()
+      <<" - Msg= "<<exc.Msg()<<endl;
+  if(fbt) delete fbt;
+  if(fbtw) delete fbtw;
+  return -2;
+
+} catch (...) {
+  cout<<" some other exception was caught !"<<endl;
+  if(fbt) delete fbt;
+  if(fbtw) delete fbtw;
+  return -2;
+}
+#endif
+
+ return 0;
+}
Index: /tags/V_Dec2002/SophyaProg/Tests/tstndblk.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/tstndblk.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/tstndblk.cc	(revision 2309)
@@ -0,0 +1,222 @@
+#include "machdefs.h"
+#include <iostream.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <complex>
+#include <unistd.h>
+#include "ntoolsinit.h"
+#include "pexceptions.h"
+#include "ndatablock.h"
+
+void  Fonction(NDataBlock<r_4> Arg);
+NDataBlock<r_4> Fonction2(NDataBlock<r_4> Arg);
+
+void  Fonction(NDataBlock<r_4> Arg)
+{
+cout<<"Fonction: arg.Size()="<<Arg.Size()<<" arg.Data()="<<Arg.Data()<<endl;
+}
+NDataBlock<r_4> Fonction2(NDataBlock<r_4> Arg)
+{
+cout<<"Fonction2: arg.Size()="<<Arg.Size()<<" arg.Data()="<<Arg.Data()<<endl;
+return Arg;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+int main(int narg,char *arg[])
+{
+//-- Decodage arguments
+int lp = 0;
+char c;
+while((c = getopt(narg,arg,"hd:")) != -1) {
+  switch (c) {
+  case 'd' :
+    sscanf(optarg,"%d",&lp);
+    break;
+  case 'h' :
+    cout<<"tstndblk [-h] [-d debug_level]"<<endl;
+    exit(-1);
+  }
+}
+
+//-- Initialization
+SophyaInit();
+const int NDim = 8;
+r_4 *x1 = new r_4[NDim];
+r_4 *x2 = new r_4[NDim];
+r_4 *x3 = new r_4[NDim];
+for(int k=0;k<NDim;k++)
+  {x1[k]=k+1; x2[k]=(k+1)*10; x3[k]=(k+1)*100;}
+
+NDataBlock<int_4>::SetPrintDebug(lp);
+NDataBlock<r_4>::SetPrintDebug(lp);
+NDataBlock<r_8>::SetPrintDebug(lp);
+NDataBlock< complex<r_4> >::SetPrintDebug(lp);
+NDataBlock< complex<r_8> >::SetPrintDebug(lp);
+
+{  // Pour voir explicitement le travail du destructeur
+
+//-----------------------------------------------------
+cout<<endl<<"Createur par defaut Va"<<endl;
+NDataBlock<int_4> V1; V1.Print(1,99);
+try {
+  cout<<endl<<"...Createur par copie V2e(V1)"<<endl;
+  NDataBlock<int_4> V2e(V1);
+} catch(PException exc) {
+  cout<<"...Exception catched : " << exc.Msg() << endl;
+} 
+
+//-----------------------------------------------------
+cout<<endl<<"Createur A1(3)"<<endl;
+NDataBlock<r_4> A1(3);
+cout<<endl<<"Createur B1("<<NDim<<")"<<endl;
+NDataBlock<r_4> B1(NDim);
+A1.FillFrom(NDim,x1); A1.Print(0,999);
+B1.FillFrom(NDim,x1); B1.Print(0,999);
+
+cout<<endl<<"Createur A2(3)"<<endl;
+NDataBlock<r_4> A2(3);
+A2.FillFrom(NDim,x2); A2.Print(0,999);
+cout<<endl<<"Createur B2("<<NDim<<")"<<endl;
+NDataBlock<r_4> B2(NDim);
+B2.FillFrom(NDim,x2); B2.Print(0,999);
+
+cout<<endl<<"Createur A3(3)"<<endl;
+NDataBlock<r_4> A3(3);
+A3.FillFrom(NDim,x3); A3.Print(0,999);
+cout<<endl<<"Createur B3("<<NDim<<")"<<endl;
+NDataBlock<r_4> B3(NDim);
+B3.FillFrom(NDim,x3); B3.Print(0,999);
+
+//-----------------------------------------------------
+cout<<endl<<"Createur par copie AA1(A1)"<<endl;
+NDataBlock<r_4> AA1(A1);
+
+cout<<endl<<"Createur par copie BB1(B1)"<<endl;
+NDataBlock<r_4> BB1(B1);
+
+{cout<<endl<<"Createur par copie {BBB1(B1)}"<<endl;
+NDataBlock<r_4> BBB1(B1);}
+
+{cout<<endl<<"Createur avec bridge {Abr("<<NDim<<",x3,new Bridge)}"<<endl;
+NDataBlock<r_4> Abr(NDim,x3,new Bridge);
+Abr.Print(0,999);
+cout<<"x3 existe encore: "<<x3[0]<<",...,"<<x3[4]<<endl;}
+
+{cout<<endl<<"Createur avec bridge {Abr("<<NDim<<",dum,NULL)}"<<endl;
+r_4 *dum = new r_4[10];
+for(int i=0;i<10;i++) dum[i] = 1000.+i;
+NDataBlock<r_4> Abr(10,dum);
+Abr.Print(0,999);}
+
+//-----------------------------------------------------
+cout<<endl<<"Passage par argument a une fonction"<<endl;
+NDataBlock<r_4> Arg;
+cout<<"... Argument cree par defaut"<<endl;
+Fonction(Arg);
+cout<<"... Argument normal"<<endl;
+Fonction(A1);
+
+cout<<endl<<"Passage par argument a une fonction avec retour d un NDataBlock"<<endl;
+cout<<"... Argument cree par defaut"<<endl;
+NDataBlock<r_4> fdum = Fonction2(Arg); cout<<fdum;
+NDataBlock<r_4> fdum1(Fonction2(Arg)); cout<<fdum1;
+cout<<"... Argument normal"<<endl;
+NDataBlock<r_4> fdum2 = Fonction2(A1); cout<<fdum2;
+NDataBlock<r_4> fdum3(Fonction2(A1)); cout<<fdum3;
+
+//-----------------------------------------------------
+cout<<endl<<endl;
+NDataBlock<r_4> AC(3);
+AC.Reset();
+cout<<endl<<"AC=2"<<endl;
+AC = 2; AC.Print(0,999);
+AC.Reset();
+cout<<endl<<"AC=A1"<<endl;
+AC = A1; AC.Print(0,999);
+
+//-----------------------------------------------------
+cout<<endl<<endl;
+AC.Reset();
+cout<<endl<<"AC+=2"<<endl;
+AC += 2; AC.Print(0,999);
+cout<<endl<<"AC+=2+3"<<endl;
+AC += 2+3; AC.Print(0,999);
+cout<<endl<<"AC+=3"<<endl;
+AC += 3; AC.Print(0,999);
+cout<<endl<<"AC-=3"<<endl;
+AC -= 3; AC.Print(0,999);
+cout<<endl<<"AC*=10"<<endl;
+AC *= 10; AC.Print(0,999);
+cout<<endl<<"AC/=10"<<endl;
+AC /= 10; AC.Print(0,999);
+
+//-----------------------------------------------------
+cout<<endl<<endl;
+AC.Reset(1000);
+cout<<endl<<"AC+=A1"<<endl;
+AC += A1; AC.Print(0,999);
+cout<<endl<<"AC-=A1"<<endl;
+AC.Reset(1000);
+AC -= A1; AC.Print(0,999);
+cout<<endl<<"AC*=A1"<<endl;
+AC.Reset(1000);
+AC *= A1; AC.Print(0,999);
+cout<<endl<<"AC/=A1"<<endl;
+AC.Reset(1000);
+AC /= A1; AC.Print(0,999);
+
+//-----------------------------------------------------
+cout<<endl<<endl;
+cout<<endl<<"AC=A1+2"<<endl;
+AC = A1+2.f; AC.Print(0,999);
+cout<<endl<<"AC=2+A1"<<endl;
+AC = 2.f+A1; AC.Print(0,999);
+cout<<endl<<"AC=A1*2"<<endl;
+AC = A1*2.f; AC.Print(0,999);
+cout<<endl<<"AC=2*A1"<<endl;
+AC = 2.f*A1; AC.Print(0,999);
+cout<<endl<<"AC=A1-2"<<endl;
+AC = A1-2.f; AC.Print(0,999);
+cout<<endl<<"AC=2-A1"<<endl;
+AC = 2.f-A1; AC.Print(0,999);
+cout<<endl<<"AC=A1/2"<<endl;
+AC = A1/2.f; AC.Print(0,999);
+cout<<endl<<"AC=2/A1"<<endl;
+AC = 2.f/A1; AC.Print(0,999);
+
+//-----------------------------------------------------
+cout<<endl<<endl;
+cout<<endl<<"AC=A1+A2"<<endl;
+AC = A1 + A2; AC.Print(0,999);
+cout<<endl<<"AC=A2-A1"<<endl;
+AC = A2 - A1; AC.Print(0,999);
+cout<<endl<<"AC=A1*A2"<<endl;
+AC = A1 * A2; AC.Print(0,999);
+cout<<endl<<"AC=A2/A1"<<endl;
+AC = A2 / A1; AC.Print(0,999);
+
+//-----------------------------------------------------
+cout<<endl<<endl;
+cout<<endl<<"AC=A1+A2+A3"<<" "<<&A1<<","<<&A2<<","<<&A3<<endl;
+AC = A1 + A2 + A3; AC.Print(0,999);
+
+
+cout<<"\n\n\n"<<endl;
+}  // Pour voir explicitement le travail du destructeur
+cout<<"Fin du Job"<<endl;
+cout<<"delete x1"<<endl; delete [] x1;
+cout<<"delete x2"<<endl; delete [] x2;
+cout<<"delete x3"<<endl; delete [] x3;
+
+//---- Final debug print
+cout<<endl<<endl<<"FINAL DEBUG SUMMARY : lp="<<lp<<endl<<endl;
+cout<<"DEBUG int_4:\n";        NDataBlock<int_4>::PrintDebug();
+cout<<"DEBUG r_4:\n";          NDataBlock<r_4>::PrintDebug();
+cout<<"DEBUG r_8:\n";          NDataBlock<r_8>::PrintDebug();
+cout<<"DEBUG complex<r_4>:\n"; NDataBlock< complex<r_4> >::PrintDebug();
+cout<<"DEBUG complex<r_8>:\n"; NDataBlock< complex<r_8> >::PrintDebug();
+
+exit(0);
+}
Index: /tags/V_Dec2002/SophyaProg/Tests/tsttmat.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/tsttmat.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/tsttmat.cc	(revision 2309)
@@ -0,0 +1,227 @@
+#include "machdefs.h"
+#include <iostream.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include "ntoolsinit.h"
+#include "pexceptions.h"
+#include "array.h"
+#include "srandgen.h"
+
+////////////////////////////////////////////////////////////////////////////////////////
+int main(int narg,char *arg[])
+{
+SophyaInit();
+r_8 v[3][4] = {{1,2,3,4},{4,5,6,5},{7,8,9,10}};
+
+{
+
+TMatrix<r_8> A(2,3);
+{for(int i=0;i<2;i++) for(int j=0;j<3;j++) A(i,j) = v[i][j];}
+cout<<"A:"<<endl<<A;
+
+{
+cout << " Test ecriture PPersist TMatrix " << endl; 
+FIO_TArray<r_8> ftm(A);
+ftm.Write("tmtx.ppf");
+}
+{
+cout << " Test lecture PPersist TMatrix " << endl; 
+FIO_TArray<r_8> ftm("tmtx.ppf");
+cout<<"Alue:"<<(TMatrix<r_8>)ftm<<endl;
+}
+
+cout<<"Matrices B(2,3)"<<endl;
+TMatrix<r_8> B(3,2);
+{for(int i=0;i<3;i++) for(int j=0;j<2;j++) B(i,j) = v[i][j];}
+cout<<"B:"<<endl<<B;
+
+cout<<"Matrices C(3,3)"<<endl;
+TMatrix<r_8> C(3,3);
+{for(int i=0;i<3;i++) for(int j=0;j<3;j++) C(i,j) = v[i][j];}
+cout<<"C:"<<endl<<C;
+
+cout<<"Matrices D(2,2)"<<endl;
+TMatrix<r_8> D(2,2);
+{for(int i=0;i<2;i++) for(int j=0;j<2;j++) D(i,j) = v[i][j];}
+cout<<"D:"<<endl<<D;
+
+cout<<"Matrices E(3,4)"<<endl;
+TMatrix<r_8> E(3,4);
+{for(int i=0;i<3;i++) for(int j=0;j<4;j++) E(i,j) = v[i][j];}
+cout<<"E:"<<endl<<E;
+
+//-----------------------------------------------
+cout<<endl<<"Matrices AA(A)"<<endl;
+TMatrix<r_8> AA(A);
+cout<<"AA:"<<endl<<AA;
+
+//-----------------------------------------------
+cout<<endl<<"Matrices AA2; AA2=A;"<<endl;
+TMatrix<r_8> AA2; AA2=A;
+cout<<"AA2:"<<endl<<AA2;
+
+//-----------------------------------------------
+cout<<endl<<"Matrices AAA.Clone(A)"<<endl;
+TMatrix<r_8> AAA; AAA.Clone(A);
+cout<<"AAA:"<<endl<<AAA;
+cout<<endl<<"Matrices BBB.Clone(B)"<<endl;
+TMatrix<r_8> BBB; BBB.Clone(B);
+cout<<"BBB:"<<endl<<BBB;
+cout<<"Matrices CCC.Clone(C)"<<endl;
+TMatrix<r_8> CCC; CCC.Clone(C);
+cout<<"CCC:"<<endl<<CCC;
+
+//-----------------------------------------------
+cout<<endl<<"Matrices I(5,5)=1.234"<<endl;
+TMatrix<r_8> I(5,5); I = 5;
+cout<<"I:"<<endl<<I;
+
+//-----------------------------------------------
+cout<<endl<<"Matrices AAA+=1"<<endl;
+AAA += 1;
+cout<<"AAA:"<<endl<<AAA;
+cout<<"Matrices AAA-=1"<<endl;
+AAA -= 1;
+cout<<"AAA:"<<endl<<AAA;
+cout<<"Matrices AAA*=10"<<endl;
+AAA *= 10;
+cout<<"AAA:"<<endl<<AAA;
+cout<<"Matrices AAA/=10"<<endl;
+AAA /= 10;
+cout<<"AAA:"<<endl<<AAA;
+
+//-----------------------------------------------
+cout<<endl<<"Matrices AAA+=A"<<endl;
+AAA += A;
+cout<<"AAA:"<<endl<<AAA;
+cout<<"Matrices AAA-=A"<<endl;
+AAA -= A;
+cout<<"AAA:"<<endl<<AAA;
+
+//-----------------------------------------------
+cout<<endl<<"Matrices AAA=A"<<endl;
+AAA = A;
+cout<<"AAA:"<<endl<<AAA;
+cout<<endl<<"Matrices BBB=B"<<endl;
+BBB = B;
+cout<<"BBB:"<<endl<<BBB;
+
+//---------------------------------------------
+TMatrix<r_8> a(A,false);
+cout<<endl<<"Matrices AAA*=C"<<endl;
+{for(uint_4 i=0;i<AAA.NRows();i++) for(uint_4 j=0;j<C.NCols();j++)
+  {a(i,j) = 0; for(uint_4 k=0;k<AAA.NCols();k++) a(i,j) += AAA(i,k)*C(k,j);}}
+AAA *= C;
+cout<<"AAA:"<<endl<<AAA;
+cout<<"a:"<<endl<<a;
+TMatrix<r_8> b(B,false);
+cout<<"Matrices BBB*=D"<<endl;
+{for(uint_4 i=0;i<BBB.NRows();i++) for(uint_4 j=0;j<D.NCols();j++)
+  {b(i,j) = 0; for(uint_4 k=0;k<BBB.NCols();k++) b(i,j) += BBB(i,k)*D(k,j);}}
+BBB *= D;
+cout<<"B:"<<endl<<BBB;
+cout<<"b:"<<endl<<b;
+
+//-----------------------------------------------
+AA.Clone(A);
+cout<<endl<<"Matrices AA = AA + 10"<<endl;
+AA = AA + 10.; cout<<"AA"<<endl<<AA;
+cout<<endl<<"Matrices AA = AA - 10"<<endl;
+AA = AA - 10.; cout<<"AA"<<endl<<AA;
+cout<<endl<<"Matrices AA = 10 - AA"<<endl;
+AA = 10. - AA; cout<<"AA"<<endl<<AA;
+cout<<endl<<"Matrices AA = AA - 10"<<endl;
+AA = AA - 10.; cout<<"AA"<<endl<<AA;
+cout<<endl<<"Matrices AA = -1 * AA"<<endl;
+AA = -1. * AA; cout<<"AA"<<endl<<AA;
+cout<<endl<<"Matrices AA = 10 * AA"<<endl;
+AA = 10. * AA; cout<<"AA"<<endl<<AA;
+cout<<endl<<"Matrices AA = AA * 10"<<endl;
+AA = AA * 10.; cout<<"AA"<<endl<<AA;
+cout<<endl<<"Matrices AA = AA / 100"<<endl;
+AA = AA / 100.; cout<<"AA"<<endl<<AA;
+
+//-----------------------------------------------
+TMatrix<r_8> R;
+AA.Clone(A); AA += 10.; AAA.Clone(A); AAA += 100.;
+cout<<endl<<"Matrices R = A + AA"<<endl;
+R = A + AA; cout<<"R"<<endl<<R;
+cout<<endl<<"Matrices R = AA - A"<<endl;
+R = AA - A; cout<<"R"<<endl<<R;
+cout<<endl<<"Matrices R = A + AA + AAA"<<endl;
+R = A + AA + AAA; cout<<"R"<<endl<<R;
+cout<<endl<<"Matrices R = A + 100 + 2*A"<<endl;
+R = A + 100. + 2.*A; cout<<"R"<<endl<<R;
+
+//-----------------------------------------------
+TMatrix<r_8> RR(2,4);
+{for(uint_4 i=0;i<A.NRows();i++) for(uint_4 j=0;j<E.NCols();j++)
+  {RR(i,j) = 0; for(uint_4 k=0;k<A.NCols();k++) RR(i,j) += A(i,k)*E(k,j);}}
+cout<<endl<<"Matrices R = A * E"<<endl;
+R = A * E;
+cout<<"R"<<endl<<R; cout<<"RR"<<endl<<RR;
+
+//-----------------------------------------------
+cout<<endl<<"Matrices A = A.Transpose 2x"<<endl;
+cout<<"A"<<endl<<A;
+A = A.Transpose(); cout<<"trA"<<endl<<A;
+A = A.Transpose(); cout<<"trtrA"<<endl<<A;
+cout<<endl<<"Matrices AT = A.Transpose()  2x"<<endl;
+TMatrix<r_8> AT;
+AT = A.Transpose(); cout<<"AT"<<endl<<AT;
+AT = AT.Transpose(); cout<<"trAT"<<endl<<AT;
+
+//-----------------------------------------------
+cout<<endl<<"Test Inversion avec couplage a M=Matrix(C)"<<endl;
+TMatrix<r_8> X(10,10);
+{for(int i=0;i<10;i++) for(int j=0;j<10;j++)
+  {X(i,j) = drand01(); if(drand01()>0.8) X(i,j) += 1.e+15*drand01();}}
+cout<<"TMatrix X"<<endl<<X;
+{
+Matrix M(X); cout<<"Matrix M"<<endl<<M<<endl;
+Matrix MI = Inverse(M); cout<<"MI"<<endl<<MI;
+MI *= M; cout<<"MI*M"<<endl<<MI;
+r_8 xmin=-1.;
+for(int i=0;i<10;i++) for(int j=0;j<10;j++)
+   if(i!=j && fabs(MI(i,j))>xmin) xmin=fabs(MI(i,j));
+cout<<"Biggest off diagonal identity matrix element is "<<xmin<<endl;
+} // destruction de M,MI
+cout<<"TMatrix X"<<endl<<X;
+
+//-----------------------------------------------
+{
+cout<<endl<<"Test Inversion directe"<<endl;
+cout<<"TMatrix X"<<endl<<X;
+TMatrix<r_8> Xinv;
+Xinv = Inverse(X);
+cout<<"TMatrix Xinv"<<endl<<Xinv;
+Xinv *= X;
+cout<<"Xinv *= X"<<endl<<Xinv;
+r_8 xmin=-1.;
+for(int i=0;i<10;i++) for(int j=0;j<10;j++)
+   if(i!=j && fabs(Xinv(i,j))>xmin) xmin=fabs(Xinv(i,j));
+cout<<"Biggest off diagonal identity matrix element is "<<xmin<<endl;
+cout<<"TMatrix X"<<endl<<X;
+}
+
+//-----------------------------------------------
+cout<<endl<<"Test liens TMatrix L avec Matrix MI"<<endl;
+Matrix MI(10,5);
+{for(int i=0;i<10;i++) for(int j=0;j<5;j++) MI(i,j) = 1000*i+j;}
+cout<<"MI"<<endl<<MI;
+{
+  sa_size_t siz[5];
+  siz[0] = MI.NCols();
+  siz[1] = MI.NRows();
+  TArray<r_8> A(2, siz, MI.Data(), 1, 0, new Bridge);
+  TMatrix<r_8> L(A);
+  cout<<"L"<<endl<<L;
+  L *= 100.; cout<<"L*=100."<<endl<<L;
+} // destruction de L
+cout<<"MI(4,4)="<<MI(4,4)<<endl;
+
+} // destruction de toutes les matrices
+exit(0);
+}
Index: /tags/V_Dec2002/SophyaProg/Tests/tsttminv.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/tsttminv.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/tsttminv.cc	(revision 2309)
@@ -0,0 +1,226 @@
+// Test de l'inversion de matrice (cmv 14/04/00)
+// Pb numeriques: dapax22 et daplxa115
+//                tsttminv -v 55,100,130,1000000000 -l 0 -a 1 
+
+// if defined COMPLEX , if not REAL
+//#define COMPLEX
+// if defined 32 bits precision, if not 64 bits
+// #define PRECIS32
+#define ALSO_LAPACK
+
+#include "machdefs.h"
+#include <iostream.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <unistd.h>
+#include "timing.h"
+#include "ntoolsinit.h"
+#include "pexceptions.h"
+#include "array.h"
+#include "srandgen.h"
+
+#ifdef ALSO_LAPACK
+#include "intflapack.h"
+#endif
+
+
+#if defined(COMPLEX)
+  #define ABS_VAL(_x_) sqrt((double)((_x_).real()*(_x_).real() + (_x_).imag()*(_x_).imag()))
+  #if defined(PRECIS32)
+    #define TYPE complex<r_4>
+  #else
+    #define TYPE complex<r_8>
+  #endif
+#else
+  #define ABS_VAL(_x_) fabs((double)_x_)
+  #if defined(PRECIS32)
+    #define TYPE r_4
+  #else
+    #define TYPE r_8
+  #endif
+#endif
+
+int main(int narg,char *arg[])
+{
+//--------------------------------------------------------
+// number of lines/columns
+uint_4 N = 5;
+// scale of the value (if =1 values between -1 and 1)
+r_8 scale = 1.;
+// number of values change by +/- vbig
+uint_4 nbig = N;
+r_8 vbig = 1000.;
+// Nombre de lignes de matrice a imprimer
+uint_4 nprline = 10;
+// Initialisation du pauvre de l'aleatoire
+uint_4 nalea = 0;
+// data scaling for gauss pivoting and determinant
+int tscal = 1;
+bool detok=false;
+bool timok = false;
+//--------------------------------------------------------
+
+//-- Decodage arguments
+char c;
+while((c = getopt(narg,arg,"hdtv:l:a:n:")) != -1) {
+  switch (c) {
+  case 'v' :
+    sscanf(optarg,"%d,%lf,%d,%lf",&N,&scale,&nbig,&vbig);
+    break;
+  case 'l' :
+    sscanf(optarg,"%d",&nprline);
+    break;
+  case 'a' :
+    sscanf(optarg,"%d",&nalea);
+    break;
+  case 'n' :
+    sscanf(optarg,"%d",&tscal);
+    break;
+  case 'd' :
+    detok = true;
+    break;
+  case 't' :
+    timok = true;
+    break;
+  case 'h' :
+    cout<<"tsttminv [-h] [-v N,scale,nbig,vbig] [-l nprline] [-a nalea]"<<endl
+        <<"         [-n typs] [-d] [-t]"<<endl
+        <<"matrix filled with : {[-1,1] +/- vbig(nbig time)}*scale"<<endl
+	<<"-n 0/1/2 : data scaling 0=no, 1=global (def), 2=row-by-row"<<endl
+	<<"-d : also compute determinant"<<endl
+	<<"-t : do timing"<<endl;
+    exit(-1);
+  }
+}
+if(N<=1) N = 1;
+cout<<"Taille matrice NxN, N = "<<N<<endl;
+cout<<"Elements entre +/- scale = "<<scale<<endl;
+cout<<"Nombre de valeurs hors standard nbig = "<<nbig<<endl;
+cout<<"Valeurs hors standard (+/- vbig = "<<vbig<<" ) * scale"<<endl;
+cout<<"Nombre de lignes de matrice a imprimer "<<nprline<<endl;
+cout<<"Initialisation de l aleatoire par "<<nalea<<" tirages"<<endl;
+ cout<<"Data scaling "<<tscal<<" determinant="<<detok<<" timing="<<timok<<endl;
+cout<<endl;
+
+//-- Initialization arrays
+SophyaInit();
+if(timok) InitTim();
+#ifdef ALSO_LAPACK
+  BaseArray::SetDefaultMemoryMapping(BaseArray::FortranMemoryMapping);
+#endif
+
+//-- Definition arrays
+TMatrix< TYPE > A(N,N);
+TMatrix< TYPE > InvA(N,N);
+TMatrix< TYPE > AiA(N,N);
+TMatrix< TYPE > B(N,N);
+TMatrix< TYPE > Adum(N,N);
+TVector< int >  Vind(N*N);
+A.Show();
+
+SimpleMatrixOperation< TYPE >::SetGausPivScal(tscal);
+
+//-- Mise a zero
+A    = (TYPE) 0;
+InvA = (TYPE) 0;
+AiA  = (TYPE) 0;
+B    = (TYPE) 0;
+Adum = (TYPE) 0;
+BaseArray::SetMaxPrint(nprline*N,0);
+
+//-- Fill matrices
+double vmax=-1.;
+uint_8 k;
+uint_4 i,j; double s;
+uint_4 nbr=0, nbi=0;
+Vind = 0;
+if(nalea>0) for(i=0;i<nalea;i++) drand01();
+A = RandomSequence(RandomSequence::Flat,0.,1.);
+if(nbig>0) for(i=0;i<nbig;i++) {
+  k=(uint_8)(drand01()*N*N); if(k>=N*N) k--;
+  s=(drand01()>0.5)?1.:-1.;
+  if(Vind[k]==0) {A[k] += (TYPE) s*vbig; Vind[k]=1; nbr++;}
+}
+A *= (TYPE) scale;
+#if defined(COMPLEX)
+Vind = 0;
+B = RandomSequence(RandomSequence::Flat,0.,1.);
+if(nbig>0) for(i=0;i<nbig;i++) {
+  k=(uint_8)(drand01()*N*N); if(k>=N*N) k--;
+  s=(drand01()>0.5)?1.:-1.;
+  if(Vind[k]==0) {B[k] += (TYPE) s*vbig; Vind[k]=1; nbi++;}
+}
+B *= (TYPE) scale;
+A += TYPE(0.,1.)*B;
+#endif
+cout<<"Nombre de valeurs BIG reelles = "<<nbr<<", imaginaires = "<<nbi<<endl;
+Adum = A;
+
+//-- Print matrice A
+cout<<"------------ TMatrix A :"<<endl;
+if(nprline>0) {cout<<A; cout<<endl<<endl;}
+
+//-- Inversion
+cout<<"------------ Inversion"<<endl;
+//InvA = Inverse(A);
+InvA = IdentityMatrix(1.,N);
+if(timok) PrtTim("--- End of filling ---");
+TYPE det = GausPiv(A,InvA,detok);
+if(timok) PrtTim("--- End of GausPiv ---");
+cout<<"Det = "<<det<<endl;
+cout<<"------------ TMatrix InvA = A^(-1):"<<endl;
+if(nprline>0) {cout<<InvA; cout<<endl<<endl;}
+
+//-- AiA = A * InvA
+cout<<"AiA = A * InvA"<<endl;
+AiA = A * InvA;
+cout<<"------------ TMatrix AiA = A * InvA:"<<endl;
+if(nprline>0) {cout<<AiA; cout<<endl;}
+
+//-- Check
+vmax=-1.;
+for(i=0;i<N;i++) {
+  double absv = ABS_VAL( 1. - AiA(i,i) );
+  if( absv > vmax ) vmax = absv;
+}
+cout<<"Ecart maximum par rapport a 1 sur diagonale = "<<vmax<<endl;
+vmax = -1.;
+for(i=0;i<N;i++) for(j=0;j<N;j++) {
+  if( i == j ) continue;
+  double absv = ABS_VAL( AiA(i,j) );
+  if( absv > vmax ) vmax = absv;
+}
+cout<<"Ecart maximum par rapport a 0 hors diagonale = "<<vmax<<endl;
+
+////////////////////////////////////
+///////// Test avec Lapack /////////
+////////////////////////////////////
+#ifdef ALSO_LAPACK
+
+cout<<endl<<"LAPACK Cross-Check"<<endl;
+InvA = IdentityMatrix(1.,N);
+if(timok) PrtTim("--- End of check ---");
+LapackLinSolve(Adum,InvA);
+if(timok) PrtTim("--- End of LapackLinSolve ---");
+AiA = A * InvA;
+vmax=-1.;
+for(i=0;i<N;i++) {
+  double absv = ABS_VAL( 1. - AiA(i,i) );
+  if( absv > vmax ) vmax = absv;
+}
+cout<<"Ecart maximum par rapport a 1 sur diagonale = "<<vmax<<endl;
+vmax = -1.;
+for(i=0;i<N;i++) for(j=0;j<N;j++) {
+  if( i == j ) continue;
+  double absv = ABS_VAL( AiA(i,j) );
+  if( absv > vmax ) vmax = absv;
+}
+cout<<"Ecart maximum par rapport a 0 hors diagonale = "<<vmax<<endl;
+
+#endif
+
+if(timok) PrtTim("--- End of Job ---");
+exit(0);
+}
Index: /tags/V_Dec2002/SophyaProg/Tests/tsttvec.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/tsttvec.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/tsttvec.cc	(revision 2309)
@@ -0,0 +1,114 @@
+#include "machdefs.h"
+#include <iostream.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include "ntoolsinit.h"
+#include "pexceptions.h"
+
+#include "array.h"
+#include "srandgen.h"
+
+////////////////////////////////////////////////////////////////////////////////////////
+int main(int narg,char *arg[])
+{
+SophyaInit();
+r_8 v[10] = {1,2,3,4,5,6,7,8,9,10};
+{
+cout<<"TVector(10)"<<endl;
+TVector<r_8> v1(10);
+{for(int i=0;i<10;i++) v1(i)=100+i;}
+cout<<"nel="<<v1.NElts()<<endl<<v1;
+
+{
+cout << " Test ecriture PPersist TVector " << endl; 
+FIO_TArray<r_8> ftv(v1);
+ftv.Write("tvec.ppf");
+}
+{
+cout << " Test lecture PPersist TVector " << endl; 
+FIO_TArray<r_8> ftv("tvec.ppf");
+cout<<"Vlue:"<<(TVector<r_8>)ftv<<endl;
+}
+
+
+cout<<"TVector(10,v,br) (v2)"<<endl;
+sa_size_t siz[5];
+siz[1] = 10;
+siz[0] = 1;
+TVector<r_8> v2(TArray<r_8>(2,siz,v,1,0,new Bridge)); cout<<v2;
+
+cout<<"TVector()"<<endl;
+TVector<r_8> v3; cout<<v3;
+
+cout<<"v3 = v1"<<endl;
+v3 = v1; cout<<v3;
+
+cout<<"v3 = 123456"<<endl;
+v3 = 123456.; cout<<v3;
+
+cout<<"ps =  v2.Transpose() * v1"<<endl;
+r_8 ps = (v2.Transpose()*v1).toScalar(); cout<<"ps="<<ps<<endl;
+
+cout<<"v2 = 10.*v1"<<endl;
+v2 = 10.*v1; cout<<v2;
+cout<<"v2 = v2*0.1"<<endl;
+v2 = v2*0.1; cout<<v2;
+
+cout<<"v2 = v1/10."<<endl;
+v2 = v1/10.; cout<<v2;
+cout<<"v2 = v2/0.1"<<endl;
+v2 = v2/0.1; cout<<v2;
+
+cout<<"v2 = 10.+v1"<<endl;
+v2 = 10.+v1; cout<<v2;
+cout<<"v2 = v2-10."<<endl;
+v2 = v2-10.; cout<<v2;
+
+cout<<"v2 = 10.-v1"<<endl;
+v2 = 10.-v1; cout<<v2;
+cout<<"v2 = (-1.)*v2+10."<<endl;
+v2 = (-1.)*v2+10.; cout<<v2;
+
+cout<<"v2 += 10."<<endl;
+v2 += 10.; cout<<v2;
+cout<<"v2 -= 10."<<endl;
+v2 -= 10.; cout<<v2;
+cout<<"v2 *= 10."<<endl;
+v2 *= 10.; cout<<v2;
+cout<<"v2 /= 10."<<endl;
+v2 /= 10.; cout<<v2;
+
+cout<<"v3.ReSize(4)"<<endl;
+v3.ReSize(4);
+{for(int i=0;i<4;i++) v3(i)=i+1;} cout<<v3;
+TMatrix<r_8> M(2,4);
+{for(int i=0;i<8;i++) M[i]=i+1;} cout<<M;
+TVector<r_8> v4(10);
+v4 = M*v3; cout<<v4;
+
+cout<<"LinSolve(A,B,X)"<<endl;
+TMatrix<r_8> A(5,5);
+TVector<r_8> B(5);
+{for(int i=0;i<25;i++) {A[i]=drand01(); if(i<5) B(i)=drand01();}}
+TVector<r_8> X;
+X = B;
+cout<<"A = "<<A; cout<<"B = "<<B;
+r_8 d=0.;
+d = LinSolve(A,B,X);
+cout<<"d="<<d<<endl; cout<<"X = "<<X;
+X = A*X; cout<<"A*X = "<<X;
+X -= B; cout<<"B-X = "<<X;
+cout<<"LinSolveInPlace(A,B)"<<endl;
+X = B;
+d = LinSolveInPlace(A,X);
+cout<<"d="<<d<<endl; cout<<"X = "<<X;
+
+cout<<"Conversion en ancien Vector"<<endl;
+Vector Vold(v1);
+cout<<"Vold = "<<Vold;
+
+} // destruction de toutes les vecteurs
+exit(0);
+}
Index: /tags/V_Dec2002/SophyaProg/Tests/zthr.cc
===================================================================
--- /tags/V_Dec2002/SophyaProg/Tests/zthr.cc	(revision 2309)
+++ /tags/V_Dec2002/SophyaProg/Tests/zthr.cc	(revision 2309)
@@ -0,0 +1,109 @@
+#include "zthread.h"
+
+#include <iostream.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+
+#include <time.h>
+#include <unistd.h>
+
+#include "timing.h"
+
+
+void fun2(void * arg)
+{
+time_t t0, t1;
+int i;
+char *strg;
+strg = (char *)arg;
+
+t0 = time(NULL);
+printf("**** Entry to fun2 (arg= %s) ***** \n", strg);
+int imax = atoi(strg);
+for(i=0; i<imax; i++)
+  {
+  sleep(4);
+  t1 = time(NULL)-t0;
+  printf("######## Fun2 [%d]  Dt= %d \n", i, (int)t1);
+  }
+
+return;
+}
+
+void fun1(void *arg)
+{
+time_t t0, t1;
+int i;
+
+char * strg = (char *)arg;
+
+t0 = time(NULL);
+printf("++++ Entry to fun1 (arg= %s) +++++ \n", strg);
+int imax = atoi(strg);
+for(i=0; i<imax; i++)
+  {
+  sleep(3);
+  t1 = time(NULL)-t0;
+  printf("%%%% Fun1 [%d]  Dt= %d \n", i, (int)t1);
+  }
+
+return;
+}
+
+class CountLock : public ZMutex {
+  int count;
+public:
+  CountLock() { count = 0; }
+  inline int Count() { lock(); int rc = ++count; unlock(); return(rc); 
+  }
+};
+
+
+int main(int narg, char *arg[])
+
+{
+
+  if (narg < 4) {
+    cout << " Usage: zthr N1 N2 NLock" << endl;
+    exit(1);
+  }
+
+  cout << " zthr-main() arg[1] = " << arg[1] << " arg[2]= " << arg[2] << endl;
+  InitTim();
+
+  CountLock clk;
+  int kk;
+  for(kk=0; kk<atoi(arg[3]); kk++) {
+    clk.Count();
+  }
+  cout << " End Count= " << clk.Count() << endl;
+  PrtTim("EndOfCount1 ");
+
+  cout << ">>> Creating Thread Z1 and Z2 " << endl;
+  ZThread zt1;
+  zt1.setAction(fun1, arg[1]);
+  ZThread zt2;
+  zt2.setAction(fun2, arg[2]);
+  cout << ">>> Starting Thread Z1 and Z2 " << endl;
+  zt1.start();
+  zt2.start();
+
+  PrtTim("BeginOfCount2 ");
+  for(kk=0; kk<atoi(arg[3]); kk++) {
+    clk.Count();
+  }
+  cout << " End Count= " << clk.Count() << endl;
+  PrtTim("EndOfCount2 ");
+
+  //  sleep(5);
+  cout << ">>> Joining Thread Z1 and Z2 " << endl;
+
+  zt1.join();
+  zt2.join();
+  cout << ">>> Thread Z1 and Z2 Finished " << endl;
+ 
+  return(0);
+  
+}
